Created
October 3, 2012 17:19
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/compile.c b/compile.c | |
index 535084b..1a2a3c0 100644 | |
--- a/compile.c | |
+++ b/compile.c | |
@@ -284,6 +284,17 @@ r_value(VALUE value) | |
ret = 0; \ | |
break; \ | |
} | |
+#define COMPILE_ERROR_RETURN(strs) \ | |
+{ \ | |
+ VALUE tmp = GET_THREAD()->errinfo; \ | |
+ if (compile_debug) rb_compile_bug strs; \ | |
+ GET_THREAD()->errinfo = iseq->compile_data->err_info; \ | |
+ rb_compile_error strs; \ | |
+ iseq->compile_data->err_info = GET_THREAD()->errinfo; \ | |
+ GET_THREAD()->errinfo = tmp; \ | |
+ ret = 0; \ | |
+ return; \ | |
+} | |
#define ERROR_ARGS ruby_sourcefile, nd_line(node), | |
@@ -2224,6 +2235,43 @@ compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node) | |
} | |
static int | |
+compile_xstr(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node) | |
+{ | |
+ OBJ_FREEZE(node->nd_lit); | |
+ ADD_CALL_RECEIVER(ret, nd_line(node)); | |
+ ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit); | |
+ ADD_CALL(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1)); | |
+ return COMPILE_OK; | |
+} | |
+ | |
+static int | |
+compile_dxstr(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node) | |
+{ | |
+ ADD_CALL_RECEIVER(ret, nd_line(node)); | |
+ compile_dstr(iseq, ret, node); | |
+ ADD_CALL(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1)); | |
+ return COMPILE_OK; | |
+} | |
+ | |
+static int | |
+compile_dregx_once(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node) | |
+{ | |
+ /* TODO: once? */ | |
+ LABEL *lend = NEW_LABEL(nd_line(node)); | |
+ int ic_index = iseq->ic_size++; | |
+ | |
+ ADD_INSN2(ret, nd_line(node), onceinlinecache, lend, INT2FIX(ic_index)); | |
+ ADD_INSN(ret, nd_line(node), pop); | |
+ | |
+ compile_dregx(iseq, ret, node); | |
+ | |
+ ADD_INSN1(ret, nd_line(node), setinlinecache, INT2FIX(ic_index)); | |
+ ADD_LABEL(ret, lend); | |
+ | |
+ return COMPILE_OK; | |
+} | |
+ | |
+static int | |
compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * cond, | |
LABEL *then_label, LABEL *else_label) | |
{ | |
@@ -3080,80 +3128,58 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *args, NODE *argn, VALUE *flag) | |
return argc; | |
} | |
- | |
-/** | |
- compile each node | |
- | |
- self: InstructionSequence | |
- node: Ruby compiled node | |
- poped: This node will be poped | |
- */ | |
-static int | |
-iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+static void | |
+compile_block_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int poped) | |
{ | |
enum node_type type; | |
- if (node == 0) { | |
- if (!poped) { | |
- debugs("node: NODE_NIL(implicit)\n"); | |
- ADD_INSN(ret, iseq->compile_data->last_line, putnil); | |
- } | |
- return COMPILE_OK; | |
- } | |
- | |
- iseq->compile_data->last_line = (int)nd_line(node); | |
- debug_node_start(node); | |
- | |
type = nd_type(node); | |
- | |
- if (node->flags & NODE_FL_NEWLINE) { | |
- ADD_TRACE(ret, nd_line(node), RUBY_EVENT_LINE); | |
+ while (node && nd_type(node) == NODE_BLOCK) { | |
+ COMPILE_(ret, "BLOCK body", node->nd_head, | |
+ (node->nd_next == 0 && poped == 0) ? 0 : 1); | |
+ node = node->nd_next; | |
+ } | |
+ if (node) { | |
+ COMPILE_(ret, "BLOCK next", node->nd_next, poped); | |
} | |
+} | |
- switch (type) { | |
- case NODE_BLOCK:{ | |
- while (node && nd_type(node) == NODE_BLOCK) { | |
- COMPILE_(ret, "BLOCK body", node->nd_head, | |
- (node->nd_next == 0 && poped == 0) ? 0 : 1); | |
- node = node->nd_next; | |
- } | |
- if (node) { | |
- COMPILE_(ret, "BLOCK next", node->nd_next, poped); | |
- } | |
- break; | |
- } | |
- case NODE_IF:{ | |
- DECL_ANCHOR(cond_seq); | |
- DECL_ANCHOR(then_seq); | |
- DECL_ANCHOR(else_seq); | |
- LABEL *then_label, *else_label, *end_label; | |
+static void | |
+compile_if_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int poped) | |
+{ | |
+ DECL_ANCHOR(cond_seq); | |
+ DECL_ANCHOR(then_seq); | |
+ 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(nd_line(node)); | |
- else_label = NEW_LABEL(nd_line(node)); | |
- end_label = NEW_LABEL(nd_line(node)); | |
+ INIT_ANCHOR(cond_seq); | |
+ INIT_ANCHOR(then_seq); | |
+ INIT_ANCHOR(else_seq); | |
+ then_label = NEW_LABEL(nd_line(node)); | |
+ else_label = NEW_LABEL(nd_line(node)); | |
+ end_label = NEW_LABEL(nd_line(node)); | |
- compile_branch_condition(iseq, 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); | |
+ compile_branch_condition(iseq, 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); | |
- ADD_SEQ(ret, cond_seq); | |
+ ADD_SEQ(ret, cond_seq); | |
- ADD_LABEL(ret, then_label); | |
- ADD_SEQ(ret, then_seq); | |
- ADD_INSNL(ret, nd_line(node), jump, end_label); | |
+ ADD_LABEL(ret, then_label); | |
+ 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_LABEL(ret, else_label); | |
+ ADD_SEQ(ret, else_seq); | |
- ADD_LABEL(ret, end_label); | |
+ ADD_LABEL(ret, end_label); | |
+} | |
- break; | |
- } | |
- case NODE_CASE:{ | |
+static void | |
+compile_case_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int poped) | |
+{ | |
+ enum node_type type; | |
NODE *vals; | |
NODE *tempnode = node; | |
LABEL *endlabel, *elselabel; | |
@@ -3163,6 +3189,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
int only_special_literals = 1; | |
VALUE literals = rb_hash_new(); | |
+ type = nd_type(node); | |
INIT_ANCHOR(head); | |
INIT_ANCHOR(body_seq); | |
INIT_ANCHOR(cond_seq); | |
@@ -3171,7 +3198,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (node->nd_head == 0) { | |
COMPILE_(ret, "when", node->nd_body, poped); | |
- break; | |
+ return; | |
} | |
COMPILE(head, "case base", node->nd_head); | |
@@ -3179,7 +3206,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
type = nd_type(node); | |
if (type != NODE_WHEN) { | |
- COMPILE_ERROR((ERROR_ARGS "NODE_CASE: unexpected node. must be NODE_WHEN, but %s", ruby_node_name(type))); | |
+ COMPILE_ERROR_RETURN((ERROR_ARGS "NODE_CASE: unexpected node. must be NODE_WHEN, but %s", ruby_node_name(type))); | |
} | |
endlabel = NEW_LABEL(nd_line(node)); | |
@@ -3253,9 +3280,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
ADD_SEQ(ret, cond_seq); | |
ADD_SEQ(ret, body_seq); | |
ADD_LABEL(ret, endlabel); | |
- break; | |
- } | |
- case NODE_WHEN:{ | |
+} | |
+ | |
+static void | |
+compile_when_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
NODE *vals; | |
NODE *val; | |
NODE *orig_node = node; | |
@@ -3304,12 +3333,12 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
ADD_SEQ(ret, body_seq); | |
ADD_LABEL(ret, endlabel); | |
+} | |
- break; | |
- } | |
- case NODE_OPT_N: | |
- case NODE_WHILE: | |
- case NODE_UNTIL:{ | |
+static void | |
+compile_while_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
+ enum node_type type; | |
LABEL *prev_start_label = iseq->compile_data->start_label; | |
LABEL *prev_end_label = iseq->compile_data->end_label; | |
LABEL *prev_redo_label = iseq->compile_data->redo_label; | |
@@ -3328,6 +3357,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
iseq->compile_data->loopval_popped = 0; | |
push_ensure_entry(iseq, &enl, 0, 0); | |
+ type = nd_type(node); | |
if (type == NODE_OPT_N || node->nd_state == 1) { | |
ADD_INSNL(ret, nd_line(node), jump, next_label); | |
} | |
@@ -3389,10 +3419,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
iseq->compile_data->redo_label = prev_redo_label; | |
iseq->compile_data->loopval_popped = prev_loopval_popped; | |
iseq->compile_data->ensure_node_stack = iseq->compile_data->ensure_node_stack->prev; | |
- break; | |
- } | |
- case NODE_ITER: | |
- case NODE_FOR:{ | |
+} | |
+ | |
+static void | |
+compile_for_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
VALUE prevblock = iseq->compile_data->current_block; | |
LABEL *retry_label = NEW_LABEL(nd_line(node)); | |
LABEL *retry_end_l = NEW_LABEL(nd_line(node)); | |
@@ -3423,10 +3454,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
iseq->compile_data->current_block = prevblock; | |
ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, retry_label, retry_end_l, 0, retry_end_l); | |
+} | |
- break; | |
- } | |
- case NODE_BREAK:{ | |
+static void | |
+compile_break_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
unsigned long level = 0; | |
if (iseq->compile_data->redo_label != 0) { | |
@@ -3454,7 +3486,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
else if (iseq->type == ISEQ_TYPE_EVAL) { | |
break_in_eval: | |
- COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with break")); | |
+ COMPILE_ERROR_RETURN((ERROR_ARGS "Can't escape from eval with break")); | |
} | |
else { | |
rb_iseq_t *ip = iseq->parent_iseq; | |
@@ -3483,11 +3515,13 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
ip = ip->parent_iseq; | |
} | |
- COMPILE_ERROR((ERROR_ARGS "Invalid break")); | |
+ COMPILE_ERROR_RETURN((ERROR_ARGS "Invalid break")); | |
} | |
- break; | |
- } | |
- case NODE_NEXT:{ | |
+} | |
+ | |
+static void | |
+compile_next_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
unsigned long level = 0; | |
if (iseq->compile_data->redo_label != 0) { | |
@@ -3519,7 +3553,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
else if (iseq->type == ISEQ_TYPE_EVAL) { | |
next_in_eval: | |
- COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with next")); | |
+ COMPILE_ERROR_RETURN((ERROR_ARGS "Can't escape from eval with next")); | |
} | |
else { | |
rb_iseq_t *ip; | |
@@ -3553,12 +3587,14 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
} | |
else { | |
- COMPILE_ERROR((ERROR_ARGS "Invalid next")); | |
+ COMPILE_ERROR_RETURN((ERROR_ARGS "Invalid next")); | |
} | |
} | |
- break; | |
- } | |
- case NODE_REDO:{ | |
+} | |
+ | |
+static void | |
+compile_redo_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
if (iseq->compile_data->redo_label) { | |
LABEL *splabel = NEW_LABEL(0); | |
debugs("redo in while"); | |
@@ -3573,7 +3609,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
else if (iseq->type == ISEQ_TYPE_EVAL) { | |
redo_in_eval: | |
- COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with redo")); | |
+ COMPILE_ERROR_RETURN((ERROR_ARGS "Can't escape from eval with redo")); | |
} | |
else if (iseq->compile_data->start_label) { | |
LABEL *splabel = NEW_LABEL(0); | |
@@ -3621,12 +3657,14 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
} | |
else { | |
- COMPILE_ERROR((ERROR_ARGS "Invalid redo")); | |
+ COMPILE_ERROR_RETURN((ERROR_ARGS "Invalid redo")); | |
} | |
} | |
- break; | |
- } | |
- case NODE_RETRY:{ | |
+} | |
+ | |
+static void | |
+compile_retry_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
if (iseq->type == ISEQ_TYPE_RESCUE) { | |
ADD_INSN(ret, nd_line(node), putnil); | |
ADD_INSN1(ret, nd_line(node), throw, INT2FIX(0x04) /* TAG_RETRY */ ); | |
@@ -3636,15 +3674,13 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
} | |
else { | |
- COMPILE_ERROR((ERROR_ARGS "Invalid retry")); | |
+ COMPILE_ERROR_RETURN((ERROR_ARGS "Invalid retry")); | |
} | |
- break; | |
- } | |
- case NODE_BEGIN:{ | |
- COMPILE_(ret, "NODE_BEGIN", node->nd_body, poped); | |
- break; | |
- } | |
- case NODE_RESCUE:{ | |
+} | |
+ | |
+static void | |
+compile_rescue_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
LABEL *lstart = NEW_LABEL(nd_line(node)); | |
LABEL *lend = NEW_LABEL(nd_line(node)); | |
LABEL *lcont = NEW_LABEL(nd_line(node)); | |
@@ -3670,9 +3706,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
/* register catch entry */ | |
ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue, lcont); | |
ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, lend, lcont, 0, lstart); | |
- break; | |
- } | |
- case NODE_RESBODY:{ | |
+} | |
+ | |
+static void | |
+compile_resbody_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
NODE *resq = node; | |
NODE *narg; | |
LABEL *label_miss, *label_hit; | |
@@ -3722,9 +3760,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
ADD_LABEL(ret, label_miss); | |
resq = resq->nd_head; | |
} | |
- break; | |
- } | |
- case NODE_ENSURE:{ | |
+} | |
+ | |
+static void | |
+compile_ensure_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
DECL_ANCHOR(ensr); | |
VALUE ensure = NEW_CHILD_ISEQVAL(node->nd_ensr, | |
rb_str_concat(rb_str_new2 | |
@@ -3765,11 +3805,12 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
iseq->compile_data->ensure_node_stack = enl.prev; | |
- break; | |
- } | |
+} | |
- case NODE_AND: | |
- case NODE_OR:{ | |
+static void | |
+compile_and_or_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
+ enum node_type type = nd_type(node); | |
LABEL *end_label = NEW_LABEL(nd_line(node)); | |
COMPILE(ret, "nd_1st", node->nd_1st); | |
if (!poped) { | |
@@ -3786,15 +3827,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
COMPILE_(ret, "nd_2nd", node->nd_2nd, poped); | |
ADD_LABEL(ret, end_label); | |
- break; | |
- } | |
- | |
- case NODE_MASGN:{ | |
- compile_massign(iseq, ret, node, poped); | |
- break; | |
- } | |
+} | |
- case NODE_LASGN:{ | |
+static void | |
+compile_lasgn_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
ID id = node->nd_vid; | |
int idx = iseq->local_iseq->local_size - get_local_var_idx(iseq, id); | |
@@ -3805,11 +3842,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
ADD_INSN(ret, nd_line(node), dup); | |
} | |
ADD_INSN1(ret, nd_line(node), setlocal, INT2FIX(idx)); | |
+} | |
- break; | |
- } | |
- case NODE_DASGN: | |
- case NODE_DASGN_CURR:{ | |
+static void | |
+compile_dasgn_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
int idx, lv, ls; | |
COMPILE(ret, "dvalue", node->nd_value); | |
debugp_param("dassn id", rb_str_new2(rb_id2name(node->nd_vid) ? rb_id2name(node->nd_vid) : "*")); | |
@@ -3826,9 +3863,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
ADD_INSN2(ret, nd_line(node), setdynamic, | |
INT2FIX(ls - idx), INT2FIX(lv)); | |
- break; | |
- } | |
- case NODE_GASGN:{ | |
+} | |
+ | |
+static void | |
+compile_gasgn_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
COMPILE(ret, "lvalue", node->nd_value); | |
if (!poped) { | |
@@ -3836,19 +3875,22 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
ADD_INSN1(ret, nd_line(node), setglobal, | |
((VALUE)node->nd_entry | 1)); | |
- break; | |
- } | |
- case NODE_IASGN: | |
- case NODE_IASGN2:{ | |
+} | |
+ | |
+static void | |
+compile_iasgn_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
COMPILE(ret, "lvalue", node->nd_value); | |
if (!poped) { | |
ADD_INSN(ret, nd_line(node), dup); | |
} | |
ADD_INSN2(ret, nd_line(node), setinstancevariable, | |
ID2SYM(node->nd_vid), INT2FIX(iseq->ic_size++)); | |
- break; | |
- } | |
- case NODE_CDECL:{ | |
+} | |
+ | |
+static void | |
+compile_cdecl_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
COMPILE(ret, "lvalue", node->nd_value); | |
if (!poped) { | |
@@ -3864,18 +3906,22 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
compile_cpath(ret, iseq, node->nd_else); | |
ADD_INSN1(ret, nd_line(node), setconstant, ID2SYM(node->nd_else->nd_mid)); | |
} | |
- break; | |
- } | |
- case NODE_CVASGN:{ | |
+} | |
+ | |
+static void | |
+compile_cvasgn_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
COMPILE(ret, "cvasgn val", node->nd_value); | |
if (!poped) { | |
ADD_INSN(ret, nd_line(node), dup); | |
} | |
ADD_INSN1(ret, nd_line(node), setclassvariable, | |
ID2SYM(node->nd_vid)); | |
- break; | |
- } | |
- case NODE_OP_ASGN1: { | |
+} | |
+ | |
+static void | |
+compile_op_asgn1_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
DECL_ANCHOR(args); | |
VALUE argc; | |
VALUE flag = 0; | |
@@ -4012,10 +4058,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
+} | |
- break; | |
- } | |
- case NODE_OP_ASGN2:{ | |
+static void | |
+compile_op_asgn2_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
ID atype = node->nd_next->nd_mid; | |
LABEL *lfin = NEW_LABEL(nd_line(node)); | |
LABEL *lcfin = NEW_LABEL(nd_line(node)); | |
@@ -4104,10 +4151,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
INT2FIX(1)); | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_OP_ASGN_AND: | |
- case NODE_OP_ASGN_OR:{ | |
+} | |
+ | |
+static void | |
+compile_op_asgn_and_or_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
LABEL *lfin = NEW_LABEL(nd_line(node)); | |
LABEL *lassign; | |
@@ -4145,11 +4193,13 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
/* we can apply more optimize */ | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_CALL: | |
- case NODE_FCALL: | |
- case NODE_VCALL:{ /* VCALL: variable or call */ | |
+} | |
+ | |
+static void | |
+compile_call_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
+ enum node_type type; | |
+ | |
/* | |
call: obj.method(...) | |
fcall: func(...) | |
@@ -4165,15 +4215,17 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
INIT_ANCHOR(recv); | |
INIT_ANCHOR(args); | |
+ | |
+ type = nd_type(node); | |
#if SUPPORT_JOKE | |
if (nd_type(node) == NODE_VCALL) { | |
if (mid == idBitblt) { | |
ADD_INSN(ret, nd_line(node), bitblt); | |
- break; | |
+ return; | |
} | |
else if (mid == idAnswer) { | |
ADD_INSN(ret, nd_line(node), answer); | |
- break; | |
+ return; | |
} | |
} | |
/* only joke */ | |
@@ -4209,7 +4261,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
} | |
else { | |
- COMPILE_ERROR((ERROR_ARGS "invalid goto/label format")); | |
+ COMPILE_ERROR_RETURN((ERROR_ARGS "invalid goto/label format")); | |
} | |
@@ -4219,7 +4271,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
else { | |
ADD_LABEL(ret, label); | |
} | |
- break; | |
+ return; | |
} | |
} | |
#endif | |
@@ -4259,10 +4311,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_SUPER: | |
- case NODE_ZSUPER:{ | |
+} | |
+ | |
+static void | |
+compile_super_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
DECL_ANCHOR(args); | |
VALUE argc; | |
VALUE flag = 0; | |
@@ -4343,19 +4396,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_ARRAY:{ | |
- compile_array_(iseq, ret, node, COMPILE_ARRAY_TYPE_ARRAY, poped); | |
- break; | |
- } | |
- case NODE_ZARRAY:{ | |
- if (!poped) { | |
- ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(0)); | |
- } | |
- break; | |
- } | |
- case NODE_VALUES:{ | |
+} | |
+ | |
+static void | |
+compile_values_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
NODE *n = node; | |
while (n) { | |
COMPILE(ret, "values item", n->nd_head); | |
@@ -4365,9 +4410,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_HASH:{ | |
+} | |
+ | |
+static void | |
+compile_hash_(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; | |
@@ -4389,14 +4436,16 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_RETURN:{ | |
+} | |
+ | |
+static void | |
+compile_return_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
rb_iseq_t *is = iseq; | |
if (is) { | |
if (is->type == ISEQ_TYPE_TOP) { | |
- COMPILE_ERROR((ERROR_ARGS "Invalid return")); | |
+ COMPILE_ERROR_RETURN((ERROR_ARGS "Invalid return")); | |
} | |
else { | |
LABEL *splabel = 0; | |
@@ -4427,16 +4476,18 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
} | |
} | |
- break; | |
- } | |
- case NODE_YIELD:{ | |
+} | |
+ | |
+static void | |
+compile_yield_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
DECL_ANCHOR(args); | |
VALUE argc; | |
VALUE flag = 0; | |
INIT_ANCHOR(args); | |
if (iseq->type == ISEQ_TYPE_TOP) { | |
- COMPILE_ERROR((ERROR_ARGS "Invalid yield")); | |
+ COMPILE_ERROR_RETURN((ERROR_ARGS "Invalid yield")); | |
} | |
if (node->nd_head) { | |
@@ -4452,9 +4503,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_LVAR:{ | |
+} | |
+ | |
+static void | |
+compile_lvar_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
if (!poped) { | |
ID id = node->nd_vid; | |
int idx = iseq->local_iseq->local_size - get_local_var_idx(iseq, id); | |
@@ -4462,9 +4515,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
debugs("id: %s idx: %d\n", rb_id2name(id), idx); | |
ADD_INSN1(ret, nd_line(node), getlocal, INT2FIX(idx)); | |
} | |
- break; | |
- } | |
- case NODE_DVAR:{ | |
+} | |
+ | |
+static void | |
+compile_dvar_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
int lv, idx, ls; | |
debugi("nd_vid", node->nd_vid); | |
if (!poped) { | |
@@ -4474,25 +4529,31 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(ls - idx), INT2FIX(lv)); | |
} | |
- break; | |
- } | |
- case NODE_GVAR:{ | |
+} | |
+ | |
+static void | |
+compile_gvar_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
ADD_INSN1(ret, nd_line(node), getglobal, | |
((VALUE)node->nd_entry | 1)); | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_IVAR:{ | |
+} | |
+ | |
+static void | |
+compile_ivar_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
debugi("nd_vid", node->nd_vid); | |
if (!poped) { | |
ADD_INSN2(ret, nd_line(node), getinstancevariable, | |
ID2SYM(node->nd_vid), INT2FIX(iseq->ic_size++)); | |
} | |
- break; | |
- } | |
- case NODE_CONST:{ | |
+} | |
+ | |
+static void | |
+compile_const_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
debugi("nd_vid", node->nd_vid); | |
if (iseq->compile_data->option->inline_const_cache) { | |
@@ -4512,32 +4573,38 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_CVAR:{ | |
+} | |
+ | |
+static void | |
+compile_cvar_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
if (!poped) { | |
ADD_INSN1(ret, nd_line(node), getclassvariable, | |
ID2SYM(node->nd_vid)); | |
} | |
- break; | |
- } | |
- case NODE_NTH_REF:{ | |
+} | |
+ | |
+static void | |
+compile_nth_ref_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
if (!poped) { | |
ADD_INSN2(ret, nd_line(node), getspecial, INT2FIX(1) /* '~' */, | |
INT2FIX(node->nd_nth << 1)); | |
} | |
- break; | |
- } | |
- case NODE_BACK_REF:{ | |
+} | |
+ | |
+static void | |
+compile_back_ref_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
if (!poped) { | |
ADD_INSN2(ret, nd_line(node), getspecial, INT2FIX(1) /* '~' */, | |
INT2FIX(0x01 | (node->nd_nth << 1))); | |
} | |
- break; | |
- } | |
- case NODE_MATCH: | |
- case NODE_MATCH2: | |
- case NODE_MATCH3:{ | |
+} | |
+ | |
+static void | |
+compile_match_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
DECL_ANCHOR(recv); | |
DECL_ANCHOR(val); | |
@@ -4583,90 +4650,30 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_LIT:{ | |
+} | |
+ | |
+static void | |
+compile_lit_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
debugp_param("lit", node->nd_lit); | |
if (!poped) { | |
ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit); | |
} | |
- break; | |
- } | |
- case NODE_STR:{ | |
+} | |
+ | |
+static void | |
+compile_str_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
debugp_param("nd_lit", node->nd_lit); | |
if (!poped) { | |
OBJ_FREEZE(node->nd_lit); | |
ADD_INSN1(ret, nd_line(node), putstring, node->nd_lit); | |
} | |
- break; | |
- } | |
- case NODE_DSTR:{ | |
- compile_dstr(iseq, ret, node); | |
- | |
- if (poped) { | |
- ADD_INSN(ret, nd_line(node), pop); | |
- } | |
- break; | |
- } | |
- case NODE_XSTR:{ | |
- OBJ_FREEZE(node->nd_lit); | |
- ADD_CALL_RECEIVER(ret, nd_line(node)); | |
- ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit); | |
- ADD_CALL(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1)); | |
- | |
- if (poped) { | |
- ADD_INSN(ret, nd_line(node), pop); | |
- } | |
- break; | |
- } | |
- case NODE_DXSTR:{ | |
- ADD_CALL_RECEIVER(ret, nd_line(node)); | |
- compile_dstr(iseq, ret, node); | |
- ADD_CALL(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1)); | |
- | |
- if (poped) { | |
- ADD_INSN(ret, nd_line(node), pop); | |
- } | |
- break; | |
- } | |
- case NODE_EVSTR:{ | |
- COMPILE(ret, "nd_body", node->nd_body); | |
- | |
- if (poped) { | |
- ADD_INSN(ret, nd_line(node), pop); | |
- } | |
- else { | |
- ADD_INSN(ret, nd_line(node), tostring); | |
- } | |
- break; | |
- } | |
- case NODE_DREGX:{ | |
- compile_dregx(iseq, ret, node); | |
- | |
- if (poped) { | |
- ADD_INSN(ret, nd_line(node), pop); | |
- } | |
- break; | |
- } | |
- case NODE_DREGX_ONCE:{ | |
- /* TODO: once? */ | |
- LABEL *lend = NEW_LABEL(nd_line(node)); | |
- int ic_index = iseq->ic_size++; | |
- | |
- ADD_INSN2(ret, nd_line(node), onceinlinecache, lend, INT2FIX(ic_index)); | |
- ADD_INSN(ret, nd_line(node), pop); | |
- | |
- compile_dregx(iseq, ret, node); | |
- | |
- ADD_INSN1(ret, nd_line(node), setinlinecache, INT2FIX(ic_index)); | |
- ADD_LABEL(ret, lend); | |
+} | |
- if (poped) { | |
- ADD_INSN(ret, nd_line(node), pop); | |
- } | |
- break; | |
- } | |
- case NODE_ARGSCAT:{ | |
+static void | |
+compile_argscat(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
if (poped) { | |
COMPILE(ret, "argscat head", node->nd_head); | |
ADD_INSN1(ret, nd_line(node), splatarray, Qfalse); | |
@@ -4680,9 +4687,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
COMPILE(ret, "argscat body", node->nd_body); | |
ADD_INSN(ret, nd_line(node), concatarray); | |
} | |
- break; | |
- } | |
- case NODE_ARGSPUSH:{ | |
+} | |
+ | |
+static void | |
+compile_argspush(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
if (poped) { | |
COMPILE(ret, "arsgpush head", node->nd_head); | |
ADD_INSN1(ret, nd_line(node), splatarray, Qfalse); | |
@@ -4695,18 +4704,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(1)); | |
ADD_INSN(ret, nd_line(node), concatarray); | |
} | |
- break; | |
- } | |
- case NODE_SPLAT:{ | |
- COMPILE(ret, "splat", node->nd_head); | |
- ADD_INSN1(ret, nd_line(node), splatarray, Qtrue); | |
+} | |
- if (poped) { | |
- ADD_INSN(ret, nd_line(node), pop); | |
- } | |
- break; | |
- } | |
- case NODE_DEFN:{ | |
+static void | |
+compile_defn(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
VALUE iseqval = NEW_ISEQVAL(node->nd_defn, | |
rb_str_dup(rb_id2str(node->nd_mid)), | |
ISEQ_TYPE_METHOD, nd_line(node)); | |
@@ -4724,9 +4726,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
debugp_param("defn", iseqval); | |
- break; | |
- } | |
- case NODE_DEFS:{ | |
+} | |
+ | |
+static void | |
+compile_defs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
VALUE iseqval = NEW_ISEQVAL(node->nd_defn, | |
rb_str_dup(rb_id2str(node->nd_mid)), | |
ISEQ_TYPE_METHOD, nd_line(node)); | |
@@ -4742,9 +4746,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_ALIAS:{ | |
+} | |
+ | |
+static void | |
+compile_alias(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
ADD_INSN1(ret, nd_line(node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); | |
ADD_INSN1(ret, nd_line(node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE)); | |
COMPILE(ret, "alias arg1", node->u1.node); | |
@@ -4754,9 +4760,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_VALIAS:{ | |
+} | |
+ | |
+static void | |
+compile_valias(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
ADD_INSN1(ret, nd_line(node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); | |
ADD_INSN1(ret, nd_line(node), putobject, ID2SYM(node->u1.id)); | |
ADD_INSN1(ret, nd_line(node), putobject, ID2SYM(node->u2.id)); | |
@@ -4765,9 +4773,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_UNDEF:{ | |
+} | |
+ | |
+static void | |
+compile_undef(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
ADD_INSN1(ret, nd_line(node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); | |
ADD_INSN1(ret, nd_line(node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE)); | |
COMPILE(ret, "undef arg", node->u2.node); | |
@@ -4776,9 +4786,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_CLASS:{ | |
+} | |
+ | |
+static void | |
+compile_class(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
VALUE iseqval = | |
NEW_CHILD_ISEQVAL( | |
node->nd_body, | |
@@ -4792,9 +4804,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_MODULE:{ | |
+} | |
+ | |
+static void | |
+compile_module(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
VALUE iseqval = NEW_CHILD_ISEQVAL( | |
node->nd_body, | |
rb_sprintf("<module:%s>", rb_id2name(node->nd_cpath->nd_mid)), | |
@@ -4807,9 +4821,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_SCLASS:{ | |
+} | |
+ | |
+static void | |
+compile_sclass(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
ID singletonclass; | |
VALUE iseqval = | |
NEW_ISEQVAL(node->nd_body, rb_str_new2("singleton class"), | |
@@ -4824,9 +4840,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_COLON2:{ | |
+} | |
+ | |
+static void | |
+compile_colon2_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
if (rb_is_const_id(node->nd_mid)) { | |
/* constant */ | |
LABEL *lend = NEW_LABEL(nd_line(node)); | |
@@ -4868,9 +4886,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_COLON3:{ | |
+} | |
+ | |
+static void | |
+compile_colon3(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
LABEL *lend = NEW_LABEL(nd_line(node)); | |
int ic_index = iseq->ic_size++; | |
@@ -4893,10 +4913,12 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_DOT2: | |
- case NODE_DOT3:{ | |
+} | |
+ | |
+static void | |
+compile_dots(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
+ enum node_type type = nd_type(node); | |
VALUE flag = type == NODE_DOT2 ? INT2FIX(0) : INT2FIX(1); | |
COMPILE(ret, "min", (NODE *) node->nd_beg); | |
COMPILE(ret, "max", (NODE *) node->nd_end); | |
@@ -4907,10 +4929,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
else { | |
ADD_INSN1(ret, nd_line(node), newrange, flag); | |
} | |
- break; | |
- } | |
- case NODE_FLIP2: | |
- case NODE_FLIP3:{ | |
+} | |
+ | |
+static void | |
+compile_flipflop(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
LABEL *lend = NEW_LABEL(nd_line(node)); | |
LABEL *lfin = NEW_LABEL(nd_line(node)); | |
LABEL *ltrue = NEW_LABEL(nd_line(node)); | |
@@ -4947,33 +4970,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
ADD_INSN1(ret, nd_line(node), putobject, Qtrue); | |
ADD_LABEL(ret, lfin); | |
- break; | |
- } | |
- case NODE_SELF:{ | |
- if (!poped) { | |
- ADD_INSN(ret, nd_line(node), putself); | |
- } | |
- break; | |
- } | |
- case NODE_NIL:{ | |
- if (!poped) { | |
- ADD_INSN(ret, nd_line(node), putnil); | |
- } | |
- break; | |
- } | |
- case NODE_TRUE:{ | |
- if (!poped) { | |
- ADD_INSN1(ret, nd_line(node), putobject, Qtrue); | |
- } | |
- break; | |
- } | |
- case NODE_FALSE:{ | |
- if (!poped) { | |
- ADD_INSN1(ret, nd_line(node), putobject, Qfalse); | |
- } | |
- break; | |
- } | |
- case NODE_ERRINFO:{ | |
+} | |
+ | |
+static void | |
+compile_errinfo(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
if (!poped) { | |
if (iseq->type == ISEQ_TYPE_RESCUE) { | |
ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0)); | |
@@ -4996,9 +4997,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
} | |
} | |
- break; | |
- } | |
- case NODE_DEFINED:{ | |
+} | |
+ | |
+static void | |
+compile_defined(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
if (!poped) { | |
LABEL *lfinish[2]; | |
lfinish[0] = NEW_LABEL(nd_line(node)); | |
@@ -5012,9 +5015,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
ADD_LABEL(ret, lfinish[0]); | |
} | |
- break; | |
- } | |
- case NODE_POSTEXE:{ | |
+} | |
+ | |
+static void | |
+compile_postexe(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
LABEL *lend = NEW_LABEL(nd_line(node)); | |
VALUE block = NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, nd_line(node)); | |
int ic_index = iseq->ic_size++; | |
@@ -5032,9 +5037,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
- break; | |
- } | |
- case NODE_KW_ARG:{ | |
+} | |
+ | |
+static void | |
+compile_kw_arg(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
LABEL *default_label = NEW_LABEL(nd_line(node)); | |
LABEL *end_label = NEW_LABEL(nd_line(node)); | |
int idx, lv, ls; | |
@@ -5064,19 +5071,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
ADD_LABEL(ret, default_label); | |
COMPILE_POPED(ret, "keyword default argument", node->nd_body); | |
ADD_LABEL(ret, end_label); | |
- break; | |
- } | |
- case NODE_DSYM:{ | |
- compile_dstr(iseq, ret, node); | |
- if (!poped) { | |
- ADD_SEND(ret, nd_line(node), ID2SYM(idIntern), INT2FIX(0)); | |
- } | |
- else { | |
- ADD_INSN(ret, nd_line(node), pop); | |
- } | |
- break; | |
- } | |
- case NODE_ATTRASGN:{ | |
+} | |
+ | |
+static void | |
+compile_attrasgn(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
DECL_ANCHOR(recv); | |
DECL_ANCHOR(args); | |
VALUE flag = 0; | |
@@ -5128,15 +5127,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
} | |
ADD_SEND_R(ret, nd_line(node), ID2SYM(node->nd_mid), argc, 0, LONG2FIX(flag)); | |
ADD_INSN(ret, nd_line(node), pop); | |
+} | |
- break; | |
- } | |
- case NODE_PRELUDE:{ | |
- COMPILE_POPED(ret, "prelude", node->nd_head); | |
- COMPILE_(ret, "body", node->nd_body, poped); | |
- break; | |
- } | |
- case NODE_LAMBDA:{ | |
+static void | |
+compile_lambda(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
/* compile same as lambda{...} */ | |
VALUE block = NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, nd_line(node)); | |
VALUE argc = INT2FIX(0); | |
@@ -5146,6 +5141,411 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
if (poped) { | |
ADD_INSN(ret, nd_line(node), pop); | |
} | |
+} | |
+ | |
+/** | |
+ compile each node | |
+ | |
+ self: InstructionSequence | |
+ node: Ruby compiled node | |
+ poped: This node will be poped | |
+ */ | |
+static int | |
+iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) | |
+{ | |
+ enum node_type type; | |
+ | |
+ if (node == 0) { | |
+ if (!poped) { | |
+ debugs("node: NODE_NIL(implicit)\n"); | |
+ ADD_INSN(ret, iseq->compile_data->last_line, putnil); | |
+ } | |
+ return COMPILE_OK; | |
+ } | |
+ | |
+ iseq->compile_data->last_line = (int)nd_line(node); | |
+ debug_node_start(node); | |
+ | |
+ type = nd_type(node); | |
+ printf("&type == %p\n", &type); | |
+ | |
+ if (node->flags & NODE_FL_NEWLINE) { | |
+ ADD_TRACE(ret, nd_line(node), RUBY_EVENT_LINE); | |
+ } | |
+ | |
+ switch (type) { | |
+ case NODE_BLOCK:{ | |
+ compile_block_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_IF:{ | |
+ compile_if_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_CASE:{ | |
+ compile_case_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_WHEN:{ | |
+ compile_when_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_OPT_N: | |
+ case NODE_WHILE: | |
+ case NODE_UNTIL:{ | |
+ compile_while_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_ITER: | |
+ case NODE_FOR:{ | |
+ compile_for_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_BREAK:{ | |
+ compile_break_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_NEXT:{ | |
+ compile_next_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_REDO:{ | |
+ compile_redo_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_RETRY:{ | |
+ compile_retry_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_BEGIN:{ | |
+ COMPILE_(ret, "NODE_BEGIN", node->nd_body, poped); | |
+ break; | |
+ } | |
+ case NODE_RESCUE:{ | |
+ compile_rescue_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_RESBODY:{ | |
+ compile_resbody_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_ENSURE:{ | |
+ compile_ensure_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ | |
+ case NODE_AND: | |
+ case NODE_OR:{ | |
+ compile_and_or_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ | |
+ case NODE_MASGN:{ | |
+ compile_massign(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ | |
+ case NODE_LASGN:{ | |
+ compile_lasgn_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_DASGN: | |
+ case NODE_DASGN_CURR:{ | |
+ compile_dasgn_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_GASGN:{ | |
+ compile_gasgn_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_IASGN: | |
+ case NODE_IASGN2:{ | |
+ compile_iasgn_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_CDECL:{ | |
+ compile_cdecl_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_CVASGN:{ | |
+ compile_cvasgn_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_OP_ASGN1: { | |
+ compile_op_asgn1_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_OP_ASGN2:{ | |
+ compile_op_asgn2_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_OP_ASGN_AND: | |
+ case NODE_OP_ASGN_OR:{ | |
+ compile_op_asgn_and_or_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_CALL: | |
+ case NODE_FCALL: | |
+ case NODE_VCALL:{ /* VCALL: variable or call */ | |
+ compile_call_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_SUPER: | |
+ case NODE_ZSUPER:{ | |
+ compile_super_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_ARRAY:{ | |
+ compile_array_(iseq, ret, node, COMPILE_ARRAY_TYPE_ARRAY, poped); | |
+ break; | |
+ } | |
+ case NODE_ZARRAY:{ | |
+ if (!poped) { | |
+ ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(0)); | |
+ } | |
+ break; | |
+ } | |
+ case NODE_VALUES:{ | |
+ compile_values_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_HASH:{ | |
+ compile_hash_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_RETURN:{ | |
+ compile_return_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_YIELD:{ | |
+ compile_yield_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_LVAR:{ | |
+ compile_lvar_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_DVAR:{ | |
+ compile_dvar_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_GVAR:{ | |
+ compile_gvar_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_IVAR:{ | |
+ compile_ivar_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_CONST:{ | |
+ compile_const_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_CVAR:{ | |
+ compile_cvar_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_NTH_REF:{ | |
+ compile_nth_ref_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_BACK_REF:{ | |
+ compile_back_ref_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_MATCH: | |
+ case NODE_MATCH2: | |
+ case NODE_MATCH3:{ | |
+ compile_match_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_LIT:{ | |
+ compile_lit_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_STR:{ | |
+ compile_str_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_DSTR:{ | |
+ compile_dstr(iseq, ret, node); | |
+ | |
+ if (poped) { | |
+ ADD_INSN(ret, nd_line(node), pop); | |
+ } | |
+ break; | |
+ } | |
+ case NODE_XSTR:{ | |
+ compile_xstr(iseq, ret, node); | |
+ | |
+ if (poped) { | |
+ ADD_INSN(ret, nd_line(node), pop); | |
+ } | |
+ break; | |
+ } | |
+ case NODE_DXSTR:{ | |
+ compile_dxstr(iseq, ret, node); | |
+ | |
+ if (poped) { | |
+ ADD_INSN(ret, nd_line(node), pop); | |
+ } | |
+ break; | |
+ } | |
+ case NODE_EVSTR:{ | |
+ COMPILE(ret, "nd_body", node->nd_body); | |
+ | |
+ if (poped) { | |
+ ADD_INSN(ret, nd_line(node), pop); | |
+ } | |
+ else { | |
+ ADD_INSN(ret, nd_line(node), tostring); | |
+ } | |
+ break; | |
+ } | |
+ case NODE_DREGX:{ | |
+ compile_dregx(iseq, ret, node); | |
+ | |
+ if (poped) { | |
+ ADD_INSN(ret, nd_line(node), pop); | |
+ } | |
+ break; | |
+ } | |
+ case NODE_DREGX_ONCE:{ | |
+ compile_dregx_once(iseq, ret, node); | |
+ | |
+ if (poped) { | |
+ ADD_INSN(ret, nd_line(node), pop); | |
+ } | |
+ break; | |
+ } | |
+ case NODE_ARGSCAT:{ | |
+ compile_argscat(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_ARGSPUSH:{ | |
+ compile_argspush(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_SPLAT:{ | |
+ COMPILE(ret, "splat", node->nd_head); | |
+ ADD_INSN1(ret, nd_line(node), splatarray, Qtrue); | |
+ | |
+ if (poped) { | |
+ ADD_INSN(ret, nd_line(node), pop); | |
+ } | |
+ break; | |
+ } | |
+ case NODE_DEFN:{ | |
+ compile_defn(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_DEFS:{ | |
+ compile_defs(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_ALIAS:{ | |
+ compile_alias(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_VALIAS:{ | |
+ compile_valias(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_UNDEF:{ | |
+ compile_undef(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_CLASS:{ | |
+ compile_class(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_MODULE:{ | |
+ compile_module(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_SCLASS:{ | |
+ compile_sclass(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_COLON2:{ | |
+ compile_colon2_(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_COLON3:{ | |
+ compile_colon3(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_DOT2: | |
+ case NODE_DOT3:{ | |
+ compile_dots(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_FLIP2: | |
+ case NODE_FLIP3:{ | |
+ compile_flipflop(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_SELF:{ | |
+ if (!poped) { | |
+ ADD_INSN(ret, nd_line(node), putself); | |
+ } | |
+ break; | |
+ } | |
+ case NODE_NIL:{ | |
+ if (!poped) { | |
+ ADD_INSN(ret, nd_line(node), putnil); | |
+ } | |
+ break; | |
+ } | |
+ case NODE_TRUE:{ | |
+ if (!poped) { | |
+ ADD_INSN1(ret, nd_line(node), putobject, Qtrue); | |
+ } | |
+ break; | |
+ } | |
+ case NODE_FALSE:{ | |
+ if (!poped) { | |
+ ADD_INSN1(ret, nd_line(node), putobject, Qfalse); | |
+ } | |
+ break; | |
+ } | |
+ case NODE_ERRINFO:{ | |
+ compile_errinfo(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_DEFINED:{ | |
+ compile_defined(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_POSTEXE:{ | |
+ compile_postexe(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_KW_ARG:{ | |
+ compile_kw_arg(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_DSYM:{ | |
+ compile_dstr(iseq, ret, node); | |
+ if (!poped) { | |
+ ADD_SEND(ret, nd_line(node), ID2SYM(idIntern), INT2FIX(0)); | |
+ } | |
+ else { | |
+ ADD_INSN(ret, nd_line(node), pop); | |
+ } | |
+ break; | |
+ } | |
+ case NODE_ATTRASGN:{ | |
+ compile_attrasgn(iseq, ret, node, poped); | |
+ break; | |
+ } | |
+ case NODE_PRELUDE:{ | |
+ COMPILE_POPED(ret, "prelude", node->nd_head); | |
+ COMPILE_(ret, "body", node->nd_body, poped); | |
+ break; | |
+ } | |
+ case NODE_LAMBDA:{ | |
+ compile_lambda(iseq, ret, node, poped); | |
break; | |
} | |
default: | |
diff --git a/thread_pthread.c b/thread_pthread.c | |
index ab227e3..4fd0ce0 100644 | |
--- a/thread_pthread.c | |
+++ b/thread_pthread.c | |
@@ -1425,6 +1425,10 @@ ruby_stack_overflowed_p(const rb_thread_t *th, const void *addr) | |
else { | |
return 0; | |
} | |
+ printf("size == %"PRIuSIZE"\n", size); | |
+ printf("base == %p\n", base); | |
+ printf("addr == %p\n", addr); | |
+ printf("base - addr == %"PRIdSIZE"\n", (char*)base - (char*)addr); | |
size /= 5; | |
if (size > water_mark) size = water_mark; | |
if (IS_STACK_DIR_UPPER()) { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(前略) | |
&type == 0x7fff5f036638 | |
&type == 0x7fff5f036408 | |
&type == 0x7fff5f0361d8 | |
&type == 0x7fff5f035fa8 | |
&type == 0x7fff5f035d78 | |
size == 3355444 | |
base == 0x7fff5f1017d4 | |
addr == 0x7fff5f034fe8 | |
base - addr == 837612 | |
-e:1: [BUG] Segmentation fault | |
ruby 2.0.0dev (2012-10-03 trunk 37076) [x86_64-darwin12.2.0] | |
-- Control frame information ----------------------------------------------- | |
c:0003 p:---- s:0008 e:000007 CFUNC :compile | |
c:0002 p:0027 s:0004 e:0001e8 EVAL -e:1 [FINISH] | |
c:0001 p:0000 s:0002 e:001bb8 TOP [FINISH] | |
-e:1:in `<main>' | |
-e:1:in `compile' | |
-- C level backtrace information ------------------------------------------- | |
See Crash Report log file under ~/Library/Logs/CrashReporter, | |
/Library/Logs/CrashReporter, or /Library/Logs/DiagnosticReports, for | |
the more detail of. | |
-- Other runtime information ----------------------------------------------- | |
* Loaded script: -e | |
* Loaded features: | |
0 enumerator.so | |
1 /Users/mrkn/work/ruby.git/.prefix/lib/ruby/2.0.0/x86_64-darwin12.2.0/enc/encdb.bundle | |
2 /Users/mrkn/work/ruby.git/.prefix/lib/ruby/2.0.0/x86_64-darwin12.2.0/enc/trans/transdb.bundle | |
3 /Users/mrkn/work/ruby.git/.prefix/lib/ruby/2.0.0/rubygems/defaults.rb | |
4 /Users/mrkn/work/ruby.git/.prefix/lib/ruby/2.0.0/x86_64-darwin12.2.0/rbconfig.rb | |
5 /Users/mrkn/work/ruby.git/.prefix/lib/ruby/2.0.0/rubygems/deprecate.rb | |
6 /Users/mrkn/work/ruby.git/.prefix/lib/ruby/2.0.0/rubygems/exceptions.rb | |
7 /Users/mrkn/work/ruby.git/.prefix/lib/ruby/2.0.0/rubygems/custom_require.rb | |
8 /Users/mrkn/work/ruby.git/.prefix/lib/ruby/2.0.0/rubygems.rb | |
[NOTE] | |
You may have encountered a bug in the Ruby interpreter or extension libraries. | |
Bug reports are welcome. | |
For details: http://www.ruby-lang.org/bugreport.html | |
Abort trap: 6 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment