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

yarv-diff:15

From: ko1 atdot.net
Date: 21 Jun 2005 13:39:41 -0000
Subject: [yarv-diff:15] r170 - in trunk: . rb tmpl

Author: ko1
Date: 2005-06-21 22:39:40 +0900 (Tue, 21 Jun 2005)
New Revision: 170

Modified:
   trunk/ChangeLog
   trunk/compile.c
   trunk/compile.h
   trunk/disasm.c
   trunk/rb/insns2vm.rb
   trunk/test.rb
   trunk/tmpl/optinsn.inc.tmpl
   trunk/yarvcore.c
   trunk/yarvcore.h
Log:
	* yarvcore.h, compile.[ch], tmpl/optinsn.inc.tmpl, rb/insns2vm.rb :
	change data structure (don't use Ruby's array to represent a
	instruction sequence)

	* disasm.c : add separator



Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2005-06-13 22:51:03 UTC (rev 169)
+++ trunk/ChangeLog	2005-06-21 13:39:40 UTC (rev 170)
@@ -4,7 +4,15 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2005-06-21(Tue) 22:34:07 +0900  Koichi Sasada  <ko1 atdot.net>
 
+	* yarvcore.h, compile.[ch], tmpl/optinsn.inc.tmpl, rb/insns2vm.rb :
+	change data structure (don't use Ruby's array to represent a
+	instruction sequence)
+
+	* disasm.c : add separator
+
+
 2005-06-14(Tue) 07:48:58 +0900  Koichi Sasada  <ko1 atdot.net>
 
 	* compile.c : support "for" statement

Modified: trunk/compile.c
===================================================================
--- trunk/compile.c	2005-06-13 22:51:03 UTC (rev 169)
+++ trunk/compile.c	2005-06-21 13:39:40 UTC (rev 170)
@@ -15,32 +15,42 @@
 #include "insns.inc"
 
 
+#ifdef HAVE_STDARG_PROTOTYPES
+#include <stdarg.h>
+#define va_init_list(a,b) va_start(a,b)
+#else
+#include <varargs.h>
+#define va_init_list(a,b) va_start(a)
+#endif
+
+
 /* for debug */
 static long gl_node_level = 0;
 static long gl_tmp = 0;
+static void debug_list(ISEQ_LINK_ANCHOR *anchor);
 
-struct link_anchor{
-  struct iseq_link_element anchor;
-  struct iseq_link_element *last;
-};
 
-static VALUE iseq_compile_each(VALUE self, NODE* n, int);
-static VALUE iseq_setup(VALUE self, VALUE seq_ary, struct iseq_object *iseqobj);
+static void ADD_LINKED_LIST(ISEQ_LINK_ANCHOR *anchor, ISEQ_LINK_ELEMENT* elem);
 
-static void iseq_optimize(VALUE self, struct link_anchor *anchor, VALUE ary);
-static void iseq_insns_unification(VALUE self,  struct link_anchor *anchor, VALUE ary);
-static void set_sequence_stackcaching(struct link_anchor *anchor, VALUE ary);
+static INSN_OBJECT *new_insn_body(struct iseq_object *iseqobj, int line_no,
+                                         int insn_id, int argc, ...);
+static LABEL_OBJECT *new_label_body(struct iseq_object *iseqobj, int line);
 
-static VALUE set_sequence(VALUE self,  struct link_anchor *anchor);
+static int iseq_compile_each(VALUE self, ISEQ_LINK_ANCHOR *anchor, NODE* n, int);
+static int iseq_setup(VALUE self, ISEQ_LINK_ANCHOR *anchor);
 
-static VALUE set_exception_table(VALUE self);
-static VALUE set_localtbl(VALUE self, ID* tbl);
-static VALUE set_arguments(VALUE self, NODE *node);
-static NODE* set_block_local_tbl(VALUE self, NODE *node, VALUE seq_ary);
-static VALUE set_exception_tbl(VALUE self);
-static VALUE set_optargs_table(VALUE self);
-static VALUE new_label(int label_no);
+static int iseq_optimize(struct iseq_object *iseqobj, ISEQ_LINK_ANCHOR *anchor);
+static int iseq_insns_unification(struct iseq_object *iseqobj,  ISEQ_LINK_ANCHOR *anchor);
+static int set_sequence_stackcaching(struct iseq_object *iseqobj, ISEQ_LINK_ANCHOR *anchor);
+static int set_sequence(struct iseq_object *iseqobj,  ISEQ_LINK_ANCHOR *anchor);
 
+static int set_exception_table(struct iseq_object *iseqobj);
+static int set_localtbl(struct iseq_object *iseqobj, ID* tbl);
+static int set_arguments(VALUE self, struct iseq_object *iseqobj, ISEQ_LINK_ANCHOR *anchor, NODE *node);
+static NODE* set_block_local_tbl(VALUE self, struct iseq_object *iseqobj, NODE *node, ISEQ_LINK_ANCHOR *anchor);
+static int set_exception_tbl(struct iseq_object *iseqobj);
+static int set_optargs_table(struct iseq_object *iseqobj);
+
 #include "optinsn.inc"
 #include "optunifs.inc"
 
@@ -48,12 +58,12 @@
 #define MREWIND_DSIZE() 2
 
 VALUE iseq_compile(VALUE self, VALUE narg){
-  VALUE volatile seq_ary = NEW_SEQ();
+  DECL_ANCHOR(list_anchor);
   VALUE tmp;
   struct iseq_object *iseqobj;
-  
   NODE *node = (NODE*)narg;
 
+
   debugs("[compile step 1 (traverse each node)]\n");
   
   GetISeqVal(self, iseqobj);
@@ -61,7 +71,7 @@
   iseqobj->node = node;
   
   if(iseqobj->type == ISEQ_TYPE_BLOCK){
-    node = set_block_local_tbl(self, node, seq_ary);
+    node = set_block_local_tbl(self, iseqobj, node, &list_anchor);
   }
   /*
     compile_each return nested array.
@@ -73,7 +83,7 @@
     NODE *ndargs  = 0;
 
     if(iseqobj->type != ISEQ_TYPE_BLOCK){
-      set_localtbl(self, ((NODE*)node)->nd_tbl);
+      set_localtbl(iseqobj, ((NODE*)node)->nd_tbl);
     }
 
     if(sn_body){
@@ -82,16 +92,16 @@
         if(nd_type(sn_body->nd_head) == NODE_ARGS){
           /* some method attribute process */
           ndargs = sn_body->nd_head;
-          ADD_SEQ(seq_ary, set_arguments(self, ndargs));
+          set_arguments(self, iseqobj, &list_anchor, ndargs);
           
           /* with sn_body->nd_head */
           if(iseqobj->type == ISEQ_TYPE_METHOD){
             iseqobj->rewind_frame_size = iseqobj->local_size + MREWIND_DSIZE();
-            ADD_SEQ(seq_ary, COMPILE("normal method", sn_body->nd_next));
+            COMPILE(&list_anchor, "normal method", sn_body->nd_next);
           }
           else if(iseqobj->type == ISEQ_TYPE_CLASS){
             iseqobj->rewind_frame_size = iseqobj->local_size + REWIND_DSIZE();
-            ADD_SEQ(seq_ary, COMPILE("class/module", sn_body->nd_next));
+            COMPILE(&list_anchor, "class/module", sn_body->nd_next);
           }
           else{
             rb_bug("must be class or method");
@@ -103,11 +113,11 @@
 
           if(iseqobj->type == ISEQ_TYPE_CLASS){
             iseqobj->rewind_frame_size = iseqobj->local_size + REWIND_DSIZE();
-            ADD_SEQ(seq_ary, COMPILE("class/module", sn_body));
+            COMPILE(&list_anchor, "class/module", sn_body);
           }
           else if(iseqobj->type == ISEQ_TYPE_BLOCK){
             iseqobj->rewind_frame_size = iseqobj->local_size + REWIND_DSIZE();
-            ADD_SEQ(seq_ary, COMPILE("normal block", sn_body));
+            COMPILE(&list_anchor, "normal block", sn_body);
           }
           else{
             rb_bug("must be class or block");
@@ -119,14 +129,14 @@
         /* some method attribute process */
         debugs("empty method\n");
         
-        ADD_SEQ (seq_ary, set_arguments(self, sn_body));
-        ADD_INSN(seq_ary, nd_line(sn_body), putnil);
+        set_arguments(self, iseqobj, &list_anchor, sn_body);
+        ADD_INSN(&list_anchor, nd_line(sn_body), putnil);
 
         iseqobj->rewind_frame_size = iseqobj->local_size + MREWIND_DSIZE();
         break;
 
       default:
-        ADD_SEQ(seq_ary, COMPILE("other scope", sn_body));
+        COMPILE(&list_anchor, "other scope", sn_body);
         
         iseqobj->rewind_frame_size = iseqobj->local_size + REWIND_DSIZE();
         break;
@@ -134,38 +144,40 @@
     }
     else{
       /* sn_body == 0 */
-      ADD_INSN(seq_ary, 0, putnil);
+      ADD_INSN(&list_anchor, 0, putnil);
       
       iseqobj->rewind_frame_size = iseqobj->local_size + REWIND_DSIZE();
     }
   }
   else{
     if(iseqobj->type == ISEQ_TYPE_BLOCK){
-      volatile VALUE endl;
+      LABEL_OBJECT* endl;
+      
       endl = iseqobj->compile_data->end_label = NEW_LABEL(0);
       iseqobj->compile_data->start_label = NEW_LABEL(0);
       iseqobj->rewind_frame_size = iseqobj->local_size + REWIND_DSIZE();
-      ADD_LABEL(seq_ary, iseqobj->compile_data->start_label);
-      ADD_SEQ  (seq_ary ,COMPILE("block body", node));
-      ADD_LABEL(seq_ary, iseqobj->compile_data->end_label);
+      
+      ADD_LABEL(&list_anchor, iseqobj->compile_data->start_label);
+      COMPILE(&list_anchor, "block body", node);
+      ADD_LABEL(&list_anchor, iseqobj->compile_data->end_label);
     }
     else if(iseqobj->type == ISEQ_TYPE_TOP){
-      set_localtbl(self, ruby_scope->local_tbl);
+      set_localtbl(iseqobj, ruby_scope->local_tbl);
       iseqobj->rewind_frame_size = iseqobj->local_size + REWIND_DSIZE();
-      ADD_SEQ(seq_ary, COMPILE("top level node", node));
+      COMPILE(&list_anchor, "top level node", node);
     }
     else if(iseqobj->type == ISEQ_TYPE_RESCUE){
-      set_exception_tbl(self);
+      set_exception_tbl(iseqobj);
       iseqobj->rewind_frame_size = iseqobj->local_size + REWIND_DSIZE();
-      ADD_SEQ(seq_ary, COMPILE("rescue", node));
+      COMPILE(&list_anchor, "rescue", node);
     }
     else if(iseqobj->type == ISEQ_TYPE_ENSURE){
-      set_exception_tbl(self);
+      set_exception_tbl(iseqobj);
       iseqobj->rewind_frame_size = iseqobj->local_size + REWIND_DSIZE();
-      ADD_SEQ(seq_ary, COMPILE_POPED("ensure", node));
+      COMPILE_POPED(&list_anchor, "ensure", node);
     }
     else if(node == 0){
-      ADD_SEQ(seq_ary, COMPILE("nil", node));
+      COMPILE(&list_anchor, "nil", node);
     }
     else{
       rb_bug("unknown scope");
@@ -177,26 +189,24 @@
   if(iseqobj->type == ISEQ_TYPE_RESCUE ||
      iseqobj->type == ISEQ_TYPE_ENSURE){
     
-    ADD_INSN2(seq_ary, 0, getdynamic, I2F(1), I2F(0));
-    ADD_INSN1(seq_ary, 0, throw, I2F(0));
+    ADD_INSN2(&list_anchor, 0, getdynamic, I2F(1), I2F(0));
+    ADD_INSN1(&list_anchor, 0, throw, I2F(0));
   }
   else{
-    ADD_INSN1(seq_ary, 0, end, I2F(iseqobj->rewind_frame_size));
+    ADD_INSN1(&list_anchor, 0, end, I2F(iseqobj->rewind_frame_size));
   }
 
-  return iseq_setup(self, seq_ary, iseqobj);
+  return iseq_setup(self, &list_anchor);
 }
 
 
 VALUE thread_eval_body(VALUE);
 
-static VALUE iseq_translate_direct_threaded_code(VALUE self){
+static int iseq_translate_direct_threaded_code(struct iseq_object *iseqobj){
 #ifdef DISPATCH_DIRECT_THREADED_CODE
-  struct iseq_object *iseqobj;
   void **table = (void **)thread_eval_body(0);
   int i, len;
   
-  GetISeqVal(self, iseqobj);
   iseqobj->iseq_dt = ALLOC_N(VALUE, iseqobj->size);
   MEMCPY(iseqobj->iseq_dt, iseqobj->iseq, VALUE, iseqobj->size);
   
@@ -207,9 +217,50 @@
     i += len;
   }
 #endif
-  return self;
+  return COMPILE_OK;
 }
 
+/*********************************************/
+/* definition of data structure for compiler */
+/*********************************************/
+
+
+static void *compile_data_alloc(struct iseq_object *iseqobj, int size){
+  void *ptr = 0;
+  struct iseq_compile_data_storage *storage = iseqobj->compile_data->storage_current;
+
+  if(storage->pos + size > storage->size){
+    unsigned long alloc_size = storage->size * 2;
+    
+  retry:
+    if(alloc_size < size){
+      alloc_size *= 2;
+      goto retry;
+    }
+    storage->next = (void *)ALLOC_N(char, alloc_size +
+                                    sizeof(struct iseq_compile_data_storage));
+    storage = iseqobj->compile_data->storage_current = storage->next;
+
+    storage->next = 0;
+    storage->pos  = 0;
+    storage->size = alloc_size;
+    storage->buff = (char *)(&storage->buff + 1);
+  }
+  
+  ptr = (void *)&storage->buff[storage->pos];
+  storage->pos += size;
+  return ptr;
+}
+
+static struct insn_object *compile_data_alloc_insn(struct iseq_object *iseqobj){
+  return (struct insn_object*)compile_data_alloc(iseqobj, sizeof(struct insn_object));
+}
+
+static struct label_object *compile_data_alloc_label(struct iseq_object *iseqobj){
+  return (struct label_object*)compile_data_alloc(iseqobj, sizeof(struct label_object));
+}
+
+
 /*
  * To make Array to LinkedList, use link_anchor
  */
@@ -217,7 +268,7 @@
 /*
  * elem1, elem2 => elem1, elem2, elem
  */
-static void ADD_LINKED_LIST(struct link_anchor *anchor, struct iseq_link_element* elem){
+static void ADD_LINKED_LIST(ISEQ_LINK_ANCHOR *anchor, ISEQ_LINK_ELEMENT* elem){
   elem->prev = anchor->last;
   anchor->last->next = elem;
   anchor->last = elem;
@@ -226,8 +277,8 @@
 /*
  * elem1, elemX => elem1, elem2, elemX
  */
-static void INSERT_ELEM_NEXT(struct iseq_link_element* elem1,
-                             struct iseq_link_element* elem2){
+static void INSERT_ELEM_NEXT(ISEQ_LINK_ELEMENT* elem1,
+                             ISEQ_LINK_ELEMENT* elem2){
   elem2->next = elem1->next;
   elem2->prev = elem1;
   elem1->next = elem2;
@@ -239,8 +290,8 @@
 /*
  * elemX, elem1 => elemX, elem2, elem1
  */
-static void INSERT_ELEM_PREV(struct iseq_link_element* elem1,
-                             struct iseq_link_element* elem2){
+static void INSERT_ELEM_PREV(ISEQ_LINK_ELEMENT* elem1,
+                             ISEQ_LINK_ELEMENT* elem2){
   elem2->prev = elem1->prev;
   elem2->next = elem1;
   elem1->prev = elem2;
@@ -252,8 +303,8 @@
 /*
  * elemX, elem1, elemY => elemX, elem2, elemY
  */
-static void REPLACE_ELEM(struct iseq_link_element* elem1,
-                         struct iseq_link_element* elem2){
+static void REPLACE_ELEM(ISEQ_LINK_ELEMENT* elem1,
+                         ISEQ_LINK_ELEMENT* elem2){
   elem2->prev = elem1->prev;
   elem2->next = elem1->next;
   if(elem1->prev){
@@ -264,43 +315,169 @@
   }
 }
 
-static void REMOVE_ELEM(struct iseq_link_element *elem){
+static void REMOVE_ELEM(ISEQ_LINK_ELEMENT *elem){
   elem->prev->next = elem->next;
   if(elem->next){
     elem->next->prev = elem->prev;
   }
 }
 
+static ISEQ_LINK_ELEMENT *FIRST_ELEMENT(ISEQ_LINK_ANCHOR *anchor){
+  return anchor->anchor.next;
+}
+
+static ISEQ_LINK_ELEMENT *LAST_ELEMENT(ISEQ_LINK_ANCHOR *anchor){
+  return anchor->last;
+}
+
+static ISEQ_LINK_ELEMENT *POP_ELEMENT(ISEQ_LINK_ANCHOR *anchor){
+  ISEQ_LINK_ELEMENT *elem = anchor->last;
+  anchor->last = anchor->last->prev;
+  anchor->last->next = 0;
+  return elem;
+}
+
+static int LIST_SIZE(ISEQ_LINK_ANCHOR *anchor){
+  ISEQ_LINK_ELEMENT *elem = anchor->anchor.next;
+  int size = 0;
+  while(elem){
+    size += 1;
+    elem = elem->next;
+  }
+  return size;
+}
+
 /*
-#define APPEND_LINKED_LIST(list1, list2) \
-{ \
-  list1->last->next = list2->first.next; \
-  list1->last       = list2->last; \
+ * anc1: e1, e2, e3
+ * anc2: e4, e5
+ *#=>
+ * anc1: e1, e2, e3, e4, e5
+ * anc2: e4, e5
+ */
+static void APPEND_LIST(ISEQ_LINK_ANCHOR *anc1, ISEQ_LINK_ANCHOR *anc2){
+  if(anc2->anchor.next){
+    anc1->last->next = anc2->anchor.next;
+    anc1->last = anc2->last;
+  }
 }
- */
 
-static struct iseq_link_element *FIRST_ELEMENT(struct link_anchor *anchor){
-  return anchor->anchor.next;
+static ISEQ_LINK_ANCHOR *REVERSE_LIST(ISEQ_LINK_ANCHOR *anc){
+  ISEQ_LINK_ELEMENT *first, *last, *elem, *e;
+  first = &anc->anchor;
+  elem  = first->next;
+  last  = anc->last;
+
+  if(elem != 0){
+    anc->anchor.next = last;
+    anc->last        = elem;
+  }
+  else{
+    /* null list */
+    return anc;
+  }
+  while(elem){
+    e = elem->next;
+    elem->next = elem->prev;
+    elem->prev = e;
+    elem = e;
+  }
+
+  first->next = last;
+  last->prev = first;
+  anc->last->next = 0;
+  
+  return anc;
 }
 
-static void debug_list(struct link_anchor *anchor){
+
+static void debug_list(ISEQ_LINK_ANCHOR *anchor){
 #if CPDEBUG > 5
-  struct iseq_link_element* list = FIRST_ELEMENT(anchor);
+  ISEQ_LINK_ELEMENT* list = FIRST_ELEMENT(anchor);
   int i = 0;
 
   printf("----\n");
+  printf("anch: %p, frst: %p, last: %p\n", &anchor->anchor, anchor->anchor.next, anchor->last);
   while(list){
-    printf("%x, %x, %d\n", list->next, list->prev, FIX2INT(list->type));
+    printf("curr: %p, next: %p, prev: %p, type: %d\n", list, list->next, list->prev, FIX2INT(list->type));
     list = list->next;
   }
   printf("----\n");
 
-  iseq_disasm_list_dump(list);
+  iseq_disasm_list_dump(anchor->anchor.next);
 #endif
 }
 
+static LABEL_OBJECT *new_label_body(struct iseq_object *iseqobj, int line){
+  LABEL_OBJECT *labelobj = compile_data_alloc_label(iseqobj);
+  static int label_no = 0;
 
-void iseq_array_to_linkedlist_each(struct link_anchor *anchor, VALUE aval){
+  labelobj->link.type = ISEQ_ELEMENT_LABEL;
+  labelobj->link.next = 0;
+
+  labelobj->label_no = label_no++;
+  labelobj->sc_state = 0;
+  return labelobj;
+}
+
+static struct insn_object *new_insn_core(struct iseq_object *iseqobj, int line_no,
+                                         int insn_id, int argc, VALUE *argv){
+  INSN_OBJECT *insnobj = compile_data_alloc_insn(iseqobj);
+  
+  insnobj->link.type = ISEQ_ELEMENT_INSN;
+  insnobj->link.next = 0;
+  insnobj->insn_id   = insn_id;
+  insnobj->line_no   = line_no;
+  insnobj->operands  = argv;
+  insnobj->operand_size = argc;
+  insnobj->sc_state = 0;
+  return insn_optimize(insnobj);
+}
+
+static struct insn_object *new_insn_body(struct iseq_object *iseqobj, int line_no,
+                                         int insn_id, int argc, ...){
+  VALUE *operands = 0;
+  va_list argv;
+  if(argc > 0){
+    int i;
+    va_init_list(argv, argc);
+    operands = (VALUE *)compile_data_alloc(iseqobj, sizeof(VALUE) * argc);
+    for(i=0; i<argc; i++){
+      VALUE v = va_arg(argv, VALUE);
+      operands[i] = v;
+
+      /* TODO: need GC mark? */
+      //if(!SPECIAL_CONST_P(v)){
+      //  rb_ary_push(iseqobj->iseq_mark_ary, v);
+      //}
+    }
+    va_end(argv);
+  }
+  return new_insn_core(iseqobj, line_no, insn_id, argc, operands);
+}
+
+static VALUE new_child_iseq(VALUE self, struct iseq_object *iseqobj,
+                            NODE *node, VALUE name, VALUE parent, VALUE type){
+  VALUE args[5];
+  VALUE ret;
+  
+  debugs("[new_child_iseq]> ---------------------------------------\n");
+  args[0] = (VALUE)node;
+  args[1] = name;
+  args[2] = iseq_filename(self);
+  args[3] = parent;
+  args[4] = type;
+
+  ret = rb_class_new_instance(5, args, cYarvISeq);
+  
+  debugs("[new_child_iseq]< ---------------------------------------\n");
+  rb_ary_push(iseqobj->compile_data->mark_ary, ret);
+  return ret;
+}
+
+
+#if 0
+
+void iseq_array_to_linkedlist_each(ISEQ_LINK_ANCHOR *anchor, VALUE aval){
   struct RArray *ary = RARRAY(aval);
   int i, len = ary->len;
 
@@ -314,8 +491,8 @@
     }
     else if(BUILTIN_TYPE(obj) == T_DATA){
       /* maybe Insn or Label */
-      struct iseq_link_element *le =
-        (struct iseq_link_element *)DATA_PTR(obj);
+      ISEQ_LINK_ELEMENT *le =
+        (ISEQ_LINK_ELEMENT *)DATA_PTR(obj);
       
       if(anchor->last->type == ISEQ_ELEMENT_INSN){
         struct insn_object *iobj;
@@ -332,58 +509,58 @@
   }
 }
 
-VALUE iseq_disasm_list_dump(struct iseq_link_element *link);
+#endif
 
-static VALUE iseq_setup(VALUE self, VALUE seq_ary, struct iseq_object *iseqobj){
-  struct link_anchor anchor;
-  volatile VALUE seq_ary_save = seq_ary;
+static int iseq_setup(VALUE self, ISEQ_LINK_ANCHOR *anchor){
+  struct iseq_object *iseqobj;
+  GetISeqVal(self, iseqobj);
 
-  anchor.anchor.next = 0;
-  anchor.last        = &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");
+//  iseq_array_to_linkedlist_each(anchor, seq_ary);
   
   GC_CHECK();
-  if(CPDEBUG > 5)iseq_disasm_list_dump(FIRST_ELEMENT(&anchor));
+  if(CPDEBUG > 5)iseq_disasm_list_dump(FIRST_ELEMENT(anchor));
   GC_CHECK();
 
   debugs("[compile step 3.1 (iseq_optimize)]\n");
-  iseq_optimize(self, &anchor, seq_ary);
+  iseq_optimize(iseqobj, anchor);
 
-  if(CPDEBUG > 5)iseq_disasm_list_dump(FIRST_ELEMENT(&anchor));
+  if(CPDEBUG > 5)iseq_disasm_list_dump(FIRST_ELEMENT(anchor));
   GC_CHECK();
   
   debugs("[compile step 3.2 (iseq_insns_unification)]\n");
-  iseq_insns_unification(self, &anchor, seq_ary);
-  if(CPDEBUG > 5)iseq_disasm_list_dump(FIRST_ELEMENT(&anchor));
+  iseq_insns_unification(iseqobj, anchor);
+  if(CPDEBUG > 5)iseq_disasm_list_dump(FIRST_ELEMENT(anchor));
   GC_CHECK();
   
   debugs("[compile step 3.3 (set_sequence_stackcaching)]\n");
-  set_sequence_stackcaching(&anchor, seq_ary);
-  if(CPDEBUG > 5)iseq_disasm_list_dump(FIRST_ELEMENT(&anchor));
+  set_sequence_stackcaching(iseqobj, anchor);
+  if(CPDEBUG > 5)iseq_disasm_list_dump(FIRST_ELEMENT(anchor));
   GC_CHECK();
   
   debugs("[compile step 4 (set_sequence)]\n");
-  set_sequence(self, &anchor);
-  if(CPDEBUG > 5)iseq_disasm_list_dump(FIRST_ELEMENT(&anchor));
+  set_sequence(iseqobj, anchor);
+  if(CPDEBUG > 5)iseq_disasm_list_dump(FIRST_ELEMENT(anchor));
   GC_CHECK();
 
   GC_CHECK();
   debugs("[compile step 4.1 (set_exception_table)]\n");
-  set_exception_table(self);
+  set_exception_table(iseqobj);
 
   debugs("[compile step 5] (set_optargs_table)\n");
-  set_optargs_table(self);
+  set_optargs_table(iseqobj);
   
   debugs("[compile step 6] (iseq_translate_direct_threaded_code)\n");
-  iseq_translate_direct_threaded_code(self);
+  iseq_translate_direct_threaded_code(iseqobj);
   GC_CHECK();
   
-  if(CPDEBUG > 5)iseq_disasm(self);
+  if(CPDEBUG > 5){
+    VALUE str = iseq_disasm(self);
+    printf("%s\n", StringValueCStr(str));
+  }
   debugs("[compile step: finish]\n");
   
-  return self;
+  return 0;
 }
 
 VALUE iseq_assemble_setup(VALUE self, VALUE args, VALUE locals, VALUE insn_ary){
@@ -413,14 +590,13 @@
   }
   
   iseqobj->catch_table_ary = rb_ary_new();
-  return iseq_setup(self, insn_ary, iseqobj);
+  // return iseq_setup(self, insn_ary, iseqobj);
+  return Qnil;
 }
 
 
-VALUE set_exception_tbl(VALUE self){
-  struct iseq_object *iseqobj;
+int set_exception_tbl(struct iseq_object *iseqobj){
   static ID id_dollar_bang;
-  GetISeqVal(self, iseqobj);
 
   if(!id_dollar_bang){
     id_dollar_bang = rb_intern("$!");
@@ -428,16 +604,14 @@
   iseqobj->local_tbl = (ID*)ALLOC_N(ID*, 1);
   iseqobj->local_size = 1;
   iseqobj->local_tbl[0] = id_dollar_bang;
-  return self;
+  return COMPILE_OK;
 }
 
 
-NODE* set_block_local_tbl(VALUE self, NODE *node, VALUE seq_ary){
-  struct iseq_object *iseqobj;
+NODE* set_block_local_tbl(VALUE self, struct iseq_object *iseqobj, NODE *node, ISEQ_LINK_ANCHOR *anchor){
   VALUE vars = rb_ary_new();
   VALUE tmp;
   NODE *nargs, *ntmp, *nelem;
-  GetISeqVal(self, iseqobj);
   
   /* argument check */
   if(iseqobj->type != ISEQ_TYPE_BLOCK){
@@ -461,13 +635,14 @@
             char buff[0x20];
             ID   id;
             int  idx = iseqobj->argc - RARRAY(vars)->len;
+            DECL_ANCHOR(anc);
+            
             snprintf(buff, 0x20, "__tp%d__", idx);
             id = rb_intern(buff);
             /* idx-th param, current level*/
-            ADD_INSN2(seq_ary, nd_line(node), getdynamic, I2F(idx), 0); 
-            ADD_SEQ(seq_ary,
-                    rb_ary_pop(COMPILE("set_block_local_tbl#masgn/other",
-                                       nelem)));
+            ADD_INSN2(anchor, nd_line(node), getdynamic, I2F(idx), 0);
+            COMPILE(&anc, "set_block_local_tbl#masgn/other", nelem);
+            ADD_LINKED_LIST(anchor, LAST_ELEMENT(&anc));
             rb_ary_push(vars, I2F(id));
           }
           else{
@@ -488,12 +663,15 @@
     default:{
       /* initial values */
       static ID tid;
+      DECL_ANCHOR(anc);
+      
       if(tid == 0){
         tid = rb_intern("__tp__");
       }
       iseqobj->argc = 1;
-      ADD_INSN2(seq_ary, nd_line(node), getdynamic, I2F(1), 0); /* first param, current level*/
-      ADD_SEQ  (seq_ary, rb_ary_pop(COMPILE("set_block_local_tbl#lasgn/dasgn", nargs)));
+      ADD_INSN2(anchor, nd_line(node), getdynamic, I2F(1), 0); /* first param, current level*/
+      COMPILE(&anc, "set_block_local_tbl#lasgn/dasgn", nargs);
+      ADD_LINKED_LIST(anchor, POP_ELEMENT(&anc));
       rb_ary_push(vars, I2F(tid));
       debugi("set_block_local_tbl#lasgin/dasgn", (nargs->nd_vid));
       break;
@@ -584,13 +762,9 @@
 /**
 
  */
-VALUE set_arguments(VALUE self, NODE *node){
-  struct iseq_object *iseqobj;
-  VALUE optargs = NEW_SEQ();
-  int i;
+int set_arguments(VALUE self, struct iseq_object *iseqobj, ISEQ_LINK_ANCHOR *optargs, NODE *node){
+  int i, j;
   
-  GetISeqVal(self, iseqobj);
-  
   if(node){
     /* normal method */
     iseqobj->argc     = node->nd_cnt;
@@ -603,27 +777,30 @@
     if(node->nd_opt){
       int oargs = 0;
       NODE* optarg = node->nd_opt;
-      VALUE label;
+      LABEL_OBJECT* label;
       VALUE labels = rb_ary_new();
       i = 0;
       while(optarg){
         label = NEW_LABEL(nd_line(node));
-        rb_ary_push(labels,  label);
-        rb_ary_push(optargs, label);
-        rb_ary_push(optargs, COMPILE_POPED("optarg", optarg->nd_head));
+        rb_ary_push(labels, (VALUE) label | 1);
+        ADD_LABEL(optargs, label);
+        COMPILE_POPED(optargs, "optarg", optarg->nd_head);
 
         optarg = optarg->nd_next;
         i += 1;
       }
       /* last label */
       label = NEW_LABEL(nd_line(node));
-      rb_ary_push(labels,  label);
-      rb_ary_push(optargs, label);
+      rb_ary_push(labels,  (VALUE) label | 1);
+      ADD_LABEL(optargs, label);
       i+=1;
       
       iseqobj->arg_opts = i;
       iseqobj->arg_opt_tbl = ALLOC_N(VALUE, i);
       MEMCPY(iseqobj->arg_opt_tbl, RARRAY(labels)->ptr, VALUE, i);
+      for(j=0; j<i; j++){
+        iseqobj->arg_opt_tbl[j] &= ~1;
+      }
     }
     else{
       iseqobj->arg_opts = 0;
@@ -643,18 +820,16 @@
     iseqobj->arg_simple = 1;
   }
 
-  return optargs;
+  return COMPILE_OK;
 }
 
 
 /**
 
  */
-VALUE set_localtbl(VALUE self, ID* tbl){
-  struct iseq_object *iseqobj;
+int set_localtbl(struct iseq_object *iseqobj, ID* tbl){
   int size;
   
-  GetISeqVal(self, iseqobj);
   if(tbl){
     size = *tbl - 2 /* $~, $_ */ + 1 /* svar location */;
   }
@@ -666,7 +841,7 @@
     MEMCPY(iseqobj->local_tbl + 1, tbl + 3, ID*, size - 1);
   }
   iseqobj->local_size = size;
-  return self;
+  return COMPILE_OK;
 }
 
 static int next_instruction_position(VALUE self, struct RArray *ary, int pos){
@@ -682,16 +857,14 @@
 /**
   ruby insn object array -> raw instruction sequence
  */
-VALUE set_sequence(VALUE self, struct link_anchor *anchor){
+static int set_sequence(struct iseq_object *iseqobj, ISEQ_LINK_ANCHOR *anchor){
   struct label_object *lobj;
   struct insn_object  *iobj;
   struct insn_info_struct *insn_info_tbl;
-  struct iseq_object *iseqobj;
-  struct iseq_link_element *list;
+  ISEQ_LINK_ELEMENT *list;
   VALUE *generated_iseq;
   
   int k, pos, stack_max = 0;
-  GetISeqVal(self, iseqobj);
 
   GC_CHECK();
 
@@ -740,9 +913,10 @@
     case ISEQ_ELEMENT_INSN:{
       int j, len, insn;
       char *types;
-      VALUE *operands = 0;
+      VALUE *operands;
       
       iobj = (struct insn_object*)list;
+      operands = iobj->operands;
       insn = iobj->insn_id;
       generated_iseq[pos] = insn;
       types = insn_op_types(insn);
@@ -750,30 +924,18 @@
       stack_max += insn_ret_num(insn);
 
       /* operand check */
-      if(iobj->operands){
-        operands = RARRAY(iobj->operands)->ptr;
-        if(RARRAY(iobj->operands)->len != len -1){
-
-          iseq_disasm_list_dump(list);
-          dp(iobj->operands);
-          rb_bug("operand size miss! (%d for %d)", RARRAY(iobj->operands)->len, len - 1);
-          return 0;
-        }
+      if(iobj->operand_size != len - 1){
+        iseq_disasm_list_dump(list);
+        rb_bug("operand size miss! (%d for %d)", iobj->operand_size, len - 1);
+        return 0;
       }
-      else{
-        if(len != 1){
-          iseq_disasm_list_dump(list);
-          rb_bug("operand size miss!");
-          return 0;
-        }
-      }
 
       for(j=0; types[j]; j++){
         char type = types[j];
         // printf("--> [%c - (%d-%d)]\n", type, k, j);
         switch(type){
         case 'L':{          /* label(destination position) */
-          GetLabelVal(operands[j], lobj);
+          lobj = (LABEL_OBJECT*)operands[j];
           if(lobj->set != Qtrue){
             rb_bug("unknown label");
           }
@@ -791,7 +953,8 @@
           for(i=0; i<RARRAY(lits)->len; i++){
             int offset;
             VALUE pair = RARRAY(lits)->ptr[i];
-            GetLabelVal(RARRAY(pair)->ptr[1], lobj);
+            lobj = (LABEL_OBJECT *)(RARRAY(pair)->ptr[1] & ~1);
+            
             if(lobj->set != Qtrue){
               rb_bug("unknown label");
             }
@@ -810,7 +973,9 @@
             VALUE v = operands[j];
             generated_iseq[pos+1+j] = v;
             /* to mark ruby object */
-            rb_ary_push(iseqobj->iseq_mark_ary, v);
+            if(!SPECIAL_CONST_P(v)){
+              rb_ary_push(iseqobj->iseq_mark_ary, v);
+            }
           }
           break;
         case 'M':          /* inline cache */
@@ -847,32 +1012,25 @@
     list = list->next;
   }
   {
-    // set self
-    volatile struct iseq_object *iseqobj;
-    GetISeqVal(self, iseqobj);
     iseqobj->iseq = (void*)generated_iseq;
     iseqobj->size  = pos;
     iseqobj->insn_info_tbl = insn_info_tbl;
     iseqobj->insn_info_size= k;
     iseqobj->stack_max = stack_max;
   }
-  return self;
+  return COMPILE_OK;
 }
 
 static int label_get_position(VALUE self){
-  struct label_object *lobj;
-  
-  GetLabelVal(self, lobj);
+  LABEL_OBJECT *lobj = (LABEL_OBJECT *) self;
   return lobj->position;
 }
 
-VALUE set_exception_table(VALUE self){
-  struct iseq_object *iseqobj;
+int set_exception_table(struct iseq_object *iseqobj){
   VALUE *tptr, *ptr;
   int tlen, i;
   struct catch_table_entry *entry;
 
-  GetISeqVal(self, iseqobj);
   tlen = RARRAY(iseqobj->catch_table_ary)->len;
   tptr = RARRAY(iseqobj->catch_table_ary)->ptr;
 
@@ -883,8 +1041,8 @@
     ptr   = RARRAY(tptr[i])->ptr;
     entry = &iseqobj->catch_table[i];
     entry->type  = ptr[0];
-    entry->start = label_get_position(ptr[1]);
-    entry->end   = label_get_position(ptr[2]);
+    entry->start = label_get_position(ptr[1] & ~1);
+    entry->end   = label_get_position(ptr[2] & ~1);
     entry->iseq  = ptr[3];
     
     if(entry->iseq != 0){
@@ -893,7 +1051,7 @@
     
     entry->sp    = FIX2INT(ptr[4]);
     if(ptr[5]){
-      entry->cont  = label_get_position(ptr[5]);
+      entry->cont  = label_get_position(ptr[5] & ~1);
     }
     else{
       entry->cont  = 0;
@@ -901,7 +1059,7 @@
   }
   //
   iseqobj->catch_table_ary = 0; /* free */
-  return self;
+  return COMPILE_OK;
 }
 
 /*
@@ -909,11 +1067,8 @@
  *   def foo(a, b=expr1, c=expr2)
  *   => 
  */
-VALUE set_optargs_table(VALUE self){
-  struct iseq_object *iseqobj;
+int set_optargs_table(struct iseq_object *iseqobj){
   int i;
-  
-  GetISeqVal(self, iseqobj);
 
   if(iseqobj->arg_opts != 0){
     for(i=0; i< iseqobj->arg_opts; i++){
@@ -922,16 +1077,14 @@
         label_get_position((VALUE)iseqobj->arg_opt_tbl[i]);
     }
   }
-
-  return self;
+  return COMPILE_OK;
 }
 
-static struct iseq_link_element *
+static ISEQ_LINK_ELEMENT *
 get_destination_insn(struct insn_object *iobj){
-  VALUE label = OPERAND_OF_RAW(iobj, 0);
-  struct label_object *lobj;
-  struct iseq_link_element *list;
-  GetLabelVal(label, lobj);
+  LABEL_OBJECT *lobj = (LABEL_OBJECT *)OPERAND_AT(iobj, 0);
+  ISEQ_LINK_ELEMENT *list;
+  
   list = lobj->link.next;
   while(list){
     if(list->type == ISEQ_ELEMENT_INSN){
@@ -942,9 +1095,10 @@
   return list;
 }
 
-static struct iseq_link_element *
+static ISEQ_LINK_ELEMENT *
 get_next_insn(struct insn_object *iobj){
-  struct iseq_link_element *list = iobj->link.next;
+  ISEQ_LINK_ELEMENT *list = iobj->link.next;
+  
   while(list){
     if(list->type == ISEQ_ELEMENT_INSN){
       return list;
@@ -954,9 +1108,10 @@
   return 0;
 }
 
-static struct iseq_link_element *
+static ISEQ_LINK_ELEMENT *
 get_prev_insn(struct insn_object *iobj){
-  struct iseq_link_element *list = iobj->link.prev;
+  ISEQ_LINK_ELEMENT *list = iobj->link.prev;
+  
   while(list){
     if(list->type == ISEQ_ELEMENT_INSN){
       return list;
@@ -966,8 +1121,8 @@
   return 0;
 }
 
-static void iseq_optimize(VALUE self, struct link_anchor *anchor, VALUE ary){
-  struct iseq_link_element *list;
+static int iseq_optimize(struct iseq_object *iseqobj, ISEQ_LINK_ANCHOR *anchor){
+  ISEQ_LINK_ELEMENT *list;
   /*
    *  useless jump elimination:
    *     jump LABEL1
@@ -982,25 +1137,24 @@
   list = FIRST_ELEMENT(anchor);
   while(list){
     if(list->type == ISEQ_ELEMENT_INSN){
-      struct insn_object *niobj, *piobj, *iobj = (struct insn_object *)list;
+      struct insn_object *niobj, *diobj, *piobj, *iobj = (struct insn_object *)list;
       if(iobj->insn_id == BIN(jump)){
-        niobj = (struct insn_object*)get_destination_insn(iobj);
+        diobj = (struct insn_object*)get_destination_insn(iobj);
+        niobj = (struct insn_object*)get_next_insn(iobj);
         
-        if(niobj->insn_id == BIN(jump)){
-          OPERAND_OF_RAW(iobj, 0) = OPERAND_OF_RAW(niobj, 0);
+        if(diobj == niobj){
+          REMOVE_ELEM(&iobj->link);
+        }
+        else if(diobj->insn_id == BIN(jump)){
+          OPERAND_AT(iobj, 0) = OPERAND_AT(diobj, 0);
           continue;
         }
-        else if(niobj->insn_id == BIN(end)){
-          VALUE endinsn = new_insn(BIN(end), iobj->line_no, niobj->operands);
-          struct insn_object *eiobj;
-          GetInsnVal(endinsn, eiobj);
-
-          /* protect for GC */
-          rb_ary_push(ary, endinsn);
-
+        else if(diobj->insn_id == BIN(end)){
+          struct insn_object *eiobj = new_insn_core(iseqobj, iobj->line_no, BIN(end),
+                                                    diobj->operand_size, diobj->operands);
           /* replace */
-          REPLACE_ELEM((struct iseq_link_element *)iobj,
-                       (struct iseq_link_element *)eiobj);
+          REPLACE_ELEM((ISEQ_LINK_ELEMENT *)iobj,
+                       (ISEQ_LINK_ELEMENT *)eiobj);
         }
         /*
          *   if   L1
@@ -1018,9 +1172,9 @@
         else if ((piobj = (struct insn_object*)get_prev_insn(iobj)) != 0 &&
                  (piobj->insn_id == BIN(if) ||
                   piobj->insn_id == BIN(unless))){
-          if(get_next_insn(iobj) == get_destination_insn(piobj)){
+          if(niobj == (INSN_OBJECT*)get_destination_insn(piobj)){
             piobj->insn_id = (piobj->insn_id == BIN(if)) ? BIN(unless) : BIN(if);
-            OPERAND_OF_RAW(piobj, 0) = OPERAND_OF_RAW(iobj, 0);
+            OPERAND_AT(piobj, 0) = OPERAND_AT(iobj, 0);
             REMOVE_ELEM(&iobj->link);
           }
         }
@@ -1028,20 +1182,37 @@
     }
     list = list->next;
   }
+  return COMPILE_OK;
 }
 
-static VALUE new_unified_insn(int id, int size, struct iseq_link_element *seq_list){
-  VALUE opes = rb_ary_new();
-  struct insn_object *iobj;
-  struct iseq_link_element *list = seq_list;
-  int i;
+static INSN_OBJECT* new_unified_insn(struct iseq_object *iseqobj,
+                                     int insn_id, int size, ISEQ_LINK_ELEMENT *seq_list){
+  INSN_OBJECT *iobj;
+  ISEQ_LINK_ELEMENT *list = seq_list;
+  int i, argc = 0;
+  VALUE *operands = 0, *ptr = 0;
+
+  /* count argc */
+  for(i=0; i<size; i++){
+    iobj = (struct insn_object*)list;
+    argc += iobj->operand_size;
+    list = list->next;
+  }
+
+  if(argc > 0){
+    ptr = operands = (VALUE *)compile_data_alloc(iseqobj, sizeof(VALUE) * argc);
+  }
   
+  /* copy operands */
+  list = seq_list;
   for(i=0; i<size; i++){
     iobj = (struct insn_object*)list;
-    rb_ary_concat(opes, iobj->operands);
+    MEMCPY(ptr, iobj->operands, VALUE, iobj->operand_size);
+    ptr += iobj->operand_size;
     list = list->next;
   }
-  return new_insn(id, iobj->line_no, opes);
+  
+  return new_insn_core(iseqobj, iobj->line_no, insn_id, argc, operands);
 }
 
 
@@ -1050,9 +1221,9 @@
  * label address resolving.
  * It's future work (if compile time was bottle neck).
  */
-static void iseq_insns_unification(VALUE self, struct link_anchor *anchor, VALUE ary){
+static int iseq_insns_unification(struct iseq_object *iseqobj, ISEQ_LINK_ANCHOR *anchor){
 #ifdef OPT_INSNS_UNIFICATION
-  struct iseq_link_element *list;
+  ISEQ_LINK_ELEMENT *list;
   struct insn_object *iobj, *niobj;
   int id, j, k, insn;
   
@@ -1065,7 +1236,7 @@
         int **entry = unified_insns_data[id];
         for(j=1; j<(int)entry[0]; j++){
           int *unified = entry[j];
-          struct iseq_link_element *li = list->next;
+          ISEQ_LINK_ELEMENT *li = list->next;
           for(k=2; k<unified[1]; k++){
             if(li->type != ISEQ_ELEMENT_INSN ||
                ((struct insn_object *)li)->insn_id != unified[k]){
@@ -1074,18 +1245,16 @@
             li = li->next;
           }
           /* matched */
-          insn = new_unified_insn(unified[0], unified[1]-1, list);
-          rb_ary_push(ary, insn);
+          niobj = new_unified_insn(iseqobj, unified[0], unified[1]-1, list);
           
           /* insert to list */
-          GetInsnVal(insn, niobj);
-          niobj->link.prev = (struct iseq_link_element *)iobj->link.prev;
+          niobj->link.prev = (ISEQ_LINK_ELEMENT *)iobj->link.prev;
           niobj->link.next = li;
           if(li){
-            li->prev = (struct iseq_link_element *)niobj;
+            li->prev = (ISEQ_LINK_ELEMENT *)niobj;
           }
-          list->prev->next = (struct iseq_link_element *)niobj;
-          list = (struct iseq_link_element *)niobj;
+          list->prev->next = (ISEQ_LINK_ELEMENT *)niobj;
+          list = (ISEQ_LINK_ELEMENT *)niobj;
         }
       }
     }
@@ -1093,6 +1262,7 @@
     list = list->next;
   }
 #endif
+  return COMPILE_OK;
 }
 
 #ifdef OPT_STACK_CACHING
@@ -1113,12 +1283,11 @@
   if(insn_id == BIN(jump) ||
      insn_id == BIN(if)   ||
      insn_id == BIN(unless)){
-    VALUE label = RARRAY(iobj->operands)->ptr[0];
-    struct label_object *lobj;
-    GetLabelVal(label, lobj);
+    struct label_object *lobj = (LABEL_OBJECT*) OPERAND_AT(iobj, 0);
+
     if(lobj->sc_state != 0){
       if(lobj->sc_state != nstate){
-        iseq_disasm_list_dump((struct iseq_link_element*) iobj);
+        iseq_disasm_list_dump((ISEQ_LINK_ELEMENT*) iobj);
         printf("%d, %d: ", lobj->sc_state, nstate);
         rb_bug("insn_set_sc_state error\n");
         return 0;
@@ -1154,9 +1323,9 @@
 
 #endif
 
-static void set_sequence_stackcaching(struct link_anchor *anchor, VALUE seq_ary){
+static int set_sequence_stackcaching(struct iseq_object *iseqobj, ISEQ_LINK_ANCHOR *anchor){
 #ifdef OPT_STACK_CACHING
-  struct iseq_link_element *list;
+  ISEQ_LINK_ELEMENT *list;
   int i, state, insn_id;
   unsigned long size;
 
@@ -1180,16 +1349,11 @@
       case BIN(if):
       case BIN(unless):{
         if(state == SCS_BA){
-          VALUE swap_insn = new_insn(BIN(swap), 0, Qfalse);
-          struct insn_object *siobj;
-          GetInsnVal(swap_insn, siobj);
-          
-          /* protect for GC */
-          rb_ary_push(seq_ary, swap_insn);
-          
+          struct insn_object *siobj = new_insn_body(iseqobj, 0, BIN(swap), 0);
+                    
           /* insert this insn */
-          INSERT_ELEM_PREV(list, (struct iseq_link_element *)siobj);
-          list = (struct iseq_link_element *)siobj;
+          INSERT_ELEM_PREV(list, (ISEQ_LINK_ELEMENT *)siobj);
+          list = (ISEQ_LINK_ELEMENT *)siobj;
           goto redo_point;
         }
         break;
@@ -1197,16 +1361,11 @@
       case BIN(nop):{
         /* exception merge point */
         if(state != SCS_AX){
-          VALUE reput_insn = new_insn(BIN(reput), 0, Qfalse);
-          struct insn_object *rpobj;
-          GetInsnVal(reput_insn, rpobj);
-
-          /* protect for GC */
-          rb_ary_push(seq_ary, reput_insn);
+          struct insn_object *rpobj = new_insn_body(iseqobj, 0, BIN(reput), 0);
           
           /* replace this insn */
-          REPLACE_ELEM(list, (struct iseq_link_element *)rpobj);
-          list = (struct iseq_link_element *)rpobj;
+          REPLACE_ELEM(list, (ISEQ_LINK_ELEMENT *)rpobj);
+          list = (ISEQ_LINK_ELEMENT *)rpobj;
           goto redo_point;
         }
         break;
@@ -1227,57 +1386,36 @@
     list = list->next;
   }
 #endif
+  return COMPILE_OK;
 }
 
-static VALUE new_label(int line){
-  static int label_no = 0;
-  VALUE obj;
-  VALUE args[16];
 
-  args[0] = I2F(label_no++);
-  obj = rb_class_new_instance(1, args, cYarvLabel);
-  return obj;
-}
 
-
-static VALUE new_insn(int insn, int line_no, VALUE operands){
-  VALUE obj;
-  VALUE args[3];
-  args[0] = insn;
-  args[1] = line_no;
-  args[2] = operands;
-  
-  obj = rb_class_new_instance(3, args, cYarvInsn);
-  obj = insn_optimize(obj);
-  return obj;
-}
-
-VALUE compile_dstr(VALUE self, NODE *node){
+int compile_dstr(VALUE self, struct iseq_object *iseqobj, ISEQ_LINK_ANCHOR *ret, NODE *node){
   NODE *list = node->nd_next;
   VALUE lit  = node->nd_lit;
-  VALUE ret;
   VALUE tmp;
   int cnt = 0;
 
   debugp_param("nd_lit", lit);
   if(RSTRING(lit)->len == 0){
-    ret = NEW_SEQ();
     cnt = 0;
   }
   else{
-    ret = NEW_INSN_SEQ1(nd_line(node), putobject, node->nd_lit);
+    ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
     cnt = 1;
   }
 
   while(list){
-    ADD_SEQ(ret, COMPILE("each string", list->nd_head));
+    COMPILE(ret, "each string", list->nd_head);
     cnt++;
     list = list->nd_next;
   }
   if(cnt > 1){
     ADD_INSN1(ret, nd_line(node), concatstrings, I2F(cnt));
   }
-  return ret;
+  
+  return COMPILE_OK;
 }
 
 static struct iseq_object *get_root_iseq_object(struct iseq_object *iop){
@@ -1300,65 +1438,70 @@
   return iseqobj->local_size;
 }
 
-static VALUE compile_branch_condition(VALUE self, NODE *cond,
-                                     VALUE then_label, VALUE else_label){
-  VALUE ret = NEW_SEQ();
+static int compile_branch_condition(VALUE self, struct iseq_object *iseqobj,
+                                    ISEQ_LINK_ANCHOR *ret, NODE *cond,
+                                    LABEL_OBJECT *then_label, LABEL_OBJECT *else_label){
   
   switch(nd_type(cond)){
   case NODE_NOT:
-    ret = compile_branch_condition(self, cond->nd_body, else_label, then_label);
+    compile_branch_condition(self, iseqobj, ret, cond->nd_body, else_label, then_label);
     break;
 
   case NODE_AND:{
-    VALUE label = NEW_LABEL(nd_line(cond));
-    ADD_SEQ  (ret, compile_branch_condition(self, cond->nd_1st, label, else_label));
+    LABEL_OBJECT *label = NEW_LABEL(nd_line(cond));
+    compile_branch_condition(self, iseqobj, ret, cond->nd_1st, label, else_label);
     ADD_LABEL(ret, label);
-    ADD_SEQ  (ret, compile_branch_condition(self, cond->nd_2nd, then_label, else_label));
+    compile_branch_condition(self, iseqobj, ret, cond->nd_2nd, then_label, else_label);
     break;
   }
   case NODE_OR:{
-    VALUE label = NEW_LABEL(nd_line(cond));
-    ADD_SEQ  (ret, compile_branch_condition(self, cond->nd_1st, then_label, label));
+    LABEL_OBJECT *label = NEW_LABEL(nd_line(cond));
+    compile_branch_condition(self, iseqobj, ret, cond->nd_1st, then_label, label);
     ADD_LABEL(ret, label);
-    ADD_SEQ  (ret, compile_branch_condition(self, cond->nd_2nd, then_label, else_label));
+    compile_branch_condition(self, iseqobj, ret, cond->nd_2nd, then_label, else_label);
     break;
   }
   default:
-    ADD_SEQ  (ret, COMPILE("branch condition", cond));
+    COMPILE(ret, "branch condition", cond);
     ADD_INSNL(ret, nd_line(cond), unless, else_label);
     ADD_INSNL(ret, nd_line(cond), jump,   then_label);
     break;
   }
-  return ret;
+  return COMPILE_OK;
 }
 
-static VALUE compile_array(VALUE self, NODE *node_root, VALUE opt_p){
+static int compile_array(VALUE self, struct iseq_object *iseqobj,
+                         ISEQ_LINK_ANCHOR *ret, NODE *node_root, VALUE opt_p){
   NODE *node = node_root;
-  VALUE obj, tmp, ret;
+  VALUE obj, tmp;
   int i, len = node->nd_alen, line = nd_line(node);
+  DECL_ANCHOR(anchor);
   
-  ret = NEW_SEQ();
   while(node){
     if(opt_p && nd_type(node->nd_head) != NODE_LIT){
       opt_p = Qfalse;
     }
-    ADD_SEQ(ret, COMPILE("element", node->nd_head));
+    COMPILE(&anchor, "element", node->nd_head);
     node = node->nd_next;
   }
 
   if(opt_p == Qtrue){
-    ret = rb_ary_new();
+    VALUE ary = rb_ary_new();
     node = node_root;
     while(node){
-      rb_ary_push(ret, node->nd_head->nd_lit);
+      rb_ary_push(ary, node->nd_head->nd_lit);
       node = node->nd_next;
     }
-    ret = NEW_INSN_SEQ1(nd_line(node_root), duparray, ret);
+
+    rb_ary_push(iseqobj->compile_data->mark_ary, ary);
+    ADD_INSN1(ret, nd_line(node_root), duparray, ary);
   }
   else{
-    ADD_INSN1(ret, line, newarray, I2F(len));
+    ADD_INSN1(&anchor, line, newarray, I2F(len));
+    APPEND_LIST(ret, &anchor);
   }
-  return ret;
+  
+  return COMPILE_OK;
 }
 
 static VALUE case_when_optimizable_literal(NODE *node){
@@ -1375,44 +1518,43 @@
   return Qfalse;
 }
 
-static VALUE make_masgn_lhs(VALUE self, NODE *node){
-  VALUE ret;
+static int make_masgn_lhs(VALUE self, struct iseq_object *iseqobj,
+                          ISEQ_LINK_ANCHOR *ret, NODE *node){
   
   switch(nd_type(node)){
   case NODE_ATTRASGN:{
-    VALUE lhs = COMPILE("masgn lhs (NODE_ATTRASGN)", node);
     struct insn_object *iobj;
-    VALUE sendinsn = rb_ary_pop(lhs);
+    VALUE sendinsn;// = rb_ary_pop(lhs);
     VALUE dupidx;
 
-    GetInsnVal(sendinsn, iobj);
-    dupidx = RARRAY(iobj->operands)->ptr[1]; /* send sym, num, ... */
+    COMPILE(ret, "masgn lhs (NODE_ATTRASGN)", node);
+    iobj = (INSN_OBJECT*)ret->last;
+    ret->last = ret->last->prev;
+    
+    dupidx = iobj->operands[1]; // RARRAY(iobj->operands)->ptr[1]; /* send sym, num, ... */
     dupidx = I2F(FIX2INT(dupidx) + 1);
-    RARRAY(iobj->operands)->ptr[1] = dupidx;
+    iobj->operands[1] = dupidx;
 
-    ADD_INSN1(lhs, nd_line(node), topn, dupidx);
-    ADD_SEQ  (lhs, sendinsn);
-    ADD_INSN (lhs, nd_line(node), pop); /* result */
-    ADD_INSN (lhs, nd_line(node), pop); /* rhs    */
-
-    ret = lhs;
+    ADD_INSN1(ret, nd_line(node), topn, dupidx);
+    ADD_LINKED_LIST(ret, (ISEQ_LINK_ELEMENT*) iobj);
+    ADD_INSN (ret, nd_line(node), pop); /* result */
+    ADD_INSN (ret, nd_line(node), pop); /* rhs    */
     break;
   }
 
   default:{
-    VALUE lhs  = COMPILE_POPED("masgn lhs", node);
-    VALUE asgn = rb_ary_pop(lhs);
-
-    ret = asgn;
+    DECL_ANCHOR(anchor);
+    
+    COMPILE_POPED(&anchor, "masgn lhs", node);
+    ADD_LINKED_LIST(ret, LAST_ELEMENT(&anchor));
   }
   }
-  return ret;
+  
+  return COMPILE_OK;
 }
 
-
-
-
-static int defined_expr(VALUE self, NODE *node, VALUE ret, VALUE lfinish, VALUE needstr){
+static int defined_expr(VALUE self, struct iseq_object *iseqobj,
+                        ISEQ_LINK_ANCHOR *ret, NODE *node, LABEL_OBJECT *lfinish, VALUE needstr){
   char *estr = 0;
   
   switch(nd_type(node)){
@@ -1455,27 +1597,27 @@
     return 1;
   case NODE_COLON2:
     if(rb_is_const_id(node->nd_mid)){
-      VALUE lcont = NEW_LABEL(nd_line(node));
-      defined_expr(self, node->nd_head, ret, lfinish, Qfalse);
+      LABEL_OBJECT *lcont = NEW_LABEL(nd_line(node));
+      defined_expr(self, iseqobj, ret, node->nd_head, lfinish, Qfalse);
       
       ADD_INSNL(ret, nd_line(node), if, lcont);
       ADD_INSN (ret, nd_line(node), putnil);
       ADD_INSNL(ret, nd_line(node), jump, lfinish);
       
       ADD_LABEL(ret, lcont);
-      ADD_SEQ(ret, COMPILE("defined/colon2#nd_head", node->nd_head));
+      COMPILE(ret, "defined/colon2#nd_head", node->nd_head);
       ADD_INSN3(ret, nd_line(node), defined, I2F(DEFINED_CONST), ID2SYM(node->nd_mid), needstr);
     }
     else{
-      VALUE lcont = NEW_LABEL(nd_line(node));
-      defined_expr(self, node->nd_head, ret, lfinish, Qfalse);
+      LABEL_OBJECT *lcont = NEW_LABEL(nd_line(node));
+      defined_expr(self, iseqobj, ret, node->nd_head, lfinish, Qfalse);
       
       ADD_INSNL(ret, nd_line(node), if, lcont);
       ADD_INSN (ret, nd_line(node), putnil);
       ADD_INSNL(ret, nd_line(node), jump, lfinish);
       
       ADD_LABEL(ret, lcont);
-      ADD_SEQ(ret, COMPILE("defined/colon2#nd_head", node->nd_head));
+      COMPILE(ret, "defined/colon2#nd_head", node->nd_head);
       ADD_INSN3(ret, nd_line(node), defined, I2F(DEFINED_METHOD), ID2SYM(node->nd_mid), needstr);
     }
     return 1;
@@ -1490,15 +1632,15 @@
   case NODE_VCALL:
   case NODE_FCALL:
     if(nd_type(node) == NODE_CALL){
-      VALUE lcont = NEW_LABEL(nd_line(node));
+      LABEL_OBJECT *lcont = NEW_LABEL(nd_line(node));
       
-      defined_expr(self, node->nd_recv, ret, lfinish, Qfalse);
+      defined_expr(self, iseqobj, ret, node->nd_recv, lfinish, Qfalse);
       ADD_INSNL(ret, nd_line(node), if, lcont);
       ADD_INSN (ret, nd_line(node), putnil);
       ADD_INSNL(ret, nd_line(node), jump, lfinish);
       
       ADD_LABEL(ret, lcont);
-      ADD_SEQ  (ret, COMPILE("defined/recv", node->nd_recv));
+      COMPILE(ret, "defined/recv", node->nd_recv);
     }
     else{
       ADD_INSN(ret, nd_line(node), putself);
@@ -1511,7 +1653,9 @@
 
   if(estr != 0){
     if(needstr != Qfalse){
-      ADD_INSN1(ret, nd_line(node), putstring, rb_str_new2(estr));
+      VALUE str = rb_str_new2(estr);
+      ADD_INSN1(ret, nd_line(node), putstring, str);
+      rb_ary_push(iseqobj->compile_data->mark_ary, str);
     }
     else{
       ADD_INSN1(ret, nd_line(node), putobject, Qtrue);
@@ -1530,9 +1674,8 @@
   node:  Ruby compiled node
   poped: This node will be poped
  */
-static VALUE iseq_compile_each(VALUE self, NODE* node, int poped){
+static int iseq_compile_each(VALUE self, ISEQ_LINK_ANCHOR *ret, NODE* node, int poped){
   VALUE tmp; /* reserved for macro */
-  VALUE ret  = Qnil;
   NODE *n = node;
   VALUE args[10];
   
@@ -1547,9 +1690,10 @@
     if(!poped){
       debug_nodeprint("NODE_NIL(implicit)");
       debug_nodeprint_close();
-      return NEW_INSN_SEQ(0, putnil);
+      ADD_INSN(ret, 0, putnil);
+      return COMPILE_OK;
     }
-    return ret;
+    return COMPILE_OK;
   }
 
   debug_nodeprint(node_name(nd_type(node)));
@@ -1579,59 +1723,55 @@
     break;
   }
   case NODE_BLOCK:{
-    ret  = NEW_SEQ();
     while(node && nd_type(node) == NODE_BLOCK){
-      ADD_SEQ(ret, COMPILE_("BLOCK body", node->nd_head,
-                            (node->nd_next == 0 && poped == 0) ? 0 : 1));
+      COMPILE_(ret, "BLOCK body", node->nd_head,
+               (node->nd_next == 0 && poped == 0) ? 0 : 1);
       node = node->nd_next;
     }
     if(node){
-      ADD_SEQ(ret, COMPILE_("BLOCK next", node->nd_next, poped));
+      COMPILE_(ret, "BLOCK next", node->nd_next, poped);
     }
     break;
   }
   case NODE_IF:{
-    VALUE cond_seq;
-    VALUE then_seq;
-    VALUE else_seq;
-    VALUE then_label, else_label, end_label;
+    DECL_ANCHOR(cond_seq);
+    DECL_ANCHOR(then_seq);
+    DECL_ANCHOR(else_seq);
+    LABEL_OBJECT *then_label, *else_label, *end_label;
 
-    ret  = NEW_SEQ  ();
-
     then_label = NEW_LABEL(nd_line(node));
     else_label = NEW_LABEL(nd_line(node));
     end_label  = NEW_LABEL(nd_line(node));
 
-    cond_seq = compile_branch_condition(self, node->nd_cond, then_label, else_label);
-    then_seq = COMPILE_("then", node->nd_body, poped);
-    else_seq = COMPILE_("else", node->nd_else, poped);
+    compile_branch_condition(self, iseqobj, &cond_seq, node->nd_cond, then_label, else_label);
+    COMPILE_(&then_seq, "then", node->nd_body, poped);
+    COMPILE_(&else_seq, "else", node->nd_else, poped);
 
-    debugp_verbose("cond", cond_seq);
-    debugp_verbose("then", then_seq);
-    debugp_verbose("else", else_seq);
-
-    ADD_SEQ  (ret, cond_seq);
+    ADD_SEQ  (ret, &cond_seq);
     
     ADD_LABEL(ret, then_label);
-    ADD_SEQ  (ret, then_seq);
+    ADD_SEQ  (ret, &then_seq);
     ADD_INSNL(ret, nd_line(node), jump,   end_label);
     
     ADD_LABEL(ret, else_label);
-    ADD_SEQ  (ret, else_seq);
+    ADD_SEQ  (ret, &else_seq);
     
     ADD_LABEL(ret, end_label);
     
     break;
   }
   case NODE_CASE:{
-    VALUE head = COMPILE("case base", node->nd_head);
     NODE* vals;
     NODE* val;
     NODE* tempnode = node;
-    VALUE endlabel, elselabel;
-    VALUE body_seq, cond_seq;
+    LABEL_OBJECT* endlabel, *elselabel;
+    DECL_ANCHOR(head);
+    DECL_ANCHOR(body_seq);
+    DECL_ANCHOR(cond_seq);
     VALUE special_literals = rb_ary_new();
     
+    COMPILE(&head, "case base", node->nd_head);
+    
     node = node->nd_body;
     type = nd_type(node);
 
@@ -1639,22 +1779,19 @@
       COMPILE_ERROR(("NODE_CASE: unexpected node. must be NODE_WHEN, byt %s", node_name(type)));
     }
     
-    ret      = NEW_SEQ();
-    cond_seq = NEW_SEQ();
-    body_seq = NEW_SEQ();
     endlabel = NEW_LABEL(nd_line(node));
     elselabel = NEW_LABEL(nd_line(node));
     
-    ADD_SEQ (ret, head); /* case VAL */
+    ADD_SEQ (ret, &head); /* case VAL */
     
     while(type == NODE_WHEN){
-      VALUE l1;
+      LABEL_OBJECT *l1;
       
       l1  = NEW_LABEL(nd_line(node));
-      ADD_LABEL(body_seq, l1);
-      ADD_INSN (body_seq, nd_line(node), pop);
-      ADD_SEQ  (body_seq, COMPILE_("when body", node->nd_body, poped));
-      ADD_INSNL(body_seq, nd_line(node), jump, endlabel);
+      ADD_LABEL(&body_seq, l1);
+      ADD_INSN (&body_seq, nd_line(node), pop);
+      COMPILE_(&body_seq, "when body", node->nd_body, poped);
+      ADD_INSNL(&body_seq, nd_line(node), jump, endlabel);
 
       vals = node->nd_head;
       if(vals && nd_type(vals) == NODE_ARRAY){
@@ -1664,16 +1801,16 @@
           val = vals->nd_head;
 
           if((lit = case_when_optimizable_literal(val)) && special_literals){
-            rb_ary_push(special_literals, rb_ary_new3(2, lit, l1));
+            rb_ary_push(special_literals, rb_ary_new3(2, lit, (VALUE)(l1) | 1));
           }
           else{
             special_literals = Qfalse;
           }
 
-          ADD_SEQ  (cond_seq, COMPILE("when cond", val));
-          ADD_INSN1(cond_seq, nd_line(node), topn, INT2FIX(1));
-          ADD_SEND (cond_seq, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
-          ADD_INSNL(cond_seq, nd_line(node), if, l1);
+          COMPILE(&cond_seq, "when cond", val);
+          ADD_INSN1(&cond_seq, nd_line(node), topn, INT2FIX(1));
+          ADD_SEND (&cond_seq, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
+          ADD_INSNL(&cond_seq, nd_line(node), if, l1);
           vals = vals->nd_next;
         }
       }
@@ -1689,53 +1826,52 @@
     }
     /* else */
     if(node){
-      ADD_LABEL(cond_seq, elselabel);
-      ADD_INSN (cond_seq, nd_line(node), pop);
-      ADD_SEQ  (cond_seq,                COMPILE_("else", node, poped));
-      ADD_INSNL(cond_seq, nd_line(node), jump, endlabel);
+      ADD_LABEL(&cond_seq, elselabel);
+      ADD_INSN (&cond_seq, nd_line(node), pop);
+      COMPILE_ (&cond_seq, "else", node, poped);
+      ADD_INSNL(&cond_seq, nd_line(node), jump, endlabel);
     }
     else{
       debugs("== else(implicit)\n");
-      ADD_LABEL(cond_seq, elselabel);
-      ADD_INSN (cond_seq, nd_line(tempnode), pop);
+      ADD_LABEL(&cond_seq, elselabel);
+      ADD_INSN (&cond_seq, nd_line(tempnode), pop);
       if(!poped){
-        ADD_INSN (cond_seq, nd_line(tempnode), putnil);
+        ADD_INSN(&cond_seq, nd_line(tempnode), putnil);
       }
-      ADD_INSNL(cond_seq, nd_line(tempnode), jump, endlabel);
+      ADD_INSNL(&cond_seq, nd_line(tempnode), jump, endlabel);
     }
     
     if(special_literals){
       special_literals = (VALUE)NEW_WHILE(special_literals, 0, 0);
       ADD_INSN2(ret, nd_line(tempnode), opt_case_dispatch,
                 special_literals, elselabel);
+      rb_ary_push(iseqobj->compile_data->mark_ary, special_literals);
     }
-    
-    ADD_SEQ  (ret, cond_seq);
-    ADD_SEQ  (ret, body_seq);
+
+    ADD_SEQ  (ret, &cond_seq);
+    ADD_SEQ  (ret, &body_seq);
     ADD_LABEL(ret, endlabel);
     break;
   }
   case NODE_WHEN:{
     NODE* vals;
     NODE* val;
-    volatile VALUE endlabel;
-    volatile VALUE body_seq;
+    LABEL_OBJECT* endlabel;
+    DECL_ANCHOR(body_seq);
 
-    ret      = NEW_SEQ();
-    body_seq = NEW_SEQ();
     endlabel = NEW_LABEL(nd_line(node));
 
     while(nd_type(node) == NODE_WHEN){
-      VALUE l1  = NEW_LABEL(nd_line(node));
-      ADD_LABEL(body_seq, l1);
-      ADD_SEQ  (body_seq, COMPILE_("when", node->nd_body, poped));
-      ADD_INSNL(body_seq, nd_line(node), jump, endlabel);
+      LABEL_OBJECT *l1  = NEW_LABEL(nd_line(node));
+      ADD_LABEL(&body_seq, l1);
+      COMPILE_ (&body_seq, "when", node->nd_body, poped);
+      ADD_INSNL(&body_seq, nd_line(node), jump, endlabel);
       
       vals = node->nd_head;
       if(vals && nd_type(vals) == NODE_ARRAY){
         while(vals){
           val = vals->nd_head;
-          ADD_SEQ  (ret, COMPILE("when2", val));
+          COMPILE  (ret, "when2", val);
           ADD_INSNL(ret, nd_line(val), if, l1);
           vals = vals->nd_next;
         }
@@ -1746,10 +1882,10 @@
       node = node->nd_next;
     }
     /* else */
-    ADD_SEQ  (ret, COMPILE_("else", node, poped));
+    COMPILE_ (ret, "else", node, poped);
     ADD_INSNL(ret, nd_line(node), jump, endlabel);
 
-    ADD_SEQ  (ret, body_seq);
+    ADD_SEQ  (ret, &body_seq);
     ADD_LABEL(ret, endlabel);
     
     break;
@@ -1761,37 +1897,35 @@
   }
   case NODE_WHILE:
   case NODE_UNTIL:{
-    VALUE prev_start_label = iseqobj->compile_data->start_label;
-    VALUE prev_end_label   = iseqobj->compile_data->end_label;
-    VALUE prev_redo_label  = iseqobj->compile_data->redo_label;
+    LABEL_OBJECT *prev_start_label = iseqobj->compile_data->start_label;
+    LABEL_OBJECT * prev_end_label   = iseqobj->compile_data->end_label;
+    LABEL_OBJECT * prev_redo_label  = iseqobj->compile_data->redo_label;
     VALUE prev_loopval_popped = iseqobj->compile_data->loopval_popped;
     
-    VALUE next_label  = iseqobj->compile_data->start_label =
+    LABEL_OBJECT * next_label  = iseqobj->compile_data->start_label =
       NEW_LABEL(nd_line(node)); /* next  */
-    VALUE redo_label  = iseqobj->compile_data->redo_label  =
+    LABEL_OBJECT * redo_label  = iseqobj->compile_data->redo_label  =
       NEW_LABEL(nd_line(node)); /* redo  */
-    VALUE break_label = iseqobj->compile_data->end_label   =
+    LABEL_OBJECT * break_label = iseqobj->compile_data->end_label   =
       NEW_LABEL(nd_line(node)); /* break */
-    VALUE end_label = NEW_LABEL(nd_line(node));
+    LABEL_OBJECT * end_label = NEW_LABEL(nd_line(node));
 
     iseqobj->compile_data->loopval_popped = poped;
     
-    ret = NEW_SEQ();
-    
     ADD_INSNL(ret, nd_line(node), jump, next_label);
 
     ADD_LABEL(ret, redo_label);
-    ADD_SEQ  (ret, COMPILE_("while body", node->nd_body, 1));
+    COMPILE_ (ret, "while body", node->nd_body, 1);
     
     ADD_LABEL(ret, next_label); /* next */
     if(type == NODE_WHILE){
-      ADD_SEQ(ret, compile_branch_condition(self, node->nd_cond,
-                                            redo_label, end_label));
+      compile_branch_condition(self, iseqobj, ret,
+                               node->nd_cond, redo_label, end_label);
     }
     else{
       /* untile */
-      ADD_SEQ(ret, compile_branch_condition(self, node->nd_cond,
-                                            end_label, redo_label));
+      compile_branch_condition(self, iseqobj, ret,
+                               node->nd_cond, end_label, redo_label);
     }
 
     ADD_LABEL(ret, end_label);
@@ -1809,17 +1943,16 @@
   case NODE_ITER:
   case NODE_FOR:{
     VALUE prevblock = iseqobj->compile_data->current_block;
-    VALUE retry_label = NEW_LABEL(nd_line(node));
-    VALUE retry_end_l = NEW_LABEL(nd_line(node));
+    LABEL_OBJECT * retry_label = NEW_LABEL(nd_line(node));
+    LABEL_OBJECT * retry_end_l = NEW_LABEL(nd_line(node));
     VALUE name = rb_str_new2("b@");
     rb_str_concat(name, iseqobj->name);
     
     iseqobj->compile_data->current_block = NEW_CHILD_ISEQOBJ(node, name,
                                                              self, ISEQ_TYPE_BLOCK);
-    ret = NEW_SEQ();
     ADD_LABEL(ret, retry_label);
     if(nd_type(node) == NODE_FOR){
-      ADD_SEQ(ret, COMPILE("iter caller (for)", node->nd_iter));
+      COMPILE(ret, "iter caller (for)", node->nd_iter);
       ADD_SEND_R(ret, nd_line(node), ID2SYM(idEach), INT2FIX(0),
                  iseqobj->compile_data->current_block, INT2FIX(0));
       if(poped){
@@ -1827,7 +1960,7 @@
       }
     }
     else{
-      ADD_SEQ  (ret, COMPILE_("iter caller", node->nd_iter, poped));
+      COMPILE_(ret, "iter caller", node->nd_iter, poped);
     }
     ADD_LABEL(ret, retry_end_l);
     iseqobj->compile_data->current_block = prevblock;
@@ -1838,15 +1971,13 @@
   case NODE_BREAK:{
     if(iseqobj->compile_data->redo_label != 0){
       /* while/until */
-      ret = NEW_SEQ();
-      ADD_SEQ  (ret, COMPILE_("break val(while/until)", node->nd_stts,
-                              iseqobj->compile_data->loopval_popped));
+      COMPILE_(ret, "break val(while/until)", node->nd_stts,
+               iseqobj->compile_data->loopval_popped);
       ADD_INSNL(ret, nd_line(node), jump, iseqobj->compile_data->end_label);
     }
     else if(iseqobj->type == ISEQ_TYPE_BLOCK){
       /* escape from block */
-      ret = NEW_SEQ();
-      ADD_SEQ  (ret, COMPILE("break val(block)", node->nd_stts));
+      COMPILE(ret, "break val(block)", node->nd_stts);
       ADD_INSN1(ret, nd_line(node), throw, I2F(0x02) /* TAG_BREAK */);
     }
     else{
@@ -1856,12 +1987,11 @@
     break;
   }
   case NODE_NEXT:{
-    ret = NEW_SEQ();
     if(iseqobj->compile_data->redo_label != 0){
       ADD_INSNL(ret, nd_line(node), jump, iseqobj->compile_data->start_label);
     }
     else if(iseqobj->compile_data->end_label){
-      ADD_SEQ  (ret, COMPILE("next val", node->nd_stts));
+      COMPILE(ret, "next val", node->nd_stts);
       ADD_INSNL(ret, nd_line(node), jump, iseqobj->compile_data->end_label);
     }
     else{
@@ -1870,7 +2000,6 @@
     break;
   }
   case NODE_REDO:{
-    ret = NEW_SEQ();
     if(iseqobj->compile_data->redo_label){
       ADD_INSNL(ret, nd_line(node), jump, iseqobj->compile_data->redo_label);
     }
@@ -1885,7 +2014,6 @@
   case NODE_RETRY:{
     if(iseqobj->type == ISEQ_TYPE_BLOCK ||
        iseqobj->type == ISEQ_TYPE_RESCUE){
-      ret = NEW_SEQ();
       ADD_INSN (ret, nd_line(node), putnil);
       ADD_INSN1(ret, nd_line(node), throw, I2F(0x04) /* TAG_RETRY */);
     }
@@ -1895,23 +2023,21 @@
     break;
   }
   case NODE_BEGIN:{
-    ret = NEW_SEQ();
-    ADD_SEQ(ret, COMPILE_("NODE_BEGIN", node->nd_body, poped));
+    COMPILE_(ret, "NODE_BEGIN", node->nd_body, poped);
     break;
   }
   case NODE_RESCUE:{
-    VALUE lstart = NEW_LABEL(nd_line(node));
-    VALUE lend   = NEW_LABEL(nd_line(node));
-    VALUE lcont  = NEW_LABEL(nd_line(node));
+    LABEL_OBJECT * lstart = NEW_LABEL(nd_line(node));
+    LABEL_OBJECT * lend   = NEW_LABEL(nd_line(node));
+    LABEL_OBJECT * lcont  = NEW_LABEL(nd_line(node));
     VALUE rescue = NEW_CHILD_ISEQOBJ(node->nd_resq, rb_str_new2("rescue clause"),
                                      self, ISEQ_TYPE_RESCUE);
     
-    ret = NEW_SEQ();
     ADD_LABEL(ret, lstart);
-    ADD_SEQ(ret, COMPILE("rescue head", node->nd_head));
+    COMPILE(ret, "rescue head", node->nd_head);
     ADD_LABEL(ret, lend);
     if(node->nd_else){
-      ADD_SEQ(ret, COMPILE("rescue else", node->nd_else));
+      COMPILE(ret, "rescue else", node->nd_else);
     }
     ADD_INSN (ret, nd_line(node), nop);
     ADD_LABEL(ret, lcont);
@@ -1928,16 +2054,15 @@
   case NODE_RESBODY:{
     NODE *resq = node;
     NODE *narg;
-    VALUE label_miss, label_hit;
+        LABEL_OBJECT * label_miss, * label_hit;
     
-    ret = NEW_SEQ();
     while(resq){
       label_miss = NEW_LABEL(nd_line(node));
       label_hit  = NEW_LABEL(nd_line(node));
       
       narg = resq->nd_args;
       while(narg){
-        ADD_SEQ  (ret, COMPILE("rescue arg", narg->nd_head));
+        COMPILE  (ret, "rescue arg", narg->nd_head);
         ADD_INSN2(ret, nd_line(node), getdynamic, I2F(1), I2F(0));
         ADD_SEND (ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
         ADD_INSNL(ret, nd_line(node), if, label_hit);
@@ -1951,7 +2076,7 @@
       }
       ADD_INSNL(ret, nd_line(node), jump, label_miss);
       ADD_LABEL(ret, label_hit);
-      ADD_SEQ  (ret, COMPILE("resbody body", resq->nd_body));
+      COMPILE  (ret, "resbody body", resq->nd_body);
       ADD_INSN1(ret, nd_line(node), end, I2F(iseqobj->rewind_frame_size));
       ADD_LABEL(ret, label_miss);
       resq = resq->nd_head;
@@ -1961,22 +2086,24 @@
   case NODE_ENSURE:{
     VALUE ensure = NEW_CHILD_ISEQOBJ(node->nd_ensr, rb_str_new2("ensure clause"),
                                      self, ISEQ_TYPE_ENSURE);
-    VALUE lstart = NEW_LABEL(nd_line(node));
-    VALUE lend   = NEW_LABEL(nd_line(node));
-    VALUE lcont  = NEW_LABEL(nd_line(node));
-    VALUE ensr   = COMPILE_POPED("ensure ensr", node->nd_ensr);
+    LABEL_OBJECT * lstart = NEW_LABEL(nd_line(node));
+    LABEL_OBJECT * lend   = NEW_LABEL(nd_line(node));
+    LABEL_OBJECT * lcont  = NEW_LABEL(nd_line(node));
+    DECL_ANCHOR(ensr);
+    
     VALUE prev_in_ensure = iseqobj->compile_data->in_ensure;
     iseqobj->compile_data->in_ensure = Qtrue;
+
+    COMPILE_POPED(&ensr, "ensure ensr", node->nd_ensr);
     
-    ret = NEW_SEQ();
     ADD_LABEL(ret, lstart);
-    ADD_SEQ(ret, COMPILE_("ensure head", node->nd_head, poped));
+    COMPILE_(ret, "ensure head", node->nd_head, poped);
     ADD_LABEL(ret, lend);
-    if(ensr == Qnil){
+    if(ensr.anchor.next == 0){
       ADD_INSN(ret, nd_line(node), nop);
     }
     else{
-      ADD_SEQ(ret, ensr);
+      ADD_SEQ(ret, &ensr);
     }
     ADD_LABEL(ret, lcont);
 
@@ -1987,9 +2114,8 @@
     
   case NODE_AND:
   case NODE_OR:{
-    VALUE end_label = NEW_LABEL(nd_line(node));
-    ret = NEW_SEQ();
-    ADD_SEQ  (ret, COMPILE("nd_1st", node->nd_1st));
+    LABEL_OBJECT * end_label = NEW_LABEL(nd_line(node));
+    COMPILE(ret, "nd_1st", node->nd_1st);
     if(!poped){
       ADD_INSN(ret, nd_line(node), dup);
     }
@@ -2001,15 +2127,14 @@
       ADD_INSNL(ret, nd_line(node), if, end_label);
     }
     ADD_INSN (ret, nd_line(node), pop);
-    ADD_SEQ  (ret, COMPILE_("nd_2nd", node->nd_2nd, poped));
+    COMPILE_ (ret, "nd_2nd", node->nd_2nd, poped);
     ADD_LABEL(ret, end_label);
     
     break;
   }
     
   case NODE_NOT:{
-    ret = NEW_SEQ();
-    ADD_SEQ( ret, COMPILE("value", node->nd_body));
+    COMPILE (ret, "value", node->nd_body);
     ADD_INSN(ret, nd_line(node), putnot);
     if(poped){
       ADD_INSN(ret, nd_line(node), pop);
@@ -2018,27 +2143,22 @@
   }
     
   case NODE_MASGN:{
-    //VALUE mlhs = COMPILE("masgin mlhs", node->nd_head); // for debug
-    //VALUE mrhs = COMPILE("masgin mrhs", node->nd_value); // for debug
-
     NODE *rhsn = node->nd_value;
     NODE *lhsn = node->nd_head;
-    VALUE mlhs_seq;
+    DECL_ANCHOR(mlhs_seq);
     
     int rlen, llen, i, max, si = 0;
     VALUE lhs_splat = Qfalse;
-    
-    ret = NEW_SEQ();
-    mlhs_seq = NEW_SEQ();
+
     llen = 0;
     while(lhsn){
-      ADD_SEQ(mlhs_seq, make_masgn_lhs(self, lhsn->nd_head));
+      make_masgn_lhs(self, iseqobj, &mlhs_seq, lhsn->nd_head);
       llen += 1;
       lhsn  = lhsn->nd_next;
     }
     
     if(node->nd_args && (long)node->nd_args != -1){
-      ADD_SEQ(mlhs_seq, make_masgn_lhs(self, node->nd_args));
+      make_masgn_lhs(self, iseqobj, &mlhs_seq, node->nd_args);
       lhs_splat = Qtrue;
     }
     
@@ -2051,21 +2171,21 @@
       for(i=0; i<max; i++){
         if(i<rlen && i<llen){
           /* a, b = c, d*/
-          ADD_SEQ(ret, COMPILE("masgn val1", rhsn->nd_head));
+          COMPILE(ret, "masgn val1", rhsn->nd_head);
           rhsn = rhsn->nd_next;
         }
         else if(i<rlen){
           if(lhs_splat){
             while(rhsn){
               si++;
-              ADD_SEQ(ret, COMPILE("masgn rhs for lhs splat", rhsn->nd_head));
+              COMPILE(ret, "masgn rhs for lhs splat", rhsn->nd_head);
               rhsn = rhsn->nd_next;
             }
             break;
           }
           else{
             /* a, b = c, d, e */
-            ADD_SEQ(ret, COMPILE_POPED("masgn val2", rhsn->nd_head));
+            COMPILE_POPED(ret, "masgn val2", rhsn->nd_head);
             rhsn = rhsn->nd_next;
           }
         }
@@ -2080,12 +2200,12 @@
       }
       break;
     case NODE_TO_ARY:
-      ADD_SEQ  (ret, COMPILE("rhs to ary", rhsn->nd_head));
+      COMPILE  (ret, "rhs to ary", rhsn->nd_head);
       ADD_INSN2(ret, nd_line(node), expandarray, I2F(llen), lhs_splat);
       break;
       
     case NODE_SPLAT:
-      ADD_SEQ  (ret, COMPILE("rhs to ary (splat)", rhsn->nd_head));
+      COMPILE  (ret, "rhs to ary (splat)", rhsn->nd_head);
       ADD_INSN2(ret, nd_line(node), expandarray, I2F(llen), lhs_splat);
       break;
 
@@ -2095,21 +2215,21 @@
       
       while(ary){
         if(idx < llen || lhs_splat){
-          ADD_SEQ(ret, COMPILE("rhs aggscat each head", ary->nd_head));
+          COMPILE(ret, "rhs aggscat each head", ary->nd_head);
         }
         else{
-          ADD_SEQ(ret, COMPILE_POPED("rhs aggscat each head (popped)", ary->nd_head));
+          COMPILE_POPED(ret, "rhs aggscat each head (popped)", ary->nd_head);
         }
         ary = ary->nd_next;
         idx++;
       }
       rlen = rhsn->nd_head->nd_alen;
       if(llen > idx){
-        ADD_SEQ  (ret, COMPILE("rhs to ary (argscat/splat)", rhsn->nd_body));
+        COMPILE  (ret, "rhs to ary (argscat/splat)", rhsn->nd_body);
         ADD_INSN2(ret, nd_line(node), expandarray, I2F(llen - idx), lhs_splat);
       }
       else if(lhs_splat){
-        ADD_SEQ  (ret, COMPILE("rhs to ary (argscat/splat)", rhsn->nd_body));
+        COMPILE  (ret, "rhs to ary (argscat/splat)", rhsn->nd_body);
         ADD_INSN2(ret, nd_line(node), expandarray, I2F(llen - idx), lhs_splat);
       }
       break;
@@ -2117,9 +2237,8 @@
     default:
       rb_bug("unknown rhs: %s", node_name(nd_type(node->nd_value)));
     }
+    ADD_SEQ(ret, REVERSE_LIST(&mlhs_seq));
 
-    ADD_SEQ(ret, rb_ary_reverse(mlhs_seq));
-
     if(!poped){
       ADD_INSN(ret, nd_line(node), putnil);
     }
@@ -2127,12 +2246,9 @@
   }
   case NODE_LASGN:{
     int idx = get_root_iseq_localsize(iseqobj) + 2 - node->nd_cnt;
-    VALUE obj;
     
     debugs("lvar: %d\n", idx);
-    obj = COMPILE("lvalue", node->nd_value);
-    ret = NEW_SEQ();
-    ADD_SEQ  (ret, obj);
+    COMPILE(ret, "lvalue", node->nd_value);
     
     if(!poped){
       ADD_INSN(ret, nd_line(node), dup);
@@ -2143,12 +2259,11 @@
   }
   case NODE_DASGN:
   case NODE_DASGN_CURR:{
-    VALUE val = COMPILE("dvalue", node->nd_value);
     int idx, lv, ls;
+    COMPILE(ret, "dvalue", node->nd_value);
     
     debugp_param("dassn id", rb_str_new2(rb_id2name(node->nd_vid)));
-    ret = NEW_SEQ();
-    ADD_SEQ(ret, val);
+
     if(!poped){
       ADD_INSN(ret, nd_line(node), dup);
     }
@@ -2169,10 +2284,8 @@
     break;
   }
   case NODE_GASGN:{
-    VALUE val = COMPILE("lvalue", node->nd_value);
+    COMPILE(ret, "lvalue", node->nd_value);
 
-    ret = NEW_SEQ();
-    ADD_SEQ(ret, val);
     if(!poped){
       ADD_INSN(ret, nd_line(node), dup);
     }
@@ -2180,8 +2293,7 @@
     break;
   }
   case NODE_IASGN:{
-    ret = NEW_SEQ();
-    ADD_SEQ(ret, COMPILE("lvalue", node->nd_value));
+    COMPILE(ret, "lvalue", node->nd_value);
     if(!poped){
       ADD_INSN(ret, nd_line(node), dup);
     }
@@ -2189,8 +2301,7 @@
     break;
   }
   case NODE_CDECL:{
-    ret = NEW_SEQ();
-    ADD_SEQ  (ret, COMPILE("lvalue", node->nd_value));
+    COMPILE(ret, "lvalue", node->nd_value);
 
     if(!poped){
       ADD_INSN(ret, nd_line(node), dup);
@@ -2201,15 +2312,14 @@
       ADD_INSN1(ret, nd_line(node), setconstant, ID2SYM(node->nd_vid));
     }
     else{
-      ADD_SEQ  (ret, COMPILE("nd_else->nd_head", node->nd_else->nd_head));
+      COMPILE  (ret, "nd_else->nd_head", node->nd_else->nd_head);
       ADD_INSN1(ret, nd_line(node), setconstant, ID2SYM(node->nd_else->nd_mid));
     }
     break;
   }
   case NODE_CVASGN:
   case NODE_CVDECL:{
-    ret = NEW_SEQ();
-    ADD_SEQ  (ret, COMPILE("cvasgn val", node->nd_value));
+    COMPILE(ret, "cvasgn val", node->nd_value);
     if(!poped){
       ADD_INSN(ret, nd_line(node), dup);
     }
@@ -2218,10 +2328,9 @@
     break;
   }
   case NODE_OP_ASGN1:{
-    VALUE args;
+    DECL_ANCHOR(args);
     int   argc;
     ID    id = node->nd_mid;
-    ret = NEW_SEQ();
 
     /*
      * a[x] (op)= y
@@ -2234,13 +2343,13 @@
      * send op   # a x a[x]+y
      * send []=  # ret
      */
-    ADD_SEQ  (ret, COMPILE("NODE_OP_ASGN1 recv", node->nd_recv));
+    COMPILE(ret, "NODE_OP_ASGN1 recv", node->nd_recv);
 
-    args = compile_array(self, node->nd_args->nd_next, Qfalse);
-    rb_ary_pop(args); rb_ary_pop(args);
-    argc =node->nd_args->nd_alen - 2;
+    compile_array(self, iseqobj, &args, node->nd_args->nd_next, Qfalse);
+    POP_ELEMENT(&args); POP_ELEMENT(&args);
+    argc = node->nd_args->nd_alen - 2;
 
-    ADD_SEQ  (ret, args);
+    ADD_SEQ  (ret, &args);
     ADD_INSN1(ret, nd_line(node), dupn, I2F(argc+1));
     ADD_SEND (ret, nd_line(node), ID2SYM(idAREF), I2F(argc));
 
@@ -2254,8 +2363,8 @@
           nil
         end
        */
-      VALUE label = NEW_LABEL(nd_line(node));
-      VALUE lfin  = NEW_LABEL(nd_line(node));
+      LABEL_OBJECT * label = NEW_LABEL(nd_line(node));
+      LABEL_OBJECT * lfin  = NEW_LABEL(nd_line(node));
       
       if(id == 0){
         ADD_INSN (ret, nd_line(node), dup);
@@ -2265,7 +2374,7 @@
       else{
         ADD_INSNL(ret, nd_line(node), unless, label);
       }
-      ADD_SEQ  (ret, COMPILE("NODE_OP_ASGN1 args->head: ", node->nd_args->nd_head));
+      COMPILE  (ret, "NODE_OP_ASGN1 args->head: ", node->nd_args->nd_head);
       ADD_SEND (ret, nd_line(node), ID2SYM(idASET), I2F(argc+1));
       ADD_INSNL(ret, nd_line(node), jump, lfin);
       ADD_LABEL(ret, label);
@@ -2275,9 +2384,9 @@
       ADD_LABEL(ret, lfin);
     }
     else{
-      ADD_SEQ  (ret, COMPILE("NODE_OP_ASGN1 args->head: ", node->nd_args->nd_head));
-      ADD_SEND (ret, nd_line(node), ID2SYM(id), I2F(1));
-      ADD_SEND (ret, nd_line(node), ID2SYM(idASET), I2F(argc+1));
+      COMPILE (ret, "NODE_OP_ASGN1 args->head: ", node->nd_args->nd_head);
+      ADD_SEND(ret, nd_line(node), ID2SYM(id), I2F(1));
+      ADD_SEND(ret, nd_line(node), ID2SYM(idASET), I2F(argc+1));
     }
 
     if(poped){
@@ -2288,8 +2397,8 @@
   }
   case NODE_OP_ASGN2:{
     ID    atype = node->nd_next->nd_mid;
-    VALUE lfin  = new_label(nd_line(node));
-    VALUE lcfin  = new_label(nd_line(node));
+    LABEL_OBJECT * lfin  = NEW_LABEL(nd_line(node));
+    LABEL_OBJECT * lcfin = NEW_LABEL(nd_line(node));
     /*
       class C; attr_accessor :c; end
       r = C.new
@@ -2328,8 +2437,7 @@
       
      */
 
-    ret = NEW_SEQ();
-    ADD_SEQ (ret, COMPILE("NODE_OP_ASGN2#recv", node->nd_recv));
+    COMPILE  (ret, "NODE_OP_ASGN2#recv", node->nd_recv);
     ADD_INSN (ret, nd_line(node), dup);
     ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_next->nd_vid), I2F(0));
 
@@ -2342,7 +2450,7 @@
         ADD_INSNL(ret, nd_line(node), unless, lcfin);
       }
       ADD_INSN (ret, nd_line(node), pop);
-      ADD_SEQ  (ret, COMPILE("NODE_OP_ASGN2 val", node->nd_value));
+      COMPILE  (ret, "NODE_OP_ASGN2 val", node->nd_value);
       ADD_SEND (ret, nd_line(node), ID2SYM(node->nd_next->nd_aid), I2F(1));
       ADD_INSNL(ret, nd_line(node), jump, lfin);
       
@@ -2353,7 +2461,7 @@
       ADD_LABEL(ret, lfin);
     }
     else{
-      ADD_SEQ (ret, COMPILE("NODE_OP_ASGN2 val", node->nd_value));
+      COMPILE (ret, "NODE_OP_ASGN2 val", node->nd_value);
       ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_next->nd_mid), I2F(1));
       ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_next->nd_aid), I2F(1));
     }
@@ -2366,10 +2474,10 @@
   }
   case NODE_OP_ASGN_AND:
   case NODE_OP_ASGN_OR:{
-    VALUE lfin = new_label(nd_line(node));
-    ret = NEW_SEQ();
-    ADD_SEQ  (ret, COMPILE("NODE_OP_ASGN_AND#nd_head", node->nd_head));
-    ADD_INSN (ret, nd_line(node), dup);
+    LABEL_OBJECT * lfin = NEW_LABEL(nd_line(node));
+    
+    COMPILE (ret, "NODE_OP_ASGN_AND#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);
     }
@@ -2377,7 +2485,7 @@
       ADD_INSNL(ret, nd_line(node), if, lfin);
     }
     ADD_INSN (ret, nd_line(node), pop);
-    ADD_SEQ  (ret, COMPILE("NODE_OP_ASGN_AND#nd_value", node->nd_value));
+    COMPILE  (ret, "NODE_OP_ASGN_AND#nd_value", node->nd_value);
     ADD_LABEL(ret, lfin);
     
     if(poped){
@@ -2394,14 +2502,14 @@
       fcall: func(...)
       vcall: func()
      */
-    VALUE recv;
-    VALUE args;
+    DECL_ANCHOR(recv);
+    DECL_ANCHOR(args);
     VALUE argc;
     VALUE flag  = 0;
     VALUE block = 0;
     VALUE parent_block = iseqobj->compile_data->current_block;
     iseqobj->compile_data->current_block = Qfalse;
-
+    
 #if SUPPORT_GOTO
     /* only joke */
     {
@@ -2430,7 +2538,6 @@
           rb_bug("illegal goto/label format");
         }
         
-        ret = NEW_SEQ();
         
         if(node->nd_mid == goto_id){
           ADD_INSNL(ret, nd_line(node), jump, label);
@@ -2445,51 +2552,48 @@
 
     /* reciever */
     if(type == NODE_CALL){
-      recv = COMPILE("recv", node->nd_recv);
+      COMPILE(&recv, "recv", node->nd_recv);
     }
     else if(type == NODE_FCALL ||
             type == NODE_VCALL){
-      recv = NEW_INSN_SEQ(nd_line(node), putself);
+      ADD_INSN(&recv, nd_line(node), putself);
     }
 
     /* args */
     if(type != NODE_VCALL && node->nd_args){
       if(nd_type(node->nd_args) == NODE_SPLAT){
-        args  = COMPILE("args(splat)", node->nd_args->nd_head);
+        COMPILE(&args, "args(splat)", node->nd_args->nd_head);
         argc  = I2F(1);
         flag |= VM_CALL_ARGS_SPLAT_BIT;
       }
       else if(nd_type(node->nd_args) == NODE_ARGSCAT){
-        args = compile_array(self, node->nd_args->nd_head, Qfalse);
-        rb_ary_pop(args);
+        compile_array(self, iseqobj, &args, node->nd_args->nd_head, Qfalse);
+        POP_ELEMENT(&args);
         
-        argc = I2F(RARRAY(args)->len + 1);
-        rb_ary_concat(args,
-                      COMPILE("args(cat: splat)", node->nd_args->nd_body));
+        argc = I2F(LIST_SIZE(&args) + 1);
+        COMPILE(&args, "args(cat: splat)", node->nd_args->nd_body);
 
         flag |= VM_CALL_ARGS_SPLAT_BIT;
       }
       else{
-        args = compile_array(self, node->nd_args, Qfalse);
-        argc = OPERAND(rb_ary_pop(args), 0);
+        compile_array(self, iseqobj, &args, node->nd_args, Qfalse);
+        argc = OPERAND_AT(POP_ELEMENT(&args), 0);
      }
     }
     else{
-      args = Qnil;
       argc = I2F(0);
     }
 
-    ret = NEW_SEQ();
-    ADD_SEQ(ret, recv);
-    ADD_SEQ(ret, args);
+    ADD_SEQ(ret, &recv);
+    ADD_SEQ(ret, &args);
     
     if(parent_block){
-      if(CLASS_OF(parent_block) == cYarvISeq){
-        block = parent_block;
+      if(parent_block & 1){
+        flag |= VM_CALL_ARGS_BLOCKARG_BIT;
+        ADD_SEQ(ret, (ISEQ_LINK_ANCHOR *)(parent_block & (~1)));
       }
       else{
-        flag |= VM_CALL_ARGS_BLOCKARG_BIT;
-        ADD_SEQ(ret, parent_block);
+        block = parent_block;
       }
     }
 
@@ -2535,7 +2639,6 @@
   normal_call:
     
     /* */
-    debugp_verbose("call args",    args);
     debugp_param("call args argc", argc);
     debugp_param("call method",    ID2SYM(node->nd_mid));
     
@@ -2548,40 +2651,37 @@
     break;
   }
   case NODE_SUPER:{
-    VALUE args;
+    DECL_ANCHOR(args);
     VALUE argc;
     VALUE flag = 0;
     
     /* args */
     if(type != NODE_VCALL && node->nd_args){
       if(nd_type(node->nd_args) == NODE_SPLAT){
-        args  = COMPILE("args(splat)", node->nd_args->nd_head);
+        COMPILE(&args, "args(splat)", node->nd_args->nd_head);
         argc  = I2F(1);
         flag |= VM_CALL_ARGS_SPLAT_BIT;
       }
       else if(nd_type(node->nd_args) == NODE_ARGSCAT){
-        args = compile_array(self, node->nd_args->nd_head, Qfalse);
-        rb_ary_pop(args);
+        compile_array(self, iseqobj, &args, node->nd_args->nd_head, Qfalse);
+        POP_ELEMENT(&args);
         
-        argc = I2F(RARRAY(args)->len + 1);
-        rb_ary_concat(args,
-                      COMPILE("args(cat: splat)", node->nd_args->nd_body));
+        argc = LIST_SIZE(&args) + 1;
+        COMPILE(&args, "args(cat: splat)", node->nd_args->nd_body);
 
         flag |= VM_CALL_ARGS_SPLAT_BIT;
       }
       else{
-        args = compile_array(self, node->nd_args, Qfalse);
-        argc = OPERAND(rb_ary_pop(args), 0);
+        compile_array(self, iseqobj, &args, node->nd_args, Qfalse);
+        argc = OPERAND_AT(POP_ELEMENT(&args), 0);
      }
     }
     else{
-      args = Qnil;
       argc = I2F(0);
     }
 
-    ret = NEW_SEQ();
     ADD_INSN(ret, nd_line(node), putnil); /* dummy reciever */
-    ADD_SEQ(ret, args);
+    ADD_SEQ(ret, &args);
     ADD_INSN2(ret, nd_line(node), super, argc, I2F(flag));
 
     if(poped){
@@ -2590,7 +2690,6 @@
     break;
   }
   case NODE_ZSUPER:{
-    ret = NEW_SEQ();
     ADD_INSN(ret, nd_line(node), zsuper);
 
     if(poped){
@@ -2599,7 +2698,7 @@
     break;
   }
   case NODE_ARRAY:{
-    ret = compile_array(self, node, Qtrue);
+    compile_array(self, iseqobj, ret, node, Qtrue);
     if(poped){
       ADD_INSN(ret, nd_line(node), pop);
     }
@@ -2607,15 +2706,14 @@
   }
   case NODE_ZARRAY:{
     if(!poped){
-      ret = NEW_INSN_SEQ1(nd_line(node), newarray, I2F(0));
+      ADD_INSN1(ret, nd_line(node), newarray, I2F(0));
     }
     break;
   }
   case NODE_VALUES:{
     NODE *n = node;
-    ret = NEW_SEQ();
     while(n){
-      ADD_SEQ(ret, COMPILE("values item", n->nd_head));
+      COMPILE(ret, "values item", n->nd_head);
       n = n->nd_next;
     }
     ADD_INSN1(ret, nd_line(node), newarray, I2F(node->nd_alen));
@@ -2625,20 +2723,16 @@
     break;
   }
   case NODE_HASH:{
-    VALUE list;
+    DECL_ANCHOR(list);
     VALUE size;
     int type = node->nd_head ? nd_type(node->nd_head) : NODE_ZARRAY;
-
-    ret = NEW_SEQ();
     
     switch(type){
     case NODE_ARRAY:{
       VALUE iary;
-      list = compile_array(self, node->nd_head, Qfalse);
-      iary = rb_ary_pop(list);
-      debugp_param("hash ary: ", iary);
-      size = OPERAND(iary, 0);
-      ADD_SEQ  (ret, list);
+      compile_array(self, iseqobj, &list, node->nd_head, Qfalse);
+      size = OPERAND_AT(POP_ELEMENT(&list), 0);
+      ADD_SEQ  (ret, &list);
       break;
     } 
     case NODE_ZARRAY:
@@ -2658,7 +2752,6 @@
   }
   case NODE_RETURN:{
     struct iseq_object *is = iseqobj;
-    ret = NEW_SEQ();
 
     while(is){
       if(is->type == ISEQ_TYPE_TOP ||
@@ -2671,7 +2764,7 @@
         is = is->parent_iseqobj;
       }
       else{
-        ADD_SEQ(ret, COMPILE("return nd_stts(return val)", node->nd_stts));
+        COMPILE(ret, "return nd_stts(return val)", node->nd_stts);
 
         if(is->type == ISEQ_TYPE_METHOD && is->compile_data->in_ensure == Qfalse){
           ADD_INSN1(ret, nd_line(node), end, I2F(iseqobj->rewind_frame_size));
@@ -2689,7 +2782,7 @@
     break;
   }
   case NODE_YIELD:{
-    VALUE args;
+    DECL_ANCHOR(args);
     int argc;
     
     if(iseqobj->type == ISEQ_TYPE_TOP ||
@@ -2699,22 +2792,20 @@
     
     if(node->nd_head){
       if(nd_type(node->nd_head) == NODE_ARRAY){
-        args = compile_array(self, node->nd_head, Qfalse);
-        rb_ary_pop(args);
-        argc = RARRAY(args)->len;
+        compile_array(self, iseqobj, &args, node->nd_head, Qfalse);
+        POP_ELEMENT(&args);
+        argc = LIST_SIZE(&args);
         debugs("argc: %d\n", argc);
       }
       else{
-        args = COMPILE("nd_head(1)", node->nd_head);
+        COMPILE(&args, "nd_head(1)", node->nd_head);
         argc = 1;
       }
     }
     else{
-      args = Qnil;
       argc = 0;
     }
-    ret = NEW_SEQ();
-    ADD_SEQ  (ret, args);
+    ADD_SEQ  (ret, &args);
     ADD_INSN2(ret, nd_line(node), yield, I2F(argc), I2F(0));
 
     if(poped){
@@ -2726,7 +2817,7 @@
     if(!poped){
       int idx = get_root_iseq_localsize(iseqobj) + 2 - node->nd_cnt;
       debugs("idx: %d\n", idx);
-      ret = NEW_INSN_SEQ1(nd_line(node), getlocal, I2F(idx));
+      ADD_INSN1(ret, nd_line(node), getlocal, I2F(idx));
     }
     break;
   }
@@ -2738,13 +2829,12 @@
       if(idx < 0){
         COMPILE_ERROR(("unknown dvar"));
       }
-      ret = NEW_SEQ();
       ADD_INSN2(ret, nd_line(node), getdynamic, I2F(ls - idx), I2F(lv));
     }
     break;
   }
   case NODE_GVAR:{
-    ret = NEW_INSN_SEQ1(nd_line(node), getglobal, (((long)node->nd_entry) | 1));
+    ADD_INSN1(ret, nd_line(node), getglobal, (((long)node->nd_entry) | 1));
     if(poped){
       ADD_INSN(ret, nd_line(node), pop);
     }
@@ -2753,7 +2843,6 @@
   case NODE_IVAR:{
     debugi("nd_vid", node->nd_vid);
     if(!poped){
-      ret = NEW_SEQ();
       ADD_INSN1(ret, nd_line(node), getinstancevariable, ID2SYM(node->nd_vid));
     }
     break;
@@ -2761,10 +2850,9 @@
   case NODE_CONST:{
     debugi("nd_vid", node->nd_vid);
     if(!poped){
-      ret = NEW_SEQ();
       if(iseqobj->compile_data->cached_const == Qfalse){
-        VALUE lstart = NEW_LABEL(nd_line(node));
-        VALUE lend   = NEW_LABEL(nd_line(node));
+        LABEL_OBJECT * lstart = NEW_LABEL(nd_line(node));
+        LABEL_OBJECT * lend   = NEW_LABEL(nd_line(node));
         
         ADD_LABEL(ret, lstart);
         ADD_INSN2(ret, nd_line(node), getinlinecache, NEW_INLINE_CACHE_ENTRY(), lend);
@@ -2782,55 +2870,50 @@
     break;
   }
   case NODE_CVAR:{
-    ret = NEW_SEQ();
     if(!poped){
       ADD_INSN1(ret, nd_line(node), getclassvariable, ID2SYM(node->nd_vid));
     }
     break;
   }
   case NODE_NTH_REF:{
-    ret = NEW_SEQ();
     ADD_INSN2(ret, nd_line(node), getspecial, I2F(node->nd_cnt), I2F(node->nd_nth << 1));
     break;
   }
   case NODE_BACK_REF:{
-    ret = NEW_SEQ();
     ADD_INSN2(ret, nd_line(node), getspecial, I2F(node->nd_cnt), I2F(0x01 | (node->nd_nth << 1)));
     break;
   }
   case NODE_MATCH:
   case NODE_MATCH2:
   case NODE_MATCH3:{
-    VALUE recv;
-    VALUE val;
+    DECL_ANCHOR(recv);
+    DECL_ANCHOR(val);
 
     if(nd_type(node) == NODE_MATCH){
-      recv = NEW_SEQ();
-      ADD_INSN1(recv, nd_line(node), putobject, node->nd_lit);
-      val  = NEW_SEQ();
-      ADD_INSN2(val, nd_line(node), getspecial, I2F(0), I2F(0));
+      ADD_INSN1(&recv, nd_line(node), putobject, node->nd_lit);
+      ADD_INSN2(&val, nd_line(node), getspecial, I2F(0), I2F(0));
     }
     else{
-      recv = COMPILE("reciever", node->nd_recv);
-      val  = COMPILE("value", node->nd_value);
+      COMPILE(&recv, "reciever", node->nd_recv);
+      COMPILE(&val, "value", node->nd_value);
     }
     
-    ret = NEW_SEQ();
 
 #ifdef OPT_REGEXP_MATCH
-    if(RARRAY(recv)->len == 1 &&
-       INSN_OF(RARRAY(recv)->ptr[0]) == BIN(putobject)){
-      ADD_SEQ  (ret, val);
-      ADD_INSN1(ret, nd_line(node), opt_regexpmatch1, OPERAND(RARRAY(RARRAY(recv)->ptr[0]), 0));
+    /* TODO: detect by node */
+    if((&recv)->last == (&recv)->anchor.next &&
+       INSN_OF((&recv)->last) == BIN(putobject)){
+      ADD_SEQ  (ret, &val);
+      ADD_INSN1(ret, nd_line(node), opt_regexpmatch1, OPERAND_AT(recv.last, 0));
     }
     else{
-      ADD_SEQ(ret, recv);
-      ADD_SEQ(ret, val);
+      ADD_SEQ(ret, &recv);
+      ADD_SEQ(ret, &val);
       ADD_INSN(ret, nd_line(node), opt_regexpmatch2);
     }
 #else
-    ADD_SEQ(ret, recv);
-    ADD_SEQ(ret, val);
+    ADD_SEQ(ret, &recv);
+    ADD_SEQ(ret, &val);
     ADD_SEND(ret, nd_line(node), ID2SYM(idEqTilde), INT2FIX(1));
 #endif
     if(poped){
@@ -2841,22 +2924,19 @@
   case NODE_LIT:{
     debugp_param("lit", node->nd_lit);
     if(!poped){
-      ret = NEW_INSN_SEQ1(nd_line(node), putobject, node->nd_lit);
+      ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
     }
     break;
   }
   case NODE_STR:{
     debugp_param("nd_lit", node->nd_lit);
     if(!poped){
-      ret = NEW_INSN_SEQ1(nd_line(node), putstring, node->nd_lit);
+      ADD_INSN1(ret, nd_line(node), putstring, node->nd_lit);
     }
     break;
   }
   case NODE_DSTR:{
-    VALUE dstr = compile_dstr(self, node);
-
-    ret = NEW_SEQ();
-    ADD_SEQ(ret, dstr);
+    VALUE dstr = compile_dstr(self, iseqobj, ret, node);
     
     if(poped){
       ADD_INSN(ret, nd_line(node), pop);
@@ -2864,7 +2944,6 @@
     break;
   }
   case NODE_XSTR:{
-    ret = NEW_SEQ();
     ADD_INSN (ret, nd_line(node), putself);
     ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
     ADD_SEND (ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));
@@ -2875,11 +2954,8 @@
     break;
   }
   case NODE_DXSTR:{
-    VALUE dstr = compile_dstr(self, node);
-    ret = NEW_SEQ();
-    
     ADD_INSN(ret, nd_line(node), putself);
-    ADD_SEQ (ret, dstr);
+    compile_dstr(self, iseqobj, ret, node);
     ADD_SEND(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));
 
     if(poped){
@@ -2888,9 +2964,7 @@
     break;
   }
   case NODE_EVSTR:{
-    VALUE body = COMPILE("nd_body", node->nd_body);
-    ret = NEW_SEQ();
-    ADD_SEQ (ret, body);
+    COMPILE(ret, "nd_body", node->nd_body);
     
     if(poped){
       ADD_INSN(ret, nd_line(node), pop);
@@ -2901,10 +2975,7 @@
     break;
   }
   case NODE_DREGX:{
-    VALUE dstr = compile_dstr(self, node);
-
-    ret = NEW_SEQ();
-    ADD_SEQ(ret, dstr);
+    compile_dstr(self, iseqobj, ret, node);
     ADD_INSN1(ret, nd_line(node), toregexp, I2F(node->nd_cflag));
     
     if(poped){
@@ -2914,10 +2985,7 @@
   }
   case NODE_DREGX_ONCE:{
     /* fix me */
-    VALUE dstr = compile_dstr(self, node);
-
-    ret = NEW_SEQ();
-    ADD_SEQ(ret, dstr);
+    compile_dstr(self, iseqobj, ret, node);
     ADD_INSN1(ret, nd_line(node), toregexp, I2F(node->nd_cflag));
     
     if(poped){
@@ -2933,16 +3001,16 @@
   case NODE_ARGSCAT:{
     NODE *n = node->nd_head;
     int i = 0;
-    ret = NEW_SEQ();
+    
     while(n){
       i++;
-      ADD_SEQ(ret, COMPILE("argscat head", n->nd_head));
+      COMPILE(ret, "argscat head", n->nd_head);
       n = n->nd_next;
     }
     n = node->nd_body;
     while(n){
       i++;
-      ADD_SEQ(ret, COMPILE("argscat body", n->nd_head));
+      COMPILE(ret, "argscat body", n->nd_head);
       n = n->nd_next;
     }
     ADD_INSN1(ret, nd_line(node), newarray, I2F(i));
@@ -2954,7 +3022,7 @@
     break;
   }
   case NODE_SPLAT:{
-    ret = COMPILE("splat", node->nd_head);
+    COMPILE(ret, "splat", node->nd_head);
     break;
   }
   case NODE_TO_ARY:{
@@ -2963,8 +3031,7 @@
     break;
   }
   case NODE_SVALUE:{
-    ret = NEW_SEQ();
-    ADD_SEQ(ret, COMPILE("svalue head", node->nd_head));
+    COMPILE(ret, "svalue head", node->nd_head);
     break;
   }
   case NODE_BLOCK_ARG:{
@@ -2974,18 +3041,16 @@
     break;
   }
   case NODE_BLOCK_PASS:{
-    VALUE prevblock = iseqobj->compile_data->current_block;
-    VALUE retry_label = NEW_LABEL(nd_line(node));
-    VALUE retry_end_l = NEW_LABEL(nd_line(node));
-    VALUE name = rb_str_new2("b@");
-    rb_str_concat(name, iseqobj->name);
+    VALUE prevblock   = iseqobj->compile_data->current_block;
+    LABEL_OBJECT * retry_label = NEW_LABEL(nd_line(node));
+    LABEL_OBJECT * retry_end_l = NEW_LABEL(nd_line(node));
+    DECL_ANCHOR(current_block);
     
-    iseqobj->compile_data->current_block = NEW_SEQ();
-    ADD_SEQ(iseqobj->compile_data->current_block, COMPILE("block pass proc", node->nd_body));
+    iseqobj->compile_data->current_block = (VALUE)&current_block | 1;
+    COMPILE(&current_block, "block pass proc", node->nd_body);
     
-    ret = NEW_SEQ();
     ADD_LABEL(ret, retry_label);
-    ADD_SEQ  (ret, COMPILE_("iter caller (NODE_BLOCK_PASS)", node->nd_iter, poped));
+    COMPILE_ (ret, "iter caller (NODE_BLOCK_PASS)", node->nd_iter, poped);
     ADD_LABEL(ret, retry_end_l);
     
     iseqobj->compile_data->current_block = prevblock;
@@ -2999,7 +3064,6 @@
     
     debugp_param("defn/iseq", iseq);
 
-    ret = NEW_SEQ();
     ADD_INSN2(ret, nd_line(node), methoddef, ID2SYM(node->nd_mid), iseq);
     if(!poped){
       ADD_INSN(ret, nd_line(node), putnil);
@@ -3014,8 +3078,7 @@
 
     debugp_param("defs/iseq", iseq);
 
-    ret = NEW_SEQ();
-    ADD_SEQ  (ret, COMPILE("defs: recv", node->nd_recv));
+    COMPILE(ret, "defs: recv", node->nd_recv);
     ADD_INSN2(ret, nd_line(node), singletonmethoddef, ID2SYM(node->nd_mid), iseq);
     if(!poped){
       ADD_INSN(ret, nd_line(node), putnil);
@@ -3032,7 +3095,6 @@
     s1 = node->u1.node->nd_lit;
     s2 = node->u2.node->nd_lit;
 
-    ret = NEW_SEQ();
     ADD_INSN3(ret, nd_line(node), alias, Qfalse, ID2SYM(rb_to_id(s1)), ID2SYM(rb_to_id(s2)));
     if(!poped){
       ADD_INSN(ret, nd_line(node), putnil);
@@ -3040,7 +3102,6 @@
     break;
   }
   case NODE_VALIAS:{
-    ret = NEW_SEQ();
     ADD_INSN3(ret, nd_line(node), alias, Qtrue, ID2SYM(node->u1.id), ID2SYM(node->u2.id));
     if(!poped){
       ADD_INSN(ret, nd_line(node), putnil);
@@ -3051,7 +3112,6 @@
     if(nd_type(node->u2.node) != NODE_LIT){
       rb_bug("undef args must be NODE_LIT");
     }
-    ret = NEW_SEQ();
     ADD_INSN1(ret, nd_line(node), undef, ID2SYM(rb_to_id(node->u2.node->nd_lit)));
     if(!poped){
       ADD_INSN(ret, nd_line(node), putnil);
@@ -3062,9 +3122,8 @@
     VALUE iseq = NEW_ISEQOBJ(node->nd_body, rb_str_new2("class"),
                              ISEQ_TYPE_CLASS);
     
-    ret = NEW_SEQ();
-    ADD_SEQ  (ret, COMPILE("cbase", node->nd_cpath->nd_head));
-    ADD_SEQ  (ret, COMPILE("super", node->nd_super));
+    COMPILE(ret, "cbase", node->nd_cpath->nd_head);
+    COMPILE(ret, "super", node->nd_super);
     ADD_INSN2(ret, nd_line(node), classdef, ID2SYM(node->nd_cpath->nd_mid), iseq);
     ADD_INSN (ret, nd_line(node), popcref);
     
@@ -3076,8 +3135,7 @@
   case NODE_MODULE:{
     VALUE iseq = NEW_ISEQOBJ(node->nd_body, rb_str_new2("module"),
                              ISEQ_TYPE_CLASS);
-    ret = NEW_SEQ();
-    ADD_SEQ  (ret, COMPILE("mbase", node->nd_cpath->nd_head));
+    COMPILE  (ret, "mbase", node->nd_cpath->nd_head);
     ADD_INSN2(ret, nd_line(node), moduledef, ID2SYM(node->nd_cpath->nd_mid), iseq);
     ADD_INSN (ret, nd_line(node), popcref);
     if(poped){
@@ -3089,8 +3147,7 @@
     VALUE iseq = NEW_ISEQOBJ(node->nd_body, rb_str_new2("singletonclass"),
                              ISEQ_TYPE_CLASS);
 
-    ret = NEW_SEQ();
-    ADD_SEQ  (ret, COMPILE("sclass#recv", node->nd_recv));
+    COMPILE (ret, "sclass#recv", node->nd_recv);
     ADD_INSN1(ret, nd_line(node), singletonclassdef, iseq);
     if(poped){
       ADD_INSN(ret, nd_line(node), pop);
@@ -3098,34 +3155,34 @@
     break;
   }
   case NODE_COLON2:{
-    ret = NEW_SEQ();
     
     if(rb_is_const_id(node->nd_mid)){
       /* constant */
       debugi("nd_mid", node->nd_mid);
       if(iseqobj->compile_data->cached_const == Qfalse){
-        VALUE lstart = NEW_LABEL(nd_line(node));
-        VALUE lend   = NEW_LABEL(nd_line(node));
+        LABEL_OBJECT * lstart = NEW_LABEL(nd_line(node));
+        LABEL_OBJECT * lend   = NEW_LABEL(nd_line(node));
+        
         /* add cache insn */
         iseqobj->compile_data->cached_const = Qtrue;
         ADD_LABEL(ret, lstart);
         ADD_INSN2(ret, nd_line(node), getinlinecache, NEW_INLINE_CACHE_ENTRY(), lend);
         ADD_INSN (ret, nd_line(node), pop);
-        ADD_SEQ(ret, COMPILE("colon2#nd_head", node->nd_head));
+        COMPILE  (ret, "colon2#nd_head", node->nd_head);
         ADD_INSN1(ret, nd_line(node), getconstant, ID2SYM(node->nd_mid));
         ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
         ADD_LABEL(ret, lend);
         iseqobj->compile_data->cached_const = Qfalse;
       }
       else{
-        ADD_SEQ(ret, COMPILE("colon2#nd_head", node->nd_head));
+        COMPILE(ret, "colon2#nd_head", node->nd_head);
         ADD_INSN1(ret, nd_line(node), getconstant, ID2SYM(node->nd_mid));
       }
     }
     else{
       /* function call */
       ADD_INSN(ret, nd_line(node), putself);
-      ADD_SEQ (ret, COMPILE("colon2#nd_head", node->nd_head));
+      COMPILE (ret, "colon2#nd_head", node->nd_head);
       ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_mid), INT2FIX(1));
     }
     if(poped){
@@ -3135,10 +3192,9 @@
   }
   case NODE_COLON3:{
     debugi("colon3#nd_mid", node->nd_mid);
-    ret = NEW_SEQ();
     if(iseqobj->compile_data->cached_const == Qfalse){
-      VALUE lstart = NEW_LABEL(nd_line(node));
-      VALUE lend   = NEW_LABEL(nd_line(node));
+      LABEL_OBJECT * lstart = NEW_LABEL(nd_line(node));
+      LABEL_OBJECT * lend   = NEW_LABEL(nd_line(node));
 
       /* add cache insn */
       ADD_LABEL(ret, lstart);
@@ -3167,27 +3223,24 @@
   case NODE_DOT3:{
     int flag = type == NODE_DOT2 ? INT2FIX(0) : INT2FIX(1);
     if(!poped){
-      ret = NEW_SEQ();
-      ADD_SEQ  (ret, COMPILE("min", (NODE*)node->nd_lit));
-      ADD_SEQ  (ret, COMPILE("max", (NODE*)node->nd_end));
+      COMPILE(ret, "min", (NODE*)node->nd_lit);
+      COMPILE(ret, "max", (NODE*)node->nd_end);
       ADD_INSN1(ret, nd_line(node), newrange, flag);
     }
     break;
   }
   case NODE_FLIP2:
   case NODE_FLIP3:{
-    VALUE lend, lfin, ltrue, lfalse;
-    lend   = NEW_LABEL(nd_line(node));
-    lfin   = NEW_LABEL(nd_line(node));
-    ltrue  = NEW_LABEL(nd_line(node));
-    lfalse = NEW_LABEL(nd_line(node));
+    LABEL_OBJECT * lend   = NEW_LABEL(nd_line(node));
+    LABEL_OBJECT * lfin   = NEW_LABEL(nd_line(node));
+    LABEL_OBJECT * ltrue  = NEW_LABEL(nd_line(node));
+    LABEL_OBJECT * lfalse = NEW_LABEL(nd_line(node));
     
-    ret = NEW_SEQ();
     ADD_INSN2(ret, nd_line(node), getspecial, I2F(node->nd_cnt), I2F(0));
     ADD_INSNL(ret, nd_line(node), if, lend);
 
     /* *flip == 0 */
-    ADD_SEQ  (ret, COMPILE("flip2 beg", node->nd_beg));
+    COMPILE  (ret, "flip2 beg", node->nd_beg);
     ADD_INSN (ret, nd_line(node), dup);
     ADD_INSNL(ret, nd_line(node), unless, lfin);
     if(nd_type(node) == NODE_FLIP3){
@@ -3201,7 +3254,7 @@
 
     /* *flip == 1 */
     ADD_LABEL(ret, lend);
-    ADD_SEQ  (ret, COMPILE("flip2 end", node->nd_end));
+    COMPILE  (ret, "flip2 end", node->nd_end);
     ADD_INSNL(ret, nd_line(node), unless, ltrue);
     ADD_INSN1(ret, nd_line(node), putobject, Qfalse);
     ADD_INSN2(ret, nd_line(node), setspecial, I2F(node->nd_cnt), I2F(0));
@@ -3220,32 +3273,31 @@
   }
   case NODE_SELF:{
     if(!poped){
-      ret = NEW_INSN_SEQ(nd_line(node), putself);
+      ADD_INSN(ret, nd_line(node), putself);
     }
 
     break;
   }
   case NODE_NIL:{
     if(!poped){
-      ret = NEW_INSN_SEQ(nd_line(node), putnil);
+      ADD_INSN(ret, nd_line(node), putnil);
     }
     break;
   }
   case NODE_TRUE:{
     if(!poped){
-      ret = NEW_INSN_SEQ1(nd_line(node), putobject, Qtrue);
+      ADD_INSN1(ret, nd_line(node), putobject, Qtrue);
     }
     break;
   }
   case NODE_FALSE:{
     if(!poped){
-      ret = NEW_INSN_SEQ1(nd_line(node), putobject, Qfalse);
+      ADD_INSN1(ret, nd_line(node), putobject, Qfalse);
     }
     break;
   }
   case NODE_ERRINFO:{
     if(!poped){
-      ret = NEW_SEQ();
       if(iseqobj->type == ISEQ_TYPE_RESCUE){
         ADD_INSN2(ret, nd_line(node), getdynamic, I2F(1), I2F(0));
       }
@@ -3256,10 +3308,9 @@
     break;
   }
   case NODE_DEFINED:{
-    ret = NEW_SEQ();
     if(!poped){
-      VALUE lfinish = NEW_LABEL(nd_line(node));
-      defined_expr(self, node->nd_head, ret, lfinish, Qtrue);
+      LABEL_OBJECT * lfinish = NEW_LABEL(nd_line(node));
+      defined_expr(self, iseqobj, ret, node->nd_head, lfinish, Qtrue);
       ADD_LABEL(ret, lfinish);
     }
     break;
@@ -3291,10 +3342,7 @@
     break;
   }
   case NODE_DSYM:{
-    VALUE dstr = compile_dstr(self, node);
-
-    ret = NEW_SEQ();
-    ADD_SEQ (ret, dstr);
+    compile_dstr(self, iseqobj, ret, node);
     if(!poped){
       ADD_SEND(ret, nd_line(node), ID2SYM(idIntern), I2F(0));
     }
@@ -3304,36 +3352,30 @@
     break;
   }
   case NODE_ATTRASGN:{
-    VALUE recv;
-    VALUE args; 
+    DECL_ANCHOR(recv);
+    DECL_ANCHOR(args);
     VALUE argc;
-    VALUE argcv;
 
     if(node->nd_args){
-      args = compile_array(self, node->nd_args, Qfalse);
-      argcv = rb_ary_pop(args);
-      argc = OPERAND(argcv, 0);
+      compile_array(self, iseqobj, &args, node->nd_args, Qfalse);
+      argc = OPERAND_AT(POP_ELEMENT(&args), 0);
     }
     else{
-      args = rb_ary_new();
       argc = I2F(0); /* massign */
     }
     
     if(node->nd_recv == (NODE *)1){
-      recv = NEW_INSN_SEQ(nd_line(node), putself);
+      ADD_INSN(&recv, nd_line(node), putself);
     }
     else{
-      recv = COMPILE("recv", node->nd_recv);
+      COMPILE(&recv, "recv", node->nd_recv);
     }
     
-    debugp_param("nd_recv", recv);
-    debugp_param("nd_args", args);
     debugp_param("argc"   , argc);
     debugp_param("nd_mid",  ID2SYM(node->nd_mid));
     
-    ret = NEW_SEQ();
-    ADD_SEQ(ret, recv);
-    ADD_SEQ(ret, args);
+    ADD_SEQ(ret, &recv);
+    ADD_SEQ(ret, &args);
 
     ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_mid), argc);
 
@@ -3348,7 +3390,7 @@
   }
 
   debug_nodeprint_close();
-  return ret;
+  return COMPILE_OK;
 }
 
 
@@ -3456,17 +3498,25 @@
 
       switch(type){
       case 'L':          /* label(destination position) */
+        {
+          char  buff[0x100];
+          LABEL_OBJECT *lobj = (LABEL_OBJECT *)OPERAND_AT(insnobj, j);
+          snprintf(buff, sizeof(buff), "<L%03d>", lobj->label_no);
+          rb_str_concat(str, rb_str_new2(buff));
+          break;
+        }
+        break;
       case 'U':          /* ulong */
       case 'V':          /* VALUE */
-        rb_str_concat(str, rb_inspect(RARRAY(insnobj->operands)->ptr[j]));
+        rb_str_concat(str, rb_inspect(OPERAND_AT(insnobj, j)));
         break;
       case 'I':          /* ID */
-        rb_str_concat(str, rb_inspect(RARRAY(insnobj->operands)->ptr[j]));
+        rb_str_concat(str, rb_inspect(OPERAND_AT(insnobj, j)));
         break;
       case 'G':
         {
           struct global_entry *entry = (struct global_entry*)
-            (RARRAY(insnobj->operands)->ptr[j] & (~1));
+            (OPERAND_AT(insnobj, j) & (~1));
           rb_str_cat2(str, rb_id2name(entry->id));
         }
       case 'M': /* method cache */

Modified: trunk/compile.h
===================================================================
--- trunk/compile.h	2005-06-13 22:51:03 UTC (rev 169)
+++ trunk/compile.h	2005-06-21 13:39:40 UTC (rev 170)
@@ -26,7 +26,10 @@
  * 10: show every AST array
  */
 
-// #define CPDEBUG 2
+#if 0
+#undef  CPDEBUG
+#define CPDEBUG 6
+#endif
 
 #if CPDEBUG > 0
 
@@ -72,97 +75,55 @@
 #endif
 
 
-/* create empty sequence */
-#define NEW_SEQ()                           \
-  (GC_CHECK(), debugp_verbose_node("new_seq", -1),  \
-   rb_ary_new())
-
 /* create new label */
-#define NEW_LABEL(l)                 \
-  (GC_CHECK(), new_label(l))
+#define NEW_LABEL(l) new_label_body(iseqobj, l)
 
-/* create insns sequence with 1 insn */
-#define NEW_INSN_SEQ(line, insn)     \
-  (tmp = NEW_SEQ(),                  \
-   ADD_INSN(tmp, line, insn),        \
-   debugp_verbose_node("new_insn_seq", tmp))
-
-/* create insns sequence with an insn and an operand */
-#define NEW_INSN_SEQ1(line, insn, op1)  \
-  (tmp = NEW_SEQ(),                     \
-   ADD_INSN1(tmp, line, insn, op1),     \
-   debugp_verbose_node("new_insn_seq1", tmp))
-
 #define iseq_filename(iseq) \
   (((struct iseq_object*)DATA_PTR(iseq))->file_name)
 
 #define NEW_ISEQOBJ(node, name, type)       \
   NEW_CHILD_ISEQOBJ(node, name, 0, type)
 
-
 #define NEW_CHILD_ISEQOBJ(node, name, parent, type)       \
-  (lv            = gl_node_level,                         \
-   gl_node_level = 0,                                     \
-   args[0]       = (VALUE)node,                           \
-   args[1]       = name,                                  \
-   args[2]       = iseq_filename(self),                   \
-   args[3]       = parent,                                \
-   args[4]       = type,                                  \
-   gl_tmp        = rb_class_new_instance(5, args,         \
-                                         cYarvISeq),      \
-   gl_node_level = lv,                                    \
-   gl_tmp)
+  new_child_iseq(self, iseqobj, node, name, parent, type)
 
 /* add instructions */
-#define ADD_SEQ(seq, seq2)    \
-  (rb_ary_push(seq, seq2),  \
-   debugp_verbose_node("add_seq", seq))
+#define ADD_SEQ(seq1, seq2) \
+  APPEND_LIST(seq1, seq2)
 
 /* add an instruction */
-#define ADD_INSN(seq, line, insn)                       \
-  (rb_ary_push(seq, new_insn(BIN(insn), line, Qfalse)), \
-   debugp_verbose_node("add_insn", seq))
+#define ADD_INSN(seq, line, insn) \
+  ADD_LINKED_LIST(seq, (struct iseq_link_element *) new_insn_body(iseqobj, line, BIN(insn), 0))
 
 /* add an instruction with label operand */
-#define ADD_INSNL(seq, line, insn, label)                              \
-  (rb_ary_push(seq, new_insn(BIN(insn), line, rb_ary_new3(1, label))), \
-   debugp_verbose_node("add_insnl", seq))
+#define ADD_INSNL(seq, line, insn, label) \
+  ADD_LINKED_LIST(seq, (struct iseq_link_element *) new_insn_body(iseqobj, line, BIN(insn), 1, label))
 
-/* add an instruction with an operand */
-#define ADD_INSN1(seq, line, insn, op1)                              \
-  (rb_ary_push(seq, new_insn(BIN(insn), line, rb_ary_new3(1, op1))), \
-   debugp_verbose_node("add_insn1", seq))
+/* add an instruction with some operands (1, 2, 3, 5) */
+#define ADD_INSN1(seq, line, insn, op1) \
+  ADD_LINKED_LIST(seq, (struct iseq_link_element *) new_insn_body(iseqobj, line, BIN(insn), 1, op1))
 
-/* add an instruction with two operands */
-#define ADD_INSN2(seq, line, insn, op1, op2)             \
-  (rb_ary_push(seq, new_insn(BIN(insn), line,            \
-                             rb_ary_new3(2, op1, op2))), \
-   debugp_verbose_node("add_insn2", seq))
+#define ADD_INSN2(seq, line, insn, op1, op2) \
+  ADD_LINKED_LIST(seq, (struct iseq_link_element *) new_insn_body(iseqobj, line, BIN(insn), 2, op1, op2))
 
 #define ADD_INSN3(seq, line, insn, op1, op2, op3)             \
-  (rb_ary_push(seq, new_insn(BIN(insn), line,                 \
-                             rb_ary_new3(3, op1, op2, op3))), \
-   debugp_verbose_node("add_insn3", seq))
+  ADD_LINKED_LIST(seq, (struct iseq_link_element *) new_insn_body(iseqobj, line, BIN(insn), 3, op1, op2, op3))
 
-#define ADD_INSN5(seq, line, insn, o1, o2, o3, o4, o5)             \
-  (rb_ary_push(seq, new_insn(BIN(insn), line,                      \
-                             rb_ary_new3(5, o1, o2, o3, o4, o5))), \
-   debugp_verbose_node("add_insn5", seq))
-
-
+#define ADD_INSN5(seq, line, insn, o1, o2, o3, o4, o5) \
+  ADD_LINKED_LIST(seq, (struct iseq_link_element *) new_insn_body(iseqobj, line, BIN(insn), 5, \
+                                                                  o1, o2, o3, o4, o5))
 /* add label */
 #define ADD_LABEL(seq, label) \
-  (rb_ary_push(seq, label),   \
-   debugp_verbose_node("add_label", seq))  \
+  ADD_LINKED_LIST(seq, (struct iseq_link_element *)label)
 
 #define ADD_CATCH_ENTRY(type, ls, le, iseq, sp, lc) \
   (tmp = rb_ary_new(),                              \
    rb_ary_push(tmp, type),                          \
-   rb_ary_push(tmp, ls),                            \
-   rb_ary_push(tmp, le),                            \
+   rb_ary_push(tmp, (VALUE) ls | 1),                \
+   rb_ary_push(tmp, (VALUE) le | 1),                \
    rb_ary_push(tmp, iseq),                          \
    rb_ary_push(tmp, I2F(sp)),                       \
-   rb_ary_push(tmp, lc),                            \
+   rb_ary_push(tmp, (VALUE) lc | 1),                \
    rb_ary_push(iseqobj->catch_table_ary, tmp))
 
 
@@ -176,37 +137,28 @@
 
 
 /* compile node */
-#define COMPILE(desc, node) \
+#define COMPILE(anchor, desc, node) \
   (debugs("== " desc "\n"), \
-   iseq_compile_each(self, node, 0))
+   iseq_compile_each(self, anchor, node, 0))
 
 /* compile node, this node's value will be poped */
-#define COMPILE_POPED(desc, node)    \
+#define COMPILE_POPED(anchor, desc, node)    \
   (debugs("== " desc "\n"),          \
-   iseq_compile_each(self, node, 1))
+   iseq_compile_each(self, anchor, node, 1))
 
 /* compile node, which is poped when 'poped' is true */
-#define COMPILE_(desc, node, poped)  \
+#define COMPILE_(anchor, desc, node, poped)  \
   (debugs("== " desc "\n"),          \
-   iseq_compile_each(self, node, poped))
+   iseq_compile_each(self, anchor, node, poped))
 
-#define INSN_CODE(insn_obj) \
-  (((struct insn_object*)DATA_PTR(insn_obj))->insn_code)
+#define OPERAND_AT(insn, idx) \
+  (((INSN_OBJECT*)(insn))->operands[idx])
 
-#define OPERAND(insn_obj, i) \
-  (RARRAY(((struct insn_object*)DATA_PTR(insn_obj))->operands)->ptr[i])
-
-#define OPERAND_OF_RAW(insn_obj, i) \
-  (RARRAY(insn_obj->operands)->ptr[i])
-
 #define INSN_OF(insn) \
-  (((struct insn_object*)DATA_PTR(insn))->insn_id)
+  (((INSN_OBJECT*)(insn))->insn_id)
      
 #define I2F(x) INT2FIX(x)
 
-static VALUE new_insn(int insn, int line_no, VALUE operands);
-
-
 /* error */
 #define COMPILE_ERROR(strs)                        \
 {                                                  \
@@ -221,5 +173,11 @@
 }
 
 
+#define COMPILE_OK 1
+#define COMPILE_NG 0
+
+#define DECL_ANCHOR(name) \
+  ISEQ_LINK_ANCHOR name = {{0,}, &name.anchor}
+
 #endif	// _COMPILER_H_INCLUDED_
 

Modified: trunk/disasm.c
===================================================================
--- trunk/disasm.c	2005-06-13 22:51:03 UTC (rev 169)
+++ trunk/disasm.c	2005-06-21 13:39:40 UTC (rev 170)
@@ -293,6 +293,7 @@
     }
     link = link->next;
   }
+  printf("---------------------\n");
   return Qtrue;
 }
 

Modified: trunk/rb/insns2vm.rb
===================================================================
--- trunk/rb/insns2vm.rb	2005-06-13 22:51:03 UTC (rev 169)
+++ trunk/rb/insns2vm.rb	2005-06-21 13:39:40 UTC (rev 170)
@@ -743,26 +743,30 @@
       }.each{|opti|
         rule += "  if(\n"
         i = 0
-        rule += '      ' + opti.defopes.map{|opinfo|
+        rule += '    ' + opti.defopes.map{|opinfo|
           i += 1
           next if opinfo[1] == '*'
-          ["GET_OPERAND(#{i-1}) == #{val_as_type(opinfo)}\n"]
-        }.compact.join('  &&  ')
+          "insnobj->operands[#{i-1}] == #{val_as_type(opinfo)}\n"
+        }.compact.join('&&  ')
         rule += "  ){\n"
-          idx = 0
-          n = 0
-          opti.defopes.each{|opinfo|
-            if opinfo[1] == '*'
-              idx += 1
-            else
-              rule += "  rb_ary_delete_at(insnobj->operands, #{idx});\n"
+        idx = 0
+        n = 0
+        opti.defopes.each{|opinfo|
+          if opinfo[1] == '*'
+            if idx != n
+              rule += "    insnobj->operands[#{idx}] = insnobj->operands[#{n}];\n"
             end
-            n += 1
-          }
-          rule += "  self = new_insn(BIN(#{opti.name}), insnobj->line_no, insnobj->operands);\n"
-        rule += "  break;}\n"
+            idx += 1
+          else
+            # skip
+          end
+          n += 1
+        }
+        rule += "    insnobj->insn_id = BIN(#{opti.name});\n"
+        rule += "    insnobj->operand_size = #{idx};\n"
+        rule += "    break;\n  }\n"
       }
-      rule += "break;\n";
+      rule += "  break;\n";
     }
     ERB.new(File.read($srcdir + '/tmpl/optinsn.inc.tmpl')).result(binding)
   end

Modified: trunk/test.rb
===================================================================
--- trunk/test.rb	2005-06-13 22:51:03 UTC (rev 169)
+++ trunk/test.rb	2005-06-21 13:39:40 UTC (rev 170)
@@ -9,6 +9,31 @@
 ###########################################################
 $prog =<<'__EOP__'
 
+i=0
+while i<100
+  i+=1
+  #a = [1,2,3,4,5,6,7,8,9,10]
+end
+
+__END__
+
+def m
+        /a(b)(c)d/ =~ 'xyzabcdefgabcdefg'
+        [$1, $2, $3, $~.class, $&, $`, $', $+]
+      end
+      m
+
+__END__
+a = 1
+b = 2
+a, b = b, a
+[a, b]
+__END__
+for i in [1, 2, 3]
+  p i
+end
+
+__END__
       sum = 0
       for x in [1, 2, 3]
         sum += x

Modified: trunk/tmpl/optinsn.inc.tmpl
===================================================================
--- trunk/tmpl/optinsn.inc.tmpl	2005-06-13 22:51:03 UTC (rev 169)
+++ trunk/tmpl/optinsn.inc.tmpl	2005-06-21 13:39:40 UTC (rev 170)
@@ -12,24 +12,16 @@
   or rb/insns2vm.rb
  */
 
-#define GET_OPERAND(n) (RARRAY(insnobj->operands)->ptr[(n)])
-
-static VALUE insn_optimize(VALUE self){
-  struct insn_object *insnobj;
-  GetInsnVal(self, insnobj);
-
+static INSN_OBJECT *insn_optimize(INSN_OBJECT *insnobj){
   /* optimize rule */
   switch(insnobj->insn_id){
+
 <%= rule %>
 
   default:
     /* do nothing */;
+    break;
   }
-  
-  return self;
+  return insnobj;
 }
 
-#undef GET_OPERAND
-
-
-

Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c	2005-06-13 22:51:03 UTC (rev 169)
+++ trunk/yarvcore.c	2005-06-21 13:39:40 UTC (rev 170)
@@ -282,6 +282,19 @@
 /* InstructionSequence */
 /***********************/
 
+static void compile_data_free(struct iseq_compile_data *compile_data){
+  if(compile_data){
+    struct iseq_compile_data_storage *cur, *next;
+    cur = compile_data->storage_head;
+    while(cur){
+      next = cur->next;
+      ruby_xfree(cur);
+      cur = next;
+    }
+    ruby_xfree(compile_data);
+  }
+}
+
 static void iseq_free(void *ptr){
   struct iseq_object *iseqobj;
   
@@ -295,7 +308,7 @@
     FREE_UNLESS_NULL(iseqobj->local_tbl);
     FREE_UNLESS_NULL(iseqobj->catch_table);
     FREE_UNLESS_NULL(iseqobj->arg_opt_tbl);
-    FREE_UNLESS_NULL(iseqobj->compile_data);
+    compile_data_free(iseqobj->compile_data);
     ruby_xfree(ptr);
   }
 }
@@ -312,10 +325,7 @@
     MARK_UNLESS_NULL((VALUE)iseqobj->node);
     
     if(iseqobj->compile_data != 0){
-      MARK_UNLESS_NULL(iseqobj->compile_data->current_block);
-      MARK_UNLESS_NULL(iseqobj->compile_data->start_label);
-      MARK_UNLESS_NULL(iseqobj->compile_data->end_label);
-      MARK_UNLESS_NULL(iseqobj->compile_data->redo_label);
+      MARK_UNLESS_NULL(iseqobj->compile_data->mark_ary);
       MARK_UNLESS_NULL(iseqobj->compile_data->err_info);
     }
   }
@@ -346,7 +356,18 @@
 
   iseqobj->compile_data    = ALLOC_N(struct iseq_compile_data, 1);
   MEMZERO(iseqobj->compile_data, struct iseq_compile_data, 1);
+  iseqobj->compile_data->mark_ary = rb_ary_new();
   
+  iseqobj->compile_data->storage_head = iseqobj->compile_data->storage_current =
+    (struct iseq_compile_data_storage *)
+      ALLOC_N(char, INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE +
+              sizeof(struct iseq_compile_data_storage));
+  
+  iseqobj->compile_data->storage_head->pos  = 0;
+  iseqobj->compile_data->storage_head->next = 0;
+  iseqobj->compile_data->storage_head->size = INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE;
+  iseqobj->compile_data->storage_head->buff = (char *)(&iseqobj->compile_data->storage_head->buff + 1);
+  
   if(parent && CLASS_OF(parent) == cYarvISeq){
     struct iseq_object *piseqobj;
     GetISeqVal(parent, piseqobj);
@@ -357,7 +378,7 @@
   
   err = iseqobj->compile_data->err_info;
   
-  ruby_xfree(iseqobj->compile_data);
+  compile_data_free(iseqobj->compile_data);
   iseqobj->compile_data = 0;
 
   if(ruby_nerrs > 0){
@@ -442,9 +463,6 @@
   struct insn_object *insnobj;
   if(ptr){
     insnobj = ptr;
-    if(insnobj->operands){
-      rb_gc_mark(insnobj->operands);
-    }
   }
 }
 
@@ -457,14 +475,7 @@
 }
 
 static VALUE insn_init(VALUE self, int insn_id, int line_no, VALUE operands){
-  struct insn_object *insnobj;
-  Data_Get_Struct(self, struct insn_object, insnobj);
-  insnobj->link.type = ISEQ_ELEMENT_INSN;
-  insnobj->link.next = 0;
-  insnobj->insn_id  = insn_id;
-  insnobj->line_no  = line_no;
-  insnobj->operands = operands; /* 0 or RArray */
-  insnobj->sc_state = 0;
+  rb_bug("unsuppoted");
   return self;
 }
 
@@ -504,9 +515,7 @@
 }
 
 static VALUE insn_operands(VALUE self){
-  struct insn_object *insnobj;
-  GetInsnVal(self, insnobj);
-  return insnobj->operands;
+  return Qnil;
 }
 
 

Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h	2005-06-13 22:51:03 UTC (rev 169)
+++ trunk/yarvcore.h	2005-06-21 13:39:40 UTC (rev 170)
@@ -56,32 +56,35 @@
 #define ISEQ_ELEMENT_INSN  INT2FIX(0x02)
 #define ISEQ_ELEMENT_SEQ   INT2FIX(0x03)
 
-struct iseq_link_element{
+typedef struct iseq_link_element{
   int type;
   struct iseq_link_element *next;
   struct iseq_link_element *prev;
-};
+} ISEQ_LINK_ELEMENT;
 
-struct label_object{
+
+typedef struct label_object{
   struct iseq_link_element link;
   int label_no;
   long position;
   unsigned long sc_state;
   VALUE set;
-};
+} LABEL_OBJECT;
 
 
 #define GetInsnVal(obj, iobj) \
   Data_Get_Struct(obj, struct insn_object, iobj)
 
-struct insn_object{
+typedef struct insn_object{
   struct iseq_link_element link;
   int insn_id;
   unsigned long line_no;
-  VALUE operands;
-  unsigned long sc_state;
-};
+  VALUE *operands;
+  unsigned int operand_size;
+  unsigned int sc_state;
+} INSN_OBJECT;
 
+
 #define GetISeqVal(obj, tobj) \
   Data_Get_Struct(obj, struct iseq_object, tobj)
 
@@ -110,18 +113,36 @@
   unsigned long cont;
 };
 
+#define INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE (1024)
+
+struct iseq_compile_data_storage{
+  struct iseq_compile_data_storage *next;
+  unsigned long pos;
+  unsigned long size;
+  char *buff;
+};
+
+typedef struct iseq_link_anchor{
+  ISEQ_LINK_ELEMENT anchor;
+  ISEQ_LINK_ELEMENT *last;
+} ISEQ_LINK_ANCHOR;
+
 struct iseq_compile_data{
   /* GC is needed */
-  VALUE current_block;
-  VALUE start_label;
-  VALUE end_label;
-  VALUE redo_label;
   VALUE err_info;
+  VALUE mark_ary;
 
   /* GC is not needed */
+  LABEL_OBJECT* start_label;
+  LABEL_OBJECT* end_label;
+  LABEL_OBJECT* redo_label;
+  VALUE current_block;
   VALUE loopval_popped;  /* used by NODE_BREAK */
   VALUE in_ensure;       /* used by NODE_RETURN */
   int   cached_const;
+
+  struct iseq_compile_data_storage *storage_head;
+  struct iseq_compile_data_storage *storage_current;
 };
 
 struct iseq_object{


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

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