From 9d61bdff146535718eb94f434c525074a031e470 Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 20 Sep 2001 06:23:50 +0000 Subject: [PATCH] * eval.c, intern.h (rb_svar): return reference to special variable from local variable index. [new] * eval.c (rb_eval): use rb_svar() for NODE_FLIP{2,3}. * parse.y (rb_(backref|lastline)_(get|set)): access via rb_svar(). * eval.c (proc_invoke): push dynamic variables. * eval.c (rb_thread_yield): push special variables as dynamic variables($_, $~ and FLIP states). * intern.h, parse.y (rb_is_local_id): return true if the ID is local symbol. [new] * parse.y (internal_id): make new ID for internal use. [new] * parse.y (cond0): allocate internal ID for NODE_FLIP{2,3}. * eval.c (rb_f_local_variables): use rb_is_local_id() to select visible local variables. * eval.c (rb_thread_start_0): SCOPE_SHARED is removed. * eval.c, intern.h (rb_thread_scope_shared_p): removed. special variables are no longer shared by threads. * re.c (rb_reg_search): MATCHDATA is no longer shared by threads. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1752 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- eval.c | 101 +++++++++++++++++++++++++++++++++++-------------------- intern.h | 3 +- parse.y | 43 +++++++++++++++++------ re.c | 7 +--- 4 files changed, 101 insertions(+), 53 deletions(-) diff --git a/eval.c b/eval.c index 8cbdb94e46..b5fcdb1597 100644 --- a/eval.c +++ b/eval.c @@ -721,6 +721,24 @@ dvar_asgn_curr(id, value) dvar_asgn_internal(id, value, 1); } +VALUE * +rb_svar(cnt) + int cnt; +{ + struct RVarmap *vars = ruby_dyna_vars; + ID id; + + if (!ruby_scope->local_tbl) return NULL; + if (cnt >= ruby_scope->local_tbl[0]) return NULL; + id = ruby_scope->local_tbl[cnt+1]; + while (vars) { + if (vars->id == id) return &vars->val; + vars = vars->next; + } + if (ruby_scope->local_vars == 0) return NULL; + return &ruby_scope->local_vars[cnt]; +} + struct iter { int iter; struct iter *prev; @@ -2536,40 +2554,41 @@ rb_eval(self, n) break; case NODE_FLIP2: /* like AWK */ - if (ruby_scope->local_vars == 0) { - rb_bug("unexpected local variable"); - } - if (!RTEST(ruby_scope->local_vars[node->nd_cnt])) { - if (RTEST(rb_eval(self, node->nd_beg))) { - ruby_scope->local_vars[node->nd_cnt] = - RTEST(rb_eval(self, node->nd_end))?Qfalse:Qtrue; - result = Qtrue; + { + VALUE *flip = rb_svar(node->nd_cnt); + if (!flip) rb_bug("unexpected local variable"); + if (!RTEST(*flip)) { + if (RTEST(rb_eval(self, node->nd_beg))) { + *flip = RTEST(rb_eval(self, node->nd_end))?Qfalse:Qtrue; + result = Qtrue; + } + else { + result = Qfalse; + } } else { - result = Qfalse; + if (RTEST(rb_eval(self, node->nd_end))) { + *flip = Qfalse; + } + result = Qtrue; } } - else { - if (RTEST(rb_eval(self, node->nd_end))) { - ruby_scope->local_vars[node->nd_cnt] = Qfalse; - } - result = Qtrue; - } break; case NODE_FLIP3: /* like SED */ - if (ruby_scope->local_vars == 0) { - rb_bug("unexpected local variable"); - } - if (!RTEST(ruby_scope->local_vars[node->nd_cnt])) { - result = RTEST(rb_eval(self, node->nd_beg)) ? Qtrue : Qfalse; - ruby_scope->local_vars[node->nd_cnt] = result; - } - else { - if (RTEST(rb_eval(self, node->nd_end))) { - ruby_scope->local_vars[node->nd_cnt] = Qfalse; + { + VALUE *flip = rb_svar(node->nd_cnt); + if (!flip) rb_bug("unexpected local variable"); + if (!RTEST(*flip)) { + result = RTEST(rb_eval(self, node->nd_beg)) ? Qtrue : Qfalse; + *flip = result; + } + else { + if (RTEST(rb_eval(self, node->nd_end))) { + *flip = Qfalse; + } + result = Qtrue; } - result = Qtrue; } break; @@ -5852,7 +5871,7 @@ rb_f_local_variables() if (tbl) { n = *tbl++; for (i=2; ilast_func) { rb_warning("block for %s#%s is useless", @@ -6425,6 +6445,7 @@ proc_invoke(proc, args, pcall) orphan = blk_orphan(data); ruby_wrapper = data->wrapper; + ruby_dyna_vars = data->dyna_vars; /* PUSH BLOCK from data */ old_block = ruby_block; _block = *data; @@ -6450,6 +6471,7 @@ proc_invoke(proc, args, pcall) } ruby_block = old_block; ruby_wrapper = old_wrapper; + ruby_dyna_vars = old_dvars; ruby_safe_level = safe; switch (state) { @@ -8254,8 +8276,6 @@ catch_timer(sig) int rb_thread_tick = THREAD_TICK; #endif -#define SCOPE_SHARED FL_USER1 - #if defined(HAVE_SETITIMER) static int thread_init = 0; @@ -8321,7 +8341,6 @@ rb_thread_start_0(fn, arg, th_arg) saved_block = ruby_block = dummy.prev; } scope_dup(ruby_scope); - FL_SET(ruby_scope, SCOPE_SHARED); if (!th->next) { /* merge in thread list */ @@ -8397,18 +8416,28 @@ rb_thread_create(fn, arg) return rb_thread_start_0(fn, arg, rb_thread_alloc(rb_cThread)); } -int -rb_thread_scope_shared_p() -{ - return FL_TEST(ruby_scope, SCOPE_SHARED); -} - static VALUE rb_thread_yield(arg, th) VALUE arg; rb_thread_t th; { + const ID *tbl; + scope_dup(ruby_block->scope); + + tbl = ruby_scope->local_tbl; + if (tbl) { + int n = *tbl++; + for (tbl += 2, n -= 2; n > 0; --n) { /* skip first 2 ($_ and $~) */ + ID id = *tbl++; + if (id != 0 && !rb_is_local_id(id)) /* push flip states */ + rb_dvar_push(id, Qfalse); + } + } + rb_dvar_push('_', Qnil); + rb_dvar_push('~', Qnil); + ruby_block->dyna_vars = ruby_dyna_vars; + return rb_yield_0(mvalue_to_svalue(arg), 0, 0, Qtrue); } diff --git a/intern.h b/intern.h index 0fcdf5ac21..4ea537c951 100644 --- a/intern.h +++ b/intern.h @@ -133,6 +133,7 @@ VALUE rb_dvar_curr _((ID)); VALUE rb_dvar_ref _((ID)); void rb_dvar_asgn _((ID, VALUE)); void rb_dvar_push _((ID, VALUE)); +VALUE *rb_svar _((int)); VALUE rb_eval_cmd _((VALUE, VALUE)); int rb_respond_to _((VALUE, ID)); void rb_interrupt _((void)); @@ -170,7 +171,6 @@ VALUE rb_thread_stop _((void)); VALUE rb_thread_wakeup _((VALUE)); VALUE rb_thread_run _((VALUE)); VALUE rb_thread_create _((VALUE (*)(ANYARGS), void*)); -int rb_thread_scope_shared_p _((void)); void rb_thread_interrupt _((void)); void rb_thread_trap_eval _((VALUE, int)); void rb_thread_signal_raise _((char*)); @@ -269,6 +269,7 @@ void rb_parser_while_loop _((int, int)); int rb_is_const_id _((ID)); int rb_is_instance_id _((ID)); int rb_is_class_id _((ID)); +int rb_is_local_id _((ID)); VALUE rb_backref_get _((void)); void rb_backref_set _((VALUE)); VALUE rb_lastline_get _((void)); diff --git a/parse.y b/parse.y index c0e14530ce..2816976a2b 100644 --- a/parse.y +++ b/parse.y @@ -30,6 +30,7 @@ #define ID_CONST 0x05 #define ID_CLASS 0x06 #define ID_JUNK 0x07 +#define ID_INTERNAL ID_JUNK #define is_notop_id(id) ((id)>LAST_TOKEN) #define is_local_id(id) (is_notop_id(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL) @@ -138,6 +139,7 @@ static int local_append(); static int local_cnt(); static int local_id(); static ID *local_tbl(); +static ID internal_id(); static struct RVarmap *dyna_push(); static void dyna_pop(); @@ -4626,7 +4628,7 @@ cond0(node) node->nd_end = range_op(node->nd_end); if (type == NODE_DOT2) nd_set_type(node,NODE_FLIP2); else if (type == NODE_DOT3) nd_set_type(node, NODE_FLIP3); - node->nd_cnt = local_append(0); + node->nd_cnt = local_append(internal_id()); warning_unless_e_option("range literal in condition"); break; @@ -5003,11 +5005,18 @@ Init_sym() rb_global_variable((VALUE*)&lex_lastline); } +static ID last_id = LAST_TOKEN; + +static ID +internal_id() +{ + return ID_INTERNAL | (++last_id << ID_SCOPE_SHIFT); +} + ID rb_intern(name) const char *name; { - static ID last_id = LAST_TOKEN; const char *m = name; ID id; int last; @@ -5162,6 +5171,14 @@ rb_is_instance_id(id) return Qfalse; } +int +rb_is_local_id(id) + ID id; +{ + if (is_local_id(id)) return Qtrue; + return Qfalse; +} + static void special_local_set(c, val) char c; @@ -5175,11 +5192,14 @@ special_local_set(c, val) ruby_scope->local_vars[cnt] = val; } +VALUE *rb_svar _((int cnt)); + VALUE rb_backref_get() { - if (ruby_scope->local_vars) { - return ruby_scope->local_vars[1]; + VALUE *var = rb_svar(1); + if (var) { + return *var; } return Qnil; } @@ -5188,8 +5208,9 @@ void rb_backref_set(val) VALUE val; { - if (ruby_scope->local_vars) { - ruby_scope->local_vars[1] = val; + VALUE *var = rb_svar(1); + if (var) { + *var = val; } else { special_local_set('~', val); @@ -5199,8 +5220,9 @@ rb_backref_set(val) VALUE rb_lastline_get() { - if (ruby_scope->local_vars) { - return ruby_scope->local_vars[0]; + VALUE *var = rb_svar(0); + if (var) { + return *var; } return Qnil; } @@ -5209,8 +5231,9 @@ void rb_lastline_set(val) VALUE val; { - if (ruby_scope->local_vars) { - ruby_scope->local_vars[0] = val; + VALUE *var = rb_svar(0); + if (var) { + *var = val; } else { special_local_set('_', val); diff --git a/re.c b/re.c index 7e57b856c1..a35851f36d 100644 --- a/re.c +++ b/re.c @@ -645,12 +645,7 @@ rb_reg_search(re, str, pos, reverse) return result; } - if (rb_thread_scope_shared_p()) { - match = Qnil; - } - else { - match = rb_backref_get(); - } + match = rb_backref_get(); if (NIL_P(match) || FL_TEST(match, MATCH_BUSY)) { match = match_alloc(); }