From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS49544 128.204.192.0/20 X-Spam-Status: No, score=-0.4 required=3.0 tests=AWL,BAYES_40,RCVD_IN_XBL, RDNS_NONE,URIBL_BLOCKED shortcircuit=no autolearn=no version=3.3.2 X-Original-To: spew@80x24.org Received: from 80x24.org (unknown [128.204.203.78]) by dcvr.yhbt.net (Postfix) with ESMTP id CBCCC1F61A for ; Wed, 17 Jun 2015 23:46:06 +0000 (UTC) From: Eric Wong To: spew@80x24.org Subject: [PATCH] compile.c: convert to use ccan/list Date: Wed, 17 Jun 2015 23:46:02 +0000 Message-Id: <1434584762-16467-1-git-send-email-e@80x24.org> List-Id: This reduces lines of code, reduces stack usage due to smaller anchor (replaced with list_head), but unfortunately also makes the compiled binary bigger. On x86-64 (gcc 4.7.2) text data bss dec hex filename 99076 1480 152 100708 18964 compile.o 93110 1480 152 94742 17216 compile.o-orig scripts/checkstack.pl in Linux kernel shows reductions in some functions as well as fewer functions having over 100: before: 1 0x00002fb3 iseq_compile_each [compile]: 1224 2 0x000030d8 iseq_compile_each [compile]: 1224 3 0x00012a33 rb_iseq_build_from_ary [compile]: 392 4 0x00013d3d rb_iseq_build_from_ary [compile]: 392 5 0x00011030 setup_args [compile]: 152 6 0x000114f7 setup_args [compile]: 152 7 0x000116ad rb_iseq_compile_node [compile]: 152 8 0x00011dcb rb_iseq_compile_node [compile]: 152 9 0x00000bc0 iseq_set_sequence [compile]: 104 10 0x00000f20 iseq_set_sequence [compile]: 104 11 0x00002116 new_insn_body [compile]: 104 12 0x00002271 new_insn_body [compile]: 104 13 0x0000f391 compile_massign_opt_lhs [compile]: 104 14 0x0000f520 compile_massign_opt_lhs [compile]: 104 15 0x0000f54e compile_massign_opt_lhs [compile]: 104 16 0x0000f56d add_ensure_iseq [compile]: 104 17 0x0000f8b0 add_ensure_iseq [compile]: 104 18 0x000103e3 defined_expr [compile]: 104 19 0x000106ab defined_expr [compile]: 104 after: 1 0x00002f33 iseq_compile_each [compile]: 1032 2 0x00003070 iseq_compile_each [compile]: 1032 3 0x00013f93 rb_iseq_build_from_ary [compile]: 392 4 0x00015f14 rb_iseq_build_from_ary [compile]: 392 5 0x00012a5d rb_iseq_compile_node [compile]: 152 6 0x0001336b rb_iseq_compile_node [compile]: 152 7 0x00012450 setup_args [compile]: 120 8 0x000128f3 setup_args [compile]: 120 9 0x00000c20 iseq_set_sequence [compile]: 104 10 0x00000fad iseq_set_sequence [compile]: 104 11 0x00002766 new_insn_body [compile]: 104 12 0x000028b9 new_insn_body [compile]: 104 13 0x00010651 compile_massign_opt_lhs [compile]: 104 14 0x000107e0 compile_massign_opt_lhs [compile]: 104 15 0x0001080e compile_massign_opt_lhs [compile]: 104 16 0x00011733 defined_expr [compile]: 104 17 0x00011a10 defined_expr [compile]: 104 --- compile.c | 451 +++++++++++++++++++++----------------------------------------- 1 file changed, 152 insertions(+), 299 deletions(-) diff --git a/compile.c b/compile.c index 6757ea3..144018e 100644 --- a/compile.c +++ b/compile.c @@ -32,15 +32,9 @@ typedef struct iseq_link_element { ISEQ_ELEMENT_INSN, ISEQ_ELEMENT_ADJUST } type; - struct iseq_link_element *next; - struct iseq_link_element *prev; + struct list_node iseq_node; } LINK_ELEMENT; -typedef struct iseq_link_anchor { - LINK_ELEMENT anchor; - LINK_ELEMENT *last; -} LINK_ANCHOR; - typedef struct iseq_label_data { LINK_ELEMENT link; int label_no; @@ -303,13 +297,8 @@ r_value(VALUE value) #define COMPILE_OK 1 #define COMPILE_NG 0 - -/* leave name uninitialized so that compiler warn if INIT_ANCHOR is - * missing */ #define DECL_ANCHOR(name) \ - LINK_ANCHOR *name, name##_body__ = {{0,},} -#define INIT_ANCHOR(name) \ - (name##_body__.last = &name##_body__.anchor, name = &name##_body__) + LIST_HEAD(name##_body__); struct list_head *name = &name##_body__ #define hide_obj(obj) do {OBJ_FREEZE(obj); RBASIC_CLEAR_CLASS(obj);} while (0) @@ -331,7 +320,7 @@ r_value(VALUE value) #define gl_node_level iseq->compile_data->node_level #endif -static void dump_disasm_list(LINK_ELEMENT *elem); +static void dump_disasm_list(struct list_head *anchor, LINK_ELEMENT *elem); static int insn_data_length(INSN *iobj); static int calc_sp_depth(int depth, INSN *iobj); @@ -340,80 +329,36 @@ static INSN *new_insn_body(rb_iseq_t *iseq, int line_no, enum ruby_vminsn_type i static LABEL *new_label_body(rb_iseq_t *iseq, long line); static ADJUST *new_adjust_body(rb_iseq_t *iseq, LABEL *label, int line); -static int iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *anchor, NODE * n, int); -static int iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *anchor); -static int iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *anchor); -static int iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *anchor); +static int iseq_compile_each(rb_iseq_t *iseq, struct list_head *anchor, NODE * n, int); +static int iseq_setup(rb_iseq_t *iseq, struct list_head *anchor); +static int iseq_optimize(rb_iseq_t *iseq, struct list_head *anchor); +static int iseq_insns_unification(rb_iseq_t *iseq, struct list_head *anchor); static int iseq_set_local_table(rb_iseq_t *iseq, const ID *tbl); static int iseq_set_exception_local_table(rb_iseq_t *iseq); -static int iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *anchor, NODE * node); +static int iseq_set_arguments(rb_iseq_t *iseq, struct list_head *anchor, NODE * node); -static int iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor); -static int iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor); +static int iseq_set_sequence_stackcaching(rb_iseq_t *iseq, struct list_head *anchor); +static int iseq_set_sequence(rb_iseq_t *iseq, struct list_head *anchor); static int iseq_set_exception_table(rb_iseq_t *iseq); static int iseq_set_optargs_table(rb_iseq_t *iseq); /* - * To make Array to LinkedList, use link_anchor - */ - -static void -verify_list(ISEQ_ARG_DECLARE const char *info, LINK_ANCHOR *anchor) -{ -#if CPDEBUG - int flag = 0; - LINK_ELEMENT *list, *plist; - - if (!compile_debug) return; - - list = anchor->anchor.next; - plist = &anchor->anchor; - while (list) { - if (plist != list->prev) { - flag += 1; - } - plist = list; - list = list->next; - } - - if (anchor->last != plist && anchor->last != 0) { - flag |= 0x70000; - } - - if (flag != 0) { - rb_bug("list verify error: %08x (%s)", flag, info); - } -#endif -} -#if CPDEBUG < 0 -#define verify_list(info, anchor) verify_list(iseq, (info), (anchor)) -#endif - -/* * elem1, elem2 => elem1, elem2, elem */ static void -ADD_ELEM(ISEQ_ARG_DECLARE LINK_ANCHOR *anchor, LINK_ELEMENT *elem) +ADD_ELEM(ISEQ_ARG_DECLARE struct list_head *anchor, LINK_ELEMENT *elem) { - elem->prev = anchor->last; - anchor->last->next = elem; - anchor->last = elem; - verify_list("add", anchor); + list_add_tail(anchor, &elem->iseq_node); } /* * elem1, before, elem2 => elem1, before, elem, elem2 */ static void -APPEND_ELEM(ISEQ_ARG_DECLARE LINK_ANCHOR *anchor, LINK_ELEMENT *before, LINK_ELEMENT *elem) +APPEND_ELEM(ISEQ_ARG_DECLARE struct list_head *anchor, LINK_ELEMENT *before, LINK_ELEMENT *elem) { - elem->prev = before; - elem->next = before->next; - elem->next->prev = elem; - before->next = elem; - if (before == anchor->last) anchor->last = elem; - verify_list("add", anchor); + list_add_after(anchor, &before->iseq_node, &elem->iseq_node); } #if CPDEBUG < 0 #define ADD_ELEM(anchor, elem) ADD_ELEM(iseq, (anchor), (elem)) @@ -440,12 +385,20 @@ iseq_add_mark_object_compile_time(rb_iseq_t *iseq, VALUE v) return COMPILE_OK; } +struct validate_arg { + rb_iseq_t *iseq; + struct list_head *anchor; +}; + static int validate_label(st_data_t name, st_data_t label, st_data_t arg) { - rb_iseq_t *iseq = (rb_iseq_t *)arg; + struct validate_arg *v = (struct validate_arg *)arg; + rb_iseq_t *iseq = v->iseq; + struct list_head *anchor = v->anchor; LABEL *lobj = (LABEL *)label; - if (!lobj->link.next) { + + if (!list_next(anchor, &lobj->link, iseq_node)) { do { int ret; COMPILE_ERROR((ruby_sourcefile, lobj->position, @@ -458,9 +411,14 @@ validate_label(st_data_t name, st_data_t label, st_data_t arg) } static void -validate_labels(rb_iseq_t *iseq, st_table *labels_table) +validate_labels(struct list_head *anchor, rb_iseq_t *iseq, st_table *labels_table) { - st_foreach(labels_table, validate_label, (st_data_t)iseq); + struct validate_arg v; + + v.iseq = iseq; + v.anchor = anchor; + + st_foreach(labels_table, validate_label, (st_data_t)&v); if (!NIL_P(iseq->compile_data->err_info)) { rb_exc_raise(iseq->compile_data->err_info); } @@ -471,7 +429,6 @@ rb_iseq_compile_node(VALUE self, NODE *node) { DECL_ANCHOR(ret); rb_iseq_t *iseq; - INIT_ANCHOR(ret); GetISeqPtr(self, iseq); if (node == 0) { @@ -742,14 +699,9 @@ compile_data_alloc_adjust(rb_iseq_t *iseq) * elem1, elemX => elem1, elem2, elemX */ static void -INSERT_ELEM_NEXT(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2) +INSERT_ELEM_NEXT(struct list_head *anchor, LINK_ELEMENT *elem1, LINK_ELEMENT *elem2) { - elem2->next = elem1->next; - elem2->prev = elem1; - elem1->next = elem2; - if (elem2->next) { - elem2->next->prev = elem2; - } + list_add_after(anchor, &elem1->iseq_node, &elem2->iseq_node); } /* @@ -758,71 +710,47 @@ INSERT_ELEM_NEXT(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2) static void REPLACE_ELEM(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2) { - elem2->prev = elem1->prev; - elem2->next = elem1->next; - if (elem1->prev) { - elem1->prev->next = elem2; - } - if (elem1->next) { - elem1->next->prev = elem2; - } + list_swap(&elem1->iseq_node, &elem2->iseq_node); } static void REMOVE_ELEM(LINK_ELEMENT *elem) { - elem->prev->next = elem->next; - if (elem->next) { - elem->next->prev = elem->prev; - } + list_del(&elem->iseq_node); } static LINK_ELEMENT * -FIRST_ELEMENT(LINK_ANCHOR *anchor) +FIRST_ELEMENT(struct list_head *anchor) { - return anchor->anchor.next; + return list_top(anchor, LINK_ELEMENT, iseq_node); } static LINK_ELEMENT * -POP_ELEMENT(ISEQ_ARG_DECLARE LINK_ANCHOR *anchor) +POP_ELEMENT(ISEQ_ARG_DECLARE struct list_head *anchor) { - LINK_ELEMENT *elem = anchor->last; - anchor->last = anchor->last->prev; - anchor->last->next = 0; - verify_list("pop", anchor); + /* list_pop in ccan/list removes the first element, not the last */ + LINK_ELEMENT *elem = list_tail(anchor, LINK_ELEMENT, iseq_node); + + if (elem) + REMOVE_ELEM(elem); + return elem; } #if CPDEBUG < 0 #define POP_ELEMENT(anchor) POP_ELEMENT(iseq, (anchor)) #endif -static int -LIST_SIZE_ZERO(LINK_ANCHOR *anchor) -{ - if (anchor->anchor.next == 0) { - return 1; - } - else { - return 0; - } -} - /* * anc1: e1, e2, e3 * anc2: e4, e5 *#=> * anc1: e1, e2, e3, e4, e5 - * anc2: e4, e5 (broken) + * anc2: (empty) */ static void -APPEND_LIST(ISEQ_ARG_DECLARE LINK_ANCHOR *anc1, LINK_ANCHOR *anc2) +APPEND_LIST(ISEQ_ARG_DECLARE struct list_head *anc1, struct list_head *anc2) { - if (anc2->anchor.next) { - anc1->last->next = anc2->anchor.next; - anc2->anchor.next->prev = anc1->last; - anc1->last = anc2->last; - } - verify_list("append", anc1); + list_append_list(anc1, anc2); } #if CPDEBUG < 0 #define APPEND_LIST(anc1, anc2) APPEND_LIST(iseq, (anc1), (anc2)) @@ -833,60 +761,23 @@ APPEND_LIST(ISEQ_ARG_DECLARE LINK_ANCHOR *anc1, LINK_ANCHOR *anc2) * anc2: e4, e5 *#=> * anc1: e4, e5, e1, e2, e3 - * anc2: e4, e5 (broken) + * anc2: (empty) */ static void -INSERT_LIST(ISEQ_ARG_DECLARE LINK_ANCHOR *anc1, LINK_ANCHOR *anc2) +INSERT_LIST(ISEQ_ARG_DECLARE struct list_head *anc1, struct list_head *anc2) { - if (anc2->anchor.next) { - LINK_ELEMENT *first = anc1->anchor.next; - anc1->anchor.next = anc2->anchor.next; - anc1->anchor.next->prev = &anc1->anchor; - anc2->last->next = first; - if (first) { - first->prev = anc2->last; - } - else { - anc1->last = anc2->last; - } - } - - verify_list("append", anc1); + list_prepend_list(anc1, anc2); } #if CPDEBUG < 0 #define INSERT_LIST(anc1, anc2) INSERT_LIST(iseq, (anc1), (anc2)) #endif -#if CPDEBUG && 0 -static void -debug_list(ISEQ_ARG_DECLARE LINK_ANCHOR *anchor) -{ - LINK_ELEMENT *list = FIRST_ELEMENT(anchor); - printf("----\n"); - printf("anch: %p, frst: %p, last: %p\n", &anchor->anchor, - anchor->anchor.next, anchor->last); - while (list) { - printf("curr: %p, next: %p, prev: %p, type: %d\n", list, list->next, - list->prev, FIX2INT(list->type)); - list = list->next; - } - printf("----\n"); - - dump_disasm_list(anchor->anchor.next); - verify_list("debug list", anchor); -} -#if CPDEBUG < 0 -#define debug_list(anc) debug_list(iseq, (anc)) -#endif -#endif - static LABEL * new_label_body(rb_iseq_t *iseq, long line) { LABEL *labelobj = compile_data_alloc_label(iseq); labelobj->link.type = ISEQ_ELEMENT_LABEL; - labelobj->link.next = 0; labelobj->label_no = iseq->compile_data->label_no++; labelobj->sc_state = 0; @@ -899,7 +790,6 @@ new_adjust_body(rb_iseq_t *iseq, LABEL *label, int line) { ADJUST *adjust = compile_data_alloc_adjust(iseq); adjust->link.type = ISEQ_ELEMENT_ADJUST; - adjust->link.next = 0; adjust->label = label; adjust->line_no = line; return adjust; @@ -913,7 +803,6 @@ new_insn_core(rb_iseq_t *iseq, int line_no, /* printf("insn_id: %d, line: %d\n", insn_id, line_no); */ iobj->link.type = ISEQ_ELEMENT_INSN; - iobj->link.next = 0; iobj->insn_id = insn_id; iobj->line_no = line_no; iobj->operands = argv; @@ -1003,37 +892,37 @@ new_child_iseq(rb_iseq_t *iseq, NODE *node, } static int -iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *anchor) +iseq_setup(rb_iseq_t *iseq, struct list_head *anchor) { /* debugs("[compile step 2] (iseq_array_to_linkedlist)\n"); */ if (compile_debug > 5) - dump_disasm_list(FIRST_ELEMENT(anchor)); + dump_disasm_list(anchor, FIRST_ELEMENT(anchor)); debugs("[compile step 3.1 (iseq_optimize)]\n"); iseq_optimize(iseq, anchor); if (compile_debug > 5) - dump_disasm_list(FIRST_ELEMENT(anchor)); + dump_disasm_list(anchor, FIRST_ELEMENT(anchor)); if (iseq->compile_data->option->instructions_unification) { debugs("[compile step 3.2 (iseq_insns_unification)]\n"); iseq_insns_unification(iseq, anchor); if (compile_debug > 5) - dump_disasm_list(FIRST_ELEMENT(anchor)); + dump_disasm_list(anchor, FIRST_ELEMENT(anchor)); } if (iseq->compile_data->option->stack_caching) { debugs("[compile step 3.3 (iseq_set_sequence_stackcaching)]\n"); iseq_set_sequence_stackcaching(iseq, anchor); if (compile_debug > 5) - dump_disasm_list(FIRST_ELEMENT(anchor)); + dump_disasm_list(anchor, FIRST_ELEMENT(anchor)); } debugs("[compile step 4.1 (iseq_set_sequence)]\n"); iseq_set_sequence(iseq, anchor); if (compile_debug > 5) - dump_disasm_list(FIRST_ELEMENT(anchor)); + dump_disasm_list(anchor, FIRST_ELEMENT(anchor)); debugs("[compile step 4.2 (iseq_set_exception_table)]\n"); iseq_set_exception_table(iseq); @@ -1163,7 +1052,7 @@ iseq_calc_param_size(rb_iseq_t *iseq) } static int -iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args) +iseq_set_arguments(rb_iseq_t *iseq, struct list_head *optargs, NODE *node_args) { debugs("iseq_set_arguments: %s\n", node_args ? "" : "0"); @@ -1419,7 +1308,7 @@ cdhash_set_label_i(VALUE key, VALUE val, void *ptr) ruby insn object list -> raw instruction sequence */ static int -iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor) +iseq_set_sequence(rb_iseq_t *iseq, struct list_head *anchor) { LABEL *lobj; INSN *iobj; @@ -1431,9 +1320,8 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor) int k, pos, sp, stack_max = 0, line = 0; /* set label position */ - list = FIRST_ELEMENT(anchor); k = pos = 0; - while (list) { + list_for_each(anchor, list, iseq_node) { switch (list->type) { case ISEQ_ELEMENT_INSN: { @@ -1465,13 +1353,12 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor) break; } default: - dump_disasm_list(FIRST_ELEMENT(anchor)); - dump_disasm_list(list); + dump_disasm_list(anchor, FIRST_ELEMENT(anchor)); + dump_disasm_list(anchor, list); rb_compile_error(RSTRING_PTR(iseq->location.path), line, "error: set_sequence"); break; } - list = list->next; } /* make instruction sequence */ @@ -1481,10 +1368,9 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor) iseq->callinfo_entries = ALLOC_N(rb_call_info_t, iseq->callinfo_size); /* MEMZERO(iseq->callinfo_entries, rb_call_info_t, iseq->callinfo_size); */ - list = FIRST_ELEMENT(anchor); k = pos = sp = 0; - while (list) { + list_for_each(anchor, list, iseq_node) { switch (list->type) { case ISEQ_ELEMENT_INSN: { @@ -1510,7 +1396,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor) /* operand check */ if (iobj->operand_size != len - 1) { /* printf("operand size miss! (%d, %d)\n", iobj->operand_size, len); */ - dump_disasm_list(list); + dump_disasm_list(anchor, list); rb_compile_error(RSTRING_PTR(iseq->location.path), iobj->line_no, "operand size miss! (%d for %d)", iobj->operand_size, len - 1); @@ -1676,7 +1562,6 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor) /* ignore */ break; } - list = list->next; } iseq->iseq_encoded = (void *)generated_iseq; @@ -1776,51 +1661,51 @@ iseq_set_optargs_table(rb_iseq_t *iseq) } static LINK_ELEMENT * -get_destination_insn(INSN *iobj) +get_destination_insn(struct list_head *anchor, INSN *iobj) { LABEL *lobj = (LABEL *)OPERAND_AT(iobj, 0); - LINK_ELEMENT *list; + LINK_ELEMENT *list = list_next(anchor, &lobj->link, iseq_node); - list = lobj->link.next; while (list) { if (list->type == ISEQ_ELEMENT_INSN || list->type == ISEQ_ELEMENT_ADJUST) { break; } - list = list->next; + list = list_next(anchor, list, iseq_node); } return list; } static LINK_ELEMENT * -get_next_insn(INSN *iobj) +get_next_insn(struct list_head *anchor, INSN *iobj) { - LINK_ELEMENT *list = iobj->link.next; + LINK_ELEMENT *list = list_next(anchor, &iobj->link, iseq_node); while (list) { if (list->type == ISEQ_ELEMENT_INSN || list->type == ISEQ_ELEMENT_ADJUST) { return list; } - list = list->next; + list = list_next(anchor, list, iseq_node); } return 0; } static LINK_ELEMENT * -get_prev_insn(INSN *iobj) +get_prev_insn(struct list_head *anchor, INSN *iobj) { - LINK_ELEMENT *list = iobj->link.prev; + LINK_ELEMENT *list = list_prev(anchor, &iobj->link, iseq_node); while (list) { if (list->type == ISEQ_ELEMENT_INSN || list->type == ISEQ_ELEMENT_ADJUST) { return list; } - list = list->prev; + list = list_prev(anchor, list, iseq_node); } return 0; } static int -iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcallopt) +iseq_peephole_optimize(rb_iseq_t *iseq, struct list_head *anchor, + LINK_ELEMENT *list, const int do_tailcallopt) { INSN *iobj = (INSN *)list; again: @@ -1836,8 +1721,8 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal * => in this case, first jump instruction should jump to * LABEL2 directly */ - diobj = (INSN *)get_destination_insn(iobj); - niobj = (INSN *)get_next_insn(iobj); + diobj = (INSN *)get_destination_insn(anchor, iobj); + niobj = (INSN *)get_next_insn(anchor, iobj); if (diobj == niobj) { /* @@ -1872,7 +1757,8 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal BIN(pop), 0, 0); /* replace */ REPLACE_ELEM((LINK_ELEMENT *)iobj, (LINK_ELEMENT *)eiobj); - INSERT_ELEM_NEXT((LINK_ELEMENT *)eiobj, (LINK_ELEMENT *)popiobj); + INSERT_ELEM_NEXT(anchor, (LINK_ELEMENT *)eiobj, + (LINK_ELEMENT *)popiobj); iobj = popiobj; } /* @@ -1889,10 +1775,10 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal * ... * L2: */ - else if ((piobj = (INSN *)get_prev_insn(iobj)) != 0 && + else if ((piobj = (INSN *)get_prev_insn(anchor, iobj)) != 0 && (piobj->insn_id == BIN(branchif) || piobj->insn_id == BIN(branchunless))) { - if (niobj == (INSN *)get_destination_insn(piobj)) { + if (niobj == (INSN *)get_destination_insn(anchor, piobj)) { piobj->insn_id = (piobj->insn_id == BIN(branchif)) ? BIN(branchunless) : BIN(branchif); OPERAND_AT(piobj, 0) = OPERAND_AT(iobj, 0); @@ -1911,7 +1797,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal * => * if L2 */ - INSN *nobj = (INSN *)get_destination_insn(iobj); + INSN *nobj = (INSN *)get_destination_insn(anchor, iobj); if (nobj->insn_id == BIN(jump)) { OPERAND_AT(iobj, 0) = OPERAND_AT(nobj, 0); } @@ -1925,7 +1811,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal * send ..., ... | VM_CALL_TAILCALL, ... * leave # unreachable */ - INSN *piobj = (INSN *)get_prev_insn((INSN *)list); + INSN *piobj = (INSN *)get_prev_insn(anchor, (INSN *)list); enum ruby_vminsn_type previ = piobj->insn_id; if (previ == BIN(send) || previ == BIN(opt_send_without_block) || previ == BIN(invokesuper)) { @@ -2011,19 +1897,18 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj) } static int -iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *anchor) +iseq_optimize(rb_iseq_t *iseq, struct list_head *anchor) { - LINK_ELEMENT *list; + LINK_ELEMENT *list, *next; const int do_peepholeopt = iseq->compile_data->option->peephole_optimization; const int do_tailcallopt = iseq->compile_data->option->tailcall_optimization; const int do_si = iseq->compile_data->option->specialized_instruction; const int do_ou = iseq->compile_data->option->operands_unification; - list = FIRST_ELEMENT(anchor); - while (list) { + list_for_each_safe(anchor, list, next, iseq_node) { if (list->type == ISEQ_ELEMENT_INSN) { if (do_peepholeopt) { - iseq_peephole_optimize(iseq, list, do_tailcallopt); + iseq_peephole_optimize(iseq, anchor, list, do_tailcallopt); } if (do_si) { iseq_specialized_instruction(iseq, (INSN *)list); @@ -2032,15 +1917,14 @@ iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *anchor) insn_operands_unification((INSN *)list); } } - list = list->next; } return COMPILE_OK; } #if OPT_INSTRUCTIONS_UNIFICATION static INSN * -new_unified_insn(rb_iseq_t *iseq, - int insn_id, int size, LINK_ELEMENT *seq_list) +new_unified_insn(rb_iseq_t *iseq, int insn_id, int size, + struct list_head *anchor, LINK_ELEMENT *seq_list) { INSN *iobj = 0; LINK_ELEMENT *list = seq_list; @@ -2052,7 +1936,7 @@ new_unified_insn(rb_iseq_t *iseq, for (i = 0; i < size; i++) { iobj = (INSN *)list; argc += iobj->operand_size; - list = list->next; + list = list_next(anchor, list, iseq_node); } if (argc > 0) { @@ -2066,7 +1950,7 @@ new_unified_insn(rb_iseq_t *iseq, iobj = (INSN *)list; MEMCPY(ptr, iobj->operands, VALUE, iobj->operand_size); ptr += iobj->operand_size; - list = list->next; + list = list_next(anchor, list, iseq_node); } return new_insn_core(iseq, iobj->line_no, insn_id, argc, operands); @@ -2079,7 +1963,7 @@ new_unified_insn(rb_iseq_t *iseq, * It's future work (if compile time was bottle neck). */ static int -iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *anchor) +iseq_insns_unification(rb_iseq_t *iseq, struct list_head *anchor) { #if OPT_INSTRUCTIONS_UNIFICATION LINK_ELEMENT *list; @@ -2096,34 +1980,32 @@ iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *anchor) const int *const *entry = unified_insns_data[id]; for (j = 1; j < (intptr_t)entry[0]; j++) { const int *unified = entry[j]; - LINK_ELEMENT *li = list->next; + LINK_ELEMENT *li = list_next(anchor, list, iseq_node); for (k = 2; k < unified[1]; k++) { if (li->type != ISEQ_ELEMENT_INSN || ((INSN *)li)->insn_id != unified[k]) { goto miss; } - li = li->next; + li = list_next(anchor, li, iseq_node); } /* matched */ niobj = new_unified_insn(iseq, unified[0], unified[1] - 1, - list); + anchor, list); /* insert to list */ - niobj->link.prev = (LINK_ELEMENT *)iobj->link.prev; - niobj->link.next = li; + APPEND_ELEM(anchor, &iobj->link, &niobj->link); if (li) { - li->prev = (LINK_ELEMENT *)niobj; + APPEND_ELEM(anchor, &niobj->link, li); } - - list->prev->next = (LINK_ELEMENT *)niobj; + REMOVE_ELEM(&iobj->link); list = (LINK_ELEMENT *)niobj; break; miss:; } } } - list = list->next; + list = list_next(anchor, list, iseq_node); } #endif return COMPILE_OK; @@ -2137,7 +2019,7 @@ iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *anchor) #include "opt_sc.inc" static int -insn_set_sc_state(rb_iseq_t *iseq, INSN *iobj, int state) +insn_set_sc_state(struct list_head *anchor, rb_iseq_t *iseq, INSN *iobj, int state) { int nstate; int insn_id; @@ -2152,8 +2034,8 @@ insn_set_sc_state(rb_iseq_t *iseq, INSN *iobj, int state) if (lobj->sc_state != 0) { if (lobj->sc_state != nstate) { - dump_disasm_list((LINK_ELEMENT *)iobj); - dump_disasm_list((LINK_ELEMENT *)lobj); + dump_disasm_list(anchor, (LINK_ELEMENT *)iobj); + dump_disasm_list(anchor, (LINK_ELEMENT *)lobj); printf("\n-- %d, %d\n", lobj->sc_state, nstate); rb_compile_error(RSTRING_PTR(iseq->location.path), iobj->line_no, "insn_set_sc_state error\n"); @@ -2193,16 +2075,16 @@ label_set_sc_state(LABEL *lobj, int state) #endif static int -iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor) +iseq_set_sequence_stackcaching(rb_iseq_t *iseq, struct list_head *anchor) { -#if OPT_STACK_CACHING - LINK_ELEMENT *list; +#if OPT_STACK_CACHING /* FIXME: bitrotten */ + LINK_ELEMENT *list, *next; int state, insn_id; /* initialize */ state = SCS_XX; list = FIRST_ELEMENT(anchor); - /* dump_disasm_list(list); */ + /* dump_disasm_list(anchor, list); */ /* for each list element */ while (list) { @@ -2213,7 +2095,7 @@ iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor) INSN *iobj = (INSN *)list; insn_id = iobj->insn_id; - /* dump_disasm_list(list); */ + /* dump_disasm_list(anchor, list); */ switch (insn_id) { case BIN(nop): @@ -2235,8 +2117,9 @@ iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor) if (state == SCS_AB || state == SCS_BA) { state = (state == SCS_AB ? SCS_BA : SCS_AB); + next = list_next(anchor, list, iseq_node); REMOVE_ELEM(list); - list = list->next; + list = next; goto redo_point; } break; @@ -2261,15 +2144,16 @@ iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor) "unreachable"); } /* remove useless pop */ + next = list_next(anchor, list, iseq_node); REMOVE_ELEM(list); - list = list->next; - goto redo_point; + list = next; + continue; } default:; /* none */ } /* end of switch */ normal_insn: - state = insn_set_sc_state(iseq, iobj, state); + state = insn_set_sc_state(anchor, iseq, iobj, state); break; } case ISEQ_ELEMENT_LABEL: @@ -2282,14 +2166,14 @@ iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor) default: break; } - list = list->next; + list = list_next(anchor, list, iseq_node); } #endif return COMPILE_OK; } static int -compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int *cntp) +compile_dstr_fragments(rb_iseq_t *iseq, struct list_head *ret, NODE *node, int *cntp) { NODE *list = node->nd_next; VALUE lit = node->nd_lit; @@ -2321,7 +2205,7 @@ compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int *cntp) } static int -compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node) +compile_dstr(rb_iseq_t *iseq, struct list_head *ret, NODE * node) { int cnt; compile_dstr_fragments(iseq, ret, node, &cnt); @@ -2330,7 +2214,7 @@ compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node) } static int -compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node) +compile_dregx(rb_iseq_t *iseq, struct list_head *ret, NODE * node) { int cnt; compile_dstr_fragments(iseq, ret, node, &cnt); @@ -2339,7 +2223,7 @@ compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node) } static int -compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * cond, +compile_branch_condition(rb_iseq_t *iseq, struct list_head *ret, NODE * cond, LABEL *then_label, LABEL *else_label) { switch (nd_type(cond)) { @@ -2384,7 +2268,7 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * cond, } static int -compile_array_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE * const root_node, rb_call_info_kw_arg_t ** const kw_arg_ptr) +compile_array_keyword_arg(rb_iseq_t *iseq, struct list_head *ret, const NODE * const root_node, rb_call_info_kw_arg_t ** const kw_arg_ptr) { if (kw_arg_ptr == NULL) return FALSE; @@ -2436,7 +2320,7 @@ enum compile_array_type_t { }; static int -compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root, +compile_array_(rb_iseq_t *iseq, struct list_head *ret, NODE* node_root, enum compile_array_type_t type, rb_call_info_kw_arg_t **keywords_ptr, int poped) { NODE *node = node_root; @@ -2461,7 +2345,6 @@ compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root, NODE *kw = 0; const int max = 0x100; DECL_ANCHOR(anchor); - INIT_ANCHOR(anchor); for (i=0; ind_next) { if (CPDEBUG > 0 && nd_type(node) != NODE_ARRAY) { @@ -2592,7 +2475,7 @@ compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root, } static VALUE -compile_array(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root, enum compile_array_type_t type) +compile_array(rb_iseq_t *iseq, struct list_head *ret, NODE* node_root, enum compile_array_type_t type) { return compile_array_(iseq, ret, node_root, type, NULL, 0); } @@ -2620,7 +2503,7 @@ case_when_optimizable_literal(NODE * node) } static int -when_vals(rb_iseq_t *iseq, LINK_ANCHOR *cond_seq, NODE *vals, LABEL *l1, int only_special_literals, VALUE literals) +when_vals(rb_iseq_t *iseq, struct list_head *cond_seq, NODE *vals, LABEL *l1, int only_special_literals, VALUE literals) { while (vals) { NODE* val = vals->nd_head; @@ -2657,7 +2540,7 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *cond_seq, NODE *vals, LABEL *l1, int onl } static int -compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node) +compile_massign_lhs(rb_iseq_t *iseq, struct list_head *ret, NODE *node) { switch (nd_type(node)) { case NODE_ATTRASGN: { @@ -2681,7 +2564,6 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node) } case NODE_MASGN: { DECL_ANCHOR(anchor); - INIT_ANCHOR(anchor); COMPILE_POPED(anchor, "nest masgn lhs", node); REMOVE_ELEM(FIRST_ELEMENT(anchor)); ADD_SEQ(ret, anchor); @@ -2689,7 +2571,6 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node) } default: { DECL_ANCHOR(anchor); - INIT_ANCHOR(anchor); COMPILE_POPED(anchor, "masgn lhs", node); REMOVE_ELEM(FIRST_ELEMENT(anchor)); ADD_SEQ(ret, anchor); @@ -2700,7 +2581,7 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node) } static void -compile_massign_opt_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *lhsn) +compile_massign_opt_lhs(rb_iseq_t *iseq, struct list_head *ret, NODE *lhsn) { if (lhsn) { compile_massign_opt_lhs(iseq, ret, lhsn->nd_next); @@ -2709,7 +2590,7 @@ compile_massign_opt_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *lhsn) } static int -compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *ret, +compile_massign_opt(rb_iseq_t *iseq, struct list_head *ret, NODE *rhsn, NODE *orig_lhsn) { VALUE mem[64]; @@ -2774,7 +2655,7 @@ compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *ret, } static void -adjust_stack(rb_iseq_t *iseq, LINK_ANCHOR *ret, int line, int rlen, int llen) +adjust_stack(rb_iseq_t *iseq, struct list_head *ret, int line, int rlen, int llen) { if (rlen < llen) { do {ADD_INSN(ret, line, putnil);} while (++rlen < llen); @@ -2785,7 +2666,7 @@ adjust_stack(rb_iseq_t *iseq, LINK_ANCHOR *ret, int line, int rlen, int llen) } static int -compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int poped) +compile_massign(rb_iseq_t *iseq, struct list_head *ret, NODE *node, int poped) { NODE *rhsn = node->nd_value; NODE *splatn = node->nd_args; @@ -2797,8 +2678,6 @@ compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int poped) int expand = 1; DECL_ANCHOR(lhsseq); - INIT_ANCHOR(lhsseq); - while (lhsn) { compile_massign_lhs(iseq, lhsseq, lhsn->nd_head); llen += 1; @@ -2811,7 +2690,7 @@ compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int poped) ADD_INSN(ret, nd_line(node), dup); } else if (!lhs_splat) { - INSN *last = (INSN*)ret->last; + INSN *last = (INSN *)list_tail(ret, LINK_ELEMENT, iseq_node); if (last->link.type == ISEQ_ELEMENT_INSN && last->insn_id == BIN(newarray) && last->operand_size == 1) { @@ -2871,7 +2750,7 @@ compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int poped) static int compile_colon2(rb_iseq_t *iseq, NODE * node, - LINK_ANCHOR *pref, LINK_ANCHOR *body) + struct list_head *pref, struct list_head *body) { switch (nd_type(node)) { case NODE_CONST: @@ -2897,7 +2776,7 @@ compile_colon2(rb_iseq_t *iseq, NODE * node, } static VALUE -compile_cpath(LINK_ANCHOR *ret, rb_iseq_t *iseq, NODE *cpath) +compile_cpath(struct list_head *ret, rb_iseq_t *iseq, NODE *cpath) { if (nd_type(cpath) == NODE_COLON3) { /* toplevel class ::Foo */ @@ -2921,7 +2800,7 @@ compile_cpath(LINK_ANCHOR *ret, rb_iseq_t *iseq, NODE *cpath) #define defined_expr defined_expr0 static int -defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret, +defined_expr(rb_iseq_t *iseq, struct list_head *ret, NODE *node, LABEL **lfinish, VALUE needstr) { enum defined_type expr_type = 0; @@ -3101,10 +2980,10 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret, #undef defined_expr static int -defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *ret, +defined_expr(rb_iseq_t *iseq, struct list_head *ret, NODE *node, LABEL **lfinish, VALUE needstr) { - LINK_ELEMENT *lcur = ret->last; + LINK_ELEMENT *lcur = list_tail(ret, LINK_ELEMENT, iseq_node); int done = defined_expr0(iseq, ret, node, lfinish, needstr); if (lfinish[1]) { int line = nd_line(node); @@ -3175,20 +3054,18 @@ add_ensure_range(rb_iseq_t *iseq, struct ensure_range *erange, } static void -add_ensure_iseq(LINK_ANCHOR *ret, rb_iseq_t *iseq, int is_return) +add_ensure_iseq(struct list_head *ret, rb_iseq_t *iseq, int is_return) { struct iseq_compile_data_ensure_node_stack *enlp = iseq->compile_data->ensure_node_stack; struct iseq_compile_data_ensure_node_stack *prev_enlp = enlp; DECL_ANCHOR(ensure); - INIT_ANCHOR(ensure); while (enlp) { if (enlp->erange != 0) { DECL_ANCHOR(ensure_part); LABEL *lstart = NEW_LABEL(0); LABEL *lend = NEW_LABEL(0); - INIT_ANCHOR(ensure_part); add_ensure_range(iseq, enlp->erange, lstart, lend); @@ -3210,15 +3087,13 @@ add_ensure_iseq(LINK_ANCHOR *ret, rb_iseq_t *iseq, int is_return) } static VALUE -setup_args(rb_iseq_t *iseq, LINK_ANCHOR *args, NODE *argn, unsigned int *flag, rb_call_info_kw_arg_t **keywords) +setup_args(rb_iseq_t *iseq, struct list_head *args, NODE *argn, unsigned int *flag, rb_call_info_kw_arg_t **keywords) { VALUE argc = INT2FIX(0); int nsplat = 0; DECL_ANCHOR(arg_block); DECL_ANCHOR(args_splat); - INIT_ANCHOR(arg_block); - INIT_ANCHOR(args_splat); if (argn && nd_type(argn) == NODE_BLOCK_PASS) { COMPILE(arg_block, "block", argn->nd_body); *flag |= VM_CALL_ARGS_BLOCKARG; @@ -3241,7 +3116,6 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *args, NODE *argn, unsigned int *flag, r int next_is_array = (nd_type(argn->nd_head) == NODE_ARRAY); DECL_ANCHOR(tmp); - INIT_ANCHOR(tmp); COMPILE(tmp, "args (cat: splat)", argn->nd_body); if (nd_type(argn) == NODE_ARGSCAT) { ADD_INSN1(tmp, nd_line(argn), splatarray, Qfalse); @@ -3280,7 +3154,7 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *args, NODE *argn, unsigned int *flag, r } } - if (!LIST_SIZE_ZERO(args_splat)) { + if (!list_empty(args_splat)) { ADD_SEQ(args, args_splat); } @@ -3291,7 +3165,7 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *args, NODE *argn, unsigned int *flag, r } static VALUE -build_postexe_iseq(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *body) +build_postexe_iseq(rb_iseq_t *iseq, struct list_head *ret, NODE *body) { int line = nd_line(body); VALUE argc = INT2FIX(0); @@ -3310,7 +3184,7 @@ build_postexe_iseq(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *body) poped: This node will be poped */ static int -iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) +iseq_compile_each(rb_iseq_t *iseq, struct list_head *ret, NODE * node, int poped) { enum node_type type; LINK_ELEMENT *saved_last_element = 0; @@ -3333,7 +3207,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) if (node->flags & NODE_FL_NEWLINE) { iseq->compile_data->last_line = line; ADD_TRACE(ret, line, RUBY_EVENT_LINE); - saved_last_element = ret->last; + saved_last_element = list_tail(ret, LINK_ELEMENT, iseq_node); } } @@ -3359,9 +3233,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) DECL_ANCHOR(else_seq); LABEL *then_label, *else_label, *end_label; - INIT_ANCHOR(cond_seq); - INIT_ANCHOR(then_seq); - INIT_ANCHOR(else_seq); then_label = NEW_LABEL(line); else_label = NEW_LABEL(line); end_label = NEW_LABEL(line); @@ -3394,10 +3265,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) int only_special_literals = 1; VALUE literals = rb_hash_new(); - INIT_ANCHOR(head); - INIT_ANCHOR(body_seq); - INIT_ANCHOR(cond_seq); - rb_hash_tbl_raw(literals)->type = &cdhash_type; if (node->nd_head == 0) { @@ -3495,7 +3362,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) LABEL *endlabel; DECL_ANCHOR(body_seq); - INIT_ANCHOR(body_seq); endlabel = NEW_LABEL(line); while (node && nd_type(node) == NODE_WHEN) { @@ -3996,7 +3862,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) struct iseq_compile_data_ensure_node_stack enl; struct ensure_range *erange; - INIT_ANCHOR(ensr); COMPILE_POPED(ensr, "ensure ensr", node->nd_ensr); er.begin = lstart; @@ -4007,7 +3872,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) ADD_LABEL(ret, lstart); COMPILE_(ret, "ensure head", node->nd_head, poped); ADD_LABEL(ret, lend); - if (ensr->anchor.next == 0) { + if (list_empty(ensr)) { ADD_INSN(ret, line, nop); } else { @@ -4174,7 +4039,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) case NODE_BLOCK_PASS: boff = 1; default: - INIT_ANCHOR(args); argc = setup_args(iseq, args, node->nd_args->nd_head, &flag, NULL); ADD_SEQ(ret, args); } @@ -4518,8 +4382,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) VALUE parent_block = iseq->compile_data->current_block; iseq->compile_data->current_block = Qfalse; - INIT_ANCHOR(recv); - INIT_ANCHOR(args); #if SUPPORT_JOKE if (nd_type(node) == NODE_VCALL) { ID id_bitblt; @@ -4629,7 +4491,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) rb_call_info_kw_arg_t *keywords = NULL; VALUE parent_block = iseq->compile_data->current_block; - INIT_ANCHOR(args); iseq->compile_data->current_block = Qfalse; if (nd_type(node) == NODE_SUPER) { VALUE vargc = setup_args(iseq, args, node->nd_args, &flag, &keywords); @@ -4767,7 +4628,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) DECL_ANCHOR(list); int type = node->nd_head ? nd_type(node->nd_head) : NODE_ZARRAY; - INIT_ANCHOR(list); switch (type) { case NODE_ARRAY: compile_array(iseq, list, node->nd_head, COMPILE_ARRAY_TYPE_HASH); @@ -4831,7 +4691,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) unsigned int flag = 0; rb_call_info_kw_arg_t *keywords = NULL; - INIT_ANCHOR(args); if (iseq->type == ISEQ_TYPE_TOP) { COMPILE_ERROR((ERROR_ARGS "Invalid yield")); } @@ -4942,8 +4801,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) DECL_ANCHOR(recv); DECL_ANCHOR(val); - INIT_ANCHOR(recv); - INIT_ANCHOR(val); switch (nd_type(node)) { case NODE_MATCH: ADD_INSN1(recv, line, putobject, node->nd_lit); @@ -4961,13 +4818,14 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) } if (iseq->compile_data->option->specialized_instruction) { + LINK_ELEMENT *last = list_tail(recv, LINK_ELEMENT, iseq_node); /* TODO: detect by node */ - if (recv->last == recv->anchor.next && - INSN_OF(recv->last) == BIN(putobject) && + if (last == list_top(recv, LINK_ELEMENT, iseq_node) && + INSN_OF(last) == BIN(putobject) && nd_type(node) == NODE_MATCH2) { ADD_SEQ(ret, val); ADD_INSN1(ret, line, opt_regexpmatch1, - OPERAND_AT(recv->last, 0)); + OPERAND_AT(last, 0)); } else { ADD_SEQ(ret, recv); @@ -5237,10 +5095,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) DECL_ANCHOR(pref); DECL_ANCHOR(body); - INIT_ANCHOR(pref); - INIT_ANCHOR(body); compile_colon2(iseq, node, pref, body); - if (LIST_SIZE_ZERO(pref)) { + if (list_empty(pref)) { if (iseq->compile_data->option->inline_const_cache) { ADD_INSN2(ret, line, getinlinecache, lend, INT2FIX(ic_index)); } @@ -5508,8 +5364,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) break; } - INIT_ANCHOR(recv); - INIT_ANCHOR(args); argc = setup_args(iseq, args, node->nd_args, &flag, NULL); flag |= COMPILE_RECV(recv, "recv", node); @@ -5575,7 +5429,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) /* check & remove redundant trace(line) */ if (saved_last_element && ret /* ret can be 0 when error */ && - ret->last == saved_last_element && + list_tail(ret, LINK_ELEMENT, iseq_node) == saved_last_element && ((INSN *)saved_last_element)->insn_id == BIN(trace)) { POP_ELEMENT(ret); } @@ -5708,7 +5562,7 @@ insn_data_to_s_detail(INSN *iobj) } static void -dump_disasm_list(struct iseq_link_element *link) +dump_disasm_list(struct list_head *anchor, struct iseq_link_element *link) { int pos = 0; INSN *iobj; @@ -5748,7 +5602,7 @@ dump_disasm_list(struct iseq_link_element *link) /* ignore */ rb_raise(rb_eSyntaxError, "dump_disasm_list error: %ld\n", FIX2LONG(link->type)); } - link = link->next; + link = list_next(anchor, link, iseq_node); } printf("---------------------\n"); } @@ -5924,7 +5778,7 @@ iseq_build_callinfo_from_hash(rb_iseq_t *iseq, VALUE op) return (VALUE)new_callinfo(iseq, mid, orig_argc, block, flag, kw_arg); } static int -iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor, +iseq_build_from_ary_body(rb_iseq_t *iseq, struct list_head *anchor, VALUE body, struct st_table *labels_table) { /* TODO: body should be frozen */ @@ -6059,7 +5913,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor, rb_raise(rb_eTypeError, "unexpected object for instruction"); } } - validate_labels(iseq, labels_table); + validate_labels(anchor, iseq, labels_table); st_free_table(labels_table); iseq_setup(iseq, anchor); return COMPILE_OK; @@ -6157,7 +6011,6 @@ rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params, VALUE keywords = rb_hash_aref(params, SYM(keyword)); VALUE sym_arg_rest = ID2SYM(rb_intern("#arg_rest")); DECL_ANCHOR(anchor); - INIT_ANCHOR(anchor); len = RARRAY_LENINT(locals); iseq->local_table_size = len; @@ -6332,7 +6185,7 @@ typedef struct { static VALUE method_for_self(VALUE name, VALUE arg, rb_insn_func_t func, - VALUE (*build)(rb_iseq_t *, LINK_ANCHOR *, VALUE)) + VALUE (*build)(rb_iseq_t *, struct list_head *, VALUE)) { VALUE path, absolute_path; accessor_args acc; @@ -6346,7 +6199,7 @@ method_for_self(VALUE name, VALUE arg, rb_insn_func_t func, } static VALUE -for_self_aref(rb_iseq_t *iseq, LINK_ANCHOR *ret, VALUE a) +for_self_aref(rb_iseq_t *iseq, struct list_head *ret, VALUE a) { const accessor_args *const args = (void *)a; const int line = args->line; @@ -6361,7 +6214,7 @@ for_self_aref(rb_iseq_t *iseq, LINK_ANCHOR *ret, VALUE a) } static VALUE -for_self_aset(rb_iseq_t *iseq, LINK_ANCHOR *ret, VALUE a) +for_self_aset(rb_iseq_t *iseq, struct list_head *ret, VALUE a) { const accessor_args *const args = (void *)a; const int line = args->line; -- EW