17 #define USE_INSN_STACK_INCREASE 1 21 #include "insns_info.inc" 29 #undef RUBY_UNTYPED_DATA_WARNING 30 #define RUBY_UNTYPED_DATA_WARNING 0 32 #define ISEQ_TYPE_ONCE_GUARD ISEQ_TYPE_DEFINED_GUARD 34 #define FIXNUM_INC(n, i) ((n)+(INT2FIX(i)&~FIXNUM_FLAG)) 35 #define FIXNUM_OR(n, i) ((n)|INT2FIX(i)) 74 enum ruby_vminsn_type insn_id;
117 #define compile_debug CPDEBUG 119 #define compile_debug ISEQ_COMPILE_DATA(iseq)->option->debug_level 124 #define compile_debug_print_indent(level) \ 125 ruby_debug_print_indent((level), compile_debug, gl_node_level * 2) 127 #define debugp(header, value) (void) \ 128 (compile_debug_print_indent(1) && \ 129 ruby_debug_print_value(1, compile_debug, (header), (value))) 131 #define debugi(header, id) (void) \ 132 (compile_debug_print_indent(1) && \ 133 ruby_debug_print_id(1, compile_debug, (header), (id))) 135 #define debugp_param(header, value) (void) \ 136 (compile_debug_print_indent(1) && \ 137 ruby_debug_print_value(1, compile_debug, (header), (value))) 139 #define debugp_verbose(header, value) (void) \ 140 (compile_debug_print_indent(2) && \ 141 ruby_debug_print_value(2, compile_debug, (header), (value))) 143 #define debugp_verbose_node(header, value) (void) \ 144 (compile_debug_print_indent(10) && \ 145 ruby_debug_print_value(10, compile_debug, (header), (value))) 147 #define debug_node_start(node) ((void) \ 148 (compile_debug_print_indent(1) && \ 149 (ruby_debug_print_node(1, CPDEBUG, "", (NODE *)(node)), gl_node_level)), \ 152 #define debug_node_end() gl_node_level -- 156 #define debugi(header, id) ((void)0) 157 #define debugp(header, value) ((void)0) 158 #define debugp_verbose(header, value) ((void)0) 159 #define debugp_verbose_node(header, value) ((void)0) 160 #define debugp_param(header, value) ((void)0) 161 #define debug_node_start(node) ((void)0) 162 #define debug_node_end() ((void)0) 165 #if CPDEBUG > 1 || CPDEBUG < 0 166 #define printf ruby_debug_printf 167 #define debugs if (compile_debug_print_indent(1)) ruby_debug_printf 168 #define debug_compile(msg, v) ((void)(compile_debug_print_indent(1) && fputs((msg), stderr)), (v)) 170 #define debugs if(0)printf 171 #define debug_compile(msg, v) (v) 174 #define LVAR_ERRINFO (1) 177 #define NEW_LABEL(l) new_label_body(iseq, (l)) 178 #define LABEL_FORMAT "<L%03d>" 180 #define NEW_ISEQ(node, name, type, line_no) \ 181 new_child_iseq(iseq, (node), rb_fstring(name), 0, (type), (line_no)) 183 #define NEW_CHILD_ISEQ(node, name, type, line_no) \ 184 new_child_iseq(iseq, (node), rb_fstring(name), iseq, (type), (line_no)) 187 #define ADD_SEQ(seq1, seq2) \ 188 APPEND_LIST((seq1), (seq2)) 191 #define ADD_INSN(seq, line, insn) \ 192 ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0)) 195 #define INSERT_BEFORE_INSN(prev, line, insn) \ 196 INSERT_ELEM_PREV(&(prev)->link, (LINK_ELEMENT *) new_insn_body(iseq, (line), BIN(insn), 0)) 199 #define ADD_INSN1(seq, line, insn, op1) \ 200 ADD_ELEM((seq), (LINK_ELEMENT *) \ 201 new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1))) 204 #define INSERT_BEFORE_INSN1(prev, line, insn, op1) \ 205 INSERT_ELEM_PREV(&(prev)->link, (LINK_ELEMENT *) \ 206 new_insn_body(iseq, (line), BIN(insn), 1, (VALUE)(op1))) 208 #define LABEL_REF(label) ((label)->refcnt++) 211 #define ADD_INSNL(seq, line, insn, label) (ADD_INSN1(seq, line, insn, label), LABEL_REF(label)) 213 #define ADD_INSN2(seq, line, insn, op1, op2) \ 214 ADD_ELEM((seq), (LINK_ELEMENT *) \ 215 new_insn_body(iseq, (line), BIN(insn), 2, (VALUE)(op1), (VALUE)(op2))) 217 #define ADD_INSN3(seq, line, insn, op1, op2, op3) \ 218 ADD_ELEM((seq), (LINK_ELEMENT *) \ 219 new_insn_body(iseq, (line), BIN(insn), 3, (VALUE)(op1), (VALUE)(op2), (VALUE)(op3))) 222 #define ADD_SEND(seq, line, id, argc) \ 223 ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)INT2FIX(0), NULL) 225 #define ADD_SEND_WITH_FLAG(seq, line, id, argc, flag) \ 226 ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)(flag), NULL) 228 #define ADD_SEND_WITH_BLOCK(seq, line, id, argc, block) \ 229 ADD_SEND_R((seq), (line), (id), (argc), (block), (VALUE)INT2FIX(0), NULL) 231 #define ADD_CALL_RECEIVER(seq, line) \ 232 ADD_INSN((seq), (line), putself) 234 #define ADD_CALL(seq, line, id, argc) \ 235 ADD_SEND_R((seq), (line), (id), (argc), NULL, (VALUE)INT2FIX(VM_CALL_FCALL), NULL) 237 #define ADD_CALL_WITH_BLOCK(seq, line, id, argc, block) \ 238 ADD_SEND_R((seq), (line), (id), (argc), (block), (VALUE)INT2FIX(VM_CALL_FCALL), NULL) 240 #define ADD_SEND_R(seq, line, id, argc, block, flag, keywords) \ 241 ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_send(iseq, (line), (id), (VALUE)(argc), (block), (VALUE)(flag), (keywords))) 243 #define ADD_TRACE_LINE_COVERAGE(seq, line) \ 245 if (ISEQ_COVERAGE(iseq) && \ 246 ISEQ_LINE_COVERAGE(iseq) && \ 248 (line) != ISEQ_COMPILE_DATA(iseq)->last_coverable_line) { \ 249 RARRAY_ASET(ISEQ_LINE_COVERAGE(iseq), (line) - 1, INT2FIX(0)); \ 250 ISEQ_COMPILE_DATA(iseq)->last_coverable_line = (line); \ 251 ADD_INSN2((seq), (line), trace2, INT2FIX(RUBY_EVENT_COVERAGE), INT2FIX(COVERAGE_INDEX_LINES)); \ 254 #define DECL_BRANCH_BASE(branches, line, type) \ 256 if (ISEQ_COVERAGE(iseq) && \ 257 ISEQ_BRANCH_COVERAGE(iseq) && \ 259 VALUE structure = RARRAY_AREF(ISEQ_BRANCH_COVERAGE(iseq), 0); \ 260 branches = rb_ary_tmp_new(0); \ 261 rb_ary_push(structure, branches); \ 262 rb_ary_push(branches, ID2SYM(rb_intern(type))); \ 263 rb_ary_push(branches, INT2FIX(line)); \ 266 #define ADD_TRACE_BRANCH_COVERAGE(seq, line, type, branches) \ 268 if (ISEQ_COVERAGE(iseq) && \ 269 ISEQ_BRANCH_COVERAGE(iseq) && \ 271 VALUE counters = RARRAY_AREF(ISEQ_BRANCH_COVERAGE(iseq), 1); \ 272 long counter_idx = RARRAY_LEN(counters); \ 273 rb_ary_push(counters, INT2FIX(0)); \ 274 rb_ary_push(branches, ID2SYM(rb_intern(type))); \ 275 rb_ary_push(branches, INT2FIX(line)); \ 276 rb_ary_push(branches, INT2FIX(counter_idx)); \ 277 ADD_INSN2((seq), (line), trace2, INT2FIX(RUBY_EVENT_COVERAGE), INT2FIX(counter_idx * 16 + COVERAGE_INDEX_BRANCHES)); \ 280 #define ADD_TRACE_METHOD_COVERAGE(seq, line, method_name) \ 282 if (ISEQ_COVERAGE(iseq) && \ 283 ISEQ_METHOD_COVERAGE(iseq) && \ 285 VALUE methods = ISEQ_METHOD_COVERAGE(iseq); \ 286 long counter_idx = RARRAY_LEN(methods) / 3; \ 287 rb_ary_push(methods, ID2SYM(method_name)); \ 288 rb_ary_push(methods, INT2FIX(line)); \ 289 rb_ary_push(methods, INT2FIX(0)); \ 290 ADD_INSN2((seq), (line), trace2, INT2FIX(RUBY_EVENT_COVERAGE), INT2FIX(counter_idx * 16 + COVERAGE_INDEX_METHODS)); \ 294 #define ADD_TRACE(seq, line, event) \ 296 if (ISEQ_COMPILE_DATA(iseq)->option->trace_instruction) { \ 297 ADD_INSN1((seq), (line), trace, INT2FIX(event)); \ 301 #define ADD_GETLOCAL(seq, line, idx, level) \ 303 ADD_INSN2((seq), (line), getlocal, INT2FIX((idx) + VM_ENV_DATA_SIZE - 1), INT2FIX(level)); \ 306 #define ADD_SETLOCAL(seq, line, idx, level) \ 308 ADD_INSN2((seq), (line), setlocal, INT2FIX((idx) + VM_ENV_DATA_SIZE - 1), INT2FIX(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); \ 331 LABEL_UNREMOVABLE(le); \ 332 LABEL_UNREMOVABLE(lc); \ 333 rb_ary_push(ISEQ_COMPILE_DATA(iseq)->catch_table_ary, freeze_hide_obj(_e)); \ 337 #define COMPILE(anchor, desc, node) \ 338 (debug_compile("== " desc "\n", \ 339 iseq_compile_each(iseq, (anchor), (node), 0))) 342 #define COMPILE_POPPED(anchor, desc, node) \ 343 (debug_compile("== " desc "\n", \ 344 iseq_compile_each(iseq, (anchor), (node), 1))) 347 #define COMPILE_(anchor, desc, node, popped) \ 348 (debug_compile("== " desc "\n", \ 349 iseq_compile_each(iseq, (anchor), (node), (popped)))) 351 #define COMPILE_RECV(anchor, desc, node) \ 352 (private_recv_p(node) ? \ 353 (ADD_INSN(anchor, nd_line(node), putself), VM_CALL_FCALL) : \ 354 (COMPILE(anchor, desc, node->nd_recv), 0)) 356 #define OPERAND_AT(insn, idx) \ 357 (((INSN*)(insn))->operands[(idx)]) 359 #define INSN_OF(insn) \ 360 (((INSN*)(insn))->insn_id) 362 #define IS_INSN(link) ((link)->type == ISEQ_ELEMENT_INSN) 363 #define IS_LABEL(link) ((link)->type == ISEQ_ELEMENT_LABEL) 364 #define IS_ADJUST(link) ((link)->type == ISEQ_ELEMENT_ADJUST) 365 #define IS_INSN_ID(iobj, insn) (INSN_OF(iobj) == BIN(insn)) 366 #define IS_NEXT_INSN_ID(link, insn) \ 367 ((link)->next && IS_INSN((link)->next) && IS_INSN_ID((link)->next, insn)) 371 NORETURN(
static void append_compile_error(
rb_iseq_t *iseq,
int line,
const char *fmt, ...));
375 append_compile_error(
rb_iseq_t *iseq,
int line,
const char *fmt, ...)
385 if (
NIL_P(err_info)) {
389 else if (!err_info) {
397 compile_bug(
rb_iseq_t *iseq,
int line,
const char *fmt, ...)
407 #define COMPILE_ERROR append_compile_error 409 #define ERROR_ARGS_AT(n) iseq, nd_line(n), 410 #define ERROR_ARGS ERROR_ARGS_AT(node) 412 #define EXPECT_NODE(prefix, node, ndtype, errval) \ 414 NODE *error_node = (node); \ 415 enum node_type error_type = nd_type(error_node); \ 416 if (error_type != (ndtype)) { \ 417 COMPILE_ERROR(ERROR_ARGS_AT(error_node) \ 418 prefix ": " #ndtype " is expected, but %s", \ 419 ruby_node_name(error_type)); \ 424 #define EXPECT_NODE_NONULL(prefix, parent, ndtype, errval) \ 426 COMPILE_ERROR(ERROR_ARGS_AT(parent) \ 427 prefix ": must be " #ndtype ", but 0"); \ 431 #define UNKNOWN_NODE(prefix, node, errval) \ 433 NODE *error_node = (node); \ 434 COMPILE_ERROR(ERROR_ARGS_AT(error_node) prefix ": unknown node (%s)", \ 435 ruby_node_name(nd_type(error_node))); \ 442 #define CHECK(sub) if (!(sub)) {BEFORE_RETURN;return COMPILE_NG;} 443 #define BEFORE_RETURN 447 #define DECL_ANCHOR(name) \ 448 LINK_ANCHOR name[1] = {{{0,},}} 449 #define INIT_ANCHOR(name) \ 450 (name->last = &name->anchor) 453 freeze_hide_obj(
VALUE obj)
460 #include "optinsn.inc" 461 #if OPT_INSTRUCTIONS_UNIFICATION 462 #include "optunifs.inc" 467 #define ISEQ_ARG iseq, 468 #define ISEQ_ARG_DECLARE rb_iseq_t *iseq, 471 #define ISEQ_ARG_DECLARE 475 #define gl_node_level ISEQ_COMPILE_DATA(iseq)->node_level 481 static int insn_data_length(
INSN *iobj);
482 static int calc_sp_depth(
int depth,
INSN *iobj);
484 static INSN *new_insn_body(
rb_iseq_t *iseq,
int line_no,
enum ruby_vminsn_type insn_id,
int argc, ...);
493 static int iseq_set_local_table(
rb_iseq_t *iseq,
const ID *tbl);
494 static int iseq_set_exception_local_table(
rb_iseq_t *iseq);
499 static int iseq_set_exception_table(
rb_iseq_t *iseq);
500 static int iseq_set_optargs_table(
rb_iseq_t *iseq);
520 if (plist != list->
prev) {
527 if (anchor->
last != plist && anchor->
last != 0) {
532 rb_bug(
"list verify error: %08x (%s)", flag, info);
537 #define verify_list(info, anchor) verify_list(iseq, (info), (anchor)) 546 elem->
prev = anchor->last;
547 anchor->last->
next = elem;
549 verify_list(
"add", anchor);
562 if (before == anchor->last) anchor->last = elem;
563 verify_list(
"add", anchor);
566 #define ADD_ELEM(anchor, elem) ADD_ELEM(iseq, (anchor), (elem)) 567 #define APPEND_ELEM(anchor, before, elem) APPEND_ELEM(iseq, (anchor), (before), (elem)) 618 iseq_set_local_table(iseq, 0);
622 iseq_set_local_table(iseq, node->nd_tbl);
623 iseq_set_arguments(iseq, ret, node->nd_args);
626 case ISEQ_TYPE_BLOCK:
645 case ISEQ_TYPE_CLASS:
652 case ISEQ_TYPE_METHOD:
669 (*ifunc->
func)(iseq, ret, ifunc->
data);
673 case ISEQ_TYPE_METHOD:
674 case ISEQ_TYPE_CLASS:
675 case ISEQ_TYPE_BLOCK:
682 case ISEQ_TYPE_RESCUE:
683 iseq_set_exception_local_table(iseq);
686 case ISEQ_TYPE_ENSURE:
687 iseq_set_exception_local_table(iseq);
690 case ISEQ_TYPE_DEFINED_GUARD:
691 iseq_set_exception_local_table(iseq);
700 if (iseq->
body->
type == ISEQ_TYPE_RESCUE || iseq->
body->
type == ISEQ_TYPE_ENSURE) {
712 validate_labels(iseq, labels_table);
715 return iseq_setup(iseq, ret);
721 #if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE 728 int len = insn_len(insn);
729 encoded[i] = (
VALUE)table[insn];
736 #if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE 738 rb_vm_insn_addr2insn(
const void *addr)
743 for (insn = 0; insn < VM_INSTRUCTION_SIZE; insn++) {
744 if (table[insn] == addr) {
748 rb_bug(
"rb_vm_insn_addr2insn: invalid insn address: %p", addr);
755 VALUE *original_code;
757 if (ISEQ_ORIGINAL_ISEQ(iseq))
return ISEQ_ORIGINAL_ISEQ(iseq);
758 original_code = ISEQ_ORIGINAL_ISEQ_ALLOC(iseq, iseq->
body->
iseq_size);
761 #if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE 766 const void *addr = (
const void *)original_code[i];
767 const int insn = rb_vm_insn_addr2insn(addr);
769 original_code[i] = insn;
774 return original_code;
787 #if defined(__sparc) && SIZEOF_VOIDP == 4 && defined(__GNUC__) 788 #define STRICT_ALIGNMENT 791 #ifdef STRICT_ALIGNMENT 792 #if defined(HAVE_TRUE_LONG_LONG) && SIZEOF_LONG_LONG > SIZEOF_VALUE 793 #define ALIGNMENT_SIZE SIZEOF_LONG_LONG 795 #define ALIGNMENT_SIZE SIZEOF_VALUE 797 #define PADDING_SIZE_MAX ((size_t)((ALIGNMENT_SIZE) - 1)) 798 #define ALIGNMENT_SIZE_MASK PADDING_SIZE_MAX 801 #define PADDING_SIZE_MAX 0 804 #ifdef STRICT_ALIGNMENT 807 calc_padding(
void *ptr,
size_t size)
812 mis = (size_t)ptr & ALIGNMENT_SIZE_MASK;
814 padding = ALIGNMENT_SIZE - mis;
820 #if ALIGNMENT_SIZE > SIZEOF_VALUE 821 if (size ==
sizeof(
VALUE) && padding ==
sizeof(
VALUE)) {
836 #ifdef STRICT_ALIGNMENT 837 size_t padding = calc_padding((
void *)&storage->
buff[storage->
pos], size);
839 const size_t padding = 0;
843 if (storage->
pos + size + padding > storage->
size) {
844 unsigned int alloc_size = storage->
size;
855 storage->
size = alloc_size;
856 #ifdef STRICT_ALIGNMENT 857 padding = calc_padding((
void *)&storage->
buff[storage->
pos], size);
861 #ifdef STRICT_ALIGNMENT 862 storage->
pos += (int)padding;
865 ptr = (
void *)&storage->
buff[storage->
pos];
873 return (
INSN *)compile_data_alloc(iseq,
sizeof(
INSN));
877 compile_data_alloc_label(
rb_iseq_t *iseq)
879 return (
LABEL *)compile_data_alloc(iseq,
sizeof(
LABEL));
883 compile_data_alloc_adjust(
rb_iseq_t *iseq)
885 return (
ADJUST *)compile_data_alloc(iseq,
sizeof(
ADJUST));
957 anchor->last = anchor->last->
prev;
958 anchor->last->
next = 0;
959 verify_list(
"pop", anchor);
963 #define POP_ELEMENT(anchor) POP_ELEMENT(iseq, (anchor)) 990 anc1->last = anc2->
last;
992 verify_list(
"append", anc1);
995 #define APPEND_LIST(anc1, anc2) APPEND_LIST(iseq, (anc1), (anc2)) 1011 anc1->anchor.
next->
prev = &anc1->anchor;
1017 anc1->last = anc2->
last;
1021 verify_list(
"append", anc1);
1024 #define INSERT_LIST(anc1, anc2) INSERT_LIST(iseq, (anc1), (anc2)) 1033 printf(
"anch: %p, frst: %p, last: %p\n", &anchor->anchor,
1034 anchor->anchor.next, anchor->last);
1036 printf(
"curr: %p, next: %p, prev: %p, type: %d\n", list, list->
next,
1042 dump_disasm_list(anchor->anchor.next);
1043 verify_list(
"debug list", anchor);
1046 #define debug_list(anc) debug_list(iseq, (anc)) 1049 #define debug_list(anc) ((void)0) 1053 new_label_body(
rb_iseq_t *iseq,
long line)
1055 LABEL *labelobj = compile_data_alloc_label(iseq);
1073 ADJUST *adjust = compile_data_alloc_adjust(iseq);
1076 adjust->
label = label;
1083 new_insn_core(
rb_iseq_t *iseq,
int line_no,
1086 INSN *iobj = compile_data_alloc_insn(iseq);
1100 new_insn_body(
rb_iseq_t *iseq,
int line_no,
enum ruby_vminsn_type insn_id,
int argc, ...)
1102 VALUE *operands = 0;
1107 operands = (
VALUE *)compile_data_alloc(iseq,
sizeof(
VALUE) *
argc);
1108 for (i = 0; i <
argc; i++) {
1114 return new_insn_core(iseq, line_no, insn_id, argc, operands);
1121 struct
rb_call_info *
ci = (struct rb_call_info *)compile_data_alloc(iseq, size);
1126 ci->orig_argc = argc;
1130 ci_kw->kw_arg = kw_arg;
1139 kw_arg ==
NULL && !has_blockiseq) {
1148 VALUE *operands = (
VALUE *)compile_data_alloc(iseq,
sizeof(
VALUE) * 3);
1151 operands[2] = (
VALUE)blockiseq;
1152 return new_insn_core(iseq, line_no, BIN(send), 3, operands);
1161 debugs(
"[new_child_iseq]> ---------------------------------------\n");
1165 debugs(
"[new_child_iseq]< ---------------------------------------\n");
1166 iseq_add_mark_object(iseq, (
VALUE)ret_iseq);
1179 dump_disasm_list(FIRST_ELEMENT(anchor));
1181 debugs(
"[compile step 3.1 (iseq_optimize)]\n");
1182 iseq_optimize(iseq, anchor);
1185 dump_disasm_list(FIRST_ELEMENT(anchor));
1188 debugs(
"[compile step 3.2 (iseq_insns_unification)]\n");
1189 iseq_insns_unification(iseq, anchor);
1191 dump_disasm_list(FIRST_ELEMENT(anchor));
1195 debugs(
"[compile step 3.3 (iseq_set_sequence_stackcaching)]\n");
1196 iseq_set_sequence_stackcaching(iseq, anchor);
1198 dump_disasm_list(FIRST_ELEMENT(anchor));
1201 debugs(
"[compile step 4.1 (iseq_set_sequence)]\n");
1202 if (!iseq_set_sequence(iseq, anchor))
return COMPILE_NG;
1204 dump_disasm_list(FIRST_ELEMENT(anchor));
1206 debugs(
"[compile step 4.2 (iseq_set_exception_table)]\n");
1207 if (!iseq_set_exception_table(iseq))
return COMPILE_NG;
1209 debugs(
"[compile step 4.3 (set_optargs_table)] \n");
1210 if (!iseq_set_optargs_table(iseq))
return COMPILE_NG;
1212 debugs(
"[compile step 5 (iseq_translate_threaded_code)] \n");
1219 debugs(
"[compile step: finish]\n");
1225 iseq_set_exception_local_table(
rb_iseq_t *iseq)
1235 ids[0] = id_dollar_bang;
1252 get_dyna_var_idx_at_raw(
const rb_iseq_t *iseq,
ID id)
1270 rb_bug(
"get_local_var_idx: %d", idx);
1279 int lv = 0, idx = -1;
1282 idx = get_dyna_var_idx_at_raw(iseq,
id);
1291 rb_bug(
"get_dyna_var_idx: -1");
1341 struct rb_iseq_param_keyword *keyword;
1344 int kw = 0, rkw = 0, di = 0, i;
1348 keyword->bits_start = get_dyna_var_idx_at_raw(iseq, args->
kw_rest_arg->nd_cflag);
1351 NODE *val_node = node->nd_body->nd_value;
1354 if (val_node == (
NODE *)-1) {
1360 dv = val_node->nd_lit;
1361 iseq_add_mark_object(iseq, dv);
1377 keyword->num = ++di;
1382 node = node->nd_next;
1388 keyword->rest_start = get_dyna_var_idx_at_raw(iseq, args->
kw_rest_arg->nd_vid);
1391 keyword->required_num = rkw;
1392 keyword->table = &iseq->
body->
local_table[keyword->bits_start - keyword->num];
1397 for (i = 0; i <
RARRAY_LEN(default_values); i++) {
1399 if (dv == complex_mark) dv =
Qundef;
1403 keyword->default_values = dvs;
1410 debugs(
"iseq_set_arguments: %s\n", node_args ?
"" :
"0");
1449 node = node->nd_next;
1461 for (j = 0; j < i+1; j++) {
1472 iseq_set_arguments_keywords(iseq, optargs, args);
1475 struct rb_iseq_param_keyword *keyword =
ZALLOC_N(
struct rb_iseq_param_keyword, 1);
1476 keyword->rest_start = get_dyna_var_idx_at_raw(iseq, args->
kw_rest_arg->nd_vid);
1503 iseq_calc_param_size(iseq);
1505 if (iseq->
body->
type == ISEQ_TYPE_BLOCK) {
1524 iseq_set_local_table(
rb_iseq_t *iseq,
const ID *tbl)
1529 size = (
unsigned int)*tbl;
1550 if (val == lit)
return 0;
1560 return !
rb_eql(lit, val);
1564 cdhash_hash(
VALUE a)
1614 #define BADINSN_DUMP(anchor, list, dest) \ 1615 dump_disasm_list_with_cursor(&anchor->anchor, list, dest) 1617 #define BADINSN_ERROR \ 1618 (xfree(generated_iseq), \ 1619 xfree(line_info_table), \ 1620 BADINSN_DUMP(anchor, list, NULL), \ 1626 int stack_max = 0, sp = 0, line = 0;
1629 for (list = FIRST_ELEMENT(anchor);
list; list = list->
next) {
1636 for (list = FIRST_ELEMENT(anchor);
list; list = list->
next) {
1637 switch (list->
type) {
1646 sp = calc_sp_depth(sp, iobj);
1650 "argument stack underflow (%d)", sp);
1653 if (sp > stack_max) {
1661 types = insn_op_types(insn);
1662 len = insn_len(insn);
1669 "operand size miss! (%d for %d)",
1674 for (j = 0; types[j]; j++) {
1675 if (types[j] == TS_OFFSET) {
1684 if (lobj->
sp == -1) {
1694 if (lobj->
sp == -1) {
1713 if (adjust->
line_no != -1 && orig_sp - sp < 0) {
1716 "iseq_set_sequence: adjust bug %d < %d",
1738 unsigned int last_line = 0;
1740 VALUE *generated_iseq;
1742 int insn_num, code_index, line_info_index, sp = 0;
1743 int stack_max = fix_sp_depth(iseq, anchor);
1748 list = FIRST_ELEMENT(anchor);
1749 insn_num = code_index = 0;
1751 switch (list->
type) {
1756 sp = calc_sp_depth(sp, iobj);
1757 code_index += insn_data_length(iobj);
1779 if (orig_sp - sp > 0) {
1780 if (orig_sp - sp > 1) code_index++;
1801 list = FIRST_ELEMENT(anchor);
1802 line_info_index = code_index = sp = 0;
1805 switch (list->
type) {
1814 sp = calc_sp_depth(sp, iobj);
1818 generated_iseq[code_index] = insn;
1819 types = insn_op_types(insn);
1820 len = insn_len(insn);
1822 for (j = 0; types[j]; j++) {
1823 char type = types[j];
1830 generated_iseq[code_index + 1 + j] = lobj->
position - (code_index +
len);
1835 VALUE map = operands[j];
1838 data.
pos = code_index;
1843 freeze_hide_obj(map);
1844 generated_iseq[code_index + 1 + j] = map;
1849 generated_iseq[code_index + 1 + j] =
FIX2INT(operands[j]);
1853 VALUE v = operands[j];
1854 generated_iseq[code_index + 1 + j] = v;
1859 VALUE v = operands[j];
1860 generated_iseq[code_index + 1 + j] = v;
1862 iseq_add_mark_object(iseq, v);
1867 unsigned int ic_index =
FIX2UINT(operands[j]);
1870 rb_bug(
"iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, iseq->
body->
is_size);
1872 generated_iseq[code_index + 1 + j] = (
VALUE)ic;
1893 generated_iseq[code_index + 1 + j] = (
VALUE)ci;
1899 generated_iseq[code_index + 1 + j] = (
VALUE)cc;
1903 generated_iseq[code_index + 1 + j] =
SYM2ID(operands[j]);
1909 generated_iseq[code_index + 1 + j] = (
VALUE)entry;
1913 generated_iseq[code_index + 1 + j] = operands[j];
1917 "unknown operand type: %c", type);
1921 if (last_line != iobj->
line_no) {
1922 line_info_table[line_info_index].
line_no = last_line = iobj->
line_no;
1923 line_info_table[line_info_index].
position = code_index;
1940 if (adjust->
label) {
1948 const int diff = orig_sp - sp;
1950 if (last_line != (
unsigned int)adjust->
line_no) {
1951 line_info_table[line_info_index].
line_no = last_line = adjust->
line_no;
1952 line_info_table[line_info_index].
position = code_index;
1957 generated_iseq[code_index++] = BIN(adjuststack);
1958 generated_iseq[code_index++] = orig_sp - sp;
1960 else if (diff == 1) {
1961 generated_iseq[code_index++] = BIN(pop);
1963 else if (diff < 0) {
1965 xfree(generated_iseq);
1966 xfree(line_info_table);
1969 "iseq_set_sequence: adjust bug to %d %d < %d",
1970 label_no, orig_sp, sp);
1998 label_get_position(
LABEL *lobj)
2004 label_get_sp(
LABEL *lobj)
2010 iseq_set_exception_table(
rb_iseq_t *iseq)
2012 const VALUE *tptr, *ptr;
2013 unsigned int tlen, i;
2020 struct iseq_catch_table *table =
xmalloc(iseq_catch_table_bytes(tlen));
2023 for (i = 0; i < table->size; i++) {
2025 entry = &table->entries[i];
2026 entry->
type = (
enum catch_type)(ptr[0] & 0xffff);
2027 entry->
start = label_get_position((
LABEL *)(ptr[1] & ~1));
2028 entry->
end = label_get_position((
LABEL *)(ptr[2] & ~1));
2032 if (entry->
iseq != 0) {
2033 iseq_add_mark_object(iseq, (
VALUE)entry->
iseq);
2039 entry->
cont = label_get_position(lobj);
2040 entry->
sp = label_get_sp(lobj);
2043 if (entry->
type == CATCH_TYPE_RESCUE ||
2044 entry->
type == CATCH_TYPE_BREAK ||
2045 entry->
type == CATCH_TYPE_NEXT) {
2080 opt_table[i] = label_get_position((
LABEL *)opt_table[i]);
2087 get_destination_insn(
INSN *iobj)
2103 get_next_insn(
INSN *iobj)
2117 get_prev_insn(
INSN *iobj)
2131 unref_destination(
INSN *iobj,
int pos)
2139 replace_destination(
INSN *dobj,
INSN *nobj)
2163 if (((
LABEL *)i)->unremovable)
return 0;
2164 if (((
LABEL *)i)->refcnt > 0) {
2165 if (i == first)
return 0;
2179 int pos,
len = insn_len(insn);
2180 for (pos = 0; pos <
len; ++pos) {
2181 switch (insn_op_types(insn)[pos]) {
2183 unref_destination((
INSN *)i, pos);
2195 }
while ((i != end) && (i = i->
next) != 0);
2204 REMOVE_ELEM(&iobj->
link);
2207 REMOVE_ELEM(&iobj->
link);
2210 iobj->
insn_id = BIN(adjuststack);
2221 INSN *niobj, *diobj, *piobj;
2222 diobj = (
INSN *)get_destination_insn(iobj);
2223 niobj = (
INSN *)get_next_insn(iobj);
2225 if (diobj == niobj) {
2232 unref_destination(iobj, 0);
2233 REMOVE_ELEM(&iobj->
link);
2236 else if (iobj != diobj &&
IS_INSN_ID(diobj, jump) &&
2248 replace_destination(iobj, diobj);
2249 remove_unreachable_chunk(iseq, iobj->
link.
next);
2264 INSN *popiobj = new_insn_core(iseq, iobj->
line_no,
2267 unref_destination(iobj, 0);
2270 INSERT_ELEM_NEXT(&iobj->
link, &popiobj->
link);
2273 else if ((piobj = (
INSN *)get_prev_insn(iobj)) != 0 &&
2276 INSN *pdiobj = (
INSN *)get_destination_insn(piobj);
2277 if (niobj == pdiobj) {
2293 ? BIN(branchunless) : BIN(branchif);
2294 replace_destination(piobj, iobj);
2295 REMOVE_ELEM(&iobj->
link);
2298 else if (diobj == pdiobj) {
2312 INSN *popiobj = new_insn_core(iseq, iobj->
line_no,
2314 REPLACE_ELEM(&piobj->
link, &popiobj->
link);
2317 if (remove_unreachable_chunk(iseq, iobj->
link.
next)) {
2336 (end = (
INSN *)get_prev_insn(range)) != 0 &&
2338 (beg = (
INSN *)get_prev_insn(end)) != 0 &&
2345 iseq_add_mark_object_compile_time(iseq, lit_range);
2346 REMOVE_ELEM(&beg->
link);
2347 REMOVE_ELEM(&end->
link);
2348 range->
insn_id = BIN(putobject);
2354 remove_unreachable_chunk(iseq, iobj->
link.
next);
2368 INSN *nobj = (
INSN *)get_destination_insn(iobj);
2380 replace_destination(iobj, nobj);
2382 else if (prev_dup &&
IS_INSN_ID(nobj, dup) &&
2401 replace_destination(iobj, nobj);
2448 if (prev_dup || !
IS_INSN_ID(pobj, newarray)) {
2451 else if (!iseq_pop_newarray(iseq, pobj)) {
2452 pobj = new_insn_core(iseq, pobj->
line_no, BIN(pop), 0,
NULL);
2453 INSERT_ELEM_NEXT(&iobj->
link, &pobj->
link);
2460 unref_destination(iobj, 0);
2461 REMOVE_ELEM(&iobj->
link);
2466 nobj = (
INSN *)get_destination_insn(nobj);
2479 enum ruby_vminsn_type previ = ((
INSN *)prev)->insn_id;
2480 if (previ == BIN(putobject) || previ == BIN(putnil) ||
2481 previ == BIN(putself) || previ == BIN(putstring) ||
2482 previ == BIN(duparray)) {
2486 REMOVE_ELEM(&iobj->
link);
2488 else if (previ == BIN(newarray) && iseq_pop_newarray(iseq, (
INSN*)prev)) {
2489 REMOVE_ELEM(&iobj->
link);
2522 if (do_tailcallopt &&
2552 next = get_destination_insn((
INSN *)next);
2584 REMOVE_ELEM(&iobj->
link);
2592 REMOVE_ELEM(set1->
next);
2605 REMOVE_ELEM(&iobj->
link);
2610 #define IS_TRACE_LINE(insn) \ 2611 (IS_INSN_ID(insn, trace) && \ 2612 OPERAND_AT(insn, 0) == INT2FIX(RUBY_EVENT_LINE)) 2624 insn_set_specialized_instruction(
rb_iseq_t *iseq,
INSN *iobj,
int insn_id)
2629 if (insn_id == BIN(opt_neq)) {
2633 iobj->
operands[0] = old_operands[0];
2656 iobj->
insn_id = BIN(opt_newarray_max);
2657 REMOVE_ELEM(&niobj->
link);
2660 iobj->
insn_id = BIN(opt_newarray_min);
2661 REMOVE_ELEM(&niobj->
link);
2672 #define SP_INSN(opt) insn_set_specialized_instruction(iseq, iobj, BIN(opt_##opt)) 2710 iobj->
insn_id = BIN(opt_send_without_block);
2724 case ISEQ_TYPE_EVAL:
2725 case ISEQ_TYPE_MAIN:
2727 case ISEQ_TYPE_RESCUE:
2728 case ISEQ_TYPE_ENSURE:
2740 const int do_peepholeopt =
ISEQ_COMPILE_DATA(iseq)->option->peephole_optimization;
2741 const int do_tailcallopt = tailcallable_p(iseq) &&
2745 int rescue_level = 0;
2746 int tailcallopt = do_tailcallopt;
2748 list = FIRST_ELEMENT(anchor);
2752 if (do_peepholeopt) {
2753 iseq_peephole_optimize(iseq, list, tailcallopt);
2756 iseq_specialized_instruction(iseq, (
INSN *)list);
2759 insn_operands_unification((
INSN *)list);
2763 switch (((
LABEL *)list)->rescued) {
2766 tailcallopt =
FALSE;
2769 if (!--rescue_level) tailcallopt = do_tailcallopt;
2778 #if OPT_INSTRUCTIONS_UNIFICATION 2786 VALUE *operands = 0, *ptr = 0;
2790 for (i = 0; i <
size; i++) {
2791 iobj = (
INSN *)list;
2803 for (i = 0; i <
size; i++) {
2804 iobj = (
INSN *)list;
2810 return new_insn_core(iseq, iobj->
line_no, insn_id, argc, operands);
2822 #if OPT_INSTRUCTIONS_UNIFICATION 2828 list = FIRST_ELEMENT(anchor);
2831 iobj = (
INSN *)list;
2833 if (unified_insns_data[
id] != 0) {
2834 const int *
const *entry = unified_insns_data[
id];
2835 for (j = 1; j < (
intptr_t)entry[0]; j++) {
2836 const int *unified = entry[j];
2838 for (k = 2; k < unified[1]; k++) {
2840 ((
INSN *)li)->insn_id != unified[k]) {
2847 new_unified_insn(iseq, unified[0], unified[1] - 1,
2870 #if OPT_STACK_CACHING 2872 #define SC_INSN(insn, stat) sc_insn_info[(insn)][(stat)] 2873 #define SC_NEXT(insn) sc_insn_next[(insn)] 2875 #include "opt_sc.inc" 2884 iobj->
insn_id = SC_INSN(insn_id, state);
2885 nstate = SC_NEXT(iobj->
insn_id);
2887 if (insn_id == BIN(jump) ||
2888 insn_id == BIN(branchif) || insn_id == BIN(branchunless)) {
2904 if (insn_id == BIN(jump)) {
2908 else if (insn_id == BIN(leave)) {
2916 label_set_sc_state(
LABEL *lobj,
int state)
2936 #if OPT_STACK_CACHING 2942 list = FIRST_ELEMENT(anchor);
2948 switch (list->
type) {
2960 if (state != SCS_AX) {
2962 new_insn_body(iseq, 0, BIN(reput), 0);
2973 if (state == SCS_AB || state == SCS_BA) {
2974 state = (state == SCS_AB ? SCS_BA : SCS_AB);
3011 state = insn_set_sc_state(iseq, anchor, iobj, state);
3017 lobj = (
LABEL *)list;
3019 state = label_set_sc_state(lobj, state);
3033 NODE *list = node->nd_next;
3034 VALUE lit = node->nd_lit;
3048 if (
RSTRING_LEN(lit) == 0) first_lit = LAST_ELEMENT(ret);
3052 node = list->nd_head;
3062 list = list->nd_next;
3064 if (
NIL_P(lit) && first_lit) {
3065 REMOVE_ELEM(first_lit);
3077 CHECK(compile_dstr_fragments(iseq, ret, node, &cnt));
3086 CHECK(compile_dstr_fragments(iseq, ret, node, &cnt));
3095 const int line =
nd_line(node);
3106 ADD_INSNL(ret, line, branchunless, else_label);
3116 ADD_INSNL(ret, line, branchunless, then_label);
3133 CHECK(compile_branch_condition(iseq, ret, cond->nd_1st, label,
3135 if (!label->
refcnt)
break;
3137 cond = cond->nd_2nd;
3143 CHECK(compile_branch_condition(iseq, ret, cond->nd_1st, then_label,
3145 if (!label->
refcnt)
break;
3147 cond = cond->nd_2nd;
3164 CHECK(compile_flip_flop(iseq, ret, cond,
TRUE, then_label, else_label));
3167 CHECK(compile_flip_flop(iseq, ret, cond,
FALSE, then_label, else_label));
3170 CHECK(compile_defined_expr(iseq, ret, cond,
Qfalse));
3184 const NODE *
const root_node,
3191 NODE *node = root_node->nd_head;
3194 NODE *key_node = node->nd_head;
3207 node = node->nd_next;
3208 node = node->nd_next;
3212 node = root_node->nd_head;
3214 int len = (int)node->nd_alen / 2;
3220 *kw_arg_ptr = kw_arg;
3222 for (i=0; node !=
NULL; i++, node = node->nd_next->nd_next) {
3223 NODE *key_node = node->nd_head;
3224 NODE *val_node = node->nd_next->nd_head;
3225 keywords[i] = key_node->nd_lit;
3226 COMPILE(ret,
"keyword values", val_node);
3242 static_literal_node_p(
NODE *node)
3244 node = node->nd_head;
3257 static_literal_value(
NODE *node)
3259 node = node->nd_head;
3268 return node->nd_lit;
3275 unsigned int *flag,
int popped)
3277 NODE *node = node_root;
3278 int line = (int)
nd_line(node);
3295 NODE *start_node = node, *end_node;
3297 const int max = 0x100;
3301 for (i=0; i<max && node; i++, len++, node = node->nd_next) {
3316 if (opt_p && !static_literal_node_p(node)) {
3321 node->nd_next ==
NULL &&
3322 compile_array_keyword_arg(iseq, anchor, node->nd_head, keywords_ptr, flag)) {
3326 COMPILE_(anchor,
"array element", node->nd_head, popped);
3337 while (node != end_node) {
3339 node = node->nd_next;
3341 while (node && node->nd_next &&
3342 static_literal_node_p(node) &&
3343 static_literal_node_p(node->nd_next)) {
3345 elem[0] = static_literal_value(node);
3346 elem[1] = static_literal_value(node->nd_next);
3348 node = node->nd_next->nd_next;
3354 iseq_add_mark_object_compile_time(iseq, ary);
3396 ADD_INSN(anchor, line, concatarray);
3399 APPEND_LIST(ret, anchor);
3405 APPEND_LIST(ret, anchor);
3410 APPEND_LIST(ret, anchor);
3417 if (i > 0 || !first)
ADD_INSN(ret, line, swap);
3418 COMPILE(ret,
"keyword splat", kw);
3425 APPEND_LIST(ret, anchor);
3431 APPEND_LIST(ret, anchor);
3440 case_when_optimizable_literal(
NODE *node)
3444 VALUE v = node->nd_lit;
3462 return node->nd_lit =
rb_fstring(node->nd_lit);
3469 LABEL *l1,
int only_special_literals,
VALUE literals)
3472 NODE* val = vals->nd_head;
3473 VALUE lit = case_when_optimizable_literal(val);
3476 only_special_literals = 0;
3482 "duplicated when clause is ignored");
3497 COMPILE(cond_seq,
"when cond", val);
3502 vals = vals->nd_next;
3504 return only_special_literals;
3519 iobj = (
INSN *)get_prev_insn((
INSN *)LAST_ELEMENT(ret));
3537 REMOVE_ELEM(FIRST_ELEMENT(anchor));
3545 REMOVE_ELEM(FIRST_ELEMENT(anchor));
3557 CHECK(compile_massign_opt_lhs(iseq, ret, lhsn->nd_next));
3558 CHECK(compile_massign_lhs(iseq, ret, lhsn->nd_head));
3570 int llen = 0, rlen = 0;
3572 NODE *lhsn = orig_lhsn;
3574 #define MEMORY(v) { \ 3576 if (memindex == memsize) return 0; \ 3577 for (i=0; i<memindex; i++) { \ 3578 if (mem[i] == (v)) return 0; \ 3580 mem[memindex++] = (v); \ 3588 NODE *ln = lhsn->nd_head;
3602 lhsn = lhsn->nd_next;
3611 COMPILE(ret,
"masgn val", rhsn->nd_head);
3613 rhsn = rhsn->nd_next;
3618 for (i=0; i<llen-rlen; i++) {
3623 compile_massign_opt_lhs(iseq, ret, orig_lhsn);
3631 do {
ADD_INSN(ret, line, putnil);}
while (++rlen < llen);
3633 else if (rlen > llen) {
3634 do {
ADD_INSN(ret, line, pop);}
while (--rlen > llen);
3641 NODE *rhsn = node->nd_value;
3642 NODE *splatn = node->nd_args;
3643 NODE *lhsn = node->nd_head;
3644 int lhs_splat = (splatn && (
VALUE)splatn != (
VALUE)-1) ? 1 : 0;
3646 if (!popped || splatn || !compile_massign_opt(iseq, ret, rhsn, lhsn)) {
3654 CHECK(compile_massign_lhs(iseq, lhsseq, lhsn->nd_head));
3656 lhsn = lhsn->nd_next;
3659 COMPILE(ret,
"normal masgn rhs", rhsn);
3664 else if (!lhs_splat) {
3673 adjust_stack(iseq, ret,
nd_line(node), rlen, llen);
3677 else if (llen > 2 && llen != rlen) {
3679 adjust_stack(iseq, ret,
nd_line(node), rlen, llen);
3683 else if (llen > 2) {
3698 NODE *postn = splatn->nd_2nd;
3699 NODE *restn = splatn->nd_1st;
3700 int num = (int)postn->nd_alen;
3701 int flag = 0x02 | (((
VALUE)restn == (
VALUE)-1) ? 0x00 : 0x01);
3707 CHECK(compile_massign_lhs(iseq, ret, restn));
3710 CHECK(compile_massign_lhs(iseq, ret, postn->nd_head));
3711 postn = postn->nd_next;
3716 CHECK(compile_massign_lhs(iseq, ret, splatn));
3729 debugi(
"compile_const_prefix - colon", node->nd_vid);
3733 debugi(
"compile_const_prefix - colon3", node->nd_mid);
3739 CHECK(compile_const_prefix(iseq, node->nd_head, pref, body));
3740 debugi(
"compile_const_prefix - colon2", node->nd_mid);
3758 else if (cpath->nd_head) {
3760 COMPILE(ret,
"nd_else->nd_head", cpath->nd_head);
3771 #define private_recv_p(node) (nd_type((node)->nd_recv) == NODE_SELF) 3783 switch (type =
nd_type(node)) {
3803 defined_expr0(iseq, ret, vals->nd_head, lfinish,
Qfalse);
3809 }
while ((vals = vals->nd_next) !=
NULL);
3829 ID2SYM(node->nd_vid), needstr);
3835 ID2SYM(node->nd_entry->
id), needstr);
3841 ID2SYM(node->nd_vid), needstr);
3847 ID2SYM(node->nd_vid), needstr);
3853 defined_expr0(iseq, ret, node->nd_head, lfinish,
Qfalse);
3855 COMPILE(ret,
"defined/colon2#nd_head", node->nd_head);
3860 ID2SYM(node->nd_mid), needstr);
3874 const int explicit_receiver =
3878 if (!lfinish[1] && (node->nd_args || explicit_receiver)) {
3881 if (node->nd_args) {
3882 defined_expr0(iseq, ret, node->nd_args, lfinish,
Qfalse);
3885 if (explicit_receiver) {
3886 defined_expr0(iseq, ret, node->nd_recv, lfinish,
Qfalse);
3888 COMPILE(ret,
"defined/recv", node->nd_recv);
3890 ID2SYM(node->nd_mid), needstr);
3895 ID2SYM(node->nd_mid), needstr);
3955 int done = defined_expr0(iseq, ret, node, lfinish, needstr);
3962 (
"defined guard in "),
3964 ISEQ_TYPE_DEFINED_GUARD, 0);
3977 const int line =
nd_line(node);
3978 if (!node->nd_head) {
3987 defined_expr(iseq, ret, node->nd_head, lfinish, needstr);
3989 INSERT_ELEM_NEXT(last, &new_insn_body(iseq, line, BIN(putnil), 0)->
link);
4000 make_name_for_block(
const rb_iseq_t *orig_iseq)
4007 if (iseq->
body->
type == ISEQ_TYPE_BLOCK) {
4040 while (erange->
next != 0) {
4041 erange = erange->
next;
4046 erange->
end = lstart;
4067 add_ensure_range(iseq, enlp->
erange, lstart, lend);
4098 COMPILE(arg_block,
"block", argn->nd_body);
4100 argn = argn->nd_head;
4107 COMPILE(args,
"args (splat)", argn->nd_head);
4120 COMPILE(tmp,
"args (cat: splat)", argn->nd_body);
4127 INSERT_LIST(args_splat, tmp);
4131 if (next_is_array) {
4133 if (len < 0)
return Qnil;
4137 argn = argn->nd_head;
4145 if (len < 0)
return Qnil;
4157 for (i=1; i<nsplat; i++) {
4162 if (!LIST_SIZE_ZERO(args_splat)) {
4181 iseq_set_local_table(iseq, 0);
4193 #if !(defined(NAMED_CAPTURE_BY_SVAR) && NAMED_CAPTURE_BY_SVAR-0) 4199 ADD_INSNL(ret, line, branchunless, fail_label);
4201 for (vars = node; vars; vars = vars->nd_next) {
4203 if (vars->nd_next) {
4212 #if !defined(NAMED_CAPTURE_SINGLE_OPT) || NAMED_CAPTURE_SINGLE_OPT-0 4213 if (!vars->nd_next && vars == node) {
4234 for (vars = node; vars; vars = vars->nd_next) {
4238 ((
INSN*)last)->insn_id = BIN(putnil);
4239 ((
INSN*)last)->operand_size = 0;
4245 number_literal_p(
NODE *n)
4253 NODE *node_body = type ==
NODE_IF ? node->nd_body : node->nd_else;
4254 NODE *node_else = type ==
NODE_IF ? node->nd_else : node->nd_body;
4256 const int line =
nd_line(node);
4260 LABEL *then_label, *else_label, *end_label;
4270 compile_branch_condition(iseq, cond_seq, node->nd_cond,
4271 then_label, else_label);
4281 if (then_label->
refcnt) {
4283 if (else_label->
refcnt) {
4291 if (else_label->
refcnt) {
4293 if (then_label->
refcnt) {
4310 NODE *tempnode = node;
4311 LABEL *endlabel, *elselabel;
4315 int only_special_literals = 1;
4327 if (node->nd_head == 0) {
4335 node = node->nd_body;
4356 CHECK(
COMPILE_(body_seq,
"when body", node->nd_body, popped));
4357 ADD_INSNL(body_seq, line, jump, endlabel);
4359 vals = node->nd_head;
4363 only_special_literals = when_vals(iseq, cond_seq, vals, l1, only_special_literals, literals);
4368 only_special_literals = 0;
4382 node = node->nd_next;
4395 ADD_INSNL(cond_seq, line, jump, endlabel);
4398 debugs(
"== else (implicit)\n");
4408 if (only_special_literals) {
4409 iseq_add_mark_object(iseq, literals);
4427 NODE *orig_node = node;
4438 const int line =
nd_line(node);
4443 ADD_INSNL(body_seq, line, jump, endlabel);
4445 vals = node->nd_head;
4453 val = vals->nd_head;
4456 vals = vals->nd_next;
4470 node = node->nd_next;
4485 const int line = (int)
nd_line(node);
4504 push_ensure_entry(iseq, &enl,
NULL,
NULL);
4506 if (type ==
NODE_OPT_N || node->nd_state == 1) {
4518 if (tmp_label)
ADD_LABEL(ret, tmp_label);
4527 compile_branch_condition(iseq, ret, node->nd_cond,
4528 redo_label, end_label);
4532 compile_branch_condition(iseq, ret, node->nd_cond,
4533 end_label, redo_label);
4538 ADD_INSNL(ret, line, branchif, redo_label);
4545 if (node->nd_state ==
Qundef) {
4578 const int line =
nd_line(node);
4586 CHECK(
COMPILE(ret,
"iter caller (for)", node->nd_iter));
4590 ISEQ_TYPE_BLOCK, line);
4596 ISEQ_TYPE_BLOCK, line);
4607 ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, retry_label, retry_end_l, child_iseq, retry_end_l);
4614 const int line =
nd_line(node);
4619 NODE *var = node->nd_var;
4627 ADD_INSNL(ret, line, branchunless, not_single);
4634 ADD_INSNL(ret, line, branchunless, not_ary);
4642 return compile_iter(iseq, ret, node, popped);
4649 const int line =
nd_line(node);
4650 unsigned long level = 0;
4657 CHECK(
COMPILE_(ret,
"break val (while/until)", node->nd_stts,
4659 add_ensure_iseq(ret, iseq, 0);
4667 else if (iseq->
body->
type == ISEQ_TYPE_BLOCK) {
4670 CHECK(
COMPILE(ret,
"break val (block)", node->nd_stts));
4676 else if (iseq->
body->
type == ISEQ_TYPE_EVAL) {
4695 else if (ip->
body->
type == ISEQ_TYPE_BLOCK) {
4699 else if (ip->
body->
type == ISEQ_TYPE_EVAL) {
4714 const int line =
nd_line(node);
4715 unsigned long level = 0;
4719 debugs(
"next in while loop\n");
4721 CHECK(
COMPILE(ret,
"next val/valid syntax?", node->nd_stts));
4722 add_ensure_iseq(ret, iseq, 0);
4732 debugs(
"next in block\n");
4736 add_ensure_iseq(ret, iseq, 0);
4744 else if (iseq->
body->
type == ISEQ_TYPE_EVAL) {
4763 else if (ip->
body->
type == ISEQ_TYPE_BLOCK) {
4766 else if (ip->
body->
type == ISEQ_TYPE_EVAL) {
4791 const int line =
nd_line(node);
4798 add_ensure_iseq(ret, iseq, 0);
4805 else if (iseq->
body->
type == ISEQ_TYPE_EVAL) {
4815 add_ensure_iseq(ret, iseq, 0);
4837 else if (ip->
body->
type == ISEQ_TYPE_BLOCK) {
4840 else if (ip->
body->
type == ISEQ_TYPE_EVAL) {
4865 const int line =
nd_line(node);
4867 if (iseq->
body->
type == ISEQ_TYPE_RESCUE) {
4885 const int line =
nd_line(node);
4891 ISEQ_TYPE_RESCUE, line);
4898 if (node->nd_else) {
4918 const int line =
nd_line(node);
4921 LABEL *label_miss, *label_hit;
4927 narg = resq->nd_args;
4935 ADD_INSNL(ret, line, branchif, label_hit);
4936 narg = narg->nd_next;
4945 ADD_INSNL(ret, line, branchif, label_hit);
4955 ADD_INSNL(ret, line, branchif, label_hit);
4965 resq = resq->nd_head;
4973 const int line =
nd_line(node);
4977 ISEQ_TYPE_ENSURE, line);
4995 push_ensure_entry(iseq, &enl, &er, node->nd_ensr);
4998 CHECK(
COMPILE_(ret,
"ensure head", node->nd_head, (popped | last_leave)));
5000 if (ensr->anchor.next ==
NULL) {
5005 if (!popped && last_leave) {
5010 if (last_leave)
ADD_INSN(ret, line, pop);
5017 erange = erange->
next;
5038 debugs(
"node: NODE_NIL(implicit)\n");
5043 return iseq_compile_each0(iseq, ret, node, popped);
5051 const int line = (int)
nd_line(node);
5062 saved_last_element = ret->
last;
5067 #undef BEFORE_RETURN 5068 #define BEFORE_RETURN debug_node_end() 5074 (node->nd_next ? 1 : popped)));
5075 node = node->nd_next;
5084 CHECK(compile_if(iseq, ret, node, popped, type));
5087 CHECK(compile_case(iseq, ret, node, popped));
5090 CHECK(compile_when(iseq, ret, node, popped));
5095 CHECK(compile_loop(iseq, ret, node, popped, type));
5098 CHECK(compile_for(iseq, ret, node, popped));
5101 CHECK(compile_iter(iseq, ret, node, popped));
5104 CHECK(compile_break(iseq, ret, node, popped));
5107 CHECK(compile_next(iseq, ret, node, popped));
5110 CHECK(compile_redo(iseq, ret, node, popped));
5113 CHECK(compile_retry(iseq, ret, node, popped));
5120 CHECK(compile_rescue(iseq, ret, node, popped));
5123 CHECK(compile_resbody(iseq, ret, node, popped));
5126 CHECK(compile_ensure(iseq, ret, node, popped));
5137 ADD_INSNL(ret, line, branchunless, end_label);
5140 ADD_INSNL(ret, line, branchif, end_label);
5151 compile_massign(iseq, ret, node, popped);
5156 ID id = node->nd_vid;
5171 ID id = node->nd_vid;
5179 idx = get_dyna_var_idx(iseq,
id, &lv, &ls);
5196 ((
VALUE)node->nd_entry | 1));
5204 ADD_INSN2(ret, line, setinstancevariable,
5206 get_ivar_ic_value(iseq,node->nd_vid));
5222 compile_cpath(ret, iseq, node->nd_else);
5239 unsigned int flag = 0;
5240 unsigned int asgnflag = 0;
5241 ID id = node->nd_mid;
5270 asgnflag =
COMPILE_RECV(ret,
"NODE_OP_ASGN1 recv", node);
5271 switch (
nd_type(node->nd_args->nd_head)) {
5279 argc = setup_args(iseq, args, node->nd_args->nd_head, &flag,
NULL);
5287 if (
id == 0 ||
id == 1) {
5307 ADD_INSNL(ret, line, branchunless, label);
5311 CHECK(
COMPILE(ret,
"NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body));
5345 CHECK(
COMPILE(ret,
"NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body));
5350 if (flag & VM_CALL_ARGS_SPLAT) {
5376 ID atype = node->nd_next->nd_mid;
5424 asgnflag =
COMPILE_RECV(ret,
"NODE_OP_ASGN2#recv", node);
5425 if (node->nd_next->nd_aid) {
5433 if (atype == 0 || atype == 1) {
5439 ADD_INSNL(ret, line, branchunless, lcfin);
5442 CHECK(
COMPILE(ret,
"NODE_OP_ASGN2 val", node->nd_value));
5462 CHECK(
COMPILE(ret,
"NODE_OP_ASGN2 val", node->nd_value));
5469 if (lskip && popped) {
5473 if (lskip && !popped) {
5484 switch (
nd_type(node->nd_head)) {
5489 CHECK(
COMPILE(ret,
"NODE_OP_CDECL/colon2#nd_head", node->nd_head->nd_head));
5496 mid = node->nd_head->nd_mid;
5498 if (node->nd_aid == 0) {
5503 ADD_INSNL(ret, line, branchunless, lassign);
5508 if (node->nd_aid == 0 || node->nd_aid == 1) {
5510 if (!popped)
ADD_INSN(ret, line, dup);
5511 if (node->nd_aid == 0)
5514 ADD_INSNL(ret, line, branchunless, lfin);
5516 if (!popped)
ADD_INSN(ret, line, pop);
5518 CHECK(
COMPILE(ret,
"NODE_OP_CDECL#nd_value", node->nd_value));
5528 if (!popped)
ADD_INSN(ret, line, swap);
5532 CHECK(
COMPILE(ret,
"NODE_OP_CDECL#nd_value", node->nd_value));
5554 defined_expr(iseq, ret, node->nd_head, lfinish,
Qfalse);
5555 lassign = lfinish[1];
5559 ADD_INSNL(ret, line, branchunless, lassign);
5565 CHECK(
COMPILE(ret,
"NODE_OP_ASGN_AND/OR#nd_head", node->nd_head));
5569 ADD_INSNL(ret, line, branchunless, lfin);
5577 CHECK(
COMPILE(ret,
"NODE_OP_ASGN_AND/OR#nd_value", node->nd_value));
5592 (node->nd_mid == idFreeze || node->nd_mid ==
idUMinus) &&
5593 node->nd_args ==
NULL &&
5597 iseq_add_mark_object(iseq, str);
5599 ADD_INSN1(ret, line, opt_str_uminus, str);
5602 ADD_INSN1(ret, line, opt_str_freeze, str);
5618 node->nd_args->nd_head->nd_lit = str;
5638 LABEL *else_label = 0;
5639 LABEL *end_label = 0;
5641 ID mid = node->nd_mid;
5643 unsigned int flag = 0;
5656 CONST_ID(id_answer,
"the_answer_to_life_the_universe_and_everything");
5658 if (mid == id_bitblt) {
5662 else if (mid == id_answer) {
5676 (mid == goto_id || mid == label_id)) {
5682 if (!labels_table) {
5687 SYMBOL_P(node->nd_args->nd_head->nd_lit)) {
5689 label_name = node->nd_args->nd_head->nd_lit;
5696 label = (
LABEL *)data;
5705 if (mid == goto_id) {
5724 ADD_INSNL(recv, line, branchnil, else_label);
5734 argc = setup_args(iseq, args, node->nd_args, &flag, &keywords);
5747 switch ((
int)type) {
5757 if (else_label && end_label) {
5772 unsigned int flag = 0;
5779 VALUE vargc = setup_args(iseq, args, node->nd_args, &flag, &keywords);
5787 int lvar_level = get_lvar_level(iseq);
5822 for (j=0; j<post_len; j++) {
5827 ADD_INSN (args, line, concatarray);
5832 for (j=0; j<post_len; j++) {
5836 argc = post_len + post_start;
5856 int idx = local_size - get_local_var_idx(liseq,
id);
5863 ADD_INSN (args, line, concatarray);
5874 ADD_INSN (args, line, concatarray);
5944 enum iseq_type type = is->
body->
type;
5946 enum iseq_type parent_type;
5948 if (type == ISEQ_TYPE_TOP) {
5956 else if ((type == ISEQ_TYPE_RESCUE || type == ISEQ_TYPE_ENSURE || type == ISEQ_TYPE_MAIN) &&
5958 ((parent_type = parent_iseq->
body->
type) == ISEQ_TYPE_TOP ||
5959 parent_type == ISEQ_TYPE_MAIN)) {
5969 if (type == ISEQ_TYPE_METHOD) {
5975 CHECK(
COMPILE(ret,
"return nd_stts (return val)", node->nd_stts));
5977 if (type == ISEQ_TYPE_METHOD) {
5978 add_ensure_iseq(ret, iseq, 1);
6000 unsigned int flag = 0;
6004 if (iseq->
body->
type == ISEQ_TYPE_TOP ||
6005 iseq->
body->
type == ISEQ_TYPE_MAIN) {
6010 if (node->nd_head) {
6011 argc = setup_args(iseq, args, node->nd_head, &flag, &keywords);
6028 ID id = node->nd_vid;
6038 debugi(
"nd_vid", node->nd_vid);
6040 idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls);
6052 ((
VALUE)node->nd_entry | 1));
6059 debugi(
"nd_vid", node->nd_vid);
6061 ADD_INSN2(ret, line, getinstancevariable,
6063 get_ivar_ic_value(iseq,node->nd_vid));
6068 debugi(
"nd_vid", node->nd_vid);
6098 if (!node->nd_nth) {
6110 INT2FIX(0x01 | (node->nd_nth << 1)));
6124 ADD_INSN1(recv, line, putobject, node->nd_lit);
6140 if (recv->last == recv->anchor.next &&
6141 INSN_OF(recv->last) == BIN(putobject) &&
6159 if (node->nd_args) {
6160 compile_named_capture_assign(iseq, ret, node->nd_args);
6171 ADD_INSN1(ret, line, putobject, node->nd_lit);
6180 ADD_INSN1(ret, line, putstring, node->nd_lit);
6188 iseq_add_mark_object_compile_time(iseq, str);
6191 ADD_INSN1(ret, line, putobject, node->nd_lit);
6198 compile_dstr(iseq, ret, node);
6208 iseq_add_mark_object_compile_time(iseq,
rb_obj_freeze(debug_info));
6210 ADD_INSN1(ret, line, freezestring, debug_info);
6218 ADD_INSN1(ret, line, putobject, node->nd_lit);
6228 compile_dstr(iseq, ret, node);
6256 compile_dregx(iseq, ret, node);
6296 CHECK(
COMPILE_(ret,
"argspush body", node->nd_body, popped));
6300 CHECK(
COMPILE_(ret,
"argspush body", node->nd_body, popped));
6318 ISEQ_TYPE_METHOD, line);
6324 ADD_INSN1(ret, line, putiseq, method_iseq);
6336 ISEQ_TYPE_METHOD, line);
6343 ADD_INSN1(ret, line, putiseq, singleton_method);
6388 ISEQ_TYPE_CLASS, line);
6391 compile_cpath(ret, iseq, node->nd_cpath);
6404 ISEQ_TYPE_CLASS, line);
6406 compile_cpath(ret, iseq, node->nd_cpath);
6419 ISEQ_TYPE_CLASS, line);
6423 CONST_ID(singletonclass,
"singletonclass");
6425 ID2SYM(singletonclass), singleton_class,
6444 CHECK(compile_const_prefix(iseq, node, pref, body));
6445 if (LIST_SIZE_ZERO(pref)) {
6480 debugi(
"colon3#nd_mid", node->nd_mid);
6505 NODE *b = node->nd_beg;
6506 NODE *e = node->nd_end;
6507 if (number_literal_p(b) && number_literal_p(e)) {
6510 iseq_add_mark_object_compile_time(iseq, val);
6564 if (iseq->
body->
type == ISEQ_TYPE_RESCUE) {
6571 if (ip->
body->
type == ISEQ_TYPE_RESCUE) {
6589 CHECK(compile_defined_expr(iseq, ret, node,
Qtrue));
6598 make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
6610 NODE *default_value = node->nd_body->nd_value;
6612 if (default_value == (
NODE *)-1) {
6633 ADD_INSNL(ret, line, branchif, end_label);
6641 compile_dstr(iseq, ret, node);
6653 unsigned int flag = 0;
6654 ID mid = node->nd_mid;
6668 node->nd_args->nd_head->nd_lit = str;
6669 iseq_add_mark_object(iseq, str);
6671 CHECK(
COMPILE(ret,
"value", node->nd_args->nd_next->nd_head));
6685 argc = setup_args(iseq, args, node->nd_args, &flag,
NULL);
6698 ADD_INSNL(recv, line, branchnil, lskip);
6707 if (flag & VM_CALL_ARGS_SPLAT) {
6714 else if (flag & VM_CALL_ARGS_SPLAT) {
6739 if (node->nd_orig) {
6771 if (saved_last_element &&
6772 ret->
last == saved_last_element &&
6773 ((
INSN *)saved_last_element)->insn_id == BIN(trace)) {
6793 insn_data_length(
INSN *iobj)
6795 return insn_len(iobj->
insn_id);
6799 calc_sp_depth(
int depth,
INSN *insn)
6805 opobj_inspect(
VALUE obj)
6824 insn_data_to_s_detail(
INSN *iobj)
6829 const char *types = insn_op_types(iobj->
insn_id);
6832 for (j = 0; types[j]; j++) {
6833 char type = types[j];
6895 if (dladdr(func, &info) && info.dli_sname) {
6918 dump_disasm_list_with_cursor(link,
NULL,
NULL);
6929 printf(
"-- raw disasm--------\n");
6932 if (curr) printf(curr == link ?
"*" :
" ");
6933 switch (link->
type) {
6936 iobj = (
INSN *)link;
6937 str = insn_data_to_s_detail(iobj);
6939 pos += insn_data_length(iobj);
6944 lobj = (
LABEL *)link;
6965 printf(
"---------------------\n");
6972 return insn_name_info[i];
6980 for (i = 0; i < VM_INSTRUCTION_SIZE; i++) {
6993 if (
st_lookup(labels_table, obj, &tmp) == 0) {
6998 label = (
LABEL *)tmp;
7008 #define rb_intern(str) rb_intern_const(str) 7009 static VALUE symRescue, symEnsure, symRetry;
7010 static VALUE symBreak, symRedo, symNext;
7012 if (symRescue == 0) {
7021 if (sym == symRescue)
return CATCH_TYPE_RESCUE;
7022 if (sym == symEnsure)
return CATCH_TYPE_ENSURE;
7023 if (sym == symRetry)
return CATCH_TYPE_RETRY;
7024 if (sym == symBreak)
return CATCH_TYPE_BREAK;
7025 if (sym == symRedo)
return CATCH_TYPE_REDO;
7026 if (sym == symNext)
return CATCH_TYPE_NEXT;
7041 LABEL *lstart, *lend, *lcont;
7050 type = get_exception_sym2type(ptr[0]);
7051 if (ptr[1] ==
Qnil) {
7058 lstart = register_label(iseq, labels_table, ptr[2]);
7059 lend = register_label(iseq, labels_table, ptr[3]);
7060 lcont = register_label(iseq, labels_table, ptr[4]);
7064 if (type == CATCH_TYPE_RESCUE ||
7065 type == CATCH_TYPE_BREAK ||
7066 type == CATCH_TYPE_NEXT) {
7080 insn_make_insn_table(
void)
7086 for (i=0; i<VM_INSTRUCTION_SIZE; i++) {
7110 iseq_add_mark_object(iseq, (
VALUE)loaded_iseq);
7119 unsigned int flag = 0;
7130 if (!
NIL_P(vorig_argc)) orig_argc =
FIX2INT(vorig_argc);
7132 if (!
NIL_P(vkw_arg)) {
7135 size_t n = rb_call_info_kw_arg_bytes(len);
7139 for (i = 0; i <
len; i++) {
7165 static struct st_table *insn_table;
7167 if (insn_table == 0) {
7168 insn_table = insn_make_insn_table();
7171 for (i=0; i<
len; i++) {
7175 LABEL *label = register_label(iseq, labels_table, obj);
7191 "unknown instruction: %+"PRIsVALUE, insn);
7196 if (argc != insn_len((
VALUE)insn_id)-1) {
7198 "operand size mismatch");
7204 argv = compile_data_alloc(iseq,
sizeof(
VALUE) * argc);
7205 for (j=0; j<
argc; j++) {
7207 switch (insn_op_type((
VALUE)insn_id, j)) {
7209 LABEL *label = register_label(iseq, labels_table, op);
7210 argv[j] = (
VALUE)label;
7220 iseq_add_mark_object(iseq, op);
7225 argv[j] = (
VALUE)iseq_build_load_iseq(iseq, op);
7243 argv[j] = iseq_build_callinfo_from_hash(iseq, op);
7250 "Symbol", idTo_sym);
7263 register_label(iseq, labels_table, sym);
7273 #if SIZEOF_VALUE <= SIZEOF_LONG 7276 LONG_LONG funcptr = NUM2LL(op);
7278 argv[j] = (
VALUE)funcptr;
7288 (
enum ruby_vminsn_type)insn_id, argc, argv));
7295 validate_labels(iseq, labels_table);
7296 if (!ret)
return ret;
7297 return iseq_setup(iseq, anchor);
7300 #define CHECK_ARRAY(v) rb_convert_type_with_id((v), T_ARRAY, "Array", idTo_ary) 7301 #define CHECK_SYMBOL(v) rb_convert_type_with_id((v), T_SYMBOL, "Symbol", idTo_sym) 7311 else if (!
NIL_P(val)) {
7318 static const struct rb_iseq_param_keyword *
7327 struct rb_iseq_param_keyword *keyword =
ZALLOC(
struct rb_iseq_param_keyword);
7332 #define SYM(s) ID2SYM(rb_intern(#s)) 7333 (void)int_param(&keyword->bits_start, params,
SYM(kwbits));
7334 i = keyword->bits_start - keyword->num;
7339 for (i = 0; i <
len; i++) {
7343 goto default_values;
7346 keyword->required_num++;
7350 default_len = len - i;
7351 if (default_len == 0) {
7352 keyword->table = ids;
7358 for (j = 0; i <
len; i++, j++) {
7375 dvs[j] = default_val;
7378 keyword->table = ids;
7379 keyword->default_values = dvs;
7388 #define SYM(s) ID2SYM(rb_intern(#s)) 7390 unsigned int arg_size, local_size, stack_max;
7404 for (i = 0; i <
len; i++) {
7407 if (sym_arg_rest == lv) {
7415 #define INT_PARAM(F) int_param(&iseq->body->param.F, params, SYM(F)) 7425 #define INT_PARAM(F) F = (int_param(&x, misc, SYM(F)) ? (unsigned int)x : 0) 7440 for (i = 0; i <
len; i++) {
7442 LABEL *label = register_label(iseq, labels_table, ent);
7443 opt_table[i] = (
VALUE)label;
7450 else if (!
NIL_P(arg_opt_labels)) {
7458 else if (!
NIL_P(keywords)) {
7467 if (int_param(&i, params,
SYM(kwrest))) {
7468 struct rb_iseq_param_keyword *keyword = (
struct rb_iseq_param_keyword *)iseq->
body->
param.
keyword;
7472 keyword->rest_start = i;
7476 iseq_calc_param_size(iseq);
7479 iseq_build_from_ary_exception(iseq, labels_table, exception);
7482 iseq_build_from_ary_body(iseq, anchor, body, labels_wrapper);
7496 if (base_block && (iseq = vm_block_iseq(base_block)) !=
NULL) {
7497 while (iseq->
body->
type == ISEQ_TYPE_BLOCK ||
7498 iseq->
body->
type == ISEQ_TYPE_RESCUE ||
7499 iseq->
body->
type == ISEQ_TYPE_ENSURE ||
7500 iseq->
body->
type == ISEQ_TYPE_EVAL ||
7521 if (base_block && (iseq = vm_block_iseq(base_block)) !=
NULL) {
7535 caller_location(
VALUE *path,
VALUE *realpath)
7564 VALUE path, realpath;
7569 acc.
line = caller_location(&path, &realpath);
7572 INT2FIX(acc.line), 0, ISEQ_TYPE_METHOD, 0);
7579 const int line = args->
line;
7581 iseq_set_local_table(iseq, 0);
7594 const int line = args->
line;
7595 static const ID vars[] = {1, idUScore};
7597 iseq_set_local_table(iseq, vars);
7614 return method_for_self(name, arg, func, for_self_aref);
7623 return method_for_self(name, arg, func, for_self_aset);
7629 #define IBF_OFFSET(ptr) ((ibf_offset_t)(VALUE)(ptr)) 7678 ibf_dump_pos(
struct ibf_dump *dump)
7684 ibf_dump_write(
struct ibf_dump *dump,
const void *buff,
unsigned long size)
7686 ibf_offset_t pos = ibf_dump_pos(dump);
7693 ibf_dump_overwrite(
struct ibf_dump *dump,
void *buff,
unsigned int size,
long offset)
7697 if ((
unsigned long)(size + offset) > (
unsigned long)
RSTRING_LEN(str))
7698 rb_bug(
"ibf_dump_overwrite: overflow");
7699 memcpy(ptr + offset, buff, size);
7703 ibf_load_alloc(
const struct ibf_load *load, ibf_offset_t offset,
int size)
7706 memcpy(buff, load->
buff + offset, size);
7710 #define IBF_W(b, type, n) (type *)(VALUE)ibf_dump_write(dump, (b), sizeof(type) * (n)) 7711 #define IBF_WV(variable) ibf_dump_write(dump, &(variable), sizeof(variable)) 7712 #define IBF_WP(b, type, n) ibf_dump_write(dump, (b), sizeof(type) * (n)) 7713 #define IBF_R(val, type, n) (type *)ibf_load_alloc(load, IBF_OFFSET(val), sizeof(type) * (n)) 7731 int index = ibf_table_lookup(table, key);
7751 for (i=0; i<index; i++) {
7755 return (
VALUE)index;
7765 ibf_load_id(
const struct ibf_load *load,
const ID id_index)
7769 if (id_index == 0) {
7773 id = load->
id_list[(long)id_index];
7777 VALUE str = ibf_load_object(load, indices[id_index]);
7779 load->
id_list[(long)id_index] =
id;
7794 static ibf_offset_t ibf_dump_iseq_each(
struct ibf_dump *dump,
const rb_iseq_t *iseq);
7804 if (iseq_index < 0) {
7815 return (
VALUE)ibf_dump_id(dump, entry->
id);
7821 ID gid = ibf_load_id(load, (
ID)(
VALUE)entry);
7835 for (code_index=0; code_index<iseq_size;) {
7836 const VALUE insn = orig_code[code_index];
7837 const char *types = insn_op_types(insn);
7840 code[code_index++] = (
VALUE)insn;
7842 for (op_index=0; types[op_index]; op_index++, code_index++) {
7843 VALUE op = orig_code[code_index];
7844 switch (types[op_index]) {
7847 code[code_index] = ibf_dump_object(dump, op);
7850 code[code_index] = (
VALUE)ibf_dump_iseq(dump, (
const rb_iseq_t *)op);
7860 code[code_index] = i;
7864 code[code_index] = ibf_dump_callinfo(dump, (
const struct rb_call_info *)op);
7867 code[code_index] = 0;
7870 code[code_index] = ibf_dump_id(dump, (
ID)op);
7873 code[code_index] = ibf_dump_gentry(dump, (
const struct rb_global_entry *)op);
7879 code[code_index] = op;
7883 assert(insn_len(insn) == op_index+1);
7901 for (code_index=0; code_index<iseq_size;) {
7902 const VALUE insn = code[code_index++];
7903 const char *types = insn_op_types(insn);
7906 for (op_index=0; types[op_index]; op_index++, code_index++) {
7907 VALUE op = code[code_index];
7909 switch (types[op_index]) {
7912 code[code_index] = ibf_load_object(load, op);
7915 code[code_index] = (
VALUE)ibf_load_iseq(load, (
const rb_iseq_t *)op);
7918 code[code_index] = (
VALUE)&is_entries[(
int)op];
7921 code[code_index] = op ? (
VALUE)ci_kw_entries++ : (
VALUE)ci_entries++;
7924 code[code_index] = (
VALUE)cc_entries++;
7927 code[code_index] = ibf_load_id(load, (
ID)op);
7930 code[code_index] = ibf_load_gentry(load, (
const struct rb_global_entry *)op);
7940 if (insn_len(insn) != op_index+1) {
7978 static struct rb_iseq_param_keyword *
7984 struct rb_iseq_param_keyword dump_kw = *kw;
7985 int dv_num = kw->num - kw->required_num;
7990 for (i=0; i<kw->num; i++) ids[i] = (
ID)ibf_dump_id(dump, kw->table[i]);
7991 for (i=0; i<dv_num; i++) dvs[i] = (
VALUE)ibf_dump_object(dump, kw->default_values[i]);
7993 dump_kw.table =
IBF_W(ids,
ID, kw->num);
7994 dump_kw.default_values =
IBF_W(dvs,
VALUE, dv_num);
7995 return IBF_W(&dump_kw,
struct rb_iseq_param_keyword, 1);
8002 static const struct rb_iseq_param_keyword *
8006 struct rb_iseq_param_keyword *kw =
IBF_R(body->
param.
keyword,
struct rb_iseq_param_keyword, 1);
8007 ID *ids =
IBF_R(kw->table,
ID, kw->num);
8008 int dv_num = kw->num - kw->required_num;
8012 for (i=0; i<kw->num; i++) {
8013 ids[i] = ibf_load_id(load, ids[i]);
8015 for (i=0; i<dv_num; i++) {
8016 dvs[i] = ibf_load_object(load, dvs[i]);
8020 kw->default_values = dvs;
8047 for (i=0; i<
size; i++) {
8051 return IBF_W(table,
ID, size);
8063 for (i=0; i<
size; i++) {
8064 table[i] = ibf_load_id(load, table[i]);
8073 static struct iseq_catch_table *
8079 int byte_size = iseq_catch_table_bytes(iseq->
body->
catch_table->size);
8080 struct iseq_catch_table *dump_table = (
struct iseq_catch_table *)
ALLOCA_N(
char, byte_size);
8082 dump_table->size = table->size;
8083 for (i=0; i<table->size; i++) {
8084 dump_table->entries[i] = table->entries[i];
8085 dump_table->entries[i].iseq = ibf_dump_iseq(dump, table->entries[i].iseq);
8087 return (
struct iseq_catch_table *)(
VALUE)ibf_dump_write(dump, dump_table, byte_size);
8094 static struct iseq_catch_table *
8098 struct iseq_catch_table *table;
8103 for (i=0; i<
size; i++) {
8104 table->entries[i].iseq = ibf_load_iseq(load, table->entries[i].
iseq);
8121 int byte_size = ci_size *
sizeof(
struct rb_call_info) +
8127 memcpy(dump_ci_entries, ci_entries, byte_size);
8129 for (i=0; i<ci_size; i++) {
8130 dump_ci_entries[i].
mid = ibf_dump_id(dump, dump_ci_entries[i].mid);
8132 for (i=0; i<ci_kw_size; i++) {
8137 keywords[j] = (
VALUE)ibf_dump_object(dump, kw_arg->
keywords[j]);
8142 dump_ci_kw_entries[i].
ci.
mid = ibf_dump_id(dump, dump_ci_kw_entries[i].ci.
mid);
8144 return (
struct rb_call_info *)(
VALUE)ibf_dump_write(dump, dump_ci_entries, byte_size);
8151 const unsigned int ci_size = body->
ci_size;
8152 const unsigned int ci_kw_size = body->
ci_kw_size;
8158 for (i=0; i<ci_size; i++) {
8159 ci_entries[i].
mid = ibf_load_id(load, ci_entries[i].mid);
8161 for (i=0; i<ci_kw_size; i++) {
8163 ibf_offset_t kw_arg_offset =
IBF_OFFSET(ci_kw_entries[i].kw_arg);
8164 const int keyword_len = *(
int *)(load->
buff + kw_arg_offset);
8165 const VALUE *keywords = (
VALUE *)(load->
buff + kw_arg_offset +
sizeof(
int));
8169 kw_arg->
keywords[j] = (
VALUE)ibf_load_object(load, keywords[j]);
8171 ci_kw_entries[i].
kw_arg = kw_arg;
8172 ci_kw_entries[i].
ci.
mid = ibf_load_id(load, ci_kw_entries[i].ci.
mid);
8182 dump_body = *iseq->
body;
8184 dump_body.
location.
pathobj = ibf_dump_object(dump, dump_body.location.pathobj);
8185 dump_body.location.base_label = ibf_dump_object(dump, dump_body.location.base_label);
8186 dump_body.location.label = ibf_dump_object(dump, dump_body.location.label);
8188 dump_body.iseq_encoded = ibf_dump_code(dump, iseq);
8189 dump_body.param.opt_table = ibf_dump_param_opt_table(dump, iseq);
8190 dump_body.param.keyword = ibf_dump_param_keyword(dump, iseq);
8191 dump_body.line_info_table = ibf_dump_line_info_table(dump, iseq);
8192 dump_body.local_table = ibf_dump_local_table(dump, iseq);
8193 dump_body.catch_table = ibf_dump_catch_table(dump, iseq);
8195 dump_body.local_iseq = ibf_dump_iseq(dump, iseq->
body->
local_iseq);
8196 dump_body.is_entries =
NULL;
8197 dump_body.ci_entries = ibf_dump_ci_entries(dump, iseq);
8198 dump_body.cc_entries =
NULL;
8201 return ibf_dump_write(dump, &dump_body,
sizeof(dump_body));
8205 ibf_load_location_str(
const struct ibf_load *load,
VALUE str_index)
8207 VALUE str = ibf_load_object(load, str_index);
8215 ibf_load_iseq_each(
const struct ibf_load *load,
rb_iseq_t *iseq, ibf_offset_t offset)
8239 VALUE pathobj = path;
8257 load_body->
ci_entries = ibf_load_ci_entries(load, body);
8259 load_body->
param.
opt_table = ibf_load_param_opt_table(load, body);
8260 load_body->
param.
keyword = ibf_load_param_keyword(load, body);
8262 load_body->
local_table = ibf_load_local_table(load, body);
8263 load_body->
catch_table = ibf_load_catch_table(load, body);
8267 load_body->
iseq_encoded = ibf_load_code(load, iseq, body);
8277 ibf_offset_t *list =
ALLOCA_N(ibf_offset_t, size);
8280 for (i=0; i<
size; i++) {
8284 header->
iseq_list_offset = ibf_dump_write(dump, list,
sizeof(ibf_offset_t) * size);
8324 header->
id_list_offset = ibf_dump_write(dump, arg.list,
sizeof(
long) * size);
8328 #define IBF_OBJECT_INTERNAL FL_PROMOTED0 8340 unsigned int internal: 1;
8395 #define IBF_OBJHEADER(offset) (struct ibf_object_header *)(load->buff + (offset)) 8396 #define IBF_OBJBODY(type, offset) (type *)(load->buff + sizeof(struct ibf_object_header) + (offset)) 8399 ibf_dump_object_unsupported(
struct ibf_dump *dump,
VALUE obj)
8402 rb_bug(
"ibf_dump_object_unsupported: unsupported");
8428 rb_bug(
"unsupported class");
8430 ibf_dump_write(dump, &cindex,
sizeof(cindex));
8448 rb_bug(
"ibf_load_object_class: unknown class (%d)", (
int)cindex);
8456 ibf_dump_write(dump, &dbl,
sizeof(dbl));
8509 regexp.
srcstr = (long)ibf_dump_object(dump, regexp.
srcstr);
8531 for (i=0; i<
len; i++) {
8532 long index = (long)ibf_dump_object(dump,
RARRAY_AREF(obj, i));
8544 for (i=0; i<array->
len; i++) {
8558 long key_index = (long)ibf_dump_object(dump, (
VALUE)
key);
8559 long val_index = (long)ibf_dump_object(dump, (
VALUE)
val);
8580 for (i=0; i<hash->
len; i++) {
8581 VALUE key = ibf_load_object(load, hash->
keyval[i*2 ]);
8582 VALUE val = ibf_load_object(load, hash->
keyval[i*2+1]);
8603 range.
beg = (long)ibf_dump_object(dump, beg);
8604 range.
end = (long)ibf_dump_object(dump, end);
8609 rb_bug(
"ibf_dump_object_struct: unsupported class");
8640 int sign = bignum->
slen > 0;
8641 ssize_t
len = sign > 0 ? bignum->
slen : -1 * bignum->
slen;
8662 ibf_dump_object_unsupported(dump, obj);
8681 return ibf_load_object_unsupported(load, header, offset);
8685 ibf_dump_object_complex_rational(
struct ibf_dump *dump,
VALUE obj)
8687 long real = (long)ibf_dump_object(dump,
RCOMPLEX(obj)->real);
8688 long imag = (long)ibf_dump_object(dump,
RCOMPLEX(obj)->imag);
8695 ibf_load_object_complex_rational(
const struct ibf_load *load,
const struct ibf_object_header *header, ibf_offset_t offset)
8698 VALUE a = ibf_load_object(load, nums->
a);
8699 VALUE b = ibf_load_object(load, nums->
b);
8712 long str_index = (long)ibf_dump_object(dump, str);
8721 VALUE str = ibf_load_object(load, symbol->
str);
8728 ibf_dump_object_unsupported,
8729 ibf_dump_object_unsupported,
8730 ibf_dump_object_class,
8731 ibf_dump_object_unsupported,
8732 ibf_dump_object_float,
8733 ibf_dump_object_string,
8734 ibf_dump_object_regexp,
8735 ibf_dump_object_array,
8736 ibf_dump_object_hash,
8737 ibf_dump_object_struct,
8738 ibf_dump_object_bignum,
8739 ibf_dump_object_unsupported,
8740 ibf_dump_object_data,
8741 ibf_dump_object_unsupported,
8742 ibf_dump_object_complex_rational,
8743 ibf_dump_object_complex_rational,
8744 ibf_dump_object_unsupported,
8745 ibf_dump_object_unsupported,
8746 ibf_dump_object_unsupported,
8747 ibf_dump_object_unsupported,
8748 ibf_dump_object_symbol,
8749 ibf_dump_object_unsupported,
8750 ibf_dump_object_unsupported,
8751 ibf_dump_object_unsupported,
8752 ibf_dump_object_unsupported,
8753 ibf_dump_object_unsupported,
8754 ibf_dump_object_unsupported,
8755 ibf_dump_object_unsupported,
8756 ibf_dump_object_unsupported,
8757 ibf_dump_object_unsupported,
8758 ibf_dump_object_unsupported,
8759 ibf_dump_object_unsupported
8766 ibf_offset_t current_offset = ibf_dump_pos(dump);
8787 (*dump_object_functions[obj_header.
type])(dump, obj);
8790 return current_offset;
8795 ibf_load_object_unsupported,
8796 ibf_load_object_unsupported,
8797 ibf_load_object_class,
8798 ibf_load_object_unsupported,
8799 ibf_load_object_float,
8800 ibf_load_object_string,
8801 ibf_load_object_regexp,
8802 ibf_load_object_array,
8803 ibf_load_object_hash,
8804 ibf_load_object_struct,
8805 ibf_load_object_bignum,
8806 ibf_load_object_unsupported,
8807 ibf_load_object_data,
8808 ibf_load_object_unsupported,
8809 ibf_load_object_complex_rational,
8810 ibf_load_object_complex_rational,
8811 ibf_load_object_unsupported,
8812 ibf_load_object_unsupported,
8813 ibf_load_object_unsupported,
8814 ibf_load_object_unsupported,
8815 ibf_load_object_symbol,
8816 ibf_load_object_unsupported,
8817 ibf_load_object_unsupported,
8818 ibf_load_object_unsupported,
8819 ibf_load_object_unsupported,
8820 ibf_load_object_unsupported,
8821 ibf_load_object_unsupported,
8822 ibf_load_object_unsupported,
8823 ibf_load_object_unsupported,
8824 ibf_load_object_unsupported,
8825 ibf_load_object_unsupported,
8826 ibf_load_object_unsupported
8830 ibf_load_object(
const struct ibf_load *load,
VALUE object_index)
8832 if (object_index == 0) {
8842 ibf_offset_t offset = offsets[object_index];
8850 obj = (*load_object_functions[header->
type])(load, header, offset);
8855 iseq_add_mark_object(load->
iseq, obj);
8868 ibf_offset_t offset = lbf_dump_object_object(dump, obj);
8874 for (i=0; i<
size; i++) {
8883 ibf_dump_mark(
void *ptr)
8892 ibf_dump_free(
void *ptr)
8907 ibf_dump_memsize(
const void *ptr)
8910 size_t size =
sizeof(*dump);
8918 {ibf_dump_mark, ibf_dump_free, ibf_dump_memsize,},
8932 ibf_table_index(dump->
id_table, 0);
8952 ibf_dump_setup(dump, dump_obj);
8954 ibf_dump_write(dump, &header,
sizeof(header));
8956 ibf_dump_iseq(dump, iseq);
8958 header.
magic[0] =
'Y';
8959 header.
magic[1] =
'A';
8960 header.
magic[2] =
'R';
8961 header.
magic[3] =
'B';
8964 ibf_dump_iseq_list(dump, &header);
8965 ibf_dump_id_list(dump, &header);
8966 ibf_dump_object_list(dump, &header);
8967 header.
size = ibf_dump_pos(dump);
8970 VALUE opt_str = opt;
8973 ibf_dump_write(dump, ptr, header.
extra_size);
8979 ibf_dump_overwrite(dump, &header,
sizeof(header), 0);
8982 ibf_dump_free(dump);
8988 static const ibf_offset_t *
8989 ibf_iseq_list(
const struct ibf_load *load)
9000 ibf_load_iseq_each(load, iseq, ibf_iseq_list(load)[iseq->
aux.
loader.index]);
9003 load->
iseq = prev_src_iseq;
9018 int iseq_index = (int)(
VALUE)index_iseq;
9020 if (iseq_index == -1) {
9026 if (iseqv !=
Qnil) {
9041 iseq_add_mark_object(load->
iseq, (
VALUE)iseq);
9068 if (strncmp(load->
header->
magic,
"YARB", 4) != 0) {
9082 ibf_loader_mark(
void *ptr)
9091 ibf_loader_free(
void *ptr)
9099 ibf_loader_memsize(
const void *ptr)
9102 return sizeof(
struct ibf_load) + load->header->id_list_size *
sizeof(
ID);
9107 {ibf_loader_mark, ibf_loader_free, ibf_loader_memsize,},
9118 ibf_load_setup(load, loader_obj, str);
9119 iseq = ibf_load_iseq(load, 0);
9132 ibf_load_setup(load, loader_obj, str);
#define RBASIC_CLEAR_CLASS(obj)
#define RUBY_EVENT_B_RETURN
#define VM_CALL_ARGS_BLOCKARG
union iseq_inline_storage_entry * is_entries
rb_control_frame_t * rb_vm_get_ruby_level_next_cfp(const rb_thread_t *th, const rb_control_frame_t *cfp)
VALUE iseq_ibf_load_extra_data(VALUE str)
int rb_enc_get_index(VALUE obj)
#define EXPECT_NODE(prefix, node, ndtype, errval)
void rb_bug(const char *fmt,...)
VALUE rb_ary_entry(VALUE ary, long offset)
struct iseq_link_element * next
VALUE rb_ary_new_capa(long capa)
int rb_id_table_lookup(struct rb_id_table *tbl, ID id, VALUE *valp)
void ibf_load_iseq_complete(rb_iseq_t *iseq)
enum iseq_link_element::@1 type
#define OPERAND_AT(insn, idx)
#define RUBY_TYPED_FREE_IMMEDIATELY
void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params, VALUE exception, VALUE body)
#define ADD_INSN2(seq, line, insn, op1, op2)
#define va_init_list(a, b)
size_t strlen(const char *)
VALUE rb_reg_compile(VALUE str, int options, const char *sourcefile, int sourceline)
int rb_vm_get_sourceline(const rb_control_frame_t *cfp)
#define RUBY_EVENT_RETURN
void rb_iseq_make_compile_option(rb_compile_option_t *option, VALUE opt)
#define INSERT_BEFORE_INSN(prev, line, insn)
VALUE rb_range_new(VALUE, VALUE, int)
#define ADD_SEND_WITH_FLAG(seq, line, id, argc, flag)
#define CPDEBUG
debug function(macro) interface depend on CPDEBUG if it is less than 0, runtime option is in effect...
struct ensure_range * next
#define DECL_BRANCH_BASE(branches, line, type)
VALUE rb_fstring_cstr(const char *str)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_str_cat(VALUE, const char *, long)
#define ADD_SEND_WITH_BLOCK(seq, line, id, argc, block)
#define IBF_R(val, type, n)
#define ISEQ_MAJOR_VERSION
VALUE(* ibf_load_object_function)(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t)
VALUE rb_insns_name_array(void)
#define ZALLOC_N(type, n)
struct rb_iseq_struct::@137::@138 loader
struct rb_iseq_constant_body::@135::@136 flags
rb_encoding * rb_to_encoding(VALUE enc)
int rb_is_const_id(ID id)
#define ADD_INSN(seq, line, insn)
VALUE rb_enc_from_encoding(rb_encoding *encoding)
#define IBF_OBJHEADER(offset)
int rb_iseq_translate_threaded_code(rb_iseq_t *iseq)
int rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp)
VALUE rb_ary_push(VALUE ary, VALUE item)
if(len<=MAX_WORD_LENGTH &&len >=MIN_WORD_LENGTH)
VALUE rb_str_concat(VALUE, VALUE)
#define debugi(header, id)
struct st_table * rb_hash_tbl_raw(VALUE hash)
VALUE rb_ary_tmp_new(long capa)
VALUE rb_iseq_defined_string(enum defined_type type)
#define ADD_GETLOCAL(seq, line, idx, level)
struct rb_iseq_constant_body * body
int rb_local_defined(ID id, const struct rb_block *base_block)
struct rb_call_info_kw_arg * kw_arg
int rb_reg_options(VALUE)
VALUE rb_ary_clear(VALUE ary)
struct iseq_compile_data_storage * next
const void ** rb_vm_get_insns_address_table(void)
#define VM_CALL_ARGS_SPLAT
#define ADD_ADJUST(seq, line, label)
st_index_t rb_str_hash(VALUE)
#define VM_DEFINECLASS_FLAG_SCOPED
#define cond(node, column)
void rb_gc_mark(VALUE ptr)
void(* ibf_dump_object_function)(struct ibf_dump *dump, VALUE obj)
VALUE rb_hash_lookup(VALUE hash, VALUE key)
#define ADD_TRACE_LINE_COVERAGE(seq, line)
void rb_obj_info_dump(VALUE obj)
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
VALUE rb_hash_new_with_size(st_index_t size)
#define debug_node_start(node)
#define COMPILE_POPPED(anchor, desc, node)
VALUE rb_str_tmp_new(long)
VALUE rb_ary_cat(VALUE ary, const VALUE *argv, long len)
struct iseq_label_data LABEL
#define IS_NEXT_INSN_ID(link, insn)
#define IBF_WP(b, type, n)
struct iseq_link_element LINK_ELEMENT
VALUE iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt)
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
enum iseq_catch_table_entry::catch_type type
#define Data_Wrap_Struct(klass, mark, free, sval)
const VALUE * iseq_encoded
rb_iseq_t * iseq_alloc(void)
void rb_hash_foreach(VALUE hash, int(*func)(ANYARGS), VALUE farg)
#define ISEQ_MINOR_VERSION
VALUE rb_iseqw_new(const rb_iseq_t *)
#define ISEQ_NOT_LOADED_YET
#define ADD_SEQ(seq1, seq2)
#define RB_TYPE_P(obj, type)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
call-seq: obj.is_a?(class) -> true or false obj.kind_of?(class) -> true or false
#define COMPILE_RECV(anchor, desc, node)
VALUE rb_hash_rehash(VALUE hash)
#define RUBY_TYPED_WB_PROTECTED
int rb_data_is_encoding(VALUE obj)
#define ADD_SETLOCAL(seq, line, idx, level)
#define rb_intern_str(string)
VALUE rb_dbl2big(double d)
#define ADD_TRACE(seq, line, event)
const char * rb_insns_name(int i)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
VALUE rb_convert_type_with_id(VALUE, int, const char *, ID)
unsigned int local_table_size
#define ISEQ_TYPE_ONCE_GUARD
RUBY_EXTERN VALUE rb_cObject
size_t st_memsize(const st_table *tab)
struct rb_call_info * ci_entries
#define INSERT_BEFORE_INSN1(prev, line, insn, op1)
VALUE rb_str_cat2(VALUE, const char *)
struct iseq_link_anchor LINK_ANCHOR
void rb_set_errinfo(VALUE err)
Sets the current exception ($!) to the given value.
#define SIZEOF_ISEQ_COMPILE_DATA_STORAGE
RUBY_EXTERN VALUE rb_cRange
#define VM_DEFINECLASS_FLAG_HAS_SUPERCLASS
#define ADD_SEND(seq, line, id, argc)
const rb_iseq_t * rb_method_for_self_aset(VALUE name, VALUE arg, rb_insn_func_t func)
#define ADD_INSNL(seq, line, insn, label)
void rb_iseq_pathobj_set(const rb_iseq_t *iseq, VALUE path, VALUE realpath)
#define VM_CALL_ARGS_SIMPLE
struct rb_id_table * rb_id_table_create(size_t capa)
void rb_ary_store(VALUE ary, long idx, VALUE val)
rb_atomic_t cnt[RUBY_NSIG]
#define ADD_CALL(seq, line, id, argc)
#define INIT_ANCHOR(name)
VALUE * rb_iseq_original_iseq(const rb_iseq_t *iseq)
#define COMPILE_(anchor, desc, node, popped)
const char * rb_builtin_type_name(int t)
VALUE rb_rational_new(VALUE, VALUE)
#define ALLOCA_N(type, n)
#define range(low, item, hi)
#define MEMCPY(p1, p2, type, n)
#define COMPILE(anchor, desc, node)
VALUE rb_enc_associate_index(VALUE obj, int idx)
struct ensure_range * erange
#define ADD_SEND_R(seq, line, id, argc, block, flag, keywords)
#define ISEQ_COVERAGE_SET(iseq, cov)
int link(const char *, const char *)
struct iseq_compile_data_ensure_node_stack * prev
VALUE rb_integer_unpack(const void *words, size_t numwords, size_t wordsize, size_t nails, int flags)
#define IS_TRACE_LINE(insn)
#define LABEL_UNREMOVABLE(label)
int rb_str_hash_cmp(VALUE, VALUE)
struct rb_call_cache * cc_entries
#define ADD_LABEL(seq, label)
#define RARRAY_CONST_PTR(a)
int rb_id_table_insert(struct rb_id_table *tbl, ID id, VALUE val)
#define REALLOC_N(var, type, n)
struct rb_iseq_constant_body::@135 param
parameter information
VALUE rb_obj_freeze(VALUE)
call-seq: obj.freeze -> obj
int rb_dvar_defined(ID id, const struct rb_block *base_block)
unsigned int coverage_enabled
VALUE rb_sprintf(const char *format,...)
struct iseq_insn_data INSN
#define IS_INSN_ID(iobj, insn)
#define private_recv_p(node)
const rb_iseq_t * rb_method_for_self_aref(VALUE name, VALUE arg, rb_insn_func_t func)
void rb_compile_warning(const char *file, int line, const char *fmt,...)
VALUE rb_ivar_set(VALUE, ID, VALUE)
#define DECL_ANCHOR(name)
#define ISEQ_COVERAGE(iseq)
IFUNC (Internal FUNCtion)
void rb_report_bug_valist(VALUE file, int line, const char *fmt, va_list args)
struct iseq_link_element * prev
VALUE rb_iseq_compile_node(rb_iseq_t *iseq, NODE *node)
#define COVERAGE_INDEX_LINES
#define ADD_CALL_RECEIVER(seq, line)
#define VM_CHECKMATCH_ARRAY
VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt)
VALUE rb_syntax_error_append(VALUE exc, VALUE file, int line, int column, rb_encoding *enc, const char *fmt, va_list args)
const char * rb_id2name(ID)
#define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc)
VALUE rb_str_new_cstr(const char *)
#define INTEGER_PACK_LITTLE_ENDIAN
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
#define RARRAY_LENINT(ary)
RUBY_EXTERN VALUE rb_cNumeric
VALUE rb_complex_new(VALUE x, VALUE y)
enum rb_iseq_constant_body::iseq_type type
const struct rb_iseq_constant_body::@135::rb_iseq_param_keyword * keyword
#define ADD_INSN3(seq, line, insn, op1, op2, op3)
register unsigned int len
#define StringValueCStr(v)
void * ruby_xmalloc(size_t size)
VALUE rb_iseq_realpath(const rb_iseq_t *iseq)
const rb_iseq_t * rb_iseqw_to_iseq(VALUE iseqw)
#define ADD_TRACE_METHOD_COVERAGE(seq, line, method_name)
#define INTEGER_PACK_NEGATIVE
#define RB_OBJ_WRITE(a, slot, b)
#define RARRAY_ASET(a, i, v)
VALUE rb_iseq_disasm(const rb_iseq_t *iseq)
#define ISEQ_LINE_COVERAGE(iseq)
#define IBF_OBJBODY(type, offset)
#define debugp_param(header, value)
const struct iseq_catch_table * catch_table
#define RARRAY_AREF(a, i)
#define UNKNOWN_NODE(prefix, node, errval)
#define RBASIC_CLASS(obj)
VALUE rb_hash_aref(VALUE hash, VALUE key)
struct rb_iseq_struct * local_iseq
unsigned int ibf_offset_t
const char * ruby_node_name(int node)
VALUE rb_str_catf(VALUE str, const char *format,...)
#define IBF_W(b, type, n)
#define ISEQ_FLIP_CNT(iseq)
void rb_iseq_add_mark_object(const rb_iseq_t *iseq, VALUE obj)
rb_control_frame_t *FUNC_FASTCALL rb_insn_func_t(rb_thread_t *, rb_control_frame_t *)
void rb_check_safe_obj(VALUE)
struct rb_encoding_entry * list
#define ADD_ADJUST_RESTORE(seq, label)
struct iseq_inline_cache_entry * IC
#define BADINSN_DUMP(anchor, list, dest)
#define NEW_ISEQ(node, name, type, line_no)
#define TypedData_Make_Struct(klass, type, data_type, sval)
VALUE rb_ary_dup(VALUE ary)
VALUE rb_iseq_path(const rb_iseq_t *iseq)
const struct st_hash_type * type
#define ADD_CALL_WITH_BLOCK(seq, line, id, argc, block)
const struct rb_iseq_struct * parent_iseq
#define NEW_CHILD_ISEQ(node, name, type, line_no)
rb_execution_context_t ec
const struct iseq_line_info_entry * line_info_table
#define RUBY_EVENT_COVERAGE
long rb_str_strlen(VALUE)
int rb_eql(VALUE, VALUE)
Determines if obj1 and obj2 are equal in terms of Object::eql?.
int rb_is_attrset_id(ID id)
#define StringValuePtr(v)
VALUE() rb_ary_new_from_args(long n,...)
unsigned int line_info_size
rb_iseq_t * rb_iseq_new_with_opt(NODE *node, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_iseq_t *parent, enum iseq_type type, const rb_compile_option_t *option)
void rb_exc_fatal(VALUE mesg)
Raises a fatal error in the current thread.
#define RTYPEDDATA_DATA(v)
int rb_enc_find_index(const char *name)
#define RSTRING_LENINT(str)
#define CONST_ID(var, str)
#define SPECIAL_CONST_P(x)
#define ISEQ_COMPILE_DATA(iseq)
#define ADD_TRACE_BRANCH_COVERAGE(seq, line, type, branches)
union rb_iseq_struct::@137 aux
#define RB_INTEGER_TYPE_P(obj)
struct rb_global_entry * rb_global_entry(ID)
#define APPEND_LABEL(seq, before, label)
const rb_iseq_t * iseq_ibf_load(VALUE str)
struct iseq_adjust_data ADJUST
VALUE rb_str_append(VALUE, VALUE)
#define EXPECT_NODE_NONULL(prefix, parent, ndtype, errval)
rb_encoding * rb_enc_find(const char *name)
const struct ibf_header * header
#define RUBY_EVENT_B_CALL
enum ruby_vminsn_type insn_id
rb_iseq_location_t location
#define ADD_INSN1(seq, line, insn, op1)
#define IFUNC_NEW(a, b, c)
rb_encoding * rb_enc_from_index(int index)
VALUE rb_str_new(const char *, long)