24#include "insns_info.inc"
32#undef RUBY_UNTYPED_DATA_WARNING
33#define RUBY_UNTYPED_DATA_WARNING 0
35#define FIXNUM_INC(n, i) ((n)+(INT2FIX(i)&~FIXNUM_FLAG))
36#define FIXNUM_OR(n, i) ((n)|INT2FIX(i))
130#define compile_debug CPDEBUG
132#define compile_debug ISEQ_COMPILE_DATA(iseq)->option->debug_level
137#define compile_debug_print_indent(level) \
138 ruby_debug_print_indent((level), compile_debug, gl_node_level * 2)
140#define debugp(header, value) (void) \
141 (compile_debug_print_indent(1) && \
142 ruby_debug_print_value(1, compile_debug, (header), (value)))
144#define debugi(header, id) (void) \
145 (compile_debug_print_indent(1) && \
146 ruby_debug_print_id(1, compile_debug, (header), (id)))
148#define debugp_param(header, value) (void) \
149 (compile_debug_print_indent(1) && \
150 ruby_debug_print_value(1, compile_debug, (header), (value)))
152#define debugp_verbose(header, value) (void) \
153 (compile_debug_print_indent(2) && \
154 ruby_debug_print_value(2, compile_debug, (header), (value)))
156#define debugp_verbose_node(header, value) (void) \
157 (compile_debug_print_indent(10) && \
158 ruby_debug_print_value(10, compile_debug, (header), (value)))
160#define debug_node_start(node) ((void) \
161 (compile_debug_print_indent(1) && \
162 (ruby_debug_print_node(1, CPDEBUG, "", (const NODE *)(node)), gl_node_level)), \
165#define debug_node_end() gl_node_level --
169#define debugi(header, id) ((void)0)
170#define debugp(header, value) ((void)0)
171#define debugp_verbose(header, value) ((void)0)
172#define debugp_verbose_node(header, value) ((void)0)
173#define debugp_param(header, value) ((void)0)
174#define debug_node_start(node) ((void)0)
175#define debug_node_end() ((void)0)
178#if CPDEBUG > 1 || CPDEBUG < 0
179#define printf ruby_debug_printf
180#define debugs if (compile_debug_print_indent(1)) ruby_debug_printf
181#define debug_compile(msg, v) ((void)(compile_debug_print_indent(1) && fputs((msg), stderr)), (v))
183#define debugs if(0)printf
184#define debug_compile(msg, v) (v)
187#define LVAR_ERRINFO (1)
190#define NEW_LABEL(l) new_label_body(iseq, (l))
191#define LABEL_FORMAT "<L%03d>"
193#define NEW_ISEQ(node, name, type, line_no) \
194 new_child_iseq(iseq, (node), rb_fstring(name), 0, (type), (line_no))
196#define NEW_CHILD_ISEQ(node, name, type, line_no) \
197 new_child_iseq(iseq, (node), rb_fstring(name), iseq, (type), (line_no))
200#define ADD_SEQ(seq1, seq2) \
201 APPEND_LIST((seq1), (seq2))
204#define ADD_INSN(seq, line, insn) \
205 ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0))
208#define INSERT_BEFORE_INSN(next, line, insn) \
209 ELEM_INSERT_PREV(&(next)->link, (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0))
212#define INSERT_AFTER_INSN(prev, line, insn) \
213 ELEM_INSERT_NEXT(&(prev)->link, (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0))
216#define ADD_INSN1(seq, line, insn, op1) \
217 ADD_ELEM((seq), (LINK_ELEMENT *) \
218 new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1)))
221#define INSERT_BEFORE_INSN1(next, line, insn, op1) \
222 ELEM_INSERT_PREV(&(next)->link, (LINK_ELEMENT *) \
223 new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1)))
226#define INSERT_AFTER_INSN1(prev, line, insn, op1) \
227 ELEM_INSERT_NEXT(&(prev)->link, (LINK_ELEMENT *) \
228 new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1)))
230#define LABEL_REF(label) ((label)->refcnt++)
233#define ADD_INSNL(seq, line, insn, label) (ADD_INSN1(seq, line, insn, label), LABEL_REF(label))
235#define ADD_INSN2(seq, line, insn, op1, op2) \
236 ADD_ELEM((seq), (LINK_ELEMENT *) \
237 new_insn_body(iseq, (line), BIN(insn), 2, (VALUE)(op1), (VALUE)(op2)))
239#define ADD_INSN3(seq, line, insn, op1, op2, op3) \
240 ADD_ELEM((seq), (LINK_ELEMENT *) \
241 new_insn_body(iseq, (line), BIN(insn), 3, (VALUE)(op1), (VALUE)(op2), (VALUE)(op3)))
244#define ADD_SEND(seq, line, id, argc) \
245 ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)INT2FIX(0), NULL)
247#define ADD_SEND_WITH_FLAG(seq, line, id, argc, flag) \
248 ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)(flag), NULL)
250#define ADD_SEND_WITH_BLOCK(seq, line, id, argc, block) \
251 ADD_SEND_R((seq), (line), (id), (argc), (block), (VALUE)INT2FIX(0), NULL)
253#define ADD_CALL_RECEIVER(seq, line) \
254 ADD_INSN((seq), (line), putself)
256#define ADD_CALL(seq, line, id, argc) \
257 ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)INT2FIX(VM_CALL_FCALL), NULL)
259#define ADD_CALL_WITH_BLOCK(seq, line, id, argc, block) \
260 ADD_SEND_R((seq), (line), (id), (argc), (block), (VALUE)INT2FIX(VM_CALL_FCALL), NULL)
262#define ADD_SEND_R(seq, line, id, argc, block, flag, keywords) \
263 ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_send(iseq, (line), (id), (VALUE)(argc), (block), (VALUE)(flag), (keywords)))
265#define ADD_TRACE(seq, event) \
266 ADD_ELEM((seq), (LINK_ELEMENT *)new_trace_body(iseq, (event), 0))
267#define ADD_TRACE_WITH_DATA(seq, event, data) \
268 ADD_ELEM((seq), (LINK_ELEMENT *)new_trace_body(iseq, (event), (data)))
271#define DECL_BRANCH_BASE(branches, first_line, first_column, last_line, last_column, type) \
273 if (ISEQ_COVERAGE(iseq) && \
274 ISEQ_BRANCH_COVERAGE(iseq) && \
275 (first_line) > 0) { \
276 VALUE structure = RARRAY_AREF(ISEQ_BRANCH_COVERAGE(iseq), 0); \
277 branches = rb_ary_tmp_new(5); \
278 rb_ary_push(structure, branches); \
279 rb_ary_push(branches, ID2SYM(rb_intern(type))); \
280 rb_ary_push(branches, INT2FIX(first_line)); \
281 rb_ary_push(branches, INT2FIX(first_column)); \
282 rb_ary_push(branches, INT2FIX(last_line)); \
283 rb_ary_push(branches, INT2FIX(last_column)); \
286#define ADD_TRACE_BRANCH_COVERAGE(seq, first_line, first_column, last_line, last_column, type, branches) \
288 if (ISEQ_COVERAGE(iseq) && \
289 ISEQ_BRANCH_COVERAGE(iseq) && \
290 (first_line) > 0) { \
291 VALUE counters = RARRAY_AREF(ISEQ_BRANCH_COVERAGE(iseq), 1); \
292 long counter_idx = RARRAY_LEN(counters); \
293 rb_ary_push(counters, INT2FIX(0)); \
294 rb_ary_push(branches, ID2SYM(rb_intern(type))); \
295 rb_ary_push(branches, INT2FIX(first_line)); \
296 rb_ary_push(branches, INT2FIX(first_column)); \
297 rb_ary_push(branches, INT2FIX(last_line)); \
298 rb_ary_push(branches, INT2FIX(last_column)); \
299 rb_ary_push(branches, INT2FIX(counter_idx)); \
300 ADD_TRACE_WITH_DATA(seq, RUBY_EVENT_COVERAGE_BRANCH, counter_idx); \
301 ADD_INSN(seq, last_line, nop); \
308#define ADD_GETLOCAL(seq, line, idx, level) iseq_add_getlocal(iseq, (seq), (line), (idx), (level))
309#define ADD_SETLOCAL(seq, line, idx, level) iseq_add_setlocal(iseq, (seq), (line), (idx), (level))
312#define ADD_LABEL(seq, label) \
313 ADD_ELEM((seq), (LINK_ELEMENT *) (label))
315#define APPEND_LABEL(seq, before, label) \
316 APPEND_ELEM((seq), (before), (LINK_ELEMENT *) (label))
318#define ADD_ADJUST(seq, line, label) \
319 ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), (line)))
321#define ADD_ADJUST_RESTORE(seq, label) \
322 ADD_ELEM((seq), (LINK_ELEMENT *) new_adjust_body(iseq, (label), -1))
324#define LABEL_UNREMOVABLE(label) \
325 ((label) ? (LABEL_REF(label), (label)->unremovable=1) : 0)
326#define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc) do { \
327 VALUE _e = rb_ary_new3(5, (type), \
328 (VALUE)(ls) | 1, (VALUE)(le) | 1, \
329 (VALUE)(iseqv), (VALUE)(lc) | 1); \
330 LABEL_UNREMOVABLE(ls); \
333 if (NIL_P(ISEQ_COMPILE_DATA(iseq)->catch_table_ary)) \
334 RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->catch_table_ary, rb_ary_tmp_new(3)); \
335 rb_ary_push(ISEQ_COMPILE_DATA(iseq)->catch_table_ary, freeze_hide_obj(_e)); \
339#define COMPILE(anchor, desc, node) \
340 (debug_compile("== " desc "\n", \
341 iseq_compile_each(iseq, (anchor), (node), 0)))
344#define COMPILE_POPPED(anchor, desc, node) \
345 (debug_compile("== " desc "\n", \
346 iseq_compile_each(iseq, (anchor), (node), 1)))
349#define COMPILE_(anchor, desc, node, popped) \
350 (debug_compile("== " desc "\n", \
351 iseq_compile_each(iseq, (anchor), (node), (popped))))
353#define COMPILE_RECV(anchor, desc, node) \
354 (private_recv_p(node) ? \
355 (ADD_INSN(anchor, nd_line(node), putself), VM_CALL_FCALL) : \
356 COMPILE(anchor, desc, node->nd_recv) ? 0 : -1)
358#define OPERAND_AT(insn, idx) \
359 (((INSN*)(insn))->operands[(idx)])
361#define INSN_OF(insn) \
362 (((INSN*)(insn))->insn_id)
364#define IS_INSN(link) ((link)->type == ISEQ_ELEMENT_INSN)
365#define IS_LABEL(link) ((link)->type == ISEQ_ELEMENT_LABEL)
366#define IS_ADJUST(link) ((link)->type == ISEQ_ELEMENT_ADJUST)
367#define IS_TRACE(link) ((link)->type == ISEQ_ELEMENT_TRACE)
368#define IS_INSN_ID(iobj, insn) (INSN_OF(iobj) == BIN(insn))
369#define IS_NEXT_INSN_ID(link, insn) \
370 ((link)->next && IS_INSN((link)->next) && IS_INSN_ID((link)->next, insn))
380 VALUE err_info = ISEQ_COMPILE_DATA(
iseq)->err_info;
388 if (
NIL_P(err_info)) {
392 else if (!err_info) {
413#define COMPILE_ERROR append_compile_error
415#define ERROR_ARGS_AT(n) iseq, nd_line(n),
416#define ERROR_ARGS ERROR_ARGS_AT(node)
418#define EXPECT_NODE(prefix, node, ndtype, errval) \
420 const NODE *error_node = (node); \
421 enum node_type error_type = nd_type(error_node); \
422 if (error_type != (ndtype)) { \
423 COMPILE_ERROR(ERROR_ARGS_AT(error_node) \
424 prefix ": " #ndtype " is expected, but %s", \
425 ruby_node_name(error_type)); \
430#define EXPECT_NODE_NONULL(prefix, parent, ndtype, errval) \
432 COMPILE_ERROR(ERROR_ARGS_AT(parent) \
433 prefix ": must be " #ndtype ", but 0"); \
437#define UNKNOWN_NODE(prefix, node, errval) \
439 const NODE *error_node = (node); \
440 COMPILE_ERROR(ERROR_ARGS_AT(error_node) prefix ": unknown node (%s)", \
441 ruby_node_name(nd_type(error_node))); \
448#define CHECK(sub) if (!(sub)) {BEFORE_RETURN;return COMPILE_NG;}
449#define NO_CHECK(sub) (void)(sub)
454#define DECL_ANCHOR(name) \
455 LINK_ANCHOR name[1] = {{{ISEQ_ELEMENT_ANCHOR,},}}
456#define INIT_ANCHOR(name) \
457 (name->last = &name->anchor)
467#include "optinsn.inc"
468#if OPT_INSTRUCTIONS_UNIFICATION
469#include "optunifs.inc"
474#define ISEQ_ARG iseq,
475#define ISEQ_ARG_DECLARE rb_iseq_t *iseq,
478#define ISEQ_ARG_DECLARE
482#define gl_node_level ISEQ_COMPILE_DATA(iseq)->node_level
488static int insn_data_length(
INSN *iobj);
489static int calc_sp_depth(
int depth,
INSN *iobj);
530 if (plist !=
list->prev) {
537 if (anchor->
last != plist && anchor->
last != 0) {
542 rb_bug(
"list verify error: %08x (%s)", flag, info);
547#define verify_list(info, anchor) verify_list(iseq, (info), (anchor))
556 while (i < iseq->body->iseq_size) {
558 const char *
types = insn_op_types(insn);
560 for (
int j=0;
types[j]; j++) {
561 if (
types[j] == TS_CALLDATA) {
566 rb_bug(
"call cache not zero for fresh iseq");
581 elem->
prev = anchor->last;
582 anchor->last->
next = elem;
584 verify_list(
"add", anchor);
597 if (before == anchor->last) anchor->last = elem;
598 verify_list(
"add", anchor);
601#define ADD_ELEM(anchor, elem) ADD_ELEM(iseq, (anchor), (elem))
602#define APPEND_ELEM(anchor, before, elem) APPEND_ELEM(iseq, (anchor), (before), (elem))
605#define ISEQ_LAST_LINE(iseq) (ISEQ_COMPILE_DATA(iseq)->last_line)
637 ADD_INSN(ret, ISEQ_COMPILE_DATA(
iseq)->last_line, leave);
640 return iseq_setup(
iseq, ret);
655 iseq_set_local_table(
iseq, 0);
660 iseq_set_local_table(
iseq, node->nd_tbl);
661 iseq_set_arguments(
iseq, ret, node->nd_args);
664 case ISEQ_TYPE_BLOCK:
685 case ISEQ_TYPE_CLASS:
690 ISEQ_COMPILE_DATA(
iseq)->last_line =
nd_line(node);
693 case ISEQ_TYPE_METHOD:
698 ISEQ_COMPILE_DATA(
iseq)->last_line =
nd_line(node);
709#define INVALID_ISEQ_TYPE(type) \
710 ISEQ_TYPE_##type: m = #type; goto invalid_iseq_type
718#undef INVALID_ISEQ_TYPE
719 case ISEQ_TYPE_RESCUE:
720 iseq_set_exception_local_table(
iseq);
723 case ISEQ_TYPE_ENSURE:
724 iseq_set_exception_local_table(
iseq);
727 case ISEQ_TYPE_PLAIN:
744 ADD_INSN(ret, ISEQ_COMPILE_DATA(
iseq)->last_line, leave);
748 if (ISEQ_COMPILE_DATA(
iseq)->labels_table) {
749 st_table *labels_table = ISEQ_COMPILE_DATA(
iseq)->labels_table;
750 ISEQ_COMPILE_DATA(
iseq)->labels_table = 0;
751 validate_labels(
iseq, labels_table);
755 return iseq_setup(
iseq, ret);
761#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
768 int len = insn_len(insn);
769 encoded[
i] = (
VALUE)table[insn];
780 VALUE *original_code;
782 if (ISEQ_ORIGINAL_ISEQ(
iseq))
return ISEQ_ORIGINAL_ISEQ(
iseq);
786#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
791 const void *addr = (
const void *)original_code[
i];
794 original_code[
i] = insn;
799 return original_code;
812#if defined(__sparc) && SIZEOF_VOIDP == 4 && defined(__GNUC__)
813 #define STRICT_ALIGNMENT
816#ifdef STRICT_ALIGNMENT
817 #if defined(HAVE_TRUE_LONG_LONG) && SIZEOF_LONG_LONG > SIZEOF_VALUE
818 #define ALIGNMENT_SIZE SIZEOF_LONG_LONG
820 #define ALIGNMENT_SIZE SIZEOF_VALUE
822 #define PADDING_SIZE_MAX ((size_t)((ALIGNMENT_SIZE) - 1))
823 #define ALIGNMENT_SIZE_MASK PADDING_SIZE_MAX
826 #define PADDING_SIZE_MAX 0
829#ifdef STRICT_ALIGNMENT
832calc_padding(
void *
ptr,
size_t size)
839 padding = ALIGNMENT_SIZE - mis;
845#if ALIGNMENT_SIZE > SIZEOF_VALUE
860#ifdef STRICT_ALIGNMENT
861 size_t padding = calc_padding((
void *)&storage->
buff[storage->
pos],
size);
863 const size_t padding = 0;
867 if (storage->
pos +
size + padding > storage->
size) {
868 unsigned int alloc_size = storage->
size;
876 storage = *arena = storage->
next;
879 storage->
size = alloc_size;
880#ifdef STRICT_ALIGNMENT
881 padding = calc_padding((
void *)&storage->
buff[storage->
pos],
size);
885#ifdef STRICT_ALIGNMENT
886 storage->
pos += (
int)padding;
898 return compile_data_alloc_with_arena(arena,
size);
905 return compile_data_alloc(
iseq,
size);
912 return (
INSN *)compile_data_alloc_with_arena(arena,
sizeof(
INSN));
1002 anchor->last = anchor->last->
prev;
1003 anchor->last->
next = 0;
1004 verify_list(
"pop", anchor);
1008#define POP_ELEMENT(anchor) POP_ELEMENT(iseq, (anchor))
1015 switch (elem->
type) {
1016 case ISEQ_ELEMENT_INSN:
1017 case ISEQ_ELEMENT_ADJUST:
1027LIST_INSN_SIZE_ONE(
const LINK_ANCHOR *
const anchor)
1029 LINK_ELEMENT *first_insn = ELEM_FIRST_INSN(FIRST_ELEMENT(anchor));
1030 if (first_insn !=
NULL &&
1031 ELEM_FIRST_INSN(first_insn->
next) ==
NULL) {
1040LIST_INSN_SIZE_ZERO(
const LINK_ANCHOR *
const anchor)
1042 if (ELEM_FIRST_INSN(FIRST_ELEMENT(anchor)) ==
NULL) {
1063 anc1->last = anc2->
last;
1065 verify_list(
"append", anc1);
1068#define APPEND_LIST(anc1, anc2) APPEND_LIST(iseq, (anc1), (anc2))
1077 printf(
"anch: %p, frst: %p, last: %p\n", &anchor->anchor,
1078 anchor->anchor.next, anchor->last);
1080 printf(
"curr: %p, next: %p, prev: %p, type: %d\n",
list,
list->next,
1086 dump_disasm_list(anchor->anchor.next);
1087 verify_list(
"debug list", anchor);
1090#define debug_list(anc) debug_list(iseq, (anc))
1093#define debug_list(anc) ((void)0)
1099 TRACE *trace = compile_data_alloc_trace(
iseq);
1101 trace->
link.
type = ISEQ_ELEMENT_TRACE;
1103 trace->
event = event;
1112 LABEL *labelobj = compile_data_alloc_label(
iseq);
1114 labelobj->
link.
type = ISEQ_ELEMENT_LABEL;
1117 labelobj->
label_no = ISEQ_COMPILE_DATA(
iseq)->label_no++;
1130 ADJUST *adjust = compile_data_alloc_adjust(
iseq);
1131 adjust->
link.
type = ISEQ_ELEMENT_ADJUST;
1133 adjust->
label = label;
1143 INSN *iobj = compile_data_alloc_insn(
iseq);
1147 iobj->
link.
type = ISEQ_ELEMENT_INSN;
1161 VALUE *operands = 0;
1173 return new_insn_core(
iseq, line_no, insn_id,
argc, operands);
1180 struct
rb_call_info *
ci = (struct rb_call_info *)compile_data_alloc(iseq, size);
1198 kw_arg ==
NULL && !has_blockiseq) {
1209 operands[1] = (
VALUE)blockiseq;
1210 return new_insn_core(
iseq, line_no,
BIN(send), 2, operands);
1224 debugs(
"[new_child_iseq]> ---------------------------------------\n");
1228 debugs(
"[new_child_iseq]< ---------------------------------------\n");
1238 debugs(
"[new_child_iseq_with_callback]> ---------------------------------------\n");
1242 debugs(
"[new_child_iseq_with_callback]< ---------------------------------------\n");
1273 while (pos < body->iseq_size) {
1274#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
1279 if (insn ==
BIN(
throw)) {
1280 set_catch_except_p(body);
1283 pos += insn_len(insn);
1289 for (
i = 0;
i < ct->
size;
i++) {
1304 VALUE catch_table_ary = ISEQ_COMPILE_DATA(
iseq)->catch_table_ary;
1305 if (
NIL_P(catch_table_ary))
return;
1306 unsigned int i, tlen = (
unsigned int)
RARRAY_LEN(catch_table_ary);
1308 for (
i = 0;
i < tlen;
i++) {
1315 INSN *nop = new_insn_core(
iseq, 0,
BIN(nop), 0, 0);
1316 ELEM_INSERT_NEXT(
end, &nop->
link);
1326 if (
RTEST(ISEQ_COMPILE_DATA(
iseq)->err_info))
1332 dump_disasm_list(FIRST_ELEMENT(anchor));
1334 debugs(
"[compile step 3.1 (iseq_optimize)]\n");
1335 iseq_optimize(
iseq, anchor);
1338 dump_disasm_list(FIRST_ELEMENT(anchor));
1340 if (ISEQ_COMPILE_DATA(
iseq)->option->instructions_unification) {
1341 debugs(
"[compile step 3.2 (iseq_insns_unification)]\n");
1342 iseq_insns_unification(
iseq, anchor);
1344 dump_disasm_list(FIRST_ELEMENT(anchor));
1347 if (ISEQ_COMPILE_DATA(
iseq)->option->stack_caching) {
1348 debugs(
"[compile step 3.3 (iseq_set_sequence_stackcaching)]\n");
1349 iseq_set_sequence_stackcaching(
iseq, anchor);
1351 dump_disasm_list(FIRST_ELEMENT(anchor));
1354 debugs(
"[compile step 3.4 (iseq_insert_nop_between_end_and_cont)]\n");
1355 iseq_insert_nop_between_end_and_cont(
iseq);
1363 if (
RTEST(ISEQ_COMPILE_DATA(
iseq)->err_info))
1366 debugs(
"[compile step 4.1 (iseq_set_sequence)]\n");
1369 dump_disasm_list(FIRST_ELEMENT(anchor));
1371 debugs(
"[compile step 4.2 (iseq_set_exception_table)]\n");
1374 debugs(
"[compile step 4.3 (set_optargs_table)] \n");
1377 debugs(
"[compile step 5 (iseq_translate_threaded_code)] \n");
1380 update_catch_except_flags(
iseq->
body);
1386 verify_call_cache(
iseq);
1387 debugs(
"[compile step: finish]\n");
1431 "get_local_var_idx: %d", idx);
1440 int lv = 0, idx = -1;
1444 idx = get_dyna_var_idx_at_raw(
iseq,
id);
1454 "get_dyna_var_idx: -1");
1463iseq_local_block_param_p(
const rb_iseq_t *
iseq,
unsigned int idx,
unsigned int level)
1482iseq_block_param_id_p(
const rb_iseq_t *
iseq,
ID id,
int *pidx,
int *plevel)
1485 int idx = get_dyna_var_idx(
iseq,
id, &level, &ls);
1486 if (iseq_local_block_param_p(
iseq, ls - idx, level)) {
1499 if (iseq_local_block_param_p(
iseq, idx, level)) {
1510 if (iseq_local_block_param_p(
iseq, idx, level)) {
1564 struct rb_iseq_param_keyword *keyword;
1567 int kw = 0, rkw = 0, di = 0,
i;
1574 node = node->nd_next;
1577 keyword->bits_start = arg_size++;
1581 const NODE *val_node = node->nd_body->nd_value;
1590 dv = val_node->nd_lit;
1606 keyword->num = ++di;
1610 node = node->nd_next;
1616 keyword->rest_start = arg_size++;
1619 keyword->required_num = rkw;
1620 keyword->table = &body->
local_table[keyword->bits_start - keyword->num];
1627 if (dv == complex_mark) dv =
Qundef;
1634 keyword->default_values = dvs;
1642 debugs(
"iseq_set_arguments: %s\n", node_args ?
"" :
"0");
1678 node = node->nd_next;
1690 for (j = 0; j <
i+1; j++) {
1719 arg_size = iseq_set_arguments_keywords(
iseq, optargs, args, arg_size);
1722 struct rb_iseq_param_keyword *keyword =
ZALLOC_N(
struct rb_iseq_param_keyword, 1);
1723 keyword->rest_start = arg_size++;
1736 iseq_calc_param_size(
iseq);
1746 if (body->
type == ISEQ_TYPE_BLOCK) {
1802 else if (tlit != tval) {
1878 ISEQ_COMPILE_DATA(
iseq)->ivar_cache_table = tbl;
1885#define BADINSN_DUMP(anchor, list, dest) \
1886 dump_disasm_list_with_cursor(FIRST_ELEMENT(anchor), list, dest)
1888#define BADINSN_ERROR \
1889 (xfree(generated_iseq), \
1890 xfree(insns_info), \
1891 BADINSN_DUMP(anchor, list, NULL), \
1897 int stack_max = 0, sp = 0, line = 0;
1901 if (
list->type == ISEQ_ELEMENT_LABEL) {
1908 switch (
list->type) {
1909 case ISEQ_ELEMENT_INSN:
1917 sp = calc_sp_depth(sp, iobj);
1921 "argument stack underflow (%d)", sp);
1924 if (sp > stack_max) {
1932 types = insn_op_types(insn);
1933 len = insn_len(insn);
1940 "operand size miss! (%d for %d)",
1945 for (j = 0;
types[j]; j++) {
1946 if (
types[j] == TS_OFFSET) {
1955 if (lobj->
sp == -1) {
1962 case ISEQ_ELEMENT_LABEL:
1965 if (lobj->
sp == -1) {
1973 case ISEQ_ELEMENT_TRACE:
1978 case ISEQ_ELEMENT_ADJUST:
1984 if (adjust->
line_no != -1 && orig_sp - sp < 0) {
1987 "iseq_set_sequence: adjust bug %d < %d",
2004 int insns_info_index,
int code_index,
const INSN *iobj)
2006 if (insns_info_index == 0 ||
2011 positions[insns_info_index] = code_index;
2019 int insns_info_index,
int code_index,
const ADJUST *adjust)
2021 if (insns_info_index > 0 ||
2022 insns_info[insns_info_index-1].line_no != adjust->
line_no) {
2024 insns_info[insns_info_index].
events = 0;
2025 positions[insns_info_index] = code_index;
2039 unsigned int *positions;
2041 VALUE *generated_iseq;
2045 int insn_num, code_index, insns_info_index, sp = 0;
2051 insn_num = code_index = 0;
2053 switch (
list->type) {
2054 case ISEQ_ELEMENT_INSN:
2058 sp = calc_sp_depth(sp, iobj);
2076 code_index += insn_data_length(iobj);
2081 case ISEQ_ELEMENT_LABEL:
2088 case ISEQ_ELEMENT_TRACE:
2091 events |= trace->
event;
2095 case ISEQ_ELEMENT_ADJUST:
2101 if (orig_sp - sp > 0) {
2102 if (orig_sp - sp > 1) code_index++;
2116 positions =
ALLOC_N(
unsigned int, insn_num);
2122 ISEQ_COMPILE_DATA(
iseq)->ci_index = ISEQ_COMPILE_DATA(
iseq)->ci_kw_index = 0;
2124 list = FIRST_ELEMENT(anchor);
2125 insns_info_index = code_index = sp = 0;
2128 switch (
list->type) {
2129 case ISEQ_ELEMENT_INSN:
2137 sp = calc_sp_depth(sp, iobj);
2141 generated_iseq[code_index] = insn;
2142 types = insn_op_types(insn);
2143 len = insn_len(insn);
2145 for (j = 0;
types[j]; j++) {
2153 generated_iseq[code_index + 1 + j] = lobj->
position - (code_index +
len);
2158 VALUE map = operands[j];
2161 data.pos = code_index;
2166 freeze_hide_obj(map);
2167 generated_iseq[code_index + 1 + j] = map;
2174 generated_iseq[code_index + 1 + j] =
FIX2INT(operands[j]);
2180 generated_iseq[code_index + 1 + j] =
v;
2195 unsigned int ic_index =
FIX2UINT(operands[j]);
2200 "iseq_set_sequence: ic_index overflow: index: %d, size: %d",
2203 generated_iseq[code_index + 1 + j] = (
VALUE)ic;
2216 assert(ISEQ_COMPILE_DATA(
iseq)->ci_kw_index <= body->ci_kw_size);
2220 cd->
ci = *source_ci;
2221 assert(ISEQ_COMPILE_DATA(
iseq)->ci_index <= body->ci_size);
2224 generated_iseq[code_index + 1 + j] = (
VALUE)cd;
2228 generated_iseq[code_index + 1 + j] =
SYM2ID(operands[j]);
2234 generated_iseq[code_index + 1 + j] = (
VALUE)entry;
2238 generated_iseq[code_index + 1 + j] = operands[j];
2241 generated_iseq[code_index + 1 + j] = operands[j];
2245 "unknown operand type: %c",
type);
2249 if (add_insn_info(insns_info, positions, insns_info_index, code_index, iobj)) insns_info_index++;
2253 case ISEQ_ELEMENT_LABEL:
2259 case ISEQ_ELEMENT_ADJUST:
2264 if (adjust->
label) {
2272 const int diff = orig_sp - sp;
2274 if (add_adjust_info(insns_info, positions, insns_info_index, code_index, adjust)) insns_info_index++;
2277 generated_iseq[code_index++] =
BIN(adjuststack);
2278 generated_iseq[code_index++] = orig_sp - sp;
2280 else if (diff == 1) {
2281 generated_iseq[code_index++] =
BIN(pop);
2283 else if (diff < 0) {
2285 xfree(generated_iseq);
2290 "iseq_set_sequence: adjust bug to %d %d < %d",
2291 label_no, orig_sp, sp);
2314 REALLOC_N(positions,
unsigned int, insns_info_index);
2322label_get_position(
LABEL *lobj)
2328label_get_sp(
LABEL *lobj)
2337 unsigned int tlen,
i;
2340 if (
NIL_P(ISEQ_COMPILE_DATA(
iseq)->catch_table_ary))
goto no_catch_table;
2348 for (
i = 0;
i < table->
size;
i++) {
2351 entry->
type = (
enum catch_type)(
ptr[0] & 0xffff);
2353 entry->
end = label_get_position((
LABEL *)(
ptr[2] & ~1));
2360 entry->
cont = label_get_position(lobj);
2361 entry->
sp = label_get_sp(lobj);
2364 if (entry->
type == CATCH_TYPE_RESCUE ||
2365 entry->
type == CATCH_TYPE_BREAK ||
2366 entry->
type == CATCH_TYPE_NEXT) {
2402 opt_table[
i] = label_get_position((
LABEL *)opt_table[
i]);
2409get_destination_insn(
INSN *iobj)
2417 switch (
list->type) {
2418 case ISEQ_ELEMENT_INSN:
2419 case ISEQ_ELEMENT_ADJUST:
2421 case ISEQ_ELEMENT_LABEL:
2424 case ISEQ_ELEMENT_TRACE:
2427 events |= trace->
event;
2443get_next_insn(
INSN *iobj)
2457get_prev_insn(
INSN *iobj)
2471unref_destination(
INSN *iobj,
int pos)
2479replace_destination(
INSN *dobj,
INSN *nobj)
2491find_destination(
INSN *
i)
2493 int pos,
len = insn_len(
i->insn_id);
2494 for (pos = 0; pos <
len; ++pos) {
2495 if (insn_op_types(
i->insn_id)[pos] == TS_OFFSET) {
2506 int *unref_counts = 0, nlabels = ISEQ_COMPILE_DATA(
iseq)->label_no;
2509 unref_counts =
ALLOCA_N(
int, nlabels);
2510 MEMZERO(unref_counts,
int, nlabels);
2519 else if ((lab = find_destination((
INSN *)
i)) != 0) {
2528 if (
i == first)
return 0;
2541 }
while ((
i =
i->next) != 0);
2547 int pos,
len = insn_len(insn);
2548 for (pos = 0; pos <
len; ++pos) {
2549 switch (insn_op_types(insn)[pos]) {
2551 unref_destination((
INSN *)
i, pos);
2563 }
while ((
i != end) && (
i =
i->next) != 0);
2572 ELEM_REMOVE(&iobj->
link);
2575 ELEM_REMOVE(&iobj->
link);
2588 if (debug1 == debug2)
return TRUE;
2599is_frozen_putstring(
INSN *insn,
VALUE *op)
2637 INSN *niobj, *ciobj, *
dup = 0;
2642 case BIN(putstring):
2648 case BIN(putobject):
2651 default:
return FALSE;
2654 ciobj = (
INSN *)get_next_insn(iobj);
2659 ciobj = (
INSN *)get_next_insn(
dup = ciobj);
2662 niobj = (
INSN *)get_next_insn(ciobj);
2674 case BIN(branchunless):
2689 ELEM_INSERT_NEXT(&niobj->
link, &dest->
link);
2704 optimize_checktype(
iseq, iobj);
2707 INSN *niobj, *diobj, *piobj;
2708 diobj = (
INSN *)get_destination_insn(iobj);
2709 niobj = (
INSN *)get_next_insn(iobj);
2711 if (diobj == niobj) {
2718 unref_destination(iobj, 0);
2719 ELEM_REMOVE(&iobj->
link);
2722 else if (iobj != diobj &&
IS_INSN(&diobj->
link) &&
2735 replace_destination(iobj, diobj);
2752 unref_destination(iobj, 0);
2762 INSN *pdiobj = (
INSN *)get_destination_insn(piobj);
2763 if (niobj == pdiobj) {
2781 ?
BIN(branchunless) :
BIN(branchif);
2782 replace_destination(piobj, iobj);
2784 ELEM_REMOVE(&iobj->
link);
2791 else if (diobj == pdiobj) {
2807 ELEM_REPLACE(&piobj->
link, &popiobj->
link);
2827 VALUE str_beg, str_end;
2830 (end = (
INSN *)get_prev_insn(
range)) != 0 &&
2831 is_frozen_putstring(end, &str_end) &&
2832 (beg = (
INSN *)get_prev_insn(end)) != 0 &&
2833 is_frozen_putstring(beg, &str_beg)) {
2837 ELEM_REMOVE(&beg->
link);
2838 ELEM_REMOVE(&end->
link);
2860 INSN *nobj = (
INSN *)get_destination_insn(iobj);
2882 int stop_optimization =
2885 if (!stop_optimization) {
2897 replace_destination(iobj, nobj);
2918 replace_destination(iobj, nobj);
2965 if (prev_dup || !
IS_INSN_ID(pobj, newarray)) {
2968 else if (!iseq_pop_newarray(
iseq, pobj)) {
2970 ELEM_INSERT_PREV(&iobj->
link, &pobj->
link);
2975 ELEM_INSERT_NEXT(&iobj->
link, &pobj->
link);
2981 unref_destination(iobj, 0);
2982 ELEM_REMOVE(&iobj->
link);
2987 nobj = (
INSN *)get_destination_insn(nobj);
3002 if (previ ==
BIN(putobject) || previ ==
BIN(putnil) ||
3003 previ ==
BIN(putself) || previ ==
BIN(putstring) ||
3005 previ ==
BIN(getlocal) ||
3006 previ ==
BIN(getblockparam) ||
3007 previ ==
BIN(getblockparamproxy) ||
3009 previ ==
BIN(duparray)) {
3013 ELEM_REMOVE(&iobj->
link);
3015 else if (previ ==
BIN(newarray) && iseq_pop_newarray(
iseq, (
INSN*)prev)) {
3016 ELEM_REMOVE(&iobj->
link);
3018 else if (previ ==
BIN(concatarray)) {
3023 else if (previ ==
BIN(concatstrings)) {
3028 ELEM_REMOVE(&iobj->
link);
3081 ELEM_REMOVE(&next->
link);
3083 ELEM_REMOVE(&iobj->
link);
3097 next = (freeze = next)->next;
3099 next = get_destination_insn(jump = (
INSN *)next);
3106 ELEM_REMOVE(&label->
link);
3114 if (same_debug_pos_p(freeze, next->
next)) {
3115 ELEM_REMOVE(freeze);
3121 ELEM_INSERT_NEXT(next, &label->
link);
3122 CHECK(iseq_peephole_optimize(
iseq, get_next_insn(jump), do_tailcallopt));
3125 if (freeze) ELEM_REMOVE(freeze);
3144 ci->orig_argc == 0) {
3150 if (do_tailcallopt &&
3179 next = get_destination_insn((
INSN *)next);
3212 ELEM_REMOVE(&iobj->
link);
3220 ELEM_REMOVE(set1->
next);
3230 niobj = niobj->
next;
3242 if (
IS_INSN_ID(iobj, opt_invokebuiltin_delegate)) {
3245 iobj->
insn_id =
BIN(opt_invokebuiltin_delegate_leave);
3259 if (insn_id ==
BIN(opt_neq)) {
3264 iobj->
operands[1] = old_operands[0];
3285 ELEM_REMOVE(&niobj->
link);
3289 ELEM_REMOVE(&niobj->
link);
3300#define SP_INSN(opt) insn_set_specialized_instruction(iseq, iobj, BIN(opt_##opt))
3302 switch (
ci->orig_argc) {
3356 case ISEQ_TYPE_EVAL:
3357 case ISEQ_TYPE_MAIN:
3359 case ISEQ_TYPE_RESCUE:
3360 case ISEQ_TYPE_ENSURE:
3372 const int do_peepholeopt = ISEQ_COMPILE_DATA(
iseq)->option->peephole_optimization;
3373 const int do_tailcallopt = tailcallable_p(
iseq) &&
3374 ISEQ_COMPILE_DATA(
iseq)->option->tailcall_optimization;
3375 const int do_si = ISEQ_COMPILE_DATA(
iseq)->option->specialized_instruction;
3376 const int do_ou = ISEQ_COMPILE_DATA(
iseq)->option->operands_unification;
3377 int rescue_level = 0;
3378 int tailcallopt = do_tailcallopt;
3380 list = FIRST_ELEMENT(anchor);
3384 if (do_peepholeopt) {
3385 iseq_peephole_optimize(
iseq,
list, tailcallopt);
3391 insn_operands_unification((
INSN *)
list);
3398 tailcallopt =
FALSE;
3401 if (!--rescue_level) tailcallopt = do_tailcallopt;
3410#if OPT_INSTRUCTIONS_UNIFICATION
3454#if OPT_INSTRUCTIONS_UNIFICATION
3460 list = FIRST_ELEMENT(anchor);
3465 if (unified_insns_data[
id] != 0) {
3466 const int *
const *entry = unified_insns_data[
id];
3467 for (j = 1; j < (
intptr_t)entry[0]; j++) {
3468 const int *unified = entry[j];
3470 for (k = 2; k < unified[1]; k++) {
3472 ((
INSN *)li)->insn_id != unified[k]) {
3479 new_unified_insn(
iseq, unified[0], unified[1] - 1,
3502#if OPT_STACK_CACHING
3504#define SC_INSN(insn, stat) sc_insn_info[(insn)][(stat)]
3505#define SC_NEXT(insn) sc_insn_next[(insn)]
3507#include "opt_sc.inc"
3516 iobj->
insn_id = SC_INSN(insn_id, state);
3517 nstate = SC_NEXT(iobj->
insn_id);
3519 if (insn_id ==
BIN(jump) ||
3520 insn_id ==
BIN(branchif) || insn_id ==
BIN(branchunless)) {
3536 if (insn_id ==
BIN(jump)) {
3540 else if (insn_id ==
BIN(leave)) {
3548label_set_sc_state(
LABEL *lobj,
int state)
3568#if OPT_STACK_CACHING
3574 list = FIRST_ELEMENT(anchor);
3580 switch (
list->type) {
3581 case ISEQ_ELEMENT_INSN:
3592 if (state != SCS_AX) {
3594 new_insn_body(
iseq, 0,
BIN(reput), 0);
3605 if (state == SCS_AB || state == SCS_BA) {
3606 state = (state == SCS_AB ? SCS_BA : SCS_AB);
3643 state = insn_set_sc_state(
iseq, anchor, iobj, state);
3646 case ISEQ_ELEMENT_LABEL:
3651 state = label_set_sc_state(lobj, state);
3663all_string_result_p(
const NODE *node)
3665 if (!node)
return FALSE;
3670 if (!node->nd_body || !node->nd_else)
return FALSE;
3671 if (all_string_result_p(node->nd_body))
3672 return all_string_result_p(node->nd_else);
3676 return all_string_result_p(node->nd_1st);
3677 if (!all_string_result_p(node->nd_1st))
3679 return all_string_result_p(node->nd_2nd);
3689 VALUE lit = node->nd_lit;
3704 if (
RSTRING_LEN(lit) == 0) first_lit = LAST_ELEMENT(ret);
3708 const NODE *
const head =
list->nd_head;
3721 if (
NIL_P(lit) && first_lit) {
3722 ELEM_REMOVE(first_lit);
3752 const int line =
nd_line(node);
3763 ADD_INSNL(ret, line, branchunless, else_label);
3773 ADD_INSNL(ret, line, branchunless, then_label);
3790 CHECK(compile_branch_condition(
iseq, ret, cond->nd_1st, label,
3792 if (!label->
refcnt)
break;
3794 cond = cond->nd_2nd;
3800 CHECK(compile_branch_condition(
iseq, ret, cond->nd_1st, then_label,
3802 if (!label->
refcnt)
break;
3804 cond = cond->nd_2nd;
3828 CHECK(compile_flip_flop(
iseq, ret, cond,
TRUE, then_label, else_label));
3831 CHECK(compile_flip_flop(
iseq, ret, cond,
FALSE, then_label, else_label));
3847keyword_node_p(
const NODE *
const node)
3854 const NODE *
const root_node,
3860 if (keyword_node_p(root_node) && root_node->nd_head &&
nd_type(root_node->nd_head) ==
NODE_LIST) {
3861 const NODE *node = root_node->nd_head;
3864 const NODE *key_node = node->nd_head;
3878 node = node->nd_next;
3879 node = node->nd_next;
3883 node = root_node->nd_head;
3885 int len = (
int)node->nd_alen / 2;
3892 *kw_arg_ptr = kw_arg;
3894 for (
i=0; node !=
NULL;
i++, node = node->nd_next->nd_next) {
3895 const NODE *key_node = node->nd_head;
3896 const NODE *val_node = node->nd_next->nd_head;
3913 for (; node;
len++, node = node->nd_next) {
3918 if (node->nd_next ==
NULL &&
3919 compile_keyword_arg(
iseq, ret, node->nd_head, keywords_ptr, flag)) {
3933 node = node->nd_head;
3941 return ISEQ_COMPILE_DATA(
iseq)->option->frozen_string_literal;
3950 node = node->nd_head;
3970 return node->nd_lit;
3989 for (; node; node = node->nd_next) {
4032 const int max_stack_len = 0x100;
4033 const int min_tmp_ary_len = 0x40;
4035 int first_chunk = 1;
4038#define FLUSH_CHUNK(newarrayinsn) \
4040 ADD_INSN1(ret, line, newarrayinsn, INT2FIX(stack_len)); \
4041 if (!first_chunk) ADD_INSN(ret, line, concatarray); \
4042 first_chunk = stack_len = 0; \
4049 if (static_literal_node_p(node,
iseq)) {
4051 const NODE *node_tmp = node->nd_next;
4052 for (; node_tmp && static_literal_node_p(node_tmp,
iseq); node_tmp = node_tmp->nd_next)
4055 if ((first_chunk && stack_len == 0 && !node_tmp) ||
count >= min_tmp_ary_len) {
4079 for (;
count;
count--, node = node->nd_next) {
4087 if (!node->nd_next && keyword_node_p(node->nd_head)) {
4094 if (stack_len >= max_stack_len)
FLUSH_CHUNK(newarray);
4106 return node->nd_head && static_literal_node_p(node,
iseq) && static_literal_node_p(node->nd_next,
iseq);
4114 node = node->nd_head;
4126 for (; node; node = node->nd_next) {
4150 const int max_stack_len = 0x100;
4151 const int min_tmp_hash_len = 0x800;
4153 int first_chunk = 1;
4158#define FLUSH_CHUNK() \
4160 if (first_chunk) { \
4161 APPEND_LIST(ret, anchor); \
4162 ADD_INSN1(ret, line, newhash, INT2FIX(stack_len)); \
4165 ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); \
4166 ADD_INSN(ret, line, swap); \
4167 APPEND_LIST(ret, anchor); \
4168 ADD_SEND(ret, line, id_core_hash_merge_ptr, INT2FIX(stack_len + 1)); \
4170 INIT_ANCHOR(anchor); \
4171 first_chunk = stack_len = 0; \
4178 if (static_literal_node_pair_p(node,
iseq)) {
4180 const NODE *node_tmp = node->nd_next->nd_next;
4181 for (; node_tmp && static_literal_node_pair_p(node_tmp,
iseq); node_tmp = node_tmp->nd_next->nd_next)
4184 if ((first_chunk && stack_len == 0 && !node_tmp) ||
count >= min_tmp_hash_len) {
4189 for (;
count;
count--, node = node->nd_next->nd_next) {
4191 elem[0] = static_literal_value(node,
iseq);
4192 elem[1] = static_literal_value(node->nd_next,
iseq);
4219 for (;
count;
count--, node = node->nd_next->nd_next) {
4225 if (node->nd_head) {
4228 NO_CHECK(
COMPILE_(anchor,
"hash value element", node->nd_next->nd_head, 0));
4238 const NODE *kw = node->nd_next->nd_head;
4240 int first_kw = first_chunk && stack_len == 0;
4241 int last_kw = !node->nd_next->nd_next;
4242 int only_kw = last_kw && first_kw;
4252 else if (first_kw) {
4313 LABEL *l1,
int only_special_literals,
VALUE literals)
4316 const NODE *val = vals->nd_head;
4320 only_special_literals = 0;
4335 if (!
COMPILE(cond_seq,
"when cond", val))
return -1;
4340 vals = vals->nd_next;
4342 return only_special_literals;
4347 LABEL *l1,
int only_special_literals,
VALUE literals)
4349 const int line =
nd_line(vals);
4353 if (when_vals(
iseq, cond_seq, vals, l1, only_special_literals, literals) < 0)
4361 ADD_INSNL(cond_seq, line, branchif, l1);
4364 CHECK(when_splat_vals(
iseq, cond_seq, vals->nd_head, l1, only_special_literals, literals));
4365 CHECK(when_splat_vals(
iseq, cond_seq, vals->nd_body, l1, only_special_literals, literals));
4368 CHECK(when_splat_vals(
iseq, cond_seq, vals->nd_head, l1, only_special_literals, literals));
4370 CHECK(
COMPILE(cond_seq,
"when argspush body", vals->nd_body));
4372 ADD_INSNL(cond_seq, line, branchif, l1);
4379 ADD_INSNL(cond_seq, line, branchif, l1);
4398 iobj = (
INSN *)get_prev_insn((
INSN *)LAST_ELEMENT(ret));
4416 ELEM_REMOVE(FIRST_ELEMENT(anchor));
4424 ELEM_REMOVE(FIRST_ELEMENT(anchor));
4436 CHECK(compile_massign_opt_lhs(
iseq, ret, lhsn->nd_next));
4437 CHECK(compile_massign_lhs(
iseq, ret, lhsn->nd_head));
4444 const NODE *rhsn,
const NODE *orig_lhsn)
4449 int llen = 0, rlen = 0;
4451 const NODE *lhsn = orig_lhsn;
4453#define MEMORY(v) { \
4455 if (memindex == memsize) return 0; \
4456 for (i=0; i<memindex; i++) { \
4457 if (mem[i] == (v)) return 0; \
4459 mem[memindex++] = (v); \
4467 const NODE *ln = lhsn->nd_head;
4481 lhsn = lhsn->nd_next;
4492 rhsn = rhsn->nd_next;
4497 for (
i=0;
i<llen-rlen;
i++) {
4502 compile_massign_opt_lhs(
iseq, ret, orig_lhsn);
4510 do {
ADD_INSN(ret, line, putnil);}
while (++rlen < llen);
4512 else if (rlen > llen) {
4513 do {
ADD_INSN(ret, line, pop);}
while (--rlen > llen);
4520 const NODE *rhsn = node->nd_value;
4521 const NODE *splatn = node->nd_args;
4522 const NODE *lhsn = node->nd_head;
4525 if (!popped || splatn || !compile_massign_opt(
iseq, ret, rhsn, lhsn)) {
4533 CHECK(compile_massign_lhs(
iseq, lhsseq, lhsn->nd_head));
4535 lhsn = lhsn->nd_next;
4543 else if (!lhs_splat) {
4547 last->operand_size == 1) {
4552 adjust_stack(
iseq, ret,
nd_line(node), rlen, llen);
4556 else if (llen > 2 && llen != rlen) {
4558 adjust_stack(
iseq, ret,
nd_line(node), rlen, llen);
4562 else if (llen > 2) {
4577 const NODE *postn = splatn->nd_2nd;
4578 const NODE *restn = splatn->nd_1st;
4579 int num = (
int)postn->nd_alen;
4586 CHECK(compile_massign_lhs(
iseq, ret, restn));
4589 CHECK(compile_massign_lhs(
iseq, ret, postn->nd_head));
4590 postn = postn->nd_next;
4595 CHECK(compile_massign_lhs(
iseq, ret, splatn));
4608 debugi(
"compile_const_prefix - colon", node->nd_vid);
4613 debugi(
"compile_const_prefix - colon3", node->nd_mid);
4620 CHECK(compile_const_prefix(
iseq, node->nd_head, pref, body));
4621 debugi(
"compile_const_prefix - colon2", node->nd_mid);
4640 else if (cpath->nd_head) {
4654private_recv_p(
const NODE *node)
4657 NODE *
self = node->nd_recv;
4658 return self->nd_state != 0;
4673 const int line =
nd_line(node);
4692 const NODE *vals = node;
4695 defined_expr0(
iseq, ret, vals->nd_head, lfinish,
Qfalse);
4700 ADD_INSNL(ret, line, branchunless, lfinish[1]);
4701 }
while ((vals = vals->nd_next) !=
NULL);
4722 ID2SYM(node->nd_vid), needstr);
4728 ID2SYM(node->nd_entry->
id), needstr);
4734 ID2SYM(node->nd_vid), needstr);
4740 ID2SYM(node->nd_vid), needstr);
4746 defined_expr0(
iseq, ret, node->nd_head, lfinish,
Qfalse);
4747 ADD_INSNL(ret, line, branchunless, lfinish[1]);
4753 ID2SYM(node->nd_mid), needstr);
4767 const int explicit_receiver =
4771 if (!lfinish[1] && (node->nd_args || explicit_receiver)) {
4774 if (node->nd_args) {
4775 defined_expr0(
iseq, ret, node->nd_args, lfinish,
Qfalse);
4776 ADD_INSNL(ret, line, branchunless, lfinish[1]);
4778 if (explicit_receiver) {
4779 defined_expr0(
iseq, ret, node->nd_recv, lfinish,
Qfalse);
4780 ADD_INSNL(ret, line, branchunless, lfinish[1]);
4783 ID2SYM(node->nd_mid), needstr);
4788 ID2SYM(node->nd_mid), needstr);
4845 iseq_set_exception_local_table(
iseq);
4853 defined_expr0(
iseq, ret, node, lfinish, needstr);
4860 rb_iseq_new_with_callback_new_callback(build_defined_rescue_iseq,
NULL);
4861 rescue = new_child_iseq_with_callback(
iseq, ifunc,
4864 iseq, ISEQ_TYPE_RESCUE, 0);
4876 const int line =
nd_line(node);
4877 if (!node->nd_head) {
4886 defined_expr(
iseq, ret, node->nd_head, lfinish, needstr);
4888 ELEM_INSERT_NEXT(
last, &new_insn_body(
iseq, line,
BIN(putnil), 0)->
link);
4899make_name_for_block(
const rb_iseq_t *orig_iseq)
4927 enl->
prev = ISEQ_COMPILE_DATA(
iseq)->ensure_node_stack;
4929 ISEQ_COMPILE_DATA(
iseq)->ensure_node_stack = enl;
4939 while (erange->
next != 0) {
4940 erange = erange->
next;
4944 ne->end = erange->
end;
4945 erange->
end = lstart;
4954 ISEQ_COMPILE_DATA(
iseq)->ensure_node_stack;
4966 add_ensure_range(
iseq, enlp->
erange, lstart, lend);
4968 ISEQ_COMPILE_DATA(
iseq)->ensure_node_stack = enlp->
prev;
4981 ISEQ_COMPILE_DATA(
iseq)->ensure_node_stack = prev_enlp;
4986check_keyword(
const NODE *node)
4991 while (node->nd_next) {
4992 node = node->nd_next;
4994 node = node->nd_head;
4997 return keyword_node_p(node);
5018 int rest_len = compile_args(
iseq, args, argn->nd_body,
NULL,
NULL);
5028 if (check_keyword(argn->nd_body))
5049 int len = compile_args(
iseq, args, argn, keywords, flag);
5071 ret = setup_args_core(
iseq, args, argn->nd_head, 0, flag, keywords);
5073 if (LIST_INSN_SIZE_ONE(arg_block)) {
5075 if (elem->
type == ISEQ_ELEMENT_INSN) {
5085 ret = setup_args_core(
iseq, args, argn, 0, flag, keywords);
5101 iseq_set_local_table(
iseq, 0);
5112#if !(defined(NAMED_CAPTURE_BY_SVAR) && NAMED_CAPTURE_BY_SVAR-0)
5118 ADD_INSNL(ret, line, branchunless, fail_label);
5122 if (
vars->nd_next) {
5131#if !defined(NAMED_CAPTURE_SINGLE_OPT) || NAMED_CAPTURE_SINGLE_OPT-0
5132 if (!
vars->nd_next &&
vars == node) {
5164number_literal_p(
const NODE *
n)
5173 const NODE *
const node_body =
type ==
NODE_IF ? node->nd_body : node->nd_else;
5174 const NODE *
const node_else =
type ==
NODE_IF ? node->nd_else : node->nd_body;
5176 const int line =
nd_line(node);
5184 LABEL *then_label, *else_label, *end_label;
5197 compile_branch_condition(
iseq, cond_seq, node->nd_cond,
5198 then_label, else_label);
5204 if (!then_label->
refcnt) {
5217 if (!else_label->
refcnt) {
5232 if (then_label->
refcnt) {
5234 if (else_label->
refcnt) {
5244 ADD_INSNL(then_seq, line, jump, end_label);
5252 if (else_label->
refcnt) {
5254 if (then_label->
refcnt) {
5278 const NODE *node = orig_node;
5279 LABEL *endlabel, *elselabel;
5283 int only_special_literals = 1;
5285 int line, lineno, column, last_lineno, last_column;
5299 node = node->nd_body;
5327 CHECK(
COMPILE_(body_seq,
"when body", node->nd_body, popped));
5328 ADD_INSNL(body_seq, line, jump, endlabel);
5330 vals = node->nd_head;
5334 only_special_literals = when_vals(
iseq, cond_seq, vals, l1, only_special_literals, literals);
5335 if (only_special_literals < 0)
return COMPILE_NG;
5340 only_special_literals = 0;
5341 CHECK(when_splat_vals(
iseq, cond_seq, vals, l1, only_special_literals, literals));
5351 node = node->nd_next;
5368 ADD_INSNL(cond_seq, line, jump, endlabel);
5371 debugs(
"== else (implicit)\n");
5381 if (only_special_literals && ISEQ_COMPILE_DATA(
iseq)->option->specialized_instruction) {
5383 ADD_INSN2(ret,
nd_line(orig_node), opt_case_dispatch, literals, elselabel);
5399 const NODE *node = orig_node->nd_body;
5410 const int line =
nd_line(node);
5426 ADD_INSNL(body_seq, line, jump, endlabel);
5428 vals = node->nd_head;
5436 val = vals->nd_head;
5439 CHECK(compile_branch_condition(
iseq, ret, val, l1, lnext));
5441 vals = vals->nd_next;
5455 node = node->nd_next;
5477 const int line =
nd_line(node);
5540 const int min_argc = pre_args_num + post_args_num;
5544 LABEL *match_failed, *type_error, *fin;
5555 if (node->nd_pconst) {
5559 ADD_INSNL(ret, line, branchunless, match_failed);
5565 ADD_INSNL(ret, line, branchunless, match_failed);
5571 ADD_INSNL(ret, line, branchunless, type_error);
5577 ADD_INSNL(ret, line, branchunless, match_failed);
5579 for (
i = 0;
i < pre_args_num;
i++) {
5583 iseq_compile_pattern_each(
iseq, ret, args->nd_head, in_alt_pattern);
5584 args = args->nd_next;
5585 ADD_INSNL(ret, line, branchunless, match_failed);
5599 iseq_compile_pattern_each(
iseq, ret, apinfo->
rest_arg, in_alt_pattern);
5600 ADD_INSNL(ret, line, branchunless, match_failed);
5603 if (post_args_num > 0) {
5615 for (
i = 0;
i < post_args_num;
i++) {
5623 iseq_compile_pattern_each(
iseq, ret, args->nd_head, in_alt_pattern);
5624 args = args->nd_next;
5625 ADD_INSNL(ret, line, branchunless, match_failed);
5713 LABEL *match_failed, *type_error, *fin;
5720 if (node->nd_pkwargs && !node->nd_pkwrestarg) {
5721 const NODE *kw_args = node->nd_pkwargs->nd_head;
5725 kw_args = kw_args->nd_next->nd_next;
5729 if (node->nd_pconst) {
5733 ADD_INSNL(ret, line, branchunless, match_failed);
5739 ADD_INSNL(ret, line, branchunless, match_failed);
5752 ADD_INSNL(ret, line, branchunless, type_error);
5754 if (node->nd_pkwrestarg) {
5758 if (node->nd_pkwargs) {
5762 args = node->nd_pkwargs->nd_head;
5767 for (
i = 0;
i < keys_num;
i++) {
5768 NODE *key_node = args->nd_head;
5769 NODE *value_node = args->nd_next->nd_head;
5775 key = key_node->nd_lit;
5780 ADD_INSNL(ret, line, branchunless, match_failed);
5785 iseq_compile_pattern_each(
iseq, match_values, value_node, in_alt_pattern);
5786 ADD_INSNL(match_values, line, branchunless, match_failed);
5787 args = args->nd_next->nd_next;
5795 ADD_INSNL(ret, line, branchunless, match_failed);
5798 if (node->nd_pkwrestarg) {
5802 ADD_INSNL(ret, line, branchunless, match_failed);
5806 iseq_compile_pattern_each(
iseq, ret, node->nd_pkwrestarg, in_alt_pattern);
5807 ADD_INSNL(ret, line, branchunless, match_failed);
5853 ID id = node->nd_vid;
5856 if (in_alt_pattern) {
5872 ID id = node->nd_vid;
5874 idx = get_dyna_var_idx(
iseq,
id, &lv, &ls);
5876 if (in_alt_pattern) {
5896 LABEL *match_failed, *fin;
5899 iseq_compile_pattern_each(
iseq, ret, node->nd_body, in_alt_pattern);
5900 ADD_INSNL(ret, line, branchunless, match_failed);
5903 ADD_INSNL(ret, line, branchunless, match_failed);
5906 ADD_INSNL(ret, line, branchif, match_failed);
5919 LABEL *match_failed, *fin;
5930 iseq_compile_pattern_each(
iseq, ret,
n->nd_head, in_alt_pattern);
5931 ADD_INSNL(ret, line, branchunless, match_failed);
5932 iseq_compile_pattern_each(
iseq, ret,
n->nd_next->nd_head, in_alt_pattern);
5943 LABEL *match_succeeded, *fin;
5948 iseq_compile_pattern_each(
iseq, ret, node->nd_1st,
TRUE);
5949 ADD_INSNL(ret, line, branchif, match_succeeded);
5950 iseq_compile_pattern_each(
iseq, ret, node->nd_2nd,
TRUE);
5969 const NODE *pattern;
5970 const NODE *node = orig_node;
5971 LABEL *endlabel, *elselabel;
5975 int line, lineno, column, last_lineno, last_column;
5987 node = node->nd_body;
6015 CHECK(
COMPILE_(body_seq,
"in body", node->nd_body, popped));
6016 ADD_INSNL(body_seq, line, jump, endlabel);
6018 pattern = node->nd_head;
6021 iseq_compile_pattern_each(
iseq, cond_seq, pattern,
FALSE);
6029 node = node->nd_next;
6046 ADD_INSNL(cond_seq, line, jump, endlabel);
6049 debugs(
"== else (implicit)\n");
6078 LABEL *prev_start_label = ISEQ_COMPILE_DATA(
iseq)->start_label;
6079 LABEL *prev_end_label = ISEQ_COMPILE_DATA(
iseq)->end_label;
6080 LABEL *prev_redo_label = ISEQ_COMPILE_DATA(
iseq)->redo_label;
6081 int prev_loopval_popped = ISEQ_COMPILE_DATA(
iseq)->loopval_popped;
6095 ISEQ_COMPILE_DATA(
iseq)->loopval_popped = 0;
6098 if (node->nd_state == 1) {
6110 if (tmp_label)
ADD_LABEL(ret, tmp_label);
6126 compile_branch_condition(
iseq, ret, node->nd_cond,
6127 redo_label, end_label);
6131 compile_branch_condition(
iseq, ret, node->nd_cond,
6132 end_label, redo_label);
6138 if (node->nd_state ==
Qundef) {
6158 ISEQ_COMPILE_DATA(
iseq)->redo_label);
6160 ISEQ_COMPILE_DATA(
iseq)->start_label = prev_start_label;
6161 ISEQ_COMPILE_DATA(
iseq)->end_label = prev_end_label;
6162 ISEQ_COMPILE_DATA(
iseq)->redo_label = prev_redo_label;
6163 ISEQ_COMPILE_DATA(
iseq)->loopval_popped = prev_loopval_popped;
6164 ISEQ_COMPILE_DATA(
iseq)->ensure_node_stack = ISEQ_COMPILE_DATA(
iseq)->ensure_node_stack->prev;
6171 const int line =
nd_line(node);
6172 const rb_iseq_t *prevblock = ISEQ_COMPILE_DATA(
iseq)->current_block;
6179 CHECK(
COMPILE(ret,
"iter caller (for)", node->nd_iter));
6181 ISEQ_COMPILE_DATA(
iseq)->current_block = child_iseq =
6183 ISEQ_TYPE_BLOCK, line);
6187 ISEQ_COMPILE_DATA(
iseq)->current_block = child_iseq =
6189 ISEQ_TYPE_BLOCK, line);
6198 ISEQ_COMPILE_DATA(
iseq)->current_block = prevblock;
6200 ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, retry_label, retry_end_l, child_iseq, retry_end_l);
6210 const int line =
nd_line(node);
6211 const NODE *var = node->nd_var;
6219 ADD_INSNL(ret, line, branchunless, not_single);
6227 ADD_INSNL(ret, line, branchunless, not_ary);
6238 const int line =
nd_line(node);
6239 unsigned long throw_flag = 0;
6241 if (ISEQ_COMPILE_DATA(
iseq)->redo_label != 0) {
6246 CHECK(
COMPILE_(ret,
"break val (while/until)", node->nd_stts,
6247 ISEQ_COMPILE_DATA(
iseq)->loopval_popped));
6248 add_ensure_iseq(ret,
iseq, 0);
6249 ADD_INSNL(ret, line, jump, ISEQ_COMPILE_DATA(
iseq)->end_label);
6259 CHECK(
COMPILE(ret,
"break val (block)", node->nd_stts));
6274 if (!ISEQ_COMPILE_DATA(ip)) {
6279 if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
6283 else if (ip->
body->
type == ISEQ_TYPE_BLOCK) {
6286 else if (ip->
body->
type == ISEQ_TYPE_EVAL) {
6301 const int line =
nd_line(node);
6302 unsigned long throw_flag = 0;
6304 if (ISEQ_COMPILE_DATA(
iseq)->redo_label != 0) {
6306 debugs(
"next in while loop\n");
6308 CHECK(
COMPILE(ret,
"next val/valid syntax?", node->nd_stts));
6309 add_ensure_iseq(ret,
iseq, 0);
6311 ADD_INSNL(ret, line, jump, ISEQ_COMPILE_DATA(
iseq)->start_label);
6317 else if (ISEQ_COMPILE_DATA(
iseq)->end_label) {
6319 debugs(
"next in block\n");
6323 add_ensure_iseq(ret,
iseq, 0);
6324 ADD_INSNL(ret, line, jump, ISEQ_COMPILE_DATA(
iseq)->end_label);
6341 if (!ISEQ_COMPILE_DATA(ip)) {
6347 if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
6351 else if (ip->
body->
type == ISEQ_TYPE_BLOCK) {
6354 else if (ip->
body->
type == ISEQ_TYPE_EVAL) {
6379 const int line =
nd_line(node);
6381 if (ISEQ_COMPILE_DATA(
iseq)->redo_label) {
6386 add_ensure_iseq(ret,
iseq, 0);
6387 ADD_INSNL(ret, line, jump, ISEQ_COMPILE_DATA(
iseq)->redo_label);
6398 else if (ISEQ_COMPILE_DATA(
iseq)->start_label) {
6403 add_ensure_iseq(ret,
iseq, 0);
6405 ADD_INSNL(ret, line, jump, ISEQ_COMPILE_DATA(
iseq)->start_label);
6416 if (!ISEQ_COMPILE_DATA(ip)) {
6421 if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
6424 else if (ip->
body->
type == ISEQ_TYPE_BLOCK) {
6427 else if (ip->
body->
type == ISEQ_TYPE_EVAL) {
6452 const int line =
nd_line(node);
6472 const int line =
nd_line(node);
6478 ISEQ_TYPE_RESCUE, line);
6485 if (node->nd_else) {
6505 const int line =
nd_line(node);
6506 const NODE *resq = node;
6508 LABEL *label_miss, *label_hit;
6514 narg = resq->nd_args;
6522 ADD_INSNL(ret, line, branchif, label_hit);
6523 narg = narg->nd_next;
6532 ADD_INSNL(ret, line, branchif, label_hit);
6542 ADD_INSNL(ret, line, branchif, label_hit);
6547 if (ISEQ_COMPILE_DATA(
iseq)->option->tailcall_optimization) {
6552 resq = resq->nd_head;
6560 const int line =
nd_line(node);
6564 ISEQ_TYPE_ENSURE, line);
6582 push_ensure_entry(
iseq, &enl, &er, node->nd_ensr);
6585 CHECK(
COMPILE_(ret,
"ensure head", node->nd_head, (popped | last_leave)));
6588 if (!popped && last_leave)
ADD_INSN(ret, line, putnil);
6590 if (last_leave)
ADD_INSN(ret, line, pop);
6592 erange = ISEQ_COMPILE_DATA(
iseq)->ensure_node_stack->erange;
6597 erange = erange->
next;
6601 ISEQ_COMPILE_DATA(
iseq)->ensure_node_stack = enl.prev;
6608 const int line =
nd_line(node);
6613 enum iseq_type t =
type;
6614 const NODE *retval = node->nd_stts;
6617 while (t == ISEQ_TYPE_RESCUE || t == ISEQ_TYPE_ENSURE) {
6623 case ISEQ_TYPE_MAIN:
6625 rb_warn(
"argument of top-level return is ignored");
6629 type = ISEQ_TYPE_METHOD;
6636 if (
type == ISEQ_TYPE_METHOD) {
6642 CHECK(
COMPILE(ret,
"return nd_stts (return val)", retval));
6644 if (
type == ISEQ_TYPE_METHOD) {
6645 add_ensure_iseq(ret,
iseq, 1);
6669 if (!popped && !all_string_result_p(node)) {
6670 const int line =
nd_line(node);
6692 DECL_BRANCH_BASE(br, first_lineno, first_column, last_lineno, last_column,
"&.");
6695 ADD_INSNL(recv, line, branchnil, else_label);
6704 if (!else_label)
return;
6721 node->nd_args ==
NULL &&
6722 ISEQ_COMPILE_DATA(
iseq)->current_block ==
NULL &&
6723 ISEQ_COMPILE_DATA(
iseq)->option->specialized_instruction) {
6742 if (node->nd_mid ==
idAREF && !private_recv_p(node) && node->nd_args &&
6745 ISEQ_COMPILE_DATA(
iseq)->current_block ==
NULL &&
6746 !ISEQ_COMPILE_DATA(
iseq)->option->frozen_string_literal &&
6747 ISEQ_COMPILE_DATA(
iseq)->option->specialized_instruction) {
6764 return ISEQ_COMPILE_DATA(
iseq)->builtin_function_table !=
NULL;
6772 for (
i=0; table[
i].
index != -1;
i++) {
6781iseq_builtin_function_name(
ID mid)
6784 static const char prefix[] =
"__builtin_";
6785 const size_t prefix_len =
sizeof(prefix) - 1;
6788 return &
name[prefix_len];
6804 unsigned int start=0;
6813 for (
unsigned int i=start;
i-start<
argc;
i++) {
6814 if (elem->
type == ISEQ_ELEMENT_INSN &&
6819 if (local_level == 0) {
6822 fprintf(
stderr,
"lvar:%s (%d), id:%s (%d) local_index:%d, local_size:%d\n",
6849 *pstart_index = start;
6866 ID mid = node->nd_mid;
6868 unsigned int flag = 0;
6870 const rb_iseq_t *parent_block = ISEQ_COMPILE_DATA(
iseq)->current_block;
6874 ISEQ_COMPILE_DATA(
iseq)->current_block =
NULL;
6884 CONST_ID(id_answer,
"the_answer_to_life_the_universe_and_everything");
6886 if (mid == id_bitblt) {
6890 else if (mid == id_answer) {
6904 (mid == goto_id || mid == label_id)) {
6907 st_table *labels_table = ISEQ_COMPILE_DATA(
iseq)->labels_table;
6910 if (!labels_table) {
6912 ISEQ_COMPILE_DATA(
iseq)->labels_table = labels_table;
6915 SYMBOL_P(node->nd_args->nd_head->nd_lit)) {
6917 label_name = node->nd_args->nd_head->nd_lit;
6924 label = (
LABEL *)data;
6932 if (mid == goto_id) {
6942 const char *builtin_func;
6943 NODE *args_node = node->nd_args;
6946 (builtin_func = iseq_builtin_function_name(mid)) !=
NULL) {
6948 if (parent_block !=
NULL) {
6953 char inline_func[0x20];
6954 bool cconst =
false;
6959 if (
strcmp(
"cstmt!", builtin_func) == 0 ||
6960 strcmp(
"cexpr!", builtin_func) == 0) {
6962 int inline_index =
GET_VM()->builtin_inline_index++;
6963 snprintf(inline_func, 0x20,
"_bi%d", inline_index);
6964 builtin_func = inline_func;
6968 else if (
strcmp(
"cconst!", builtin_func) == 0) {
6972 else if (
strcmp(
"cinit!", builtin_func) == 0) {
6974 GET_VM()->builtin_inline_index++;
6979 rb_bug(
"can't find builtin function:%s", builtin_func);
6988 typedef VALUE(*builtin_func0)(
void *,
VALUE);
6990 ADD_INSN1(ret, line, putobject, const_val);
6996 argc = setup_args(
iseq, args, args_node, &flag, &keywords);
7004 unsigned int start_index;
7006 ADD_INSN2(ret, line, opt_invokebuiltin_delegate, bf,
INT2FIX(start_index));
7013 if (popped)
ADD_INSN(ret, line, pop);
7025 iseq_block_param_id_p(
iseq, node->nd_recv->nd_vid, &idx, &level)) {
7028 else if (private_recv_p(node)) {
7037 else_label = qcall_branch_start(
iseq, recv, &branches, node, line);
7046 argc = setup_args(
iseq, args, node->nd_args, &flag, &keywords);
7059 switch ((
int)
type) {
7069 qcall_branch_end(
iseq, ret, else_label, branches, node, line);
7090 int lineno = ISEQ_COMPILE_DATA(
iseq)->last_line;
7092 debugs(
"node: NODE_NIL(implicit)\n");
7097 return iseq_compile_each0(
iseq, ret, node, popped);
7106 case ISEQ_TYPE_MAIN:
7108 case ISEQ_TYPE_CLASS:
7112 "`yield' in class syntax will not be supported from Ruby 3.0. [Feature #15575]");
7127 if (ISEQ_COMPILE_DATA(
iseq)->last_line == line) {
7133 ISEQ_COMPILE_DATA(
iseq)->last_line = line;
7143#define BEFORE_RETURN debug_node_end()
7149 (node->nd_next ? 1 : popped)));
7150 node = node->nd_next;
7162 CHECK(compile_case(
iseq, ret, node, popped));
7165 CHECK(compile_case2(
iseq, ret, node, popped));
7168 CHECK(compile_case3(
iseq, ret, node, popped));
7176 CHECK(compile_iter(
iseq, ret, node, popped));
7179 CHECK(compile_for_masgn(
iseq, ret, node, popped));
7182 CHECK(compile_break(
iseq, ret, node, popped));
7185 CHECK(compile_next(
iseq, ret, node, popped));
7188 CHECK(compile_redo(
iseq, ret, node, popped));
7191 CHECK(compile_retry(
iseq, ret, node, popped));
7198 CHECK(compile_rescue(
iseq, ret, node, popped));
7201 CHECK(compile_resbody(
iseq, ret, node, popped));
7204 CHECK(compile_ensure(
iseq, ret, node, popped));
7215 ADD_INSNL(ret, line, branchunless, end_label);
7218 ADD_INSNL(ret, line, branchif, end_label);
7229 compile_massign(
iseq, ret, node, popped);
7234 ID id = node->nd_vid;
7249 ID id = node->nd_vid;
7257 idx = get_dyna_var_idx(
iseq,
id, &lv, &ls);
7274 ((
VALUE)node->nd_entry | 1));
7282 ADD_INSN2(ret, line, setinstancevariable,
7284 get_ivar_ic_value(
iseq,node->nd_vid));
7300 compile_cpath(ret,
iseq, node->nd_else);
7316 unsigned int flag = 0;
7318 ID id = node->nd_mid;
7347 asgnflag =
COMPILE_RECV(ret,
"NODE_OP_ASGN1 recv", node);
7348 CHECK(asgnflag != -1);
7349 switch (
nd_type(node->nd_args->nd_head)) {
7357 argc = setup_args(
iseq, ret, node->nd_args->nd_head, &flag,
NULL);
7381 ADD_INSNL(ret, line, branchunless, label);
7385 CHECK(
COMPILE(ret,
"NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body));
7419 CHECK(
COMPILE(ret,
"NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body));
7450 ID atype = node->nd_next->nd_mid;
7498 asgnflag =
COMPILE_RECV(ret,
"NODE_OP_ASGN2#recv", node);
7499 CHECK(asgnflag != -1);
7500 if (node->nd_next->nd_aid) {
7514 ADD_INSNL(ret, line, branchunless, lcfin);
7517 CHECK(
COMPILE(ret,
"NODE_OP_ASGN2 val", node->nd_value));
7537 CHECK(
COMPILE(ret,
"NODE_OP_ASGN2 val", node->nd_value));
7544 if (lskip && popped) {
7548 if (lskip && !popped) {
7559 switch (
nd_type(node->nd_head)) {
7564 CHECK(
COMPILE(ret,
"NODE_OP_CDECL/colon2#nd_head", node->nd_head->nd_head));
7571 mid = node->nd_head->nd_mid;
7573 if (node->nd_aid ==
idOROP) {
7578 ADD_INSNL(ret, line, branchunless, lassign);
7587 if (node->nd_aid ==
idOROP)
7590 ADD_INSNL(ret, line, branchunless, lfin);
7592 if (!popped)
ADD_INSN(ret, line, pop);
7594 CHECK(
COMPILE(ret,
"NODE_OP_CDECL#nd_value", node->nd_value));
7604 if (!popped)
ADD_INSN(ret, line, swap);
7608 CHECK(
COMPILE(ret,
"NODE_OP_CDECL#nd_value", node->nd_value));
7630 defined_expr(
iseq, ret, node->nd_head, lfinish,
Qfalse);
7631 lassign = lfinish[1];
7635 ADD_INSNL(ret, line, branchunless, lassign);
7641 CHECK(
COMPILE(ret,
"NODE_OP_ASGN_AND/OR#nd_head", node->nd_head));
7645 ADD_INSNL(ret, line, branchunless, lfin);
7653 CHECK(
COMPILE(ret,
"NODE_OP_ASGN_AND/OR#nd_value", node->nd_value));
7664 if (compile_call_precheck_freeze(
iseq, ret, node, line, popped) ==
TRUE) {
7678 unsigned int flag = 0;
7680 const rb_iseq_t *parent_block = ISEQ_COMPILE_DATA(
iseq)->current_block;
7683 ISEQ_COMPILE_DATA(
iseq)->current_block =
NULL;
7694 const struct rb_iseq_param_keyword *
const local_kwd = local_body->
param.
keyword;
7695 int lvar_level = get_lvar_level(
iseq);
7732 for (j=0; j<post_len; j++) {
7737 ADD_INSN (args, line, concatarray);
7742 for (j=0; j<post_len; j++) {
7746 argc = post_len + post_start;
7764 for (
i = 0;
i < local_kwd->num; ++
i) {
7765 ID id = local_kwd->table[
i];
7766 int idx =
local_size - get_local_var_idx(liseq,
id);
7773 ADD_INSN (args, line, concatarray);
7785 ADD_INSN (args, line, concatarray);
7806 CHECK(compile_array(
iseq, ret, node, popped) >= 0);
7816 const NODE *
n = node;
7828 CHECK(compile_hash(
iseq, ret, node, popped) >= 0);
7831 CHECK(compile_return(
iseq, ret, node, popped));
7836 unsigned int flag = 0;
7841 if (check_yield_place(
iseq, line) ==
FALSE) {
7846 if (node->nd_head) {
7864 ID id = node->nd_vid;
7874 debugi(
"nd_vid", node->nd_vid);
7876 idx = get_dyna_var_idx(
iseq, node->nd_vid, &lv, &ls);
7888 ((
VALUE)node->nd_entry | 1));
7895 debugi(
"nd_vid", node->nd_vid);
7897 ADD_INSN2(ret, line, getinstancevariable,
7899 get_ivar_ic_value(
iseq,node->nd_vid));
7904 debugi(
"nd_vid", node->nd_vid);
7906 if (ISEQ_COMPILE_DATA(
iseq)->option->inline_const_cache) {
7908 int ic_index = body->
is_size++;
7936 if (!node->nd_nth) {
7948 INT2FIX(0x01 | (node->nd_nth << 1)));
7962 ADD_INSN1(recv, line, putobject, node->nd_lit);
7980 if (node->nd_args) {
7981 compile_named_capture_assign(
iseq, ret, node->nd_args);
7992 ADD_INSN1(ret, line, putobject, node->nd_lit);
7999 VALUE lit = node->nd_lit;
8000 if (!ISEQ_COMPILE_DATA(
iseq)->option->frozen_string_literal) {
8022 compile_dstr(
iseq, ret, node);
8028 if (ISEQ_COMPILE_DATA(
iseq)->option->frozen_string_literal) {
8033 ADD_INSN1(ret, line, freezestring, debug_info);
8034 if (!
NIL_P(debug_info)) {
8055 compile_dstr(
iseq, ret, node);
8064 CHECK(compile_evstr(
iseq, ret, node->nd_body, popped));
8067 compile_dregx(
iseq, ret, node);
8075 int ic_index = body->
is_size++;
8077 block_iseq =
NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(
iseq), ISEQ_TYPE_PLAIN, line);
8108 CHECK(
COMPILE_(ret,
"argspush body", node->nd_body, popped));
8112 CHECK(
COMPILE_(ret,
"argspush body", node->nd_body, popped));
8128 ID mid = node->nd_mid;
8131 ISEQ_TYPE_METHOD, line);
8144 ID mid = node->nd_mid;
8147 ISEQ_TYPE_METHOD, line);
8151 ADD_INSN2(ret, line, definesmethod,
ID2SYM(mid), singleton_method_iseq);
8196 ISEQ_TYPE_CLASS, line);
8199 compile_cpath(ret,
iseq, node->nd_cpath);
8213 ISEQ_TYPE_CLASS, line);
8215 compile_cpath(ret,
iseq, node->nd_cpath);
8229 ISEQ_TYPE_CLASS, line);
8233 CONST_ID(singletonclass,
"singletonclass");
8235 ID2SYM(singletonclass), singleton_class,
8248 int ic_index = body->
is_size++;
8255 CHECK(compile_const_prefix(
iseq, node, pref, body));
8256 if (LIST_INSN_SIZE_ZERO(pref)) {
8257 if (ISEQ_COMPILE_DATA(
iseq)->option->inline_const_cache) {
8266 if (ISEQ_COMPILE_DATA(
iseq)->option->inline_const_cache) {
8289 int ic_index = body->
is_size++;
8291 debugi(
"colon3#nd_mid", node->nd_mid);
8294 if (ISEQ_COMPILE_DATA(
iseq)->option->inline_const_cache) {
8303 if (ISEQ_COMPILE_DATA(
iseq)->option->inline_const_cache) {
8317 const NODE *b = node->nd_beg;
8318 const NODE *e = node->nd_end;
8319 if (number_literal_p(b) && number_literal_p(e)) {
8376 if (body->
type == ISEQ_TYPE_RESCUE) {
8383 if (ip->
body->
type == ISEQ_TYPE_RESCUE) {
8408 int is_index = body->
is_size++;
8410 rb_iseq_new_with_callback_new_callback(build_postexe_iseq, node->nd_body);
8412 new_child_iseq_with_callback(
iseq, ifunc,
8426 const NODE *default_value = node->nd_body->nd_value;
8449 ADD_INSNL(ret, line, branchif, end_label);
8457 compile_dstr(
iseq, ret, node);
8469 unsigned int flag = 0;
8470 ID mid = node->nd_mid;
8478 if (mid ==
idASET && !private_recv_p(node) && node->nd_args &&
8481 ISEQ_COMPILE_DATA(
iseq)->current_block ==
NULL &&
8482 !ISEQ_COMPILE_DATA(
iseq)->option->frozen_string_literal &&
8483 ISEQ_COMPILE_DATA(
iseq)->option->specialized_instruction)
8487 CHECK(
COMPILE(ret,
"value", node->nd_args->nd_next->nd_head));
8501 argc = setup_args(
iseq, args, node->nd_args, &flag,
NULL);
8505 CHECK(asgnflag != -1);
8506 flag |= (
unsigned int)asgnflag;
8514 else_label = qcall_branch_start(
iseq, recv, &branches, node, line);
8546 qcall_branch_end(
iseq, ret, else_label, branches, node, line);
8581insn_data_length(
INSN *iobj)
8583 return insn_len(iobj->
insn_id);
8587calc_sp_depth(
int depth,
INSN *insn)
8589 return comptime_insn_stack_increase(depth, insn->
insn_id, insn->
operands);
8595 struct RBasic *r = (
struct RBasic *)
obj;
8612insn_data_to_s_detail(
INSN *iobj)
8620 for (j = 0;
types[j]; j++) {
8680 if (dladdr(func, &info) && info.dli_sname) {
8689 rb_bug(
"unsupported: TS_BUILTIN");
8717 printf(
"-- raw disasm--------\n");
8721 switch (
link->type) {
8722 case ISEQ_ELEMENT_INSN:
8725 str = insn_data_to_s_detail(iobj);
8727 pos += insn_data_length(iobj);
8730 case ISEQ_ELEMENT_LABEL:
8734 dest == lobj ?
" <---" :
"");
8737 case ISEQ_ELEMENT_TRACE:
8743 case ISEQ_ELEMENT_ADJUST:
8755 printf(
"---------------------\n");
8762 return insn_name(
i);
8788 label = (
LABEL *)tmp;
8798#define rb_intern(str) rb_intern_const(str)
8799 static VALUE symRescue, symEnsure, symRetry;
8800 static VALUE symBreak, symRedo, symNext;
8802 if (symRescue == 0) {
8811 if (
sym == symRescue)
return CATCH_TYPE_RESCUE;
8812 if (
sym == symEnsure)
return CATCH_TYPE_ENSURE;
8813 if (
sym == symRetry)
return CATCH_TYPE_RETRY;
8814 if (
sym == symBreak)
return CATCH_TYPE_BREAK;
8815 if (
sym == symRedo)
return CATCH_TYPE_REDO;
8816 if (
sym == symNext)
return CATCH_TYPE_NEXT;
8830 LABEL *lstart, *lend, *lcont;
8851 if (
type == CATCH_TYPE_RESCUE ||
8852 type == CATCH_TYPE_BREAK ||
8853 type == CATCH_TYPE_NEXT) {
8867insn_make_insn_table(
void)
8905 unsigned int flag = 0;
8916 if (!
NIL_P(vorig_argc)) orig_argc =
FIX2INT(vorig_argc);
8918 if (!
NIL_P(vkw_arg)) {
8921 size_t n = rb_call_info_kw_arg_bytes(
len);
8925 for (
i = 0;
i <
len;
i++) {
8939#define CHECK_EVENT(ev) if (sym == ID2SYM(rb_intern(#ev))) return ev;
8965 static struct st_table *insn_table;
8967 if (insn_table == 0) {
8968 insn_table = insn_make_insn_table();
8980 LABEL *label = register_label(
iseq, labels_table,
obj);
8997 "unknown instruction: %+"PRIsVALUE, insn);
9002 if (
argc != insn_len((
VALUE)insn_id)-1) {
9004 "operand size mismatch");
9011 for (j=0; j<
argc; j++) {
9013 switch (insn_op_type((
VALUE)insn_id, j)) {
9015 LABEL *label = register_label(
iseq, labels_table, op);
9055 argv[j] = iseq_build_callinfo_from_hash(
iseq, op);
9071 register_label(
iseq, labels_table,
sym);
9081#if SIZEOF_VALUE <= SIZEOF_LONG
9103 validate_labels(
iseq, labels_table);
9104 if (!ret)
return ret;
9105 return iseq_setup(
iseq, anchor);
9108#define CHECK_ARRAY(v) rb_to_array_type(v)
9109#define CHECK_SYMBOL(v) rb_to_symbol_type(v)
9119 else if (!
NIL_P(val)) {
9126static const struct rb_iseq_param_keyword *
9135 struct rb_iseq_param_keyword *keyword =
ZALLOC(
struct rb_iseq_param_keyword);
9140#define SYM(s) ID2SYM(rb_intern(#s))
9141 (
void)int_param(&keyword->bits_start, params,
SYM(kwbits));
9142 i = keyword->bits_start - keyword->num;
9147 for (
i = 0;
i <
len;
i++) {
9151 goto default_values;
9154 keyword->required_num++;
9158 default_len =
len -
i;
9159 if (default_len == 0) {
9160 keyword->table = ids;
9163 else if (default_len < 0) {
9169 for (j = 0;
i <
len;
i++, j++) {
9186 dvs[j] = default_val;
9189 keyword->table = ids;
9190 keyword->default_values = dvs;
9200 unsigned int pos = 0;
9203#ifdef STRICT_ALIGNMENT
9204 size_t padding = calc_padding((
void *)&storage->
buff[pos],
size);
9206 const size_t padding = 0;
9208 size_t offset = pos +
size + padding;
9209 if (offset > storage->
size || offset > storage->
pos) {
9211 storage = storage->
next;
9214#ifdef STRICT_ALIGNMENT
9215 pos += (
int)padding;
9218 iobj = (
INSN *)&storage->
buff[pos];
9224 for (j = 0;
types[j]; j++) {
9251#define SYM(s) ID2SYM(rb_intern(#s))
9253 unsigned int arg_size,
local_size, stack_max;
9267 for (
i = 0;
i <
len;
i++) {
9270 if (sym_arg_rest == lv) {
9278#define INT_PARAM(F) int_param(&iseq->body->param.F, params, SYM(F))
9288#define INT_PARAM(F) F = (int_param(&x, misc, SYM(F)) ? (unsigned int)x : 0)
9303 for (
i = 0;
i <
len;
i++) {
9305 LABEL *label = register_label(
iseq, labels_table, ent);
9306 opt_table[
i] = (
VALUE)label;
9313 else if (!
NIL_P(arg_opt_labels)) {
9321 else if (!
NIL_P(keywords)) {
9330 if (int_param(&
i, params,
SYM(kwrest))) {
9331 struct rb_iseq_param_keyword *keyword = (
struct rb_iseq_param_keyword *)
iseq->
body->
param.
keyword;
9335 keyword->rest_start =
i;
9339 iseq_calc_param_size(
iseq);
9342 iseq_build_from_ary_exception(
iseq, labels_table, exception);
9345 iseq_build_from_ary_body(
iseq, anchor, body, labels_wrapper);
9432 rb_iseq_new_with_callback_new_callback(build, &acc);
9442 const int line = args->
line;
9445 iseq_set_local_table(
iseq, 0);
9457 const int line = args->
line;
9477 return method_for_self(
name,
arg, func, for_self_aref);
9486 return method_for_self(
name,
arg, func, for_self_aset);
9491#ifndef IBF_ISEQ_DEBUG
9492#define IBF_ISEQ_DEBUG 0
9495#ifndef IBF_ISEQ_ENABLE_LOCAL_BUFFER
9496#define IBF_ISEQ_ENABLE_LOCAL_BUFFER 0
9500#define IBF_OFFSET(ptr) ((ibf_offset_t)(VALUE)(ptr))
9502#define IBF_MAJOR_VERSION ISEQ_MAJOR_VERSION
9504#define IBF_DEVEL_VERSION 2
9505#define IBF_MINOR_VERSION (ISEQ_MINOR_VERSION * 10000 + IBF_DEVEL_VERSION)
9507#define IBF_MINOR_VERSION ISEQ_MINOR_VERSION
9560#if SIZEOF_LONG > SIZEOF_INT
9565 return (
unsigned int)pos;
9569ibf_dump_align(
struct ibf_dump *dump,
size_t align)
9573 static const char padding[
sizeof(
VALUE)];
9575#if SIZEOF_LONG > SIZEOF_INT
9580 for (;
size >
sizeof(padding);
size -=
sizeof(padding)) {
9597ibf_dump_write_byte(
struct ibf_dump *dump,
unsigned char byte)
9599 return ibf_dump_write(dump, &
byte,
sizeof(
unsigned char));
9603ibf_dump_overwrite(
struct ibf_dump *dump,
void *
buff,
unsigned int size,
long offset)
9608 rb_bug(
"ibf_dump_overwrite: overflow");
9624 size_t size = x * y;
9629#define IBF_W_ALIGN(type) (RUBY_ALIGNOF(type) > 1 ? ibf_dump_align(dump, RUBY_ALIGNOF(type)) : (void)0)
9631#define IBF_W(b, type, n) (IBF_W_ALIGN(type), (type *)(VALUE)IBF_WP(b, type, n))
9632#define IBF_WV(variable) ibf_dump_write(dump, &(variable), sizeof(variable))
9633#define IBF_WP(b, type, n) ibf_dump_write(dump, (b), sizeof(type) * (n))
9634#define IBF_R(val, type, n) (type *)ibf_load_alloc(load, IBF_OFFSET(val), sizeof(type), (n))
9635#define IBF_ZERO(variable) memset(&(variable), 0, sizeof(variable))
9653 int index = ibf_table_lookup(table,
key);
9671ibf_dump_object_list_new(
void)
9698 return ibf_dump_object(dump,
rb_id2sym(
id));
9702ibf_load_id(
const struct ibf_load *load,
const ID id_index)
9704 if (id_index == 0) {
9707 VALUE sym = ibf_load_object(load, id_index);
9729 if (iseq_index < 0) {
9740 return (
VALUE)ibf_dump_id(dump, entry->
id);
9746 ID gid = ibf_load_id(load, (
ID)(
VALUE)entry);
9771 ibf_dump_write(dump, &x,
sizeof(
VALUE));
9774 enum { max_byte_length =
sizeof(
VALUE) + 1 };
9776 unsigned char bytes[max_byte_length];
9779 for (
n = 0;
n <
sizeof(
VALUE) && (x >> (7 -
n));
n++, x >>= 8) {
9780 bytes[max_byte_length - 1 -
n] = (
unsigned char)x;
9786 bytes[max_byte_length - 1 -
n] = (
unsigned char)x;
9789 ibf_dump_write(dump, bytes + max_byte_length -
n,
n);
9799 *offset +=
sizeof(
VALUE);
9804 enum { max_byte_length =
sizeof(
VALUE) + 1 };
9807 const unsigned char c = buffer[*offset];
9811 c == 0 ? 9 : ntz_int32(c) + 1;
9819 for (
i = 1;
i <
n;
i++) {
9821 x |= (
VALUE)buffer[*offset +
i];
9835 ibf_dump_write_small_value(dump, (
VALUE)bf->
index);
9838 ibf_dump_write_small_value(dump, (
VALUE)
len);
9839 ibf_dump_write(dump, bf->
name,
len);
9845 int i = (
int)ibf_load_small_value(load, offset);
9846 int len = (
int)ibf_load_small_value(load, offset);
9847 const char *
name = (
char *)ibf_load_ptr(load, offset,
len);
9873 for (code_index=0; code_index<
iseq_size;) {
9874 const VALUE insn = orig_code[code_index++];
9875 const char *
types = insn_op_types(insn);
9880 ibf_dump_write_small_value(dump, insn);
9883 for (op_index=0;
types[op_index]; op_index++, code_index++) {
9884 VALUE op = orig_code[code_index];
9887 switch (
types[op_index]) {
9890 wv = ibf_dump_object(dump, op);
9912 ibf_dump_write_byte(dump, c);
9916 wv = ibf_dump_id(dump, (
ID)op);
9931 ibf_dump_write_small_value(dump, wv);
9934 assert(insn_len(insn) == op_index+1);
9943 unsigned int code_index;
9952 for (code_index=0; code_index<iseq_size;) {
9954 const VALUE insn = code[code_index++] = ibf_load_small_value(load, &reading_pos);
9955 const char *
types = insn_op_types(insn);
9959 for (op_index=0;
types[op_index]; op_index++, code_index++) {
9960 switch (
types[op_index]) {
9964 VALUE op = ibf_load_small_value(load, &reading_pos);
9965 VALUE v = ibf_load_object(load, op);
9966 code[code_index] =
v;
9975 VALUE op = (
VALUE)ibf_load_small_value(load, &reading_pos);
9977 code[code_index] =
v;
9990 VALUE op = ibf_load_small_value(load, &reading_pos);
9991 code[code_index] = (
VALUE)&is_entries[op];
9996 unsigned char op = ibf_load_byte(load, &reading_pos);
9997 code[code_index] = op ? (
VALUE)cd_kw_entries++ : (
VALUE)cd_entries++;
10002 VALUE op = ibf_load_small_value(load, &reading_pos);
10003 code[code_index] = ibf_load_id(load, (
ID)(
VALUE)op);
10008 VALUE op = ibf_load_small_value(load, &reading_pos);
10016 code[code_index] = (
VALUE)ibf_load_builtin(load, &reading_pos);
10019 code[code_index] = ibf_load_small_value(load, &reading_pos);
10023 if (insn_len(insn) != op_index+1) {
10030 assert(code_index == iseq_size);
10031 assert(reading_pos == bytecode_offset + bytecode_size);
10045 return ibf_dump_pos(dump);
10050ibf_load_param_opt_table(
const struct ibf_load *load,
ibf_offset_t opt_table_offset,
int opt_num)
10068 struct rb_iseq_param_keyword dump_kw = *kw;
10069 int dv_num = kw->num - kw->required_num;
10074 for (
i=0;
i<kw->num;
i++) ids[
i] = (
ID)ibf_dump_id(dump, kw->table[
i]);
10075 for (
i=0;
i<dv_num;
i++) dvs[
i] = (
VALUE)ibf_dump_object(dump, kw->default_values[
i]);
10077 dump_kw.table =
IBF_W(ids,
ID, kw->num);
10078 dump_kw.default_values =
IBF_W(dvs,
VALUE, dv_num);
10080 return ibf_dump_write(dump, &dump_kw,
sizeof(
struct rb_iseq_param_keyword) * 1);
10087static const struct rb_iseq_param_keyword *
10090 if (param_keyword_offset) {
10091 struct rb_iseq_param_keyword *kw =
IBF_R(param_keyword_offset,
struct rb_iseq_param_keyword, 1);
10092 ID *ids =
IBF_R(kw->table,
ID, kw->num);
10093 int dv_num = kw->num - kw->required_num;
10097 for (
i=0;
i<kw->num;
i++) {
10098 ids[
i] = ibf_load_id(load, ids[
i]);
10100 for (
i=0;
i<dv_num;
i++) {
10101 dvs[
i] = ibf_load_object(load, dvs[
i]);
10105 kw->default_values = dvs;
10136 entries[
i].line_no = (
int)ibf_load_small_value(load, &reading_pos);
10144ibf_dump_insns_info_positions(
struct ibf_dump *dump,
const unsigned int *positions,
unsigned int size)
10148 unsigned int last = 0;
10151 ibf_dump_write_small_value(dump, positions[
i] -
last);
10152 last = positions[
i];
10158static unsigned int *
10162 unsigned int *positions =
ALLOC_N(
unsigned int,
size);
10164 unsigned int last = 0;
10167 positions[
i] =
last + (
unsigned int)ibf_load_small_value(load, &reading_pos);
10168 last = positions[
i];
10187 return ibf_dump_write(dump,
table,
sizeof(
ID) *
size);
10216 for (
i=0;
i<table->
size;
i++) {
10217 iseq_indices[
i] = ibf_dump_iseq(dump, table->
entries[
i].
iseq);
10222 for (
i=0;
i<table->
size;
i++) {
10223 ibf_dump_write_small_value(dump, iseq_indices[
i]);
10224 ibf_dump_write_small_value(dump, table->
entries[
i].
type);
10226 ibf_dump_write_small_value(dump, table->
entries[
i].
end);
10227 ibf_dump_write_small_value(dump, table->
entries[
i].
cont);
10228 ibf_dump_write_small_value(dump, table->
entries[
i].
sp);
10233 return ibf_dump_pos(dump);
10247 for (
i=0;
i<table->
size;
i++) {
10248 int iseq_index = (
int)ibf_load_small_value(load, &reading_pos);
10249 table->
entries[
i].
type = (
enum catch_type)ibf_load_small_value(load, &reading_pos);
10250 table->
entries[
i].
start = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10251 table->
entries[
i].
end = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10252 table->
entries[
i].
cont = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10253 table->
entries[
i].
sp = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10277 for (
i = 0;
i < ci_size;
i++) {
10278 VALUE mid = ibf_dump_id(dump, calls[
i].
ci.mid);
10280 ibf_dump_write_small_value(dump, mid);
10281 ibf_dump_write_small_value(dump, calls[
i].
ci.flag);
10282 ibf_dump_write_small_value(dump, calls[
i].
ci.orig_argc);
10285 for (
i = 0;
i < ci_kw_size;
i++) {
10288 VALUE mid = ibf_dump_id(dump, kw_calls[
i].ci_kw.ci.mid);
10290 ibf_dump_write_small_value(dump, mid);
10291 ibf_dump_write_small_value(dump, kw_calls[
i].ci_kw.ci.flag);
10292 ibf_dump_write_small_value(dump, kw_calls[
i].ci_kw.ci.orig_argc);
10294 ibf_dump_write_small_value(dump, kw_arg->
keyword_len);
10298 VALUE keyword = ibf_dump_object(dump, kw_arg->
keywords[j]);
10300 ibf_dump_write_small_value(dump, keyword);
10309ibf_load_ci_entries(
const struct ibf_load *load,
10311 unsigned int ci_size,
10312 unsigned int ci_kw_size)
10324 for (
i = 0;
i < ci_size;
i++) {
10325 VALUE mid_index = ibf_load_small_value(load, &reading_pos);
10327 calls[
i].
ci.
mid = ibf_load_id(load, mid_index);
10328 calls[
i].
ci.
flag = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10329 calls[
i].
ci.
orig_argc = (
int)ibf_load_small_value(load, &reading_pos);
10332 for (
i = 0;
i < ci_kw_size;
i++) {
10333 VALUE mid_index = ibf_load_small_value(load, &reading_pos);
10335 kw_calls[
i].
ci_kw.
ci.
mid = ibf_load_id(load, mid_index);
10336 kw_calls[
i].
ci_kw.
ci.
flag = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10339 int keyword_len = (
int)ibf_load_small_value(load, &reading_pos);
10348 VALUE keyword = ibf_load_small_value(load, &reading_pos);
10362 unsigned int *positions;
10370#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
10376 buffer.obj_list = ibf_dump_object_list_new();
10381 const ibf_offset_t bytecode_size = ibf_dump_pos(dump) - bytecode_offset;
10382 const ibf_offset_t param_opt_table_offset = ibf_dump_param_opt_table(dump,
iseq);
10383 const ibf_offset_t param_keyword_offset = ibf_dump_param_keyword(dump,
iseq);
10384 const ibf_offset_t insns_info_body_offset = ibf_dump_insns_info_body(dump,
iseq);
10397#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
10399 unsigned int local_obj_list_size;
10401 ibf_dump_object_list(dump, &local_obj_list_offset, &local_obj_list_size);
10407 unsigned int param_flags =
10419#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
10420# define IBF_BODY_OFFSET(x) (x)
10422# define IBF_BODY_OFFSET(x) (body_offset - (x))
10425 ibf_dump_write_small_value(dump, body->
type);
10426 ibf_dump_write_small_value(dump, body->
iseq_size);
10428 ibf_dump_write_small_value(dump, bytecode_size);
10429 ibf_dump_write_small_value(dump, param_flags);
10430 ibf_dump_write_small_value(dump, body->
param.
size);
10432 ibf_dump_write_small_value(dump, body->
param.
opt_num);
10437 ibf_dump_write_small_value(dump,
IBF_BODY_OFFSET(param_opt_table_offset));
10438 ibf_dump_write_small_value(dump, param_keyword_offset);
10439 ibf_dump_write_small_value(dump, location_pathobj_index);
10440 ibf_dump_write_small_value(dump, location_base_label_index);
10441 ibf_dump_write_small_value(dump, location_label_index);
10448 ibf_dump_write_small_value(dump,
IBF_BODY_OFFSET(insns_info_body_offset));
10449 ibf_dump_write_small_value(dump,
IBF_BODY_OFFSET(insns_info_positions_offset));
10451 ibf_dump_write_small_value(dump,
IBF_BODY_OFFSET(local_table_offset));
10452 ibf_dump_write_small_value(dump, catch_table_size);
10453 ibf_dump_write_small_value(dump,
IBF_BODY_OFFSET(catch_table_offset));
10454 ibf_dump_write_small_value(dump, parent_iseq_index);
10455 ibf_dump_write_small_value(dump, local_iseq_index);
10456 ibf_dump_write_small_value(dump,
IBF_BODY_OFFSET(ci_entries_offset));
10459 ibf_dump_write_small_value(dump, body->
is_size);
10460 ibf_dump_write_small_value(dump, body->
ci_size);
10461 ibf_dump_write_small_value(dump, body->
ci_kw_size);
10462 ibf_dump_write_small_value(dump, body->
stack_max);
10465#undef IBF_BODY_OFFSET
10467#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
10471 ibf_dump_write(dump,
RSTRING_PTR(buffer.str), iseq_length_bytes);
10474 ibf_dump_write_small_value(dump, iseq_start);
10475 ibf_dump_write_small_value(dump, iseq_length_bytes);
10476 ibf_dump_write_small_value(dump, body_offset);
10478 ibf_dump_write_small_value(dump, local_obj_list_offset);
10479 ibf_dump_write_small_value(dump, local_obj_list_size);
10483 return body_offset;
10488ibf_load_location_str(
const struct ibf_load *load,
VALUE str_index)
10490 VALUE str = ibf_load_object(load, str_index);
10504#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
10508 const ibf_offset_t iseq_start = ibf_load_small_value(load, &reading_pos);
10509 const ibf_offset_t iseq_length_bytes = ibf_load_small_value(load, &reading_pos);
10510 const ibf_offset_t body_offset = ibf_load_small_value(load, &reading_pos);
10514 buffer.size = iseq_length_bytes;
10515 buffer.obj_list_offset = ibf_load_small_value(load, &reading_pos);
10516 buffer.obj_list_size = ibf_load_small_value(load, &reading_pos);
10521 reading_pos = body_offset;
10524#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
10525# define IBF_BODY_OFFSET(x) (x)
10527# define IBF_BODY_OFFSET(x) (offset - (x))
10530 const unsigned int type = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10531 const unsigned int iseq_size = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10534 const unsigned int param_flags = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10535 const unsigned int param_size = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10536 const int param_lead_num = (
int)ibf_load_small_value(load, &reading_pos);
10537 const int param_opt_num = (
int)ibf_load_small_value(load, &reading_pos);
10538 const int param_rest_start = (
int)ibf_load_small_value(load, &reading_pos);
10539 const int param_post_start = (
int)ibf_load_small_value(load, &reading_pos);
10540 const int param_post_num = (
int)ibf_load_small_value(load, &reading_pos);
10541 const int param_block_start = (
int)ibf_load_small_value(load, &reading_pos);
10544 const VALUE location_pathobj_index = ibf_load_small_value(load, &reading_pos);
10545 const VALUE location_base_label_index = ibf_load_small_value(load, &reading_pos);
10546 const VALUE location_label_index = ibf_load_small_value(load, &reading_pos);
10547 const VALUE location_first_lineno = ibf_load_small_value(load, &reading_pos);
10548 const int location_node_id = (
int)ibf_load_small_value(load, &reading_pos);
10549 const int location_code_location_beg_pos_lineno = (
int)ibf_load_small_value(load, &reading_pos);
10550 const int location_code_location_beg_pos_column = (
int)ibf_load_small_value(load, &reading_pos);
10551 const int location_code_location_end_pos_lineno = (
int)ibf_load_small_value(load, &reading_pos);
10552 const int location_code_location_end_pos_column = (
int)ibf_load_small_value(load, &reading_pos);
10555 const unsigned int insns_info_size = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10557 const unsigned int catch_table_size = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10559 const int parent_iseq_index = (
int)ibf_load_small_value(load, &reading_pos);
10560 const int local_iseq_index = (
int)ibf_load_small_value(load, &reading_pos);
10562 const rb_snum_t variable_flip_count = (
rb_snum_t)ibf_load_small_value(load, &reading_pos);
10563 const unsigned int local_table_size = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10564 const unsigned int is_size = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10565 const unsigned int ci_size = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10566 const unsigned int ci_kw_size = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10567 const unsigned int stack_max = (
unsigned int)ibf_load_small_value(load, &reading_pos);
10568 const char catch_except_p = (
char)ibf_load_small_value(load, &reading_pos);
10570#undef IBF_BODY_OFFSET
10592 load_body->
is_size = is_size;
10593 load_body->
ci_size = ci_size;
10598 ISEQ_ORIGINAL_ISEQ_CLEAR(
iseq);
10610 load_body->
call_data = ibf_load_ci_entries(load, ci_entries_offset, ci_size, ci_kw_size);
10611 load_body->
param.
opt_table = ibf_load_param_opt_table(load, param_opt_table_offset, param_opt_num);
10612 load_body->
param.
keyword = ibf_load_param_keyword(load, param_keyword_offset);
10614 load_body->
insns_info.
body = ibf_load_insns_info_body(load, insns_info_body_offset, insns_info_size);
10615 load_body->
insns_info.
positions = ibf_load_insns_info_positions(load, insns_info_positions_offset, insns_info_size);
10616 load_body->
local_table = ibf_load_local_table(load, local_table_offset, local_table_size);
10617 load_body->
catch_table = ibf_load_catch_table(load, catch_table_offset, catch_table_size);
10621 ibf_load_code(load,
iseq, bytecode_offset, bytecode_size, iseq_size);
10622#if VM_INSN_INFO_TABLE_IMPL == 2
10626 rb_iseq_translate_threaded_code(
iseq);
10628#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
10662#if IBF_ISEQ_ENABLE_LOCAL_BUFFER
10665 verify_call_cache(
iseq);
10691#define IBF_OBJECT_INTERNAL FL_PROMOTED0
10703 unsigned int internal: 1;
10749#define IBF_ALIGNED_OFFSET(align, offset) \
10750 ((((offset) - 1) / (align) + 1) * (align))
10751#define IBF_OBJBODY(type, offset) (const type *)\
10752 ibf_load_check_offset(load, IBF_ALIGNED_OFFSET(RUBY_ALIGNOF(type), offset))
10755ibf_load_check_offset(
const struct ibf_load *load,
size_t offset)
10802 rb_bug(
"unsupported class");
10804 ibf_dump_write_small_value(dump, (
VALUE)cindex);
10839 const double *dblp =
IBF_OBJBODY(
double, offset);
10856 ibf_dump_write_small_value(dump, encindex);
10857 ibf_dump_write_small_value(dump,
len);
10866 int encindex = (
int)ibf_load_small_value(load, &reading_pos);
10867 const long len = (
long)ibf_load_small_value(load, &reading_pos);
10890 regexp.srcstr = (
long)ibf_dump_object(dump,
srcstr);
10892 ibf_dump_write_byte(dump, (
unsigned char)regexp.option);
10893 ibf_dump_write_small_value(dump, regexp.srcstr);
10900 regexp.
option = ibf_load_byte(load, &offset);
10901 regexp.srcstr = ibf_load_small_value(load, &offset);
10903 VALUE srcstr = ibf_load_object(load, regexp.srcstr);
10916 ibf_dump_write_small_value(dump,
len);
10919 ibf_dump_write_small_value(dump,
index);
10928 const long len = (
long)ibf_load_small_value(load, &reading_pos);
10934 const VALUE index = ibf_load_small_value(load, &reading_pos);
10950 VALUE val_index = ibf_dump_object(dump, (
VALUE)val);
10952 ibf_dump_write_small_value(dump, key_index);
10953 ibf_dump_write_small_value(dump, val_index);
10961 ibf_dump_write_small_value(dump, (
VALUE)
len);
10969 long len = (
long)ibf_load_small_value(load, &offset);
10973 for (
i = 0;
i <
len;
i++) {
10974 VALUE key_index = ibf_load_small_value(load, &offset);
10975 VALUE val_index = ibf_load_small_value(load, &offset);
10977 VALUE key = ibf_load_object(load, key_index);
10978 VALUE val = ibf_load_object(load, val_index);
10997 range.class_index = 0;
11039 int sign = bignum->
slen > 0;
11062 ibf_dump_object_unsupported(dump,
obj);
11072 const char *data = (
const char *)&body[2];
11082 return ibf_load_object_unsupported(load, header, offset);
11099 VALUE a = ibf_load_object(load, nums->
a);
11100 VALUE b = ibf_load_object(load, nums->
b);
11113 VALUE str_index = ibf_dump_object(dump,
str);
11115 ibf_dump_write_small_value(dump, str_index);
11121 VALUE str_index = ibf_load_small_value(load, &offset);
11122 VALUE str = ibf_load_object(load, str_index);
11129 ibf_dump_object_unsupported,
11130 ibf_dump_object_unsupported,
11131 ibf_dump_object_class,
11132 ibf_dump_object_unsupported,
11133 ibf_dump_object_float,
11134 ibf_dump_object_string,
11135 ibf_dump_object_regexp,
11136 ibf_dump_object_array,
11137 ibf_dump_object_hash,
11138 ibf_dump_object_struct,
11139 ibf_dump_object_bignum,
11140 ibf_dump_object_unsupported,
11141 ibf_dump_object_data,
11142 ibf_dump_object_unsupported,
11143 ibf_dump_object_complex_rational,
11144 ibf_dump_object_complex_rational,
11145 ibf_dump_object_unsupported,
11146 ibf_dump_object_unsupported,
11147 ibf_dump_object_unsupported,
11148 ibf_dump_object_unsupported,
11149 ibf_dump_object_symbol,
11150 ibf_dump_object_unsupported,
11151 ibf_dump_object_unsupported,
11152 ibf_dump_object_unsupported,
11153 ibf_dump_object_unsupported,
11154 ibf_dump_object_unsupported,
11155 ibf_dump_object_unsupported,
11156 ibf_dump_object_unsupported,
11157 ibf_dump_object_unsupported,
11158 ibf_dump_object_unsupported,
11159 ibf_dump_object_unsupported,
11160 ibf_dump_object_unsupported,
11166 unsigned char byte =
11167 (header.
type << 0) |
11178 unsigned char byte = ibf_load_byte(load, offset);
11181 header.
type = (
byte >> 0) & 0x1f;
11183 header.
frozen = (
byte >> 6) & 0x01;
11184 header.
internal = (
byte >> 7) & 0x01;
11198 current_offset = ibf_dump_pos(dump);
11203 obj_header.internal =
FALSE;
11206 obj_header.special_const =
TRUE;
11207 obj_header.frozen =
TRUE;
11208 obj_header.internal =
TRUE;
11209 ibf_dump_object_object_header(dump, obj_header);
11210 ibf_dump_write_small_value(dump,
obj);
11215 obj_header.special_const =
FALSE;
11217 ibf_dump_object_object_header(dump, obj_header);
11218 (*dump_object_functions[obj_header.type])(dump,
obj);
11221 return current_offset;
11226 ibf_load_object_unsupported,
11227 ibf_load_object_unsupported,
11228 ibf_load_object_class,
11229 ibf_load_object_unsupported,
11230 ibf_load_object_float,
11231 ibf_load_object_string,
11232 ibf_load_object_regexp,
11233 ibf_load_object_array,
11234 ibf_load_object_hash,
11235 ibf_load_object_struct,
11236 ibf_load_object_bignum,
11237 ibf_load_object_unsupported,
11238 ibf_load_object_data,
11239 ibf_load_object_unsupported,
11240 ibf_load_object_complex_rational,
11241 ibf_load_object_complex_rational,
11242 ibf_load_object_unsupported,
11243 ibf_load_object_unsupported,
11244 ibf_load_object_unsupported,
11245 ibf_load_object_unsupported,
11246 ibf_load_object_symbol,
11247 ibf_load_object_unsupported,
11248 ibf_load_object_unsupported,
11249 ibf_load_object_unsupported,
11250 ibf_load_object_unsupported,
11251 ibf_load_object_unsupported,
11252 ibf_load_object_unsupported,
11253 ibf_load_object_unsupported,
11254 ibf_load_object_unsupported,
11255 ibf_load_object_unsupported,
11256 ibf_load_object_unsupported,
11257 ibf_load_object_unsupported,
11261ibf_load_object(
const struct ibf_load *load,
VALUE object_index)
11263 if (object_index == 0) {
11274 const struct ibf_object_header header = ibf_load_object_object_header(load, &offset);
11277 fprintf(
stderr,
"ibf_load_object: list=%#x offsets=%p offset=%#x\n",
11279 fprintf(
stderr,
"ibf_load_object: type=%#x special=%d frozen=%d internal=%d\n",
11289 obj = ibf_load_small_value(load, &reading_pos);
11292 obj = (*load_object_functions[header.
type])(load, &header, offset);
11299 object_index,
obj);
11306ibf_dump_object_list(
struct ibf_dump *dump,
ibf_offset_t *obj_list_offset,
unsigned int *obj_list_size)
11319 *obj_list_offset = ibf_dump_pos(dump);
11326 *obj_list_size =
size;
11330ibf_dump_mark(
void *
ptr)
11339ibf_dump_free(
void *
ptr)
11350ibf_dump_memsize(
const void *
ptr)
11353 size_t size =
sizeof(*dump);
11360 {ibf_dump_mark, ibf_dump_free, ibf_dump_memsize,},
11392 ibf_dump_setup(dump, dump_obj);
11394 ibf_dump_write(dump, &header,
sizeof(header));
11396 ibf_dump_iseq(dump,
iseq);
11398 header.
magic[0] =
'Y';
11399 header.
magic[1] =
'A';
11400 header.
magic[2] =
'R';
11401 header.
magic[3] =
'B';
11404 ibf_dump_iseq_list(dump, &header);
11406 header.
size = ibf_dump_pos(dump);
11409 VALUE opt_str = opt;
11418 ibf_dump_overwrite(dump, &header,
sizeof(header), 0);
11421 ibf_dump_free(dump);
11428ibf_iseq_list(
const struct ibf_load *load)
11441 fprintf(
stderr,
"rb_ibf_load_iseq_complete: index=%#x offset=%#x size=%#x\n",
11445 ibf_load_iseq_each(load,
iseq, offset);
11446 ISEQ_COMPILE_DATA_CLEAR(
iseq);
11449 load->
iseq = prev_src_iseq;
11464 int iseq_index = (
int)(
VALUE)index_iseq;
11467 fprintf(
stderr,
"ibf_load_iseq: index_iseq=%p iseq_list=%p\n",
11468 (
void *)index_iseq, (
void *)load->
iseq_list);
11470 if (iseq_index == -1) {
11477 fprintf(
stderr,
"ibf_load_iseq: iseqv=%p\n", (
void *)iseqv);
11479 if (iseqv !=
Qnil) {
11491 fprintf(
stderr,
"ibf_load_iseq: iseq=%p loader_obj=%p index=%d\n",
11502 if (
GET_VM()->builtin_function_table) {
11509 (
void *)
iseq, (
void *)load->
iseq);
11532 if (size < load->header->size) {
11572ibf_loader_mark(
void *
ptr)
11581ibf_loader_free(
void *
ptr)
11588ibf_loader_memsize(
const void *
ptr)
11595 {ibf_loader_mark, ibf_loader_free, ibf_loader_memsize,},
11607 iseq = ibf_load_iseq(load, 0);
11621 iseq = ibf_load_iseq(load, 0);
#define ADD_SEND_WITH_BLOCK(seq, line, id, argc, block)
#define NEW_CHILD_ISEQ(node, name, type, line_no)
#define NEW_ISEQ(node, name, type, line_no)
#define COMPILE(anchor, desc, node)
struct iseq_label_data LABEL
#define INSERT_AFTER_INSN(prev, line, insn)
#define IS_INSN_ID(iobj, insn)
struct iseq_insn_data INSN
const ID rb_iseq_shared_exc_local_tbl[]
void rb_ibf_load_iseq_complete(rb_iseq_t *iseq)
#define IBF_ZERO(variable)
#define APPEND_LABEL(seq, before, label)
#define COMPILE_POPPED(anchor, desc, node)
#define ADD_SEND_R(seq, line, id, argc, block, flag, keywords)
struct iseq_adjust_data ADJUST
#define ADD_INSN1(seq, line, insn, op1)
#define INSERT_AFTER_INSN1(prev, line, insn, op1)
#define INSERT_BEFORE_INSN(next, line, insn)
#define ADD_GETLOCAL(seq, line, idx, level)
#define EXPECT_NODE(prefix, node, ndtype, errval)
#define IBF_MAJOR_VERSION
#define ADD_CALL_RECEIVER(seq, line)
#define LABEL_UNREMOVABLE(label)
#define ISEQ_LAST_LINE(iseq)
VALUE(* ibf_load_object_function)(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset)
#define ADD_LABEL(seq, label)
#define UNKNOWN_NODE(prefix, node, errval)
VALUE rb_iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt)
#define FLUSH_CHUNK(newarrayinsn)
#define COMPILE_RECV(anchor, desc, node)
int rb_dvar_defined(ID id, const rb_iseq_t *iseq)
#define COMPILE_(anchor, desc, node, popped)
rb_iseq_t * iseq_alloc(void)
#define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc)
#define ADD_SETLOCAL(seq, line, idx, level)
#define INSERT_BEFORE_INSN1(next, line, insn, op1)
VALUE rb_insns_name_array(void)
#define DECL_BRANCH_BASE(branches, first_line, first_column, last_line, last_column, type)
#define BADINSN_DUMP(anchor, list, dest)
VALUE rb_iseq_ibf_load_extra_data(VALUE str)
#define debug_compile(msg, v)
#define CPDEBUG
debug function(macro) interface depend on CPDEBUG if it is less than 0, runtime option is in effect.
#define ADD_ADJUST(seq, line, label)
unsigned int ibf_offset_t
#define debugi(header, id)
#define IS_NEXT_INSN_ID(link, insn)
VALUE rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node)
void(* ibf_dump_object_function)(struct ibf_dump *dump, VALUE obj)
#define IBF_WP(b, type, n)
#define ADD_INSN2(seq, line, insn, op1, op2)
VALUE rb_node_case_when_optimizable_literal(const NODE *const node)
struct iseq_link_anchor LINK_ANCHOR
#define ADD_INSN(seq, line, insn)
const rb_iseq_t * rb_iseq_ibf_load(VALUE str)
#define ADD_SEND_WITH_FLAG(seq, line, id, argc, flag)
#define DECL_ANCHOR(name)
const char * rb_insns_name(int i)
#define ADD_SEND(seq, line, id, argc)
#define ADD_CALL(seq, line, id, argc)
#define IBF_W_ALIGN(type)
#define IBF_W(b, type, n)
#define IBF_R(val, type, n)
const rb_iseq_t * rb_method_for_self_aref(VALUE name, VALUE arg, rb_insn_func_t func)
VALUE rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func *ifunc)
int rb_local_defined(ID id, const rb_iseq_t *iseq)
struct iseq_link_element LINK_ELEMENT
#define IBF_OBJBODY(type, offset)
@ IBF_OBJECT_DATA_ENCODING
@ IBF_OBJECT_CLASS_TYPE_ERROR
@ IBF_OBJECT_CLASS_NO_MATCHING_PATTERN_ERROR
@ IBF_OBJECT_CLASS_STANDARD_ERROR
@ IBF_OBJECT_CLASS_OBJECT
#define INIT_ANCHOR(name)
void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params, VALUE exception, VALUE body)
#define OPERAND_AT(insn, idx)
#define ADD_TRACE_BRANCH_COVERAGE(seq, first_line, first_column, last_line, last_column, type, branches)
#define ADD_INSNL(seq, line, insn, label)
const rb_iseq_t * rb_iseq_ibf_load_bytes(const char *bytes, size_t size)
#define ADD_ADJUST_RESTORE(seq, label)
#define debug_node_start(node)
#define debugp_param(header, value)
#define EXPECT_NODE_NONULL(prefix, parent, ndtype, errval)
VALUE * rb_iseq_original_iseq(const rb_iseq_t *iseq)
#define IBF_MINOR_VERSION
void rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *storage)
NORETURN(static void ibf_dump_object_unsupported(struct ibf_dump *dump, VALUE obj))
#define INVALID_ISEQ_TYPE(type)
const rb_iseq_t * rb_method_for_self_aset(VALUE name, VALUE arg, rb_insn_func_t func)
#define ADD_CALL_WITH_BLOCK(seq, line, id, argc, block)
#define ADD_INSN3(seq, line, insn, op1, op2, op3)
#define IBF_BODY_OFFSET(x)
#define ADD_TRACE(seq, event)
struct iseq_trace_data TRACE
#define ADD_SEQ(seq1, seq2)
#define range(low, item, hi)
@ RUBY_ENCINDEX_BUILTIN_MAX
struct rb_encoding_entry * list
int rb_enc_get_index(VALUE obj)
rb_encoding * rb_enc_from_index(int index)
int rb_data_is_encoding(VALUE obj)
rb_encoding * rb_enc_find(const char *name)
rb_encoding * rb_to_encoding(VALUE enc)
VALUE rb_enc_from_encoding(rb_encoding *encoding)
VALUE rb_enc_associate_index(VALUE obj, int idx)
int rb_enc_find_index(const char *name)
char str[HTML_ESCAPE_MAX_LEN+1]
#define rb_intern_str(string)
VALUE rb_cObject
Object class.
VALUE rb_syntax_error_append(VALUE exc, VALUE file, int line, int column, rb_encoding *enc, const char *fmt, va_list args)
void rb_raise(VALUE exc, const char *fmt,...)
_Bool rb_warning_category_enabled_p(rb_warning_category_t category)
void rb_bug(const char *fmt,...)
void rb_set_errinfo(VALUE err)
Sets the current exception ($!) to the given value.
const char * rb_builtin_type_name(int t)
VALUE rb_eNoMatchingPatternError
void rb_exc_fatal(VALUE mesg)
Raises a fatal error in the current thread.
void rb_warn(const char *fmt,...)
void rb_report_bug_valist(VALUE file, int line, const char *fmt, va_list args)
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
VALUE rb_obj_is_kind_of(VALUE, VALUE)
Determines if obj is a kind of c.
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
int rb_id_table_insert(struct rb_id_table *tbl, ID id, VALUE val)
int rb_id_table_lookup(struct rb_id_table *tbl, ID id, VALUE *valp)
struct rb_id_table * rb_id_table_create(size_t capa)
VALUE type(ANYARGS)
ANYARGS-ed function type.
rb_atomic_t cnt[RUBY_NSIG]
void st_free_table(st_table *tab)
st_table * st_init_numtable_with_size(st_index_t size)
size_t st_memsize(const st_table *tab)
st_table * st_init_numtable(void)
int st_insert(st_table *tab, st_data_t key, st_data_t value)
int st_lookup(st_table *tab, st_data_t key, st_data_t *value)
int st_foreach(st_table *tab, st_foreach_callback_func *func, st_data_t arg)
struct ensure_range * next
struct ibf_dump_buffer * current_buffer
struct ibf_dump_buffer global_buffer
ibf_offset_t obj_list_offset
unsigned int obj_list_size
struct ibf_load_buffer global_buffer
struct ibf_load_buffer * current_buffer
const struct ibf_header * header
BDIGIT digits[FLEX_ARY_LEN]
long keyval[FLEX_ARY_LEN]
enum iseq_catch_table_entry::catch_type type
struct iseq_catch_table_entry entries[]
struct iseq_compile_data_ensure_node_stack * prev
struct ensure_range * erange
struct iseq_compile_data_storage * next
struct iseq_insn_data::@64 insn_info
enum ruby_vminsn_type insn_id
struct iseq_link_element * prev
enum iseq_link_element::@63 type
struct iseq_link_element * next
unsigned int ruby2_keywords
const void *const func_ptr
struct rb_call_info_kw_arg * kw_arg
rb_code_position_t beg_pos
rb_code_position_t end_pos
const struct iseq_insn_info_entry * body
unsigned int ruby2_keywords
unsigned int ambiguous_param0
struct rb_iseq_constant_body::iseq_insn_info insns_info
enum rb_iseq_constant_body::iseq_type type
struct rb_iseq_constant_body::@45 param
union iseq_inline_storage_entry * is_entries
unsigned int local_table_size
const struct rb_iseq_constant_body::@45::rb_iseq_param_keyword * keyword
rb_iseq_location_t location
struct rb_iseq_constant_body::@45::@47 flags
struct rb_call_data * call_data
unsigned int accepts_no_kwarg
struct iseq_catch_table * catch_table
const struct rb_iseq_struct * parent_iseq
struct rb_iseq_constant_body::@46 variable
struct rb_iseq_struct * local_iseq
rb_code_location_t code_location
void(* func)(rb_iseq_t *, struct iseq_link_anchor *, const void *)
struct rb_iseq_constant_body * body
union rb_iseq_struct::@48 aux
struct rb_iseq_struct::@48::@49 loader
struct rb_call_info_with_kwarg ci_kw
int rb_is_const_id(ID id)
int rb_is_attrset_id(ID id)
rb_control_frame_t *FUNC_FASTCALL rb_insn_func_t(rb_execution_context_t *, rb_control_frame_t *)