16 #define USE_INSN_STACK_INCREASE 1
22 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
23 #define FIXNUM_INC(n, i) ((n)+(INT2FIX(i)&~FIXNUM_FLAG))
24 #define FIXNUM_OR(n, i) ((n)|INT2FIX(i))
96 #define compile_debug CPDEBUG
98 #define compile_debug iseq->compile_data->option->debug_level
103 #define compile_debug_print_indent(level) \
104 ruby_debug_print_indent((level), compile_debug, gl_node_level * 2)
106 #define debugp(header, value) (void) \
107 (compile_debug_print_indent(1) && \
108 ruby_debug_print_value(1, compile_debug, (header), (value)))
110 #define debugi(header, id) (void) \
111 (compile_debug_print_indent(1) && \
112 ruby_debug_print_id(1, compile_debug, (header), (id)))
114 #define debugp_param(header, value) (void) \
115 (compile_debug_print_indent(1) && \
116 ruby_debug_print_value(1, compile_debug, (header), (value)))
118 #define debugp_verbose(header, value) (void) \
119 (compile_debug_print_indent(2) && \
120 ruby_debug_print_value(2, compile_debug, (header), (value)))
122 #define debugp_verbose_node(header, value) (void) \
123 (compile_debug_print_indent(10) && \
124 ruby_debug_print_value(10, compile_debug, (header), (value)))
126 #define debug_node_start(node) ((void) \
127 (compile_debug_print_indent(1) && \
128 (ruby_debug_print_node(1, CPDEBUG, "", (NODE *)(node)), gl_node_level)), \
131 #define debug_node_end() gl_node_level --;
147 #define debugi(header, id) r_id(id)
148 #define debugp(header, value) r_value(value)
149 #define debugp_verbose(header, value) r_value(value)
150 #define debugp_verbose_node(header, value) r_value(value)
151 #define debugp_param(header, value) r_value(value)
152 #define debug_node_start(node) ((void)0)
153 #define debug_node_end() ((void)0)
156 #if CPDEBUG > 1 || CPDEBUG < 0
157 #define debugs if (compile_debug_print_indent(1)) ruby_debug_printf
158 #define debug_compile(msg, v) ((void)(compile_debug_print_indent(1) && fputs((msg), stderr)), (v))
160 #define debugs if(0)printf
161 #define debug_compile(msg, v) (v)
166 #define NEW_LABEL(l) new_label_body(iseq, (l))
168 #define iseq_filename(iseq) \
169 (((rb_iseq_t*)DATA_PTR(iseq))->filename)
171 #define iseq_filepath(iseq) \
172 (((rb_iseq_t*)DATA_PTR(iseq))->filepath)
174 #define NEW_ISEQVAL(node, name, type, line_no) \
175 new_child_iseq(iseq, (node), (name), 0, (type), (line_no))
177 #define NEW_CHILD_ISEQVAL(node, name, type, line_no) \
178 new_child_iseq(iseq, (node), (name), iseq->self, (type), (line_no))
181 #define ADD_SEQ(seq1, seq2) \
182 APPEND_LIST((seq1), (seq2))
185 #define ADD_INSN(seq, line, insn) \
186 ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0))
189 #define ADD_INSNL(seq, line, insn, label) \
190 ADD_ELEM((seq), (LINK_ELEMENT *) \
191 new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(label)))
194 #define ADD_INSN1(seq, line, insn, op1) \
195 ADD_ELEM((seq), (LINK_ELEMENT *) \
196 new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1)))
198 #define ADD_INSN2(seq, line, insn, op1, op2) \
199 ADD_ELEM((seq), (LINK_ELEMENT *) \
200 new_insn_body(iseq, (line), BIN(insn), 2, (VALUE)(op1), (VALUE)(op2)))
202 #define ADD_INSN3(seq, line, insn, op1, op2, op3) \
203 ADD_ELEM((seq), (LINK_ELEMENT *) \
204 new_insn_body(iseq, (line), BIN(insn), 3, (VALUE)(op1), (VALUE)(op2), (VALUE)(op3)))
207 #define ADD_SEND(seq, line, id, argc) \
208 ADD_SEND_R((seq), (line), (id), (argc), (VALUE)Qfalse, (VALUE)INT2FIX(0))
210 #define ADD_CALL_RECEIVER(seq, line) \
211 ADD_INSN((seq), (line), putself)
213 #define ADD_CALL(seq, line, id, argc) \
214 ADD_SEND_R((seq), (line), (id), (argc), (VALUE)Qfalse, (VALUE)INT2FIX(VM_CALL_FCALL_BIT))
216 #define ADD_CALL_WITH_BLOCK(seq, line, id, argc, block) \
217 ADD_SEND_R((seq), (line), (id), (argc), (block), (VALUE)INT2FIX(VM_CALL_FCALL_BIT))
219 #define ADD_SEND_R(seq, line, id, argc, block, flag) \
220 ADD_ELEM((seq), (LINK_ELEMENT *) \
221 new_insn_send(iseq, (line), \
222 (VALUE)(id), (VALUE)(argc), (VALUE)(block), (VALUE)(flag)))
224 #define ADD_TRACE(seq, line, event) \
226 if ((event) == RUBY_EVENT_LINE && iseq->coverage && \
227 (line) != iseq->compile_data->last_coverable_line) { \
228 RARRAY_PTR(iseq->coverage)[(line) - 1] = INT2FIX(0); \
229 iseq->compile_data->last_coverable_line = (line); \
230 ADD_INSN1((seq), (line), trace, INT2FIX(RUBY_EVENT_COVERAGE)); \
232 if (iseq->compile_data->option->trace_instruction) { \
233 ADD_INSN1((seq), (line), trace, INT2FIX(event)); \
238 #define ADD_LABEL(seq, label) \
239 ADD_ELEM((seq), (LINK_ELEMENT *) (label))
241 #define APPEND_LABEL(seq, before, label) \
242 APPEND_ELEM((seq), (before), (LINK_ELEMENT *) (label))
244 #define ADD_ADJUST(seq, line, label) \
245 ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), (line)))
247 #define ADD_ADJUST_RESTORE(seq, label) \
248 ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), -1))
250 #define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc) \
251 (rb_ary_push(iseq->compile_data->catch_table_ary, \
252 rb_ary_new3(5, (type), \
253 (VALUE)(ls) | 1, (VALUE)(le) | 1, \
254 (VALUE)(iseqv), (VALUE)(lc) | 1)))
257 #define COMPILE(anchor, desc, node) \
258 (debug_compile("== " desc "\n", \
259 iseq_compile_each(iseq, (anchor), (node), 0)))
262 #define COMPILE_POPED(anchor, desc, node) \
263 (debug_compile("== " desc "\n", \
264 iseq_compile_each(iseq, (anchor), (node), 1)))
267 #define COMPILE_(anchor, desc, node, poped) \
268 (debug_compile("== " desc "\n", \
269 iseq_compile_each(iseq, (anchor), (node), (poped))))
271 #define OPERAND_AT(insn, idx) \
272 (((INSN*)(insn))->operands[(idx)])
274 #define INSN_OF(insn) \
275 (((INSN*)(insn))->insn_id)
278 #define COMPILE_ERROR(strs) \
280 VALUE tmp = GET_THREAD()->errinfo; \
281 if (compile_debug) rb_compile_bug strs; \
282 GET_THREAD()->errinfo = iseq->compile_data->err_info; \
283 rb_compile_error strs; \
284 iseq->compile_data->err_info = GET_THREAD()->errinfo; \
285 GET_THREAD()->errinfo = tmp; \
290 #define ERROR_ARGS ruby_sourcefile, nd_line(node),
299 #define DECL_ANCHOR(name) \
300 LINK_ANCHOR *name, name##_body__ = {{0,},}
301 #define INIT_ANCHOR(name) \
302 (name##_body__.last = &name##_body__.anchor, name = &name##_body__)
304 #define hide_obj(obj) do {OBJ_FREEZE(obj); RBASIC(obj)->klass = 0;} while (0)
307 #if OPT_INSTRUCTIONS_UNIFICATION
313 #define ISEQ_ARG iseq,
314 #define ISEQ_ARG_DECLARE rb_iseq_t *iseq,
317 #define ISEQ_ARG_DECLARE
321 #define gl_node_level iseq->compile_data->node_level
367 if (plist != list->
prev) {
374 if (anchor->
last != plist && anchor->
last != 0) {
379 rb_bug(
"list verify error: %08x (%s)", flag, info);
384 #define verify_list(info, anchor) verify_list(iseq, (info), (anchor))
393 elem->
prev = anchor->last;
394 anchor->last->
next = elem;
409 if (before == anchor->last) anchor->last = elem;
413 #define ADD_ELEM(anchor, elem) ADD_ELEM(iseq, (anchor), (elem))
414 #define APPEND_ELEM(anchor, before, elem) ADD_ELEM(iseq, (anchor), (before), (elem))
426 #define ruby_sourcefile RSTRING_PTR(iseq->filename)
456 if (!
NIL_P(iseq->compile_data->err_info)) {
478 switch (iseq->
type) {
479 case ISEQ_TYPE_BLOCK: {
484 COMPILE(ret,
"block body", node->nd_body);
492 case ISEQ_TYPE_CLASS: {
494 COMPILE(ret,
"scoped node", node->nd_body);
498 case ISEQ_TYPE_METHOD: {
500 COMPILE(ret,
"scoped node", node->nd_body);
505 COMPILE(ret,
"scoped node", node->nd_body);
511 switch (iseq->
type) {
512 case ISEQ_TYPE_METHOD:
513 case ISEQ_TYPE_CLASS:
514 case ISEQ_TYPE_BLOCK:
521 case ISEQ_TYPE_RESCUE:
525 case ISEQ_TYPE_ENSURE:
529 case ISEQ_TYPE_DEFINED_GUARD:
531 COMPILE(ret,
"defined guard", node);
538 if (iseq->
type == ISEQ_TYPE_RESCUE || iseq->
type == ISEQ_TYPE_ENSURE) {
557 #if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
566 int len = insn_len(insn);
587 if (storage->
pos + size > storage->
size) {
588 unsigned long alloc_size = storage->
size * 2;
591 if (alloc_size < size) {
601 storage->
size = alloc_size;
602 storage->
buff = (
char *)(&storage->
buff + 1);
605 ptr = (
void *)&storage->
buff[storage->
pos];
606 storage->
pos += size;
701 anchor->last = anchor->last->
prev;
702 anchor->last->
next = 0;
707 #define POP_ELEMENT(anchor) POP_ELEMENT(iseq, (anchor))
760 anc1->last = anc2->
last;
765 #define APPEND_LIST(anc1, anc2) APPEND_LIST(iseq, (anc1), (anc2))
781 anc1->anchor.
next->
prev = &anc1->anchor;
787 anc1->last = anc2->
last;
794 #define INSERT_LIST(anc1, anc2) INSERT_LIST(iseq, (anc1), (anc2))
818 #define SWAP_LIST(anc1, anc2) SWAP_LIST(iseq, (anc1), (anc2))
825 first = &anc->anchor;
852 #define REVERSE_LIST(anc) REVERSE_LIST(iseq, (anc))
862 printf(
"anch: %p, frst: %p, last: %p\n", &anchor->anchor,
863 anchor->anchor.next, anchor->last);
865 printf(
"curr: %p, next: %p, prev: %p, type: %d\n", list, list->
next,
875 #define debug_list(anc) debug_list(iseq, (anc))
884 labelobj->
link.
type = ISEQ_ELEMENT_LABEL;
897 adjust->
link.
type = ISEQ_ELEMENT_ADJUST;
899 adjust->
label = label;
911 iobj->
link.
type = ISEQ_ELEMENT_INSN;
930 for (i = 0; i <
argc; i++) {
936 return new_insn_core(iseq, line_no, insn_id, argc, operands);
961 debugs(
"[new_child_iseq]> ---------------------------------------\n");
964 debugs(
"[new_child_iseq]< ---------------------------------------\n");
977 debugs(
"[compile step 3.1 (iseq_optimize)]\n");
984 debugs(
"[compile step 3.2 (iseq_insns_unification)]\n");
991 debugs(
"[compile step 3.3 (iseq_set_sequence_stackcaching)]\n");
997 debugs(
"[compile step 4.1 (iseq_set_sequence)]\n");
1002 debugs(
"[compile step 4.2 (iseq_set_exception_table)]\n");
1005 debugs(
"[compile step 4.3 (set_optargs_table)] \n");
1008 debugs(
"[compile step 5 (iseq_translate_threaded_code)] \n");
1016 debugs(
"[compile step: finish]\n");
1053 rb_bug(
"get_local_var_idx: %d", idx);
1062 int lv = 0, idx = -1;
1074 rb_bug(
"get_dyna_var_idx: -1");
1085 debugs(
"iseq_set_arguments: %s\n", node_args ?
"" :
"0");
1088 NODE *node_aux = node_args->nd_next;
1089 NODE *node_opt = node_args->nd_opt;
1093 NODE *node_init = 0;
1096 rb_bug(
"iseq_set_arguments: NODE_ARGS is expected, but %s",
1112 iseq->
argc = (int)node_args->nd_frml;
1116 rest_id = node_aux->nd_rest;
1121 block_id = (
ID)node_aux->nd_body;
1122 node_aux = node_aux->nd_next;
1125 ID post_start_id = node_aux->nd_pid;
1128 node_init = node_aux->nd_next;
1133 NODE *node = node_opt;
1143 node = node->nd_next;
1156 for (j = 0; j <
i; j++) {
1166 if (node_init->nd_1st) {
1167 COMPILE_POPED(optargs,
"init arguments (m)", node_init->nd_1st);
1169 if (node_init->nd_2nd) {
1170 COMPILE_POPED(optargs,
"init arguments (p)", node_init->nd_2nd);
1216 if (iseq->
type == ISEQ_TYPE_BLOCK) {
1218 if (iseq->
argc == 1 && last_comma == 0) {
1267 if (val == lit)
return 0;
1277 return !
rb_eql(lit, val);
1306 VALUE *generated_iseq;
1308 int k, pos,
sp, stack_max = 0, line = 0;
1314 switch (list->
type) {
1315 case ISEQ_ELEMENT_INSN:
1317 iobj = (
INSN *)list;
1323 case ISEQ_ELEMENT_LABEL:
1325 lobj = (
LABEL *)list;
1330 case ISEQ_ELEMENT_NONE:
1335 case ISEQ_ELEMENT_ADJUST:
1348 "error: set_sequence");
1364 switch (list->
type) {
1365 case ISEQ_ELEMENT_INSN:
1371 iobj = (
INSN *)list;
1375 if (sp > stack_max) {
1382 generated_iseq[pos] = insn;
1383 types = insn_op_types(insn);
1384 len = insn_len(insn);
1391 "operand size miss! (%d for %d)",
1393 xfree(generated_iseq);
1394 xfree(insn_info_table);
1398 for (j = 0; types[j]; j++) {
1399 char type = types[j];
1405 lobj = (
LABEL *)operands[j];
1410 if (lobj->
sp == -1) {
1413 generated_iseq[pos + 1 + j] =
1423 VALUE lits = operands[j];
1430 lobj = (
LABEL *)(lv & ~1);
1441 "duplicated when clause is ignored");
1445 generated_iseq[pos + 1 + j] = map;
1452 generated_iseq[pos + 1 + j] =
FIX2INT(operands[j]);
1461 generated_iseq[pos + 1 + j] = (
VALUE)block;
1467 generated_iseq[pos + 1 + j] =
v;
1474 int ic_index =
FIX2INT(operands[j]);
1477 rb_bug(
"iseq_set_sequence: ic_index overflow: index: %d, size: %d",
1480 generated_iseq[pos + 1 + j] = (
VALUE)ic;
1484 generated_iseq[pos + 1 + j] =
SYM2ID(operands[j]);
1490 generated_iseq[pos + 1 + j] = (
VALUE)entry;
1495 "unknown operand type: %c", type);
1496 xfree(generated_iseq);
1497 xfree(insn_info_table);
1503 insn_info_table[k].
sp = sp;
1508 case ISEQ_ELEMENT_LABEL:
1510 lobj = (
LABEL *)list;
1511 if (lobj->
sp == -1) {
1519 case ISEQ_ELEMENT_ADJUST:
1524 if (adjust->
label) {
1532 if (orig_sp - sp > 0) {
1535 insn_info_table[k].
sp = sp;
1537 generated_iseq[pos++] = BIN(adjuststack);
1538 generated_iseq[pos++] = orig_sp - sp;
1540 else if (orig_sp - sp == 0) {
1544 insn_info_table[k].
sp = sp;
1546 generated_iseq[pos++] = BIN(jump);
1547 generated_iseq[pos++] = 0;
1550 rb_bug(
"iseq_set_sequence: adjust bug");
1569 iseq->
iseq = (
void *)generated_iseq;
1603 for (i = 0; i < tlen; i++) {
1609 entry->
iseq = ptr[3];
1612 if (entry->
iseq != 0) {
1653 for (i = 0; i < iseq->
arg_opts; i++) {
1669 if (list->
type == ISEQ_ELEMENT_INSN || list->
type == ISEQ_ELEMENT_ADJUST) {
1683 if (list->
type == ISEQ_ELEMENT_INSN || list->
type == ISEQ_ELEMENT_ADJUST) {
1697 if (list->
type == ISEQ_ELEMENT_INSN || list->
type == ISEQ_ELEMENT_ADJUST) {
1710 if (iobj->
insn_id == BIN(jump)) {
1711 INSN *niobj, *diobj, *piobj;
1725 if (diobj == niobj) {
1734 else if (iobj != diobj && diobj->
insn_id == BIN(jump)) {
1740 else if (diobj->
insn_id == BIN(leave)) {
1776 (piobj->
insn_id == BIN(branchif) ||
1777 piobj->
insn_id == BIN(branchunless))) {
1780 ? BIN(branchunless) : BIN(branchif);
1787 if (iobj->
insn_id == BIN(branchif) ||
1788 iobj->
insn_id == BIN(branchunless)) {
1798 if (nobj->
insn_id == BIN(jump)) {
1803 if (do_tailcallopt && iobj->
insn_id == BIN(leave)) {
1813 if (piobj->
insn_id == BIN(send) &&
1845 if (iobj->
insn_id == BIN(send)) {
1852 if (block == 0 && flag ==
INT2FIX(0)) {
1854 if (mid == idLength) {
1857 else if (mid == idSize) {
1860 else if (mid == idSucc) {
1863 else if (mid ==
idNot) {
1867 else if (argc == 1) {
1870 else if (mid ==
idPLUS) {
1876 else if (mid ==
idMULT) {
1879 else if (mid ==
idDIV) {
1882 else if (mid ==
idMOD) {
1885 else if (mid ==
idEq) {
1888 else if (mid ==
idNeq) {
1891 else if (mid ==
idLT) {
1894 else if (mid ==
idLE) {
1897 else if (mid ==
idGT) {
1900 else if (mid ==
idGE) {
1903 else if (mid ==
idLTLT) {
1906 else if (mid ==
idAREF) {
1926 if (list->
type == ISEQ_ELEMENT_INSN) {
1927 if (do_peepholeopt) {
1934 insn_operands_unification((
INSN *)list);
1942 #if OPT_INSTRUCTIONS_UNIFICATION
1950 VALUE *operands = 0, *ptr = 0;
1954 for (i = 0; i <
size; i++) {
1955 iobj = (
INSN *)list;
1967 for (i = 0; i <
size; i++) {
1968 iobj = (
INSN *)list;
1986 #if OPT_INSTRUCTIONS_UNIFICATION
1994 if (list->
type == ISEQ_ELEMENT_INSN) {
1995 iobj = (
INSN *)list;
1997 if (unified_insns_data[
id] != 0) {
1998 const int *
const *entry = unified_insns_data[
id];
1999 for (j = 1; j < (
intptr_t)entry[0]; j++) {
2000 const int *unified = entry[j];
2002 for (k = 2; k < unified[1]; k++) {
2003 if (li->
type != ISEQ_ELEMENT_INSN ||
2004 ((
INSN *)li)->insn_id != unified[k]) {
2011 new_unified_insn(iseq, unified[0], unified[1] - 1,
2034 #if OPT_STACK_CACHING
2036 #define SC_INSN(insn, stat) sc_insn_info[(insn)][(stat)]
2037 #define SC_NEXT(insn) sc_insn_next[(insn)]
2048 iobj->
insn_id = SC_INSN(insn_id, state);
2049 nstate = SC_NEXT(iobj->
insn_id);
2051 if (insn_id == BIN(jump) ||
2052 insn_id == BIN(branchif) || insn_id == BIN(branchunless)) {
2059 printf(
"\n-- %d, %d\n", lobj->
sc_state, nstate);
2061 "insn_set_sc_state error\n");
2068 if (insn_id == BIN(jump)) {
2072 else if (insn_id == BIN(leave)) {
2080 label_set_sc_state(
LABEL *lobj,
int state)
2100 #if OPT_STACK_CACHING
2112 switch (list->
type) {
2113 case ISEQ_ELEMENT_INSN:
2124 if (state != SCS_AX) {
2137 if (state == SCS_AB || state == SCS_BA) {
2138 state = (state == SCS_AB ? SCS_BA : SCS_AB);
2174 state = insn_set_sc_state(iseq, iobj, state);
2177 case ISEQ_ELEMENT_LABEL:
2180 lobj = (
LABEL *)list;
2182 state = label_set_sc_state(lobj, state);
2198 NODE *list = node->nd_next;
2199 VALUE lit = node->nd_lit;
2210 COMPILE(ret,
"each string", list->nd_head);
2212 list = list->nd_next;
2274 COMPILE(ret,
"branch condition", cond);
2284 VALUE opt_p,
int poped)
2286 NODE *node = node_root;
2287 int len = (int)node->nd_alen, line = (
int)
nd_line(node), i=0;
2294 rb_bug(
"compile_array: This node is not NODE_ARRAY, but %s",
2302 COMPILE_(anchor,
"array element", node->nd_head, poped);
2303 node = node->nd_next;
2309 rb_bug(
"node error: compile_array (%d: %d-%d)",
2310 (
int)
nd_line(node_root), len, i);
2315 if (opt_p ==
Qtrue) {
2321 node = node->nd_next;
2360 return node->nd_lit;
2372 val = vals->nd_head;
2374 if (special_literals &&
2380 special_literals =
Qfalse;
2389 COMPILE(cond_seq,
"when cond", val);
2394 vals = vals->nd_next;
2396 return special_literals;
2457 int llen = 0, rlen = 0;
2459 NODE *lhsn = orig_lhsn;
2461 #define MEMORY(v) { \
2463 if (memindex == memsize) return 0; \
2464 for (i=0; i<memindex; i++) { \
2465 if (mem[i] == (v)) return 0; \
2467 mem[memindex++] = (v); \
2475 NODE *ln = lhsn->nd_head;
2490 lhsn = lhsn->nd_next;
2499 COMPILE(ret,
"masgn val", rhsn->nd_head);
2501 rhsn = rhsn->nd_next;
2506 for (i=0; i<llen-rlen; i++) {
2518 NODE *rhsn = node->nd_value;
2519 NODE *splatn = node->nd_args;
2520 NODE *lhsn = node->nd_head;
2521 int lhs_splat = (splatn && (
VALUE)splatn != (
VALUE)-1) ? 1 : 0;
2532 lhsn = lhsn->nd_next;
2535 COMPILE(ret,
"normal masgn rhs", rhsn);
2548 NODE *postn = splatn->nd_2nd;
2549 NODE *restn = splatn->nd_1st;
2550 int num = (int)postn->nd_alen;
2551 int flag = 0x02 | (((
VALUE)restn == (
VALUE)-1) ? 0x00 : 0x01);
2561 postn = postn->nd_next;
2579 debugi(
"compile_colon2 - colon", node->nd_vid);
2583 debugi(
"compile_colon2 - colon3", node->nd_mid);
2590 debugi(
"compile_colon2 - colon2", node->nd_mid);
2594 COMPILE(pref,
"const colon2 prefix", node);
2608 else if (cpath->nd_head) {
2610 COMPILE(ret,
"nd_else->nd_head", cpath->nd_head);
2621 #define defined_expr defined_expr0
2626 const char *estr = 0;
2629 switch (type =
nd_type(node)) {
2655 }
while ((vals = vals->nd_next) !=
NULL);
2663 estr =
"expression";
2669 estr =
"local-variable";
2675 ID2SYM(node->nd_vid), needstr);
2681 ID2SYM(node->nd_entry->
id), needstr);
2687 ID2SYM(node->nd_vid), needstr);
2693 ID2SYM(node->nd_vid), needstr);
2703 COMPILE(ret,
"defined/colon2#nd_head", node->nd_head);
2705 ID2SYM(node->nd_mid), needstr);
2708 COMPILE(ret,
"defined/colon2#nd_head", node->nd_head);
2710 ID2SYM(node->nd_mid), needstr);
2728 if (node->nd_recv == (
NODE *)1)
break;
2738 if (node->nd_args) {
2745 COMPILE(ret,
"defined/recv", node->nd_recv);
2747 ID2SYM(node->nd_mid), needstr);
2752 ID2SYM(node->nd_mid), needstr);
2791 estr =
"assignment";
2816 int done = defined_expr0(iseq, ret, node, lfinish, needstr);
2823 (
"defined guard in "),
2825 ISEQ_TYPE_DEFINED_GUARD, 0);
2833 #define BUFSIZE 0x100
2843 if (ip->
type == ISEQ_TYPE_BLOCK) {
2876 while (erange->
next != 0) {
2877 erange = erange->
next;
2882 erange->
end = lstart;
2933 COMPILE(arg_block,
"block", argn->nd_body);
2935 argn = argn->nd_head;
2942 COMPILE(args,
"args (splat)", argn->nd_head);
2954 COMPILE(tmp,
"args (cat: splat)", argn->nd_body);
2955 if (next_is_array && nsplat == 0) {
2970 if (next_is_array) {
2975 argn = argn->nd_head;
2993 for (i=1; i<nsplat; i++) {
3023 debugs(
"node: NODE_NIL(implicit)\n");
3041 COMPILE_(ret,
"BLOCK body", node->nd_head,
3042 (node->nd_next == 0 && poped == 0) ? 0 : 1);
3043 node = node->nd_next;
3046 COMPILE_(ret,
"BLOCK next", node->nd_next, poped);
3054 LABEL *then_label, *else_label, *end_label;
3064 then_label, else_label);
3065 COMPILE_(then_seq,
"then", node->nd_body, poped);
3066 COMPILE_(else_seq,
"else", node->nd_else, poped);
3083 NODE *tempnode = node;
3084 LABEL *endlabel, *elselabel;
3093 if (node->nd_head == 0) {
3094 COMPILE_(ret,
"when", node->nd_body, poped);
3097 COMPILE(head,
"case base", node->nd_head);
3099 node = node->nd_body;
3117 COMPILE_(body_seq,
"when body", node->nd_body, poped);
3120 vals = node->nd_head;
3124 special_literals =
when_vals(iseq, cond_seq, vals, l1, special_literals);
3129 special_literals = 0;
3130 COMPILE(cond_seq,
"when/cond splat", vals);
3135 rb_bug(
"NODE_CASE: unknown node (%s)",
3140 rb_bug(
"NODE_CASE: must be NODE_ARRAY, but 0");
3143 node = node->nd_next;
3153 COMPILE_(cond_seq,
"else", node, poped);
3157 debugs(
"== else (implicit)\n");
3166 if (special_literals) {
3169 special_literals, elselabel);
3181 NODE *orig_node = node;
3191 COMPILE_(body_seq,
"when", node->nd_body, poped);
3194 vals = node->nd_head;
3196 rb_bug(
"NODE_WHEN: must be NODE_ARRAY, but 0");
3201 val = vals->nd_head;
3204 vals = vals->nd_next;
3211 COMPILE(ret,
"when2/cond splat", vals);
3217 rb_bug(
"NODE_WHEN: unknown node (%s)",
3220 node = node->nd_next;
3223 COMPILE_(ret,
"else", node, poped);
3252 if (type ==
NODE_OPT_N || node->nd_state == 1) {
3263 if (tmp_label)
ADD_LABEL(ret, tmp_label);
3271 redo_label, end_label);
3276 end_label, redo_label);
3287 if (node->nd_state ==
Qundef) {
3289 rb_bug(
"unsupported: putundef");
3324 COMPILE(ret,
"iter caller (for)", node->nd_iter);
3328 ISEQ_TYPE_BLOCK,
nd_line(node));
3337 ISEQ_TYPE_BLOCK,
nd_line(node));
3338 COMPILE(ret,
"iter caller", node->nd_iter);
3348 ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, retry_label, retry_end_l, 0, retry_end_l);
3353 unsigned long level = 0;
3369 else if (iseq->
type == ISEQ_TYPE_BLOCK) {
3372 COMPILE(ret,
"break val (block)", node->nd_stts);
3378 else if (iseq->
type == ISEQ_TYPE_EVAL) {
3399 else if (ip->
type == ISEQ_TYPE_BLOCK) {
3403 else if (ip->
type == ISEQ_TYPE_EVAL) {
3414 unsigned long level = 0;
3418 debugs(
"next in while loop\n");
3420 COMPILE(ret,
"next val/valid syntax?", node->nd_stts);
3431 debugs(
"next in block\n");
3434 COMPILE(ret,
"next val", node->nd_stts);
3443 else if (iseq->
type == ISEQ_TYPE_EVAL) {
3456 level = 0x8000 | 0x4000;
3461 else if (ip->
type == ISEQ_TYPE_BLOCK) {
3464 else if (ip->
type == ISEQ_TYPE_EVAL) {
3471 COMPILE(ret,
"next val", node->nd_stts);
3497 else if (iseq->
type == ISEQ_TYPE_EVAL) {
3517 unsigned long level;
3518 level = 0x8000 | 0x4000;
3529 else if (ip->
type == ISEQ_TYPE_BLOCK) {
3532 else if (ip->
type == ISEQ_TYPE_EVAL) {
3553 if (iseq->
type == ISEQ_TYPE_RESCUE) {
3567 COMPILE_(ret,
"NODE_BEGIN", node->nd_body, poped);
3577 ISEQ_TYPE_RESCUE,
nd_line(node));
3580 COMPILE(ret,
"rescue head", node->nd_head);
3582 if (node->nd_else) {
3584 COMPILE(ret,
"rescue else", node->nd_else);
3601 LABEL *label_miss, *label_hit;
3607 narg = resq->nd_args;
3612 COMPILE(ret,
"rescue arg", narg->nd_head);
3616 narg = narg->nd_next;
3623 COMPILE(ret,
"rescue/cond splat", narg);
3630 rb_bug(
"NODE_RESBODY: unknown node (%s)",
3643 COMPILE(ret,
"resbody body", resq->nd_body);
3649 resq = resq->nd_head;
3659 ISEQ_TYPE_ENSURE,
nd_line(node));
3676 COMPILE_(ret,
"ensure head", node->nd_head, poped);
3678 if (ensr->anchor.next == 0) {
3690 erange = erange->
next;
3700 COMPILE(ret,
"nd_1st", node->nd_1st);
3713 COMPILE_(ret,
"nd_2nd", node->nd_2nd, poped);
3724 ID id = node->nd_vid;
3728 COMPILE(ret,
"rvalue", node->nd_value);
3740 COMPILE(ret,
"dvalue", node->nd_value);
3758 COMPILE(ret,
"lvalue", node->nd_value);
3764 ((
VALUE)node->nd_entry | 1));
3769 COMPILE(ret,
"lvalue", node->nd_value);
3778 COMPILE(ret,
"lvalue", node->nd_value);
3796 COMPILE(ret,
"cvasgn val", node->nd_value);
3808 ID id = node->nd_mid;
3837 COMPILE(ret,
"NODE_OP_ASGN1 recv", node->nd_recv);
3838 switch (
nd_type(node->nd_args->nd_head)) {
3852 if (
id == 0 ||
id == 1) {
3876 COMPILE(ret,
"NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body);
3912 COMPILE(ret,
"NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body);
3945 ID atype = node->nd_next->nd_mid;
3990 COMPILE(ret,
"NODE_OP_ASGN2#recv", node->nd_recv);
3995 if (atype == 0 || atype == 1) {
4004 COMPILE(ret,
"NODE_OP_ASGN2 val", node->nd_value);
4022 COMPILE(ret,
"NODE_OP_ASGN2 val", node->nd_value);
4045 lassign = lfinish[1];
4055 COMPILE(ret,
"NODE_OP_ASGN_AND/OR#nd_head", node->nd_head);
4067 COMPILE(ret,
"NODE_OP_ASGN_AND/OR#nd_value", node->nd_value);
4086 ID mid = node->nd_mid;
4096 if (mid == idBitblt) {
4100 else if (mid == idAnswer) {
4114 (mid == goto_id || mid == label_id)) {
4120 if (!labels_table) {
4125 SYMBOL_P(node->nd_args->nd_head->nd_lit)) {
4127 label_name =
SYM2ID(node->nd_args->nd_head->nd_lit);
4134 label = (
LABEL *)data;
4142 if (mid == goto_id) {
4154 COMPILE(recv,
"recv", node->nd_recv);
4183 argc, parent_block,
LONG2FIX(flag));
4210 for (i = 0; i < liseq->
argc; i++) {
4219 for (j = 0; j < liseq->
arg_opts - 1; j++) {
4242 for (j=0; j<post_len; j++) {
4243 int idx = liseq->
local_size - (post_start + j);
4252 for (j=0; j<post_len; j++) {
4253 int idx = liseq->
local_size - (post_start + j);
4256 argc =
INT2FIX(post_len + post_start);
4267 argc, parent_block,
LONG2FIX(flag));
4287 COMPILE(ret,
"values item", n->nd_head);
4328 if (is->
type == ISEQ_TYPE_TOP) {
4334 if (is->
type == ISEQ_TYPE_METHOD) {
4340 COMPILE(ret,
"return nd_stts (return val)", node->nd_stts);
4342 if (is->
type == ISEQ_TYPE_METHOD) {
4368 if (iseq->
type == ISEQ_TYPE_TOP) {
4372 if (node->nd_head) {
4389 ID id = node->nd_vid;
4399 debugi(
"nd_vid", node->nd_vid);
4411 ((
VALUE)node->nd_entry | 1));
4418 debugi(
"nd_vid", node->nd_vid);
4426 debugi(
"nd_vid", node->nd_vid);
4430 int ic_index = iseq->
ic_size++;
4464 INT2FIX(0x01 | (node->nd_nth << 1)));
4483 COMPILE(recv,
"receiver", node->nd_recv);
4484 COMPILE(val,
"value", node->nd_value);
4487 COMPILE(recv,
"receiver", node->nd_value);
4488 COMPILE(val,
"value", node->nd_recv);
4494 if (recv->last == recv->anchor.next &&
4495 INSN_OF(recv->last) == BIN(putobject) &&
4563 COMPILE(ret,
"nd_body", node->nd_body);
4584 int ic_index = iseq->
ic_size++;
4601 COMPILE(ret,
"argscat head", node->nd_head);
4604 COMPILE(ret,
"argscat body", node->nd_body);
4609 COMPILE(ret,
"argscat head", node->nd_head);
4610 COMPILE(ret,
"argscat body", node->nd_body);
4617 COMPILE(ret,
"arsgpush head", node->nd_head);
4620 COMPILE_(ret,
"argspush body", node->nd_body, poped);
4623 COMPILE(ret,
"arsgpush head", node->nd_head);
4624 COMPILE_(ret,
"argspush body", node->nd_body, poped);
4631 COMPILE(ret,
"splat", node->nd_head);
4642 ISEQ_TYPE_METHOD,
nd_line(node));
4662 ISEQ_TYPE_METHOD,
nd_line(node));
4667 COMPILE(ret,
"defs: recv", node->nd_recv);
4716 ISEQ_TYPE_CLASS,
nd_line(node));
4718 COMPILE(ret,
"super", node->nd_super);
4720 ID2SYM(node->nd_cpath->nd_mid), iseqval,
INT2FIX(noscope ? 3 : 0));
4731 ISEQ_TYPE_CLASS,
nd_line(node));
4736 ID2SYM(node->nd_cpath->nd_mid), iseqval,
INT2FIX(noscope ? 5 : 2));
4746 ISEQ_TYPE_CLASS,
nd_line(node));
4748 COMPILE(ret,
"sclass#recv", node->nd_recv);
4750 CONST_ID(singletonclass,
"singletonclass");
4763 int ic_index = iseq->
ic_size++;
4794 COMPILE(ret,
"colon2#nd_head", node->nd_head);
4805 int ic_index = iseq->
ic_size++;
4807 debugi(
"colon3#nd_mid", node->nd_mid);
4858 COMPILE(ret,
"flip2 beg", node->nd_beg);
4872 COMPILE(ret,
"flip2 end", node->nd_end);
4909 if (iseq->
type == ISEQ_TYPE_RESCUE) {
4916 if (ip->
type == ISEQ_TYPE_RESCUE) {
4951 int ic_index = iseq->
ic_size++;
4988 if (node->nd_recv == (
NODE *) 1) {
4993 COMPILE(recv,
"recv", node->nd_recv);
5042 COMPILE_(ret,
"optblock body", node->nd_head, 1 );
5049 COMPILE_(ret,
"body", node->nd_body, poped);
5080 return insn_len(iobj->
insn_id);
5092 return insn_len(iobj->
line_no);
5104 for (j = 0; types[j]; j++) {
5105 char type = types[j];
5106 printf(
"str: %"PRIxVALUE", type: %c\n", str, type);
5167 printf(
"-- raw disasm--------\n");
5170 switch (link->
type) {
5171 case ISEQ_ELEMENT_INSN:
5173 iobj = (
INSN *)link;
5180 case ISEQ_ELEMENT_LABEL:
5182 lobj = (
LABEL *)link;
5183 printf(
"<L%03d>\n", lobj->
label_no);
5186 case ISEQ_ELEMENT_NONE:
5191 case ISEQ_ELEMENT_ADJUST:
5203 printf(
"---------------------\n");
5211 for (i = 0; i <
numberof(insn_name_info); i++) {
5224 if (
st_lookup(labels_table, obj, &tmp) == 0) {
5229 label = (
LABEL *)tmp;
5238 #define rb_intern(str) rb_intern_const(str)
5240 static VALUE symRescue, symEnsure, symRetry;
5241 static VALUE symBreak, symRedo, symNext;
5243 if (symRescue == 0) {
5252 if (sym == symRescue)
return CATCH_TYPE_RESCUE;
5253 if (sym == symEnsure)
return CATCH_TYPE_ENSURE;
5254 if (sym == symRetry)
return CATCH_TYPE_RETRY;
5255 if (sym == symBreak)
return CATCH_TYPE_BREAK;
5256 if (sym == symRedo)
return CATCH_TYPE_REDO;
5257 if (sym == symNext)
return CATCH_TYPE_NEXT;
5272 LABEL *lstart, *lend, *lcont;
5282 if (ptr[1] ==
Qnil) {
5306 for (i=0; i<VM_INSTRUCTION_SIZE; i++) {
5325 static struct st_table *insn_table;
5327 if (insn_table == 0) {
5331 for (i=0; i<
len; i++) {
5355 if (argc != insn_len((
VALUE)insn_id)-1) {
5357 "operand size mismatch");
5362 for (j=0; j<
argc; j++) {
5364 switch (insn_op_type((
VALUE)insn_id, j)) {
5367 argv[j] = (
VALUE)label;
5410 "Symbol",
"to_sym");
5434 (
enum ruby_vminsn_type)insn_id, argc, argv));
5446 #define CHECK_ARRAY(v) rb_convert_type((v), T_ARRAY, "Array", "to_ary")
5447 #define CHECK_STRING(v) rb_convert_type((v), T_STRING, "String", "to_str")
5448 #define CHECK_SYMBOL(v) rb_convert_type((v), T_SYMBOL, "Symbol", "to_sym")
5506 for (i=0; i<
RARRAY_LEN(arg_opt_labels); i++) {
5531 while (iseq->
type == ISEQ_TYPE_BLOCK ||
5532 iseq->
type == ISEQ_TYPE_RESCUE ||
5533 iseq->
type == ISEQ_TYPE_ENSURE ||
5534 iseq->
type == ISEQ_TYPE_EVAL ||
5535 iseq->
type == ISEQ_TYPE_MAIN