From 385f0e8af657b1334e477e6837b0846cc14fa00d Mon Sep 17 00:00:00 2001 From: ko1 Date: Mon, 19 May 2008 03:08:50 +0000 Subject: * vm.c, insns.def, eval.c, vm_insnhelper.c: fix CREF handling. VM value stack frame of block contains cref information. (dfp[-1] points CREF) * compile.c, eval_intern.h, eval_method.c, load.c, proc.c, vm_dump.h, vm_core.h: ditto. * include/ruby/ruby.h, gc.c: remove T_VALUES because of above changes. * bootstraptest/test_eval.rb, test_knownbug.rb: move solved test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16468 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 14 +++++ benchmark/bmx_temp.rb | 9 +++ bootstraptest/test_eval.rb | 19 ++++++ bootstraptest/test_knownbug.rb | 20 ------- compile.c | 37 ++++++------ eval.c | 131 +++++++++++------------------------------ eval_intern.h | 17 ++---- eval_method.c | 2 +- gc.c | 15 +---- include/ruby/ruby.h | 10 ---- insns.def | 20 ++++--- load.c | 6 +- proc.c | 6 -- version.h | 8 +-- vm.c | 130 +++++++++++++++++----------------------- vm_core.h | 4 +- vm_dump.c | 9 ++- vm_insnhelper.c | 109 +++++++++++++++------------------- 18 files changed, 228 insertions(+), 338 deletions(-) diff --git a/ChangeLog b/ChangeLog index 58ce5fb231..085be0630b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Mon May 19 11:32:47 2008 Koichi Sasada + + * vm.c, insns.def, eval.c, vm_insnhelper.c: fix CREF handling. + VM value stack frame of block contains cref information. + (dfp[-1] points CREF) + + * compile.c, eval_intern.h, eval_method.c, load.c, proc.c, + vm_dump.h, vm_core.h: ditto. + + * include/ruby/ruby.h, gc.c: remove T_VALUES because of above + changes. + + * bootstraptest/test_eval.rb, test_knownbug.rb: move solved test. + Sun May 18 22:26:51 2008 GOTOU Yuuzou * lib/webrick/httpservlet/filehandler.rb: should normalize path diff --git a/benchmark/bmx_temp.rb b/benchmark/bmx_temp.rb index e69de29bb2..0b4b219ca2 100644 --- a/benchmark/bmx_temp.rb +++ b/benchmark/bmx_temp.rb @@ -0,0 +1,9 @@ +def m + nil +end + +i=0 +while i<800000 # benchmark loop 2 + i+=1 + m; m; m; m; m; m; m; m; +end diff --git a/bootstraptest/test_eval.rb b/bootstraptest/test_eval.rb index a0e37b9b9a..47976a304e 100644 --- a/bootstraptest/test_eval.rb +++ b/bootstraptest/test_eval.rb @@ -208,3 +208,22 @@ assert_normal_exit %q{ end Foo.add_method }, '[ruby-core:14556] reported by Frederick Cheung' + +assert_equal 'ok', %q{ + class Module + def my_module_eval(&block) + module_eval(&block) + end + end + class String + Integer.my_module_eval do + def hoge; end + end + end + if Integer.instance_methods(false).map{|m|m.to_sym}.include?(:hoge) && + !String.instance_methods(false).map{|m|m.to_sym}.include?(:hoge) + :ok + else + :ng + end +}, "[ruby-dev:34236]" diff --git a/bootstraptest/test_knownbug.rb b/bootstraptest/test_knownbug.rb index bccb14a0e9..9041cfdbf4 100644 --- a/bootstraptest/test_knownbug.rb +++ b/bootstraptest/test_knownbug.rb @@ -136,26 +136,6 @@ assert_equal 'ok', %q{ end }, '[ruby-core:16010]' - -assert_equal 'ok', %q{ - class Module - def my_module_eval(&block) - module_eval(&block) - end - end - class String - Integer.my_module_eval do - def hoge; end - end - end - if Integer.instance_methods(false).map{|m|m.to_sym}.include?(:hoge) && - !String.instance_methods(false).map{|m|m.to_sym}.include?(:hoge) - :ok - else - :ng - end -}, "[ruby-dev:34236]" - assert_equal 'ok', %q{ def m t = Thread.new { while true do // =~ "" end } diff --git a/compile.c b/compile.c index 10476081fe..5e2400a2c2 100644 --- a/compile.c +++ b/compile.c @@ -280,7 +280,7 @@ iseq_compile(VALUE self, NODE *node) } if (iseq->type == ISEQ_TYPE_RESCUE || iseq->type == ISEQ_TYPE_ENSURE) { - ADD_INSN2(ret, 0, getdynamic, INT2FIX(1), INT2FIX(0)); + ADD_INSN2(ret, 0, getdynamic, INT2FIX(2), INT2FIX(0)); ADD_INSN1(ret, 0, throw, INT2FIX(0) /* continue throw */ ); } else { @@ -771,7 +771,8 @@ iseq_set_exception_local_table(rb_iseq_t *iseq) id_dollar_bang = rb_intern("#$!"); } iseq->local_table = (ID *)ALLOC_N(ID *, 1); - iseq->local_table_size = iseq->local_size = 1; + iseq->local_table_size = 1; + iseq->local_size = iseq->local_table_size + 1; iseq->local_table[0] = id_dollar_bang; return COMPILE_OK; } @@ -992,12 +993,14 @@ iseq_set_local_table(rb_iseq_t *iseq, ID *tbl) } iseq->local_size = iseq->local_table_size = size; - - if (iseq->type == ISEQ_TYPE_METHOD || - iseq->type == ISEQ_TYPE_CLASS || - iseq->type == ISEQ_TYPE_TOP) { - iseq->local_size += 1 /* svar */; - } + iseq->local_size += 1; + /* + if (lfp == dfp ) { // top, class, method + dfp[-1]: svar + else { // block + dfp[-1]: cref + } + */ debugs("iseq_set_local_table: %d, %d\n", iseq->local_size, iseq->local_table_size); return COMPILE_OK; @@ -3264,8 +3267,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) case NODE_ARRAY: while (narg) { COMPILE(ret, "rescue arg", narg->nd_head); - ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1), - INT2FIX(0)); + ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0)); ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1)); ADD_INSNL(ret, nd_line(node), branchif, label_hit); narg = narg->nd_next; @@ -3274,8 +3276,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) case NODE_SPLAT: case NODE_ARGSCAT: case NODE_ARGSPUSH: - ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1), - INT2FIX(0)); + ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0)); COMPILE(ret, "rescue/cond splat", narg); ADD_INSN1(ret, nd_line(node), checkincludearray, Qtrue); ADD_INSN(ret, nd_line(node), swap); @@ -3290,8 +3291,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) else { ADD_INSN1(ret, nd_line(node), putobject, rb_eStandardError); - ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1), - INT2FIX(0)); + ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0)); ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1)); ADD_INSNL(ret, nd_line(node), branchif, label_hit); } @@ -4012,8 +4012,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) if (idx < 0) { rb_bug("unknown dvar (%s)", rb_id2name(node->nd_vid)); } - ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(ls - idx), - INT2FIX(lv)); + ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(ls - idx), INT2FIX(lv)); } break; } @@ -4485,8 +4484,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) case NODE_ERRINFO:{ if (!poped) { if (iseq->type == ISEQ_TYPE_RESCUE) { - ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1), - INT2FIX(0)); + ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0)); } else { rb_iseq_t *ip = iseq; @@ -4499,8 +4497,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) level++; } if (ip) { - ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1), - INT2FIX(level)); + ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(level)); } else { ADD_INSN(ret, nd_line(node), putnil); diff --git a/eval.c b/eval.c index f79854d0e9..a224744ac0 100644 --- a/eval.c +++ b/eval.c @@ -32,7 +32,7 @@ VALUE sysstack_error; static VALUE exception_error; -static VALUE eval(VALUE, VALUE, VALUE, const char *, int); +static VALUE eval_string(VALUE, VALUE, VALUE, const char *, int); static inline VALUE rb_yield_0(int argc, VALUE *argv); static VALUE rb_call(VALUE, VALUE, ID, int, const VALUE *, int); @@ -264,7 +264,7 @@ ruby_run_node(void *n) VALUE rb_eval_string(const char *str) { - return eval(rb_vm_top_self(), rb_str_new2(str), Qnil, "(eval)", 1); + return eval_string(rb_vm_top_self(), rb_str_new2(str), Qnil, "(eval)", 1); } VALUE @@ -329,7 +329,7 @@ rb_eval_cmd(VALUE cmd, VALUE arg, int level) PUSH_TAG(); if ((state = EXEC_TAG()) == 0) { - val = eval(rb_vm_top_self(), cmd, Qnil, 0, 0); + val = eval_string(rb_vm_top_self(), cmd, Qnil, 0, 0); } POP_TAG(); @@ -884,11 +884,12 @@ rb_iterator_p() VALUE -rb_f_block_given_p() +rb_f_block_given_p(void) { rb_thread_t *th = GET_THREAD(); rb_control_frame_t *cfp = th->cfp; cfp = vm_get_ruby_level_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)); + if (GC_GUARDED_PTR_REF(cfp->lfp[0])) { return Qtrue; } @@ -1681,7 +1682,7 @@ rb_frame_self(void) } static VALUE -eval(VALUE self, VALUE src, VALUE scope, const char *file, int line) +eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char *file, int line) { int state; VALUE result = Qundef; @@ -1689,7 +1690,7 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line) rb_binding_t *bind = 0; rb_thread_t *th = GET_THREAD(); rb_env_t *env = NULL; - NODE *stored_cref_stack = 0; + rb_block_t block; if (file == 0) { file = rb_sourcefile(); @@ -1705,7 +1706,6 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line) if (rb_obj_is_kind_of(scope, rb_cBinding)) { GetBindingPtr(scope, bind); envval = bind->env; - stored_cref_stack = bind->cref_stack; } else { rb_raise(rb_eTypeError, @@ -1717,7 +1717,9 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line) } else { rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp); - th->base_block = RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp); + block = *RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp); + th->base_block = █ + th->base_block->self = self; th->base_block->iseq = cfp->iseq; /* TODO */ } @@ -1725,7 +1727,8 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line) th->parse_in_eval++; iseqval = rb_iseq_compile(src, rb_str_new2(file), INT2FIX(line)); th->parse_in_eval--; - rb_vm_set_eval_stack(th, iseqval); + + rb_vm_set_eval_stack(th, iseqval, cref); th->base_block = 0; if (0) { /* for debug */ @@ -1739,22 +1742,12 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line) bind->env = vm_make_env_object(th, th->cfp); } - /* push tag */ - if (stored_cref_stack) { - stored_cref_stack = - vm_set_special_cref(th, env->block.lfp, stored_cref_stack); - } - /* kick */ CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max); result = vm_eval_body(th); } POP_TAG(); - if (stored_cref_stack) { - vm_set_special_cref(th, env->block.lfp, stored_cref_stack); - } - if (state) { if (state == TAG_RAISE) { VALUE errinfo = th->errinfo; @@ -1779,6 +1772,12 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line) return result; } +static VALUE +eval_string(VALUE self, VALUE src, VALUE scope, const char *file, int line) +{ + return eval_string_with_cref(self, src, scope, 0, file, line); +} + /* * call-seq: * eval(string [, binding [, filename [,lineno]]]) => obj @@ -1825,90 +1824,36 @@ rb_f_eval(int argc, VALUE *argv, VALUE self) if (!NIL_P(vfile)) file = RSTRING_PTR(vfile); - return eval(self, src, scope, file, line); + return eval_string(self, src, scope, file, line); } -VALUE vm_cfp_svar_get(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key); -void vm_cfp_svar_set(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key, VALUE val); - -/* function to call func under the specified class/module context */ +/* block eval under the class/module context */ static VALUE -exec_under(VALUE (*func) (VALUE), VALUE under, VALUE self, VALUE args) +yield_under(VALUE under, VALUE self, VALUE values) { - VALUE val = Qnil; /* OK */ rb_thread_t *th = GET_THREAD(); - rb_control_frame_t *cfp = th->cfp; - rb_control_frame_t *pcfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); - VALUE stored_self = pcfp->self; - NODE *stored_cref = 0; - - rb_block_t block; - rb_block_t *blockptr; - int state; + rb_block_t block, *blockptr; + NODE *cref = vm_cref_push(th, under, NOEX_PUBLIC); - /* replace environment */ - pcfp->self = self; - if ((blockptr = GC_GUARDED_PTR_REF(*th->cfp->lfp)) != 0) { - /* copy block info */ - /* TODO: why? */ + if ((blockptr = GC_GUARDED_PTR_REF(th->cfp->lfp[0])) != 0) { block = *blockptr; block.self = self; - *th->cfp->lfp = GC_GUARDED_PTR(&block); + th->cfp->lfp[0] = GC_GUARDED_PTR(&block); } - while (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) { - cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); - } - - stored_cref = (NODE *)vm_cfp_svar_get(th, cfp, 2); - vm_cfp_svar_set(th, cfp, 2, (VALUE)vm_cref_push(th, under, NOEX_PUBLIC)); - - PUSH_TAG(); - if ((state = EXEC_TAG()) == 0) { - val = (*func) (args); - } - POP_TAG(); - - /* restore environment */ - vm_cfp_svar_set(th, cfp, 2, (VALUE)stored_cref); - pcfp->self = stored_self; - - if (state) { - JUMP_TAG(state); - } - return val; -} - -static VALUE -yield_under_i(VALUE arg) -{ - if (arg == Qundef) { - return rb_yield_0(0, 0); + if (values == Qundef) { + return vm_yield_with_cref(th, 0, 0, cref); } else { - return rb_yield_0(RARRAY_LEN(arg), RARRAY_PTR(arg)); + return vm_yield_with_cref(th, RARRAY_LEN(values), RARRAY_PTR(values), cref); } } -/* block eval under the class/module context */ -static VALUE -yield_under(VALUE under, VALUE self, VALUE values) -{ - return exec_under(yield_under_i, under, self, values); -} - -static VALUE -eval_under_i(VALUE arg) -{ - VALUE *args = (VALUE *)arg; - return eval(args[0], args[1], Qnil, (char *)args[2], (int)args[3]); -} - /* string eval under the class/module context */ static VALUE eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line) { - VALUE args[4]; + NODE *cref = vm_cref_push(GET_THREAD(), under, NOEX_PUBLIC); if (rb_safe_level() >= 4) { StringValue(src); @@ -1916,11 +1861,8 @@ eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line) else { SafeStringValue(src); } - args[0] = self; - args[1] = src; - args[2] = (VALUE)file; - args[3] = (VALUE)line; - return exec_under(eval_under_i, under, self, (VALUE)args); + + return eval_string_with_cref(self, src, Qnil, cref, file, line); } static VALUE @@ -1928,8 +1870,7 @@ specific_eval(int argc, VALUE *argv, VALUE klass, VALUE self) { if (rb_block_given_p()) { if (argc > 0) { - rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", - argc); + rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc); } return yield_under(klass, self, Qundef); } @@ -2499,12 +2440,12 @@ errinfo_place(void) while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) { if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) { if (cfp->iseq->type == ISEQ_TYPE_RESCUE) { - return &cfp->dfp[-1]; + return &cfp->dfp[-2]; } else if (cfp->iseq->type == ISEQ_TYPE_ENSURE && - TYPE(cfp->dfp[-1]) != T_NODE && - !FIXNUM_P(cfp->dfp[-1])) { - return &cfp->dfp[-1]; + TYPE(cfp->dfp[-2]) != T_NODE && + !FIXNUM_P(cfp->dfp[-2])) { + return &cfp->dfp[-2]; } } cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); diff --git a/eval_intern.h b/eval_intern.h index c53cc32330..d4949822d7 100644 --- a/eval_intern.h +++ b/eval_intern.h @@ -225,11 +225,12 @@ NORETURN(void rb_print_undef(VALUE, ID, int)); NORETURN(void vm_localjump_error(const char *, VALUE, int)); NORETURN(void vm_jump_tag_but_local_jump(int, VALUE)); -NODE *vm_get_cref(rb_thread_t *th, rb_iseq_t *iseq, rb_control_frame_t *cfp); NODE *vm_cref_push(rb_thread_t *th, VALUE, int); NODE *vm_set_special_cref(rb_thread_t *th, VALUE *lfp, NODE * cref_stack); VALUE vm_make_jump_tag_but_local_jump(int state, VALUE val); +NODE *ruby_cref(void); + static rb_control_frame_t * vm_get_ruby_level_cfp(rb_thread_t *th, rb_control_frame_t *cfp) { @@ -242,22 +243,12 @@ vm_get_ruby_level_cfp(rb_thread_t *th, rb_control_frame_t *cfp) return 0; } -static inline NODE * -ruby_cref() -{ - rb_thread_t *th = GET_THREAD(); - rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp); - return vm_get_cref(th, cfp->iseq, cfp); -} - -VALUE vm_get_cbase(rb_thread_t *th); VALUE rb_obj_is_proc(VALUE); void rb_vm_check_redefinition_opt_method(NODE *node); VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, rb_block_t *blockptr, VALUE filename); void rb_thread_terminate_all(void); -void rb_vm_set_eval_stack(rb_thread_t *, VALUE iseq); +void rb_vm_set_eval_stack(rb_thread_t *, VALUE iseq, NODE *cref); VALUE rb_vm_top_self(); - -#define ruby_cbase() vm_get_cbase(GET_THREAD()) +VALUE rb_vm_cbase(void); #endif /* RUBY_EVAL_INTERN_H */ diff --git a/eval_method.c b/eval_method.c index 4a3f560939..de315a6682 100644 --- a/eval_method.c +++ b/eval_method.c @@ -463,7 +463,7 @@ rb_undef(VALUE klass, ID id) VALUE origin; NODE *body; - if (ruby_cbase() == rb_cObject && klass == rb_cObject) { + if (rb_vm_cbase() == rb_cObject && klass == rb_cObject) { rb_secure(4); } if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) { diff --git a/gc.c b/gc.c index 91e778f485..bcb671f700 100644 --- a/gc.c +++ b/gc.c @@ -1280,15 +1280,6 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev) } break; - case T_VALUES: - { - rb_gc_mark(RVALUES(obj)->v1); - rb_gc_mark(RVALUES(obj)->v2); - ptr = RVALUES(obj)->v3; - goto again; - } - break; - default: rb_bug("rb_gc_mark(): unknown data type 0x%lx(%p) %s", obj->as.basic.flags & T_MASK, obj, @@ -1531,8 +1522,6 @@ obj_free(rb_objspace_t *objspace, VALUE obj) case T_FLOAT: break; - case T_VALUES: - break; case T_BIGNUM: if (!(RBASIC(obj)->flags & RBIGNUM_EMBED_FLAG) && RBIGNUM_DIGITS(obj)) { @@ -1878,7 +1867,6 @@ os_obj_of(rb_objspace_t *objspace, VALUE of) case T_NONE: case T_ICLASS: case T_NODE: - case T_VALUES: continue; case T_CLASS: if (FL_TEST(p, FL_SINGLETON)) continue; @@ -2175,7 +2163,7 @@ id2ref(VALUE obj, VALUE objid) } if (!is_pointer_to_heap(objspace, (void *)ptr) || - BUILTIN_TYPE(ptr) >= T_VALUES || BUILTIN_TYPE(ptr) == T_ICLASS) { + BUILTIN_TYPE(ptr) > T_FIXNUM || BUILTIN_TYPE(ptr) == T_ICLASS) { rb_raise(rb_eRangeError, "%p is not id value", p0); } if (BUILTIN_TYPE(ptr) == 0 || RBASIC(ptr)->klass == 0) { @@ -2334,7 +2322,6 @@ count_objects(int argc, VALUE *argv, VALUE os) COUNT_TYPE(T_FALSE); COUNT_TYPE(T_SYMBOL); COUNT_TYPE(T_FIXNUM); - COUNT_TYPE(T_VALUES); COUNT_TYPE(T_UNDEF); COUNT_TYPE(T_NODE); COUNT_TYPE(T_ICLASS); diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h index 5707571cfa..0d146fbbce 100644 --- a/include/ruby/ruby.h +++ b/include/ruby/ruby.h @@ -262,7 +262,6 @@ enum ruby_value_type { RUBY_T_SYMBOL = 0x14, RUBY_T_FIXNUM = 0x15, - RUBY_T_VALUES = 0x1a, RUBY_T_UNDEF = 0x1b, RUBY_T_NODE = 0x1c, RUBY_T_ICLASS = 0x1d, @@ -292,7 +291,6 @@ enum ruby_value_type { #define T_SYMBOL RUBY_T_SYMBOL #define T_RATIONAL RUBY_T_RATIONAL #define T_COMPLEX RUBY_T_COMPLEX -#define T_VALUES RUBY_T_VALUES #define T_UNDEF RUBY_T_UNDEF #define T_NODE RUBY_T_NODE #define T_MASK RUBY_T_MASK @@ -438,13 +436,6 @@ struct RObject { RCLASS_IV_INDEX_TBL(rb_obj_class(o)) : \ ROBJECT(o)->as.heap.iv_index_tbl) -struct RValues { - struct RBasic basic; - VALUE v1; - VALUE v2; - VALUE v3; -}; - typedef struct { VALUE super; struct st_table *iv_tbl; @@ -654,7 +645,6 @@ struct RBignum { #define RFILE(obj) (R_CAST(RFile)(obj)) #define RRATIONAL(obj) (R_CAST(RRational)(obj)) #define RCOMPLEX(obj) (R_CAST(RComplex)(obj)) -#define RVALUES(obj) (R_CAST(RValues)(obj)) #define FL_SINGLETON FL_USER0 #define FL_MARK (((VALUE)1)<<5) diff --git a/insns.def b/insns.def index 7723874c6c..43172efda9 100644 --- a/insns.def +++ b/insns.def @@ -183,7 +183,8 @@ getclassvariable () (VALUE val) { - val = rb_cvar_get(vm_get_cvar_base(th, GET_ISEQ()), id); + NODE *cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP()); + val = rb_cvar_get(vm_get_cvar_base(cref), id); } /** @@ -197,7 +198,8 @@ setclassvariable (VALUE val) () { - rb_cvar_set(vm_get_cvar_base(th, GET_ISEQ()), id, val); + NODE *cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP()); + rb_cvar_set(vm_get_cvar_base(cref), id, val); } /** @@ -317,7 +319,7 @@ putcbase () (VALUE val) { - val = vm_get_cbase(th); + val = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP()); } /** @@ -723,8 +725,8 @@ definemethod (VALUE obj) () { - vm_define_method(th, obj, id, body, is_singleton, - get_cref(GET_ISEQ(), GET_LFP())); + NODE *cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP()); + vm_define_method(th, obj, id, body, is_singleton, cref); } /** @@ -744,7 +746,7 @@ alias rb_alias_variable(SYM2ID(sym1), SYM2ID(sym2)); } else { - klass = get_cref(GET_ISEQ(), GET_LFP())->nd_clss; + klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP()); rb_alias(klass, SYM2ID(sym1), SYM2ID(sym2)); } } @@ -760,7 +762,7 @@ undef (VALUE sym) () { - VALUE klass = get_cref(GET_ISEQ(), GET_LFP())->nd_clss; + VALUE klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP()); rb_undef(klass, SYM2ID(sym)); INC_VM_STATE_VERSION(); } @@ -787,7 +789,7 @@ defined } break; case DEFINED_IVAR2: - klass = get_cref(GET_ISEQ(), GET_LFP())->nd_clss; + klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP()); break; case DEFINED_GVAR: if (rb_gvar_defined((struct global_entry *)(obj & ~1))) { @@ -795,7 +797,7 @@ defined } break; case DEFINED_CVAR: - klass = get_cref(GET_ISEQ(), GET_LFP())->nd_clss; + klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP()); if (rb_cvar_defined(klass, SYM2ID(obj))) { expr_type = "class variable"; } diff --git a/load.c b/load.c index 154572d80a..f91768c31a 100644 --- a/load.c +++ b/load.c @@ -650,7 +650,7 @@ rb_mod_autoload_p(VALUE mod, VALUE sym) static VALUE rb_f_autoload(VALUE obj, VALUE sym, VALUE file) { - VALUE klass = ruby_cbase(); + VALUE klass = rb_vm_cbase(); if (NIL_P(klass)) { rb_raise(rb_eTypeError, "Can not set autoload on singleton class"); } @@ -664,8 +664,8 @@ rb_f_autoload(VALUE obj, VALUE sym, VALUE file) static VALUE rb_f_autoload_p(VALUE obj, VALUE sym) { - /* use ruby_cbase() as same as rb_f_autoload. */ - VALUE klass = ruby_cbase(); + /* use rb_vm_cbase() as same as rb_f_autoload. */ + VALUE klass = rb_vm_cbase(); if (NIL_P(klass)) { return Qnil; } diff --git a/proc.c b/proc.c index 57109eff73..2ac261c789 100644 --- a/proc.c +++ b/proc.c @@ -50,7 +50,6 @@ proc_mark(void *ptr) proc = ptr; RUBY_MARK_UNLESS_NULL(proc->envval); RUBY_MARK_UNLESS_NULL(proc->blockprocval); - RUBY_MARK_UNLESS_NULL((VALUE)proc->special_cref_stack); RUBY_MARK_UNLESS_NULL(proc->block.proc); RUBY_MARK_UNLESS_NULL(proc->block.self); if (proc->block.iseq && RUBY_VM_IFUNC_P(proc->block.iseq)) { @@ -94,7 +93,6 @@ proc_dup(VALUE self) dst->block.proc = procval; dst->envval = src->envval; dst->safe_level = dst->safe_level; - dst->special_cref_stack = src->special_cref_stack; dst->is_lambda = src->is_lambda; return procval; @@ -241,7 +239,6 @@ binding_mark(void *ptr) if (ptr) { bind = ptr; RUBY_MARK_UNLESS_NULL(bind->env); - RUBY_MARK_UNLESS_NULL((VALUE)bind->cref_stack); } RUBY_MARK_LEAVE("binding"); } @@ -264,7 +261,6 @@ binding_dup(VALUE self) GetBindingPtr(self, src); GetBindingPtr(bindval, dst); dst->env = src->env; - dst->cref_stack = src->cref_stack; return bindval; } @@ -286,7 +282,6 @@ rb_binding_new(void) GetBindingPtr(bindval, bind); bind->env = vm_make_env_object(th, cfp); - bind->cref_stack = ruby_cref(); return bindval; } @@ -1587,7 +1582,6 @@ proc_binding(VALUE self) } bind->env = proc->envval; - bind->cref_stack = proc->special_cref_stack; return bindval; } diff --git a/version.h b/version.h index e131064ff3..7870b2492a 100644 --- a/version.h +++ b/version.h @@ -1,7 +1,7 @@ #define RUBY_VERSION "1.9.0" -#define RUBY_RELEASE_DATE "2008-05-18" +#define RUBY_RELEASE_DATE "2008-05-19" #define RUBY_VERSION_CODE 190 -#define RUBY_RELEASE_CODE 20080518 +#define RUBY_RELEASE_CODE 20080519 #define RUBY_PATCHLEVEL 0 #define RUBY_VERSION_MAJOR 1 @@ -9,7 +9,7 @@ #define RUBY_VERSION_TEENY 0 #define RUBY_RELEASE_YEAR 2008 #define RUBY_RELEASE_MONTH 5 -#define RUBY_RELEASE_DAY 18 +#define RUBY_RELEASE_DAY 19 #ifdef RUBY_EXTERN RUBY_EXTERN const char ruby_version[]; @@ -46,7 +46,7 @@ RUBY_EXTERN const char ruby_copyright[]; # define RUBY_DESCRIPTION \ "ruby "RUBY_VERSION \ - " ("RUBY_RELEASE_DATE" " \ + "2008-05-19" \ RUBY_RELEASE_STR" " \ STRINGIZE(RUBY_RELEASE_NUM)") " \ "["RUBY_PLATFORM"]" diff --git a/vm.c b/vm.c index f29a1e221e..f5038462fb 100644 --- a/vm.c +++ b/vm.c @@ -79,7 +79,7 @@ rb_vm_set_top_stack(rb_thread_t *th, VALUE iseqval) } void -rb_vm_set_eval_stack(rb_thread_t *th, VALUE iseqval) +rb_vm_set_eval_stack(rb_thread_t *th, VALUE iseqval, NODE *cref) { rb_iseq_t *iseq; rb_block_t *block = th->base_block; @@ -90,6 +90,10 @@ rb_vm_set_eval_stack(rb_thread_t *th, VALUE iseqval) vm_push_frame(th, iseq, FRAME_MAGIC_EVAL, block->self, GC_GUARDED_PTR(block->dfp), iseq->iseq_encoded, th->cfp->sp, block->lfp, iseq->local_size); + + if (cref) { + th->cfp->dfp[-1] = (VALUE)cref; + } } /* Env */ @@ -263,12 +267,6 @@ vm_make_env_each(rb_thread_t *th, rb_control_frame_t *cfp, env->block.dfp = cfp->dfp; env->block.iseq = cfp->iseq; - if (VMDEBUG && - (!(cfp->lfp[-1] == Qnil || - BUILTIN_TYPE(cfp->lfp[-1]) == T_VALUES))) { - rb_bug("invalid svar"); - } - if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) { /* TODO */ env->block.iseq = 0; @@ -389,7 +387,6 @@ vm_make_proc(rb_thread_t *th, proc->block.proc = procval; proc->envval = envval; proc->safe_level = th->safe_level; - proc->special_cref_stack = lfp_get_special_cref(block->lfp); if (VMDEBUG) { if (th->stack < block->dfp && block->dfp < th->stack + th->stack_size) { @@ -540,8 +537,8 @@ rb_call_super(int argc, const VALUE *argv) /* C -> Ruby: block */ static VALUE -invoke_block(rb_thread_t *th, rb_block_t *block, VALUE self, - int argc, VALUE *argv, rb_block_t *blockptr) +invoke_block_from_c(rb_thread_t *th, rb_block_t *block, VALUE self, + int argc, VALUE *argv, rb_block_t *blockptr, NODE *cref) { VALUE val; if (BUILTIN_TYPE(block->iseq) != T_NODE) { @@ -566,6 +563,7 @@ invoke_block(rb_thread_t *th, rb_block_t *block, VALUE self, self, GC_GUARDED_PTR(block->dfp), iseq->iseq_encoded + opt_pc, cfp->sp + arg_size, block->lfp, iseq->local_size - arg_size); + th->cfp->dfp[-1] = (VALUE)cref; val = vm_eval_body(th); } @@ -576,7 +574,7 @@ invoke_block(rb_thread_t *th, rb_block_t *block, VALUE self, } VALUE -vm_yield(rb_thread_t *th, int argc, VALUE *argv) +vm_yield_with_cref(rb_thread_t *th, int argc, VALUE *argv, NODE *cref) { rb_block_t *block = GC_GUARDED_PTR_REF(th->cfp->lfp[0]); @@ -584,7 +582,13 @@ vm_yield(rb_thread_t *th, int argc, VALUE *argv) vm_localjump_error("no block given", Qnil, 0); } - return invoke_block(th, block, block->self, argc, argv, 0); + return invoke_block_from_c(th, block, block->self, argc, argv, 0, cref); +} + +VALUE +vm_yield(rb_thread_t *th, int argc, VALUE *argv) +{ + return vm_yield_with_cref(th, argc, argv, (NODE *)Qnil); } VALUE @@ -594,14 +598,12 @@ vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE val = Qundef; int state; volatile int stored_safe = th->safe_level; - volatile NODE *stored_special_cref_stack = - lfp_set_special_cref(proc->block.lfp, proc->special_cref_stack); rb_control_frame_t * volatile cfp = th->cfp; TH_PUSH_TAG(th); if ((state = EXEC_TAG()) == 0) { th->safe_level = proc->safe_level; - val = invoke_block(th, &proc->block, self, argc, argv, blockptr); + val = invoke_block_from_c(th, &proc->block, self, argc, argv, blockptr, (NODE *)Qnil); } TH_POP_TAG(); @@ -609,8 +611,6 @@ vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, th->safe_level = stored_safe; } - lfp_set_special_cref(proc->block.lfp, (NODE*)stored_special_cref_stack); - if (state) { if (state == TAG_RETURN && proc->is_lambda) { VALUE err = th->errinfo; @@ -773,8 +773,6 @@ vm_backtrace(rb_thread_t *th, int lev) return ary; } -/* cref */ - static void check_svar(void) { @@ -783,7 +781,7 @@ check_svar(void) while ((void *)(cfp + 1) < (void *)(th->stack + th->stack_size)) { /* printf("cfp: %p\n", cfp->type); */ if (cfp->lfp && cfp->lfp[-1] != Qnil && - TYPE(cfp->lfp[-1]) != T_VALUES) { + TYPE(cfp->lfp[-1]) != T_NODE) { /* dp(cfp->lfp[-1]); */ rb_bug("!!!invalid svar!!!"); } @@ -791,30 +789,12 @@ check_svar(void) } } -static NODE * -lfp_set_special_cref(VALUE *lfp, NODE * cref) -{ - struct RValues *values = (void *) lfp[-1]; - NODE *old_cref; - - if (VMDEBUG) { - check_svar(); - } - - if (cref == 0 && ((VALUE)values == Qnil || values->basic.klass == 0)) { - old_cref = 0; - } - else { - old_cref = (NODE *)lfp_svar_get(GET_THREAD(), lfp, 2); - lfp_svar_set(GET_THREAD(), lfp, 2, (VALUE)cref); - } - return old_cref; -} - NODE * -vm_set_special_cref(rb_thread_t *th, VALUE *lfp, NODE * cref_stack) +ruby_cref(void) { - return lfp_set_special_cref(lfp, cref_stack); + rb_thread_t *th = GET_THREAD(); + rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp); + return vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp); } #if 0 @@ -829,12 +809,6 @@ debug_cref(NODE *cref) } #endif -NODE * -vm_get_cref(rb_thread_t *th, rb_iseq_t *iseq, rb_control_frame_t *cfp) -{ - return get_cref(iseq, cfp->lfp); -} - NODE * vm_cref_push(rb_thread_t *th, VALUE klass, int noex) { @@ -842,16 +816,15 @@ vm_cref_push(rb_thread_t *th, VALUE klass, int noex) rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp); cref->nd_file = 0; - cref->nd_next = get_cref(cfp->iseq, cfp->lfp); + cref->nd_next = vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp); cref->nd_visi = noex; return cref; } -VALUE -vm_get_cbase(rb_thread_t *th) +static inline VALUE +vm_get_cbase(rb_iseq_t *iseq, VALUE *lfp, VALUE *dfp) { - rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp); - NODE *cref = get_cref(cfp->iseq, cfp->lfp); + NODE *cref = vm_get_cref(iseq, lfp, dfp); VALUE klass = Qundef; while (cref) { @@ -860,9 +833,18 @@ vm_get_cbase(rb_thread_t *th) } cref = cref->nd_next; } + return klass; } +VALUE +rb_vm_cbase(void) +{ + rb_thread_t *th = GET_THREAD(); + rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp); + return vm_get_cbase(cfp->iseq, cfp->lfp, cfp->dfp); +} + /* jump */ static VALUE @@ -1038,16 +1020,16 @@ vm_init_redefined_flag(void) C1 : pushed by send insn (CFUNC) struct CONTROL_FRAME { - VALUE *pc; // cfp[0] - VALUE *sp; // cfp[1] - VALUE *bp; // cfp[2] - rb_iseq_t *iseq; // cfp[3] - VALUE flag; // cfp[4] - VALUE self; // cfp[5] - VALUE *lfp; // cfp[6] - VALUE *dfp; // cfp[7] - rb_iseq_t * block_iseq; // cfp[8] - VALUE proc; // cfp[9] always 0 + VALUE *pc; // cfp[0], program counter + VALUE *sp; // cfp[1], stack pointer + VALUE *bp; // cfp[2], base pointer + rb_iseq_t *iseq; // cfp[3], iseq + VALUE flag; // cfp[4], magic + VALUE self; // cfp[5], self + VALUE *lfp; // cfp[6], local frame pointer + VALUE *dfp; // cfp[7], dynamic frame pointer + rb_iseq_t * block_iseq; // cfp[8], block iseq + VALUE proc; // cfp[9], always 0 }; struct BLOCK { @@ -1055,15 +1037,11 @@ vm_init_redefined_flag(void) VALUE *lfp; VALUE *dfp; rb_iseq_t *block_iseq; - }; - - struct PROC { - VALUE proc_sig = 0; - struct BLOCK; + VALUE proc; }; struct METHOD_CONTROL_FRAME { - struct CONTROL_FRAME; + rb_control_frame_t frame; }; struct METHOD_FRAME { @@ -1073,12 +1051,13 @@ vm_init_redefined_flag(void) VALUE param0; ... VALUE paramN; + VALUE cref; VALUE special; // lfp [1] struct block_object *block_ptr | 0x01; // lfp [0] }; struct BLOCK_CONTROL_FRAME { - struct STACK_FRAME; + rb_control_frame_t frame; }; struct BLOCK_FRAME { @@ -1088,17 +1067,19 @@ vm_init_redefined_flag(void) VALUE param0; ... VALUE paramN; + VALUE cref; VALUE *(prev_ptr | 0x01); // DFP[0] }; struct CLASS_CONTROL_FRAME { - struct STACK_FRAME; + rb_control_frame_t frame; }; struct CLASS_FRAME { VALUE param0; ... VALUE paramN; + VALUE cref; VALUE prev_dfp; // for frame jump }; @@ -1125,11 +1106,6 @@ vm_init_redefined_flag(void) VALUE *dfp; // lfp rb_iseq_t * block_iseq; // 0 }; - - struct C_METHDO_FRAME{ - VALUE block_ptr; - VALUE special; - }; */ @@ -1315,7 +1291,7 @@ vm_eval_body(rb_thread_t *th) cfp->sp[0] = err; vm_push_frame(th, catch_iseq, FRAME_MAGIC_BLOCK, cfp->self, (VALUE)cfp->dfp, catch_iseq->iseq_encoded, - cfp->sp + 1, cfp->lfp, catch_iseq->local_size - 1); + cfp->sp + 1 /* push value */, cfp->lfp, catch_iseq->local_size - 1); state = 0; th->errinfo = Qnil; diff --git a/vm_core.h b/vm_core.h index 19a52eeeff..a6699ce1ad 100644 --- a/vm_core.h +++ b/vm_core.h @@ -497,8 +497,6 @@ typedef struct { int safe_level; int is_from_method; int is_lambda; - - NODE *special_cref_stack; } rb_proc_t; #define GetEnvPtr(obj, ptr) \ @@ -517,7 +515,6 @@ typedef struct { typedef struct { VALUE env; - NODE *cref_stack; } rb_binding_t; @@ -614,6 +611,7 @@ VALUE vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp); VALUE vm_backtrace(rb_thread_t *, int); VALUE vm_yield(rb_thread_t *th, int argc, VALUE *argv); +VALUE vm_yield_with_cref(rb_thread_t *th, int argc, VALUE *argv, NODE *cref); VALUE vm_call0(rb_thread_t *th, VALUE klass, VALUE recv, VALUE id, ID oid, int argc, const VALUE *argv, NODE *body, int nosuper); diff --git a/vm_dump.c b/vm_dump.c index d3e1e423a5..a0c6db5759 100644 --- a/vm_dump.c +++ b/vm_dump.c @@ -140,7 +140,7 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp) void vm_stack_dump_raw(rb_thread_t *th, rb_control_frame_t *cfp) { -#if 0 +#if 1 VALUE *sp = cfp->sp, *bp = cfp->bp; VALUE *lfp = cfp->lfp; VALUE *dfp = cfp->dfp; @@ -174,6 +174,13 @@ vm_stack_dump_raw(rb_thread_t *th, rb_control_frame_t *cfp) fprintf(stderr, "---------------------------\n"); } +void +vm_stack_dump_raw_current(void) +{ + rb_thread_t *th = GET_THREAD(); + vm_stack_dump_raw(th, th->cfp); +} + void env_dump_raw(rb_env_t *env, VALUE *lfp, VALUE *dfp) { diff --git a/vm_insnhelper.c b/vm_insnhelper.c index ddd060e18b..eb7c218f6d 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -29,6 +29,8 @@ vm_push_frame(rb_thread_t *th, rb_iseq_t *iseq, VALUE type, rb_control_frame_t *cfp; int i; + /* setup vm value stack */ + /* nil initialize */ for (i=0; i < local_size; i++) { *sp = Qnil; @@ -43,6 +45,8 @@ vm_push_frame(rb_thread_t *th, rb_iseq_t *iseq, VALUE type, lfp = sp; } + /* setup vm control frame stack */ + cfp = th->cfp = th->cfp - 1; cfp->pc = pc; cfp->sp = sp + 1; @@ -827,45 +831,24 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_n } } -/* cref */ - -static NODE * -lfp_get_special_cref(VALUE *lfp) -{ - struct RValues *values; - if (((VALUE)(values = (void *)lfp[-1])) != Qnil && values->basic.klass) { - return (NODE *)values->basic.klass; - } - else { - return 0; - } -} - -static struct RValues * -new_value(void) -{ - struct RValues *val = RVALUES(rb_newobj()); - OBJSETUP(val, 0, T_VALUES); - val->v1 = val->v2 = val->v3 = Qnil; - return val; -} +/* svar */ -static struct RValues * +static inline NODE * lfp_svar_place(rb_thread_t *th, VALUE *lfp) { - struct RValues *svar; + NODE *svar; if (th->local_lfp != lfp) { - svar = (struct RValues *)lfp[-1]; + svar = (NODE *)lfp[-1]; if ((VALUE)svar == Qnil) { - svar = new_value(); + svar = NEW_IF(Qnil, Qnil, Qnil); lfp[-1] = (VALUE)svar; } } else { - svar = (struct RValues *)th->local_svar; + svar = (NODE *)th->local_svar; if ((VALUE)svar == Qnil) { - svar = new_value(); + svar = NEW_IF(Qnil, Qnil, Qnil); th->local_svar = (VALUE)svar; } } @@ -875,17 +858,15 @@ lfp_svar_place(rb_thread_t *th, VALUE *lfp) static VALUE lfp_svar_get(rb_thread_t *th, VALUE *lfp, VALUE key) { - struct RValues *svar = lfp_svar_place(th, lfp); + NODE *svar = lfp_svar_place(th, lfp); switch (key) { case 0: - return svar->v1; + return svar->u1.value; case 1: - return svar->v2; - case 2: - return svar->basic.klass; + return svar->u2.value; default: { - VALUE hash = svar->v3; + VALUE hash = svar->u3.value; if (hash == Qnil) { return Qnil; @@ -900,45 +881,26 @@ lfp_svar_get(rb_thread_t *th, VALUE *lfp, VALUE key) static void lfp_svar_set(rb_thread_t *th, VALUE *lfp, VALUE key, VALUE val) { - struct RValues *svar = lfp_svar_place(th, lfp); + NODE *svar = lfp_svar_place(th, lfp); switch (key) { case 0: - svar->v1 = val; + svar->u1.value = val; return; case 1: - svar->v2 = val; - return; - case 2: - svar->basic.klass = val; + svar->u2.value = val; return; default: { - VALUE hash = svar->v3; + VALUE hash = svar->u3.value; if (hash == Qnil) { - svar->v3 = hash = rb_hash_new(); + svar->u3.value = hash = rb_hash_new(); } rb_hash_aset(hash, key, val); } } } -static NODE * -get_cref(rb_iseq_t *iseq, VALUE *lfp) -{ - NODE *cref; - if ((cref = lfp_get_special_cref(lfp)) != 0) { - /* */ - } - else if ((cref = iseq->cref_stack) != 0) { - /* */ - } - else { - rb_bug("get_cref: unreachable"); - } - return cref; -} - static inline VALUE vm_getspecial(rb_thread_t *th, VALUE *lfp, VALUE key, rb_num_t type) { @@ -976,6 +938,30 @@ vm_getspecial(rb_thread_t *th, VALUE *lfp, VALUE key, rb_num_t type) return val; } +static NODE * +vm_get_cref(rb_iseq_t *iseq, const VALUE * const lfp, const VALUE *dfp) +{ + NODE *cref = 0; + + while (1) { + if (lfp == dfp) { + cref = iseq->cref_stack; + break; + } + else if (dfp[-1] != Qnil) { + cref = (NODE *)dfp[-1]; + break; + } + dfp = GET_PREV_DFP(dfp); + } + + if (cref == 0) { + rb_bug("vm_get_cref: unreachable"); + } + return cref; +} + + static inline void vm_check_if_namespace(VALUE klass) { @@ -997,7 +983,7 @@ vm_get_ev_const(rb_thread_t *th, rb_iseq_t *iseq, if (klass == Qnil) { /* in current lexical scope */ - NODE *root_cref = get_cref(iseq, th->cfp->lfp); + NODE *root_cref = vm_get_cref(iseq, th->cfp->lfp, th->cfp->dfp); NODE *cref = root_cref; while (cref && cref->nd_next) { @@ -1054,9 +1040,8 @@ vm_get_ev_const(rb_thread_t *th, rb_iseq_t *iseq, } static inline VALUE -vm_get_cvar_base(rb_thread_t *th, rb_iseq_t *iseq) +vm_get_cvar_base(NODE *cref) { - NODE *cref = get_cref(iseq, th->cfp->lfp); VALUE klass = Qnil; if (cref) { @@ -1076,8 +1061,8 @@ vm_define_method(rb_thread_t *th, VALUE obj, ID id, rb_iseq_t *miseq, rb_num_t is_singleton, NODE *cref) { NODE *newbody; - int noex = cref->nd_visi; VALUE klass = cref->nd_clss; + int noex = cref->nd_visi; if (is_singleton) { if (FIXNUM_P(obj) || SYMBOL_P(obj)) { -- cgit v1.2.3