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

yarv-diff:318

From: ko1 atdot.net
Date: 7 Apr 2006 02:18:54 -0000
Subject: [yarv-diff:318] r483 - in trunk: . benchmark rb template

Author: ko1
Date: 2006-04-07 11:18:53 +0900 (Fri, 07 Apr 2006)
New Revision: 483

Modified:
   trunk/
   trunk/ChangeLog
   trunk/benchmark/bmx_temp.rb
   trunk/common.mk
   trunk/compile.c
   trunk/disasm.c
   trunk/insns.def
   trunk/rb/insns2vm.rb
   trunk/rb/yasm.rb
   trunk/template/insns.inc.tmpl
   trunk/vm.c
   trunk/vm_evalbody.h
   trunk/yarvcore.c
   trunk/yarvcore.h
Log:
 r745@lermite:  ko1 | 2006-04-07 11:15:28 +0900
 	* common.mk : fix some make rules
 
 	* insns.def : rename some instructions name
 
 	* rb/insns2vm.rb : change some operand type name
 
 	* vm_evalbody.h : ditto
 
 	* template/insns.inc.tmpl : add YARV_MAX_INSTRUCTION_SIZE macro
 
 	* compile.c, disasm.c, yarvcore.c : support load/store iseq from/to simple
 	data structure such as array, literals, and so on
 
 	* rb/yasm.rb : supported
 
 	* vm.c : change interface of eval_define_method
 
 	* yarvcore.h : remove unused externals
 



Property changes on: trunk
___________________________________________________________________
Name: svk:merge
   - 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:740
   + 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:745

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2006-03-08 01:32:31 UTC (rev 482)
+++ trunk/ChangeLog	2006-04-07 02:18:53 UTC (rev 483)
@@ -4,6 +4,28 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2006-04-07(Fri) 11:09:43 +0900  Koichi Sasada  <ko1 atdot.net>
+
+	* common.mk : fix some make rules
+
+	* insns.def : rename some instructions name
+
+	* rb/insns2vm.rb : change some operand type name
+
+	* vm_evalbody.h : ditto
+
+	* template/insns.inc.tmpl : add YARV_MAX_INSTRUCTION_SIZE macro
+
+	* compile.c, disasm.c, yarvcore.c : support load/store iseq from/to simple
+	data structure such as array, literals, and so on
+
+	* rb/yasm.rb : supported
+
+	* vm.c : change interface of eval_define_method
+
+	* yarvcore.h : remove unused externals
+
+
 2006-03-08(Wed) 10:31:29 +0900  Minero Aoki  <aamine loveruby.net>
 
 	* lib/delegate.rb (DelegateClass): do not delegate #send and

Modified: trunk/benchmark/bmx_temp.rb
===================================================================
--- trunk/benchmark/bmx_temp.rb	2006-03-08 01:32:31 UTC (rev 482)
+++ trunk/benchmark/bmx_temp.rb	2006-04-07 02:18:53 UTC (rev 483)
@@ -1,7 +1,33 @@
-1000000.times{
+
+class Range
+  def each
+    f = self.first
+    l = self.last
+    while f < l
+      yield
+      f = f.succ
+    end
+  end
+end
+
+(0..10000000).each{
 }
+
 __END__
+class Fixnum_
+  def times
+    i = 0
+    while i<self
+      yield(i)
+      i+=1
+    end
+  end
+end
 
+10000000.times{
+}
+__END__
+
 ths = (1..10).map{
   Thread.new{
     1000000.times{

Modified: trunk/common.mk
===================================================================
--- trunk/common.mk	2006-03-08 01:32:31 UTC (rev 482)
+++ trunk/common.mk	2006-04-07 02:18:53 UTC (rev 483)
@@ -440,10 +440,10 @@
 	$(MINIRUBY) $(srcdir)/rb/parse.rb $(srcdir)/test.rb
 
 benchmark: all
-	$(BASERUBY) -I$(srcdir) -I$(srcdir)/lib $(srcdir)/benchmark/run_rite.rb $(OPT) $(ITEMS) --yarv-program=./$(RUBY) --ruby-program=$(BASERUBY) --opts=-I$(srcdir)/lib
+	$(BASERUBY) -I$(srcdir) -I$(srcdir)/lib $(srcdir)/benchmark/run_rite.rb $(OPT) $(ITEMS) --yarv-program=./$(PROGRAM) --ruby-program=$(BASERUBY) --opts=-I$(srcdir)/lib
 
-tbench: all
-	$(BASERUBY) -I$(srcdir) -I$(srcdir)/lib $(srcdir)/benchmark/run_rite.rb bmx $(OPT) --yarv-program=./$(RUBY) --ruby-program=$(BASERUBY) --opts=-I$(srcdir)/lib
+tbench: prog
+	$(BASERUBY) -I$(srcdir) -I$(srcdir)/lib $(srcdir)/benchmark/run_rite.rb bmx $(OPT) --yarv-program=./$(PROGRAM) --ruby-program=$(BASERUBY) --opts=-I$(srcdir)/lib
 
 bench-each: all
 	$(BASERUBY) -I$(srcdir) $(srcdir)/benchmark/run_rite.rb bm_$(ITEM) $(OPT) --yarv-program=./$(RUBY) --ruby-program=$(BASERUBY) --opts=-I$(srcdir)/lib

Modified: trunk/compile.c
===================================================================
--- trunk/compile.c	2006-03-08 01:32:31 UTC (rev 482)
+++ trunk/compile.c	2006-04-07 02:18:53 UTC (rev 483)
@@ -223,7 +223,7 @@
 
 	    /* wide range catch handler must put at last */
 	    ADD_CATCH_ENTRY(CATCH_TYPE_REDO, start, end, 0, start);
-	    ADD_CATCH_ENTRY(CATCH_TYPE_NEXT, start, end, 0, end);
+	    ADD_CATCH_ENTRY(CATCH_TYPE_NEXT, start, start, 0, end);
 	}
 	else if (iseq->type == ISEQ_TYPE_TOP) {
 	    set_localtbl(iseq, GET_THREAD()->top_local_tbl);
@@ -259,7 +259,7 @@
 	ADD_INSN1(list_anchor, 0, throw, INT2FIX(0) /* continue throw */ );
     }
     else {
-	ADD_INSN(list_anchor, iseq->compile_data->last_line, end);
+	ADD_INSN(list_anchor, iseq->compile_data->last_line, leave);
     }
 
     return iseq_setup(iseq, list_anchor);
@@ -730,8 +730,7 @@
 static int
 iseq_setup(yarv_iseq_t *iseq, LINK_ANCHOR *anchor)
 {
-//  debugs("[compile step 2] (iseq_array_to_linkedlist)\n");
-//  iseq_array_to_linkedlist_each(anchor, seq_ary);
+    //  debugs("[compile step 2] (iseq_array_to_linkedlist)\n");
 
     GC_CHECK();
     if (CPDEBUG > 5)
@@ -1316,7 +1315,7 @@
 		    case TS_NUM:	/* ulong */
 			generated_iseq[pos + 1 + j] = FIX2INT(operands[j]);
 			break;
-		    case TS_BLOCKISEQ:	/* BLOCK */
+		    case TS_ISEQ:	/* iseq */
 			{
 			    VALUE v = operands[j];
 			    yarv_iseq_t *block = 0;
@@ -1546,8 +1545,8 @@
 		    OPERAND_AT(iobj, 0) = OPERAND_AT(diobj, 0);
 		    continue;
 		}
-		else if (diobj->insn_id == BIN(end)) {
-		    INSN *eiobj = new_insn_core(iseq, iobj->line_no, BIN(end),
+		else if (diobj->insn_id == BIN(leave)) {
+		    INSN *eiobj = new_insn_core(iseq, iobj->line_no, BIN(leave),
 						diobj->operand_size,
 						diobj->operands);
 		    /* replace */
@@ -1568,11 +1567,11 @@
 		 * L2:
 		 */
 		else if ((piobj = (INSN *)get_prev_insn(iobj)) != 0 &&
-			 (piobj->insn_id == BIN(if) ||
-			  piobj->insn_id == BIN(unless))) {
+			 (piobj->insn_id == BIN(branchif) ||
+			  piobj->insn_id == BIN(branchunless))) {
 		    if (niobj == (INSN *)get_destination_insn(piobj)) {
-			piobj->insn_id = (piobj->insn_id == BIN(if))
-			    ? BIN(unless) : BIN(if) ;
+			piobj->insn_id = (piobj->insn_id == BIN(branchif))
+			    ? BIN(branchunless) : BIN(branchif) ;
 			OPERAND_AT(piobj, 0) = OPERAND_AT(iobj, 0);
 			REMOVE_ELEM(&iobj->link);
 		    }
@@ -1582,7 +1581,8 @@
 		    dump_disasm_anchor(anchor);
 		}
 	    }
-	    if (iobj->insn_id == BIN(if) || iobj->insn_id == BIN(unless)) {
+	    if (iobj->insn_id == BIN(branchif) ||
+		iobj->insn_id == BIN(branchunless)) {
 		/*
 		 *   if L1
 		 *   ...
@@ -1597,7 +1597,7 @@
 		}
 	    }
 
-	    if (iobj->insn_id == BIN(end)) {
+	    if (iobj->insn_id == BIN(leave)) {
 		INSN *piobj = (INSN *)get_prev_insn((INSN *)list);
 		if (piobj->insn_id == BIN(send)) {
 		    /* TODO: tail call optimization */
@@ -1740,7 +1740,7 @@
 	    nstate = SCS_XX;
 	}
     }
-    else if (insn_id == BIN(end)) {
+    else if (insn_id == BIN(leave)) {
 	nstate = SCS_XX;
     }
 
@@ -1926,7 +1926,7 @@
 	break;
     default:
 	COMPILE(ret, "branch condition", cond);
-	ADD_INSNL(ret, nd_line(cond), unless, else_label);
+	ADD_INSNL(ret, nd_line(cond), branchunless, else_label);
 	ADD_INSNL(ret, nd_line(cond), jump, then_label);
 	break;
     }
@@ -2248,7 +2248,7 @@
 	    LABEL *lcont = NEW_LABEL(nd_line(node));
 	    defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse);
 
-	    ADD_INSNL(ret, nd_line(node), if, lcont) ;
+	    ADD_INSNL(ret, nd_line(node), branchif, lcont) ;
 	    ADD_INSN(ret, nd_line(node), putnil);
 	    ADD_INSNL(ret, nd_line(node), jump, lfinish);
 
@@ -2261,7 +2261,7 @@
 	    LABEL *lcont = NEW_LABEL(nd_line(node));
 	    defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse);
 
-	    ADD_INSNL(ret, nd_line(node), if, lcont) ;
+	    ADD_INSNL(ret, nd_line(node), branchif, lcont) ;
 	    ADD_INSN(ret, nd_line(node), putnil);
 	    ADD_INSNL(ret, nd_line(node), jump, lfinish);
 
@@ -2285,7 +2285,7 @@
 	    LABEL *lcont = NEW_LABEL(nd_line(node));
 
 	    defined_expr(iseq, ret, node->nd_recv, lfinish, Qfalse);
-	    ADD_INSNL(ret, nd_line(node), if, lcont) ;
+	    ADD_INSNL(ret, nd_line(node), branchif, lcont) ;
 	    ADD_INSN(ret, nd_line(node), putnil);
 	    ADD_INSNL(ret, nd_line(node), jump, lfinish);
 
@@ -2335,7 +2335,7 @@
 
 	  ADD_LABEL(ret, lstart);
 	  COMPILE(ret, "defined expr (others)", node);
-	  ADD_INSNL(ret, nd_line(node), if, ldefed) ;
+	  ADD_INSNL(ret, nd_line(node), branchif, ldefed) ;
 	  ADD_INSN(ret, nd_line(node), putnil);
 	  ADD_INSNL(ret, nd_line(node), jump, lend);
 	  ADD_LABEL(ret, ldefed);
@@ -2596,7 +2596,7 @@
 			  ADD_SEND(cond_seq, nd_line(node), ID2SYM(idEqq),
 				   INT2FIX(1));
 		      }
-		      ADD_INSNL(cond_seq, nd_line(node), if, l1) ;
+		      ADD_INSNL(cond_seq, nd_line(node), branchif, l1) ;
 		      vals = vals->nd_next;
 		  }
 	      }
@@ -2666,11 +2666,11 @@
 			  ADD_INSN1(ret, nd_line(val), checkincludearray,
 				    Qfalse);
 			  ADD_INSN(ret, nd_line(val), pop);
-			  ADD_INSNL(ret, nd_line(val), if, l1) ;
+			  ADD_INSNL(ret, nd_line(val), branchif, l1) ;
 		      }
 		      else {
 			  COMPILE(ret, "when2", val);
-			  ADD_INSNL(ret, nd_line(val), if, l1) ;
+			  ADD_INSNL(ret, nd_line(val), branchif, l1) ;
 		      }
 		      vals = vals->nd_next;
 		  }
@@ -2728,7 +2728,7 @@
 	  else {
 	      ADD_INSN(ret, nd_line(node), putself);
 	      ADD_CALL(ret, nd_line(node), ID2SYM(idGets), INT2FIX(0));
-	      ADD_INSNL(ret, nd_line(node), if, redo_label) ;
+	      ADD_INSNL(ret, nd_line(node), branchif, redo_label) ;
 	      /* opt_n */
 	  }
 
@@ -2986,7 +2986,7 @@
 		  ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
 			    INT2FIX(0));
 		  ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
-		  ADD_INSNL(ret, nd_line(node), if, label_hit) ;
+		  ADD_INSNL(ret, nd_line(node), branchif, label_hit) ;
 		  narg = narg->nd_next;
 	      }
 	      if (resq->nd_args == 0) {
@@ -2995,12 +2995,12 @@
 		  ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
 			    INT2FIX(0));
 		  ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
-		  ADD_INSNL(ret, nd_line(node), if, label_hit) ;
+		  ADD_INSNL(ret, nd_line(node), branchif, label_hit) ;
 	      }
 	      ADD_INSNL(ret, nd_line(node), jump, label_miss);
 	      ADD_LABEL(ret, label_hit);
 	      COMPILE(ret, "resbody body", resq->nd_body);
-	      ADD_INSN(ret, nd_line(node), end);
+	      ADD_INSN(ret, nd_line(node), leave);
 	      ADD_LABEL(ret, label_miss);
 	      resq = resq->nd_head;
 	  }
@@ -3057,10 +3057,10 @@
 	      ADD_INSN(ret, nd_line(node), dup);
 	  }
 	  if (type == NODE_AND) {
-	      ADD_INSNL(ret, nd_line(node), unless, end_label);
+	      ADD_INSNL(ret, nd_line(node), branchunless, end_label);
 	  }
 	  else {
-	      ADD_INSNL(ret, nd_line(node), if, end_label) ;
+	      ADD_INSNL(ret, nd_line(node), branchif, end_label) ;
 	  }
 	  if (!poped) {
 	      ADD_INSN(ret, nd_line(node), pop);
@@ -3221,12 +3221,12 @@
 	      if (id == 0) {
 		  /* or */
 		  ADD_INSN(ret, nd_line(node), dup);
-		  ADD_INSNL(ret, nd_line(node), if, label) ;
+		  ADD_INSNL(ret, nd_line(node), branchif, label) ;
 		  ADD_INSN(ret, nd_line(node), pop);
 	      }
 	      else {
 		  /* and */
-		  ADD_INSNL(ret, nd_line(node), unless, label);
+		  ADD_INSNL(ret, nd_line(node), branchunless, label);
 	      }
 
 	      COMPILE(ret, "NODE_OP_ASGN1 args->head: ",
@@ -3312,10 +3312,10 @@
 	  if (atype == 0 || atype == 1) {	/* 0: OR or 1: AND */
 	      ADD_INSN(ret, nd_line(node), dup);
 	      if (atype == 0) {
-		  ADD_INSNL(ret, nd_line(node), if, lcfin) ;
+		  ADD_INSNL(ret, nd_line(node), branchif, lcfin) ;
 	      }
 	      else {
-		  ADD_INSNL(ret, nd_line(node), unless, lcfin);
+		  ADD_INSNL(ret, nd_line(node), branchunless, lcfin);
 	      }
 	      ADD_INSN(ret, nd_line(node), pop);
 	      COMPILE(ret, "NODE_OP_ASGN2 val", node->nd_value);
@@ -3350,17 +3350,17 @@
 	  
 	  if (nd_type(node) == NODE_OP_ASGN_OR) {
 	      defined_expr(iseq, ret, node->nd_head, lassign, Qfalse);
-	      ADD_INSNL(ret, nd_line(node), unless, lassign);
+	      ADD_INSNL(ret, nd_line(node), branchunless, lassign);
 	  }
 	  
 	  COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_head", node->nd_head);
 	  ADD_INSN(ret, nd_line(node), dup);
 	  
 	  if (nd_type(node) == NODE_OP_ASGN_AND) {
-	      ADD_INSNL(ret, nd_line(node), unless, lfin);
+	      ADD_INSNL(ret, nd_line(node), branchunless, lfin);
 	  }
 	  else {
-	      ADD_INSNL(ret, nd_line(node), if, lfin) ;
+	      ADD_INSNL(ret, nd_line(node), branchif, lfin) ;
 	  }
 
 	  ADD_INSN(ret, nd_line(node), pop);
@@ -3606,7 +3606,7 @@
 	      }
 	  }
 
-	  ADD_INSN3(ret, nd_line(node), super, argc, block, INT2FIX(flag));
+	  ADD_INSN3(ret, nd_line(node), invokesuper, argc, block, INT2FIX(flag));
 
 	  if (poped) {
 	      ADD_INSN(ret, nd_line(node), pop);
@@ -3684,7 +3684,7 @@
 
 		  if (is->type == ISEQ_TYPE_METHOD) {
 		      add_ensure_iseq(ret, iseq);
-		      ADD_INSN(ret, nd_line(node), end);
+		      ADD_INSN(ret, nd_line(node), leave);
 		  }
 		  else {
 		      ADD_INSN1(ret, nd_line(node), throw,
@@ -3753,7 +3753,7 @@
 	      argc = 0;
 	  }
 	  ADD_SEQ(ret, args);
-	  ADD_INSN2(ret, nd_line(node), yield, INT2FIX(argc),
+	  ADD_INSN2(ret, nd_line(node), invokeblock, INT2FIX(argc),
 		    INT2FIX(flag));
 
 	  if (poped) {
@@ -4094,8 +4094,8 @@
 					    ISEQ_TYPE_CLASS);
 	  compile_cpath(ret, iseq, node->nd_cpath);
 	  COMPILE(ret, "super", node->nd_super);
-	  ADD_INSN2(ret, nd_line(node), classdef,
-		    ID2SYM(node->nd_cpath->nd_mid), iseqval);
+	  ADD_INSN3(ret, nd_line(node), defineclass,
+		    ID2SYM(node->nd_cpath->nd_mid), iseqval, INT2FIX(0));
 
 	  if (poped) {
 	      ADD_INSN(ret, nd_line(node), pop);
@@ -4111,8 +4111,9 @@
 					    ISEQ_TYPE_CLASS);
 
 	  COMPILE(ret, "mbase", node->nd_cpath->nd_head);
-	  ADD_INSN2(ret, nd_line(node), moduledef,
-		    ID2SYM(node->nd_cpath->nd_mid), iseqval);
+	  ADD_INSN (ret, nd_line(node), putnil); /* dummy */
+	  ADD_INSN3(ret, nd_line(node), defineclass,
+		    ID2SYM(node->nd_cpath->nd_mid), iseqval, INT2FIX(2));
 	  if (poped) {
 	      ADD_INSN(ret, nd_line(node), pop);
 	  }
@@ -4124,7 +4125,9 @@
 			ISEQ_TYPE_CLASS);
 
 	  COMPILE(ret, "sclass#recv", node->nd_recv);
-	  ADD_INSN1(ret, nd_line(node), singletonclassdef, iseqval);
+	  ADD_INSN (ret, nd_line(node), putnil);
+	  ADD_INSN3(ret, nd_line(node), defineclass,
+		    ID2SYM(rb_intern("singletonclass")), iseqval, INT2FIX(1));
 
 	  if (poped) {
 	      ADD_INSN(ret, nd_line(node), pop);
@@ -4212,12 +4215,12 @@
 
 	  ADD_INSN2(ret, nd_line(node), getspecial, INT2FIX(node->nd_cnt),
 		    INT2FIX(0));
-	  ADD_INSNL(ret, nd_line(node), if, lend) ;
+	  ADD_INSNL(ret, nd_line(node), branchif, lend) ;
 
 	  /* *flip == 0 */
 	  COMPILE(ret, "flip2 beg", node->nd_beg);
 	  ADD_INSN(ret, nd_line(node), dup);
-	  ADD_INSNL(ret, nd_line(node), unless, lfin);
+	  ADD_INSNL(ret, nd_line(node), branchunless, lfin);
 	  if (nd_type(node) == NODE_FLIP3) {
 	      ADD_INSN(ret, nd_line(node), dup);
 	      ADD_INSN1(ret, nd_line(node), setspecial, INT2FIX(node->nd_cnt));
@@ -4230,7 +4233,7 @@
 	  /* *flip == 1 */
 	  ADD_LABEL(ret, lend);
 	  COMPILE(ret, "flip2 end", node->nd_end);
-	  ADD_INSNL(ret, nd_line(node), unless, ltrue);
+	  ADD_INSNL(ret, nd_line(node), branchunless, ltrue);
 	  ADD_INSN1(ret, nd_line(node), putobject, Qfalse);
 	  ADD_INSN1(ret, nd_line(node), setspecial, INT2FIX(node->nd_cnt));
 
@@ -4454,9 +4457,18 @@
 		    break;
 		}
 		break;
+	      case TS_ISEQ:	/* iseq */
+		{
+		    yarv_iseq_t *iseq = (yarv_iseq_t *)OPERAND_AT(insnobj, j);
+		    VALUE val = Qnil;
+		    if (iseq) {
+			val = iseq->self;
+		    }
+		    rb_str_concat(str, rb_inspect(val));
+		}
+		break;
 	      case TS_LINDEX:
 	      case TS_DINDEX:
-	      case TS_BLOCKISEQ:	/* block */
 	      case TS_NUM:	/* ulong */
 	      case TS_VALUE:	/* VALUE */
 		rb_str_concat(str, rb_inspect(OPERAND_AT(insnobj, j)));
@@ -4549,3 +4561,148 @@
     }
     return ary;
 }
+
+struct st_table *insn_make_insn_table(void);
+
+static int
+insn_simpledata2iseq_body(yarv_iseq_t *iseq, LINK_ANCHOR *anchor,
+			  VALUE body, VALUE line)
+{
+    /* TODO: body should be freezed */
+    VALUE *ptr = RARRAY(body)->ptr;
+    int len = RARRAY(body)->len;
+    int i, j;
+    struct st_table *labels_table = st_init_numtable();
+    static struct st_table *insn_table;
+
+    if (insn_table == 0) {
+	insn_table = insn_make_insn_table();
+    }
+
+    for (i=0; i<len; i++) {
+	VALUE obj = ptr[i];
+
+	if (SYMBOL_P(obj)) {
+	    LABEL *label = 0;
+	    if (st_lookup(labels_table, obj, (st_data_t *)&label) == 0) {
+		label = NEW_LABEL(0);
+		st_insert(labels_table, obj, (st_data_t)label);
+	    }
+	    ADD_LABEL(anchor, label);
+	}
+	else if (TYPE(obj) == T_ARRAY) {
+	    VALUE *argv = 0;
+	    int argc = RARRAY(obj)->len - 1;
+	    int line_no = 0;
+	    VALUE insn_id;
+
+	    if (st_lookup(insn_table, RARRAY(obj)->ptr[0], &insn_id) == 0) {
+		// TODO: exception
+		rb_bug("unknown instruction: ");
+	    }
+
+	    if (argc != insn_len(insn_id)-1) {
+		rb_bug("operand size mismatch");
+	    }
+
+	    if (argc > 0) {
+		argv = compile_data_alloc(iseq, sizeof(VALUE) * argc);
+		for (j=0; j<argc; j++) {
+		    VALUE op = RARRAY(obj)->ptr[j+1];
+		    switch (insn_op_type(insn_id, j)) {
+		      case TS_OFFSET: {
+			  LABEL *label;
+			  if (st_lookup(labels_table, op, (st_data_t *)&label) == 0) {
+			      label = NEW_LABEL(0);
+			      st_insert(labels_table, op, (st_data_t)label);
+			  }
+			  argv[j] = (VALUE)label;
+			  break;
+		      }
+		      case TS_LINDEX:
+		      case TS_DINDEX:
+		      case TS_NUM:
+			argv[j] = op;
+			break;
+		      case TS_VALUE:
+			argv[j] = op;
+			if (!SPECIAL_CONST_P(op)) {
+			    iseq_add_mark_object(iseq, op);
+			}
+			break;
+		      case TS_ISEQ:
+			{
+			    if (op != Qnil) {
+				argv[j] =
+				  iseq_load_simpledata(0, op, iseq->self);
+			    }
+			    else {
+				argv[j] = 0;
+			    }
+			}
+			break;
+		      case TS_GENTRY:
+			argv[j] = (VALUE)rb_global_entry(SYM2ID(op));
+			break;
+		      case TS_IC:
+			argv[j] = (VALUE)NEW_INLINE_CACHE_ENTRY();
+			iseq_add_mark_object(iseq, argv[j]);
+			break;
+		      case TS_ID:
+			argv[j] = op;
+			break;
+		      case TS_CDHASH:
+			
+		      default:
+			rb_bug("unknown operand: %c", insn_op_type(insn_id, j));
+		    }
+		}
+	    }
+	    ADD_ELEM(anchor,
+		     (LINK_ELEMENT*)new_insn_core(iseq, line_no,
+						  insn_id, argc, argv));
+	}
+	else {
+	    // TODO: should throw exception
+	    rb_bug("unexpected object");
+	}
+    }
+    st_free_table(labels_table);
+    iseq_setup(iseq, anchor);
+    return COMPILE_OK;
+}
+
+VALUE
+iseq_simpledata2iseq(yarv_iseq_t *iseq, VALUE line,
+		     VALUE args, VALUE vars, VALUE exception, VALUE body)
+{
+    int i;
+    int opt = 0;
+    ID *tbl;
+    DECL_ANCHOR(anchor);
+
+    if (iseq->type == ISEQ_TYPE_METHOD ||
+	iseq->type == ISEQ_TYPE_TOP ||
+	iseq->type == ISEQ_TYPE_CLASS) {
+	opt = 1;
+    }
+
+    iseq->local_size = opt + RARRAY(args)->len + RARRAY(vars)->len;
+    iseq->local_tbl = (ID *)ALLOC_N(ID *, iseq->local_size);
+    tbl = iseq->local_tbl + opt;
+    
+    /* args */
+    for (i=0; i<RARRAY(args)->len; i++) {
+	*tbl++ = SYM2ID(RARRAY(args)->ptr[i]);
+    }
+    iseq->argc = i;
+
+    /* vars */
+    for (i=0; i<RARRAY(vars)->len; i++) {
+	*tbl++ = SYM2ID(RARRAY(vars)->ptr[i]);
+    }
+
+    /* body */
+    insn_simpledata2iseq_body(iseq, anchor, body, line);
+    return iseq->self;
+}

Modified: trunk/disasm.c
===================================================================
--- trunk/disasm.c	2006-03-08 01:32:31 UTC (rev 482)
+++ trunk/disasm.c	2006-04-07 02:18:53 UTC (rev 483)
@@ -70,11 +70,13 @@
 	snprintf(buff, sizeof(buff), "%lu", op);
 	ret = rb_str_new2(buff);
 	break;
-    case TS_LINDEX:{
+
+    case TS_LINDEX:
+	{
 	    yarv_iseq_t *ip = iseq->local_iseq;
 	    ret =
-		rb_str_new2(rb_id2name
-			    (ip->local_tbl[ip->local_size - op + 1]));
+	      rb_str_new2(
+		  rb_id2name(ip->local_tbl[ip->local_size - op + 1]));
 	    break;
 	}
     case TS_DINDEX:{
@@ -103,13 +105,13 @@
 	}
 	break;
 
-    case TS_BLOCKISEQ:		/* block */
+    case TS_ISEQ:		/* iseq */
 	{
-	    yarv_iseq_t *block = (yarv_iseq_t *)op;
-	    if (block) {
-		ret = block->name;
+	    yarv_iseq_t *iseq = (yarv_iseq_t *)op;
+	    if (iseq) {
+		ret = iseq->name;
 		if (child) {
-		    rb_ary_push(child, block->self);
+		    rb_ary_push(child, iseq->self);
 		}
 	    }
 	    else {
@@ -565,4 +567,184 @@
     printf("node name: %s\n", node_name(nd_type(node)));
     printf("node filename: %s\n", node->nd_file);
     return 0;
-}
\ No newline at end of file
+}
+
+#define DECL_SYMBOL(name) \
+  static VALUE sym_##name;
+#define INIT_SYMBOL(name) \
+  sym_##name = ID2SYM(rb_intern(#name))
+
+VALUE
+iseq_iseq2simpledata(yarv_iseq_t *iseq)
+{
+    int i, j, pos, opt = 0;
+    VALUE *seq;
+
+    VALUE val = rb_ary_new();
+    VALUE type; /* Symbol */
+    VALUE args = rb_ary_new(); /* [:arg1, ...] */
+    VALUE vars = rb_ary_new(); /* [:var1, ...] */
+    VALUE body = rb_ary_new(); /* [[:insn1, ...], ...] */
+    VALUE nbody;
+    VALUE line = rb_ary_new();
+    VALUE exception = rb_ary_new(); /* [[....]] */
+    static VALUE insn_syms[YARV_MAX_INSTRUCTION_SIZE];
+    struct st_table *labels_table = st_init_numtable();
+    
+    DECL_SYMBOL(toplevel);
+    DECL_SYMBOL(method);
+    DECL_SYMBOL(block);
+    DECL_SYMBOL(class);
+    DECL_SYMBOL(rescue);
+    DECL_SYMBOL(ensure);
+    DECL_SYMBOL(eval);
+
+    if (sym_toplevel == 0) {
+	int i;
+	for (i=0; i<YARV_MAX_INSTRUCTION_SIZE; i++) {
+	    insn_syms[i] = ID2SYM(rb_intern(insn_name(i)));
+	}
+	INIT_SYMBOL(toplevel);
+	INIT_SYMBOL(method);
+	INIT_SYMBOL(block);
+	INIT_SYMBOL(class);
+	INIT_SYMBOL(rescue);
+	INIT_SYMBOL(ensure);
+	INIT_SYMBOL(eval);
+    }
+    
+    /* type */
+    switch(iseq->type) {
+      case ISEQ_TYPE_TOP:    type = sym_toplevel; break;
+      case ISEQ_TYPE_METHOD: type = sym_method;   break;
+      case ISEQ_TYPE_BLOCK:  type = sym_block;    break;
+      case ISEQ_TYPE_CLASS:  type = sym_class;    break;
+      case ISEQ_TYPE_RESCUE: type = sym_rescue;   break;
+      case ISEQ_TYPE_ENSURE: type = sym_ensure;   break;
+      case ISEQ_TYPE_EVAL:   type = sym_eval;     break;
+      default: rb_bug("unsupported iseq type");
+    };
+
+    if (iseq->type == ISEQ_TYPE_METHOD ||
+	iseq->type == ISEQ_TYPE_TOP ||
+	iseq->type == ISEQ_TYPE_CLASS) {
+	opt = 1;
+    }
+    /* args */
+    for (i=0; i<iseq->argc; i++) {
+	rb_ary_push(args, ID2SYM(iseq->local_tbl[i+opt]));
+    }
+    /* vars */
+    for(; i<iseq->local_size - opt; i++) {
+	rb_ary_push(vars, ID2SYM(iseq->local_tbl[i+opt]));
+    }
+    
+    /* body */
+    for (seq = iseq->iseq; seq < iseq->iseq + iseq->size; ) {
+	VALUE ary = rb_ary_new();
+	VALUE insn = *seq++;
+	int j;
+	rb_ary_push(ary, insn_syms[insn]);
+	for (j=0; j<insn_len(insn)-1; j++, seq++) {
+	    switch (insn_op_type(insn, j)) {
+	      case TS_OFFSET: {
+		  unsigned int idx = seq - iseq->iseq + *seq + 1;
+		  char buff[0x20];
+		  VALUE sym;
+		  snprintf(buff, 0x20, "label_%u", idx);
+		  sym = ID2SYM(rb_intern(buff));
+		  rb_ary_push(ary, sym);
+		  st_insert(labels_table, idx, sym);
+		  break;
+	      }
+	      case TS_LINDEX:
+	      case TS_DINDEX:
+	      case TS_NUM:
+		rb_ary_push(ary, INT2FIX(*seq));
+		break;
+	      case TS_VALUE:
+		rb_ary_push(ary, *seq);
+		break;
+	      case TS_ISEQ:
+		{
+		    yarv_iseq_t *iseq = (yarv_iseq_t *)*seq;
+		    if (iseq) {
+			VALUE val = iseq_iseq2simpledata(iseq);
+			rb_ary_push(ary, val);
+		    }
+		    else {
+			rb_ary_push(ary, Qnil);
+		    }
+		}
+		break;
+	      case TS_GENTRY:
+		{
+		    struct global_entry *entry = (struct global_entry *)*seq;
+		    rb_ary_push(ary, ID2SYM(entry->id));
+		}
+		break;
+	      case TS_IC:
+		rb_ary_push(ary, Qnil);
+		break;
+	      case TS_ID:
+		rb_ary_push(ary, ID2SYM(*seq));
+		break;
+	      case TS_CDHASH:
+	      default:
+		rb_bug("unknown operand: %c", insn_op_type(insn, j));
+	    }
+	}
+	rb_ary_push(body, ary);
+    }
+
+    nbody = body;
+    body = rb_ary_new();
+
+    for (i=0, pos=0; i<RARRAY(nbody)->len; i++) {
+	VALUE ary = RARRAY(nbody)->ptr[i];
+	VALUE label;
+	
+	if (st_lookup(labels_table, pos, &label)) {
+	    rb_ary_push(body, label);
+	}
+	rb_ary_push(body, ary);
+	pos += RARRAY(ary)->len;
+    }
+
+    st_free_table(labels_table);
+
+    /* build */
+    
+    /* [magic, major_version, minor_version, format_type, misc,
+     *  name, filename, line,
+     *  type, args, vars, exception_table, body]
+     */
+    rb_ary_push(val, rb_str_new2("YARVInstructionSimpledataFormat"));
+    rb_ary_push(val, INT2FIX(1));
+    rb_ary_push(val, INT2FIX(1));
+    rb_ary_push(val, INT2FIX(1));
+    rb_ary_push(val, Qnil);
+    rb_ary_push(val, iseq->name);
+    rb_ary_push(val, iseq->file_name);
+    rb_ary_push(val, line);
+    rb_ary_push(val, type);
+    rb_ary_push(val, args);
+    rb_ary_push(val, vars);
+    rb_ary_push(val, exception);
+    rb_ary_push(val, body);
+    return val;
+}
+
+struct st_table *
+insn_make_insn_table(void)
+{
+    struct st_table *table;
+    table = st_init_numtable();
+    int i;
+
+    for (i=0; i<YARV_MAX_INSTRUCTION_SIZE; i++) {
+	st_insert(table, ID2SYM(rb_intern(insn_name(i))), i);
+    }
+
+    return table;
+}

Modified: trunk/insns.def
===================================================================
--- trunk/insns.def	2006-03-08 01:32:31 UTC (rev 482)
+++ trunk/insns.def	2006-04-07 02:18:53 UTC (rev 483)
@@ -800,7 +800,7 @@
  */
 DEFINE_INSN
 definemethod
-(ID id, VALUE body, num_t is_singleton)
+(ID id, ISEQ body, num_t is_singleton)
 (VALUE obj)
 ()
 {
@@ -960,7 +960,7 @@
  */
 DEFINE_INSN
 postexe
-(BLOCKISEQ blockiseq)
+(ISEQ blockiseq)
 ()
 ()
 {
@@ -1007,51 +1007,82 @@
    `A`BAklass NX`B
  */
 DEFINE_INSN
-classdef
-(ID id, VALUE klass_iseqval)
+defineclass
+(ID id, ISEQ klass_iseq, num_t define_type)
 (VALUE cbase, VALUE super)
 (VALUE val)
 {
-    /* val is dummy.  classdef returns class scope value */
-    yarv_iseq_t *klass_iseq;
     VALUE klass;
 
-    if (super == Qnil) {
-	super = rb_cObject;
-    }
-    if (cbase == Qnil) {
-	cbase = th_get_cbase(th);
-    }
+    if (define_type == 0) {
+	/* val is dummy.  classdef returns class scope value */
 
-    /* find klass */
-    if (rb_const_defined_at(cbase, id)) {
-	/* already exist */
-	klass = rb_const_get_at(cbase, id);
-	if (TYPE(klass) != T_CLASS) {
-	    rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id));
+	if (super == Qnil) {
+	    super = rb_cObject;
 	}
+	if (cbase == Qnil) {
+	    cbase = th_get_cbase(th);
+	}
 
-	if (super != rb_cObject) {
-	    VALUE tmp;
-	    tmp = rb_class_real(RCLASS(klass)->super);
+	/* find klass */
+	if (rb_const_defined_at(cbase, id)) {
+	    /* already exist */
+	    klass = rb_const_get_at(cbase, id);
+	    if (TYPE(klass) != T_CLASS) {
+		rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id));
+	    }
 
-	    if (tmp != super) {
-		rb_raise(rb_eTypeError, "superclass mismatch for class %s",
-			 rb_id2name(id));
+	    if (super != rb_cObject) {
+		VALUE tmp;
+		tmp = rb_class_real(RCLASS(klass)->super);
+
+		if (tmp != super) {
+		    rb_raise(rb_eTypeError, "superclass mismatch for class %s",
+			     rb_id2name(id));
+		}
 	    }
 	}
+	else {
+	    /* new class declaration */
+	    klass = rb_define_class_id(id, super);
+	    rb_set_class_path(klass, cbase, rb_id2name(id));
+	    rb_const_set(cbase, id, klass);
+	    rb_class_inherited(super, klass);
+	}
     }
-    else {
-	/* new class declaration */
-	klass = rb_define_class_id(id, super);
-	rb_set_class_path(klass, cbase, rb_id2name(id));
-	rb_const_set(cbase, id, klass);
-	rb_class_inherited(super, klass);
+    else if (define_type == 1) {
+	/* val is dummy.  classdef returns class scope value */
+	/* super is dummy */
+	klass = rb_singleton_class(cbase);
     }
+    else if (define_type == 2) {
+	/* val is dummy.  classdef returns class scope value */
+	/* super is dummy */
+	if (cbase == Qnil) {
+	    cbase = th_get_cbase(th);
+	}
 
-    GetISeqVal(klass_iseqval, klass_iseq);
+	/* find klass */
+	if (rb_const_defined_at(cbase, id)) {
+	    klass = rb_const_get_at(cbase, id);
+	    /* already exist */
+	    if (TYPE(klass) != T_MODULE) {
+		rb_raise(rb_eTypeError, "%s is not a module", rb_id2name(id));
+	    }
+	}
+	else {
+	    /* new module declaration */
+	    klass = rb_define_module_id(id);
+	    rb_set_class_path(klass, cbase, rb_id2name(id));
+	    rb_const_set(cbase, id, klass);
+	}
+    }
+    else {
+	rb_bug("unknown defineclass type: %d", define_type);
+    }
+    
     COPY_CREF(klass_iseq->cref_stack, th_cref_push(th, klass, NOEX_PUBLIC));
-
+    
     /* enter scope */
     push_frame(th, klass_iseq,
 	       FRAME_MAGIC_CLASS, klass, (VALUE) GET_DFP() | 0x02,
@@ -1063,85 +1094,7 @@
     NEXT_INSN();
 }
 
-/**
-  @c class/module
-  @e enter singleton class definition scope.
-  @j NX`XR[vsB
- */
-DEFINE_INSN
-singletonclassdef
-(VALUE sclass_iseqval)
-(VALUE obj)
-(VALUE val)
-{
-    /* val is dummy.  classdef returns class scope value */
-    yarv_iseq_t *sklass_iseq;
-    VALUE klass;
 
-    GetISeqVal(sclass_iseqval, sklass_iseq);
-    klass = rb_singleton_class(obj);
-
-    COPY_CREF(sklass_iseq->cref_stack, th_cref_push(th, klass, NOEX_PUBLIC));
-
-    /* enter scope */
-    push_frame(th, sklass_iseq,
-	       FRAME_MAGIC_CLASS, klass, (VALUE) GET_DFP() | 0x02,
-	       sklass_iseq->iseq_encoded, GET_SP(), 0,
-	       sklass_iseq->local_size);
-    RESTORE_REGS();
-    
-    INC_VM_STATE_VERSION();
-    NEXT_INSN();
-}
-
-/**
-  @c class/module
-  @e enter module definition scope.
-  @j W[`XR[vsB
- */
-DEFINE_INSN
-moduledef
-(ID id, VALUE module_iseqval)
-(VALUE mbase)
-(VALUE val)
-{
-    yarv_iseq_t *module_iseq;
-    VALUE module;
-
-    if (mbase == Qnil) {
-	mbase = th_get_cbase(th);
-    }
-
-    /* find klass */
-    if (rb_const_defined_at(mbase, id)) {
-	module = rb_const_get_at(mbase, id);
-	/* already exist */
-	if (TYPE(module) != T_MODULE) {
-	    rb_raise(rb_eTypeError, "%s is not a module", rb_id2name(id));
-	}
-    }
-    else {
-	/* new module declaration */
-	module = rb_define_module_id(id);
-	rb_set_class_path(module, mbase, rb_id2name(id));
-	rb_const_set(mbase, id, module);
-    }
-
-    GetISeqVal(module_iseqval, module_iseq);
-    COPY_CREF(module_iseq->cref_stack, th_cref_push(th, module, NOEX_PUBLIC));
-
-    /* enter scope */
-    push_frame(th, module_iseq,
-	       FRAME_MAGIC_CLASS, module, (VALUE) GET_DFP() | 0x02,
-	       module_iseq->iseq_encoded, GET_SP(), 0,
-	       module_iseq->local_size);
-    RESTORE_REGS();
-
-    INC_VM_STATE_VERSION();
-    NEXT_INSN();
-}
-
-
 /**********************************************************/
 /* deal with control flow 2: method/iterator              */
 /**********************************************************/
@@ -1157,7 +1110,7 @@
  */
 DEFINE_INSN
 send
-(ID id, num_t op_argc, BLOCKISEQ blockiseq, num_t op_flag, IC ic)
+(ID id, num_t op_argc, ISEQ blockiseq, num_t op_flag, IC ic)
 (...)
 (VALUE val) // inc += - (op_argc + ((op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ? 1 : 0));
 {
@@ -1260,8 +1213,8 @@
   @j super(args) # args.size => num
  */
 DEFINE_INSN
-super
-(num_t op_argc, BLOCKISEQ blockiseq, num_t flag)
+invokesuper
+(num_t op_argc, ISEQ blockiseq, num_t flag)
 (...)
 (VALUE val) // inc += - op_argc;
 {
@@ -1285,7 +1238,7 @@
   @j yield(args) # args.size => num
  */
 DEFINE_INSN
-yield
+invokeblock
 (num_t num, num_t flag)
 (...)
 (VALUE val)  // inc += 1 - num;
@@ -1344,7 +1297,7 @@
   @j XR[vB
  */
 DEFINE_INSN
-end
+leave
 ()
 (VALUE val)
 (VALUE val)
@@ -1495,7 +1448,7 @@
   @j  val  false  nil APC  (PC + dst) B
  */
 DEFINE_INSN
-if
+branchif
 (OFFSET dst)
 (VALUE val)
 ()
@@ -1512,7 +1465,7 @@
   @j  val  false  nil APC  (PC + dst) B
  */
 DEFINE_INSN
-unless
+branchunless
 (OFFSET dst)
 (VALUE val)
 ()

Modified: trunk/rb/insns2vm.rb
===================================================================
--- trunk/rb/insns2vm.rb	2006-03-08 01:32:31 UTC (rev 482)
+++ trunk/rb/insns2vm.rb	2006-04-07 02:18:53 UTC (rev 483)
@@ -838,8 +838,8 @@
       "TS_VARIABLE"
     when /^CDHASH/
       "TS_CDHASH"
-    when /^BLOCKISEQ/
-      "TS_BLOCKISEQ"
+    when /^ISEQ/
+      "TS_ISEQ"
     else
       raise "unknown op type: #{op}"
     end
@@ -855,7 +855,7 @@
     'TS_GENTRY'    => 'G',
     'TS_IC'        => 'C',
     'TS_CDHASH'    => 'H',
-    'TS_BLOCKISEQ' => 'B',
+    'TS_ISEQ'      => 'S',
     'TS_VARIABLE'  =>  '.',
   }
   

Modified: trunk/rb/yasm.rb
===================================================================
--- trunk/rb/yasm.rb	2006-03-08 01:32:31 UTC (rev 482)
+++ trunk/rb/yasm.rb	2006-04-07 02:18:53 UTC (rev 483)
@@ -1,316 +1,259 @@
 #
 # YASM: YARV Assembler
 #
-raise "YASM is currently not supported"
-
-=begin
-
-== Usage:
-
-require 'yasm'
-yasm = YARVCore::Assembler.new
-
-
+# Usage: See examples on the end of this file.
 #
-# def m1(a, b)
-#   p [a, b]
-# end
-# =>
-m1 = yasm.method(:m1, :a, :b){|x|
-  x.putself
-  x.getlocal :a
-  x.getlocal :b
-  x.newarray 2
-  x.send :p, 2
-  x.putnil
-  x.end
-}
 
-
-#
-# def m2(a1, a2)
-#   begin
-#     t1()
-#   rescue
-#     t2()
-#   ensure
-#     t3()
-#   end
-# end
-m2 = yasm.method(:m2, :a1, :a2){|x|
-  x.begin{|y|
-    y.putself
-    y.send :t1, 0
-  }.rescue{|y|
-    y.putself
-    y.send :t2, 0
-  }.ensure{|y|
-    y.putself
-    y.send :t3, 0
-  }
-}
-
-
-#
-# def m3(a)   # abs
-#   if a > 0
-#     a
-#   else
-#     -a
-#   end
-# end
-m3 = yasm.method(:m3, :a){|x|
-  x.getlocal   :a
-  x.putobject  0
-  x.send :>,   1
-  x.unless     :lelse
-  x.getlocal   :a
-  x.jump       :lend
-x.label      :lelse ##
-  x.getlocal   :a
-  x.send       :+@, 0
-x.label      :lend  ##
-  x.end
-}
-
-
-#
-# def m4(a)
-#   3.times{|i|
-#     p a
-#   }
-# end
-m4 = yasm.method(:m4, :a){|x|
-  x.putobject 3
-  x.send      :times, 0, x.block(:i){|y|
-    y.getself
-    y.getlocal :a
-    y.send     :p, 1
-    y.end
-  }
-  x.end
-}
-
-
-#
-# def m5(a)
-#   b = a * 2
-# end
-m5 = yasm.method(:a){|x|
-  x.local_vars(:b) # you must declare local variables at first
-  x.getlocal :a
-  x.putobject 2
-  x.send :*, 1
-  x.dup
-  x.setlocal :b
-  x.end
-}
-
-
-
-
-#
-# def m1(...); ...; end
-#
-# m1(1, 2)
-# =>
-top = yasm.top{|x|
-  x.methoddef(:m1, m1)
-  x.putself
-  x.putobject 1
-  x.putobject 2
-  x.send :m1, 2
-  x.end
-}
-
-top = yasm.top{|x|
-  x.methoddef(:m1, :a){|y|
-    y.putself
-    y.getlocal :a
-    y.send :p, 1
-    y.end
-  }
-  x.putself
-  x.putobject 1
-  x.send :m1, 1
-  x.end
-}
-
-top = yasm.top{|x|
-  x.putself
-  x.putobject 1
-  x.send :p, 1
-}
-
-#=> run
-YARVCore::eval_parsed(top)
-
-=end
-
-require 'yarvcore'
 require 'yasmdata'
 
 module YARVCore
   class Assembler
+    def self.toplevel vars = [], &b
+      sdb = SimpleDataBuilder.new(
+        :toplevel, "<toplevel@yasm>", "<yasm>",
+        [], vars, [nil], nil
+      )
+      sdb.instance_eval(&b)
+      sdb
+    end
 
-    # from yarvcore.h
-    ISeqType = {
-      :top    => 1,
-      :method => 2,
-      :block  => 3,
-      :class  => 4,
-      :rescue => 5,
-      :ensure => 6,
-    }
+    def self.method name, args = [], vars = [], &b
+      sdb = SimpleDataBuilder.new(
+        :method, name, "TODO: filename",
+        args, vars, [nil], nil
+      )
+      sdb.instance_eval(&b)
+      sdb
+    end
     
-    class ScopeAssember
-      def initialize scope_type, id, file_name, parent, args = []
-        @st     = scope_type
-        @seq    = []
-        @args   = args
-        @locals = []
-        @labels = {}
-        @parent = parent || false
-        @file_name = file_name
-
-        # null iseq
-        @iseq   = YARVCore::InstructionSequence.new(
-          false, id.to_s, file_name,
-          parent ? parent.iseq : nil, ISeqType[scope_type])
+    class SimpleDataBuilder
+      def initialize type, name, filename, args, vars, lopt, parent
+        @type = type
+        @name = name
+        @filename = filename
+        @args = args || []
+        @vars = vars || []
+        @locals = args + vars + lopt
+        @line = []
+        @body = []
+        @exception = []
+        @parent_sdb = parent
+        @local_sdb = parent ? parent.local_sdb : self
       end
-      attr_reader :iseq
-      
-      def set_parent parent
-        @parent = parent
-      end
 
-      def local_vars *vars
-        @locals = vars
-      end
-      
-      def assemble
-        @iseq.assemble @args, @locals, @seq
-      end
+      attr_reader :body
+      attr_reader :locals
+      attr_reader :local_sdb, :parent_sdb
 
-      def block *args
-        sa = ScopeAssember.new(:block, 'block', @file_name, self, args)
-        sa.set_parent self
-        yield(sa)
-        sa.assemble
+      def to_simpledata
+        # [magic, major_version, minor_version, format_type, misc,
+        #  name, filename, line,
+        #  type, args, vars, exception_table, body]
+        ['YARVInstructionSimpledataFormat', 1, 1, 1, nil,
+         @name, @filename, @line,
+         @type, @args, @vars, @exception, @body]
       end
 
-      def rescue
-        sa = ScopeAssember.new(:rescue, 'rescue', args)
-        sa.set_parent self
-        yield(sa)
-        sa.assemble
+      def to_iseq
+        YARVCore::InstructionSequence.load_simpledata(self.to_simpledata)
       end
 
-      def ensure
-        sa = ScopeAssember.new(:ensure, 'ensure', args)
-        sa.set_parent self
-        yield(sa)
-        sa.assemble
+      def method name, args=[], vars=[], &b
+        YASM.method(name, args, vars, &b).to_simpledata
       end
-
-      ##
-      def make_insn id, *args
-        if insn_no = YARVCore::InstructionSequence::Instruction.id2insn_no(id)
-          /\:(\d+)\Z/ =~ caller(1)[1]
-          line = $1.to_i
-          @seq << YARVCore::InstructionSequence::Instruction.make(insn_no, line, args)
-          true
-        end
+      
+      def block args=[], vars=[], &b
+        sdb = SimpleDataBuilder.new(
+          :block, "block", "TODO: filename",
+          args, vars, [], self
+        )
+        sdb.instance_eval(&b)
+        sdb.to_simpledata
       end
       
-      def search_local sym
-        @args.each_with_index{|e, i|
-          return 1 + i              if e == sym
+      # label
+      
+      def label sym
+        raise "Label must be Symbol, but #{sym.class}" unless Symbol === sym
+        @body << sym
+      end
+      
+      alias _ label
+      alias l label
+      
+      YARVCore::InstructionSequence::Instruction::InsnID2NO.each_key{|insn|
+        define_method(insn){|*ops|
+          @body << [insn, *ops]
         }
-        @locals.each_with_index{|e, i|
-          return 1 + i + @args.size if e == sym
-        }
-        raise "unknown local variable: #{sym}"
+      }
+      
+      # support instructions
+      
+      def send id, argc, block = nil, flag = 0
+        @body << [:send, id, argc, block, flag, nil]
       end
-
-      def search_label label
-        if lobj = @labels[label]
-          lobj
-        else
-          @labels[label] = YARVCore::InstructionSequence::Label.new(false)
-        end
+      
+      def call id, argc, block = nil
+        @body << [:send, id, argc, block, 0x04, nil]
       end
-
-      def label l
-        @seq << search_label(l)
+      
+      def sym2lidx sym
+        raise unless @locals.index(sym)
+        @local_sdb.locals.size - @local_sdb.locals.index(sym)
       end
       
-      ##
-      
-      def method_missing id, *args
-        unless make_insn id, *args
-          super
-        end
+      def setlocal sym
+        @body << [:setlocal, sym2lidx(sym)]
       end
-
+      
       def getlocal sym
-        make_insn :getlocal, search_local(sym)
+        @body << [:getlocal, sym2lidx(sym)]
       end
 
-      def setlocal sym
-        make_insn :setlocal, search_local(sym)
+      def sym2didx sym
+        sdb = self
+        level = 0
+        while sdb
+          if idx = sdb.locals.index(sym)
+            return [sdb.locals.size - idx, level]
+          end
+          level += 1
+          sdb = sdb.parent_sdb
+        end
+        raise "unknown local dynamic variable: #{sym}"
       end
-
-      def send sym, argc, block = 0, flag = 0
-        make_insn :send, sym, argc, block, flag, 0
-      end
       
-      def end
-        make_insn :end, @args.size + @locals.size + 1
+      def getdynamic sym
+        @body << [:getdynamic, *sym2didx(sym)]
       end
 
-      def jump l
-        make_insn :jump, search_label(l)
+      def setdynamic sym
+        @body << [:setdynamic, *sym2didx(sym)]
       end
       
-      def if l
-        make_insn :if, search_label(l)
+      def definemethod name, method
+        @body << [:definemethod, name, method, 0]
       end
       
-      def unless l
-        make_insn :unless, search_label(l)
+      def definesingletonmethod name, method
+        @body << [:definemethod, name, method, 1]
       end
-      
     end
-    
-    def initialize file_name = '*YASM*'
-      @file_name = file_name
-    end
+  end
+end
 
-    attr_accessor :file_name
-    
-    def top id = 'top'
-      # def initialize scope_type, id, file_name, parent, args = []
-      sa = ScopeAssember.new(:top, id, @file_name,  nil)
-      yield(sa)
-      sa.assemble
-    end
+YASM = YARVCore::Assembler
 
-    def class id = 'Class'
-      sa = ScopeAssember.new(:class, id)
-      yield(sa)
-      sa.assemble
-    end
 
-    def method id, *args
-      sa = ScopeAssember.new(:method, id, @file_name, nil, args)
-      yield(sa)
-      sa.assemble
-    end
-  end
-end
+if __FILE__ == $0
 
-hoge.each{|i|
-  
+#
+# samples
+#
+
+######################################################
+
+result = YASM.toplevel([:a, :b]){
+  #
+  # a = 10
+  # b = 20
+  # p(a+b)
+  # 3.times{|i| p i}
+  #
+  putobject 10
+  setlocal :a
+  putobject 20
+  setlocal :b
+  putself
+  getlocal :a
+  getlocal :b
+  send :+, 1
+  call :p, 1 # call means send with flags 4
+  pop
+  putobject 3
+  send :times, 0, block([:i]){
+    putself
+    getdynamic :i
+    call :p, 1
+    leave
+  }
+  leave
 }
+data = result.to_simpledata
+iseq = result.to_iseq
 
+p data
+iseq.eval #=> 30
+
+###########################################################
+
+#
+# def m1(a, b)
+#   p [a, b]
+# end
+# =>
+m1 = YASM.method(:m1, [:a, :b]){
+  putself
+  getlocal :a
+  getlocal :b
+  newarray 2
+  call :p, 1
+  leave
+}
+
+#
+# def m3(a)   # abs
+#   if a > 0
+#     a
+#   else
+#     -a
+#   end
+# end
+m3 = YASM.method(:m3, [:a]){
+  getlocal :a
+  putobject 0
+  send :>, 1
+  branchunless :label_else
+  getlocal :a
+  jump :label_end
+_ :label_else
+  getlocal :a
+  send :+@, 0
+_ :label_end
+  leave
+}
+
+#
+# def m5(a)
+#   b = a * 2
+# end
+m5 = YASM.method(:m5, [:a], [:b]){
+  getlocal :a
+  putobject 2
+  send :*, 1
+  dup
+  setlocal :b
+  leave
+}
+
+
+#
+# def m1(...); ...; end
+#
+# m1(1, 2)
+# =>
+top = YASM.toplevel{
+  putnil
+  definemethod(:m1, m1.to_simpledata)
+  putself
+  putobject 1
+  putobject 2
+  call :m1, 2
+  leave
+}
+
+#=> run
+top.to_iseq.eval
+
+###########################################################
+end

Modified: trunk/template/insns.inc.tmpl
===================================================================
--- trunk/template/insns.inc.tmpl	2006-03-08 01:32:31 UTC (rev 482)
+++ trunk/template/insns.inc.tmpl	2006-04-07 02:18:53 UTC (rev 483)
@@ -17,3 +17,5 @@
 <%= insns %>
 };
 
+#define YARV_MAX_INSTRUCTION_SIZE <%= @insns.size %>
+

Modified: trunk/vm.c
===================================================================
--- trunk/vm.c	2006-03-08 01:32:31 UTC (rev 482)
+++ trunk/vm.c	2006-04-07 02:18:53 UTC (rev 483)
@@ -1121,13 +1121,11 @@
 
 EVALBODY_HELPER_FUNCTION void
 eval_define_method(yarv_thread_t *th, VALUE obj,
-		   ID id, VALUE body, num_t is_singleton, NODE *cref)
+		   ID id, yarv_iseq_t *miseq, num_t is_singleton, NODE *cref)
 {
     NODE *newbody;
-    yarv_iseq_t *miseq;
     int noex = cref->nd_visi;
     VALUE klass = cref->nd_clss;
-    GetISeqVal(body, miseq);
 
     if (is_singleton) {
 	if (FIXNUM_P(obj) || SYMBOL_P(obj)) {
@@ -1156,7 +1154,7 @@
     COPY_CREF(miseq->cref_stack, cref);
     miseq->klass = klass;
     miseq->defined_method_id = id;
-    newbody = NEW_NODE(YARV_METHOD_NODE, 0, body, 0);
+    newbody = NEW_NODE(YARV_METHOD_NODE, 0, miseq->self, 0);
     rb_add_method(klass, id, newbody, noex);
 
     if (!is_singleton && noex == NOEX_MODFUNC) {

Modified: trunk/vm_evalbody.h
===================================================================
--- trunk/vm_evalbody.h	2006-03-08 01:32:31 UTC (rev 482)
+++ trunk/vm_evalbody.h	2006-04-07 02:18:53 UTC (rev 483)
@@ -18,7 +18,7 @@
 #endif
 // #define DECL_SC_REG(r, reg) VALUE reg_##r
 
-typedef yarv_iseq_t *BLOCKISEQ;
+typedef yarv_iseq_t *ISEQ;
 
 #if !OPT_CALL_THREADED_CODE
 VALUE

Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c	2006-03-08 01:32:31 UTC (rev 482)
+++ trunk/yarvcore.c	2006-04-07 02:18:53 UTC (rev 483)
@@ -40,8 +40,6 @@
 ID idBackquote;
 ID idEqTilde;
 ID idThrowState;
-ID idThrowBackDFP;
-ID idThrowObject;
 ID idAREF;
 ID idASET;
 ID idIntern;
@@ -84,6 +82,7 @@
 	printf(" ");
     }
 }
+
 static void
 MARK_REPORT_BODY(char *msg, int st, void *ptr)
 {
@@ -156,7 +155,6 @@
     return 0;
 }
 
-
 VALUE *th_svar(yarv_thread_t *self, int cnt);
 
 VALUE *
@@ -364,6 +362,7 @@
     return obj;
 }
 
+
 static VALUE
 prepare_iseq_build(yarv_iseq_t *iseq,
 		   VALUE name, VALUE file_name,
@@ -465,14 +464,87 @@
     return self;
 }
 
-VALUE iseq_assemble_setup(VALUE self, VALUE args, VALUE locals, VALUE ary);
+VALUE
+iseq_load_simpledata(VALUE self, VALUE data, VALUE parent)
+{
+    VALUE iseqval = iseq_alloc(cYarvISeq);
 
+    VALUE magic, version1, version2, format_type, misc;
+    VALUE name, filename, line;
+    VALUE type, body, args, vars, exception;
+
+    VALUE iseq_type;
+    struct st_table *type_map = 0;
+
+    /* [magic, major_version, minor_version, format_type, misc,
+     *  name, filename, line,
+     *  type, args, vars, exception_table, body]
+     */
+    
+    magic  = rb_ary_entry(data, 0);
+    version1 = rb_ary_entry(data, 1);
+    version2 = rb_ary_entry(data, 2);
+    format_type = rb_ary_entry(data, 3);
+    misc = rb_ary_entry(data, 4);
+
+    /* TODO: load check */
+
+    name = rb_ary_entry(data, 5);
+    filename = rb_ary_entry(data, 6);
+    line = rb_ary_entry(data, 7);
+
+    type = rb_ary_entry(data, 8);
+    args = rb_ary_entry(data, 9);
+    vars = rb_ary_entry(data, 10);
+    exception = rb_ary_entry(data, 11);
+    body = rb_ary_entry(data, 12);
+
+    yarv_iseq_t *iseq;
+    GetISeqVal(iseqval, iseq);
+    iseq->self = iseqval;
+
+    if (type_map == 0) {
+	type_map = st_init_numtable();
+	st_insert(type_map, ID2SYM(rb_intern("toplevel")), ISEQ_TYPE_TOP);
+	st_insert(type_map, ID2SYM(rb_intern("method")),   ISEQ_TYPE_METHOD);
+	st_insert(type_map, ID2SYM(rb_intern("block")),    ISEQ_TYPE_BLOCK);
+	st_insert(type_map, ID2SYM(rb_intern("class")),    ISEQ_TYPE_CLASS);
+	st_insert(type_map, ID2SYM(rb_intern("rescue")),   ISEQ_TYPE_RESCUE);
+	st_insert(type_map, ID2SYM(rb_intern("ensure")),   ISEQ_TYPE_ENSURE);
+	st_insert(type_map, ID2SYM(rb_intern("eval")),     ISEQ_TYPE_EVAL);
+    }
+
+    if (st_lookup(type_map,
+		  type, &iseq_type) == 0) {
+	rb_raise(rb_eTypeError, "unsupport type: %p", type);
+    }
+
+    if (parent == Qnil) {
+	parent = 0;
+    }
+
+    prepare_iseq_build(iseq,
+		       name, filename,
+		       parent, iseq_type, 0);
+
+    iseq_simpledata2iseq(iseq, line, args, vars, exception, body);
+
+    cleanup_iseq_build(iseq);
+    return iseqval;
+}
+
 static VALUE
-iseq_assemble(VALUE self, VALUE args, VALUE locals, VALUE insn_ary)
+iseq_m_load_simpledata(VALUE self, VALUE data)
 {
-    return iseq_assemble_setup(self, args, locals, insn_ary);
+    return iseq_load_simpledata(self, data, 0);
 }
 
+static VALUE
+iseq_eval(VALUE self)
+{
+    return yarvcore_eval_iseq(self);
+}
+
 VALUE
 iseq_inspect(VALUE self)
 {
@@ -486,6 +558,16 @@
     return rb_str_new2(buff);
 }
 
+VALUE iseq_iseq2simpledata(yarv_iseq_t *iseq);
+
+static VALUE
+iseq_to_simpledata(VALUE self)
+{
+    yarv_iseq_t *iseq;
+    GetISeqVal(self, iseq);
+    return iseq_iseq2simpledata(iseq);
+}
+
 /******/
 /* VM */
 /******/
@@ -1122,7 +1204,6 @@
 
     rb_define_singleton_method(mYarvCore, "eval", yarvcore_eval, 3);
     rb_define_singleton_method(mYarvCore, "parse", yarvcore_parse, 3);
-    rb_define_singleton_method(mYarvCore, "eval_iseq", yarvcore_eval_iseq, 1);
 
     /* declare YARVCore::InstructionSequence */
     cYarvISeq =
@@ -1131,8 +1212,10 @@
     rb_define_method(cYarvISeq, "initialize", iseq_init, 6);
     rb_define_method(cYarvISeq, "inspect", iseq_inspect, 0);
     rb_define_method(cYarvISeq, "disasm", iseq_disasm, 0);
-    rb_define_method(cYarvISeq, "assemble", iseq_assemble, 3);
-    // rb_define_singleton_method(cYarvISeq, "new_from_insn_ary", iseq_init_from_insn_ary, 1);
+    rb_define_method(cYarvISeq, "to_simpledata", iseq_to_simpledata, 0);
+    rb_define_method(cYarvISeq, "eval", iseq_eval, 0);
+    rb_define_singleton_method(cYarvISeq, "load_simpledata",
+			       iseq_m_load_simpledata, 1);
 
     /* declare YARVCore::VM */
     cYarvVM = rb_define_class_under(mYarvCore, "VM", rb_cObject);
@@ -1225,8 +1308,6 @@
     idMethodMissing = rb_intern("method_missing");
 
     idThrowState = rb_intern("#__ThrowState__");
-    idThrowBackDFP = rb_intern("#__ThrowBackDFP__");
-    idThrowObject = rb_intern("#__ThrowObject__");
 
     idBitblt = rb_intern("bitblt");
     idAnswer = rb_intern("the_answer_to_life_the_universe_and_everything");

Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h	2006-03-08 01:32:31 UTC (rev 482)
+++ trunk/yarvcore.h	2006-04-07 02:18:53 UTC (rev 483)
@@ -107,8 +107,6 @@
 extern ID idBackquote;
 extern ID idEqTilde;
 extern ID idThrowState;
-extern ID idThrowBackDFP;
-extern ID idThrowObject;
 extern ID idAREF;
 extern ID idASET;
 extern ID idIntern;


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

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