Skip to content

Instantly share code, notes, and snippets.

@mrkn
Created October 3, 2012 17:19
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save mrkn/3828416 to your computer and use it in GitHub Desktop.
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()) {
(前略)
&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