16 #define USE_INSN_STACK_INCREASE 1
20 #include "insns_info.inc"
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_path(iseq) \
169 (((rb_iseq_t*)DATA_PTR(iseq))->location.path)
171 #define iseq_absolute_path(iseq) \
172 (((rb_iseq_t*)DATA_PTR(iseq))->location.absolute_path)
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_INSN1(seq, line, insn, op1) \
190 ADD_ELEM((seq), (LINK_ELEMENT *) \
191 new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1)))
194 #define ADD_INSNL(seq, line, insn, label) ADD_INSN1(seq, line, insn, label)
196 #define ADD_INSN2(seq, line, insn, op1, op2) \
197 ADD_ELEM((seq), (LINK_ELEMENT *) \
198 new_insn_body(iseq, (line), BIN(insn), 2, (VALUE)(op1), (VALUE)(op2)))
200 #define ADD_INSN3(seq, line, insn, op1, op2, op3) \
201 ADD_ELEM((seq), (LINK_ELEMENT *) \
202 new_insn_body(iseq, (line), BIN(insn), 3, (VALUE)(op1), (VALUE)(op2), (VALUE)(op3)))
205 #define ADD_SEND(seq, line, id, argc) \
206 ADD_SEND_R((seq), (line), (id), (argc), (VALUE)Qfalse, (VALUE)INT2FIX(0))
208 #define ADD_CALL_RECEIVER(seq, line) \
209 ADD_INSN((seq), (line), putself)
211 #define ADD_CALL(seq, line, id, argc) \
212 ADD_SEND_R((seq), (line), (id), (argc), (VALUE)Qfalse, (VALUE)INT2FIX(VM_CALL_FCALL))
214 #define ADD_CALL_WITH_BLOCK(seq, line, id, argc, block) \
215 ADD_SEND_R((seq), (line), (id), (argc), (block), (VALUE)INT2FIX(VM_CALL_FCALL))
217 #define ADD_SEND_R(seq, line, id, argc, block, flag) \
218 ADD_ELEM((seq), (LINK_ELEMENT *) \
219 new_insn_send(iseq, (line), \
220 (VALUE)(id), (VALUE)(argc), (VALUE)(block), (VALUE)(flag)))
222 #define ADD_TRACE(seq, line, event) \
224 if ((event) == RUBY_EVENT_LINE && iseq->coverage && \
225 (line) != iseq->compile_data->last_coverable_line) { \
226 RARRAY_PTR(iseq->coverage)[(line) - 1] = INT2FIX(0); \
227 iseq->compile_data->last_coverable_line = (line); \
228 ADD_INSN1((seq), (line), trace, INT2FIX(RUBY_EVENT_COVERAGE)); \
230 if (iseq->compile_data->option->trace_instruction) { \
231 ADD_INSN1((seq), (line), trace, INT2FIX(event)); \
236 #define ADD_LABEL(seq, label) \
237 ADD_ELEM((seq), (LINK_ELEMENT *) (label))
239 #define APPEND_LABEL(seq, before, label) \
240 APPEND_ELEM((seq), (before), (LINK_ELEMENT *) (label))
242 #define ADD_ADJUST(seq, line, label) \
243 ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), (line)))
245 #define ADD_ADJUST_RESTORE(seq, label) \
246 ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), -1))
248 #define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc) \
249 (rb_ary_push(iseq->compile_data->catch_table_ary, \
250 rb_ary_new3(5, (type), \
251 (VALUE)(ls) | 1, (VALUE)(le) | 1, \
252 (VALUE)(iseqv), (VALUE)(lc) | 1)))
255 #define COMPILE(anchor, desc, node) \
256 (debug_compile("== " desc "\n", \
257 iseq_compile_each(iseq, (anchor), (node), 0)))
260 #define COMPILE_POPED(anchor, desc, node) \
261 (debug_compile("== " desc "\n", \
262 iseq_compile_each(iseq, (anchor), (node), 1)))
265 #define COMPILE_(anchor, desc, node, poped) \
266 (debug_compile("== " desc "\n", \
267 iseq_compile_each(iseq, (anchor), (node), (poped))))
269 #define OPERAND_AT(insn, idx) \
270 (((INSN*)(insn))->operands[(idx)])
272 #define INSN_OF(insn) \
273 (((INSN*)(insn))->insn_id)
276 #define COMPILE_ERROR(strs) \
278 VALUE tmp = GET_THREAD()->errinfo; \
279 if (compile_debug) rb_compile_bug strs; \
280 GET_THREAD()->errinfo = iseq->compile_data->err_info; \
281 rb_compile_error strs; \
282 iseq->compile_data->err_info = GET_THREAD()->errinfo; \
283 GET_THREAD()->errinfo = tmp; \
288 #define ERROR_ARGS ruby_sourcefile, nd_line(node),
297 #define DECL_ANCHOR(name) \
298 LINK_ANCHOR *name, name##_body__ = {{0,},}
299 #define INIT_ANCHOR(name) \
300 (name##_body__.last = &name##_body__.anchor, name = &name##_body__)
302 #define hide_obj(obj) do {OBJ_FREEZE(obj); RBASIC(obj)->klass = 0;} while (0)
304 #include "optinsn.inc"
305 #if OPT_INSTRUCTIONS_UNIFICATION
306 #include "optunifs.inc"
311 #define ISEQ_ARG iseq,
312 #define ISEQ_ARG_DECLARE rb_iseq_t *iseq,
315 #define ISEQ_ARG_DECLARE
319 #define gl_node_level iseq->compile_data->node_level
365 if (plist != list->
prev) {
372 if (anchor->
last != plist && anchor->
last != 0) {
377 rb_bug(
"list verify error: %08x (%s)", flag, info);
382 #define verify_list(info, anchor) verify_list(iseq, (info), (anchor))
391 elem->
prev = anchor->last;
407 if (before == anchor->last) anchor->last =
elem;
411 #define ADD_ELEM(anchor, elem) ADD_ELEM(iseq, (anchor), (elem))
412 #define APPEND_ELEM(anchor, before, elem) ADD_ELEM(iseq, (anchor), (before), (elem))
424 #define ruby_sourcefile RSTRING_PTR(iseq->location.path)
455 if (!
NIL_P(iseq->compile_data->err_info)) {
477 switch (iseq->
type) {
478 case ISEQ_TYPE_BLOCK:
494 case ISEQ_TYPE_CLASS:
501 case ISEQ_TYPE_METHOD:
515 switch (iseq->
type) {
516 case ISEQ_TYPE_METHOD:
517 case ISEQ_TYPE_CLASS:
518 case ISEQ_TYPE_BLOCK:
525 case ISEQ_TYPE_RESCUE:
529 case ISEQ_TYPE_ENSURE:
533 case ISEQ_TYPE_DEFINED_GUARD:
542 if (iseq->
type == ISEQ_TYPE_RESCUE || iseq->
type == ISEQ_TYPE_ENSURE) {
561 #if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
570 int len = insn_len(insn);
591 if (storage->
pos + size > storage->
size) {
592 unsigned long alloc_size = storage->
size * 2;
595 if (alloc_size < size) {
605 storage->
size = alloc_size;
606 storage->
buff = (
char *)(&storage->
buff + 1);
609 ptr = (
void *)&storage->
buff[storage->
pos];
610 storage->
pos += size;
705 anchor->last = anchor->last->prev;
706 anchor->last->next = 0;
711 #define POP_ELEMENT(anchor) POP_ELEMENT(iseq, (anchor))
764 anc1->last = anc2->
last;
769 #define APPEND_LIST(anc1, anc2) APPEND_LIST(iseq, (anc1), (anc2))
785 anc1->anchor.
next->
prev = &anc1->anchor;
791 anc1->last = anc2->
last;
798 #define INSERT_LIST(anc1, anc2) INSERT_LIST(iseq, (anc1), (anc2))
822 #define SWAP_LIST(anc1, anc2) SWAP_LIST(iseq, (anc1), (anc2))
829 first = &anc->anchor;
856 #define REVERSE_LIST(anc) REVERSE_LIST(iseq, (anc))
866 printf(
"anch: %p, frst: %p, last: %p\n", &anchor->anchor,
867 anchor->anchor.next, anchor->last);
869 printf(
"curr: %p, next: %p, prev: %p, type: %d\n", list, list->
next,
879 #define debug_list(anc) debug_list(iseq, (anc))
888 labelobj->
link.
type = ISEQ_ELEMENT_LABEL;
901 adjust->
link.
type = ISEQ_ELEMENT_ADJUST;
903 adjust->
label = label;
915 iobj->
link.
type = ISEQ_ELEMENT_INSN;
934 for (i = 0; i <
argc; i++) {
940 return new_insn_core(iseq, line_no, insn_id, argc, operands);
985 debugs(
"[new_child_iseq]> ---------------------------------------\n");
989 debugs(
"[new_child_iseq]< ---------------------------------------\n");
1002 debugs(
"[compile step 3.1 (iseq_optimize)]\n");
1009 debugs(
"[compile step 3.2 (iseq_insns_unification)]\n");
1016 debugs(
"[compile step 3.3 (iseq_set_sequence_stackcaching)]\n");
1022 debugs(
"[compile step 4.1 (iseq_set_sequence)]\n");
1027 debugs(
"[compile step 4.2 (iseq_set_exception_table)]\n");
1030 debugs(
"[compile step 4.3 (set_optargs_table)] \n");
1033 debugs(
"[compile step 5 (iseq_translate_threaded_code)] \n");
1041 debugs(
"[compile step: finish]\n");
1089 rb_bug(
"get_local_var_idx: %d", idx);
1098 int lv = 0,
idx = -1;
1110 rb_bug(
"get_dyna_var_idx: -1");
1121 debugs(
"iseq_set_arguments: %s\n", node_args ?
"" :
"0");
1130 rb_bug(
"iseq_set_arguments: NODE_ARGS is expected, but %s",
1161 node = node->nd_next;
1174 for (j = 0; j <
i; j++) {
1193 node = node->nd_next;
1199 for (j = 0; j <
i; j++) {
1266 if (iseq->
type == ISEQ_TYPE_BLOCK) {
1269 if (iseq->
argc == 1 && last_comma == 0) {
1318 if (val == lit)
return 0;
1328 return !
rb_eql(lit, val);
1371 unsigned int last_line = 0;
1373 VALUE *generated_iseq;
1375 int k, pos, sp, stack_max = 0, line = 0;
1381 switch (list->
type) {
1382 case ISEQ_ELEMENT_INSN:
1384 iobj = (
INSN *)list;
1390 case ISEQ_ELEMENT_LABEL:
1392 lobj = (
LABEL *)list;
1397 case ISEQ_ELEMENT_NONE:
1402 case ISEQ_ELEMENT_ADJUST:
1415 "error: set_sequence");
1433 switch (list->
type) {
1434 case ISEQ_ELEMENT_INSN:
1440 iobj = (
INSN *)list;
1444 if (sp > stack_max) {
1451 generated_iseq[pos] = insn;
1452 types = insn_op_types(insn);
1453 len = insn_len(insn);
1460 "operand size miss! (%d for %d)",
1462 xfree(generated_iseq);
1463 xfree(line_info_table);
1467 for (j = 0; types[j]; j++) {
1468 char type = types[j];
1474 lobj = (
LABEL *)operands[j];
1479 if (lobj->
sp == -1) {
1482 generated_iseq[pos + 1 + j] = lobj->
position - (pos +
len);
1487 VALUE map = operands[j];
1495 generated_iseq[pos + 1 + j] = map;
1500 generated_iseq[pos + 1 + j] =
FIX2INT(operands[j]);
1509 generated_iseq[pos + 1 + j] = (
VALUE)block;
1515 generated_iseq[pos + 1 + j] =
v;
1522 int ic_index =
FIX2INT(operands[j]);
1525 rb_bug(
"iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, iseq->
ic_size);
1527 generated_iseq[pos + 1 + j] = (
VALUE)ic;
1539 generated_iseq[pos + 1 + j] = (
VALUE)ci;
1543 generated_iseq[pos + 1 + j] =
SYM2ID(operands[j]);
1549 generated_iseq[pos + 1 + j] = (
VALUE)entry;
1554 "unknown operand type: %c", type);
1555 xfree(generated_iseq);
1556 xfree(line_info_table);
1560 if (last_line != iobj->
line_no) {
1568 case ISEQ_ELEMENT_LABEL:
1570 lobj = (
LABEL *)list;
1571 if (lobj->
sp == -1) {
1579 case ISEQ_ELEMENT_ADJUST:
1584 if (adjust->
label) {
1592 if (orig_sp - sp > 0) {
1593 if (last_line != (
unsigned int)adjust->
line_no) {
1598 generated_iseq[pos++] = BIN(adjuststack);
1599 generated_iseq[pos++] = orig_sp - sp;
1601 else if (orig_sp - sp == 0) {
1603 if (last_line != (
unsigned int)adjust->
line_no) {
1608 generated_iseq[pos++] = BIN(jump);
1609 generated_iseq[pos++] = 0;
1612 rb_bug(
"iseq_set_sequence: adjust bug");
1631 iseq->
iseq = (
void *)generated_iseq;
1667 for (i = 0; i < tlen; i++) {
1673 entry->
iseq = ptr[3];
1676 if (entry->
iseq != 0) {
1717 for (i = 0; i < iseq->
arg_opts; i++) {
1733 if (list->
type == ISEQ_ELEMENT_INSN || list->
type == ISEQ_ELEMENT_ADJUST) {
1747 if (list->
type == ISEQ_ELEMENT_INSN || list->
type == ISEQ_ELEMENT_ADJUST) {
1761 if (list->
type == ISEQ_ELEMENT_INSN || list->
type == ISEQ_ELEMENT_ADJUST) {
1774 if (iobj->
insn_id == BIN(jump)) {
1775 INSN *niobj, *diobj, *piobj;
1789 if (diobj == niobj) {
1798 else if (iobj != diobj && diobj->
insn_id == BIN(jump)) {
1804 else if (diobj->
insn_id == BIN(leave)) {
1840 (piobj->
insn_id == BIN(branchif) ||
1841 piobj->
insn_id == BIN(branchunless))) {
1844 ? BIN(branchunless) : BIN(branchif);
1851 if (iobj->
insn_id == BIN(branchif) ||
1852 iobj->
insn_id == BIN(branchunless)) {
1862 if (nobj->
insn_id == BIN(jump)) {
1867 if (do_tailcallopt && iobj->
insn_id == BIN(leave)) {
1877 if (piobj->
insn_id == BIN(send) || piobj->
insn_id == BIN(opt_send_simple)) {
1896 if (insn_id != BIN(opt_neq)) {
1897 rb_bug(
"insn_set_specialized_instruction: unknown insn: %d", insn_id);
1900 iobj->
operands[0] = old_operands[0];
1910 if (iobj->
insn_id == BIN(send)) {
1913 #define SP_INSN(opt) insn_set_specialized_instruction(iseq, iobj, BIN(opt_##opt))
1945 iobj->
insn_id = BIN(opt_send_simple);
1964 if (list->
type == ISEQ_ELEMENT_INSN) {
1965 if (do_peepholeopt) {
1972 insn_operands_unification((
INSN *)list);
1980 #if OPT_INSTRUCTIONS_UNIFICATION
1992 for (i = 0; i <
size; i++) {
1993 iobj = (
INSN *)list;
2005 for (i = 0; i <
size; i++) {
2006 iobj = (
INSN *)list;
2024 #if OPT_INSTRUCTIONS_UNIFICATION
2032 if (list->
type == ISEQ_ELEMENT_INSN) {
2033 iobj = (
INSN *)list;
2035 if (unified_insns_data[
id] != 0) {
2036 const int *
const *entry = unified_insns_data[
id];
2037 for (j = 1; j < (
intptr_t)entry[0]; j++) {
2038 const int *unified = entry[j];
2040 for (k = 2; k < unified[1]; k++) {
2041 if (li->
type != ISEQ_ELEMENT_INSN ||
2042 ((
INSN *)li)->insn_id != unified[k]) {
2049 new_unified_insn(iseq, unified[0], unified[1] - 1,
2072 #if OPT_STACK_CACHING
2074 #define SC_INSN(insn, stat) sc_insn_info[(insn)][(stat)]
2075 #define SC_NEXT(insn) sc_insn_next[(insn)]
2077 #include "opt_sc.inc"
2086 iobj->
insn_id = SC_INSN(insn_id, state);
2087 nstate = SC_NEXT(iobj->
insn_id);
2089 if (insn_id == BIN(jump) ||
2090 insn_id == BIN(branchif) || insn_id == BIN(branchunless)) {
2097 printf(
"\n-- %d, %d\n", lobj->
sc_state, nstate);
2099 "insn_set_sc_state error\n");
2106 if (insn_id == BIN(jump)) {
2110 else if (insn_id == BIN(leave)) {
2118 label_set_sc_state(
LABEL *lobj,
int state)
2138 #if OPT_STACK_CACHING
2150 switch (list->
type) {
2151 case ISEQ_ELEMENT_INSN:
2162 if (state != SCS_AX) {
2175 if (state == SCS_AB || state == SCS_BA) {
2176 state = (state == SCS_AB ? SCS_BA : SCS_AB);
2212 state = insn_set_sc_state(iseq, iobj, state);
2215 case ISEQ_ELEMENT_LABEL:
2218 lobj = (
LABEL *)list;
2220 state = label_set_sc_state(lobj, state);
2234 NODE *list = node->nd_next;
2235 VALUE lit = node->nd_lit;
2246 node = list->nd_head;
2252 COMPILE(ret,
"each string", node);
2255 list = list->nd_next;
2317 COMPILE(ret,
"branch condition", cond);
2335 NODE *node = node_root;
2353 NODE *start_node = node, *end_node;
2355 const int max = 0x100;
2359 for (i=0; i<max && node; i++, len++, node = node->nd_next) {
2375 COMPILE_(anchor,
"array element", node->nd_head, poped);
2385 while (node != end_node) {
2387 node = node->nd_next;
2392 node = node->nd_next;
2394 node = node->nd_next;
2436 ADD_INSN(anchor, line, concatarray);
2456 COMPILE(ret,
"keyword splat", kw);
2498 return node->nd_lit;
2511 only_special_literals = 0;
2530 COMPILE(cond_seq,
"when cond", val);
2535 vals = vals->nd_next;
2537 return only_special_literals;
2599 int llen = 0, rlen = 0;
2601 NODE *lhsn = orig_lhsn;
2603 #define MEMORY(v) { \
2605 if (memindex == memsize) return 0; \
2606 for (i=0; i<memindex; i++) { \
2607 if (mem[i] == (v)) return 0; \
2609 mem[memindex++] = (v); \
2617 NODE *ln = lhsn->nd_head;
2632 lhsn = lhsn->nd_next;
2641 COMPILE(ret,
"masgn val", rhsn->nd_head);
2643 rhsn = rhsn->nd_next;
2648 for (i=0; i<llen-rlen; i++) {
2660 NODE *rhsn = node->nd_value;
2661 NODE *splatn = node->nd_args;
2662 NODE *lhsn = node->nd_head;
2663 int lhs_splat = (splatn && (
VALUE)splatn != (
VALUE)-1) ? 1 : 0;
2674 lhsn = lhsn->nd_next;
2677 COMPILE(ret,
"normal masgn rhs", rhsn);
2690 NODE *postn = splatn->nd_2nd;
2691 NODE *restn = splatn->nd_1st;
2692 int num = (
int)postn->nd_alen;
2703 postn = postn->nd_next;
2721 debugi(
"compile_colon2 - colon", node->nd_vid);
2725 debugi(
"compile_colon2 - colon3", node->nd_mid);
2732 debugi(
"compile_colon2 - colon2", node->nd_mid);
2736 COMPILE(pref,
"const colon2 prefix", node);
2750 else if (cpath->nd_head) {
2752 COMPILE(ret,
"nd_else->nd_head", cpath->nd_head);
2763 #define defined_expr defined_expr0
2771 switch (type =
nd_type(node)) {
2797 }
while ((vals = vals->nd_next) !=
NULL);
2817 ID2SYM(node->nd_vid), needstr);
2823 ID2SYM(node->nd_entry->
id), needstr);
2829 ID2SYM(node->nd_vid), needstr);
2835 ID2SYM(node->nd_vid), needstr);
2845 COMPILE(ret,
"defined/colon2#nd_head", node->nd_head);
2847 ID2SYM(node->nd_mid), needstr);
2850 COMPILE(ret,
"defined/colon2#nd_head", node->nd_head);
2852 ID2SYM(node->nd_mid), needstr);
2870 if (node->nd_recv == (
NODE *)1)
break;
2880 if (node->nd_args) {
2887 COMPILE(ret,
"defined/recv", node->nd_recv);
2889 ID2SYM(node->nd_mid), needstr);
2894 ID2SYM(node->nd_mid), needstr);
2956 int done = defined_expr0(iseq, ret, node, lfinish, needstr);
2963 (
"defined guard in "),
2965 ISEQ_TYPE_DEFINED_GUARD, 0);
2973 #define BUFSIZE 0x100
2983 if (ip->
type == ISEQ_TYPE_BLOCK) {
3016 while (erange->
next != 0) {
3017 erange = erange->
next;
3022 erange->
end = lstart;
3073 COMPILE(arg_block,
"block", argn->nd_body);
3075 argn = argn->nd_head;
3082 COMPILE(args,
"args (splat)", argn->nd_head);
3094 COMPILE(
tmp,
"args (cat: splat)", argn->nd_body);
3095 if (next_is_array && nsplat == 0) {
3110 if (next_is_array) {
3114 argn = argn->nd_head;
3131 for (i=1; i<nsplat; i++) {
3162 debugs(
"node: NODE_NIL(implicit)\n");
3180 COMPILE_(ret,
"BLOCK body", node->nd_head,
3181 (node->nd_next == 0 && poped == 0) ? 0 : 1);
3182 node = node->nd_next;
3185 COMPILE_(ret,
"BLOCK next", node->nd_next, poped);
3193 LABEL *then_label, *else_label, *end_label;
3203 then_label, else_label);
3204 COMPILE_(then_seq,
"then", node->nd_body, poped);
3205 COMPILE_(else_seq,
"else", node->nd_else, poped);
3222 NODE *tempnode = node;
3223 LABEL *endlabel, *elselabel;
3227 int only_special_literals = 1;
3236 if (node->nd_head == 0) {
3237 COMPILE_(ret,
"when", node->nd_body, poped);
3242 node = node->nd_body;
3261 COMPILE_(body_seq,
"when body", node->nd_body, poped);
3262 ADD_INSNL(body_seq, line, jump, endlabel);
3264 vals = node->nd_head;
3268 only_special_literals =
when_vals(iseq, cond_seq, vals, l1, only_special_literals, literals);
3273 only_special_literals = 0;
3275 COMPILE(cond_seq,
"when/cond splat", vals);
3280 rb_bug(
"NODE_CASE: unknown node (%s)",
3285 rb_bug(
"NODE_CASE: must be NODE_ARRAY, but 0");
3288 node = node->nd_next;
3299 COMPILE_(cond_seq,
"else", node, poped);
3300 ADD_INSNL(cond_seq, line, jump, endlabel);
3303 debugs(
"== else (implicit)\n");
3312 if (only_special_literals) {
3327 NODE *orig_node = node;
3337 COMPILE_(body_seq,
"when", node->nd_body, poped);
3338 ADD_INSNL(body_seq, line, jump, endlabel);
3340 vals = node->nd_head;
3342 rb_bug(
"NODE_WHEN: must be NODE_ARRAY, but 0");
3347 val = vals->nd_head;
3350 vals = vals->nd_next;
3357 COMPILE(ret,
"when2/cond splat", vals);
3362 rb_bug(
"NODE_WHEN: unknown node (%s)",
3365 node = node->nd_next;
3368 COMPILE_(ret,
"else", node, poped);
3397 if (type ==
NODE_OPT_N || node->nd_state == 1) {
3408 if (tmp_label)
ADD_LABEL(ret, tmp_label);
3416 redo_label, end_label);
3421 end_label, redo_label);
3426 ADD_INSNL(ret, line, branchif, redo_label);
3432 if (node->nd_state ==
Qundef) {
3434 rb_bug(
"unsupported: putundef");
3468 COMPILE(ret,
"iter caller (for)", node->nd_iter);
3472 ISEQ_TYPE_BLOCK, line);
3480 ISEQ_TYPE_BLOCK, line);
3481 COMPILE(ret,
"iter caller", node->nd_iter);
3491 ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, retry_label, retry_end_l, 0, retry_end_l);
3496 unsigned long level = 0;
3512 else if (iseq->
type == ISEQ_TYPE_BLOCK) {
3515 COMPILE(ret,
"break val (block)", node->nd_stts);
3521 else if (iseq->
type == ISEQ_TYPE_EVAL) {
3542 else if (ip->
type == ISEQ_TYPE_BLOCK) {
3546 else if (ip->
type == ISEQ_TYPE_EVAL) {
3557 unsigned long level = 0;
3561 debugs(
"next in while loop\n");
3563 COMPILE(ret,
"next val/valid syntax?", node->nd_stts);
3574 debugs(
"next in block\n");
3577 COMPILE(ret,
"next val", node->nd_stts);
3586 else if (iseq->
type == ISEQ_TYPE_EVAL) {
3599 level = 0x8000 | 0x4000;
3604 else if (ip->
type == ISEQ_TYPE_BLOCK) {
3607 else if (ip->
type == ISEQ_TYPE_EVAL) {
3614 COMPILE(ret,
"next val", node->nd_stts);
3640 else if (iseq->
type == ISEQ_TYPE_EVAL) {
3660 unsigned long level;
3661 level = 0x8000 | 0x4000;
3672 else if (ip->
type == ISEQ_TYPE_BLOCK) {
3675 else if (ip->
type == ISEQ_TYPE_EVAL) {
3696 if (iseq->
type == ISEQ_TYPE_RESCUE) {
3710 COMPILE_(ret,
"NODE_BEGIN", node->nd_body, poped);
3720 ISEQ_TYPE_RESCUE, line);
3723 COMPILE(ret,
"rescue head", node->nd_head);
3725 if (node->nd_else) {
3727 COMPILE(ret,
"rescue else", node->nd_else);
3744 LABEL *label_miss, *label_hit;
3750 narg = resq->nd_args;
3756 COMPILE(ret,
"rescue arg", narg->nd_head);
3758 ADD_INSNL(ret, line, branchif, label_hit);
3759 narg = narg->nd_next;
3766 COMPILE(ret,
"rescue/cond splat", narg);
3768 ADD_INSNL(ret, line, branchif, label_hit);
3771 rb_bug(
"NODE_RESBODY: unknown node (%s)",
3779 ADD_INSNL(ret, line, branchif, label_hit);
3783 COMPILE(ret,
"resbody body", resq->nd_body);
3789 resq = resq->nd_head;
3799 ISEQ_TYPE_ENSURE, line);
3816 COMPILE_(ret,
"ensure head", node->nd_head, poped);
3818 if (ensr->anchor.next == 0) {
3830 erange = erange->
next;
3840 COMPILE(ret,
"nd_1st", node->nd_1st);
3845 ADD_INSNL(ret, line, branchunless, end_label);
3848 ADD_INSNL(ret, line, branchif, end_label);
3853 COMPILE_(ret,
"nd_2nd", node->nd_2nd, poped);
3864 ID id = node->nd_vid;
3868 COMPILE(ret,
"rvalue", node->nd_value);
3880 COMPILE(ret,
"dvalue", node->nd_value);
3897 COMPILE(ret,
"lvalue", node->nd_value);
3903 ((
VALUE)node->nd_entry | 1));
3908 COMPILE(ret,
"lvalue", node->nd_value);
3912 ADD_INSN2(ret, line, setinstancevariable,
3917 COMPILE(ret,
"lvalue", node->nd_value);
3935 COMPILE(ret,
"cvasgn val", node->nd_value);
3947 ID id = node->nd_mid;
3976 COMPILE(ret,
"NODE_OP_ASGN1 recv", node->nd_recv);
3977 switch (
nd_type(node->nd_args->nd_head)) {
3991 if (
id == 0 ||
id == 1) {
4011 ADD_INSNL(ret, line, branchunless, label);
4015 COMPILE(ret,
"NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body);
4051 COMPILE(ret,
"NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body);
4084 ID atype = node->nd_next->nd_mid;
4129 COMPILE(ret,
"NODE_OP_ASGN2#recv", node->nd_recv);
4134 if (atype == 0 || atype == 1) {
4140 ADD_INSNL(ret, line, branchunless, lcfin);
4143 COMPILE(ret,
"NODE_OP_ASGN2 val", node->nd_value);
4161 COMPILE(ret,
"NODE_OP_ASGN2 val", node->nd_value);
4179 switch (
nd_type(node->nd_head)) {
4184 COMPILE(ret,
"NODE_OP_CDECL/colon2#nd_head", node->nd_head->nd_head);
4193 mid = node->nd_head->nd_mid;
4195 if (node->nd_aid == 0) {
4200 ADD_INSNL(ret, line, branchunless, lassign);
4205 if (node->nd_aid == 0 || node->nd_aid == 1) {
4207 if (!poped)
ADD_INSN(ret, line, dup);
4208 if (node->nd_aid == 0)
4211 ADD_INSNL(ret, line, branchunless, lfin);
4213 if (!poped)
ADD_INSN(ret, line, pop);
4215 COMPILE(ret,
"NODE_OP_CDECL#nd_value", node->nd_value);
4225 if (!poped)
ADD_INSN(ret, line, swap);
4229 COMPILE(ret,
"NODE_OP_CDECL#nd_value", node->nd_value);
4252 lassign = lfinish[1];
4256 ADD_INSNL(ret, line, branchunless, lassign);
4262 COMPILE(ret,
"NODE_OP_ASGN_AND/OR#nd_head", node->nd_head);
4266 ADD_INSNL(ret, line, branchunless, lfin);
4274 COMPILE(ret,
"NODE_OP_ASGN_AND/OR#nd_value", node->nd_value);
4293 ID mid = node->nd_mid;
4307 CONST_ID(id_answer,
"the_answer_to_life_the_universe_and_everything");
4309 if (mid == id_bitblt) {
4313 else if (mid == id_answer) {
4327 (mid == goto_id || mid == label_id)) {
4333 if (!labels_table) {
4338 SYMBOL_P(node->nd_args->nd_head->nd_lit)) {
4340 label_name =
SYM2ID(node->nd_args->nd_head->nd_lit);
4347 label = (
LABEL *)data;
4355 if (mid == goto_id) {
4367 COMPILE(recv,
"recv", node->nd_recv);
4396 argc, parent_block,
LONG2FIX(flag));
4425 for (i = 0; i < liseq->
argc; i++) {
4434 for (j = 0; j < liseq->
arg_opts - 1; j++) {
4457 for (j=0; j<post_len; j++) {
4467 for (j=0; j<post_len; j++) {
4471 argc = post_len + post_start;
4522 COMPILE(ret,
"values item", n->nd_head);
4559 if (is->
type == ISEQ_TYPE_TOP) {
4565 if (is->
type == ISEQ_TYPE_METHOD) {
4571 COMPILE(ret,
"return nd_stts (return val)", node->nd_stts);
4573 if (is->
type == ISEQ_TYPE_METHOD) {
4599 if (iseq->
type == ISEQ_TYPE_TOP) {
4603 if (node->nd_head) {
4620 ID id = node->nd_vid;
4630 debugi(
"nd_vid", node->nd_vid);
4642 ((
VALUE)node->nd_entry | 1));
4649 debugi(
"nd_vid", node->nd_vid);
4651 ADD_INSN2(ret, line, getinstancevariable,
4657 debugi(
"nd_vid", node->nd_vid);
4661 int ic_index = iseq->
ic_size++;
4695 INT2FIX(0x01 | (node->nd_nth << 1)));
4709 ADD_INSN1(recv, line, putobject, node->nd_lit);
4714 COMPILE(recv,
"receiver", node->nd_recv);
4718 COMPILE(recv,
"receiver", node->nd_value);
4725 if (recv->last == recv->anchor.next &&
4726 INSN_OF(recv->last) == BIN(putobject) &&
4735 ADD_INSN(ret, line, opt_regexpmatch2);
4752 ADD_INSN1(ret, line, putobject, node->nd_lit);
4760 ADD_INSN1(ret, line, putstring, node->nd_lit);
4775 ADD_INSN1(ret, line, putobject, node->nd_lit);
4794 COMPILE(ret,
"nd_body", node->nd_body);
4815 int ic_index = iseq->
ic_size++;
4832 COMPILE(ret,
"argscat head", node->nd_head);
4835 COMPILE(ret,
"argscat body", node->nd_body);
4840 COMPILE(ret,
"argscat head", node->nd_head);
4841 COMPILE(ret,
"argscat body", node->nd_body);
4848 COMPILE(ret,
"arsgpush head", node->nd_head);
4851 COMPILE_(ret,
"argspush body", node->nd_body, poped);
4854 COMPILE(ret,
"arsgpush head", node->nd_head);
4855 COMPILE_(ret,
"argspush body", node->nd_body, poped);
4862 COMPILE(ret,
"splat", node->nd_head);
4873 ISEQ_TYPE_METHOD, line);
4893 ISEQ_TYPE_METHOD, line);
4898 COMPILE(ret,
"defs: recv", node->nd_recv);
4947 ISEQ_TYPE_CLASS, line);
4952 COMPILE(ret,
"super", node->nd_super);
4965 ISEQ_TYPE_CLASS, line);
4982 ISEQ_TYPE_CLASS, line);
4984 COMPILE(ret,
"sclass#recv", node->nd_recv);
4986 CONST_ID(singletonclass,
"singletonclass");
4988 ID2SYM(singletonclass), iseqval,
5000 int ic_index = iseq->
ic_size++;
5031 COMPILE(ret,
"colon2#nd_head", node->nd_head);
5042 int ic_index = iseq->
ic_size++;
5044 debugi(
"colon3#nd_mid", node->nd_mid);
5095 COMPILE(ret,
"flip2 beg", node->nd_beg);
5097 ADD_INSNL(ret, line, branchunless, lfin);
5109 COMPILE(ret,
"flip2 end", node->nd_end);
5110 ADD_INSNL(ret, line, branchunless, ltrue);
5146 if (iseq->
type == ISEQ_TYPE_RESCUE) {
5153 if (ip->
type == ISEQ_TYPE_RESCUE) {
5171 if (!node->nd_head) {
5193 int ic_index = iseq->
ic_size++;
5214 ID id = node->nd_body->nd_vid;
5219 ADD_INSNL(ret, line, branchunless, default_label);
5223 switch (
nd_type(node->nd_body)) {
5238 COMPILE_POPED(ret,
"keyword default argument", node->nd_body);
5262 if (node->nd_recv == (
NODE *) 1) {
5267 COMPILE(recv,
"recv", node->nd_recv);
5309 COMPILE_(ret,
"body", node->nd_body, poped);
5340 return insn_len(iobj->
insn_id);
5352 return insn_len(iobj->
line_no);
5361 const char *types = insn_op_types(iobj->
insn_id);
5364 for (j = 0; types[j]; j++) {
5365 char type = types[j];
5366 printf(
"str: %"PRIxVALUE", type: %c\n", str, type);
5436 printf(
"-- raw disasm--------\n");
5439 switch (link->
type) {
5440 case ISEQ_ELEMENT_INSN:
5442 iobj = (
INSN *)link;
5448 case ISEQ_ELEMENT_LABEL:
5450 lobj = (
LABEL *)link;
5451 printf(
"<L%03d>\n", lobj->
label_no);
5454 case ISEQ_ELEMENT_NONE:
5459 case ISEQ_ELEMENT_ADJUST:
5471 printf(
"---------------------\n");
5477 return insn_name_info[
i];
5485 for (i = 0; i <
numberof(insn_name_info); i++) {
5498 if (
st_lookup(labels_table, obj, &tmp) == 0) {
5503 label = (
LABEL *)tmp;
5512 #define rb_intern(str) rb_intern_const(str)
5514 static VALUE symRescue, symEnsure, symRetry;
5515 static VALUE symBreak, symRedo, symNext;
5517 if (symRescue == 0) {
5526 if (sym == symRescue)
return CATCH_TYPE_RESCUE;
5527 if (sym == symEnsure)
return CATCH_TYPE_ENSURE;
5528 if (sym == symRetry)
return CATCH_TYPE_RETRY;
5529 if (sym == symBreak)
return CATCH_TYPE_BREAK;
5530 if (sym == symRedo)
return CATCH_TYPE_REDO;
5531 if (sym == symNext)
return CATCH_TYPE_NEXT;
5546 LABEL *lstart, *lend, *lcont;
5556 if (ptr[1] ==
Qnil) {
5582 for (i=0; i<VM_INSTRUCTION_SIZE; i++) {
5619 static struct st_table *insn_table;
5621 if (insn_table == 0) {
5625 for (i=0; i<
len; i++) {
5649 if (argc != insn_len((
VALUE)insn_id)-1) {
5651 "operand size mismatch");
5656 for (j=0; j<
argc; j++) {
5658 switch (insn_op_type((
VALUE)insn_id, j)) {
5661 argv[j] = (
VALUE)label;
5698 unsigned long flag = 0;
5708 if (!
NIL_P(vorig_argc)) orig_argc =
FIX2INT(vorig_argc);
5716 "Symbol",
"to_sym");
5740 (
enum ruby_vminsn_type)insn_id, argc, argv));
5752 #define CHECK_ARRAY(v) rb_convert_type((v), T_ARRAY, "Array", "to_ary")
5753 #define CHECK_STRING(v) rb_convert_type((v), T_STRING, "String", "to_str")
5754 #define CHECK_SYMBOL(v) rb_convert_type((v), T_SYMBOL, "Symbol", "to_sym")
5812 for (i=0; i<
RARRAY_LEN(arg_opt_labels); i++) {
5837 while (iseq->
type == ISEQ_TYPE_BLOCK ||
5838 iseq->
type == ISEQ_TYPE_RESCUE ||
5839 iseq->
type == ISEQ_TYPE_ENSURE ||
5840 iseq->
type == ISEQ_TYPE_EVAL ||
5841 iseq->
type == ISEQ_TYPE_MAIN
#define RB_TYPE_P(obj, type)
#define VM_CALL_ARGS_BLOCKARG
#define DEFAULT_SPECIAL_VAR_COUNT
struct rb_block_struct * blockptr
static int iseq_add_mark_object(rb_iseq_t *iseq, VALUE v)
#define RUBY_EVENT_B_RETURN
static int iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcallopt)
int register char * block
static VALUE compile_array(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node_root, enum compile_array_type_t type)
VALUE rb_ary_entry(VALUE ary, long offset)
struct iseq_link_element * next
void rb_bug(const char *fmt,...)
static void verify_list(ISEQ_ARG_DECLARE const char *info, LINK_ANCHOR *anchor)
void rb_compile_error(const char *file, int line, const char *fmt,...)
enum iseq_link_element::@1 type
#define OPERAND_AT(insn, idx)
static ADJUST * compile_data_alloc_adjust(rb_iseq_t *iseq)
#define ADD_INSN2(seq, line, insn, op1, op2)
static int compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int poped)
static int insn_data_length(INSN *iobj)
static void push_ensure_entry(rb_iseq_t *iseq, struct iseq_compile_data_ensure_node_stack *enl, struct ensure_range *er, NODE *node)
static int max(int a, int b)
int st_lookup(st_table *, st_data_t, st_data_t *)
#define CPDEBUG
debug function(macro) interface depend on CPDEBUG if it is less than 0, runtime option is in effect...
struct ensure_range * next
static int insn_data_line_no(INSN *iobj)
st_table * st_init_numtable(void)
struct iseq_compile_data * compile_data
VALUE rb_insns_name_array(void)
const void ** rb_vm_get_insns_address_table(void)
rb_call_info_t * callinfo_entries
#define ADD_INSN(seq, line, insn)
static INSN * compile_data_alloc_insn(rb_iseq_t *iseq)
static int compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node)
VALUE rb_obj_freeze(VALUE)
static LABEL * compile_data_alloc_label(rb_iseq_t *iseq)
int rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
static INSN * new_insn_send(rb_iseq_t *iseq, int line_no, VALUE id, VALUE argc, VALUE block, VALUE flag)
VALUE rb_ary_push(VALUE ary, VALUE item)
static int compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node_root, enum compile_array_type_t type, int poped)
static void validate_labels(rb_iseq_t *iseq, st_table *labels_table)
#define debugi(header, id)
static int iseq_build_from_ary_exception(rb_iseq_t *iseq, struct st_table *labels_table, VALUE exception)
VALUE rb_ary_tmp_new(long capa)
VALUE rb_iseq_defined_string(enum defined_type type)
VALUE(* call)(struct rb_thread_struct *th, struct rb_control_frame_struct *cfp, struct rb_call_info_struct *ci)
static int validate_label(st_data_t name, st_data_t label, st_data_t arg)
struct rb_iseq_struct * local_iseq
void rb_raise(VALUE exc, const char *fmt,...)
struct iseq_label_data * start_label
VALUE rb_ary_clear(VALUE ary)
struct iseq_compile_data_storage * next
static int compile_colon2(rb_iseq_t *iseq, NODE *node, LINK_ANCHOR *pref, LINK_ANCHOR *body)
struct iseq_inline_cache_entry * ic_entries
static LINK_ELEMENT * POP_ELEMENT(ISEQ_ARG_DECLARE LINK_ANCHOR *anchor)
#define VM_CALL_ARGS_SPLAT
#define ADD_ADJUST(seq, line, label)
#define VM_DEFINECLASS_FLAG_SCOPED
int peephole_optimization
static int iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
VALUE rb_iseq_compile_node(VALUE self, NODE *node)
struct iseq_compile_data_ensure_node_stack * ensure_node_stack
static void APPEND_LIST(ISEQ_ARG_DECLARE LINK_ANCHOR *anc1, LINK_ANCHOR *anc2)
#define debug_node_start(node)
static void REMOVE_ELEM(LINK_ELEMENT *elem)
static int iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
static int get_dyna_var_idx(rb_iseq_t *iseq, ID id, int *level, int *ls)
struct iseq_label_data LABEL
VALUE rb_str_concat(VALUE, VALUE)
struct iseq_link_element LINK_ELEMENT
static int insn_set_specialized_instruction(rb_iseq_t *iseq, INSN *iobj, int insn_id)
static void INSERT_ELEM_NEXT(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
void rb_hash_foreach(VALUE, int(*)(ANYARGS), VALUE)
const rb_compile_option_t * option
int tailcall_optimization
static int iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor, VALUE body, struct st_table *labels_table)
enum iseq_catch_table_entry::catch_type type
#define MEMZERO(p, type, n)
void rb_exc_raise(VALUE mesg)
static VALUE sym_inspect(VALUE sym)
int rb_is_const_id(ID id)
#define ADD_SEQ(seq1, seq2)
enum rb_iseq_struct::iseq_type type
static VALUE iseq_build_load_iseq(rb_iseq_t *iseq, VALUE op)
static int iseq_set_local_table(rb_iseq_t *iseq, ID *tbl)
static void ADD_ELEM(ISEQ_ARG_DECLARE LINK_ANCHOR *anchor, LINK_ELEMENT *elem)
struct rb_global_entry * rb_global_entry(ID)
static INSN * new_insn_body(rb_iseq_t *iseq, int line_no, int insn_id, int argc,...)
int specialized_instruction
static int compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *rhsn, NODE *orig_lhsn)
VALUE rb_dbl2big(double d)
#define ADD_TRACE(seq, line, event)
const char * rb_insns_name(int i)
static VALUE CHECK_INTEGER(VALUE v)
#define VM_CALL_ARGS_SKIP_SETUP
#define StringValuePtr(v)
int instructions_unification
static LABEL * new_label_body(rb_iseq_t *iseq, long line)
#define NEW_ISEQVAL(node, name, type, line_no)
static void Tcl_Interp * ip
struct iseq_link_anchor LINK_ANCHOR
#define StringValueCStr(v)
static ADJUST * new_adjust_body(rb_iseq_t *iseq, LABEL *label, int line)
#define RUBY_EVENT_B_CALL
int argc
argument information
static int iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
#define VM_DEFINECLASS_FLAG_HAS_SUPERCLASS
static int cdhash_cmp(VALUE val, VALUE lit)
#define ADD_SEND(seq, line, id, argc)
#define ADD_INSNL(seq, line, insn, label)
VALUE rb_str_cat2(VALUE, const char *)
#define RUBY_EVENT_RETURN
void rb_ary_store(VALUE ary, long idx, VALUE val)
static int iseq_set_exception_local_table(rb_iseq_t *iseq)
static struct st_hash_type cdhash_type
#define ADD_CALL(seq, line, id, argc)
#define INIT_ANCHOR(name)
static LINK_ELEMENT * get_destination_insn(INSN *iobj)
static VALUE case_when_optimizable_literal(NODE *node)
#define COMPILE(anchor, desc, node)
static int get_dyna_var_idx_at_raw(rb_iseq_t *iseq, ID id)
int rb_parse_in_main(void)
static int iseq_set_optargs_table(rb_iseq_t *iseq)
struct ensure_range * erange
int link(const char *, const char *)
struct iseq_compile_data_ensure_node_stack * prev
static int get_lvar_level(rb_iseq_t *iseq)
static int LIST_SIZE_ZERO(LINK_ANCHOR *anchor)
static int iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
ruby insn object list -> raw instruction sequence
static VALUE r_value(VALUE value)
VALUE rb_hash_aset(VALUE, VALUE, VALUE)
int rb_dvar_defined(ID id)
#define ADD_SEND_R(seq, line, id, argc, block, flag)
#define ADD_LABEL(seq, label)
int st_foreach(st_table *, int(*)(ANYARGS), st_data_t)
static int iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *anchor, NODE *node)
VALUE rb_sprintf(const char *format,...)
static int compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node)
struct iseq_insn_data INSN
static void REPLACE_ELEM(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
static LINK_ELEMENT * get_next_insn(INSN *iobj)
#define CONST_ID(var, str)
VALUE rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE locals, VALUE args, VALUE exception, VALUE body)
struct rb_iseq_struct * parent_iseq
struct iseq_label_data * redo_label
#define DECL_ANCHOR(name)
#define NEW_CHILD_ISEQVAL(node, name, type, line_no)
static LINK_ELEMENT * get_prev_insn(INSN *iobj)
static INSN * new_insn_core(rb_iseq_t *iseq, int line_no, int insn_id, int argc, VALUE *argv)
struct iseq_link_element * prev
static void * compile_data_alloc(rb_iseq_t *iseq, size_t size)
static VALUE new_child_iseq(rb_iseq_t *iseq, NODE *node, VALUE name, VALUE parent, enum iseq_type type, int line_no)
#define ADD_CALL_RECEIVER(seq, line)
#define VM_CHECKMATCH_ARRAY
rb_iseq_location_t location
VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt)
static LABEL * register_label(rb_iseq_t *iseq, struct st_table *labels_table, VALUE obj)
#define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc)
static int compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *cond, LABEL *then_label, LABEL *else_label)
static VALUE compile_cpath(LINK_ANCHOR *ret, rb_iseq_t *iseq, NODE *cpath)
#define ADD_INSN3(seq, line, insn, op1, op2, op3)
#define MEMCPY(p1, p2, type, n)
static VALUE get_exception_sym2type(VALUE sym)
static int calc_sp_depth(int depth, INSN *iobj)
static int cdhash_set_label_i(VALUE key, VALUE val, void *ptr)
#define va_init_list(a, b)
void * ruby_xrealloc(void *ptr, size_t size)
static int label_get_position(LABEL *lobj)
static void add_ensure_range(rb_iseq_t *iseq, struct ensure_range *erange, LABEL *lstart, LABEL *lend)
static int label_get_sp(LABEL *lobj)
#define COMPILE_POPED(anchor, desc, node)
static int compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node)
#define debugp_param(header, value)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
if(RB_TYPE_P(r, T_FLOAT))
static VALUE insn_data_to_s_detail(INSN *iobj)
static int iseq_set_exception_table(rb_iseq_t *iseq)
const char * ruby_node_name(int node)
st_index_t rb_str_hash(VALUE)
VALUE rb_str_catf(VALUE str, const char *format,...)
struct iseq_compile_data_storage * storage_current
struct iseq_catch_table_entry * catch_table
void rb_compile_warning(const char *file, int line, const char *fmt,...)
RUBY_EXTERN VALUE rb_cObject
#define RARRAY_LENINT(ary)
struct rb_encoding_entry * list
#define ADD_ADJUST_RESTORE(seq, label)
struct iseq_line_info_entry * line_info_table
VALUE rb_ary_dup(VALUE ary)
int st_insert(st_table *, st_data_t, st_data_t)
#define ADD_CALL_WITH_BLOCK(seq, line, id, argc, block)
static VALUE setup_args(rb_iseq_t *iseq, LINK_ANCHOR *args, NODE *argn, VALUE *flag)
static rb_call_info_t * new_callinfo(rb_iseq_t *iseq, ID mid, int argc, VALUE block, unsigned long flag)
static const char * catch_type(int type)
static st_index_t cdhash_hash(VALUE a)
static struct st_table * insn_make_insn_table(void)
static void add_ensure_iseq(LINK_ANCHOR *ret, rb_iseq_t *iseq, int is_return)
#define GetISeqPtr(obj, ptr)
#define COMPILE_ERROR(strs)
const char * rb_id2name(ID id)
struct iseq_label_data * end_label
static void INSERT_LIST(ISEQ_ARG_DECLARE LINK_ANCHOR *anc1, LINK_ANCHOR *anc2)
#define COMPILE_(anchor, desc, node, poped)
static VALUE make_name_for_block(rb_iseq_t *iseq)
int rb_str_hash_cmp(VALUE, VALUE)
VALUE rb_hash_aref(VALUE, VALUE)
static int iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
static void APPEND_ELEM(ISEQ_ARG_DECLARE LINK_ANCHOR *anchor, LINK_ELEMENT *before, LINK_ELEMENT *elem)
#define SPECIAL_CONST_P(x)
static int iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
int rb_parse_in_eval(void)
static int when_vals(rb_iseq_t *iseq, LINK_ANCHOR *cond_seq, NODE *vals, LABEL *l1, int only_special_literals, VALUE literals)
#define APPEND_LABEL(seq, before, label)
static LINK_ELEMENT * FIRST_ELEMENT(LINK_ANCHOR *anchor)
static int get_local_var_idx(rb_iseq_t *iseq, ID id)
static int iseq_add_mark_object_compile_time(rb_iseq_t *iseq, VALUE v)
union rb_call_info_struct::@151 aux
int rb_local_defined(ID id)
static rb_thread_t * GET_THREAD(void)
struct iseq_adjust_data ADJUST
static int eq(VALUE x, VALUE y)
VALUE rb_iseq_disasm(VALUE self)
static int compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int *cntp)
static void compile_massign_opt_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *lhsn)
RUBY_EXTERN VALUE rb_cNumeric
VALUE rb_convert_type(VALUE, int, const char *, const char *)
#define iseq_absolute_path(iseq)
void st_free_table(st_table *)
VALUE rb_iseq_new_with_opt(NODE *node, VALUE name, VALUE path, VALUE absolute_path, VALUE first_lineno, VALUE parent, enum iseq_type type, const rb_compile_option_t *option)
static int iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *anchor, NODE *n, int)
compile each node
enum ruby_vminsn_type insn_id
static Bigint * mult(Bigint *a, Bigint *b)
int parse_in_eval
Thread-local state of evaluation context.
#define ADD_INSN1(seq, line, insn, op1)
static void dump_disasm_list(LINK_ELEMENT *elem)