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

ruby-changes:4975

From: ko1@a...
Date: Mon, 19 May 2008 12:09:17 +0900 (JST)
Subject: [ruby-changes:4975] ko1 - Ruby:r16468 (trunk): * vm.c, insns.def, eval.c, vm_insnhelper.c: fix CREF handling.

ko1	2008-05-19 12:08:50 +0900 (Mon, 19 May 2008)

  New Revision: 16468

  Modified files:
    trunk/ChangeLog
    trunk/benchmark/bmx_temp.rb
    trunk/bootstraptest/test_eval.rb
    trunk/bootstraptest/test_knownbug.rb
    trunk/compile.c
    trunk/eval.c
    trunk/eval_intern.h
    trunk/eval_method.c
    trunk/gc.c
    trunk/include/ruby/ruby.h
    trunk/insns.def
    trunk/load.c
    trunk/proc.c
    trunk/version.h
    trunk/vm.c
    trunk/vm_core.h
    trunk/vm_dump.c
    trunk/vm_insnhelper.c

  Log:
    * 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.
    


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm_dump.c?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/load.c?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/include/ruby/ruby.h?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/benchmark/bmx_temp.rb?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/version.h?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/eval_method.c?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/compile.c?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/gc.c?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/eval.c?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm_core.h?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/proc.c?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm.c?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/insns.def?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm_insnhelper.c?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/eval_intern.h?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_eval.rb?r1=16468&r2=16467&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_knownbug.rb?r1=16468&r2=16467&diff_format=u

Index: eval_intern.h
===================================================================
--- eval_intern.h	(revision 16467)
+++ eval_intern.h	(revision 16468)
@@ -225,11 +225,12 @@
 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 @@
     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();
+VALUE rb_vm_cbase(void);
 
-#define ruby_cbase() vm_get_cbase(GET_THREAD())
-
 #endif /* RUBY_EVAL_INTERN_H */
Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 16467)
+++ include/ruby/ruby.h	(revision 16468)
@@ -262,7 +262,6 @@
     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 @@
 #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 @@
      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 @@
 #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)
Index: insns.def
===================================================================
--- insns.def	(revision 16467)
+++ insns.def	(revision 16468)
@@ -183,7 +183,8 @@
 ()
 (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 @@
 (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 @@
 ()
 (VALUE val)
 {
-    val = vm_get_cbase(th);
+    val = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
 }
 
 /**
@@ -723,8 +725,8 @@
 (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 @@
 	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 @@
 (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 @@
 	}
 	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 @@
 	}
 	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";
 	}
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 16467)
+++ ChangeLog	(revision 16468)
@@ -1,3 +1,17 @@
+Mon May 19 11:32:47 2008  Koichi Sasada  <ko1@a...>
+
+	* 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  <gotoyuzo@n...>
 
 	* lib/webrick/httpservlet/filehandler.rb: should normalize path
Index: bootstraptest/test_eval.rb
===================================================================
--- bootstraptest/test_eval.rb	(revision 16467)
+++ bootstraptest/test_eval.rb	(revision 16468)
@@ -208,3 +208,22 @@
   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]"
Index: bootstraptest/test_knownbug.rb
===================================================================
--- bootstraptest/test_knownbug.rb	(revision 16467)
+++ bootstraptest/test_knownbug.rb	(revision 16468)
@@ -136,27 +136,7 @@
   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 }
     sleep 0.1
Index: vm_core.h
===================================================================
--- vm_core.h	(revision 16467)
+++ vm_core.h	(revision 16468)
@@ -497,8 +497,6 @@
     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 {
     VALUE env;
-    NODE *cref_stack;
 } rb_binding_t;
 
 
@@ -614,6 +611,7 @@
 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);
 
Index: load.c
===================================================================
--- load.c	(revision 16467)
+++ load.c	(revision 16468)
@@ -650,7 +650,7 @@
 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 @@
 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;
     }
Index: compile.c
===================================================================
--- compile.c	(revision 16467)
+++ compile.c	(revision 16468)
@@ -280,7 +280,7 @@
     }
 
     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 @@
 	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,13 +993,15 @@
     }
 
     iseq->local_size = iseq->local_table_size = size;
+    iseq->local_size += 1;
+    /*
+      if (lfp == dfp ) { // top, class, method
+	  dfp[-1]: svar
+      else {             // block
+          dfp[-1]: cref
+      }
+     */
 
-    if (iseq->type == ISEQ_TYPE_METHOD ||
-	iseq->type == ISEQ_TYPE_CLASS  ||
-	iseq->type == ISEQ_TYPE_TOP) {
-	iseq->local_size += 1 /* svar */;
-    }
-
     debugs("iseq_set_local_table: %d, %d\n", iseq->local_size, iseq->local_table_size);
     return COMPILE_OK;
 }
@@ -3264,8 +3267,7 @@
 		  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 @@
 		  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 @@
 	    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 @@
 	    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 @@
       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 @@
 		    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);
Index: proc.c
===================================================================
--- proc.c	(revision 16467)
+++ proc.c	(revision 16468)
@@ -50,7 +50,6 @@
 	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 @@
     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 @@
     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 @@
     GetBindingPtr(self, src);
     GetBindingPtr(bindval, dst);
     dst->env = src->env;
-    dst->cref_stack = src->cref_stack;
     return bindval;
 }
 
@@ -286,7 +282,6 @@
 
     GetBindingPtr(bindval, bind);
     bind->env = vm_make_env_object(th, cfp);
-    bind->cref_stack = ruby_cref();
     return bindval;
 }
 
@@ -1587,7 +1582,6 @@
     }
 
     bind->env = proc->envval;
-    bind->cref_stack = proc->special_cref_stack;
     return bindval;
 }
 
Index: eval.c
===================================================================
--- eval.c	(revision 16467)
+++ eval.c	(revision 16468)
@@ -32,7 +32,7 @@
 
 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 @@
 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 @@
 
     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 @@
 
 
 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 @@
 }
 
 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 @@
     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 @@
 	    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 @@
 	}
 	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 = &block;
+	    th->base_block->self = self;
 	    th->base_block->iseq = cfp->iseq;	/* TODO */
 	}
 
@@ -1725,7 +1727,8 @@
 	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 @@
 	    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 @@
     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 @@
 
     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, *blockptr;
+    NODE *cref = vm_cref_push(th, under, NOEX_PUBLIC);
 
-    rb_block_t block;
-    rb_block_t *blockptr;
-    int state;
-
-    /* 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);
+    if (values == Qundef) {
+	return vm_yield_with_cref(th, 0, 0, cref);
     }
-
-    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);
-    }
     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 @@
     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 @@
 {
     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 @@
     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);
Index: gc.c
===================================================================
--- gc.c	(revision 16467)
+++ gc.c	(revision 16468)
@@ -1280,15 +1280,6 @@
 	}
 	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 @@
 
       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 @@
 		  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 @@
     }
 
     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_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);
Index: eval_method.c
===================================================================
--- eval_method.c	(revision 16467)
+++ eval_method.c	(revision 16468)
@@ -463,7 +463,7 @@
     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)) {
Index: vm.c
===================================================================
--- vm.c	(revision 16467)
+++ vm.c	(revision 16468)
@@ -79,7 +79,7 @@
 }
 
 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 @@
     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 @@
     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 @@
     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 @@
 /* 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 @@
 		      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 @@
 }
 
 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,24 +582,28 @@
 	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
 vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
 	       VALUE self, int argc, VALUE *argv, rb_block_t *blockptr)
 {
     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 @@
 	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 @@
     return ary;
 }
 
-/* cref */
-
 static void
 check_svar(void)
 {
@@ -783,7 +781,7 @@
     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 @@
     }
 }
 
-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
@@ -830,28 +810,21 @@
 #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)
 {
     NODE *cref = NEW_BLOCK(klass);
     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 @@
 	}
 	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 @@
   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 @@
     VALUE *lfp;
     VALUE *dfp;
     rb_iseq_t *block_iseq;
+    VALUE proc;
   };
 
-  struct PROC {
-    VALUE  proc_sig = 0;
-    struct BLOCK;
-  };
-
   struct METHOD_CONTROL_FRAME {
-    struct CONTROL_FRAME;
+    rb_control_frame_t frame;
   };
 
   struct METHOD_FRAME {
@@ -1073,12 +1051,13 @@
     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 @@
     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 @@
     VALUE *dfp;                      // lfp
     rb_iseq_t * block_iseq; // 0
   };
-
-  struct C_METHDO_FRAME{
-    VALUE block_ptr;
-    VALUE special;
-  };
  */
 
 
@@ -1315,7 +1291,7 @@
 	    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;
Index: version.h
===================================================================
--- version.h	(revision 16467)
+++ version.h	(revision 16468)
@@ -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 @@
 
 # define RUBY_DESCRIPTION	    \
     "ruby "RUBY_VERSION		    \
-    " ("RUBY_RELEASE_DATE" "	    \
+    "2008-05-19"	    \
     RUBY_RELEASE_STR" "		    \
     STRINGIZE(RUBY_RELEASE_NUM)") " \
     "["RUBY_PLATFORM"]"
Index: vm_dump.c
===================================================================
--- vm_dump.c	(revision 16467)
+++ vm_dump.c	(revision 16468)
@@ -140,7 +140,7 @@
 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;
@@ -175,6 +175,13 @@
 }
 
 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)
 {
     int i;
Index: benchmark/bmx_temp.rb
===================================================================
--- benchmark/bmx_temp.rb	(revision 16467)
+++ benchmark/bmx_temp.rb	(revision 16468)
@@ -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
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c	(revision 16467)
+++ vm_insnhelper.c	(revision 16468)
@@ -29,6 +29,8 @@
     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 @@
 	lfp = sp;
     }
 
+    /* setup vm control frame stack */
+
     cfp = th->cfp = th->cfp - 1;
     cfp->pc = pc;
     cfp->sp = sp + 1;
@@ -827,45 +831,24 @@
     }
 }
 
-/* cref */
+/* svar */
 
-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;
-}
-
-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 @@
 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 @@
 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;
+	svar->u2.value = val;
 	return;
-      case 2:
-	svar->basic.klass = 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 @@
     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 @@
 
     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 @@
 }
 
 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 @@
 		   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)) {

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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