ruby-changes:14167
From: shugo <ko1@a...>
Date: Fri, 4 Dec 2009 03:26:18 +0900 (JST)
Subject: [ruby-changes:14167] Ruby:r25984 (trunk): * compile.c (compile_cpath, iseq_compile_each): reverted
shugo 2009-12-04 03:25:57 +0900 (Fri, 04 Dec 2009) New Revision: 25984 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=25984 Log: * compile.c (compile_cpath, iseq_compile_each): reverted constant/class variable lookup in instance_eval etc. to the behavior of 1.8. * eval.c (rb_mod_nesting): ditto. * insns.def (putspecialobject, defineclass): ditto. * node.h (NODE_FL_CREF_PUSHED_BY_EVAL): ditto. * vm_core.h (VM_SPECIAL_OBJECT_CONST_BASE): ditto. * vm_eval.c (yield_under, eval_under): ditto. * vm_insnhelper.c (vm_cref_push, vm_get_const_base, vm_get_ev_const, vm_get_cvar_base): ditto. Modified files: trunk/ChangeLog trunk/compile.c trunk/eval.c trunk/insns.def trunk/node.h trunk/test/ruby/test_module.rb trunk/test/ruby/test_object.rb trunk/vm_core.h trunk/vm_eval.c trunk/vm_insnhelper.c Index: insns.def =================================================================== --- insns.def (revision 25983) +++ insns.def (revision 25984) @@ -343,6 +343,9 @@ case VM_SPECIAL_OBJECT_CBASE: val = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP()); break; + case VM_SPECIAL_OBJECT_CONST_BASE: + val = vm_get_const_base(GET_ISEQ(), GET_LFP(), GET_DFP()); + break; default: rb_bug("putspecialobject insn: unknown value_type"); } @@ -944,7 +947,7 @@ rb_bug("unknown defineclass type: %d", (int)define_type); } - COPY_CREF(class_iseq->cref_stack, vm_cref_push(th, klass, NOEX_PUBLIC)); + COPY_CREF(class_iseq->cref_stack, vm_cref_push(th, klass, NOEX_PUBLIC, NULL)); /* enter scope */ vm_push_frame(th, class_iseq, Index: ChangeLog =================================================================== --- ChangeLog (revision 25983) +++ ChangeLog (revision 25984) @@ -1,3 +1,22 @@ +Fri Dec 4 03:10:38 2009 Shugo Maeda <shugo@r...> + + * compile.c (compile_cpath, iseq_compile_each): reverted + constant/class variable lookup in instance_eval etc. to the + behavior of 1.8. + + * eval.c (rb_mod_nesting): ditto. + + * insns.def (putspecialobject, defineclass): ditto. + + * node.h (NODE_FL_CREF_PUSHED_BY_EVAL): ditto. + + * vm_core.h (VM_SPECIAL_OBJECT_CONST_BASE): ditto. + + * vm_eval.c (yield_under, eval_under): ditto. + + * vm_insnhelper.c (vm_cref_push, vm_get_const_base, + vm_get_ev_const, vm_get_cvar_base): ditto. + Thu Dec 3 20:27:27 2009 Martin Duerst <duerst@i...> * enc/trans/gb18030-tbl.rb: Fix omission of C1 region in code table Index: vm_core.h =================================================================== --- vm_core.h (revision 25983) +++ vm_core.h (revision 25984) @@ -524,8 +524,9 @@ #define VM_CALL_SUPER_BIT (0x01 << 7) #define VM_CALL_OPT_SEND_BIT (0x01 << 8) -#define VM_SPECIAL_OBJECT_VMCORE 0x01 -#define VM_SPECIAL_OBJECT_CBASE 0x02 +#define VM_SPECIAL_OBJECT_VMCORE 0x01 +#define VM_SPECIAL_OBJECT_CBASE 0x02 +#define VM_SPECIAL_OBJECT_CONST_BASE 0x03 #define VM_FRAME_MAGIC_METHOD 0x11 #define VM_FRAME_MAGIC_BLOCK 0x21 Index: compile.c =================================================================== --- compile.c (revision 25983) +++ compile.c (revision 25984) @@ -2549,7 +2549,8 @@ } else { /* class at cbase Foo */ - ADD_INSN1(ret, nd_line(cpath), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE)); + ADD_INSN1(ret, nd_line(cpath), putspecialobject, + INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE)); return Qtrue; } } @@ -3710,7 +3711,8 @@ } if (node->nd_vid) { - ADD_INSN1(ret, nd_line(node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE)); + ADD_INSN1(ret, nd_line(node), putspecialobject, + INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE)); ADD_INSN1(ret, nd_line(node), setconstant, ID2SYM(node->nd_vid)); } else { Index: vm_eval.c =================================================================== --- vm_eval.c (revision 25983) +++ vm_eval.c (revision 25984) @@ -17,7 +17,7 @@ static inline VALUE vm_yield(rb_thread_t *th, int argc, const VALUE *argv); static inline VALUE vm_backtrace(rb_thread_t *th, int lev); static int vm_backtrace_each(rb_thread_t *th, int lev, rb_backtrace_iter_func *iter, void *arg); -static NODE *vm_cref_push(rb_thread_t *th, VALUE klass, int noex); +static NODE *vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr); static VALUE vm_exec(rb_thread_t *th); static void vm_set_eval_stack(rb_thread_t * th, VALUE iseqval, const NODE *cref); static int vm_collect_local_variables_in_heap(rb_thread_t *th, VALUE *dfp, VALUE ary); @@ -1161,16 +1161,18 @@ { rb_thread_t *th = GET_THREAD(); rb_block_t block, *blockptr; - NODE *cref = vm_cref_push(th, under, NOEX_PUBLIC); + NODE *cref; if ((blockptr = GC_GUARDED_PTR_REF(th->cfp->lfp[0])) != 0) { block = *blockptr; block.self = self; th->cfp->lfp[0] = GC_GUARDED_PTR(&block); } + cref = vm_cref_push(th, under, NOEX_PUBLIC, &block); + cref->flags |= NODE_FL_CREF_PUSHED_BY_EVAL; if (values == Qundef) { - return vm_yield_with_cref(th, 0, 0, cref); + return vm_yield_with_cref(th, 1, &self, cref); } else { return vm_yield_with_cref(th, RARRAY_LENINT(values), RARRAY_PTR(values), cref); @@ -1181,7 +1183,7 @@ static VALUE eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line) { - NODE *cref = vm_cref_push(GET_THREAD(), under, NOEX_PUBLIC); + NODE *cref = vm_cref_push(GET_THREAD(), under, NOEX_PUBLIC, NULL); if (rb_safe_level() >= 4) { StringValue(src); Index: eval.c =================================================================== --- eval.c (revision 25983) +++ eval.c (revision 25984) @@ -274,7 +274,8 @@ while (cref && cref->nd_next) { VALUE klass = cref->nd_clss; - if (!NIL_P(klass)) { + if (!(cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL) && + !NIL_P(klass)) { rb_ary_push(ary, klass); } cref = cref->nd_next; Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 25983) +++ vm_insnhelper.c (revision 25984) @@ -1066,14 +1066,17 @@ } static NODE * -vm_cref_push(rb_thread_t *th, VALUE klass, int noex) +vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr) { rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, th->cfp); NODE *cref = NEW_BLOCK(klass); cref->nd_file = 0; cref->nd_visi = noex; - if (cfp) { + if (blockptr) { + cref->nd_next = vm_get_cref(blockptr->iseq, blockptr->lfp, blockptr->dfp); + } + else if (cfp) { cref->nd_next = vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp); } @@ -1096,6 +1099,23 @@ return klass; } +static inline VALUE +vm_get_const_base(const rb_iseq_t *iseq, const VALUE *lfp, const VALUE *dfp) +{ + NODE *cref = vm_get_cref(iseq, lfp, dfp); + VALUE klass = Qundef; + + while (cref) { + if (!(cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL) && + (klass = cref->nd_clss) != 0) { + break; + } + cref = cref->nd_next; + } + + return klass; +} + static inline void vm_check_if_namespace(VALUE klass) { @@ -1117,12 +1137,16 @@ if (orig_klass == Qnil) { /* in current lexical scope */ - const NODE *root_cref = vm_get_cref(iseq, th->cfp->lfp, th->cfp->dfp); - const NODE *cref = root_cref; + const NODE *cref = vm_get_cref(iseq, th->cfp->lfp, th->cfp->dfp); + const NODE *root_cref = NULL; VALUE klass = orig_klass; while (cref && cref->nd_next) { - klass = cref->nd_clss; + if (!(cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL)) { + klass = cref->nd_clss; + if (root_cref == NULL) + root_cref = cref; + } cref = cref->nd_next; if (!NIL_P(klass)) { @@ -1149,8 +1173,10 @@ } /* search self */ - klass = root_cref->nd_clss; - if (NIL_P(klass)) { + if (root_cref && !NIL_P(root_cref->nd_clss)) { + klass = root_cref->nd_clss; + } + else { klass = CLASS_OF(th->cfp->self); } @@ -1178,7 +1204,8 @@ VALUE klass; while (cref && cref->nd_next && - (NIL_P(cref->nd_clss) || FL_TEST(cref->nd_clss, FL_SINGLETON))) { + (NIL_P(cref->nd_clss) || FL_TEST(cref->nd_clss, FL_SINGLETON) || + (cref->flags & NODE_FL_CREF_PUSHED_BY_EVAL))) { cref = cref->nd_next; if (!cref->nd_next) { Index: test/ruby/test_module.rb =================================================================== --- test/ruby/test_module.rb (revision 25983) +++ test/ruby/test_module.rb (revision 25984) @@ -216,10 +216,29 @@ remove_rake_mixins(remove_json_mixins(remove_pp_mixins(String.ancestors)))) end + CLASS_EVAL = 2 + @@class_eval = 'b' + def test_class_eval Other.class_eval("CLASS_EVAL = 1") assert_equal(1, Other::CLASS_EVAL) assert(Other.constants.include?(:CLASS_EVAL)) + assert_equal(2, Other.class_eval { CLASS_EVAL }) + + Other.class_eval("@@class_eval = 'a'") + assert_equal('a', Other.class_variable_get(:@@class_eval)) + assert_equal('b', Other.class_eval { @@class_eval }) + + Other.class_eval do + module_function + + def class_eval_test + "foo" + end + end + assert("foo", Other.class_eval_test) + + assert_equal([Other], Other.class_eval { |*args| args }) end def test_const_defined? @@ -451,7 +470,7 @@ def test_class_variable_get c = Class.new - c.class_eval { @@foo = :foo } + c.class_eval('@@foo = :foo') assert_equal(:foo, c.class_variable_get(:@@foo)) assert_raise(NameError) { c.class_variable_get(:@@bar) } # c.f. instance_variable_get assert_raise(NameError) { c.class_variable_get(:foo) } @@ -460,13 +479,13 @@ def test_class_variable_set c = Class.new c.class_variable_set(:@@foo, :foo) - assert_equal(:foo, c.class_eval { @@foo }) + assert_equal(:foo, c.class_eval('@@foo')) assert_raise(NameError) { c.class_variable_set(:foo, 1) } end def test_class_variable_defined c = Class.new - c.class_eval { @@foo = :foo } + c.class_eval('@@foo = :foo') assert_equal(true, c.class_variable_defined?(:@@foo)) assert_equal(false, c.class_variable_defined?(:@@bar)) assert_raise(NameError) { c.class_variable_defined?(:foo) } @@ -474,7 +493,7 @@ def test_remove_class_variable c = Class.new - c.class_eval { @@foo = :foo } + c.class_eval('@@foo = :foo') c.class_eval { remove_class_variable(:@@foo) } assert_equal(false, c.class_variable_defined?(:@@foo)) end Index: test/ruby/test_object.rb =================================================================== --- test/ruby/test_object.rb (revision 25983) +++ test/ruby/test_object.rb (revision 25984) @@ -416,12 +416,20 @@ end end + class InstanceExec + INSTANCE_EXEC = 123 + end + def test_instance_exec x = 1.instance_exec(42) {|a| self + a } assert_equal(43, x) x = "foo".instance_exec("bar") {|a| self + a } assert_equal("foobar", x) + + assert_raise(NameError) do + InstanceExec.new.instance_exec { INSTANCE_EXEC } + end end def test_extend Index: node.h =================================================================== --- node.h (revision 25983) +++ node.h (revision 25984) @@ -262,6 +262,7 @@ /* 0..4:T_TYPES, 5:FL_MARK, 6:reserved, 7:NODE_FL_NEWLINE */ #define NODE_FL_NEWLINE (((VALUE)1)<<7) +#define NODE_FL_CREF_PUSHED_BY_EVAL NODE_FL_NEWLINE #define NODE_TYPESHIFT 8 #define NODE_TYPEMASK (((VALUE)0x7f)<<NODE_TYPESHIFT) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/