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);
590 #if defined(__sparc) && SIZEOF_VOIDP == 4 && defined(__GNUC__)
591 #define STRICT_ALIGNMENT
594 #ifdef STRICT_ALIGNMENT
595 #if defined(HAVE_TRUE_LONG_LONG) && SIZEOF_LONG_LONG > SIZEOF_VALUE
596 #define ALIGNMENT_SIZE SIZEOF_LONG_LONG
598 #define ALIGNMENT_SIZE SIZEOF_VALUE
600 #define PADDING_SIZE_MAX ((size_t)((ALIGNMENT_SIZE) - 1))
601 #define ALIGNMENT_SIZE_MASK PADDING_SIZE_MAX
604 #define PADDING_SIZE_MAX 0
607 #ifdef STRICT_ALIGNMENT
610 calc_padding(
void *
ptr,
size_t size)
615 mis = (size_t)ptr & ALIGNMENT_SIZE_MASK;
617 padding = ALIGNMENT_SIZE - mis;
623 #if ALIGNMENT_SIZE > SIZEOF_VALUE
624 if (size ==
sizeof(
VALUE) && padding ==
sizeof(
VALUE)) {
639 #ifdef STRICT_ALIGNMENT
640 size_t padding = calc_padding((
void *)&storage->
buff[storage->
pos], size);
642 const size_t padding = 0;
645 if (storage->
pos + size + padding > storage->
size) {
646 unsigned long alloc_size = storage->
size * 2;
659 storage->
size = alloc_size;
660 storage->
buff = (
char *)(&storage->
buff + 1);
661 #ifdef STRICT_ALIGNMENT
662 padding = calc_padding((
void *)&storage->
buff[storage->
pos], size);
666 #ifdef STRICT_ALIGNMENT
667 storage->
pos += (
int)padding;
670 ptr = (
void *)&storage->
buff[storage->
pos];
671 storage->
pos += size;
766 anchor->last = anchor->last->prev;
767 anchor->last->next = 0;
772 #define POP_ELEMENT(anchor) POP_ELEMENT(iseq, (anchor))
825 anc1->last = anc2->
last;
830 #define APPEND_LIST(anc1, anc2) APPEND_LIST(iseq, (anc1), (anc2))
846 anc1->anchor.
next->
prev = &anc1->anchor;
852 anc1->last = anc2->
last;
859 #define INSERT_LIST(anc1, anc2) INSERT_LIST(iseq, (anc1), (anc2))
883 #define SWAP_LIST(anc1, anc2) SWAP_LIST(iseq, (anc1), (anc2))
890 first = &anc->anchor;
917 #define REVERSE_LIST(anc) REVERSE_LIST(iseq, (anc))
927 printf(
"anch: %p, frst: %p, last: %p\n", &anchor->anchor,
928 anchor->anchor.next, anchor->last);
930 printf(
"curr: %p, next: %p, prev: %p, type: %d\n", list, list->
next,
940 #define debug_list(anc) debug_list(iseq, (anc))
949 labelobj->
link.
type = ISEQ_ELEMENT_LABEL;
962 adjust->
link.
type = ISEQ_ELEMENT_ADJUST;
964 adjust->
label = label;
976 iobj->
link.
type = ISEQ_ELEMENT_INSN;
995 for (i = 0; i <
argc; i++) {
1001 return new_insn_core(iseq, line_no, insn_id, argc, operands);
1037 return new_insn_core(iseq, line_no, BIN(send), 1, operands);
1046 debugs(
"[new_child_iseq]> ---------------------------------------\n");
1050 debugs(
"[new_child_iseq]< ---------------------------------------\n");
1063 debugs(
"[compile step 3.1 (iseq_optimize)]\n");
1070 debugs(
"[compile step 3.2 (iseq_insns_unification)]\n");
1077 debugs(
"[compile step 3.3 (iseq_set_sequence_stackcaching)]\n");
1083 debugs(
"[compile step 4.1 (iseq_set_sequence)]\n");
1088 debugs(
"[compile step 4.2 (iseq_set_exception_table)]\n");
1091 debugs(
"[compile step 4.3 (set_optargs_table)] \n");
1094 debugs(
"[compile step 5 (iseq_translate_threaded_code)] \n");
1102 debugs(
"[compile step: finish]\n");
1150 rb_bug(
"get_local_var_idx: %d", idx);
1159 int lv = 0,
idx = -1;
1171 rb_bug(
"get_dyna_var_idx: -1");
1182 debugs(
"iseq_set_arguments: %s\n", node_args ?
"" :
"0");
1191 rb_bug(
"iseq_set_arguments: NODE_ARGS is expected, but %s",
1222 node = node->nd_next;
1235 for (j = 0; j <
i; j++) {
1254 node = node->nd_next;
1260 for (j = 0; j <
i; j++) {
1327 if (iseq->
type == ISEQ_TYPE_BLOCK) {
1330 if (iseq->
argc == 1 && last_comma == 0) {
1379 if (val == lit)
return 0;
1389 return !
rb_eql(lit, val);
1432 unsigned int last_line = 0;
1434 VALUE *generated_iseq;
1436 int k, pos, sp, stack_max = 0, line = 0;
1442 switch (list->
type) {
1443 case ISEQ_ELEMENT_INSN:
1445 iobj = (
INSN *)list;
1451 case ISEQ_ELEMENT_LABEL:
1453 lobj = (
LABEL *)list;
1458 case ISEQ_ELEMENT_NONE:
1463 case ISEQ_ELEMENT_ADJUST:
1476 "error: set_sequence");
1494 switch (list->
type) {
1495 case ISEQ_ELEMENT_INSN:
1501 iobj = (
INSN *)list;
1505 if (sp > stack_max) {
1512 generated_iseq[pos] = insn;
1513 types = insn_op_types(insn);
1514 len = insn_len(insn);
1521 "operand size miss! (%d for %d)",
1523 xfree(generated_iseq);
1524 xfree(line_info_table);
1528 for (j = 0; types[j]; j++) {
1529 char type = types[j];
1535 lobj = (
LABEL *)operands[j];
1540 if (lobj->
sp == -1) {
1543 generated_iseq[pos + 1 + j] = lobj->
position - (pos +
len);
1548 VALUE map = operands[j];
1556 generated_iseq[pos + 1 + j] = map;
1561 generated_iseq[pos + 1 + j] =
FIX2INT(operands[j]);
1570 generated_iseq[pos + 1 + j] = (
VALUE)block;
1576 generated_iseq[pos + 1 + j] =
v;
1583 int ic_index =
FIX2INT(operands[j]);
1586 rb_bug(
"iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, iseq->
ic_size);
1588 generated_iseq[pos + 1 + j] = (
VALUE)ic;
1600 generated_iseq[pos + 1 + j] = (
VALUE)ci;
1604 generated_iseq[pos + 1 + j] =
SYM2ID(operands[j]);
1610 generated_iseq[pos + 1 + j] = (
VALUE)entry;
1615 "unknown operand type: %c", type);
1616 xfree(generated_iseq);
1617 xfree(line_info_table);
1621 if (last_line != iobj->
line_no) {
1629 case ISEQ_ELEMENT_LABEL:
1631 lobj = (
LABEL *)list;
1632 if (lobj->
sp == -1) {
1640 case ISEQ_ELEMENT_ADJUST:
1645 if (adjust->
label) {
1653 if (orig_sp - sp > 0) {
1654 if (last_line != (
unsigned int)adjust->
line_no) {
1659 generated_iseq[pos++] = BIN(adjuststack);
1660 generated_iseq[pos++] = orig_sp - sp;
1662 else if (orig_sp - sp == 0) {
1664 if (last_line != (
unsigned int)adjust->
line_no) {
1669 generated_iseq[pos++] = BIN(jump);
1670 generated_iseq[pos++] = 0;
1673 rb_bug(
"iseq_set_sequence: adjust bug");
1692 iseq->
iseq = (
void *)generated_iseq;
1728 for (i = 0; i < tlen; i++) {
1734 entry->
iseq = ptr[3];
1737 if (entry->
iseq != 0) {
1778 for (i = 0; i < iseq->
arg_opts; i++) {
1794 if (list->
type == ISEQ_ELEMENT_INSN || list->
type == ISEQ_ELEMENT_ADJUST) {
1808 if (list->
type == ISEQ_ELEMENT_INSN || list->
type == ISEQ_ELEMENT_ADJUST) {
1822 if (list->
type == ISEQ_ELEMENT_INSN || list->
type == ISEQ_ELEMENT_ADJUST) {
1835 if (iobj->
insn_id == BIN(jump)) {
1836 INSN *niobj, *diobj, *piobj;
1850 if (diobj == niobj) {
1859 else if (iobj != diobj && diobj->
insn_id == BIN(jump)) {
1865 else if (diobj->
insn_id == BIN(leave)) {
1901 (piobj->
insn_id == BIN(branchif) ||
1902 piobj->
insn_id == BIN(branchunless))) {
1905 ? BIN(branchunless) : BIN(branchif);
1912 if (iobj->
insn_id == BIN(branchif) ||
1913 iobj->
insn_id == BIN(branchunless)) {
1923 if (nobj->
insn_id == BIN(jump)) {
1928 if (do_tailcallopt && iobj->
insn_id == BIN(leave)) {
1938 if (piobj->
insn_id == BIN(send) || piobj->
insn_id == BIN(opt_send_simple)) {
1957 if (insn_id != BIN(opt_neq)) {
1958 rb_bug(
"insn_set_specialized_instruction: unknown insn: %d", insn_id);
1961 iobj->
operands[0] = old_operands[0];
1971 if (iobj->
insn_id == BIN(send)) {
1974 #define SP_INSN(opt) insn_set_specialized_instruction(iseq, iobj, BIN(opt_##opt))
2006 iobj->
insn_id = BIN(opt_send_simple);
2025 if (list->
type == ISEQ_ELEMENT_INSN) {
2026 if (do_peepholeopt) {
2033 insn_operands_unification((
INSN *)list);
2041 #if OPT_INSTRUCTIONS_UNIFICATION
2053 for (i = 0; i <
size; i++) {
2054 iobj = (
INSN *)list;
2066 for (i = 0; i <
size; i++) {
2067 iobj = (
INSN *)list;
2085 #if OPT_INSTRUCTIONS_UNIFICATION
2093 if (list->
type == ISEQ_ELEMENT_INSN) {
2094 iobj = (
INSN *)list;
2096 if (unified_insns_data[
id] != 0) {
2097 const int *
const *entry = unified_insns_data[
id];
2098 for (j = 1; j < (
intptr_t)entry[0]; j++) {
2099 const int *unified = entry[j];
2101 for (k = 2; k < unified[1]; k++) {
2102 if (li->
type != ISEQ_ELEMENT_INSN ||
2103 ((
INSN *)li)->insn_id != unified[k]) {
2110 new_unified_insn(iseq, unified[0], unified[1] - 1,
2133 #if OPT_STACK_CACHING
2135 #define SC_INSN(insn, stat) sc_insn_info[(insn)][(stat)]
2136 #define SC_NEXT(insn) sc_insn_next[(insn)]
2138 #include "opt_sc.inc"
2147 iobj->
insn_id = SC_INSN(insn_id, state);
2148 nstate = SC_NEXT(iobj->
insn_id);
2150 if (insn_id == BIN(jump) ||
2151 insn_id == BIN(branchif) || insn_id == BIN(branchunless)) {
2158 printf(
"\n-- %d, %d\n", lobj->
sc_state, nstate);
2160 "insn_set_sc_state error\n");
2167 if (insn_id == BIN(jump)) {
2171 else if (insn_id == BIN(leave)) {
2179 label_set_sc_state(
LABEL *lobj,
int state)
2199 #if OPT_STACK_CACHING
2211 switch (list->
type) {
2212 case ISEQ_ELEMENT_INSN:
2223 if (state != SCS_AX) {
2236 if (state == SCS_AB || state == SCS_BA) {
2237 state = (state == SCS_AB ? SCS_BA : SCS_AB);
2273 state = insn_set_sc_state(iseq, iobj, state);
2276 case ISEQ_ELEMENT_LABEL:
2279 lobj = (
LABEL *)list;
2281 state = label_set_sc_state(lobj, state);
2295 NODE *list = node->nd_next;
2296 VALUE lit = node->nd_lit;
2307 node = list->nd_head;
2313 COMPILE(ret,
"each string", node);
2316 list = list->nd_next;
2378 COMPILE(ret,
"branch condition", cond);
2396 NODE *node = node_root;
2414 NODE *start_node = node, *end_node;
2416 const int max = 0x100;
2420 for (i=0; i<max && node; i++, len++, node = node->nd_next) {
2436 COMPILE_(anchor,
"array element", node->nd_head, poped);
2446 while (node != end_node) {
2448 node = node->nd_next;
2453 node = node->nd_next;
2455 node = node->nd_next;
2497 ADD_INSN(anchor, line, concatarray);
2517 COMPILE(ret,
"keyword splat", kw);
2559 return node->nd_lit;
2572 only_special_literals = 0;
2591 COMPILE(cond_seq,
"when cond", val);
2596 vals = vals->nd_next;
2598 return only_special_literals;
2660 int llen = 0, rlen = 0;
2662 NODE *lhsn = orig_lhsn;
2664 #define MEMORY(v) { \
2666 if (memindex == memsize) return 0; \
2667 for (i=0; i<memindex; i++) { \
2668 if (mem[i] == (v)) return 0; \
2670 mem[memindex++] = (v); \
2678 NODE *ln = lhsn->nd_head;
2693 lhsn = lhsn->nd_next;
2702 COMPILE(ret,
"masgn val", rhsn->nd_head);
2704 rhsn = rhsn->nd_next;
2709 for (i=0; i<llen-rlen; i++) {
2721 NODE *rhsn = node->nd_value;
2722 NODE *splatn = node->nd_args;
2723 NODE *lhsn = node->nd_head;
2724 int lhs_splat = (splatn && (
VALUE)splatn != (
VALUE)-1) ? 1 : 0;
2735 lhsn = lhsn->nd_next;
2738 COMPILE(ret,
"normal masgn rhs", rhsn);
2751 NODE *postn = splatn->nd_2nd;
2752 NODE *restn = splatn->nd_1st;
2753 int num = (
int)postn->nd_alen;
2764 postn = postn->nd_next;
2782 debugi(
"compile_colon2 - colon", node->nd_vid);
2786 debugi(
"compile_colon2 - colon3", node->nd_mid);
2793 debugi(
"compile_colon2 - colon2", node->nd_mid);
2797 COMPILE(pref,
"const colon2 prefix", node);
2811 else if (cpath->nd_head) {
2813 COMPILE(ret,
"nd_else->nd_head", cpath->nd_head);
2824 #define defined_expr defined_expr0
2832 switch (type =
nd_type(node)) {
2858 }
while ((vals = vals->nd_next) !=
NULL);
2878 ID2SYM(node->nd_vid), needstr);
2884 ID2SYM(node->nd_entry->
id), needstr);
2890 ID2SYM(node->nd_vid), needstr);
2896 ID2SYM(node->nd_vid), needstr);
2906 COMPILE(ret,
"defined/colon2#nd_head", node->nd_head);
2908 ID2SYM(node->nd_mid), needstr);
2911 COMPILE(ret,
"defined/colon2#nd_head", node->nd_head);
2913 ID2SYM(node->nd_mid), needstr);
2931 if (node->nd_recv == (
NODE *)1)
break;
2941 if (node->nd_args) {
2948 COMPILE(ret,
"defined/recv", node->nd_recv);
2950 ID2SYM(node->nd_mid), needstr);
2955 ID2SYM(node->nd_mid), needstr);
3017 int done = defined_expr0(iseq, ret, node, lfinish, needstr);
3024 (
"defined guard in "),
3026 ISEQ_TYPE_DEFINED_GUARD, 0);
3034 #define BUFSIZE 0x100
3044 if (ip->
type == ISEQ_TYPE_BLOCK) {
3077 while (erange->
next != 0) {
3078 erange = erange->
next;
3083 erange->
end = lstart;
3134 COMPILE(arg_block,
"block", argn->nd_body);
3136 argn = argn->nd_head;
3143 COMPILE(args,
"args (splat)", argn->nd_head);
3155 COMPILE(
tmp,
"args (cat: splat)", argn->nd_body);
3156 if (next_is_array && nsplat == 0) {
3171 if (next_is_array) {
3175 argn = argn->nd_head;
3192 for (i=1; i<nsplat; i++) {
3223 debugs(
"node: NODE_NIL(implicit)\n");
3241 COMPILE_(ret,
"BLOCK body", node->nd_head,
3242 (node->nd_next == 0 && poped == 0) ? 0 : 1);
3243 node = node->nd_next;
3246 COMPILE_(ret,
"BLOCK next", node->nd_next, poped);
3254 LABEL *then_label, *else_label, *end_label;
3264 then_label, else_label);
3265 COMPILE_(then_seq,
"then", node->nd_body, poped);
3266 COMPILE_(else_seq,
"else", node->nd_else, poped);
3283 NODE *tempnode = node;
3284 LABEL *endlabel, *elselabel;
3288 int only_special_literals = 1;
3297 if (node->nd_head == 0) {
3298 COMPILE_(ret,
"when", node->nd_body, poped);
3303 node = node->nd_body;
3322 COMPILE_(body_seq,
"when body", node->nd_body, poped);
3323 ADD_INSNL(body_seq, line, jump, endlabel);
3325 vals = node->nd_head;
3329 only_special_literals =
when_vals(iseq, cond_seq, vals, l1, only_special_literals, literals);
3334 only_special_literals = 0;
3336 COMPILE(cond_seq,
"when/cond splat", vals);
3341 rb_bug(
"NODE_CASE: unknown node (%s)",
3346 rb_bug(
"NODE_CASE: must be NODE_ARRAY, but 0");
3349 node = node->nd_next;
3360 COMPILE_(cond_seq,
"else", node, poped);
3361 ADD_INSNL(cond_seq, line, jump, endlabel);
3364 debugs(
"== else (implicit)\n");
3373 if (only_special_literals) {
3388 NODE *orig_node = node;
3398 COMPILE_(body_seq,
"when", node->nd_body, poped);
3399 ADD_INSNL(body_seq, line, jump, endlabel);
3401 vals = node->nd_head;
3403 rb_bug(
"NODE_WHEN: must be NODE_ARRAY, but 0");
3408 val = vals->nd_head;
3411 vals = vals->nd_next;
3418 COMPILE(ret,
"when2/cond splat", vals);
3423 rb_bug(
"NODE_WHEN: unknown node (%s)",
3426 node = node->nd_next;
3429 COMPILE_(ret,
"else", node, poped);
3458 if (type ==
NODE_OPT_N || node->nd_state == 1) {
3469 if (tmp_label)
ADD_LABEL(ret, tmp_label);
3477 redo_label, end_label);
3482 end_label, redo_label);
3487 ADD_INSNL(ret, line, branchif, redo_label);
3493 if (node->nd_state ==
Qundef) {
3495 rb_bug(
"unsupported: putundef");
3529 COMPILE(ret,
"iter caller (for)", node->nd_iter);
3533 ISEQ_TYPE_BLOCK, line);
3541 ISEQ_TYPE_BLOCK, line);
3542 COMPILE(ret,
"iter caller", node->nd_iter);
3552 ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, retry_label, retry_end_l, 0, retry_end_l);
3557 unsigned long level = 0;
3573 else if (iseq->
type == ISEQ_TYPE_BLOCK) {
3576 COMPILE(ret,
"break val (block)", node->nd_stts);
3582 else if (iseq->
type == ISEQ_TYPE_EVAL) {
3603 else if (ip->
type == ISEQ_TYPE_BLOCK) {
3607 else if (ip->
type == ISEQ_TYPE_EVAL) {
3618 unsigned long level = 0;
3622 debugs(
"next in while loop\n");
3624 COMPILE(ret,
"next val/valid syntax?", node->nd_stts);
3635 debugs(
"next in block\n");
3638 COMPILE(ret,
"next val", node->nd_stts);
3647 else if (iseq->
type == ISEQ_TYPE_EVAL) {
3660 level = 0x8000 | 0x4000;
3665 else if (ip->
type == ISEQ_TYPE_BLOCK) {
3668 else if (ip->
type == ISEQ_TYPE_EVAL) {
3675 COMPILE(ret,
"next val", node->nd_stts);
3701 else if (iseq->
type == ISEQ_TYPE_EVAL) {
3721 unsigned long level;
3722 level = 0x8000 | 0x4000;
3733 else if (ip->
type == ISEQ_TYPE_BLOCK) {
3736 else if (ip->
type == ISEQ_TYPE_EVAL) {
3757 if (iseq->
type == ISEQ_TYPE_RESCUE) {
3771 COMPILE_(ret,
"NODE_BEGIN", node->nd_body, poped);
3781 ISEQ_TYPE_RESCUE, line);
3784 COMPILE(ret,
"rescue head", node->nd_head);
3786 if (node->nd_else) {
3788 COMPILE(ret,
"rescue else", node->nd_else);
3805 LABEL *label_miss, *label_hit;
3811 narg = resq->nd_args;
3817 COMPILE(ret,
"rescue arg", narg->nd_head);
3819 ADD_INSNL(ret, line, branchif, label_hit);
3820 narg = narg->nd_next;
3827 COMPILE(ret,
"rescue/cond splat", narg);
3829 ADD_INSNL(ret, line, branchif, label_hit);
3832 rb_bug(
"NODE_RESBODY: unknown node (%s)",
3840 ADD_INSNL(ret, line, branchif, label_hit);
3844 COMPILE(ret,
"resbody body", resq->nd_body);
3850 resq = resq->nd_head;
3860 ISEQ_TYPE_ENSURE, line);
3877 COMPILE_(ret,
"ensure head", node->nd_head, poped);
3879 if (ensr->anchor.next == 0) {
3891 erange = erange->
next;
3901 COMPILE(ret,
"nd_1st", node->nd_1st);
3906 ADD_INSNL(ret, line, branchunless, end_label);
3909 ADD_INSNL(ret, line, branchif, end_label);
3914 COMPILE_(ret,
"nd_2nd", node->nd_2nd, poped);
3925 ID id = node->nd_vid;
3929 COMPILE(ret,
"rvalue", node->nd_value);
3941 COMPILE(ret,
"dvalue", node->nd_value);
3958 COMPILE(ret,
"lvalue", node->nd_value);
3964 ((
VALUE)node->nd_entry | 1));
3969 COMPILE(ret,
"lvalue", node->nd_value);
3973 ADD_INSN2(ret, line, setinstancevariable,
3978 COMPILE(ret,
"lvalue", node->nd_value);
3996 COMPILE(ret,
"cvasgn val", node->nd_value);
4008 ID id = node->nd_mid;
4037 COMPILE(ret,
"NODE_OP_ASGN1 recv", node->nd_recv);
4038 switch (
nd_type(node->nd_args->nd_head)) {
4052 if (
id == 0 ||
id == 1) {
4072 ADD_INSNL(ret, line, branchunless, label);
4076 COMPILE(ret,
"NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body);
4112 COMPILE(ret,
"NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body);
4145 ID atype = node->nd_next->nd_mid;
4190 COMPILE(ret,
"NODE_OP_ASGN2#recv", node->nd_recv);
4195 if (atype == 0 || atype == 1) {
4201 ADD_INSNL(ret, line, branchunless, lcfin);
4204 COMPILE(ret,
"NODE_OP_ASGN2 val", node->nd_value);
4222 COMPILE(ret,
"NODE_OP_ASGN2 val", node->nd_value);
4240 switch (
nd_type(node->nd_head)) {
4245 COMPILE(ret,
"NODE_OP_CDECL/colon2#nd_head", node->nd_head->nd_head);
4254 mid = node->nd_head->nd_mid;
4256 if (node->nd_aid == 0) {
4261 ADD_INSNL(ret, line, branchunless, lassign);
4266 if (node->nd_aid == 0 || node->nd_aid == 1) {
4268 if (!poped)
ADD_INSN(ret, line, dup);
4269 if (node->nd_aid == 0)
4272 ADD_INSNL(ret, line, branchunless, lfin);
4274 if (!poped)
ADD_INSN(ret, line, pop);
4276 COMPILE(ret,
"NODE_OP_CDECL#nd_value", node->nd_value);
4286 if (!poped)
ADD_INSN(ret, line, swap);
4290 COMPILE(ret,
"NODE_OP_CDECL#nd_value", node->nd_value);
4313 lassign = lfinish[1];
4317 ADD_INSNL(ret, line, branchunless, lassign);
4323 COMPILE(ret,
"NODE_OP_ASGN_AND/OR#nd_head", node->nd_head);
4327 ADD_INSNL(ret, line, branchunless, lfin);
4335 COMPILE(ret,
"NODE_OP_ASGN_AND/OR#nd_value", node->nd_value);
4354 ID mid = node->nd_mid;
4368 CONST_ID(id_answer,
"the_answer_to_life_the_universe_and_everything");
4370 if (mid == id_bitblt) {
4374 else if (mid == id_answer) {
4388 (mid == goto_id || mid == label_id)) {
4394 if (!labels_table) {
4399 SYMBOL_P(node->nd_args->nd_head->nd_lit)) {
4401 label_name =
SYM2ID(node->nd_args->nd_head->nd_lit);
4408 label = (
LABEL *)data;
4416 if (mid == goto_id) {
4428 COMPILE(recv,
"recv", node->nd_recv);
4457 argc, parent_block,
LONG2FIX(flag));
4486 for (i = 0; i < liseq->
argc; i++) {
4495 for (j = 0; j < liseq->
arg_opts - 1; j++) {
4518 for (j=0; j<post_len; j++) {
4528 for (j=0; j<post_len; j++) {
4532 argc = post_len + post_start;
4583 COMPILE(ret,
"values item", n->nd_head);
4620 if (is->
type == ISEQ_TYPE_TOP) {
4626 if (is->
type == ISEQ_TYPE_METHOD) {
4632 COMPILE(ret,
"return nd_stts (return val)", node->nd_stts);
4634 if (is->
type == ISEQ_TYPE_METHOD) {
4660 if (iseq->
type == ISEQ_TYPE_TOP) {
4664 if (node->nd_head) {
4681 ID id = node->nd_vid;
4691 debugi(
"nd_vid", node->nd_vid);
4703 ((
VALUE)node->nd_entry | 1));
4710 debugi(
"nd_vid", node->nd_vid);
4712 ADD_INSN2(ret, line, getinstancevariable,
4718 debugi(
"nd_vid", node->nd_vid);
4722 int ic_index = iseq->
ic_size++;
4756 INT2FIX(0x01 | (node->nd_nth << 1)));
4770 ADD_INSN1(recv, line, putobject, node->nd_lit);
4775 COMPILE(recv,
"receiver", node->nd_recv);
4779 COMPILE(recv,
"receiver", node->nd_value);
4786 if (recv->last == recv->anchor.next &&
4787 INSN_OF(recv->last) == BIN(putobject) &&
4796 ADD_INSN(ret, line, opt_regexpmatch2);
4813 ADD_INSN1(ret, line, putobject, node->nd_lit);
4821 ADD_INSN1(ret, line, putstring, node->nd_lit);
4836 ADD_INSN1(ret, line, putobject, node->nd_lit);
4855 COMPILE(ret,
"nd_body", node->nd_body);
4876 int ic_index = iseq->
ic_size++;
4893 COMPILE(ret,
"argscat head", node->nd_head);
4896 COMPILE(ret,
"argscat body", node->nd_body);
4901 COMPILE(ret,
"argscat head", node->nd_head);
4902 COMPILE(ret,
"argscat body", node->nd_body);
4909 COMPILE(ret,
"arsgpush head", node->nd_head);
4912 COMPILE_(ret,
"argspush body", node->nd_body, poped);
4915 COMPILE(ret,
"arsgpush head", node->nd_head);
4916 COMPILE_(ret,
"argspush body", node->nd_body, poped);
4923 COMPILE(ret,
"splat", node->nd_head);
4934 ISEQ_TYPE_METHOD, line);
4954 ISEQ_TYPE_METHOD, line);
4959 COMPILE(ret,
"defs: recv", node->nd_recv);
5008 ISEQ_TYPE_CLASS, line);
5013 COMPILE(ret,
"super", node->nd_super);
5026 ISEQ_TYPE_CLASS, line);
5043 ISEQ_TYPE_CLASS, line);
5045 COMPILE(ret,
"sclass#recv", node->nd_recv);
5047 CONST_ID(singletonclass,
"singletonclass");
5049 ID2SYM(singletonclass), iseqval,
5061 int ic_index = iseq->
ic_size++;
5092 COMPILE(ret,
"colon2#nd_head", node->nd_head);
5103 int ic_index = iseq->
ic_size++;
5105 debugi(
"colon3#nd_mid", node->nd_mid);
5156 COMPILE(ret,
"flip2 beg", node->nd_beg);
5158 ADD_INSNL(ret, line, branchunless, lfin);
5170 COMPILE(ret,
"flip2 end", node->nd_end);
5171 ADD_INSNL(ret, line, branchunless, ltrue);
5207 if (iseq->
type == ISEQ_TYPE_RESCUE) {
5214 if (ip->
type == ISEQ_TYPE_RESCUE) {
5232 if (!node->nd_head) {
5254 int ic_index = iseq->
ic_size++;
5275 ID id = node->nd_body->nd_vid;
5280 ADD_INSNL(ret, line, branchunless, default_label);
5284 switch (
nd_type(node->nd_body)) {
5299 COMPILE_POPED(ret,
"keyword default argument", node->nd_body);
5323 if (node->nd_recv == (
NODE *) 1) {
5328 COMPILE(recv,
"recv", node->nd_recv);
5370 COMPILE_(ret,
"body", node->nd_body, poped);
5401 return insn_len(iobj->
insn_id);
5413 return insn_len(iobj->
line_no);
5422 const char *types = insn_op_types(iobj->
insn_id);
5425 for (j = 0; types[j]; j++) {
5426 char type = types[j];
5427 printf(
"str: %"PRIxVALUE", type: %c\n", str, type);
5497 printf(
"-- raw disasm--------\n");
5500 switch (link->
type) {
5501 case ISEQ_ELEMENT_INSN:
5503 iobj = (
INSN *)link;
5509 case ISEQ_ELEMENT_LABEL:
5511 lobj = (
LABEL *)link;
5512 printf(
"<L%03d>\n", lobj->
label_no);
5515 case ISEQ_ELEMENT_NONE:
5520 case ISEQ_ELEMENT_ADJUST:
5532 printf(
"---------------------\n");
5538 return insn_name_info[
i];
5546 for (i = 0; i <
numberof(insn_name_info); i++) {
5559 if (
st_lookup(labels_table, obj, &tmp) == 0) {
5564 label = (
LABEL *)tmp;
5573 #define rb_intern(str) rb_intern_const(str)
5575 static VALUE symRescue, symEnsure, symRetry;
5576 static VALUE symBreak, symRedo, symNext;
5578 if (symRescue == 0) {
5587 if (sym == symRescue)
return CATCH_TYPE_RESCUE;
5588 if (sym == symEnsure)
return CATCH_TYPE_ENSURE;
5589 if (sym == symRetry)
return CATCH_TYPE_RETRY;
5590 if (sym == symBreak)
return CATCH_TYPE_BREAK;
5591 if (sym == symRedo)
return CATCH_TYPE_REDO;
5592 if (sym == symNext)
return CATCH_TYPE_NEXT;
5607 LABEL *lstart, *lend, *lcont;
5617 if (ptr[1] ==
Qnil) {
5643 for (i=0; i<VM_INSTRUCTION_SIZE; i++) {
5680 static struct st_table *insn_table;
5682 if (insn_table == 0) {
5686 for (i=0; i<
len; i++) {
5710 if (argc != insn_len((
VALUE)insn_id)-1) {
5712 "operand size mismatch");
5717 for (j=0; j<
argc; j++) {
5719 switch (insn_op_type((
VALUE)insn_id, j)) {
5722 argv[j] = (
VALUE)label;
5759 unsigned long flag = 0;
5769 if (!
NIL_P(vorig_argc)) orig_argc =
FIX2INT(vorig_argc);
5777 "Symbol",
"to_sym");
5801 (
enum ruby_vminsn_type)insn_id, argc, argv));
5813 #define CHECK_ARRAY(v) rb_convert_type((v), T_ARRAY, "Array", "to_ary")
5814 #define CHECK_STRING(v) rb_convert_type((v), T_STRING, "String", "to_str")
5815 #define CHECK_SYMBOL(v) rb_convert_type((v), T_SYMBOL, "Symbol", "to_sym")
5873 for (i=0; i<
RARRAY_LEN(arg_opt_labels); i++) {
5898 while (iseq->
type == ISEQ_TYPE_BLOCK ||
5899 iseq->
type == ISEQ_TYPE_RESCUE ||
5900 iseq->
type == ISEQ_TYPE_ENSURE ||
5901 iseq->
type == ISEQ_TYPE_EVAL ||
5902 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)
void rb_iseq_add_mark_object(rb_iseq_t *iseq, VALUE obj)
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)