22 #include "insns_info.inc"
24 #define ISEQ_MAJOR_VERSION 2
25 #define ISEQ_MINOR_VERSION 1
29 #define hidden_obj_p(obj) (!SPECIAL_CONST_P(obj) && !RBASIC(obj)->klass)
199 #define ISEQ_SET_CREF(iseq, cref) RB_OBJ_WRITE((iseq)->self, &(iseq)->cref_stack, (cref))
209 if (type == ISEQ_TYPE_TOP) {
216 cref->nd_refinements =
Qnil;
223 else if (type == ISEQ_TYPE_METHOD || type == ISEQ_TYPE_CLASS) {
228 else if (
RTEST(parent)) {
239 if (type == ISEQ_TYPE_MAIN) {
269 if (
RTEST(absolute_path))
309 if (
RTEST(coverages)) {
354 else if (opt ==
Qtrue) {
362 #define SET_COMPILE_OPTION(o, h, mem) \
363 { VALUE flag = rb_hash_aref((h), ID2SYM(rb_intern(#mem))); \
364 if (flag == Qtrue) { (o)->mem = 1; } \
365 else if (flag == Qfalse) { (o)->mem = 0; } \
367 #define SET_COMPILE_OPTION_NUM(o, h, mem) \
368 { VALUE num = rb_hash_aref(opt, ID2SYM(rb_intern(#mem))); \
369 if (!NIL_P(num)) (o)->mem = NUM2INT(num); \
380 #undef SET_COMPILE_OPTION
381 #undef SET_COMPILE_OPTION_NUM
392 #define SET_COMPILE_OPTION(o, h, mem) \
393 rb_hash_aset((h), ID2SYM(rb_intern(#mem)), (o)->mem ? Qtrue : Qfalse)
394 #define SET_COMPILE_OPTION_NUM(o, h, mem) \
395 rb_hash_aset((h), ID2SYM(rb_intern(#mem)), INT2NUM((o)->mem))
407 #undef SET_COMPILE_OPTION
408 #undef SET_COMPILE_OPTION_NUM
417 &COMPILE_OPTION_DEFAULT);
424 &COMPILE_OPTION_DEFAULT);
433 parent, ISEQ_TYPE_MAIN, &COMPILE_OPTION_DEFAULT);
447 prepare_iseq_build(iseq, name, path, absolute_path, first_lineno, parent, type, bopt, option);
469 bopt, &COMPILE_OPTION_DEFAULT);
472 #define CHECK_ARRAY(v) rb_convert_type((v), T_ARRAY, "Array", "to_ary")
473 #define CHECK_STRING(v) rb_convert_type((v), T_STRING, "String", "to_str")
474 #define CHECK_SYMBOL(v) rb_convert_type((v), T_SYMBOL, "Symbol", "to_sym")
481 VALUE magic, version1, version2, format_type, misc;
482 VALUE name, path, absolute_path, first_lineno;
483 VALUE type, body, locals, args, exception;
486 static struct st_table *type_map_cache = 0;
504 ((void)magic, (
void)version1, (void)version2, (
void)format_type, (void)misc);
524 iseq->
self = iseqval;
527 type_map = type_map_cache;
543 type_map = cached_map;
547 if (
st_lookup(type_map, type, &iseq_type) == 0) {
556 if (parent ==
Qnil) {
562 parent, (
enum iseq_type)iseq_type, 0, &option);
620 if (base_block && base_block->
iseq) {
622 file, absolute_path, line, base_block->
iseq->
self,
623 ISEQ_TYPE_EVAL, &option);
627 ISEQ_TYPE_TOP, &option);
681 rb_scan_args(argc, argv,
"14", &src, &file, &path, &line, &opt);
730 ISEQ_TYPE_TOP, &option);
771 COMPILE_OPTION_DEFAULT = option;
979 if (local_iseq->
type == ISEQ_TYPE_METHOD) {
1091 const int debug = 0;
1102 else if (
size == 1) {
1106 for (i=1; i<
size; i++) {
1107 if (debug) printf(
"table[%"PRIdSIZE"]: position: %d, line: %d, pos: %"PRIdSIZE"\n",
1110 if (table[i].position == pos) {
1113 if (table[i].position > pos) {
1149 str = default_value;
1160 int len,
size_t pos,
VALUE *pnop,
VALUE child)
1162 const char *types = insn_op_types(insn);
1163 char type = types[op_no];
1176 if (insn == BIN(getlocal) || insn == BIN(setlocal)) {
1181 for (i = 0; i < level; i++) {
1276 rb_bug(
"insn_operand_intern: unknown operand type: %c", type);
1289 VALUE insn = iseq[pos];
1290 int len = insn_len(insn);
1292 const char *types = insn_op_types(insn);
1294 const char *insn_name_buff;
1296 insn_name_buff = insn_name(insn);
1302 (
int)strcspn(insn_name_buff,
"_"), insn_name_buff);
1305 for (j = 0; types[j]; j++) {
1306 const char *types = insn_op_types(insn);
1308 len, pos, &iseq[pos + j + 2],
1319 unsigned int prev = pos == 0 ? 0 :
find_line_no(iseqdat, pos - 1);
1320 if (line_no && line_no != prev) {
1322 slen = (slen > 70) ? 0 : (70 - slen);
1323 str =
rb_str_catf(str,
"%*s(%4d)", (
int)slen,
"", line_no);
1341 case CATCH_TYPE_RESCUE:
1343 case CATCH_TYPE_ENSURE:
1345 case CATCH_TYPE_RETRY:
1347 case CATCH_TYPE_BREAK:
1349 case CATCH_TYPE_REDO:
1351 case CATCH_TYPE_NEXT:
1354 rb_bug(
"unknown catch type (%d)", type);
1389 enum {header_minlen = 72};
1393 iseq = iseqdat->
iseq;
1401 memset(
RSTRING_PTR(str) + l,
'=', header_minlen - l);
1412 "| catch type: %-6s st: %04d ed: %04d sp: %04d cont: %04d\n",
1414 (
int)entry->
end, (
int)entry->
sp, (
int)entry->
cont);
1420 rb_str_cat2(str,
"|-------------------------------------"
1421 "-----------------------------------\n");
1429 "local table (size: %d, argc: %d "
1430 "[opts: %d, rest: %d, post: %d, block: %d, keyword: %d@%d] s%d)\n",
1440 char argi[0x100] =
"";
1441 char opti[0x100] =
"";
1446 if (i >= argc && i < argc + opts - 1) {
1452 snprintf(argi,
sizeof(argi),
"%s%s%s%s%s",
1453 iseqdat->
argc > i ?
"Arg" :
"",
1455 iseqdat->
arg_rest == i ?
"Rest" :
"",
1457 i < iseqdat->arg_post_start + iseqdat->
arg_post_len) ?
"Post" :
"",
1458 iseqdat->
arg_block == i ?
"Block" :
"");
1473 for (n = 0; n <
size;) {
1606 #include "node_name.inc"
1608 rb_bug(
"unknown node (%d)", node);
1613 #define DECL_SYMBOL(name) \
1614 static VALUE sym_##name
1616 #define INIT_SYMBOL(name) \
1617 sym_##name = ID2SYM(rb_intern(#name))
1623 char buff[8 + (
sizeof(idx) *
CHAR_BIT * 32 / 100)];
1625 snprintf(buff,
sizeof(buff),
"label_%lu", idx);
1662 unsigned int line = 0;
1674 static VALUE insn_syms[VM_INSTRUCTION_SIZE];
1689 for (i=0; i<VM_INSTRUCTION_SIZE; i++) {
1704 switch (iseq->
type) {
1705 case ISEQ_TYPE_TOP: type = sym_top;
break;
1706 case ISEQ_TYPE_METHOD: type = sym_method;
break;
1707 case ISEQ_TYPE_BLOCK: type = sym_block;
break;
1708 case ISEQ_TYPE_CLASS: type = sym_class;
break;
1709 case ISEQ_TYPE_RESCUE: type = sym_rescue;
break;
1710 case ISEQ_TYPE_ENSURE: type = sym_ensure;
break;
1711 case ISEQ_TYPE_EVAL: type = sym_eval;
break;
1712 case ISEQ_TYPE_MAIN: type = sym_main;
break;
1713 case ISEQ_TYPE_DEFINED_GUARD: type = sym_defined_guard;
break;
1714 default:
rb_bug(
"unsupported iseq type");
1764 for (seq = iseq->
iseq; seq < iseq->iseq + iseq->
iseq_size; ) {
1765 VALUE insn = *seq++;
1766 int j, len = insn_len(insn);
1767 VALUE *nseq = seq + len - 1;
1771 for (j=0; j<len-1; j++, seq++) {
1772 switch (insn_op_type(insn, j)) {
1774 unsigned long idx = nseq - iseq->
iseq + *seq;
1833 unsigned long idx = nseq - iseq->
iseq + pos;
1842 rb_bug(
"unknown operand: %c", insn_op_type(insn, j));
1878 if (
st_lookup(labels_table, pos, &label)) {
1932 iseq1->
self = newiseq;
1957 ID req, opt, rest, block,
key, keyrest;
1958 #define PARAM_TYPE(type) rb_ary_push(a = rb_ary_new2(2), ID2SYM(type))
1959 #define PARAM_ID(i) iseq->local_table[(i)]
1960 #define PARAM(i, type) ( \
1962 rb_id2str(PARAM_ID(i)) ? \
1963 rb_ary_push(a, ID2SYM(PARAM_ID(i))) : \
1969 for (i = 0; i < iseq->
argc; i++) {
1976 for (i = 0; i < iseq->
argc; i++) {
1981 for (; i < r; i++) {
2041 static const char expr_names[][18] = {
2043 "instance-variable",
2060 if ((
unsigned)(type - 1) >= (
unsigned)
numberof(expr_names))
return 0;
2061 estr = expr_names[type - 1];
2062 if (!estr[0])
return 0;
2063 defs =
GET_VM()->defined_strings;
2066 GET_VM()->defined_strings = defs;
2084 const char **local_table,
2085 const VALUE *arg_opt_table,
2089 const unsigned short first_lineno)
2102 iseq->
self = iseqval;
2107 iseq->
iseq[i] = BIN(opt_call_c_function);
2113 #define ALLOC_AND_COPY(dst, src, type, size) do { \
2115 (dst) = ALLOC_N(type, (size)); \
2116 MEMCPY((dst), (src), type, (size)); \
2147 for (pos = 0; cont && pos < iseq->
iseq_size; pos += insn_len(insn)) {
2148 insn = iseq->
iseq[pos];
2150 if (insn == BIN(trace)) {
2160 cont = (*func)(line, &events, data);
2161 if (current_events != events) {
2163 (
VALUE)(current_events | (events & RUBY_EVENT_SPECIFIED_LINE));
2204 if (data->
pos == 0) {
2250 if (data.
prev == 0) {