[前][次][番号順一覧][スレッド一覧][生データ]

yarv-diff:75

From: ko1 atdot.net
Date: 15 Aug 2005 00:55:31 -0000
Subject: [yarv-diff:75] r231 - in trunk: . benchmark yarvext yarvtest

Author: ko1
Date: 2005-08-15 09:55:30 +0900 (Mon, 15 Aug 2005)
New Revision: 231

Added:
   trunk/benchmark/run_rite.rb
   trunk/test.rb
Modified:
   trunk/ChangeLog
   trunk/Makefile.in
   trunk/benchmark/bmx_temp.rb
   trunk/common.mk
   trunk/depend
   trunk/eval.c
   trunk/inits.c
   trunk/vm.c
   trunk/vm.h
   trunk/vm_dump.c
   trunk/yarv.h
   trunk/yarvcore.c
   trunk/yarvcore.h
   trunk/yarvext/test.rb
   trunk/yarvtest/yarvtest.rb
Log:
	* yarvcore.h : define SDR()

	* vm_dump.c : stack_dump_raw() -> vm_stack_dump_raw()

	* yarvtest/yarvtest.rb : add rite test scheme

	* benchmark/run_rite.rb : added

	* yarvcore.c, inits.c : add Init_vm()

	* yarv.h : add some prototype declarations, GET_THREAD()

	* eval.c : remove unused functions

	* eval.c : support Kernel.eval, some schemes (same as evalc.patch)



Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/ChangeLog	2005-08-15 00:55:30 UTC (rev 231)
@@ -4,6 +4,25 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2005-08-15(Mon) 09:42:01 +0900  Koichi Sasada  <ko1 atdot.net>
+
+	* yarvcore.h : define SDR()
+
+	* vm_dump.c : stack_dump_raw() -> vm_stack_dump_raw()
+
+	* yarvtest/yarvtest.rb : add rite test scheme
+
+	* benchmark/run_rite.rb : added
+
+	* yarvcore.c, inits.c : add Init_vm()
+
+	* yarv.h : add some prototype declarations, GET_THREAD()
+
+	* eval.c : remove unused functions
+
+	* eval.c : support Kernel.eval, some schemes (same as evalc.patch)
+
+
 2005-08-15(Mon) 00:53:28 +0900  Koichi Sasada  <ko1 atdot.net>
 
 	* yarv_version.h : move configurations to yarvcore.h

Modified: trunk/Makefile.in
===================================================================
--- trunk/Makefile.in	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/Makefile.in	2005-08-15 00:55:30 UTC (rev 231)
@@ -168,63 +168,59 @@
 
 
 
-BASE_RUBY = ruby
+BASERUBY = ruby
 
 INSNS2VMOPT = $(CPPFLAGS) --srcdir=$(srcdir)
 
 minsns.inc:
-	$(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
+	$(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
 
 opt_sc.inc:
-	$(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
+	$(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
 
 optinsn.inc:
-	$(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) optinsn.inc
+	$(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) optinsn.inc
 
 optunifs.inc:
-	$(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) optunifs.inc
+	$(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) optunifs.inc
 
 insns.inc:
-	$(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
+	$(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
 
 vmtc.inc:
-	$(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) vmtc.inc
+	$(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) vmtc.inc
 
 vm.inc: $(srcdir)/insns.def
-	$(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) vm.inc
+	$(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) vm.inc
 
 vm_macro.inc: $(srcdir)/vm_macro.def
-	$(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) vm_macro.inc
+	$(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) vm_macro.inc
 
 rev.inc: $(srcdir)/ChangeLog
-	$(BASE_RUBY) $(srcdir)/rb/getrev.rb $(srcdir)/ChangeLog > rev.inc
+	$(BASERUBY) $(srcdir)/rb/getrev.rb $(srcdir)/ChangeLog > rev.inc
 
 incs:
-	$(BASE_RUBY) $(srcdir)/rb/getrev.rb $(srcdir)/ChangeLog > rev.inc
-	$(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
+	$(BASERUBY) $(srcdir)/rb/getrev.rb $(srcdir)/ChangeLog > rev.inc
+	$(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
 
 docs:
-	$(BASE_RUBY) -I$(srcdir) $(srcdir)/rb/makedocs.rb $(INSNS2VMOPT)
+	$(BASERUBY) -I$(srcdir) $(srcdir)/rb/makedocs.rb $(INSNS2VMOPT)
 
 yarv-test-all: all
-	$(BASE_RUBY) -I$(srcdir) $(srcdir)/test/runner.rb $(OPT)
+	$(BASERUBY) -I$(srcdir) $(srcdir)/yarvtest/runner.rb $(OPT) yarv=$(MINIRUBY) ruby=$(BASERUBY)
 
 yarv-test-each: all
-	$(BASE_RUBY) -I$(srcdir) $(srcdir)/test/test_$(ITEM).rb $(OPT)
+	$(BASERUBY) -I$(srcdir) $(srcdir)/yarvtest/test_$(ITEM).rb $(OPT) yarv=$(MINIRUBY) ruby=$(BASERUBY)
 
 run: all
-	@echo "Ruby --"
-	@$(BASE_RUBY) $(srcdir)/test.rb $(RUNOPT)
-	@echo "YARV --"
-	@$(MINIRUBY) $(srcdir)/test.rb $(RUNOPT)
+	$(BASERUBY) $(srcdir)/test.rb $(RUNOPT) $(MINIRUBY) $(BASERUBY)
 
 benchmark: all
-	$(BASE_RUBY) -I$(srcdir) $(srcdir)/benchmark/run.rb $(OPT) $(ITEMS)
+	$(BASERUBY) -I$(srcdir) $(srcdir)/benchmark/run_rite.rb $(OPT) $(ITEMS) --yarv-program=$(MINIRUBY) --ruby-program=$(BASERUBY)
 
 ITEM=bmx_temp
 tbench: all
-	$(RUBY) -I$(srcdir) $(srcdir)/benchmark/run.rb $(ITEM) $(OPT)
-
+	$(RUBY) -I$(srcdir) $(srcdir)/benchmark/run_rite.rb $(ITEM) $(OPT) --yarv-program=$(MINIRUBY) --ruby-program=$(BASERUBY)
 aotc:
 	$(RUBY) -I$(srcdir) -I. $(srcdir)/rb/aotcompile.rb $(INSNS2VMOPT)
 
@@ -232,4 +228,4 @@
 	echo run > run.gdb
 
 gdb: all run.gdb
-	gdb -x run.gdb --quiet --args $(RUBY) -I$(srcdir) $(srcdir)/test.rb
+	gdb -x run.gdb --quiet --args $(MINIRUBY) -I$(srcdir) $(srcdir)/test.rb

Modified: trunk/benchmark/bmx_temp.rb
===================================================================
--- trunk/benchmark/bmx_temp.rb	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/benchmark/bmx_temp.rb	2005-08-15 00:55:30 UTC (rev 231)
@@ -1,19 +1,5 @@
 i = 0
-ary = (1..100).to_a
-
-class Array
-  def map
-    i = 0
-    ret = []
-    while i<self.length
-      ret << yield(self[i])
-      i+=1
-    end
-    ret
-  end
-end
-
-while i<30000
+while i < 1000000
   i+=1
-  ary.map{|x| x * 1}
 end
+

Added: trunk/benchmark/run_rite.rb
===================================================================
--- trunk/benchmark/run_rite.rb	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/benchmark/run_rite.rb	2005-08-15 00:55:30 UTC (rev 231)
@@ -0,0 +1,112 @@
+#
+# YARV benchmark driver
+#
+
+require 'benchmark'
+require 'rbconfig'
+
+$yarvonly = false
+$rubyonly = false
+
+$results  = []
+
+def bm file
+  prog = File.read(file).map{|e| e.rstrip}.join("\n")
+  return if prog.empty?
+
+  /[a-z]+_(.+)\.rb/ =~ file
+  bm_name = $1
+  puts '-----------------------------------------------------------' unless $yarvonly || $rubyonly
+  puts "#{bm_name}: "
+  
+  
+puts <<EOS unless $yarvonly || $rubyonly
+#{prog}
+--
+EOS
+  #iseq = YARVUtil.parse(File.read(file))
+  #vm   = YARVCore::VM.new
+  begin
+    result = [bm_name]
+    result << ruby_exec(file) unless $yarvonly
+    result << yarv_exec(file) unless $rubyonly
+    $results << result
+    
+    # puts YARVUtil.parse(File.read(file), file, 1).disasm
+    
+    # x.report("ruby"){ load(file, false)    }
+    # x.report("yarv"){ vm.eval iseq }
+  rescue Exception => e
+    puts
+    puts "** benchmark failure: #{e}"
+    puts e.backtrace
+  end
+end
+
+def benchmark file, bin
+  m = Benchmark.measure{
+    `#{bin} #{file}`
+  }
+  sec = '%.3f' % m.real
+  puts " #{sec}"
+  sec
+end
+
+def ruby_exec file
+  print 'ruby'
+  benchmark file, $ruby_program
+end
+
+def yarv_exec file
+  print 'yarv'
+  benchmark file, $yarv_program
+end
+
+if $0 == __FILE__
+  ARGV.each{|arg|
+    case arg
+    when /\A--yarv-program=(.+)/
+      $yarv_program = $1
+    when /\A--ruby-program=(.+)/
+      $ruby_program = $1
+    when /\A(--yarv)|(-y)/
+      $yarvonly = true
+    when /\A(--ruby)|(-r)/
+      $rubyonly = true
+    end
+  }
+  ARGV.delete_if{|arg|
+    /\A-/ =~ arg
+  }
+  
+  puts "Ruby:"
+  system("#{$ruby_program} -v")
+  puts
+  puts "YARV:"
+  system("#{$yarv_program} -v")
+
+  if ARGV.empty?
+    Dir.glob(File.dirname(__FILE__) + '/bm_*.rb').sort.each{|file|
+      bm file
+    }
+  else
+    ARGV.each{|file|
+      Dir.glob(File.join(File.dirname(__FILE__), file + '*')){|ef|
+        # file = "#{File.dirname(__FILE__)}/#{file}.rb"
+        bm ef
+      }
+    }
+  end
+
+  puts
+  puts "-- benchmark summary ---------------------------"
+  $results.each{|res|
+    print res.shift, "\t"
+    (res||[]).each{|result|
+      /([\d\.]+)/ =~ result
+      print $1 + "\t" if $1
+    }
+    puts
+  }
+end
+


Property changes on: trunk/benchmark/run_rite.rb
___________________________________________________________________
Name: svn:executable
   + *

Modified: trunk/common.mk
===================================================================
--- trunk/common.mk	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/common.mk	2005-08-15 00:55:30 UTC (rev 231)
@@ -251,7 +251,7 @@
 eval.$(OBJEXT): {$(VPATH)}eval.c {$(VPATH)}ruby.h config.h \
   {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
   {$(VPATH)}node.h {$(VPATH)}env.h {$(VPATH)}util.h \
-  {$(VPATH)}rubysig.h {$(VPATH)}st.h {$(VPATH)}dln.h
+  {$(VPATH)}rubysig.h {$(VPATH)}st.h {$(VPATH)}dln.h {$(VPATH)}yarv.h
 file.$(OBJEXT): {$(VPATH)}file.c {$(VPATH)}ruby.h config.h \
   {$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
   {$(VPATH)}rubyio.h {$(VPATH)}rubysig.h {$(VPATH)}util.h \

Modified: trunk/depend
===================================================================
--- trunk/depend	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/depend	2005-08-15 00:55:30 UTC (rev 231)
@@ -57,11 +57,11 @@
 	$(RUBY) -I$(srcdir)/yarvext $(srcdir)/yarvext/test.rb $(RUNOPT)
 
 benchmark: all
-	$(RUBY) -I$(srcdir) $(srcdir)/benchmark/run.rb $(OPT) $(ITEMS)
+	$(RUBY) -I$(srcdir)/yarvext $(srcdir)/benchmark/run.rb $(OPT) $(ITEMS)
 
 ITEM=bmx_temp
 tbench: all
-	$(RUBY) -I$(srcdir) $(srcdir)/benchmark/run.rb $(ITEM) $(OPT)
+	$(RUBY) -I$(srcdir)/yarvext $(srcdir)/benchmark/run.rb $(ITEM) $(OPT)
 
 
 test-compiler: all

Modified: trunk/eval.c
===================================================================
--- trunk/eval.c	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/eval.c	2005-08-15 00:55:30 UTC (rev 231)
@@ -17,6 +17,7 @@
 #include "env.h"
 #include "util.h"
 #include "rubysig.h"
+#include "yarv.h"
 
 #ifdef HAVE_STDLIB_H
 #include <stdlib.h>
@@ -202,7 +203,6 @@
 static VALUE rb_f_binding _((VALUE));
 static void rb_f_END _((void));
 static VALUE rb_f_block_given_p _((void));
-static VALUE block_pass _((VALUE,NODE*));
 static VALUE rb_cMethod;
 static VALUE rb_cUnboundMethod;
 static VALUE umethod_bind _((VALUE, VALUE));
@@ -924,18 +924,7 @@
 rb_svar(cnt)
     int cnt;
 {
-    struct RVarmap *vars = ruby_dyna_vars;
-    ID id;
-
-    if (!ruby_scope->local_tbl) return NULL;
-    if (cnt >= ruby_scope->local_tbl[0]) return NULL;
-    id = ruby_scope->local_tbl[cnt+1];
-    while (vars) {
-	if (vars->id == id) return &vars->val;
-	vars = vars->next;
-    }
-    if (ruby_scope->local_vars == 0) return NULL;
-    return &ruby_scope->local_vars[cnt];
+  return yarv_svar(cnt);
 }
 
 struct iter {
@@ -1089,7 +1078,6 @@
     } while (0);				 \
     POP_TAG()
 
-static VALUE rb_eval _((VALUE,NODE*));
 static VALUE eval _((VALUE,VALUE,VALUE,char*,int));
 static NODE *compile _((VALUE, char*, int));
 
@@ -1102,12 +1090,7 @@
 #define YIELD_FUNC_SVALUE 2
 
 static VALUE rb_call _((VALUE,VALUE,ID,int,const VALUE*,int));
-static VALUE module_setup _((VALUE,NODE*));
 
-static VALUE massign _((VALUE,NODE*,VALUE,int));
-static void assign _((VALUE,NODE*,VALUE,int));
-static int formal_assign _((VALUE, NODE*, int, VALUE*, VALUE*));
-
 typedef struct event_hook {
     rb_event_hook_func_t func;
     rb_event_t events;
@@ -1399,20 +1382,6 @@
     ruby_running = 1;
 }
 
-static VALUE
-eval_node(self, node)
-    VALUE self;
-    NODE *node;
-{
-    if (!node) return Qnil;
-    if (nd_type(node) == NODE_PRELUDE) {
-	rb_eval(self, node->nd_head);
-	node = node->nd_body;
-    }
-    if (!node) return Qnil;
-    return rb_eval(self, node);
-}
-
 int ruby_in_eval;
 
 static void rb_thread_cleanup _((void));
@@ -1587,10 +1556,10 @@
 ruby_exec_internal()
 {
   int state;
+  VALUE val;
   PUSH_TAG(0);
   if((state = EXEC_TAG()) == 0) {
-    // VM start
-    yarvcore_eval_parsed(ruby_eval_tree, ruby_sourcefile);
+    val = yarvcore_eval_parsed((VALUE)ruby_eval_tree, rb_str_new2(ruby_sourcefile));
   }
   POP_TAG();
   return state;
@@ -2213,40 +2182,6 @@
 # define TMP_ALLOC(n) ALLOCA_N(VALUE,n)
 #endif
 
-#define SETUP_ARGS0(anode,alen) do {\
-    NODE *n = anode;\
-    if (!n) {\
-	argc = 0;\
-	argv = 0;\
-    }\
-    else if (nd_type(n) == NODE_ARRAY) {\
-	argc=alen;\
-	if (argc > 0) {\
-	    int i;\
-	    n = anode;\
-	    argv = TMP_ALLOC(argc);\
-	    for (i=0;i<argc;i++) {\
-		argv[i] = rb_eval(self,n->nd_head);\
-		n=n->nd_next;\
-	    }\
-	}\
-	else {\
-	    argc = 0;\
-	    argv = 0;\
-	}\
-    }\
-    else {\
-	VALUE args = rb_eval(self,n);\
-	if (TYPE(args) != T_ARRAY)\
-	    args = rb_ary_to_ary(args);\
-	argc = RARRAY(args)->len;\
-	argv = ALLOCA_N(VALUE, argc);\
-	MEMCPY(argv, RARRAY(args)->ptr, VALUE, argc);\
-    }\
-} while (0)
-
-#define SETUP_ARGS(anode) SETUP_ARGS0(anode, anode->nd_alen)
-
 #define BEGIN_CALLARGS do {\
     struct BLOCK *tmp_block = ruby_block;\
     int tmp_iter = ruby_iter->iter;\
@@ -2263,219 +2198,6 @@
 
 #define MATCH_DATA *rb_svar(node->nd_cnt)
 
-static const char* is_defined _((VALUE, NODE*, char*, int));
-
-static char*
-arg_defined(self, node, buf, type)
-    VALUE self;
-    NODE *node;
-    char *buf;
-    char *type;
-{
-    int argc;
-    int i;
-
-    if (!node) return type;	/* no args */
-    if (nd_type(node) == NODE_ARRAY) {
-	argc=node->nd_alen;
-	if (argc > 0) {
-	    for (i=0;i<argc;i++) {
-		if (!is_defined(self, node->nd_head, buf, 0))
-		    return 0;
-		node = node->nd_next;
-	    }
-	}
-    }
-    else if (!is_defined(self, node, buf, 0)) {
-	return 0;
-    }
-    return type;
-}
-
-static const char*
-is_defined(self, node, buf, noeval)
-    VALUE self;
-    NODE *node;			/* OK */
-    char *buf;
-    int noeval;
-{
-    VALUE val;			/* OK */
-    int state;
-    static const char *ex = "expression";
-
-    if (!node) return ex;
-    switch (nd_type(node)) {
-      case NODE_SUPER:
-      case NODE_ZSUPER:
-	if (ruby_frame->this_func == 0) return 0;
-	else if (ruby_frame->this_class == 0) return 0;
-	val = ruby_frame->this_class;
-	if (rb_method_boundp(RCLASS(val)->super, ruby_frame->this_func, 0)) {
-	    if (nd_type(node) == NODE_SUPER) {
-		return arg_defined(self, node->nd_args, buf, "super");
-	    }
-	    return "super";
-	}
-	break;
-
-      case NODE_VCALL:
-      case NODE_FCALL:
-	val = self;
-	goto check_bound;
-
-      case NODE_ATTRASGN:
-	val = self;
-	if (node->nd_recv == (NODE *)1) goto check_bound;
-      case NODE_CALL:
-	if (!is_defined(self, node->nd_recv, buf, Qtrue)) return 0;
-	if (noeval) return ex;
-	val = rb_eval(self, node->nd_recv);
-      check_bound:
-	{
-	    int call = nd_type(node)==NODE_CALL;
-
-	    val = CLASS_OF(val);
-	    if (call) {
-		int noex;
-		ID id = node->nd_mid;
-
-		if (!rb_get_method_body(&val, &id, &noex))
-		    break;
-		if ((noex & NOEX_PRIVATE))
-		    break;
-		if ((noex & NOEX_PROTECTED) &&
-		    !rb_obj_is_kind_of(self, rb_class_real(val)))
-		    break;
-	    }
-	    else if (!rb_method_boundp(val, node->nd_mid, call))
-		break;
-	    return arg_defined(self, node->nd_args, buf,
-			       nd_type(node) == NODE_ATTRASGN ?
-			       "assignment" : "method");
-	}
-	break;
-
-      case NODE_MATCH2:
-      case NODE_MATCH3:
-	return "method";
-
-      case NODE_YIELD:
-	if (rb_block_given_p()) {
-	    return "yield";
-	}
-	break;
-
-      case NODE_SELF:
-	return "self";
-
-      case NODE_NIL:
-	return "nil";
-
-      case NODE_TRUE:
-	return "true";
-
-      case NODE_FALSE:
-	return "false";
-
-      case NODE_ATTRSET:
-      case NODE_OP_ASGN1:
-      case NODE_OP_ASGN2:
-      case NODE_MASGN:
-      case NODE_LASGN:
-      case NODE_DASGN:
-      case NODE_DASGN_CURR:
-      case NODE_GASGN:
-      case NODE_IASGN:
-      case NODE_CDECL:
-      case NODE_CVDECL:
-      case NODE_CVASGN:
-	return "assignment";
-
-      case NODE_LVAR:
-	return "local-variable";
-      case NODE_DVAR:
-	return "local-variable(in-block)";
-
-      case NODE_GVAR:
-	if (rb_gvar_defined(node->nd_entry)) {
-	    return "global-variable";
-	}
-	break;
-
-      case NODE_IVAR:
-	if (rb_ivar_defined(self, node->nd_vid)) {
-	    return "instance-variable";
-	}
-	break;
-
-      case NODE_CONST:
-	if (ev_const_defined(ruby_cref, node->nd_vid, self)) {
-	    return "constant";
-	}
-	break;
-
-      case NODE_CVAR:
-	if (rb_cvar_defined(cvar_cbase(), node->nd_vid)) {
-	    return "class variable";
-	}
-	break;
-
-      case NODE_COLON2:
-	if (!is_defined(self, node->nd_recv, buf, Qtrue)) return 0;
-	if (noeval) return ex;
-	val = rb_eval(self, node->nd_recv);
-	switch (TYPE(val)) {
-	  case T_CLASS:
-	  case T_MODULE:
-	    if (rb_const_defined_from(val, node->nd_mid))
-		return "constant";
-	    break;
-	  default:
-	    if (rb_method_boundp(CLASS_OF(val), node->nd_mid, 1)) {
-		return "method";
-	    }
-	}
-	break;
-
-      case NODE_COLON3:
-	if (rb_const_defined_from(rb_cObject, node->nd_mid)) {
-	    return "constant";
-	}
-	break;
-
-      case NODE_NTH_REF:
-	if (RTEST(rb_reg_nth_defined(node->nd_nth, MATCH_DATA))) {
-	    if (!buf) return ex;
-	    sprintf(buf, "$%d", (int)node->nd_nth);
-	    return buf;
-	}
-	break;
-
-      case NODE_BACK_REF:
-	if (RTEST(rb_reg_nth_defined(0, MATCH_DATA))) {
-	    if (!buf) return ex;
-	    sprintf(buf, "$%c", (char)node->nd_nth);
-	    return buf;
-	}
-	break;
-
-      default:
-	PUSH_TAG(PROT_NONE);
-	if ((state = EXEC_TAG()) == 0) {
-	    rb_eval(self, node);
-	}
-	POP_TAG();
-	if (!state) {
-	    return ex;
-	}
-	ruby_errinfo = Qnil;
-	break;
-    }
-    return 0;
-}
-
-static int handle_rescue _((VALUE,NODE*));
-
 static void blk_free();
 
 static VALUE
@@ -2775,37 +2497,6 @@
     return rb_values_from_ary(val);
 }
 
-static VALUE
-class_prefix(self, cpath)
-    VALUE self;
-    NODE *cpath;
-{
-    if (!cpath) {
-	rb_bug("class path missing");
-    }
-    if (cpath->nd_head) {
-	VALUE c = rb_eval(self, cpath->nd_head);
-	switch (TYPE(c)) {
-	  case T_CLASS:
-	  case T_MODULE:
-	    break;
-	  default:
-	    rb_raise(rb_eTypeError, "%s is not a class/module",
-		     RSTRING(rb_obj_as_string(c))->ptr);
-	}
-	return c;
-    }
-    else if (nd_type(cpath) == NODE_COLON2) {
-	return ruby_cbase;
-    }
-    else if (ruby_wrapper) {
-	return ruby_wrapper;
-    }
-    else {
-	return rb_cObject;
-    }
-}
-
 #define return_value(v) do {\
   if ((prot_tag->retval = (v)) == Qundef) {\
     prot_tag->retval = Qnil;\
@@ -2832,1316 +2523,6 @@
     }
 }
 
-static VALUE
-rb_eval(self, n)
-    VALUE self;
-    NODE *n;
-{
-    NODE * volatile contnode = 0;
-    NODE * volatile node = n;
-    int state;
-    volatile VALUE result = Qnil;
-
-#define RETURN(v) do { \
-    result = (v); \
-    goto finish; \
-} while (0)
-
-  again:
-    if (!node) RETURN(Qnil);
-
-    ruby_current_node = node;
-    if (node->flags & NODE_NEWLINE) {
-	EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self, 
-			ruby_frame->this_func,
-			ruby_frame->this_class);
-    }
-    switch (nd_type(node)) {
-      case NODE_BLOCK:
-	if (contnode) {
-	    result = rb_eval(self, node);
-	    break;
-	}
-	contnode = node->nd_next;
-	node = node->nd_head;
-	goto again;
-
-      case NODE_POSTEXE:
-	rb_f_END();
-	nd_set_type(node, NODE_NIL); /* exec just once */
-	result = Qnil;
-	break;
-
-	/* begin .. end without clauses */
-      case NODE_BEGIN:
-	node = node->nd_body;
-	goto again;
-
-	/* nodes for speed-up(default match) */
-      case NODE_MATCH:
-	result = rb_reg_match2(node->nd_lit);
-	break;
-
-	/* nodes for speed-up(literal match) */
-      case NODE_MATCH2:
-	{
-	    VALUE l = rb_eval(self,node->nd_recv);
-	    VALUE r = rb_eval(self,node->nd_value);
-	    result = rb_reg_match(l, r);
-	}
-	break;
-
-	/* nodes for speed-up(literal match) */
-      case NODE_MATCH3:
-	{
-	    VALUE r = rb_eval(self,node->nd_recv);
-	    VALUE l = rb_eval(self,node->nd_value);
-	    if (TYPE(l) == T_STRING) {
-		result = rb_reg_match(r, l);
-	    }
-	    else {
-		result = rb_funcall(l, match, 1, r);
-	    }
-	}
-	break;
-
-	/* node for speed-up(top-level loop for -n/-p) */
-      case NODE_OPT_N:
-	PUSH_TAG(PROT_LOOP);
-	switch (state = EXEC_TAG()) {
-	  case 0:
-	  opt_n_next:
-	    while (!NIL_P(rb_gets())) {
-	      opt_n_redo:
-		rb_eval(self, node->nd_body);
-	    }
-	    break;
-
-	  case TAG_REDO:
-	    state = 0;
-	    goto opt_n_redo;
-	  case TAG_NEXT:
-	    state = 0;
-	    goto opt_n_next;
-	  case TAG_BREAK:
-	    state = 0;
-	  default:
-	    break;
-	}
-	POP_TAG();
-	if (state) JUMP_TAG(state);
-	RETURN(Qnil);
-
-      case NODE_SELF:
-	RETURN(self);
-
-      case NODE_NIL:
-	RETURN(Qnil);
-
-      case NODE_TRUE:
-	RETURN(Qtrue);
-
-      case NODE_FALSE:
-	RETURN(Qfalse);
-
-      case NODE_ERRINFO:
-	RETURN(ruby_errinfo);
-
-      case NODE_IF:
-	EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self,
-			ruby_frame->this_func,
-			ruby_frame->this_class);
-	if (RTEST(rb_eval(self, node->nd_cond))) {
-	    node = node->nd_body;
-	}
-	else {
-	    node = node->nd_else;
-	}
-	goto again;
-
-      case NODE_WHEN:
-	while (node) {
-	    NODE *tag;
-
-	    if (nd_type(node) != NODE_WHEN) goto again;
-	    tag = node->nd_head;
-	    while (tag) {
-		EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self,
-				ruby_frame->this_func,
-				ruby_frame->this_class);
-		if (tag->nd_head && nd_type(tag->nd_head) == NODE_WHEN) {
-		    VALUE v = rb_eval(self, tag->nd_head->nd_head);
-		    long i;
-
-		    if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v);
-		    for (i=0; i<RARRAY(v)->len; i++) {
-			if (RTEST(RARRAY(v)->ptr[i])) {
-			    node = node->nd_body;
-			    goto again;
-			}
-		    }
-		    tag = tag->nd_next;
-		    continue;
-		}
-		if (RTEST(rb_eval(self, tag->nd_head))) {
-		    node = node->nd_body;
-		    goto again;
-		}
-		tag = tag->nd_next;
-	    }
-	    node = node->nd_next;
-	}
-	RETURN(Qnil);
-
-      case NODE_CASE:
-	{
-	    VALUE val;
-
-	    val = rb_eval(self, node->nd_head);
-	    node = node->nd_body;
-	    while (node) {
-		NODE *tag;
-
-		if (nd_type(node) != NODE_WHEN) {
-		    goto again;
-		}
-		tag = node->nd_head;
-		while (tag) {
-		    EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self,
-				    ruby_frame->this_func,
-				    ruby_frame->this_class);
-		    if (tag->nd_head && nd_type(tag->nd_head) == NODE_WHEN) {
-			VALUE v = rb_eval(self, tag->nd_head->nd_head);
-			long i;
-
-			if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v);
-			for (i=0; i<RARRAY(v)->len; i++) {
-			    if (RTEST(rb_funcall2(RARRAY(v)->ptr[i], eqq, 1, &val))){
-				node = node->nd_body;
-				goto again;
-			    }
-			}
-			tag = tag->nd_next;
-			continue;
-		    }
-		    if (RTEST(rb_funcall2(rb_eval(self, tag->nd_head), eqq, 1, &val))) {
-			node = node->nd_body;
-			goto again;
-		    }
-		    tag = tag->nd_next;
-		}
-		node = node->nd_next;
-	    }
-	}
-	RETURN(Qnil);
-
-      case NODE_WHILE:
-	PUSH_TAG(PROT_LOOP);
-	result = Qnil;
-	switch (state = EXEC_TAG()) {
-	  case 0:
-	    if (node->nd_state && !RTEST(rb_eval(self, node->nd_cond)))
-		goto while_out;
-	    do {
-	      while_redo:
-		rb_eval(self, node->nd_body);
-	      while_next:
-		;
-	    } while (RTEST(rb_eval(self, node->nd_cond)));
-	    break;
-
-	  case TAG_REDO:
-	    state = 0;
-	    goto while_redo;
-	  case TAG_NEXT:
-	    state = 0;
-	    goto while_next;
-	  case TAG_BREAK:
-	    if (TAG_DST()) {
-		state = 0;
-		result = prot_tag->retval;
-	    }
-	    /* fall through */
-	  default:
-	    break;
-	}
-      while_out:
-	POP_TAG();
-	if (state) JUMP_TAG(state);
-	RETURN(result);
-
-      case NODE_UNTIL:
-	PUSH_TAG(PROT_LOOP);
-	result = Qnil;
-	switch (state = EXEC_TAG()) {
-	  case 0:
-	    if (node->nd_state && RTEST(rb_eval(self, node->nd_cond)))
-		goto until_out;
-	    do {
-	      until_redo:
-		rb_eval(self, node->nd_body);
-	      until_next:
-		;
-	    } while (!RTEST(rb_eval(self, node->nd_cond)));
-	    break;
-
-	  case TAG_REDO:
-	    state = 0;
-	    goto until_redo;
-	  case TAG_NEXT:
-	    state = 0;
-	    goto until_next;
-	  case TAG_BREAK:
-	    if (TAG_DST()) {
-		state = 0;
-		result = prot_tag->retval;
-	    }
-	    /* fall through */
-	  default:
-	    break;
-	}
-      until_out:
-	POP_TAG();
-	if (state) JUMP_TAG(state);
-	RETURN(result);
-
-      case NODE_BLOCK_PASS:
-	result = block_pass(self, node);
-	break;
-
-      case NODE_LAMBDA:
-	PUSH_TAG(PROT_LOOP);
-	PUSH_BLOCK(node->nd_var, node->nd_body);
-
-	state = EXEC_TAG();
-	PUSH_ITER(ITER_PRE);
-	ruby_iter->iter = ruby_frame->iter = ITER_CUR;
-	result = proc_lambda();
-	POP_ITER();
-	POP_BLOCK();
-	POP_TAG();
-	break;
-
-      case NODE_ITER:
-      case NODE_FOR:
-	{
-	    PUSH_TAG(PROT_LOOP);
-	    PUSH_BLOCK(node->nd_var, node->nd_body);
-
-	    state = EXEC_TAG();
-	    if (state == 0) {
-	      iter_retry:
-		PUSH_ITER(ITER_PRE);
-		if (nd_type(node) == NODE_ITER) {
-		    result = rb_eval(self, node->nd_iter);
-		}
-		else if (nd_type(node) == NODE_LAMBDA) {
-		    ruby_iter->iter = ruby_frame->iter = ITER_CUR;
-		    result = rb_block_proc();
-		}
-		else {
-		    VALUE recv;
-
-		    _block.flags &= ~BLOCK_D_SCOPE;
-		    BEGIN_CALLARGS;
-		    recv = rb_eval(self, node->nd_iter);
-		    END_CALLARGS;
-		    ruby_current_node = node;
-		    SET_CURRENT_SOURCE();
-		    result = rb_call(CLASS_OF(recv),recv,each,0,0,0);
-		}
-		POP_ITER();
-	    }
-	    else if (state == TAG_BREAK && TAG_DST()) {
-		result = prot_tag->retval;
-		state = 0;
-	    }
-	    else if (state == TAG_RETRY && ruby_block == &_block) {
-		state = 0;
-		goto iter_retry;
-	    }
-	    POP_BLOCK();
-	    POP_TAG();
-	    switch (state) {
-	      case 0:
-		break;
-	      default:
-		JUMP_TAG(state);
-	    }
-	}
-	break;
-
-      case NODE_BREAK:
-	break_jump(rb_eval(self, node->nd_stts));
-	break;
-
-      case NODE_NEXT:
-	CHECK_INTS;
-	return_value(rb_eval(self, node->nd_stts));
-	JUMP_TAG(TAG_NEXT);
-	break;
-
-      case NODE_REDO:
-	CHECK_INTS;
-	JUMP_TAG(TAG_REDO);
-	break;
-
-      case NODE_RETRY:
-	CHECK_INTS;
-	JUMP_TAG(TAG_RETRY);
-	break;
-
-      case NODE_SPLAT:
-	result = splat_value(rb_eval(self, node->nd_head));
-	break;
-
-      case NODE_TO_ARY:
-	result = rb_ary_to_ary(rb_eval(self, node->nd_head));
-	break;
-
-      case NODE_SVALUE:
-	result = avalue_splat(rb_eval(self, node->nd_head));
-	if (result == Qundef) result = Qnil;
-	break;
-
-      case NODE_YIELD:
-	if (node->nd_head) {
-	    result = rb_eval(self, node->nd_head);
-	    ruby_current_node = node;
-	}
-	else {
-	    result = Qundef;	/* no arg */
-	}
-	SET_CURRENT_SOURCE();
-	result = rb_yield_0(result, 0, 0, 0, node->nd_state);
-	break;
-
-      case NODE_RESCUE:
-	{
-	    volatile VALUE e_info = ruby_errinfo;
-	    volatile int rescuing = 0;
-
-	    PUSH_TAG(PROT_NONE);
-	    if ((state = EXEC_TAG()) == 0) {
-	      retry_entry:
-		result = rb_eval(self, node->nd_head);
-	    }
-	    else if (rescuing) {
-		if (rescuing < 0) {
-		    /* in rescue argument, just reraise */
-		}
-		else if (state == TAG_RETRY) {
-		    rescuing = state = 0;
-		    ruby_errinfo = e_info;
-		    goto retry_entry;
-		}
-		else if (state != TAG_RAISE) {
-		    result = prot_tag->retval;
-		}
-	    }
-	    else if (state == TAG_RAISE) {
-		NODE *resq = node->nd_resq;
-
-		rescuing = -1;
-		while (resq) {
-		    ruby_current_node = resq;
-		    if (handle_rescue(self, resq)) {
-			state = 0;
-			rescuing = 1;
-			result = rb_eval(self, resq->nd_body);
-			break;
-		    }
-		    resq = resq->nd_head; /* next rescue */
-		}
-	    }
-	    else {
-		result = prot_tag->retval;
-	    }
-	    POP_TAG();
-	    if (state != TAG_RAISE) ruby_errinfo = e_info;
-	    if (state) {
-		if (state == TAG_NEXT) prot_tag->retval = result;
-		JUMP_TAG(state);
-	    }
-	    /* no exception raised */
-	    if (!rescuing && (node = node->nd_else)) { /* else clause given */
-		goto again;
-	    }
-	}
-	break;
-
-      case NODE_ENSURE:
-	PUSH_TAG(PROT_NONE);
-	if ((state = EXEC_TAG()) == 0) {
-	    result = rb_eval(self, node->nd_head);
-	}
-	POP_TAG();
-	if (node->nd_ensr) {
-	    VALUE retval = prot_tag->retval; /* save retval */
-	    VALUE errinfo = ruby_errinfo;
-
-	    rb_eval(self, node->nd_ensr);
-	    return_value(retval);
-	    ruby_errinfo = errinfo;
-	}
-	if (state) JUMP_TAG(state);
-	break;
-
-      case NODE_AND:
-	result = rb_eval(self, node->nd_1st);
-	if (!RTEST(result)) break;
-	node = node->nd_2nd;
-	goto again;
-
-      case NODE_OR:
-	result = rb_eval(self, node->nd_1st);
-	if (RTEST(result)) break;
-	node = node->nd_2nd;
-	goto again;
-
-      case NODE_NOT:
-	if (RTEST(rb_eval(self, node->nd_body))) result = Qfalse;
-	else result = Qtrue;
-	break;
-
-      case NODE_DOT2:
-      case NODE_DOT3:
-        {
-	    VALUE beg = rb_eval(self, node->nd_beg);
-	    VALUE end = rb_eval(self, node->nd_end);
-	    result = rb_range_new(beg, end, nd_type(node) == NODE_DOT3);
-	}
-	break;
-
-      case NODE_FLIP2:		/* like AWK */
-	{
-	    VALUE *flip = rb_svar(node->nd_cnt);
-	    if (!flip) rb_bug("unexpected local variable");
-	    if (!RTEST(*flip)) {
-		if (RTEST(rb_eval(self, node->nd_beg))) {
-		    *flip = RTEST(rb_eval(self, node->nd_end))?Qfalse:Qtrue;
-		    result = Qtrue;
-		}
-		else {
-		    result = Qfalse;
-		}
-	    }
-	    else {
-		if (RTEST(rb_eval(self, node->nd_end))) {
-		    *flip = Qfalse;
-		}
-		result = Qtrue;
-	    }
-	}
-	break;
-
-      case NODE_FLIP3:		/* like SED */
-	{
-	    VALUE *flip = rb_svar(node->nd_cnt);
-	    if (!flip) rb_bug("unexpected local variable");
-	    if (!RTEST(*flip)) {
-		result = RTEST(rb_eval(self, node->nd_beg)) ? Qtrue : Qfalse;
-		*flip = result;
-	    }
-	    else {
-		if (RTEST(rb_eval(self, node->nd_end))) {
-		    *flip = Qfalse;
-		}
-		result = Qtrue;
-	    }
-	}
-	break;
-
-      case NODE_RETURN:
-	return_jump(rb_eval(self, node->nd_stts));
-	break;
-
-      case NODE_ARGSCAT:
-	{
-	    VALUE args = rb_eval(self, node->nd_head);
-	    result = rb_ary_concat(args, splat_value(rb_eval(self, node->nd_body)));
-	}
-	break;
-
-      case NODE_ARGSPUSH:
-	{
-	    VALUE args = rb_ary_dup(rb_eval(self, node->nd_head));
-	    result = rb_ary_push(args, rb_eval(self, node->nd_body));
-	}
-	break;
-
-      case NODE_ATTRASGN:
-	{
-	    VALUE recv;
-	    int argc; VALUE *argv; /* used in SETUP_ARGS */
-	    int scope;
-	    TMP_PROTECT;
-
-	    BEGIN_CALLARGS;
-	    if (node->nd_recv == (NODE *)1) {
-		recv = self;
-		scope = 1;
-	    }
-	    else {
-		recv = rb_eval(self, node->nd_recv);
-		scope = 0;
-	    }
-	    SETUP_ARGS(node->nd_args);
-	    END_CALLARGS;
-
-	    ruby_current_node = node;
-	    SET_CURRENT_SOURCE();
-	    rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,scope);
-	    result = argv[argc-1];
-	}
-	break;
-
-      case NODE_CALL:
-	{
-	    VALUE recv;
-	    int argc; VALUE *argv; /* used in SETUP_ARGS */
-	    TMP_PROTECT;
-
-	    BEGIN_CALLARGS;
-	    recv = rb_eval(self, node->nd_recv);
-	    SETUP_ARGS(node->nd_args);
-	    END_CALLARGS;
-
-	    ruby_current_node = node;
-	    SET_CURRENT_SOURCE();
-	    result = rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,0);
-	}
-	break;
-
-      case NODE_FCALL:
-	{
-	    int argc; VALUE *argv; /* used in SETUP_ARGS */
-	    TMP_PROTECT;
-
-	    BEGIN_CALLARGS;
-	    SETUP_ARGS(node->nd_args);
-	    END_CALLARGS;
-
-	    ruby_current_node = node;
-	    SET_CURRENT_SOURCE();
-	    result = rb_call(CLASS_OF(self),self,node->nd_mid,argc,argv,1);
-	}
-	break;
-
-      case NODE_VCALL:
-	SET_CURRENT_SOURCE();
-	result = rb_call(CLASS_OF(self),self,node->nd_mid,0,0,2);
-	break;
-
-      case NODE_SUPER:
-      case NODE_ZSUPER:
-	{
-	    int argc; VALUE *argv; /* used in SETUP_ARGS */
-	    TMP_PROTECT;
-
-	    if (ruby_frame->this_class == 0) {
-		if (ruby_frame->this_func) {
-		    rb_name_error(ruby_frame->callee,
-				  "superclass method `%s' disabled",
-				  rb_id2name(ruby_frame->this_func));
-		}
-		else {
-		    rb_raise(rb_eNoMethodError, "super called outside of method");
-		}
-	    }
-	    if (nd_type(node) == NODE_ZSUPER) {
-		argc = ruby_frame->argc;
-		if (argc && ruby_frame->prev &&
-                    (ruby_frame->prev->flags & FRAME_DMETH)) {
-                    if (TYPE(RBASIC(ruby_scope)->klass) != T_ARRAY ||
-                        RARRAY(RBASIC(ruby_scope)->klass)->len != argc) {
-                        rb_raise(rb_eRuntimeError, 
-                                 "super: specify arguments explicitly");
-                    }
-                    argv = RARRAY(RBASIC(ruby_scope)->klass)->ptr;
-                }
-                else {
-                    argv = ruby_scope->local_vars + 2;
-                }
-	    }
-	    else {
-		BEGIN_CALLARGS;
-		SETUP_ARGS(node->nd_args);
-		END_CALLARGS;
-		ruby_current_node = node;
-	    }
-
-	    SET_CURRENT_SOURCE();
-	    result = rb_call_super(argc, argv);
-	}
-	break;
-
-      case NODE_SCOPE:
-	{
-	    struct FRAME frame;
-	    NODE *saved_cref = 0;
-
-	    frame = *ruby_frame;
-	    frame.tmp = ruby_frame;
-	    ruby_frame = &frame;
-
-	    PUSH_SCOPE();
-	    PUSH_TAG(PROT_NONE);
-	    if (node->nd_rval) {
-		saved_cref = ruby_cref;
-		ruby_cref = (NODE*)node->nd_rval;
-	    }
-	    if (node->nd_tbl) {
-		VALUE *vars = ALLOCA_N(VALUE, node->nd_tbl[0]+1);
-		*vars++ = (VALUE)node;
-		ruby_scope->local_vars = vars;
-		rb_mem_clear(ruby_scope->local_vars, node->nd_tbl[0]);
-		ruby_scope->local_tbl = node->nd_tbl;
-	    }
-	    else {
-		ruby_scope->local_vars = 0;
-		ruby_scope->local_tbl  = 0;
-	    }
-	    if ((state = EXEC_TAG()) == 0) {
-		result = rb_eval(self, node->nd_next);
-	    }
-	    POP_TAG();
-	    POP_SCOPE();
-	    ruby_frame = frame.tmp;
-	    if (saved_cref)
-		ruby_cref = saved_cref;
-	    if (state) JUMP_TAG(state);
-	}
-	break;
-
-      case NODE_OP_ASGN1:
-	{
-	    int argc; VALUE *argv; /* used in SETUP_ARGS */
-	    VALUE recv, val;
-	    NODE *rval;
-	    TMP_PROTECT;
-
-	    recv = rb_eval(self, node->nd_recv);
-	    rval = node->nd_args->nd_head;
-	    SETUP_ARGS0(node->nd_args->nd_next, node->nd_args->nd_alen - 1);
-	    val = rb_funcall2(recv, aref, argc-1, argv);
-	    switch (node->nd_mid) {
-	    case 0: /* OR */
-		if (RTEST(val)) RETURN(val);
-		val = rb_eval(self, rval);
-		break;
-	    case 1: /* AND */
-		if (!RTEST(val)) RETURN(val);
-		val = rb_eval(self, rval);
-		break;
-	    default:
-		val = rb_funcall(val, node->nd_mid, 1, rb_eval(self, rval));
-	    }
-	    argv[argc-1] = val;
-	    rb_funcall2(recv, aset, argc, argv);
-	    result = val;
-	}
-	break;
-
-      case NODE_OP_ASGN2:
-	{
-	    ID id = node->nd_next->nd_vid;
-	    VALUE recv, val;
-
-	    recv = rb_eval(self, node->nd_recv);
-	    val = rb_funcall(recv, id, 0);
-	    switch (node->nd_next->nd_mid) {
-	    case 0: /* OR */
-		if (RTEST(val)) RETURN(val);
-		val = rb_eval(self, node->nd_value);
-		break;
-	    case 1: /* AND */
-		if (!RTEST(val)) RETURN(val);
-		val = rb_eval(self, node->nd_value);
-		break;
-	    default:
-		val = rb_funcall(val, node->nd_next->nd_mid, 1,
-				 rb_eval(self, node->nd_value));
-	    }
-
-	    rb_funcall2(recv, node->nd_next->nd_aid, 1, &val);
-	    result = val;
-	}
-	break;
-
-      case NODE_OP_ASGN_AND:
-	result = rb_eval(self, node->nd_head);
-	if (!RTEST(result)) break;
-	node = node->nd_value;
-	goto again;
-
-      case NODE_OP_ASGN_OR:
-	if ((node->nd_aid && !is_defined(self, node->nd_head, 0, 0)) ||
-	    !RTEST(result = rb_eval(self, node->nd_head))) {
-	    node = node->nd_value;
-	    goto again;
-	}
-	break;
-
-      case NODE_MASGN:
-	result = massign(self, node, rb_eval(self, node->nd_value), 0);
-	break;
-
-      case NODE_LASGN:
-	if (ruby_scope->local_vars == 0)
-	    rb_bug("unexpected local variable assignment");
-	result = rb_eval(self, node->nd_value);
-	ruby_scope->local_vars[node->nd_cnt] = result;
-	break;
-
-      case NODE_DASGN:
-	result = rb_eval(self, node->nd_value);
-	dvar_asgn(node->nd_vid, result);
-	break;
-
-      case NODE_DASGN_CURR:
-	result = rb_eval(self, node->nd_value);
-	dvar_asgn_curr(node->nd_vid, result);
-	break;
-
-      case NODE_GASGN:
-	result = rb_eval(self, node->nd_value);
-	rb_gvar_set(node->nd_entry, result);
-	break;
-
-      case NODE_IASGN:
-	result = rb_eval(self, node->nd_value);
-	rb_ivar_set(self, node->nd_vid, result);
-	break;
-
-      case NODE_CDECL:
-	result = rb_eval(self, node->nd_value);
-	if (node->nd_vid == 0) {
-	    rb_const_set(class_prefix(self, node->nd_else), node->nd_else->nd_mid, result);
-	}
-	else {
-	    if (NIL_P(ruby_cbase)) {
-		rb_raise(rb_eTypeError, "no class/module to define constant");
-	    }
-	    rb_const_set(ruby_cbase, node->nd_vid, result);
-	}
-	break;
-
-      case NODE_CVDECL:
-	if (NIL_P(ruby_cbase)) {
-	    rb_raise(rb_eTypeError, "no class/module to define class variable");
-	}
-	result = rb_eval(self, node->nd_value);
-	rb_cvar_set(cvar_cbase(), node->nd_vid, result, Qtrue);
-	break;
-
-      case NODE_CVASGN:
-	result = rb_eval(self, node->nd_value);
-	rb_cvar_set(cvar_cbase(), node->nd_vid, result, Qfalse);
-	break;
-
-      case NODE_LVAR:
-	if (ruby_scope->local_vars == 0) {
-	    rb_bug("unexpected local variable");
-	}
-	result = ruby_scope->local_vars[node->nd_cnt];
-	break;
-
-      case NODE_DVAR:
-	result = rb_dvar_ref(node->nd_vid);
-	break;
-
-      case NODE_GVAR:
-	result = rb_gvar_get(node->nd_entry);
-	break;
-
-      case NODE_IVAR:
-	result = rb_ivar_get(self, node->nd_vid);
-	break;
-
-      case NODE_CONST:
-	result = ev_const_get(ruby_cref, node->nd_vid, self);
-	break;
-
-      case NODE_CVAR:
-	result = rb_cvar_get(cvar_cbase(), node->nd_vid);
-	break;
-
-      case NODE_BLOCK_ARG:
-	if (ruby_scope->local_vars == 0)
-	    rb_bug("unexpected block argument");
-	if (rb_block_given_p()) {
-	    result = rb_block_proc();
-	    ruby_scope->local_vars[node->nd_cnt] = result;
-	}
-	else {
-	    result = Qnil;
-	}
-	break;
-
-      case NODE_COLON2:
-	{
-	    VALUE klass;
-
-	    klass = rb_eval(self, node->nd_head);
-	    if (rb_is_const_id(node->nd_mid)) {
-		switch (TYPE(klass)) {
-		  case T_CLASS:
-		  case T_MODULE:
-		    result = rb_const_get_from(klass, node->nd_mid);
-		    break;
-		  default:
-		    rb_raise(rb_eTypeError, "%s is not a class/module",
-			     RSTRING(rb_obj_as_string(klass))->ptr);
-		    break;
-		}
-	    }
-	    else {
-		result = rb_funcall(klass, node->nd_mid, 0, 0);
-	    }
-	}
-	break;
-
-      case NODE_COLON3:
-	result = rb_const_get_from(rb_cObject, node->nd_mid);
-	break;
-
-      case NODE_NTH_REF:
-	result = rb_reg_nth_match(node->nd_nth, MATCH_DATA);
-	break;
-
-      case NODE_BACK_REF:
-	switch (node->nd_nth) {
-	  case '&':
-	    result = rb_reg_last_match(MATCH_DATA);
-	    break;
-	  case '`':
-	    result = rb_reg_match_pre(MATCH_DATA);
-	    break;
-	  case '\'':
-	    result = rb_reg_match_post(MATCH_DATA);
-	    break;
-	  case '+':
-	    result = rb_reg_match_last(MATCH_DATA);
-	    break;
-	  default:
-	    rb_bug("unexpected back-ref");
-	}
-	break;
-
-      case NODE_HASH:
-	{
-	    NODE *list;
-	    VALUE hash = rb_hash_new();
-	    VALUE key, val;
-
-	    list = node->nd_head;
-	    while (list) {
-		key = rb_eval(self, list->nd_head);
-		list = list->nd_next;
-		if (list == 0)
-		    rb_bug("odd number list for Hash");
-		val = rb_eval(self, list->nd_head);
-		list = list->nd_next;
-		rb_hash_aset(hash, key, val);
-	    }
-	    result = hash;
-	}
-	break;
-
-      case NODE_ZARRAY:		/* zero length list */
-	result = rb_ary_new();
-	break;
-
-      case NODE_ARRAY:
-	{
-	    VALUE ary;
-	    long i;
-
-	    i = node->nd_alen;
-	    ary = rb_ary_new2(i);
-	    for (i=0;node;node=node->nd_next) {
-		RARRAY(ary)->ptr[i++] = rb_eval(self, node->nd_head);
-		RARRAY(ary)->len = i;
-	    }
-
-	    result = ary;
-	}
-	break;
-
-      case NODE_VALUES:
-	{
-	    VALUE val;
-	    long i;
-
-	    i = node->nd_alen;
-	    val = rb_values_new2(i, 0);
-	    for (i=0;node;node=node->nd_next) {
-		RARRAY(val)->ptr[i++] = rb_eval(self, node->nd_head);
-		RARRAY(val)->len = i;
-	    }
-
-	    result = val;
-	}
-	break;
-
-      case NODE_STR:
-	result = rb_str_new3(node->nd_lit);
-	break;
-
-      case NODE_EVSTR:
-	result = rb_obj_as_string(rb_eval(self, node->nd_body));
-	break;
-
-      case NODE_DSTR:
-      case NODE_DXSTR:
-      case NODE_DREGX:
-      case NODE_DREGX_ONCE:
-      case NODE_DSYM:
-	{
-	    VALUE str, str2;
-	    NODE *list = node->nd_next;
-
-	    str = rb_str_new3(node->nd_lit);
-	    while (list) {
-		if (list->nd_head) {
-		    switch (nd_type(list->nd_head)) {
-		      case NODE_STR:
-			str2 = list->nd_head->nd_lit;
-			break;
-		      default:
-			str2 = rb_eval(self, list->nd_head);
-			break;
-		    }
-		    rb_str_append(str, str2);
-		    OBJ_INFECT(str, str2);
-		}
-		list = list->nd_next;
-	    }
-	    switch (nd_type(node)) {
-	      case NODE_DREGX:
-		result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
-				    node->nd_cflag);
-		break;
-	      case NODE_DREGX_ONCE:	/* regexp expand once */
-		result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
-				    node->nd_cflag);
-		nd_set_type(node, NODE_LIT);
-		node->nd_lit = result;
-		break;
-	      case NODE_LIT:
-		/* other thread may replace NODE_DREGX_ONCE to NODE_LIT */
-		goto again;
-	      case NODE_DXSTR:
-		result = rb_funcall(self, '`', 1, str);
-		break;
-	      case NODE_DSYM:
-		result = rb_str_intern(str);
-		break;
-	      default:
-		result = str;
-		break;
-	    }
-	}
-	break;
-
-      case NODE_XSTR:
-	result = rb_funcall(self, '`', 1, rb_str_new3(node->nd_lit));
-	break;
-
-      case NODE_LIT:
-	result = node->nd_lit;
-	break;
-
-      case NODE_DEFN:
-	if (node->nd_defn) {
-	    NODE *body,  *defn;
-	    VALUE origin;
-	    int noex;
-
-	    if (NIL_P(ruby_class)) {
-		rb_raise(rb_eTypeError, "no class/module to add method");
-	    }
-	    if (ruby_class == rb_cObject && node->nd_mid == init) {
-		rb_warn("redefining Object#initialize may cause infinite loop");
-	    }
-	    if (node->nd_mid == __id__ || node->nd_mid == __send__) {
-		rb_warn("redefining `%s' may cause serious problem",
-			rb_id2name(node->nd_mid));
-	    }
-	    rb_frozen_class_p(ruby_class);
-	    body = search_method(ruby_class, node->nd_mid, &origin);
-	    if (body){
-		if (RTEST(ruby_verbose) && ruby_class == origin && body->nd_cnt == 0 && body->nd_body) {
-		    rb_warning("method redefined; discarding old %s", rb_id2name(node->nd_mid));
-		}
-	    }
-
-	    if (SCOPE_TEST(SCOPE_PRIVATE) || node->nd_mid == init) {
-		noex = NOEX_PRIVATE;
-	    }
-	    else if (SCOPE_TEST(SCOPE_PROTECTED)) {
-		noex = NOEX_PROTECTED;
-	    }
-	    else {
-		noex = NOEX_PUBLIC;
-	    }
-	    if (body && origin == ruby_class && body->nd_body == 0) {
-		noex |= NOEX_NOSUPER;
-	    }
-
-	    defn = copy_node_scope(node->nd_defn, ruby_cref);
-	    rb_add_method(ruby_class, node->nd_mid, defn, noex);
-	    if (scope_vmode == SCOPE_MODFUNC) {
-		rb_add_method(rb_singleton_class(ruby_class),
-			      node->nd_mid, defn, NOEX_PUBLIC);
-	    }
-	    result = Qnil;
-	}
-	break;
-
-      case NODE_DEFS:
-	if (node->nd_defn) {
-	    VALUE recv = rb_eval(self, node->nd_recv);
-	    VALUE klass;
-	    NODE *body = 0, *defn;
-
-	    if (ruby_safe_level >= 4 && !OBJ_TAINTED(recv)) {
-		rb_raise(rb_eSecurityError, "Insecure: can't define singleton method");
-	    }
-	    if (FIXNUM_P(recv) || SYMBOL_P(recv)) {
-		rb_raise(rb_eTypeError,
-			 "can't define singleton method \"%s\" for %s",
-			 rb_id2name(node->nd_mid),
-			 rb_obj_classname(recv));
-	    }
-
-	    if (OBJ_FROZEN(recv)) rb_error_frozen("object");
-	    klass = rb_singleton_class(recv);
-	    if (st_lookup(RCLASS(klass)->m_tbl, node->nd_mid, (st_data_t *)&body)) {
-		if (ruby_safe_level >= 4) {
-		    rb_raise(rb_eSecurityError, "redefining method prohibited");
-		}
-		if (RTEST(ruby_verbose)) {
-		    rb_warning("redefine %s", rb_id2name(node->nd_mid));
-		}
-	    }
-	    defn = copy_node_scope(node->nd_defn, ruby_cref);
-	    rb_add_method(klass, node->nd_mid, defn,
-			  NOEX_PUBLIC|(body?body->nd_noex&NOEX_UNDEF:0));
-	    result = Qnil;
-	}
-	break;
-
-      case NODE_UNDEF:
-	if (NIL_P(ruby_class)) {
-	    rb_raise(rb_eTypeError, "no class to undef method");
-	}
-	rb_undef(ruby_class, rb_to_id(rb_eval(self, node->u2.node)));
-	result = Qnil;
-	break;
-
-      case NODE_ALIAS:
-	if (NIL_P(ruby_class)) {
-	    rb_raise(rb_eTypeError, "no class to make alias");
-	}
-	rb_alias(ruby_class, rb_to_id(rb_eval(self, node->u1.node)),
-		             rb_to_id(rb_eval(self, node->u2.node)));
-	result = Qnil;
-	break;
-
-      case NODE_VALIAS:
-	rb_alias_variable(node->u1.id, node->u2.id);
-	result = Qnil;
-	break;
-
-      case NODE_CLASS:
-	{
-	    VALUE super, klass, tmp, cbase;
-	    ID cname;
-	    int gen = Qfalse;
-
-	    cbase = class_prefix(self, node->nd_cpath);
-	    cname = node->nd_cpath->nd_mid;
-
-	    if (NIL_P(ruby_cbase)) {
-		rb_raise(rb_eTypeError, "no outer class/module");
-	    }
-	    if (node->nd_super) {
-	       super = rb_eval(self, node->nd_super);
-	       rb_check_inheritable(super);
-	    }
-	    else {
-		super = 0;
-	    }
-
-	    if (rb_const_defined_at(cbase, cname)) {
-		klass = rb_const_get_at(cbase, cname);
-		if (TYPE(klass) != T_CLASS) {
-		    rb_raise(rb_eTypeError, "%s is not a class",
-			     rb_id2name(cname));
-		}
-		if (super) {
-		    tmp = rb_class_real(RCLASS(klass)->super);
-		    if (tmp != super) {
-			rb_raise(rb_eTypeError, "superclass mismatch for class %s",
-				 rb_id2name(cname));
-		    }
-		    super = 0;
-		}
-		if (ruby_safe_level >= 4) {
-		    rb_raise(rb_eSecurityError, "extending class prohibited");
-		}
-	    }
-	    else {
-		if (!super) super = rb_cObject;
-		klass = rb_define_class_id(cname, super);
-		rb_set_class_path(klass, cbase, rb_id2name(cname));
-		rb_const_set(cbase, cname, klass);
-		gen = Qtrue;
-	    }
-	    if (ruby_wrapper) {
-		rb_extend_object(klass, ruby_wrapper);
-		rb_include_module(klass, ruby_wrapper);
-	    }
-	    if (super && gen) {
-		rb_class_inherited(super, klass);
-	    }
-	    result = module_setup(klass, node);
-	}
-	break;
-
-      case NODE_MODULE:
-	{
-	    VALUE module, cbase;
-	    ID cname;
-
-	    if (NIL_P(ruby_cbase)) {
-		rb_raise(rb_eTypeError, "no outer class/module");
-	    }
-	    cbase = class_prefix(self, node->nd_cpath);
-	    cname = node->nd_cpath->nd_mid;
-	    if (rb_const_defined_at(cbase, cname)) {
-		module = rb_const_get_at(cbase, cname);
-		if (TYPE(module) != T_MODULE) {
-		    rb_raise(rb_eTypeError, "%s is not a module",
-			     rb_id2name(cname));
-		}
-		if (ruby_safe_level >= 4) {
-		    rb_raise(rb_eSecurityError, "extending module prohibited");
-		}
-	    }
-	    else {
-		module = rb_define_module_id(cname);
-		rb_set_class_path(module, cbase, rb_id2name(cname));
-		rb_const_set(cbase, cname, module);
-	    }
-	    if (ruby_wrapper) {
-		rb_extend_object(module, ruby_wrapper);
-		rb_include_module(module, ruby_wrapper);
-	    }
-
-	    result = module_setup(module, node);
-	}
-	break;
-
-      case NODE_SCLASS:
-	{
-	    VALUE klass;
-
-	    result = rb_eval(self, node->nd_recv);
-	    if (FIXNUM_P(result) || SYMBOL_P(result)) {
-		rb_raise(rb_eTypeError, "no singleton class for %s",
-			 rb_obj_classname(result));
-	    }
-	    if (ruby_safe_level >= 4 && !OBJ_TAINTED(result))
-		rb_raise(rb_eSecurityError, "Insecure: can't extend object");
-	    klass = rb_singleton_class(result);
-
-	    if (ruby_wrapper) {
-		rb_extend_object(klass, ruby_wrapper);
-		rb_include_module(klass, ruby_wrapper);
-	    }
-
-	    result = module_setup(klass, node);
-	}
-	break;
-
-      case NODE_DEFINED:
-	{
-	    char buf[20];
-	    const char *desc = is_defined(self, node->nd_head, buf, 0);
-
-	    if (desc) result = rb_str_new2(desc);
-	    else result = Qnil;
-	}
-	break;
-
-      default:
-	unknown_node(node);
-    }
-  finish:
-    CHECK_INTS;
-    if (contnode) {
-	node = contnode;
-	contnode = 0;
-	goto again;
-    }
-    return result;
-}
-
-static VALUE
-module_setup(module, n)
-    VALUE module;
-    NODE *n;
-{
-    NODE * volatile node = n->nd_body;
-    int state;
-    struct FRAME frame;
-    VALUE result = Qnil;	/* OK */
-    TMP_PROTECT;
-
-    frame = *ruby_frame;
-    frame.tmp = ruby_frame;
-    ruby_frame = &frame;
-
-    PUSH_CLASS(module);
-    PUSH_SCOPE();
-    PUSH_VARS();
-
-    if (node->nd_tbl) {
-	VALUE *vars = TMP_ALLOC(node->nd_tbl[0]+1);
-	*vars++ = (VALUE)node;
-	ruby_scope->local_vars = vars;
-	rb_mem_clear(ruby_scope->local_vars, node->nd_tbl[0]);
-	ruby_scope->local_tbl = node->nd_tbl;
-    }
-    else {
-	ruby_scope->local_vars = 0;
-	ruby_scope->local_tbl  = 0;
-    }
-
-    PUSH_CREF(module);
-    PUSH_TAG(PROT_NONE);
-    if ((state = EXEC_TAG()) == 0) {
-	EXEC_EVENT_HOOK(RUBY_EVENT_CLASS, n, ruby_cbase,
-			ruby_frame->this_func, ruby_frame->this_class);
-	result = rb_eval(ruby_cbase, node->nd_next);
-    }
-    POP_TAG();
-    POP_CREF();
-    POP_VARS();
-    POP_SCOPE();
-    POP_CLASS();
-
-    ruby_frame = frame.tmp;
-    EXEC_EVENT_HOOK(RUBY_EVENT_END, n, 0, ruby_frame->this_func,
-		    ruby_frame->this_class);
-    if (state) JUMP_TAG(state);
-
-    return result;
-}
-
 static NODE *basic_respond_to = 0;
 
 int
@@ -4670,9 +3051,12 @@
 int
 rb_block_given_p()
 {
-    if (ruby_frame->iter == ITER_CUR && ruby_block)
-	return Qtrue;
+  if(GC_GUARDED_PTR_REF(GET_THREAD()->cfp->lfp[0])){
+    return Qtrue;
+  }
+  else{
     return Qfalse;
+  }
 }
 
 int
@@ -4809,259 +3193,20 @@
     VALUE val, self, klass;	/* OK */
     int flags, avalue;
 {
-    NODE *node, *var;
-    volatile VALUE result = Qnil;
-    volatile VALUE old_cref;
-    volatile VALUE old_wrapper;
-    struct BLOCK * volatile block;
-    struct SCOPE * volatile old_scope;
-    int old_vmode;
-    struct FRAME frame;
-    NODE *cnode = ruby_current_node;
-    int lambda = flags & YIELD_LAMBDA_CALL;
-    int state;
-
-    rb_need_block();
-
-    PUSH_VARS();
-    block = ruby_block;
-    frame = block->frame;
-    frame.prev = ruby_frame;
-    frame.node = cnode;
-    ruby_frame = &(frame);
-    old_cref = (VALUE)ruby_cref;
-    ruby_cref = block->cref;
-    old_wrapper = ruby_wrapper;
-    ruby_wrapper = block->wrapper;
-    old_scope = ruby_scope;
-    ruby_scope = block->scope;
-    old_vmode = scope_vmode;
-    scope_vmode = (flags & YIELD_PUBLIC_DEF) ? SCOPE_PUBLIC : block->vmode;
-    ruby_block = block->prev;
-    if (block->flags & BLOCK_D_SCOPE) {
-	/* put place holder for dynamic (in-block) local variables */
-	ruby_dyna_vars = new_dvar(0, 0, block->dyna_vars);
-    }
-    else {
-	/* FOR does not introduce new scope */
-	ruby_dyna_vars = block->dyna_vars;
-    }
-    PUSH_CLASS(klass ? klass : block->klass);
-    if (!klass) {
-	self = block->self;
-    }
-    node = block->body;
-    var = block->var;
-
-    if (var) {
-	PUSH_TAG(PROT_NONE);
-	if ((state = EXEC_TAG()) == 0) {
-	    NODE *bvar = NULL;
-	  block_var:
-	    if (var == (NODE*)1) { /* no parameter || */
-		if (lambda && RARRAY(val)->len != 0) {
-		    rb_raise(rb_eArgError, "wrong number of arguments (%ld for 0)",
-			     RARRAY(val)->len);
-		}
-	    }
-	    else if (var == (NODE*)2) {
-		if (TYPE(val) == T_ARRAY && RARRAY(val)->len != 0) {
-		    rb_raise(rb_eArgError, "wrong number of arguments (%ld for 0)",
-			     RARRAY(val)->len);
-		}
-	    }
-	    else if (!bvar && nd_type(var) == NODE_BLOCK_PASS) {
-		bvar = var->nd_body;
-		var = var->nd_args;
-		goto block_var;
-	    }
-	    else if (nd_type(var) == NODE_MASGN) {
-		if (!avalue) {
-		    val = svalue_to_mrhs(val, var->nd_head);
-		}
-		massign(self, var, val, lambda);
-	    }
-	    else if (nd_type(var) == NODE_ARGS) {
-		if (!avalue) {
-		    val = svalue_to_mrhs(val, var->nd_head);
-		}
-		formal_assign(self, var, RARRAY(val)->len, RARRAY(val)->ptr, 0);
-	    }
-	    else if (nd_type(var) == NODE_BLOCK) {
-		if (var->nd_next) {
-		    bvar = var->nd_next->nd_head;
-		}
-		var = var->nd_head;
-		goto block_var;
-	    }
-	    else {
-		int len = 0;
-		if (avalue) {
-		    len = RARRAY(val)->len;
-		    if (len == 0) {
-			goto zero_arg;
-		    }
-		    if (len == 1) {
-			val = RARRAY(val)->ptr[0];
-		    }
-		    else {
-			goto multi_values;
-		    }
-		}
-		else if (val == Qundef) {
-		  zero_arg:
-		    val = Qnil;
-		  multi_values:
-		    {
-			ruby_current_node = var;
-			rb_warn("multiple values for a block parameter (%d for 1)\n\tfrom %s:%d",
-				len, cnode->nd_file, nd_line(cnode));
-			ruby_current_node = cnode;
-		    }
-		}
-		assign(self, var, val, lambda);
-	    }
-	    if (bvar) {
-		VALUE blk;
-		if (flags & YIELD_PROC_CALL)
-		    blk = block->block_obj;
-		else
-		    blk = rb_block_proc();
-		assign(self, bvar, blk, 0);
-	    }
-	}
-	POP_TAG();
-	if (state) goto pop_state;
-    }
-    else if (lambda && RARRAY(val)->len != 0 &&
-	     (!node || nd_type(node) != NODE_IFUNC ||
-	      node->nd_cfnc != bmcall)) {
-	rb_raise(rb_eArgError, "wrong number of arguments (%ld for 0)",
-		 RARRAY(val)->len);
-    }
-    if (!node) {
-	state = 0;
-	goto pop_state;
-    }
-    ruby_current_node = node;
-
-    PUSH_ITER(block->iter);
-    PUSH_TAG(lambda ? PROT_NONE : PROT_YIELD);
-    if ((state = EXEC_TAG()) == 0) {
-      redo:
-	if (nd_type(node) == NODE_CFUNC || nd_type(node) == NODE_IFUNC) {
-	    if (node->nd_state == YIELD_FUNC_AVALUE) {
-		if (!avalue) {
-		    val = svalue_to_avalue(val);
-		}
-	    }
-	    else {
-		if (avalue) {
-		    val = avalue_to_svalue(val);
-		}
-		if (val == Qundef && node->nd_state != YIELD_FUNC_SVALUE)
-		    val = Qnil;
-	    }
-	    if ((block->flags&BLOCK_FROM_METHOD) && RTEST(block->block_obj)) {
-		struct BLOCK *data, _block;
-		Data_Get_Struct(block->block_obj, struct BLOCK, data);
-		_block = *data;
-		_block.outer = ruby_block;
-		_block.uniq = block_unique++;
-		ruby_block = &_block;
-		PUSH_ITER(ITER_PRE);
-		ruby_frame->iter = ITER_CUR;
-		result = (*node->nd_cfnc)(val, node->nd_tval, self);
-		POP_ITER();
-	    }
-	    else {
-		result = (*node->nd_cfnc)(val, node->nd_tval, self);
-	    }
-	}
-	else {
-	    result = rb_eval(self, node);
-	}
-    }
-    else {
-	switch (state) {
-	  case TAG_REDO:
-	    state = 0;
-	    CHECK_INTS;
-	    goto redo;
-	  case TAG_NEXT:
-	    state = 0;
-	    result = prot_tag->retval;
-	    break;
-	  case TAG_BREAK:
-	    if (TAG_DST()) {
-		result = prot_tag->retval;
-	    }
-	    else {
-		lambda = Qtrue;	/* just pass TAG_BREAK */
-	    }
-	    break;
-	  default:
-	    break;
-	}
-    }
-    POP_TAG();
-    POP_ITER();
-  pop_state:
-    POP_CLASS();
-    if (ruby_dyna_vars && (block->flags & BLOCK_D_SCOPE) &&
-	!FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) {
-	struct RVarmap *vars = ruby_dyna_vars;
-
-	if (ruby_dyna_vars->id == 0) {
-	    vars = ruby_dyna_vars->next;
-	    rb_gc_force_recycle((VALUE)ruby_dyna_vars);
-	    while (vars && vars->id != 0 && vars != block->dyna_vars) {
-		struct RVarmap *tmp = vars->next;
-		rb_gc_force_recycle((VALUE)vars);
-		vars = tmp;
-	    }
-	}
-    }
-    POP_VARS();
-    ruby_block = block;
-    ruby_frame = ruby_frame->prev;
-    ruby_cref = (NODE*)old_cref;
-    ruby_wrapper = old_wrapper;
-    if (ruby_scope->flags & SCOPE_DONT_RECYCLE)
-	scope_dup(old_scope);
-    ruby_scope = old_scope;
-    scope_vmode = old_vmode;
-    switch (state) {
-      case 0:
-	break;
-      case TAG_BREAK:
-	if (!lambda) {
-	    struct tag *tt = prot_tag;
-
-	    while (tt) {
-		if (tt->tag == PROT_LOOP && tt->blkid == ruby_block->uniq) {
-		    tt->dst = (VALUE)tt->frame->uniq;
-		    tt->retval = result;
-		    JUMP_TAG(TAG_BREAK);
-		}
-		tt = tt->prev;
-	    }
-	    proc_jump_error(TAG_BREAK, result);
-	}
-	/* fall through */
-      default:
-	JUMP_TAG(state);
-	break;
-    }
-    ruby_current_node = cnode;
-    return result;
+  if(avalue){
+    return th_invoke_yield(GET_THREAD(),
+                           RARRAY(val)->len, RARRAY(val)->ptr);
+  }
+  else{
+    return th_invoke_yield(GET_THREAD(), 1, &val);
+  }
 }
 
 VALUE
 rb_yield(val)
     VALUE val;
 {
-    return rb_yield_0(val, 0, 0, 0, Qfalse);
+  return rb_yield_0(val, 0, 0, 0, Qfalse);
 }
 
 VALUE
@@ -5131,216 +3276,41 @@
     return Qnil;		/* dummy */
 }
 
-static VALUE
-massign(self, node, val, pcall)
-    VALUE self;
-    NODE *node;
-    VALUE val;
-    int pcall;
-{
-    NODE *list;
-    long i = 0, len;
-
-    len = RARRAY(val)->len;
-    list = node->nd_head;
-    for (; list && i<len; i++) {
-	assign(self, list->nd_head, RARRAY(val)->ptr[i], pcall);
-	list = list->nd_next;
-    }
-    if (pcall && list) goto arg_error;
-    if (node->nd_args) {
-	if ((long)(node->nd_args) == -1) {
-	    /* no check for mere `*' */
-	}
-	else if (!list && i<len) {
-	    assign(self, node->nd_args, rb_ary_new4(len-i, RARRAY(val)->ptr+i), pcall);
-	}
-	else {
-	    assign(self, node->nd_args, rb_ary_new2(0), pcall);
-	}
-    }
-    else if (pcall && i < len) {
-	goto arg_error;
-    }
-
-    while (list) {
-	i++;
-	assign(self, list->nd_head, Qnil, pcall);
-	list = list->nd_next;
-    }
-    return val;
-
-  arg_error:
-    while (list) {
-	i++;
-	list = list->nd_next;
-    }
-    rb_raise(rb_eArgError, "wrong number of arguments (%ld for %ld)", len, i);
-}
-
-static void
-assign(self, lhs, val, pcall)
-    VALUE self;
-    NODE *lhs;
-    VALUE val;
-    int pcall;
-{
-    ruby_current_node = lhs;
-    if (val == Qundef) {
-	rb_warning("assigning void value");
-	val = Qnil;
-    }
-    switch (nd_type(lhs)) {
-      case NODE_GASGN:
-	rb_gvar_set(lhs->nd_entry, val);
-	break;
-
-      case NODE_IASGN:
-	rb_ivar_set(self, lhs->nd_vid, val);
-	break;
-
-      case NODE_LASGN:
-	if (ruby_scope->local_vars == 0)
-	    rb_bug("unexpected local variable assignment");
-	ruby_scope->local_vars[lhs->nd_cnt] = val;
-	break;
-
-      case NODE_DASGN:
-	dvar_asgn(lhs->nd_vid, val);
-	break;
-
-      case NODE_DASGN_CURR:
-	dvar_asgn_curr(lhs->nd_vid, val);
-	break;
-
-      case NODE_CDECL:
-	if (lhs->nd_vid == 0) {
-	    rb_const_set(class_prefix(self, lhs->nd_else), lhs->nd_else->nd_mid, val);
-	}
-	else {
-	    rb_const_set(ruby_cbase, lhs->nd_vid, val);
-	}
-	break;
-
-      case NODE_CVDECL:
-	if (RTEST(ruby_verbose) && FL_TEST(ruby_cbase, FL_SINGLETON)) {
-	    rb_warn("declaring singleton class variable");
-	}
-	rb_cvar_set(cvar_cbase(), lhs->nd_vid, val, Qtrue);
-	break;
-
-      case NODE_CVASGN:
-	rb_cvar_set(cvar_cbase(), lhs->nd_vid, val, Qfalse);
-	break;
-
-      case NODE_MASGN:
-	massign(self, lhs, svalue_to_mrhs(val, lhs->nd_head), pcall);
-	break;
-
-      case NODE_CALL:
-      case NODE_ATTRASGN:
-	{
-	    VALUE recv;
-	    int scope;
-	    if (lhs->nd_recv == (NODE *)1) {
-		recv = self;
-		scope = 1;
-	    }
-	    else {
-		recv = rb_eval(self, lhs->nd_recv);
-		scope = 0;
-	    }
-	    if (!lhs->nd_args) {
-		/* attr set */
-		ruby_current_node = lhs;
-		SET_CURRENT_SOURCE();
-		rb_call(CLASS_OF(recv), recv, lhs->nd_mid, 1, &val, scope);
-	    }
-	    else {
-		/* array set */
-		VALUE args;
-
-		args = rb_eval(self, lhs->nd_args);
-		rb_ary_push(args, val);
-		ruby_current_node = lhs;
-		SET_CURRENT_SOURCE();
-		rb_call(CLASS_OF(recv), recv, lhs->nd_mid,
-			RARRAY(args)->len, RARRAY(args)->ptr, scope);
-	    }
-	}
-	break;
-
-      default:
-	rb_bug("bug in variable assignment");
-	break;
-    }
-}
-
 VALUE
 rb_iterate(it_proc, data1, bl_proc, data2)
     VALUE (*it_proc) _((VALUE)), (*bl_proc)(ANYARGS);
     VALUE data1, data2;
 {
-    int state;
-    volatile VALUE retval = Qnil;
-    NODE *node = NEW_IFUNC(bl_proc, data2);
-    VALUE self = ruby_top_self;
+  int state;
+  volatile VALUE retval = Qnil;
+  NODE *node = NEW_IFUNC(bl_proc, data2);
 
-    PUSH_ITER(ITER_PRE);
-    PUSH_TAG(PROT_LOOP);
-    PUSH_BLOCK(0, node);
-    state = EXEC_TAG();
-    if (state == 0) {
+  PUSH_TAG(PROT_LOOP);
+  state = EXEC_TAG();
+  if (state == 0) {
   iter_retry:
-	retval = (*it_proc)(data1);
-    }
-    else if (state == TAG_BREAK && TAG_DST()) {
-	retval = prot_tag->retval;
-	state = 0;
-    }
-    else if (state == TAG_RETRY) {
-	state = 0;
-	goto iter_retry;
-    }
-    POP_BLOCK();
-    POP_TAG();
-    POP_ITER();
+    GET_THREAD()->ifuncnode = node;
+    retval = (*it_proc)(data1);
+  }
+  else if (state == TAG_BREAK && TAG_DST()) {
+    retval = prot_tag->retval;
+    state = 0;
+  }
+  else if (state == TAG_RETRY) {
+    state = 0;
+    goto iter_retry;
+  }
+  POP_TAG();
 
-    switch (state) {
-      case 0:
-	break;
-      default:
-	JUMP_TAG(state);
-    }
-    return retval;
+  switch (state) {
+  case 0:
+    break;
+  default:
+    JUMP_TAG(state);
+  }
+  return retval;
 }
 
-static int
-handle_rescue(self, node)
-    VALUE self;
-    NODE *node;
-{
-    int argc; VALUE *argv; /* used in SETUP_ARGS */
-    TMP_PROTECT;
-
-    if (!node->nd_args) {
-	return rb_obj_is_kind_of(ruby_errinfo, rb_eStandardError);
-    }
-
-    BEGIN_CALLARGS;
-    SETUP_ARGS(node->nd_args);
-    END_CALLARGS;
-
-    while (argc--) {
-	if (!rb_obj_is_kind_of(argv[0], rb_cModule)) {
-	    rb_raise(rb_eTypeError, "class or module required for rescue clause");
-	}
-	if (RTEST(rb_funcall(*argv, eqq, 1, ruby_errinfo))) return 1;
-	argv++;
-    }
-    return 0;
-}
-
 VALUE
 #ifdef HAVE_STDARG_PROTOTYPES
 rb_rescue2(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*r_proc)(ANYARGS), VALUE data2, ...)
@@ -5628,360 +3598,8 @@
     return rb_funcall2(obj, missing, argc+1, nargv);
 }
 
-static inline VALUE
-call_cfunc(func, recv, len, argc, argv)
-    VALUE (*func)();
-    VALUE recv;
-    int len, argc;
-    VALUE *argv;
-{
-    if (len >= 0 && argc != len) {
-	rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
-		 argc, len);
-    }
 
-    switch (len) {
-      case -2:
-	return (*func)(recv, rb_ary_new4(argc, argv));
-	break;
-      case -1:
-	return (*func)(argc, argv, recv);
-	break;
-      case 0:
-	return (*func)(recv);
-	break;
-      case 1:
-	return (*func)(recv, argv[0]);
-	break;
-      case 2:
-	return (*func)(recv, argv[0], argv[1]);
-	break;
-      case 3:
-	return (*func)(recv, argv[0], argv[1], argv[2]);
-	break;
-      case 4:
-	return (*func)(recv, argv[0], argv[1], argv[2], argv[3]);
-	break;
-      case 5:
-	return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4]);
-	break;
-      case 6:
-	return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-		       argv[5]);
-	break;
-      case 7:
-	return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-		       argv[5], argv[6]);
-	break;
-      case 8:
-	return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-		       argv[5], argv[6], argv[7]);
-	break;
-      case 9:
-	return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-		       argv[5], argv[6], argv[7], argv[8]);
-	break;
-      case 10:
-	return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-		       argv[5], argv[6], argv[7], argv[8], argv[9]);
-	break;
-      case 11:
-	return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-		       argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
-	break;
-      case 12:
-	return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-		       argv[5], argv[6], argv[7], argv[8], argv[9],
-		       argv[10], argv[11]);
-	break;
-      case 13:
-	return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-		       argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
-		       argv[11], argv[12]);
-	break;
-      case 14:
-	return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-		       argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
-		       argv[11], argv[12], argv[13]);
-	break;
-      case 15:
-	return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
-		       argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
-		       argv[11], argv[12], argv[13], argv[14]);
-	break;
-      default:
-	rb_raise(rb_eArgError, "too many arguments (%d)", len);
-	break;
-    }
-    return Qnil;		/* not reached */
-}
-
-static int
-formal_assign(recv, node, argc, argv, local_vars)
-    VALUE recv;
-    NODE *node;
-    int argc;
-    VALUE *argv;
-    VALUE *local_vars;
-{
-    int i;
-    int nopt = 0;
-
-    if (nd_type(node) != NODE_ARGS) {
-	rb_bug("no argument-node");
-    }
-
-    i = node->nd_frml ? RARRAY(node->nd_frml)->len : 0;
-    if (i > argc) {
-	rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, i);
-    }
-    if (!node->nd_rest) {
-	NODE *optnode = node->nd_opt;
-
-	nopt = i;
-	while (optnode) {
-	    nopt++;
-	    optnode = optnode->nd_next;
-	}
-	if (nopt < argc) {
-	    rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, nopt);
-	}
-    }
-    if (local_vars) {
-	if (i > 0) {
-	    /* +2 for $_ and $~ */
-	    MEMCPY(local_vars+2, argv, VALUE, i);
-	}
-    }
-    else {
-	int j;
-	VALUE a = node->nd_frml;
-
-	for (j=0; j<i; j++) {
-	    dvar_asgn_curr(SYM2ID(RARRAY(a)->ptr[j]), argv[j]);
-	}
-    }
-    argv += i; argc -= i;
-    if (node->nd_opt) {
-	NODE *opt = node->nd_opt;
-
-	while (opt && argc) {
-	    assign(recv, opt->nd_head, *argv, 1);
-	    argv++; argc--;
-	    ++i;
-	    opt = opt->nd_next;
-	}
-	if (opt) {
-	    rb_eval(recv, opt);
-	}
-    }
-    if (!node->nd_rest) {
-	i = nopt;
-    }
-    else {
-	VALUE v;
-
-	if (argc > 0) {
-	    v = rb_ary_new4(argc,argv);
-	    i = -i - 1;
-	}
-	else {
-	    v = rb_ary_new2(0);
-	}
-	assign(recv, node->nd_rest, v, 1);
-    }
-    return i;
-}
-
 static VALUE
-rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
-    VALUE klass, recv;
-    ID    id;
-    ID    oid;
-    int argc;			/* OK */
-    VALUE *argv;		/* OK */
-    NODE * volatile body;
-    int nosuper;
-{
-    NODE *b2;		/* OK */
-    volatile VALUE result = Qnil;
-    int itr;
-    static int tick;
-    volatile VALUE args;
-    TMP_PROTECT;
-
-    switch (ruby_iter->iter) {
-      case ITER_PRE:
-	itr = ITER_CUR;
-	break;
-      case ITER_CUR:
-      default:
-	itr = ITER_NOT;
-	break;
-    }
-
-    if ((++tick & 0xff) == 0) {
-	CHECK_INTS;		/* better than nothing */
-	stack_check();
-	rb_gc_finalize_deferred();
-    }
-    if (argc < 0) {
-	argc = -argc-1;
-	args = rb_ary_concat(rb_ary_new4(argc, argv), splat_value(argv[argc]));
-	argc = RARRAY(args)->len;
-	argv = RARRAY(args)->ptr;
-    }
-    PUSH_ITER(itr);
-    PUSH_FRAME();
-    ruby_frame->callee = id;
-    ruby_frame->this_func = oid;
-    ruby_frame->this_class = nosuper?0:klass;
-    ruby_frame->self = recv;
-    ruby_frame->argc = argc;
-
-    switch (nd_type(body)) {
-      case NODE_CFUNC:
-	{
-	    int len = body->nd_argc;
-
-	    if (len < -2) {
-		rb_bug("bad argc (%d) specified for `%s(%s)'",
-		       len, rb_class2name(klass), rb_id2name(id));
-	    }
-	    if (event_hooks) {
-		int state;
-
-		EXEC_EVENT_HOOK(RUBY_EVENT_C_CALL, ruby_current_node,
-				recv, id, klass);
-		PUSH_TAG(PROT_FUNC);
-		if ((state = EXEC_TAG()) == 0) {
-		    result = call_cfunc(body->nd_cfnc, recv, len, argc, argv);
-		}
-		POP_TAG();
-		ruby_current_node = ruby_frame->node;
-		EXEC_EVENT_HOOK(RUBY_EVENT_C_RETURN, ruby_current_node,
-				recv, id, klass);
-		if (state) JUMP_TAG(state);
-	    }
-	    else {
-		result = call_cfunc(body->nd_cfnc, recv, len, argc, argv);
-	    }
-	}
-	break;
-
-	/* for attr get/set */
-      case NODE_IVAR:
-	if (argc != 0) {
-	    rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
-	}
-	result = rb_attr_get(recv, body->nd_vid);
-	break;
-
-      case NODE_ATTRSET:
-	if (argc != 1)
-	    rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
-	result = rb_ivar_set(recv, body->nd_vid, argv[0]);
-	break;
-
-      case NODE_ZSUPER:		/* visibility override */
-	result = rb_call_super(argc, argv);
-	break;
-
-      case NODE_BMETHOD:
-	ruby_frame->flags |= FRAME_DMETH;
-	result = proc_invoke(body->nd_cval, rb_ary_new4(argc, argv), recv, klass);
-	break;
-
-      case NODE_SCOPE:
-	{
-	    int state;
-	    VALUE *local_vars;	/* OK */
-	    NODE *saved_cref = 0;
-
-	    PUSH_SCOPE();
-
-	    if (body->nd_rval) {
-		saved_cref = ruby_cref;
-		ruby_cref = (NODE*)body->nd_rval;
-	    }
-	    PUSH_CLASS(ruby_cbase);
-	    if (body->nd_tbl) {
-		local_vars = TMP_ALLOC(body->nd_tbl[0]+1);
-		*local_vars++ = (VALUE)body;
-		rb_mem_clear(local_vars, body->nd_tbl[0]);
-		ruby_scope->local_tbl = body->nd_tbl;
-		ruby_scope->local_vars = local_vars;
-	    }
-	    else {
-		local_vars = ruby_scope->local_vars = 0;
-		ruby_scope->local_tbl  = 0;
-	    }
-	    b2 = body = body->nd_next;
-
-	    PUSH_VARS();
-	    PUSH_TAG(PROT_FUNC);
-
-	    if ((state = EXEC_TAG()) == 0) {
-		NODE *node = 0;
-
-		if (nd_type(body) == NODE_ARGS) {
-		    node = body;
-		    body = 0;
-		}
-		else if (nd_type(body) == NODE_BLOCK) {
-		    node = body->nd_head;
-		    body = body->nd_next;
-		}
-		if (node) {
-		    ruby_frame->argc = formal_assign(recv, node, argc, argv, local_vars);
-		}
-
-		if (event_hooks) {
-		    EXEC_EVENT_HOOK(RUBY_EVENT_CALL, b2, recv, id, klass);
-		}
-		result = rb_eval(recv, body);
-	    }
-	    else if (state == TAG_RETURN && TAG_DST()) {
-		result = prot_tag->retval;
-		state = 0;
-	    }
-	    POP_TAG();
-	    POP_VARS();
-	    POP_CLASS();
-	    POP_SCOPE();
-	    ruby_cref = saved_cref;
-	    if (event_hooks) {
-		EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, body, recv, id, klass);
-	    }
-	    switch (state) {
-	      case 0:
-		break;
-
-	      case TAG_BREAK:
-	      case TAG_RETURN:
-		JUMP_TAG(state);
-		break;
-
-	      case TAG_RETRY:
-		if (rb_block_given_p()) JUMP_TAG(state);
-		/* fall through */
-	      default:
-		jump_tag_but_local_jump(state, result);
-		break;
-	    }
-	}
-	break;
-
-      default:
-	unknown_node(body);
-	break;
-    }
-    POP_FRAME();
-    POP_ITER();
-    return result;
-}
-
-static VALUE
 rb_call(klass, recv, mid, argc, argv, scope)
     VALUE klass, recv;
     ID    mid;
@@ -6032,7 +3650,19 @@
 	}
     }
 
-    return rb_call0(klass, recv, mid, id, argc, argv, body, noex & NOEX_NOSUPER);
+  {
+    VALUE val;
+    static int level;
+    int i;
+    //for(i=0; i<level; i++){printf("  ");}
+    //printf("invoke %s (%s)\n", rb_id2name(mid), node_name(nd_type(body)));
+    //level++;
+    val = th_call0(GET_THREAD(), klass, recv, mid, id, argc, argv, body, noex & NOEX_NOSUPER);
+    //level--;
+    //for(i=0; i<level; i++){printf("  ");}
+    //printf("done %s (%s)\n", rb_id2name(mid), node_name(nd_type(body)));
+    return val;
+  }
 }
 
 VALUE
@@ -6143,73 +3773,14 @@
     int argc;
     const VALUE *argv;
 {
-    VALUE result, self, klass;
-
-    if (ruby_frame->this_class == 0) {
-	rb_name_error(ruby_frame->callee, "calling `super' from `%s' is prohibited",
-		      rb_id2name(ruby_frame->this_func));
-    }
-
-    self = ruby_frame->self;
-    klass = ruby_frame->this_class;
-
-    PUSH_ITER(ruby_iter->iter ? ITER_PRE : ITER_NOT);
-    result = rb_call(RCLASS(klass)->super, self, ruby_frame->this_func, argc, argv, 3);
-    POP_ITER();
-
-    return result;
+  return th_call_super(GET_THREAD(), argc, argv);
 }
 
 static VALUE
 backtrace(lev)
     int lev;
 {
-    struct FRAME *frame = ruby_frame;
-    VALUE str;
-    volatile VALUE ary;
-    NODE *n;
-
-    ary = rb_ary_new();
-    if (frame->this_func == ID_ALLOCATOR) {
-	frame = frame->prev;
-    }
-    if (lev < 0) {
-	ruby_set_current_source();
-	if (frame->this_func) {
-	    str = rb_sprintf("%s:%d:in `%s'", ruby_sourcefile, ruby_sourceline,
-			     rb_id2name(frame->this_func));
-	}
-	else if (ruby_sourceline == 0) {
-	    str = rb_str_new2(ruby_sourcefile);
-	}
-	else {
-	    str = rb_sprintf("%s:%d", ruby_sourcefile, ruby_sourceline);
-	}
-	rb_ary_push(ary, str);
-	if (lev < -1) return ary;
-    }
-    else {
-	while (lev-- > 0) {
-	    frame = frame->prev;
-	    if (!frame) {
-		ary = Qnil;
-		break;
-	    }
-	}
-    }
-    for (; frame && (n = frame->node); frame = frame->prev) {
-	if (frame->prev && frame->prev->this_func) {
-	    if (frame->prev->node == n) continue;
-	    str = rb_sprintf("%s:%d:in `%s'", n->nd_file, nd_line(n),
-			     rb_id2name(frame->prev->this_func));
-	}
-	else {
-	    str = rb_sprintf("%s:%d", n->nd_file, nd_line(n));
-	}
-	rb_ary_push(ary, str);
-    }
-
-    return ary;
+  return yarv_backtrace(lev);
 }
 
 /*
@@ -6304,136 +3875,43 @@
     char *file;
     int line;
 {
-    struct BLOCK *data = NULL;
-    volatile VALUE result = Qnil;
-    struct SCOPE * volatile old_scope;
-    struct BLOCK * volatile old_block;
-    struct RVarmap * volatile old_dyna_vars;
-    VALUE volatile old_cref;
-    int volatile old_vmode;
-    volatile VALUE old_wrapper;
-    struct FRAME frame;
-    NODE *nodesave = ruby_current_node;
-    volatile int iter = ruby_frame->iter;
-    volatile int safe = ruby_safe_level;
-    int state;
-
-    if (!NIL_P(scope)) {
-	if (!rb_obj_is_proc(scope)) {
-	    rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc/Binding)",
-		     rb_obj_classname(scope));
-	}
-
-	Data_Get_Struct(scope, struct BLOCK, data);
-	/* PUSH BLOCK from data */
-	frame = data->frame;
-	frame.tmp = ruby_frame;	/* gc protection */
-	ruby_frame = &(frame);
-	old_scope = ruby_scope;
-	ruby_scope = data->scope;
-	old_block = ruby_block;
-	ruby_block = data->prev;
-	old_dyna_vars = ruby_dyna_vars;
-	ruby_dyna_vars = data->dyna_vars;
-	old_vmode = scope_vmode;
-	scope_vmode = data->vmode;
-	old_cref = (VALUE)ruby_cref;
-	ruby_cref = data->cref;
-	old_wrapper = ruby_wrapper;
-	ruby_wrapper = data->wrapper;
-	if ((file == 0 || (line == 1 && strcmp(file, "(eval)") == 0)) && data->frame.node) {
-	    file = data->frame.node->nd_file;
-	    if (!file) file = "__builtin__";
-	    line = nd_line(data->frame.node);
-	}
-
-	self = data->self;
-	ruby_frame->iter = data->iter;
-    }
-    else {
-	if (ruby_frame->prev) {
-	    ruby_frame->iter = ruby_frame->prev->iter;
-	}
-    }
-    if (file == 0) {
-	ruby_set_current_source();
-	file = ruby_sourcefile;
-	line = ruby_sourceline;
-    }
-    PUSH_CLASS(ruby_cbase);
-    ruby_in_eval++;
-    if (TYPE(ruby_class) == T_ICLASS) {
-	ruby_class = RBASIC(ruby_class)->klass;
-    }
-    PUSH_TAG(PROT_NONE);
-    if ((state = EXEC_TAG()) == 0) {
-	NODE *node;
-
-	ruby_safe_level = 0;
-	result = ruby_errinfo;
-	ruby_errinfo = Qnil;
-	node = compile(src, file, line);
-	ruby_safe_level = safe;
-	if (ruby_nerrs > 0) {
-	    compile_error(0);
-	}
-	if (!NIL_P(result)) ruby_errinfo = result;
-	result = eval_node(self, node);
-    }
-    POP_TAG();
-    POP_CLASS();
-    ruby_in_eval--;
-    ruby_safe_level = safe;
-    if (!NIL_P(scope)) {
-	int dont_recycle = ruby_scope->flags & SCOPE_DONT_RECYCLE;
-
-	ruby_wrapper = old_wrapper;
-	ruby_cref  = (NODE*)old_cref;
-	ruby_frame = frame.tmp;
-	ruby_scope = old_scope;
-	ruby_block = old_block;
-	ruby_dyna_vars = old_dyna_vars;
-	data->vmode = scope_vmode; /* write back visibility mode */
-	scope_vmode = old_vmode;
-	if (dont_recycle) {
-	    struct tag *tag;
-	    struct RVarmap *vars;
-
-	    scope_dup(ruby_scope);
-	    for (tag=prot_tag; tag; tag=tag->prev) {
-		scope_dup(tag->scope);
-	    }
-	    for (vars = ruby_dyna_vars; vars; vars = vars->next) {
-		FL_SET(vars, DVAR_DONT_RECYCLE);
-	    }
-	}
-    }
-    else {
-	ruby_frame->iter = iter;
-    }
-    ruby_current_node = nodesave;
+  volatile int safe = ruby_safe_level;
+  int state;
+  VALUE result;
+  
+  if (file == 0) {
     ruby_set_current_source();
-    if (state) {
-	if (state == TAG_RAISE) {
-	    if (strcmp(file, "(eval)") == 0) {
-		VALUE mesg, errat;
+    file = ruby_sourcefile;
+    line = ruby_sourceline;
+  }
 
-		errat = get_backtrace(ruby_errinfo);
-		mesg  = rb_attr_get(ruby_errinfo, rb_intern("mesg"));
-		if (!NIL_P(errat) && TYPE(errat) == T_ARRAY) {
-		    if (!NIL_P(mesg) && TYPE(mesg) == T_STRING) {
-			rb_str_update(mesg, 0, 0, rb_str_new2(": "));
-			rb_str_update(mesg, 0, 0, RARRAY(errat)->ptr[0]);
-		    }
-		    RARRAY(errat)->ptr[0] = RARRAY(backtrace(-2))->ptr[0];
-		}
-	    }
-	    rb_exc_raise(ruby_errinfo);
-	}
-	JUMP_TAG(state);
-    }
+  PUSH_TAG(PROT_NONE);
+  if ((state = EXEC_TAG()) == 0) {
+    NODE *node;
+    result = yarvcore_eval(0, src, rb_str_new2(file), INT2FIX(line));
+  }
+  POP_TAG();
+  
+  if (state) {
+    if (state == TAG_RAISE) {
+      if (strcmp(file, "(eval)") == 0) {
+        VALUE mesg, errat;
 
-    return result;
+        errat = get_backtrace(ruby_errinfo);
+        mesg  = rb_attr_get(ruby_errinfo, rb_intern("mesg"));
+        if (!NIL_P(errat) && TYPE(errat) == T_ARRAY) {
+          if (!NIL_P(mesg) && TYPE(mesg) == T_STRING) {
+            rb_str_update(mesg, 0, 0, rb_str_new2(": "));
+            rb_str_update(mesg, 0, 0, RARRAY(errat)->ptr[0]);
+          }
+          RARRAY(errat)->ptr[0] = RARRAY(backtrace(-2))->ptr[0];
+        }
+      }
+      rb_exc_raise(ruby_errinfo);
+    }
+    JUMP_TAG(state);
+  }
+  return result;
 }
 
 /*
@@ -6770,7 +4248,7 @@
 	rb_thread_critical = critical;
 	ALLOW_INTS;
 	if (ruby_nerrs == 0) {
-	    eval_node(self, node);
+          rb_bug("load");
 	}
     }
     ruby_frame->callee = callee;
@@ -8873,25 +6351,6 @@
     NODE *iter;
 };
 
-static VALUE
-call_block(arg)
-    struct block_arg *arg;
-{
-    return rb_eval(arg->self, arg->iter);
-}
-
-static VALUE
-block_pass(self, node)
-    VALUE self;
-    NODE *node;
-{
-    struct block_arg arg;
-    arg.self = self;
-    arg.iter = node->nd_iter;
-    return rb_block_pass((VALUE (*)_((VALUE)))call_block,
-			 (VALUE)&arg, rb_eval(self, node->nd_body));
-}
-
 struct METHOD {
     VALUE klass, rklass;
     VALUE recv;
@@ -9185,7 +6644,8 @@
 	if (ruby_safe_level < 4) ruby_safe_level = 4;
     }
     if ((state = EXEC_TAG()) == 0) {
-	result = rb_call0(data->klass,data->recv,data->id,data->oid,argc,argv,data->body,0);
+	result = th_call0(GET_THREAD(),
+                          data->klass,data->recv,data->id,data->oid,argc,argv,data->body,0);
     }
     POP_TAG();
     POP_ITER();

Modified: trunk/inits.c
===================================================================
--- trunk/inits.c	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/inits.c	2005-08-15 00:55:30 UTC (rev 231)
@@ -47,10 +47,12 @@
 void Init_var_tables _((void));
 void Init_version _((void));
 void Init_yarvcore _((void));
+void Init_vm _((void));
 
 void
 rb_call_inits()
 {
+    Init_vm();
     Init_sym();
     Init_var_tables();
     Init_Object();

Added: trunk/test.rb
===================================================================
--- trunk/test.rb	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/test.rb	2005-08-15 00:55:30 UTC (rev 231)
@@ -0,0 +1,35 @@
+
+$prog = <<'__EOP__'
+
+p 1
+100
+
+__EOP__
+
+$prog = <<__EOP__
+p eval(%q{
+#{$prog}})
+__EOP__
+
+def exec program
+  r = nil
+  IO.popen("#{program}", 'r+'){|io|
+    #
+    io.write $prog
+    io.close_write
+    r = io.read
+  }
+  r
+end
+
+puts "=========================================================="
+puts "YARV"
+puts "----------------------------------------------------------"
+puts exec(ARGV[0])
+
+puts
+puts "=========================================================="
+puts "Ruby"
+puts "----------------------------------------------------------"
+puts exec(ARGV[1])
+


Property changes on: trunk/test.rb
___________________________________________________________________
Name: svn:executable
   + *

Modified: trunk/vm.c
===================================================================
--- trunk/vm.c	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/vm.c	2005-08-15 00:55:30 UTC (rev 231)
@@ -552,7 +552,7 @@
              file, line_no);
     str = rb_str_new2(buf);
   }
-
+  
   if(th->cfp != cfp){
     th_backtrace_each(th, cfp-1, file, line_no, ary);
   }
@@ -583,7 +583,7 @@
     }
     ary = rb_ary_new();
   }
-
+  
   th_backtrace_each(th, top_of_cfp, "", 0, ary);
   return ary;
 }

Modified: trunk/vm.h
===================================================================
--- trunk/vm.h	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/vm.h	2005-08-15 00:55:30 UTC (rev 231)
@@ -75,8 +75,7 @@
 #define throwdebug if(0)printf
 //#define throwdebug printf
 
-#define SDR()     stack_dump_raw(th, GET_CFP());
-#define SDR2(cfp) stack_dump_raw(th, (cfp));
+#define SDR2(cfp) vm_stack_dump_raw(GET_THREAD(), (cfp))
 
 
 /************************************************/

Modified: trunk/vm_dump.c
===================================================================
--- trunk/vm_dump.c	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/vm_dump.c	2005-08-15 00:55:30 UTC (rev 231)
@@ -4,8 +4,9 @@
 #include "yarvcore.h"
 #include "vm.h"
 
-
-void control_frame_dump(yarv_thread_t *th, yarv_control_frame_t *cfp){
+static void
+control_frame_dump(yarv_thread_t *th, yarv_control_frame_t *cfp)
+{
   int pc = -1, bp = -1;
   int lfp = cfp->lfp - th->stack;
   int dfp = cfp->dfp - th->stack;
@@ -66,7 +67,9 @@
   printf("\n");
 }
 
-void stack_dump_raw(yarv_thread_t *th, yarv_control_frame_t *cfp){
+void
+vm_stack_dump_raw(yarv_thread_t *th, yarv_control_frame_t *cfp)
+{
   VALUE *sp  = cfp->sp, *bp = cfp->bp;
   VALUE *lfp = cfp->lfp;
   VALUE *dfp = cfp->dfp;
@@ -95,7 +98,9 @@
   printf("---------------------------\n");
 }
 
-void env_dump_raw(yarv_env_t *env, VALUE *lfp, VALUE *dfp){
+void
+env_dump_raw(yarv_env_t *env, VALUE *lfp, VALUE *dfp)
+{
   int i;
   printf("-- env --------------------\n");
   
@@ -118,7 +123,9 @@
   printf("---------------------------\n");
 }
 
-void proc_dump_raw(yarv_proc_t *proc){
+void
+proc_dump_raw(yarv_proc_t *proc)
+{
   yarv_env_t *env;
   char *selfstr;
   VALUE val = rb_inspect(proc->block.self);
@@ -131,13 +138,17 @@
   env_dump_raw(env, proc->block.lfp, proc->block.dfp);
 }
 
-void stack_dump_th(VALUE thval){
+void
+stack_dump_th(VALUE thval)
+{
   yarv_thread_t *th;
   GetThreadVal(thval, th);
-  stack_dump_raw(th, th->cfp);
+  vm_stack_dump_raw(th, th->cfp);
 }
 
-void stack_dump_each(yarv_thread_t *th, yarv_control_frame_t *cfp){
+void
+stack_dump_each(yarv_thread_t *th, yarv_control_frame_t *cfp)
+{
   int i, lim = 1;
   
   VALUE rstr;
@@ -211,7 +222,9 @@
 }
 
 
-void debug_print_register(yarv_thread_t *th){
+void
+debug_print_register(yarv_thread_t *th)
+{
   yarv_control_frame_t *cfp = th->cfp;
   int pc = -1;
   int lfp = cfp->lfp - th->stack;
@@ -230,13 +243,17 @@
          pc, cfp->sp - th->stack, lfp, dfp, cfpi);
 }
 
-void thread_dump_regs(VALUE thval){
+void
+thread_dump_regs(VALUE thval)
+{
   yarv_thread_t *th;
   GetThreadVal(thval, th);
   debug_print_register(th);
 }
 
-void debug_print_pre(yarv_thread_t *th, yarv_control_frame_t *cfp){
+void
+debug_print_pre(yarv_thread_t *th, yarv_control_frame_t *cfp)
+{
   yarv_iseq_t *iseq = cfp->iseq;
 
   if(iseq != 0 && cfp->magic != FRAME_MAGIC_FINISH){
@@ -252,11 +269,13 @@
 #endif
 }
 
-void debug_print_post(yarv_thread_t *th, yarv_control_frame_t *cfp
+void
+debug_print_post(yarv_thread_t *th, yarv_control_frame_t *cfp
 #ifdef OPT_STACK_CACHING
                       , VALUE reg_a, VALUE reg_b
 #endif
-                      ){
+                      )
+{
 #if VMDEBUG > 9
   SDR2(cfp);
 #endif
@@ -298,7 +317,9 @@
  *   val(interned string) => count(Fixnum)
  * }
  */
-void vm_analysis_insn(int insn){
+void
+vm_analysis_insn(int insn)
+{
   static ID usage_hash;
   static ID bigram_hash;
   static int prev_insn = -1;
@@ -345,10 +366,12 @@
 }
 
 /* from disasm.c */
-VALUE insn_operand_intern(int insn, int op_no, VALUE op,
-                          int len, int pos, VALUE child);
+extern VALUE insn_operand_intern(int insn, int op_no, VALUE op,
+                                 int len, int pos, VALUE child);
 
-void vm_analysis_operand(int insn, int n, VALUE op){
+void
+vm_analysis_operand(int insn, int n, VALUE op)
+{
   static ID usage_hash;
   
   VALUE uh;
@@ -384,7 +407,9 @@
   SET_YARV_START();
 }
 
-void vm_analysis_register(int reg, int isset){
+void
+vm_analysis_register(int reg, int isset)
+{
   static ID usage_hash;
   VALUE uh;
   VALUE rhash;
@@ -436,7 +461,10 @@
 
 #endif
 
-VALUE thread_dump_state(VALUE self){
+
+VALUE
+thread_dump_state(VALUE self)
+{
   yarv_thread_t* th;
   yarv_control_frame_t *cfp;
   GetThreadVal(self, th);

Modified: trunk/yarv.h
===================================================================
--- trunk/yarv.h	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/yarv.h	2005-08-15 00:55:30 UTC (rev 231)
@@ -27,6 +27,7 @@
 yarv_vm_t *yarv_get_current_running_vm _(());
 yarv_thread_t *yarv_get_current_running_thread _(());
 
+#define GET_THREAD() yarv_get_current_running_thread()
 
 struct yarv_yield_data{
   yarv_thread_t *th;
@@ -40,5 +41,18 @@
 VALUE thread_yield_light_prepare _((VALUE self, int argc, VALUE *argv,
                                     struct yarv_yield_data *data));
 
+VALUE th_invoke_yield(yarv_thread_t *th, int argc, VALUE *argv);
 
+VALUE th_call0(yarv_thread_t *th, VALUE klass, VALUE recv,
+               VALUE id, ID oid, int argc, const VALUE *argv,
+               NODE *body, int nosuper);
+
+VALUE *yarv_svar(int);
+
+VALUE th_call_super(yarv_thread_t *th, int argc, const VALUE *argv);
+
+VALUE yarv_backtrace(int lev);
+
+VALUE yarvcore_eval_parsed(VALUE node, VALUE file);
+
 #endif

Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/yarvcore.c	2005-08-15 00:55:30 UTC (rev 231)
@@ -107,7 +107,7 @@
 
 /* rb_block_given */
 int yarv_block_given_p(){
-  if(GC_GUARDED_PTR_REF(yarv_get_current_running_thread()->cfp->lfp[0])){
+  if(GC_GUARDED_PTR_REF(GET_THREAD()->cfp->lfp[0])){
     return 1;
   }
   else{
@@ -119,7 +119,7 @@
 
 /* rb_yield_values */
 VALUE yarv_yield_values(int argc, VALUE *argv){
-  yarv_thread_t *th = yarv_get_current_running_thread();
+  yarv_thread_t *th = GET_THREAD();
 
   if(argc == 1 && CLASS_OF(argv[0]) == rb_cValues){
     argc = RARRAY(argv[0])->len;
@@ -135,20 +135,20 @@
 /* rb_call0 continued for yarv function */
 VALUE yarv_call0(VALUE klass, VALUE recv, VALUE id, ID oid,
                  int argc, VALUE *argv, NODE *body, int nosuper){
-  return th_call0(yarv_get_current_running_thread(), klass, recv, id, oid, argc, argv, body, nosuper);
+  return th_call0(GET_THREAD(), klass, recv, id, oid, argc, argv, body, nosuper);
 }
 
 
-VALUE thread_call_super(VALUE self, int argc, const VALUE *argv);
+VALUE th_call_super(yarv_thread_t *th, int argc, const VALUE *argv);
 
 VALUE yarv_call_super(int argc, const VALUE *argv){
-  return th_call_super(yarv_get_current_running_thread(), argc, argv);
+  return th_call_super(GET_THREAD(), argc, argv);
 }
 
 VALUE thread_backtrace(VALUE th, int level);
 
 VALUE yarv_backtrace(int level){
-  return th_backtrace(yarv_get_current_running_thread(), level);
+  return th_backtrace(GET_THREAD(), level);
 }
 
 VALUE yarv_caller(VALUE self, VALUE level){
@@ -202,11 +202,11 @@
 VALUE *th_svar(yarv_thread_t *self, int cnt);
 
 VALUE *yarv_svar(int cnt){
-  return th_svar(yarv_get_current_running_thread(), cnt);
+  return th_svar(GET_THREAD(), cnt);
 }
 
 static int yarv_iterate(NODE *node){
-  yarv_thread_t *th = yarv_get_current_running_thread();
+  yarv_thread_t *th = GET_THREAD();
   th->ifuncnode = node;
   return 0;
 }
@@ -366,7 +366,7 @@
     iseq->klass_nest_stack = rb_ary_new();
   }
 
-  iseq->compile_data    = ALLOC_N(struct iseq_compile_data, 1);
+  iseq->compile_data    = ALLOC(struct iseq_compile_data);
   MEMZERO(iseq->compile_data, struct iseq_compile_data, 1);
   iseq->compile_data->mark_ary = rb_ary_new();
 
@@ -534,15 +534,9 @@
   return obj;
 }
 
-extern VALUE thread_set_top_stack(VALUE self, VALUE iseq);
-
-static VALUE thread_init(VALUE self, VALUE vmval){
-  yarv_thread_t *th;
-  yarv_vm_t *vm;
-  
-  GetThreadVal(self, th);
-  GetVMVal(vmval, vm);
-  
+static void
+th_init(yarv_thread_t *th)
+{
   /* allocate thread stack */
   th->stack      = ALLOC_N(VALUE, YARV_THREAD_STACK_SIZE);
   th->stack_size = YARV_THREAD_STACK_SIZE;
@@ -554,11 +548,22 @@
   th->cfp->pc  = 0;
   th->cfp->sp  = th->stack;
   th->cfp->bp  = 0;
-  th->cfp->lfp = 0;
-  th->cfp->dfp = 0;
+  th->cfp->lfp = th->stack;
+  th->cfp->dfp = th->stack;
   th->cfp->self = Qnil;
   th->cfp->magic = 0;
+}
+
+static VALUE
+thread_init(VALUE self, VALUE vmval)
+{
+  yarv_thread_t *th;
+  yarv_vm_t *vm;
   
+  GetThreadVal(self, th);
+  GetVMVal(vmval, vm);
+  
+  th_init(th);
   th->self = self;
   
   th->vm_value = vmval;
@@ -568,6 +573,7 @@
 }
 
 VALUE th_eval_body(yarv_thread_t *th);
+extern VALUE thread_set_top_stack(VALUE self, VALUE iseq);
 
 static VALUE thread_eval(VALUE self, VALUE iseq){
   VALUE val;
@@ -657,7 +663,7 @@
   yarv_proc_t *proc;
   GetProcVal(procval, proc);
 
-  return th_invoke_proc(yarv_get_current_running_thread(), proc, argc, argv);
+  return th_invoke_proc(GET_THREAD(), proc, argc, argv);
 }
 
 
@@ -843,7 +849,27 @@
     GetVMVal(vmval, vm);
     GetThreadVal(vm->main_thread, th);
 
+    thread_free(GET_THREAD());
     yarv_set_current_running_thread(th);
   }
 }
 
+static void
+test()
+{
+  int i; int *p;
+  printf("!test!\n");
+  for(i=0; i<1000000; i++){
+    p = ALLOC(int);
+  }
+}
+
+void
+Init_vm()
+{
+  /* initialize main thread */
+  yarv_thread_t *th = ALLOC(yarv_thread_t);
+  th_init(th);
+  yarv_set_current_running_thread(th);
+}
+

Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/yarvcore.h	2005-08-15 00:55:30 UTC (rev 231)
@@ -389,6 +389,10 @@
 #define DEFINED_CONST  INT2FIX(4)
 #define DEFINED_METHOD INT2FIX(5)
 
+/* for debug */
+extern void vm_stack_dump_raw(yarv_thread_t *, yarv_control_frame_t *);
+#define SDR() vm_stack_dump_raw(GET_THREAD(), GET_THREAD()->cfp)
+
 #include "yarv.h"
 
 #endif	// _YARVCORE_H_INCLUDED_

Modified: trunk/yarvext/test.rb
===================================================================
--- trunk/yarvext/test.rb	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/yarvext/test.rb	2005-08-15 00:55:30 UTC (rev 231)
@@ -8,57 +8,19 @@
 ###########################################################
 $prog =<<'__EOP__'
 
-def m a, b, &c
-  c.call(a, b)
+def m
+  puts caller
 end
 
-m(10, 20){|x, y|
-  [x+y, x*y]
-}
+m
 
+
 __END__
 
-module Enumerable
-  def all_?
-    self.each{|e|
-      unless yield(e)
-        return false
-      end
-    }
-    true
-  end
-end
-GC.start
-100000.times{|x|
-  x.to_s
+p [1,2,3].map{|e|
+  e+1
 }
-GC.start
 
-xxx = 0
-[1,2].each{|bi|
-  [3,4].each{|bj|
-    [true, nil, true].all_?{|be| be}
-    break
-  }
-  xxx += 1
-}
-xxx
-__END__
-
-__END__
-
-
-def m
-  /a/ =~ 'a'
-end
-m
-__END__
-def m
-  /a(b)(c)d/ =~ 'xyzabcdefgabcdefg'
-  [$1, $2, $3, $~.class, $&, $`, $', $+]
-end
-m
-
 __EOP__
 ###########################################################
 

Modified: trunk/yarvtest/yarvtest.rb
===================================================================
--- trunk/yarvtest/yarvtest.rb	2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/yarvtest/yarvtest.rb	2005-08-15 00:55:30 UTC (rev 231)
@@ -1,4 +1,6 @@
 require 'test/unit'
+
+if defined? YARV_PATCHED
 require 'yarvutil'
 
 class YarvTestBase < Test::Unit::TestCase
@@ -33,3 +35,51 @@
 
 end
 
+else
+
+class YarvTestBase < Test::Unit::TestCase
+  def initialize *args
+    super
+    
+    @yarv = ARGV.each{|e| break $1 if /^yarv=(.+)/ =~ ARGV[0]} or raise
+    @ruby = ARGV.each{|e| break $1 if /^ruby=(.+)/ =~ ARGV[1]} or raise
+  end
+
+  def remove_const sym
+    Object.module_eval{
+      remove_const sym
+    }
+  end
+
+  def remove_method sym
+    Object.module_eval{
+      undef sym
+    }
+  end
+
+  def exec exec_file, program
+    r = nil
+    IO.popen("#{exec_file}", 'r+'){|io|
+      #
+      io.write program
+      io.close_write
+      r = io.read
+    }
+    r
+  end
+  
+  def ae str
+    # puts str
+    # puts YARVUtil.parse(str, $0, 0).disasm
+
+    ruby = exec(@ruby, str)
+    yarv = exec(@yarv, str)
+
+    assert_equal(ruby, yarv)
+  end
+  
+  def test_
+  end
+end
+
+end


--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧][生データ]