Ruby
2.7.1p83(2020-03-31revisiona0c7c23c9cec0d0ffcba012279cd652d28ad5bf3)
|
Go to the documentation of this file.
20 #define RUBY_VM_INSNS_INFO 1
29 #include "insns_info.inc"
36 #if VM_INSN_INFO_TABLE_IMPL == 2
38 static unsigned int *succ_index_table_invert(
int max_pos,
struct succ_index_table *sd,
int size);
42 #define hidden_obj_p(obj) (!SPECIAL_CONST_P(obj) && !RBASIC(obj)->klass)
99 #if VM_INSN_INFO_TABLE_IMPL == 2
122 compile_data_free(ISEQ_COMPILE_DATA(
iseq));
133 #if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
135 rb_vm_insn_addr2insn2(
const void *addr)
142 rb_vm_insn_null_translator(
const void *addr)
153 VALUE insn = translator((
void *)code[pos]);
154 int len = insn_len(insn);
156 const char *
types = insn_op_types(insn);
158 for (op_no = 0;
types[op_no]; op_no++) {
165 VALUE op = code[pos + op_no + 1];
167 VALUE newop = func(data, op);
169 code[pos + op_no + 1] = newop;
200 #if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
203 rb_vm_insn_null_translator;
210 n += iseq_extract_values(code,
n, func, data, translator);
215 update_each_insn_value(
void *ctx,
VALUE obj)
238 rb_iseq_each_value(
iseq, update_each_insn_value,
NULL);
239 VALUE *original_iseq = ISEQ_ORIGINAL_ISEQ(
iseq);
244 n += iseq_extract_values(original_iseq,
n, update_each_insn_value,
NULL, rb_vm_insn_null_translator);
265 for (
i = 0;
i < table->
size;
i++) {
280 each_insn_value(
void *ctx,
VALUE obj)
297 rb_iseq_each_value(
iseq, each_insn_value,
NULL);
308 const struct rb_iseq_param_keyword *
const keyword = body->
param.
keyword;
311 i = keyword->required_num;
313 for (j = 0;
i < keyword->num;
i++, j++) {
314 VALUE obj = keyword->default_values[j];
324 for (
i = 0;
i < table->
size;
i++) {
360 param_keyword_size(
const struct rb_iseq_param_keyword *pkw)
364 if (!pkw)
return size;
366 size +=
sizeof(
struct rb_iseq_param_keyword);
367 size +=
sizeof(
VALUE) * (pkw->num - pkw->required_num);
414 compile_data = ISEQ_COMPILE_DATA(
iseq);
430 static uintptr_t fresh_iseq_unique_id = 0;
553 set_relation(
iseq, parent);
561 ISEQ_ORIGINAL_ISEQ_CLEAR(
iseq);
564 ISEQ_COMPILE_DATA_ALLOC(
iseq);
568 ISEQ_COMPILE_DATA(
iseq)->node.storage_head = ISEQ_COMPILE_DATA(
iseq)->node.storage_current = new_arena();
569 ISEQ_COMPILE_DATA(
iseq)->insn.storage_head = ISEQ_COMPILE_DATA(
iseq)->insn.storage_current = new_arena();
570 ISEQ_COMPILE_DATA(
iseq)->option = option;
572 ISEQ_COMPILE_DATA(
iseq)->ivar_cache_table =
NULL;
574 ISEQ_COMPILE_DATA(
iseq)->builtin_function_table =
GET_VM()->builtin_function_table;
578 if (
RTEST(coverages)) {
590 #if VM_CHECK_MODE > 0 && VM_INSN_INFO_TABLE_IMPL > 0
597 #if VM_INSN_INFO_TABLE_IMPL == 2
604 #if VM_CHECK_MODE == 0
611 #if VM_INSN_INFO_TABLE_IMPL == 2
618 return succ_index_table_invert(max_pos, sd,
size);
637 ISEQ_COMPILE_DATA_CLEAR(
iseq);
638 compile_data_free(data);
640 #if VM_INSN_INFO_TABLE_IMPL == 2
647 #if VM_CHECK_MODE > 0 && VM_INSN_INFO_TABLE_IMPL > 0
648 validate_get_insn_info(
iseq);
680 #define SET_COMPILE_OPTION(o, h, mem) \
681 { VALUE flag = rb_hash_aref((h), ID2SYM(rb_intern(#mem))); \
682 if (flag == Qtrue) { (o)->mem = 1; } \
683 else if (flag == Qfalse) { (o)->mem = 0; } \
685 #define SET_COMPILE_OPTION_NUM(o, h, mem) \
686 { VALUE num = rb_hash_aref(opt, ID2SYM(rb_intern(#mem))); \
687 if (!NIL_P(num)) (o)->mem = NUM2INT(num); \
700 #undef SET_COMPILE_OPTION
701 #undef SET_COMPILE_OPTION_NUM
708 set_compile_option_from_hash(option, opt);
715 *option = COMPILE_OPTION_DEFAULT;
718 *option = COMPILE_OPTION_FALSE;
720 else if (opt ==
Qtrue) {
723 ((
int *)option)[
i] = 1;
726 *option = COMPILE_OPTION_DEFAULT;
727 set_compile_option_from_hash(option, opt);
738 #define SET_COMPILE_OPTION(o, h, mem) \
739 rb_hash_aset((h), ID2SYM(rb_intern(#mem)), (o)->mem ? Qtrue : Qfalse)
740 #define SET_COMPILE_OPTION_NUM(o, h, mem) \
741 rb_hash_aset((h), ID2SYM(rb_intern(#mem)), INT2NUM((o)->mem))
755 #undef SET_COMPILE_OPTION
756 #undef SET_COMPILE_OPTION_NUM
765 &COMPILE_OPTION_DEFAULT);
772 if (
RTEST(coverages)) {
781 &COMPILE_OPTION_DEFAULT);
811 const NODE *node = ast ? ast->
root : 0;
816 new_opt = option ? *option : COMPILE_OPTION_DEFAULT;
822 finish_iseq_build(
iseq);
824 return iseq_translate(
iseq);
837 if (!option) option = &COMPILE_OPTION_DEFAULT;
841 finish_iseq_build(
iseq);
843 return iseq_translate(
iseq);
852 return iseqw_check(iseqv);
858 #define CHECK_ARRAY(v) rb_to_array_type(v)
859 #define CHECK_HASH(v) rb_to_hash_type(v)
860 #define CHECK_STRING(v) rb_str_to_str(v)
861 #define CHECK_SYMBOL(v) rb_to_symbol_type(v)
896 VALUE magic, version1, version2, format_type, misc;
898 VALUE type, body, locals, params, exception;
917 ((
void)magic, (
void)version1, (
void)version2, (
void)format_type);
948 make_compile_option(&option, opt);
955 finish_iseq_build(
iseq);
957 return iseqw_new(
iseq);
968 return iseq_load(data,
NULL, opt);
982 #if !defined(__GNUC__) || (__GNUC__ == 4 && __GNUC_MINOR__ == 8)
983 # define INITIALIZED volatile
992 make_compile_option(&option, opt);
1009 ast = (*parse)(parser, file,
src, ln);
1012 if (!ast->body.root) {
1092 remove_coverage_i(
void *vstart,
void *vend,
size_t stride,
void *data)
1095 for (;
v != (
VALUE)vend;
v += stride) {
1096 void *
ptr = asan_poisoned_object_p(
v);
1097 asan_unpoison_object(
v,
false);
1099 if (rb_obj_is_iseq(
v)) {
1118 iseqw_mark(
void *
ptr)
1124 iseqw_memsize(
const void *
ptr)
1131 {iseqw_mark,
NULL, iseqw_memsize,},
1142 union {
const rb_iseq_t *in;
void *out; } deconst;
1159 return iseqw_new(
iseq);
1204 case 5: opt =
argv[--
i];
1205 case 4: line =
argv[--
i];
1207 case 2: file =
argv[--
i];
1217 return iseqw_new(rb_iseq_compile_with_option(
src, file,
path, line, opt));
1252 case 2: opt =
argv[--
i];
1270 make_compile_option(&option, opt);
1275 line,
NULL, ISEQ_TYPE_TOP, &option));
1312 iseqw_s_compile_option_set(
VALUE self,
VALUE opt)
1315 make_compile_option(&option, opt);
1316 COMPILE_OPTION_DEFAULT = option;
1329 iseqw_s_compile_option_get(
VALUE self)
1331 return make_compile_option_value(&COMPILE_OPTION_DEFAULT);
1335 iseqw_check(
VALUE iseqw)
1352 return iseqw_check(iseqw);
1364 iseqw_eval(
VALUE self)
1374 iseqw_inspect(
VALUE self)
1415 iseqw_path(
VALUE self)
1437 iseqw_absolute_path(
VALUE self)
1466 iseqw_label(
VALUE self)
1492 iseqw_base_label(
VALUE self)
1508 iseqw_first_lineno(
VALUE self)
1597 iseqw_to_a(
VALUE self)
1600 return iseq_data_to_ary(
iseq);
1603 #if VM_INSN_INFO_TABLE_IMPL == 1
1605 get_insn_info_binary_search(
const rb_iseq_t *
iseq,
size_t pos)
1611 const int debug = 0;
1616 (
size_t)0, positions[0], insns_info[0].
line_no, pos);
1622 else if (
size == 1) {
1623 return &insns_info[0];
1626 size_t l = 1, r =
size - 1;
1628 size_t m = l + (r - l) / 2;
1629 if (positions[m] == pos) {
1630 return &insns_info[m];
1632 if (positions[m] < pos) {
1640 return &insns_info[
size-1];
1642 if (positions[l] > pos) {
1643 return &insns_info[l-1];
1645 return &insns_info[l];
1652 return get_insn_info_binary_search(
iseq, pos);
1656 #if VM_INSN_INFO_TABLE_IMPL == 2
1658 get_insn_info_succinct_bitvector(
const rb_iseq_t *
iseq,
size_t pos)
1663 const int debug = 0;
1666 #if VM_CHECK_MODE > 0
1670 (
size_t)0, positions[0], insns_info[0].
line_no, pos);
1674 (
size_t)0, insns_info[0].
line_no, pos);
1681 else if (
size == 1) {
1682 return &insns_info[0];
1688 return &insns_info[
index-1];
1695 return get_insn_info_succinct_bitvector(
iseq, pos);
1699 #if VM_CHECK_MODE > 0 || VM_INSN_INFO_TABLE_IMPL == 0
1701 get_insn_info_linear_search(
const rb_iseq_t *
iseq,
size_t pos)
1707 const int debug = 0;
1712 i, positions[
i], insns_info[
i].
line_no, pos);
1718 else if (
size == 1) {
1719 return &insns_info[0];
1724 i, positions[
i], insns_info[
i].
line_no, pos);
1726 if (positions[
i] == pos) {
1727 return &insns_info[
i];
1729 if (positions[
i] > pos) {
1730 return &insns_info[
i-1];
1734 return &insns_info[
i-1];
1738 #if VM_INSN_INFO_TABLE_IMPL == 0
1742 return get_insn_info_linear_search(
iseq, pos);
1746 #if VM_CHECK_MODE > 0 && VM_INSN_INFO_TABLE_IMPL > 0
1753 if (get_insn_info_linear_search(
iseq,
i) != get_insn_info(
iseq,
i)) {
1754 rb_bug(
"validate_get_insn_info: get_insn_info_linear_search(iseq, %"PRIuSIZE") != get_insn_info(iseq, %"PRIuSIZE")",
i,
i);
1806 for (
i = 0;
i < level;
i++) {
1832 const char *
types = insn_op_types(insn);
1842 if (insn ==
BIN(defined) && op_no == 0) {
1860 else if (insn ==
BIN(checktype) && op_no == 0) {
1871 if (
types[op_no+1] == TS_NUM && pnop) {
1887 op = obj_resurrect(op);
1888 if (insn ==
BIN(defined) && op_no == 1 &&
FIXNUM_P(op)) {
1956 # define CALL_FLAG(n) if (ci->flag & VM_CALL_##n) rb_ary_push(flags, rb_str_new2(#n))
1984 if (dladdr((
void *)op, &info) && info.dli_sname) {
2011 while (end-- > beg && *end ==
' ');
2024 VALUE insn = code[pos];
2025 int len = insn_len(insn);
2027 const char *
types = insn_op_types(insn);
2029 const char *insn_name_buff;
2031 insn_name_buff = insn_name(insn);
2033 extern const int rb_vm_max_insn_name_size;
2038 (
int)
strcspn(insn_name_buff,
"_"), insn_name_buff);
2041 for (j = 0;
types[j]; j++) {
2043 len, pos, &code[pos + j + 2],
2055 if (line_no && line_no != prev) {
2057 slen = (slen > 70) ? 0 : (70 - slen);
2092 catch_type(
int type)
2095 case CATCH_TYPE_RESCUE:
2097 case CATCH_TYPE_ENSURE:
2099 case CATCH_TYPE_RETRY:
2101 case CATCH_TYPE_BREAK:
2103 case CATCH_TYPE_REDO:
2105 case CATCH_TYPE_NEXT:
2149 enum {header_minlen = 72};
2152 const char *indent_str;
2184 "| catch type: %-6s st: %04d ed: %04d sp: %04d cont: %04d\n",
2186 (
int)entry->
end, (
int)entry->
sp, (
int)entry->
cont);
2203 "-----------------------------------\n");
2208 const struct rb_iseq_param_keyword *
const keyword = body->
param.
keyword;
2211 "local table (size: %d, argc: %d "
2212 "[opts: %d, rest: %d, post: %d, block: %d, kw: %d@%d, kwrest: %d])\n",
2219 body->
param.
flags.has_kw ? keyword->num : -1,
2220 body->
param.
flags.has_kw ? keyword->required_num : -1,
2221 body->
param.
flags.has_kwrest ? keyword->rest_start : -1);
2234 if (li >=
argc && li <
argc + opts) {
2240 snprintf(argi,
sizeof(argi),
"%s%s%s%s%s%s",
2245 (body->
param.
flags.has_kwrest && keyword->rest_start == li) ?
"Kwrest" :
"",
2302 iseqw_disasm(
VALUE self)
2308 iseq_iterate_children(
const rb_iseq_t *
iseq,
void (*iter_func)(
const rb_iseq_t *child_iseq,
void *data),
void *data)
2320 child = entry->
iseq;
2324 (*iter_func)(child, data);
2332 int len = insn_len(insn);
2333 const char *
types = insn_op_types(insn);
2336 for (j=0;
types[j]; j++) {
2343 (*iter_func)(child, data);
2358 yield_each_children(
const rb_iseq_t *child_iseq,
void *data)
2372 iseqw_each_child(
VALUE self)
2375 iseq_iterate_children(
iseq, yield_each_children,
NULL);
2382 #define C(ev, cstr, l) if (events & ev) rb_ary_push(ary, rb_ary_new_from_args(2, l, ID2SYM(rb_intern(cstr))));
2401 iseqw_trace_points(
VALUE self)
2458 iseq = vm_proc_iseq(body);
2537 #include "node_name.inc"
2539 rb_bug(
"unknown node: %d", node);
2544 #define DECL_SYMBOL(name) \
2545 static ID sym_##name
2547 #define INIT_SYMBOL(name) \
2548 sym_##name = rb_intern(#name)
2551 register_label(
struct st_table *table,
unsigned long idx)
2563 case CATCH_TYPE_RESCUE:
CONST_ID(
id,
"rescue");
break;
2564 case CATCH_TYPE_ENSURE:
CONST_ID(
id,
"ensure");
break;
2565 case CATCH_TYPE_RETRY:
CONST_ID(
id,
"retry");
break;
2566 case CATCH_TYPE_BREAK:
CONST_ID(
id,
"break");
break;
2567 case CATCH_TYPE_REDO:
CONST_ID(
id,
"redo");
break;
2568 case CATCH_TYPE_NEXT:
CONST_ID(
id,
"next");
break;
2570 rb_bug(
"unknown exception type: %d", (
int)
type);
2598 VALUE *seq, *iseq_original;
2640 switch (iseq_body->
type) {
2641 case ISEQ_TYPE_TOP:
type = sym_top;
break;
2642 case ISEQ_TYPE_METHOD:
type = sym_method;
break;
2643 case ISEQ_TYPE_BLOCK:
type = sym_block;
break;
2644 case ISEQ_TYPE_CLASS:
type = sym_class;
break;
2645 case ISEQ_TYPE_RESCUE:
type = sym_rescue;
break;
2646 case ISEQ_TYPE_ENSURE:
type = sym_ensure;
break;
2647 case ISEQ_TYPE_EVAL:
type = sym_eval;
break;
2648 case ISEQ_TYPE_MAIN:
type = sym_main;
break;
2649 case ISEQ_TYPE_PLAIN:
type = sym_plain;
break;
2650 default:
rb_bug(
"unsupported iseq type: %d", (
int)iseq_body->
type);
2671 const struct rb_iseq_param_keyword *
const keyword = iseq_body->
param.
keyword;
2678 for (j = 0; j <
len; j++) {
2694 for (
i=0;
i<keyword->required_num;
i++) {
2697 for (j=0;
i<keyword->num;
i++, j++) {
2699 if (keyword->default_values[j] !=
Qundef) {
2706 INT2FIX(keyword->bits_start));
2716 for (seq = iseq_original; seq < iseq_original + iseq_body->
iseq_size; ) {
2717 VALUE insn = *seq++;
2718 int j,
len = insn_len(insn);
2723 for (j=0; j<
len-1; j++, seq++) {
2724 switch (insn_op_type(insn, j)) {
2726 unsigned long idx = nseq - iseq_original + *seq;
2727 rb_ary_push(ary, register_label(labels_table, idx));
2741 VALUE val = iseq_data_to_ary(rb_iseq_check(
iseq));
2803 unsigned long idx = nseq - iseq_original + pos;
2806 register_label(labels_table, idx));
2813 #if SIZEOF_VALUE <= SIZEOF_LONG
2824 #if SIZEOF_VALUE <= SIZEOF_LONG
2837 rb_bug(
"unknown operand: %c", insn_op_type(insn, j));
2866 prev_insn_info =
NULL;
2873 if (
st_lookup(labels_table, pos, &label)) {
2877 info = get_insn_info(
iseq, pos);
2879 if (prev_insn_info != info) {
2883 if (line > 0 && last_line != line) {
2887 #define CHECK_EVENT(ev) if (events & ev) rb_ary_push(body, ID2SYM(rb_intern(#ev)));
2896 prev_insn_info = info;
2943 const struct rb_iseq_param_keyword *
const keyword = body->
param.
keyword;
2945 ID req, opt, rest, block,
key, keyrest;
2946 #define PARAM_TYPE(type) rb_ary_push(a = rb_ary_new2(2), ID2SYM(type))
2947 #define PARAM_ID(i) body->local_table[(i)]
2948 #define PARAM(i, type) ( \
2950 rb_id2str(PARAM_ID(i)) ? \
2951 rb_ary_push(a, ID2SYM(PARAM_ID(i))) : \
2969 for (;
i < r;
i++) {
3001 if (keyword->required_num > 0) {
3004 for (;
i < keyword->required_num;
i++) {
3013 for (;
i < keyword->num;
i++) {
3035 static const char expr_names[][18] = {
3037 "instance-variable",
3054 if ((
unsigned)(
type - 1) >= (
unsigned)
numberof(expr_names))
return 0;
3055 estr = expr_names[
type - 1];
3056 if (!estr[0])
return 0;
3057 defs =
GET_VM()->defined_strings;
3060 GET_VM()->defined_strings = defs;
3075 static st_table *encoded_insn_data;
3087 #if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
3089 #define INSN_CODE(insn) ((VALUE)table[insn])
3091 #define INSN_CODE(insn) (insn)
3100 insn_data[insn].
insn = (
int)insn;
3101 insn_data[insn].
insn_len = insn_len(insn);
3118 return (
int)e->
insn;
3121 rb_bug(
"rb_vm_insn_addr2insn: invalid insn address: %p", addr);
3136 rb_bug(
"trace_instrument: invalid insn address: %p", (
void *)*iseq_encoded_insn);
3163 if (target_line == 0 || target_line == line) {
3170 if (pc_events & target_events) {
3173 pc += encoded_iseq_trace_instrument(&iseq_encoded[
pc], pc_events & (target_events |
iseq->
aux.
exec.global_trace_events));
3198 iseq_iterate_children(
iseq, iseq_add_local_tracepoint_i, p);
3210 iseq_add_local_tracepoint_i(
iseq, (
void *)&data);
3227 local_events =
iseq->
aux.
exec.local_hooks->events;
3229 if (local_events == 0) {
3250 iseq_remove_local_tracepoint_i(
const rb_iseq_t *
iseq,
void *p)
3253 data->
n += iseq_remove_local_tracepoint(
iseq, data->
tpval);
3254 iseq_iterate_children(
iseq, iseq_remove_local_tracepoint_i, p);
3264 iseq_remove_local_tracepoint_i(
iseq, (
void *)&data);
3271 if (
iseq->
aux.
exec.global_trace_events == turnon_events) {
3285 ((
rb_iseq_t *)
iseq)->aux.exec.global_trace_events = turnon_events;
3286 enabled_events = turnon_events | local_events;
3290 pc += encoded_iseq_trace_instrument(&
iseq_encoded[
pc], pc_events & enabled_events);
3296 trace_set_i(
void *vstart,
void *vend,
size_t stride,
void *data)
3301 for (;
v != (
VALUE)vend;
v += stride) {
3302 void *
ptr = asan_poisoned_object_p(
v);
3303 asan_unpoison_object(
v,
false);
3305 if (rb_obj_is_iseq(
v)) {
3381 #if VM_INSN_INFO_TABLE_IMPL == 2
3414 #define IMMEDIATE_TABLE_SIZE 54
3425 #define imm_block_rank_set(v, i, r) (v) |= (uint64_t)(r) << (7 * (i))
3426 #define imm_block_rank_get(v, i) (((int)((v) >> ((i) * 7))) & 0x7f)
3427 #define small_block_rank_set(v, i, r) (v) |= (uint64_t)(r) << (9 * ((i) - 1))
3428 #define small_block_rank_get(v, i) ((i) == 0 ? 0 : (((int)((v) >> (((i) - 1) * 9))) & 0x1ff))
3431 succ_index_table_create(
int max_pos,
int *data,
int size)
3438 succ_size,
sizeof(
struct succ_dict_block));
3442 for (j = 0; j < imm_size; j++) {
3443 for (
i = 0;
i < 9;
i++) {
3444 if (r <
size && data[r] == j * 9 +
i) r++;
3448 for (k = 0; k < succ_size; k++) {
3449 struct succ_dict_block *sd_block = &sd->
succ_part[k];
3452 for (j = 0; j < 8; j++) {
3455 for (
i = 0;
i < 64;
i++) {
3461 sd_block->bits[j] = bits;
3462 small_rank += rb_popcount64(bits);
3468 static unsigned int *
3473 unsigned int *positions =
ALLOC_N(
unsigned int,
size), *p;
3474 int i, j, k, r = -1;
3476 for (j = 0; j < imm_size; j++) {
3477 for (
i = 0;
i < 9;
i++) {
3479 if (r != nr) *p++ = j * 9 +
i;
3483 for (k = 0; k < succ_size; k++) {
3484 for (j = 0; j < 8; j++) {
3485 for (
i = 0;
i < 64;
i++) {
3499 const int i = x / 9;
3500 const int j = x % 9;
3505 const struct succ_dict_block *block = &sd->
succ_part[block_index];
3507 const int small_block_index = block_bit_index / 64;
3508 const int small_block_popcount =
small_block_rank_get(block->small_block_ranks, small_block_index);
3509 const int popcnt = rb_popcount64(block->bits[small_block_index] << (63 - block_bit_index % 64));
3511 return block->rank + small_block_popcount + popcnt;
VALUE rb_iseq_realpath(const rb_iseq_t *iseq)
VALUE rb_parser_new(void)
int rb_str_symname_p(VALUE)
VALUE rb_check_funcall(VALUE, ID, int, const VALUE *)
VALUE rb_str_concat(VALUE, VALUE)
size_t rb_iseq_memsize(const rb_iseq_t *iseq)
#define OPT_INSTRUCTIONS_UNIFICATION
VALUE rb_iseq_local_variables(const rb_iseq_t *iseq)
const char * ruby_node_name(int node)
#define IMMEDIATE_TABLE_SIZE
void * rb_xcalloc_mul_add_mul(size_t x, size_t y, size_t z, size_t w)
VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt)
VALUE rb_iseq_eval(const rb_iseq_t *iseq)
ID rb_check_id(volatile VALUE *)
Returns ID for the given name if it is interned already, or 0.
VALUE rb_iseq_label(const rb_iseq_t *iseq)
#define SET_COMPILE_OPTION_NUM(o, h, mem)
VALUE rb_iseq_first_lineno(const rb_iseq_t *iseq)
#define RUBY_MARK_NO_PIN_UNLESS_NULL(ptr)
VALUE rb_obj_hide(VALUE obj)
Make the object invisible from Ruby code.
#define RUBY_MARK_LEAVE(msg)
VALUE rb_ident_hash_new(void)
void rb_gc_register_mark_object(VALUE obj)
MJIT_FUNC_EXPORTED VALUE rb_hash_resurrect(VALUE hash)
const char * rb_type_str(enum ruby_value_type type)
struct rb_iseq_constant_body::iseq_insn_info insns_info
struct succ_index_table::succ_dict_block succ_part[FLEX_ARY_LEN]
VALUE rb_iseq_disasm(const rb_iseq_t *iseq)
void rb_ast_dispose(rb_ast_t *ast)
struct succ_index_table * succ_index_table
VALUE rb_iseq_pathobj_new(VALUE path, VALUE realpath)
#define st_is_member(table, key)
struct iseq_compile_data_storage * storage_head
rb_event_flag_t turnon_events
rb_iseq_t * rb_iseq_new_top(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent)
VALUE rb_hash_aref(VALUE hash, VALUE key)
st_table * st_init_numtable(void)
rb_code_location_t code_location
void rb_ary_store(VALUE ary, long idx, VALUE val)
#define offsetof(p_type, field)
#define RB_TYPE_P(obj, type)
#define ISEQ_MINOR_VERSION
VALUE rb_gc_location(VALUE value)
rb_event_flag_t ruby_vm_event_enabled_global_flags
#define ISEQ_NOT_LOADED_YET
void st_add_direct(st_table *tab, st_data_t key, st_data_t value)
VALUE rb_iseq_path(const rb_iseq_t *iseq)
struct rb_iseq_struct::@181::@182 loader
unsigned long long uint64_t
rb_iseq_location_t location
#define OPT_OPERANDS_UNIFICATION
VALUE rb_inspect(VALUE)
Convenient wrapper of Object::inspect.
VALUE rb_ary_resurrect(VALUE ary)
rb_ast_t * rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE file, int start)
const struct rb_iseq_constant_body::@178::rb_iseq_param_keyword * keyword
struct rb_iseq_struct * local_iseq
#define RUBY_EVENT_B_RETURN
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
#define hidden_obj_p(obj)
VALUE rb_str_inspect(VALUE)
rb_iseq_t * rb_iseq_new(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent, enum iseq_type type)
const struct rb_iseq_struct * parent_iseq
union rb_iseq_struct::@181 aux
#define SPECIAL_CONST_P(x)
void rb_ibf_load_iseq_complete(rb_iseq_t *iseq)
struct insn_data_struct insn_data_t
unsigned int coverage_enabled
int st_insert(st_table *tab, st_data_t key, st_data_t value)
#define SET_COMPILE_OPTION(o, h, mem)
void rb_mark_set(st_table *tbl)
struct iseq_compile_data::@117 insn
int rb_respond_to(VALUE, ID)
void rb_undef_method(VALUE klass, const char *name)
VALUE rb_iseq_coverage(const rb_iseq_t *iseq)
MJIT_FUNC_EXPORTED VALUE rb_hash_new_with_size(st_index_t size)
struct rb_iseq_constant_body * rb_iseq_constant_body_alloc(void)
#define RARRAY_LENINT(ary)
VALUE rb_str_resize(VALUE, long)
void rb_iseq_code_location(const rb_iseq_t *iseq, int *beg_pos_lineno, int *beg_pos_column, int *end_pos_lineno, int *end_pos_column)
struct rb_call_info_with_kwarg ci_kw
VALUE * rb_iseq_original_iseq(const rb_iseq_t *iseq)
void rb_raise(VALUE exc, const char *fmt,...)
int rb_iseq_remove_local_tracepoint_recursively(const rb_iseq_t *iseq, VALUE tpval)
VALUE rb_ary_entry(VALUE ary, long offset)
#define ISEQ_PC2BRANCHINDEX_SET(iseq, h)
if((ID)(DISPID) nameid !=nameid)
VALUE rb_obj_class(VALUE)
Equivalent to Object#class in Ruby.
struct iseq_compile_data::@116 node
VALUE rb_obj_is_proc(VALUE)
MJIT_FUNC_EXPORTED rb_event_flag_t rb_iseq_event_flags(const rb_iseq_t *iseq, size_t pos)
struct rb_iseq_constant_body::@178 param
parameter information
VALUE rb_file_open_str(VALUE, const char *)
#define ISEQ_BRANCH_COVERAGE(iseq)
#define RUBY_EVENT_COVERAGE_LINE
const rb_iseq_t * rb_iseqw_to_iseq(VALUE iseqw)
rb_iseq_t * rb_iseq_new_main(const rb_ast_body_t *ast, VALUE path, VALUE realpath, const rb_iseq_t *parent)
VALUE rb_str_intern(VALUE)
VALUE rb_iseqw_new(const rb_iseq_t *iseq)
void rb_iseq_init_trace(rb_iseq_t *iseq)
void rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *storage)
st_table * st_init_numtable_with_size(st_index_t size)
const rb_iseq_t * rb_iseq_load_iseq(VALUE fname)
const void ** rb_vm_get_insns_address_table(void)
#define OPT_FROZEN_STRING_LITERAL
unsigned int local_table_size
union iseq_inline_storage_entry * is_entries
void * trace_encoded_insn
VALUE rb_ary_tmp_new(long capa)
#define COVERAGE_TARGET_ONESHOT_LINES
#define imm_block_rank_get(v, i)
VALUE rb_iseqw_local_variables(VALUE iseqval)
#define RB_OBJ_WRITTEN(a, oldv, b)
VALUE rb_iseq_defined_string(enum defined_type type)
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params, VALUE exception, VALUE body)
int rb_iseq_disasm_insn(VALUE ret, const VALUE *code, size_t pos, const rb_iseq_t *iseq, VALUE child)
Disassemble a instruction Iseq -> Iseq inspect object.
VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict)
void rb_hook_list_remove_tracepoint(rb_hook_list_t *list, VALUE tpval)
void rb_hook_list_connect_tracepoint(VALUE target, rb_hook_list_t *list, VALUE tpval, unsigned int target_line)
struct rb_iseq_constant_body::@179 variable
#define INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE
void rb_hook_list_free(rb_hook_list_t *hooks)
VALUE rb_hash_lookup(VALUE hash, VALUE key)
VALUE iseq_value_itr_t(void *ctx, VALUE obj)
VALUE rb_ary_push(VALUE ary, VALUE item)
struct rb_call_info_kw_arg * kw_arg
void * ruby_xcalloc(size_t n, size_t size)
void rb_iseq_free(const rb_iseq_t *iseq)
#define OPT_SPECIALISED_INSTRUCTION
struct iseq_catch_table * catch_table
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
#define TypedData_Wrap_Struct(klass, data_type, sval)
enum rb_iseq_constant_body::iseq_type type
void rb_iseq_remove_coverage_all(void)
#define RBASIC_CLASS(obj)
unsigned int peephole_optimization
VALUE rb_get_coverages(void)
VALUE rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node)
#define RUBY_FREE_LEAVE(msg)
#define RUBY_FREE_ENTER(msg)
#define RARRAY_AREF(a, i)
void rb_str_set_len(VALUE, long)
#define OPT_TAILCALL_OPTIMIZATION
const struct iseq_insn_info_entry * body
void rb_gc_mark_movable(VALUE ptr)
int rb_typeddata_is_instance_of(VALUE obj, const rb_data_type_t *data_type)
VALUE rb_iseq_base_label(const rb_iseq_t *iseq)
rb_ast_t * rb_parser_compile_string_path(VALUE vparser, VALUE f, VALUE s, int line)
struct rb_iseq_constant_body::@178::@180 flags
void rb_hash_foreach(VALUE hash, rb_foreach_func *func, VALUE farg)
VALUE rb_vm_insns_translator_t(const void *addr)
enum iseq_catch_table_entry::catch_type type
#define OPT_STACK_CACHING
MJIT_STATIC void rb_error_arity(int argc, int min, int max)
#define RB_OBJ_WRITE(a, slot, b)
#define CONST_ID(var, str)
#define StringValueCStr(v)
void rb_vm_encoded_insn_data_table_init(void)
int rb_vm_insn_addr2insn(const void *addr)
unsigned int rb_iseq_line_no(const rb_iseq_t *iseq, size_t pos)
#define RUBY_MARK_UNLESS_NULL(ptr)
#define ISEQ_USE_COMPILE_DATA
void rb_id_table_free(struct rb_id_table *tbl)
void rb_hook_list_mark(rb_hook_list_t *hooks)
#define DECL_SYMBOL(name)
#define FL_TEST_RAW(x, f)
RUBY_EXTERN VALUE rb_cObject
#define ISEQ_COVERAGE_SET(iseq, cov)
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
void rb_objspace_each_objects(each_obj_callback *callback, void *data)
#define OPT_INLINE_CONST_CACHE
VALUE rb_str_append(VALUE, VALUE)
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
void rb_bug(const char *fmt,...)
#define RUBY_MARK_ENTER(msg)
struct rb_id_table * ivar_cache_table
rb_code_location_t nd_loc
rb_iseq_t * iseq_alloc(void)
#define INIT_SYMBOL(name)
VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
#define small_block_rank_get(v, i)
VALUE rb_sprintf(const char *format,...)
VALUE rb_insn_operand_intern(const rb_iseq_t *iseq, VALUE insn, int op_no, VALUE op, int len, size_t pos, const VALUE *pnop, VALUE child)
void rb_iseq_mark(const rb_iseq_t *iseq)
VALUE rb_ary_join(VALUE ary, VALUE sep)
void rb_iseq_insns_info_encode_positions(const rb_iseq_t *iseq)
char str[HTML_ESCAPE_MAX_LEN+1]
#define ISEQ_MAJOR_VERSION
#define RUBY_TYPED_FREE_IMMEDIATELY
VALUE rb_parser_set_context(VALUE vparser, const struct rb_iseq_struct *base, int main)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
void rb_iseq_clear_event_flags(const rb_iseq_t *iseq, size_t pos, rb_event_flag_t reset)
#define ISEQ_MARKABLE_ISEQ
void rb_str_modify_expand(VALUE, long)
#define ISEQ_COVERAGE(iseq)
const ID rb_iseq_shared_exc_local_tbl[]
rb_code_position_t beg_pos
#define RUBY_EVENT_B_CALL
int rb_get_coverage_mode(void)
uint64_t imm_part[IMMEDIATE_TABLE_SIZE/9]
#define imm_block_rank_set(v, i, r)
rb_iseq_t * rb_iseq_new_with_opt(const rb_ast_body_t *ast, 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_gc_mark(VALUE ptr)
#define MJIT_FUNC_EXPORTED
#define asan_poison_object_if(ptr, obj)
#define RUBY_EVENT_C_RETURN
void rb_iseq_trace_set_all(rb_event_flag_t turnon_events)
rb_iseq_t * rb_iseq_new_with_callback(const struct rb_iseq_new_with_callback_callback_func *ifunc, VALUE name, VALUE path, VALUE realpath, VALUE first_lineno, const rb_iseq_t *parent, enum iseq_type type, const rb_compile_option_t *option)
int rb_iseq_add_local_tracepoint_recursively(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval, unsigned int target_line)
VALUE rb_str_catf(VALUE str, const char *format,...)
VALUE rb_iseq_ibf_load_extra_data(VALUE str)
VALUE rb_obj_is_method(VALUE)
VALUE rb_class_name(VALUE)
void rb_iseq_pathobj_set(const rb_iseq_t *iseq, VALUE path, VALUE realpath)
void rb_iseq_trace_flag_cleared(const rb_iseq_t *iseq, size_t pos)
void rb_mark_tbl(st_table *tbl)
struct rb_iseq_constant_body * body
const VALUE catch_table_ary
const rb_iseq_t * rb_iseq_ibf_load(VALUE str)
#define RUBY_EVENT_RETURN
void * notrace_encoded_insn
int rb_insn_unified_local_var_level(VALUE)
#define RUBY_EVENT_C_CALL
VALUE rb_define_class_under(VALUE outer, const char *name, VALUE super)
Defines a class under the namespace of outer.
VALUE rb_str_resurrect(VALUE str)
#define OPT_DEBUG_FROZEN_STRING_LITERAL
const rb_iseq_t * rb_method_iseq(VALUE body)
rb_code_position_t end_pos
#define OPT_PEEPHOLE_OPTIMIZATION
#define RUBY_EVENT_COVERAGE_BRANCH
#define rb_fstring_lit(str)
VALUE rb_iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt)
int st_lookup(st_table *tab, st_data_t key, st_data_t *value)
VALUE rb_iseq_absolute_path(const rb_iseq_t *iseq)
#define UNALIGNED_MEMBER_PTR(ptr, mem)
struct rb_call_data * call_data
struct rb_iseq_struct::@181::@183 exec
uint64_t small_block_ranks
void rb_undef_alloc_func(VALUE)
void rb_iseq_trace_set(const rb_iseq_t *iseq, rb_event_flag_t turnon_events)
VALUE rb_iseq_method_name(const rb_iseq_t *iseq)
void rb_iseq_update_references(rb_iseq_t *iseq)
void st_free_table(st_table *tab)
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
struct iseq_compile_data_storage * next
VALUE rb_str_cat(VALUE, const char *, long)
VALUE rb_default_coverage(int)
unsigned int * rb_iseq_insns_info_decode_positions(const struct rb_iseq_constant_body *body)
VALUE type(ANYARGS)
ANYARGS-ed function type.
VALUE rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func *ifunc)
#define ISEQ_TRACE_EVENTS
#define ISEQ_EXECUTABLE_P(iseq)
#define RUBY_TYPED_WB_PROTECTED
#define small_block_rank_set(v, i, r)
int rb_str_cmp(VALUE, VALUE)
struct iseq_inline_storage_entry::@177 once