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)¤t_block | 1;
+ COMPILE(¤t_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