[ruby-dev:26838] remove env.h from parse.y
From:
SASADA Koichi <ko1@...>
Date:
2005-08-19 12:51:24 UTC
List:
ruby-dev #26838
ささだです。 実行コンテキストにとても依存していた parse.y ですが、これを分離する パッチを作りました。具体的には、env.h を include しないでもよくなるよう にしてみました。 方針は、 ・グローバル変数除去 ・どうしてもアクセスしたい場合は eval.c の関数に丸投げ ・K&Rで書いてみる です。 実行コンテキストへのアクセスは eval.c に書いた関数で抽象化していますの で、それを差し替えると yarv でもパーサにうまいこと情報を渡せる、という寸 法です。 ついでに、ID を一個足すごとに REALLOC していたのをなんとかしました。 x86_64 (linux) 環境で test-all がだいたい通ることを確認しました。9 個 の failure は、パーサ以外が原因のようです。 もうちょっとやれば(eval.c への関数アクセスをなんとかすれば)、ripper が難しいことしなくてもよくなるような気がするんですが、どうですかね。 採用を検討していただけると幸いです。 -- // SASADA Koichi at atdot dot net //
Attachments (1)
remove_env.patch
(19.8 KB, text/x-diff)
? remove_env.patch
Index: eval.c
===================================================================
RCS file: /src/ruby/eval.c,v
retrieving revision 1.819
diff -u -r1.819 eval.c
--- eval.c 17 Aug 2005 14:58:35 -0000 1.819
+++ eval.c 19 Aug 2005 12:36:22 -0000
@@ -827,6 +827,12 @@
return vars;
}
+int
+rb_dvar_current()
+{
+ return ruby_dyna_vars != 0;
+}
+
VALUE
rb_dvar_defined(id)
ID id;
@@ -941,6 +947,71 @@
return &ruby_scope->local_vars[cnt];
}
+int
+rb_scope_setup(len)
+ int len;
+{
+ if (len > 0) {
+ int i = ruby_scope->local_tbl?ruby_scope->local_tbl[0]:0;
+
+ if (i < len) {
+ if (i == 0 || (ruby_scope->flags & SCOPE_MALLOC) == 0) {
+ VALUE *vars = ALLOC_N(VALUE, len+1);
+ if (ruby_scope->local_vars) {
+ *vars++ = ruby_scope->local_vars[-1];
+ MEMCPY(vars, ruby_scope->local_vars, VALUE, i);
+ rb_mem_clear(vars+i, len-i);
+ }
+ else {
+ *vars++ = 0;
+ rb_mem_clear(vars, len);
+ }
+ ruby_scope->local_vars = vars;
+ ruby_scope->flags |= SCOPE_MALLOC;
+ }
+ else {
+ VALUE *vars = ruby_scope->local_vars-1;
+ REALLOC_N(vars, VALUE, len+1);
+ ruby_scope->local_vars = vars+1;
+ rb_mem_clear(ruby_scope->local_vars+i, len-i);
+ }
+ if (ruby_scope->local_tbl && ruby_scope->local_vars[-1] == 0) {
+ xfree(ruby_scope->local_tbl);
+ }
+ ruby_scope->local_vars[-1] = 0;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+void
+rb_scope_setup_local_tbl(tbl)
+ ID *tbl;
+{
+ ruby_scope->local_tbl = tbl;
+}
+
+int
+rb_scope_local_tbl_size(){
+ return ruby_scope->local_tbl?ruby_scope->local_tbl[0]:0;
+}
+
+ID
+rb_scope_local_tbl_id(i)
+ int i;
+{
+ return ruby_scope->local_tbl[i+1];
+}
+
+void
+rb_scope_set(cnt, val)
+ int cnt;
+ VALUE val;
+{
+ ruby_scope->local_vars[cnt] = val;
+}
+
struct iter {
int iter;
struct iter *prev;
Index: parse.y
===================================================================
RCS file: /src/ruby/parse.y,v
retrieving revision 1.404
diff -u -r1.404 parse.y
--- parse.y 16 Aug 2005 15:24:14 -0000 1.404
+++ parse.y 19 Aug 2005 12:36:23 -0000
@@ -15,7 +15,6 @@
#define YYDEBUG 1
#include "ruby.h"
-#include "env.h"
#include "intern.h"
#include "node.h"
#include "st.h"
@@ -23,6 +22,8 @@
#include <errno.h>
#include <ctype.h>
+extern int ruby_in_eval;
+
#define ID_SCOPE_SHIFT 3
#define ID_SCOPE_MASK 0x07
#define ID_LOCAL 0x01
@@ -97,17 +98,90 @@
struct RVarmap *vars;
};
+struct vtable{
+ ID *tbl;
+ int pos;
+ int capa;
+ struct vtable *prev;
+};
+
struct local_vars {
- ID *tbl;
- int nofree;
- int cnt;
- int dlev;
- int dname_size;
- ID *dnames;
- struct RVarmap* dyna_vars;
+ struct vtable *tbl;
+ struct vtable *dnames;
+ struct vtable *dvars;
struct local_vars *prev;
+ int nofree;
};
+static int
+vtable_size(tbl)
+ struct vtable *tbl;
+{
+ if((VALUE)tbl & ~3){
+ return tbl->pos;
+ }
+ else{
+ return 0;
+ }
+}
+
+static struct vtable *
+vtable_alloc(prev)
+ struct vtable *prev;
+{
+ struct vtable *tbl = ALLOC(struct vtable);
+ tbl->pos = 0;
+ tbl->capa = 16;
+ tbl->tbl = ALLOC_N(ID, tbl->capa);
+ tbl->prev = prev;
+ return tbl;
+}
+
+static void
+vtable_free(tbl)
+ struct vtable * tbl;
+{
+ if((VALUE)tbl & ~3){
+ if(tbl->tbl){
+ xfree(tbl->tbl);
+ }
+ if(tbl){
+ xfree(tbl);
+ }
+ }
+}
+
+static void
+vtable_add(tbl, id)
+ struct vtable *tbl;
+ ID id;
+{
+ if(!((VALUE)tbl & ~3)){
+ rb_bug("vtable_add: vtable is not allocated (%p)", tbl);
+ }
+ if(tbl->pos == tbl->capa){
+ tbl->capa = tbl->capa * 2;
+ REALLOC_N(tbl->tbl, ID, tbl->capa);
+ }
+ tbl->tbl[tbl->pos++] = id;
+}
+
+static int
+vtable_included(tbl, id)
+ struct vtable *tbl;
+ ID id;
+{
+ int i;
+ if((VALUE)tbl & ~3){
+ for(i=0; i<tbl->pos; i++){
+ if(tbl->tbl[i] == id){
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
/*
Structure of Lexer Buffer:
@@ -295,18 +369,23 @@
#define local_tbl() local_tbl_gen(parser)
static ID internal_id _((void));
-static struct RVarmap *dyna_push_gen _((struct parser_params*));
+static int dyna_push_gen _((struct parser_params*));
#define dyna_push() dyna_push_gen(parser)
static void dyna_pop_gen _((struct parser_params*, struct RVarmap*));
#define dyna_pop(vars) dyna_pop_gen(parser, vars)
static int dyna_in_block_gen _((struct parser_params*));
#define dyna_in_block() dyna_in_block_gen(parser)
-static NODE *dyna_init_gen _((struct parser_params*, NODE*, struct RVarmap *));
+static NODE *dyna_init_gen _((struct parser_params*, NODE*, int));
#define dyna_init(node, pre) dyna_init_gen(parser, node, pre)
static void dyna_var_gen _((struct parser_params*,ID));
#define dyna_var(id) dyna_var_gen(parser, id)
static void dyna_check_gen _((struct parser_params*,ID));
#define dyna_check(id) dyna_check_gen(parser, id)
+static int dvar_defined_gen _((struct parser_params*,ID));
+#define dvar_defined(id) dvar_defined_gen(parser, id)
+static int dvar_curr_gen _((struct parser_params*,ID));
+#define dvar_curr(id) dvar_curr_gen(parser, id)
+
static void top_local_init_gen _((struct parser_params*));
#define top_local_init() top_local_init_gen(parser)
@@ -597,11 +676,8 @@
/*%%%*/
lex_state = EXPR_BEG;
top_local_init();
- if (ruby_class == rb_cObject) class_nest = 0;
- else class_nest = 1;
/*%
lex_state = EXPR_BEG;
- class_nest = !parser->toplevel_p;
$$ = Qnil;
%*/
}
@@ -621,9 +697,7 @@
}
ruby_eval_tree = block_append(ruby_eval_tree, $2);
top_local_setup();
- class_nest = 0;
/*%
- class_nest = 0;
$$ = $2;
parser->result = dispatch1(program, $$);
%*/
@@ -1114,18 +1188,18 @@
cmd_brace_block : tLBRACE_ARG
{
/*%%%*/
- $<vars>$ = dyna_push();
+ $<num>$ = dyna_push();
$<num>1 = ruby_sourceline;
/*%
%*/
}
- opt_block_param {$<vars>$ = ruby_dyna_vars;}
+ opt_block_param {$<num>$ = vtable_size(lvtbl->dvars);}
compstmt
'}'
{
/*%%%*/
$3->nd_body = block_append($3->nd_body,
- dyna_init($5, $<vars>4));
+ dyna_init($5, $<num>4));
$$ = $3;
nd_set_line($$, $<num>1);
dyna_pop($<vars>2);
@@ -2723,13 +2797,11 @@
/*%%%*/
if (in_def || in_single)
yyerror("class definition in method body");
- class_nest++;
local_push(0);
$<num>$ = ruby_sourceline;
/*%
if (in_def || in_single)
yyerror("class definition in method body");
- class_nest++;
%*/
}
bodystmt
@@ -2739,10 +2811,8 @@
$$ = NEW_CLASS($2, $5, $3);
nd_set_line($$, $<num>4);
local_pop();
- class_nest--;
/*%
$$ = dispatch3(class, $2, $3, $5);
- class_nest--;
%*/
}
| kCLASS tLSHFT expr
@@ -2759,12 +2829,10 @@
/*%%%*/
$<num>$ = in_single;
in_single = 0;
- class_nest++;
local_push(0);
/*%
$$ = in_single;
in_single = 0;
- class_nest++;
%*/
}
bodystmt
@@ -2774,12 +2842,10 @@
$$ = NEW_SCLASS($3, $7);
fixpos($$, $3);
local_pop();
- class_nest--;
in_def = $<num>4;
in_single = $<num>6;
/*%
$$ = dispatch2(sclass, $3, $7);
- class_nest--;
in_def = $<val>4;
in_single = $<val>6;
%*/
@@ -2789,13 +2855,11 @@
/*%%%*/
if (in_def || in_single)
yyerror("module definition in method body");
- class_nest++;
local_push(0);
$<num>$ = ruby_sourceline;
/*%
if (in_def || in_single)
yyerror("module definition in method body");
- class_nest++;
%*/
}
bodystmt
@@ -2805,10 +2869,8 @@
$$ = NEW_MODULE($2, $4);
nd_set_line($$, $<num>3);
local_pop();
- class_nest--;
/*%
$$ = dispatch2(module, $2, $4);
- class_nest--;
%*/
}
| kDEF fname
@@ -3178,7 +3240,7 @@
lambda : {
/*%%%*/
- $<vars>$ = dyna_push();
+ $<num>$ = dyna_push();
/*%
%*/
}
@@ -3188,7 +3250,7 @@
}
f_larglist
{
- $<vars>$ = ruby_dyna_vars;
+ $<num>$ = vtable_size(lvtbl->dvars);
}
lambda_body
{
@@ -3234,14 +3296,14 @@
do_block : kDO_BLOCK
{
/*%%%*/
- $<vars>$ = dyna_push();
+ $<num>$ = dyna_push();
$<num>1 = ruby_sourceline;
/*% %*/
}
opt_block_param
{
/*%%%*/
- $<vars>$ = ruby_dyna_vars;
+ $<num>$ = vtable_size(lvtbl->dvars);
/*% %*/
}
compstmt
@@ -3249,7 +3311,7 @@
{
/*%%%*/
$3->nd_body = block_append($3->nd_body,
- dyna_init($5, $<vars>4));
+ dyna_init($5, $<num>4));
$$ = $3;
nd_set_line($$, $<num>1);
dyna_pop($<vars>2);
@@ -3372,14 +3434,14 @@
brace_block : '{'
{
/*%%%*/
- $<vars>$ = dyna_push();
+ $<num>$ = dyna_push();
$<num>1 = ruby_sourceline;
/*% %*/
}
opt_block_param
{
/*%%%*/
- $<vars>$ = ruby_dyna_vars;
+ $<num>$ = vtable_size(lvtbl->dvars);
/*%
%*/
}
@@ -3387,7 +3449,7 @@
{
/*%%%*/
$3->nd_body = block_append($3->nd_body,
- dyna_init($5, $<vars>4));
+ dyna_init($5, $<num>4));
$$ = $3;
nd_set_line($$, $<num>1);
dyna_pop($<vars>2);
@@ -3398,14 +3460,14 @@
| kDO
{
/*%%%*/
- $<vars>$ = dyna_push();
+ $<num>$ = dyna_push();
$<num>1 = ruby_sourceline;
/*% %*/
}
opt_block_param
{
/*%%%*/
- $<vars>$ = ruby_dyna_vars;
+ $<num>$ = vtable_size(lvtbl->dvars);
/*%
%*/
}
@@ -3413,7 +3475,7 @@
{
/*%%%*/
$3->nd_body = block_append($3->nd_body,
- dyna_init($5, $<vars>4));
+ dyna_init($5, $<num>4));
$$ = $3;
nd_set_line($$, $<num>1);
dyna_pop($<vars>2);
@@ -4516,7 +4578,6 @@
{
int n;
NODE *node = 0;
- struct RVarmap *vp, *vars = ruby_dyna_vars;
const char *kcode_save;
if (!compile_for_eval && rb_safe_level() == 0 &&
@@ -4551,14 +4612,7 @@
compile_for_eval = 0;
rb_set_kcode(kcode_save);
- vp = ruby_dyna_vars;
- ruby_dyna_vars = vars;
lex_strterm = 0;
- while (vp && vp != vars) {
- struct RVarmap *tmp = vp;
- vp = vp->next;
- rb_gc_force_recycle((VALUE)tmp);
- }
if (ruby_eval_tree_begin) {
return NEW_PRELUDE(ruby_eval_tree_begin, ruby_eval_tree);
}
@@ -5436,7 +5490,7 @@
ID id;
{
#ifndef RIPPER
- return (dyna_in_block() && rb_dvar_defined(id)) || local_id(id);
+ return (dyna_in_block() && dvar_defined(id)) || local_id(id);
#else
return 0;
#endif
@@ -7222,7 +7276,7 @@
return NEW_LIT(INT2FIX(ruby_sourceline));
}
else if (is_local_id(id)) {
- if (dyna_in_block() && rb_dvar_defined(id)) return NEW_DVAR(id);
+ if (dyna_in_block() && dvar_defined(id)) return NEW_DVAR(id);
if (local_id(id)) return NEW_LVAR(id);
/* method call without arguments */
dyna_check(id);
@@ -7270,10 +7324,10 @@
yyerror("Can't assign to __LINE__");
}
else if (is_local_id(id)) {
- if (rb_dvar_curr(id)) {
+ if (dvar_curr(id)) {
return NEW_DASGN_CURR(id, val);
}
- else if (rb_dvar_defined(id)) {
+ else if (dvar_defined(id)) {
return NEW_DASGN(id, val);
}
else if (local_id(id) || !dyna_in_block()) {
@@ -7310,7 +7364,7 @@
struct parser_params *parser;
ID name;
{
- if (rb_dvar_defined(name) || local_id(name)) {
+ if (dvar_defined(name) || local_id(name)) {
rb_warningS("shadowing outer local variable - %s", rb_id2name(name));
}
}
@@ -8066,7 +8120,7 @@
NODE *a;
{
if (is_local_id(m)) {
- if ((dyna_in_block() && rb_dvar_defined(m)) || local_id(m)) {
+ if ((dyna_in_block() && dvar_defined(m)) || local_id(m)) {
return NEW_CALL(gettable(m), rb_intern("call"), a);
}
}
@@ -8098,27 +8152,18 @@
}
static void
-local_push_gen(parser, top)
+local_push_gen(parser, inherit_dvars)
struct parser_params *parser;
- int top;
+ int inherit_dvars;
{
struct local_vars *local;
local = ALLOC(struct local_vars);
local->prev = lvtbl;
- local->nofree = 0;
- local->cnt = 0;
local->tbl = 0;
- local->dlev = 0;
- local->dname_size = 0;
local->dnames = 0;
- local->dyna_vars = ruby_dyna_vars;
+ local->dvars = (void *)inherit_dvars;
lvtbl = local;
- if (!top) {
- /* preserve reference for GC, but link should be cut. */
- rb_dvar_push(0, (VALUE)ruby_dyna_vars);
- ruby_dyna_vars->next = 0;
- }
}
static void
@@ -8126,15 +8171,9 @@
struct parser_params *parser;
{
struct local_vars *local = lvtbl->prev;
-
- if (lvtbl->tbl) {
- if (!lvtbl->nofree) xfree(lvtbl->tbl);
- else lvtbl->tbl[0] = lvtbl->cnt;
- }
- if (lvtbl->dnames) {
- xfree(lvtbl->dnames);
- }
- ruby_dyna_vars = lvtbl->dyna_vars;
+ vtable_free(lvtbl->tbl);
+ vtable_free(lvtbl->dnames);
+ vtable_free(lvtbl->dvars);
xfree(lvtbl);
lvtbl = local;
}
@@ -8143,8 +8182,16 @@
local_tbl_gen(parser)
struct parser_params *parser;
{
- lvtbl->nofree = 1;
- return lvtbl->tbl;
+ int i, cnt = vtable_size(lvtbl->tbl);
+ if(cnt > 0){
+ ID *tbl = ALLOC_N(ID, cnt + 1);
+ tbl[0] = cnt;
+ for(i=0; i<cnt; i++){
+ tbl[i+1] = lvtbl->tbl->tbl[i];
+ }
+ return tbl;
+ }
+ return 0;
}
static int
@@ -8153,20 +8200,14 @@
ID id;
{
if (lvtbl->tbl == 0) {
- lvtbl->tbl = ALLOC_N(ID, 4);
- lvtbl->tbl[0] = 0;
- lvtbl->tbl[1] = '_';
- lvtbl->tbl[2] = '~';
- lvtbl->cnt = 2;
+ lvtbl->tbl = vtable_alloc(0);
+ vtable_add(lvtbl->tbl, '_');
+ vtable_add(lvtbl->tbl, '~');
if (id == '_') return 0;
if (id == '~') return 1;
}
- else {
- REALLOC_N(lvtbl->tbl, ID, lvtbl->cnt+2);
- }
-
- lvtbl->tbl[lvtbl->cnt+1] = id;
- return lvtbl->cnt++;
+ vtable_add(lvtbl->tbl, id);
+ return vtable_size(lvtbl->tbl) - 1;
}
static int
@@ -8176,10 +8217,10 @@
{
int cnt, max;
- if (id == 0) return lvtbl->cnt;
+ if (id == 0) return vtable_size(lvtbl->tbl);
- for (cnt=1, max=lvtbl->cnt+1; cnt<max;cnt++) {
- if (lvtbl->tbl[cnt] == id) return cnt-1;
+ for (cnt=0, max=vtable_size(lvtbl->tbl); cnt<max;cnt++) {
+ if (lvtbl->tbl->tbl[cnt] == id) return cnt;
}
return local_append(id);
}
@@ -8192,68 +8233,38 @@
int i, max;
if (lvtbl == 0) return Qfalse;
- for (i=3, max=lvtbl->cnt+1; i<max; i++) {
- if (lvtbl->tbl[i] == id) return Qtrue;
- }
- return Qfalse;
+ return vtable_included(lvtbl->tbl, id);
}
+
+extern int rb_dvar_current();
+extern int rb_scope_local_tbl_size _(());
+extern ID rb_scope_local_tbl_id _((int i));
+extern int rb_scope_setup _((int len));
+extern void rb_scope_setup_local_tbl _((ID *tbl));
+
static void
top_local_init_gen(parser)
struct parser_params *parser;
{
- local_push(1);
- lvtbl->cnt = ruby_scope->local_tbl?ruby_scope->local_tbl[0]:0;
- if (lvtbl->cnt > 0) {
- lvtbl->tbl = ALLOC_N(ID, lvtbl->cnt+3);
- MEMCPY(lvtbl->tbl, ruby_scope->local_tbl, ID, lvtbl->cnt+1);
- }
- else {
- lvtbl->tbl = 0;
+ int i, cnt;
+ local_push(rb_dvar_current());
+ if(cnt = rb_scope_local_tbl_size()){
+ if(lvtbl->tbl == 0){
+ lvtbl->tbl = vtable_alloc(0);
+ }
+ for(i=0; i<cnt; i++){
+ vtable_add(lvtbl->tbl, rb_scope_local_tbl_id(i));
+ }
}
- if (ruby_dyna_vars)
- lvtbl->dlev = 1;
- else
- lvtbl->dlev = 0;
}
static void
top_local_setup_gen(parser)
struct parser_params *parser;
{
- int len = lvtbl->cnt;
- int i;
-
- if (len > 0) {
- i = ruby_scope->local_tbl?ruby_scope->local_tbl[0]:0;
-
- if (i < len) {
- if (i == 0 || (ruby_scope->flags & SCOPE_MALLOC) == 0) {
- VALUE *vars = ALLOC_N(VALUE, len+1);
- if (ruby_scope->local_vars) {
- *vars++ = ruby_scope->local_vars[-1];
- MEMCPY(vars, ruby_scope->local_vars, VALUE, i);
- rb_mem_clear(vars+i, len-i);
- }
- else {
- *vars++ = 0;
- rb_mem_clear(vars, len);
- }
- ruby_scope->local_vars = vars;
- ruby_scope->flags |= SCOPE_MALLOC;
- }
- else {
- VALUE *vars = ruby_scope->local_vars-1;
- REALLOC_N(vars, VALUE, len+1);
- ruby_scope->local_vars = vars+1;
- rb_mem_clear(ruby_scope->local_vars+i, len-i);
- }
- if (ruby_scope->local_tbl && ruby_scope->local_vars[-1] == 0) {
- xfree(ruby_scope->local_tbl);
- }
- ruby_scope->local_vars[-1] = 0;
- ruby_scope->local_tbl = local_tbl();
- }
+ if(rb_scope_setup(vtable_size(lvtbl->tbl))){
+ rb_scope_setup_local_tbl(local_tbl());
}
local_pop();
}
@@ -8264,18 +8275,16 @@
ID id;
{
int i;
-
- rb_dvar_push(id, Qnil);
- for (i=0; i<lvtbl->dname_size; i++) {
- if (lvtbl->dnames[i] == id) return;
- }
- if (lvtbl->dname_size == 0) {
- lvtbl->dnames = ALLOC_N(ID, 1);
+ if(!((VALUE)lvtbl->dvars & ~3)){
+ lvtbl->dvars = vtable_alloc(lvtbl->dvars);
}
- else {
- REALLOC_N(lvtbl->dnames, ID, lvtbl->dname_size+1);
+ vtable_add(lvtbl->dvars, id);
+ if(!vtable_included(lvtbl->dnames, id)){
+ if(!lvtbl->dnames){
+ lvtbl->dnames = vtable_alloc(0);
+ }
+ vtable_add(lvtbl->dnames, id);
}
- lvtbl->dnames[lvtbl->dname_size++] = id;
}
static void
@@ -8286,23 +8295,20 @@
int i;
if (in_defined) return; /* no check needed */
- for (i=0; i<lvtbl->dname_size; i++) {
- if (lvtbl->dnames[i] == id) {
+ for (i=0; i<vtable_size(lvtbl->dnames); i++) {
+ if (lvtbl->dnames->tbl[i] == id) {
rb_warnS("out-of-scope variable - %s", rb_id2name(id));
return;
}
}
}
-static struct RVarmap*
+static int
dyna_push_gen(parser)
struct parser_params *parser;
{
- struct RVarmap* vars = ruby_dyna_vars;
-
- rb_dvar_push(0, 0);
- lvtbl->dlev++;
- return vars;
+ lvtbl->dvars = vtable_alloc(lvtbl->dvars);
+ return 0;
}
static void
@@ -8310,33 +8316,60 @@
struct parser_params *parser;
struct RVarmap* vars;
{
- lvtbl->dlev--;
- ruby_dyna_vars = vars;
+ struct vtable *tmp = lvtbl->dvars;
+ lvtbl->dvars = lvtbl->dvars->prev;
+ vtable_free(tmp);
}
static int
dyna_in_block_gen(parser)
struct parser_params *parser;
{
- return (lvtbl->dlev > 0);
+ return lvtbl->dvars != 0;
}
static NODE *
-dyna_init_gen(parser, node, pre)
+dyna_init_gen(parser, node, pre_cnt)
struct parser_params *parser;
NODE *node;
- struct RVarmap *pre;
+ int pre_cnt;
{
- struct RVarmap *post = ruby_dyna_vars;
NODE *var;
+ int post_cnt = vtable_size(lvtbl->dvars);
- if (!node || !post || pre == post) return node;
- for (var = 0; post != pre && post->id; post = post->next) {
- var = NEW_DASGN_CURR(post->id, var);
+ if (!node || pre_cnt == post_cnt) return node;
+ for (var = 0; post_cnt != pre_cnt; post_cnt--) {
+ var = NEW_DASGN_CURR(lvtbl->dvars->tbl[post_cnt], var);
}
return block_append(var, node);
}
+static int
+dvar_defined_gen(parser, id)
+ struct parser_params *parser;
+ ID id;
+{
+ struct vtable *dvars = lvtbl->dvars;
+ while((VALUE)dvars & ~3){
+ if(vtable_included(dvars, id)){
+ return 1;
+ }
+ dvars = dvars->prev;
+ }
+ if((VALUE)dvars == 1){
+ return rb_dvar_defined(id);
+ }
+ return 0;
+}
+
+static int
+dvar_curr_gen(parser, id)
+ struct parser_params *parser;
+ ID id;
+{
+ return vtable_included(lvtbl->dvars, id);
+}
+
void
rb_gc_mark_parser()
{
@@ -8646,6 +8679,8 @@
return Qfalse;
}
+void rb_scope_set _((int cnt, VALUE val));
+
static void
special_local_set(c, val)
char c;
@@ -8659,7 +8694,7 @@
top_local_init();
cnt = local_cnt(c);
top_local_setup();
- ruby_scope->local_vars[cnt] = val;
+ rb_scope_set(cnt, val);
}
VALUE