[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]