23 #define ISEQ_MAJOR_VERSION 1
24 #define ISEQ_MINOR_VERSION 2
28 #define hidden_obj_p(obj) (!SPECIAL_CONST_P(obj) && !RBASIC(obj)->klass)
184 if (type == ISEQ_TYPE_TOP) {
195 else if (type == ISEQ_TYPE_METHOD || type == ISEQ_TYPE_CLASS) {
198 else if (
RTEST(parent)) {
204 if (type == ISEQ_TYPE_TOP ||
205 type == ISEQ_TYPE_METHOD || type == ISEQ_TYPE_CLASS) {
208 else if (
RTEST(parent)) {
220 if (type == ISEQ_TYPE_MAIN) {
237 iseq->
line_no = (
unsigned short)line_no;
279 if (
RTEST(coverages)) {
324 else if (opt ==
Qtrue) {
330 #define SET_COMPILE_OPTION(o, h, mem) \
331 { VALUE flag = rb_hash_aref((h), ID2SYM(rb_intern(#mem))); \
332 if (flag == Qtrue) { (o)->mem = 1; } \
333 else if (flag == Qfalse) { (o)->mem = 0; } \
335 #define SET_COMPILE_OPTION_NUM(o, h, mem) \
336 { VALUE num = rb_hash_aref(opt, ID2SYM(rb_intern(#mem))); \
337 if (!NIL_P(num)) (o)->mem = NUM2INT(num); \
348 #undef SET_COMPILE_OPTION
349 #undef SET_COMPILE_OPTION_NUM
360 #define SET_COMPILE_OPTION(o, h, mem) \
361 rb_hash_aset((h), ID2SYM(rb_intern(#mem)), (o)->mem ? Qtrue : Qfalse)
362 #define SET_COMPILE_OPTION_NUM(o, h, mem) \
363 rb_hash_aset((h), ID2SYM(rb_intern(#mem)), INT2NUM((o)->mem))
374 #undef SET_COMPILE_OPTION
375 #undef SET_COMPILE_OPTION_NUM
384 &COMPILE_OPTION_DEFAULT);
391 &COMPILE_OPTION_DEFAULT);
400 parent, ISEQ_TYPE_MAIN, &COMPILE_OPTION_DEFAULT);
414 prepare_iseq_build(iseq, name, filename, filepath, line_no, parent, type, bopt, option);
436 bopt, &COMPILE_OPTION_DEFAULT);
439 #define CHECK_ARRAY(v) rb_convert_type((v), T_ARRAY, "Array", "to_ary")
440 #define CHECK_STRING(v) rb_convert_type((v), T_STRING, "String", "to_str")
441 #define CHECK_SYMBOL(v) rb_convert_type((v), T_SYMBOL, "Symbol", "to_sym")
448 VALUE magic, version1, version2, format_type, misc;
453 static struct st_table *type_map_cache = 0;
490 iseq->
self = iseqval;
492 type_map = type_map_cache;
508 type_map = cached_map;
512 if (
st_lookup(type_map, type, &iseq_type) == 0) {
520 if (parent ==
Qnil) {
526 parent, (
enum iseq_type)iseq_type, 0, &option);
574 ISEQ_TYPE_EVAL, &option);
578 ISEQ_TYPE_TOP, &option);
595 rb_scan_args(argc, argv,
"14", &src, &file, &path, &line, &opt);
624 ISEQ_TYPE_TOP, &option);
633 COMPILE_OPTION_DEFAULT = option;
701 for (i = 0; i <
size; i++) {
710 static unsigned short
722 static unsigned short
728 for (i = 0; i <
size; i++) {
747 const char *
types = insn_op_types(insn);
748 char type = types[op_no];
775 if (insn == BIN(getdynamic) || insn == BIN(setdynamic)) {
779 for (i = 0; i < level; i++) {
839 rb_bug(
"rb_iseq_disasm: unknown operand type: %c", type);
852 VALUE insn = iseq[pos];
853 int len = insn_len(insn);
855 const char *
types = insn_op_types(insn);
857 const char *insn_name_buff;
859 insn_name_buff = insn_name(insn);
865 (
int)strcspn(insn_name_buff,
"_"), insn_name_buff);
868 for (j = 0; types[j]; j++) {
869 const char *types = insn_op_types(insn);
871 len, pos, &iseq[pos + j + 2],
883 if (line_no && line_no != prev) {
885 slen = (slen > 70) ? 0 : (70 - slen);
886 str =
rb_str_catf(str,
"%*s(%4d)", (
int)slen,
"", line_no);
893 slen = (slen > 60) ? 0 : (60 - slen);
895 (
int)slen,
"", entry->
line_no, entry->
sp);
912 case CATCH_TYPE_RESCUE:
914 case CATCH_TYPE_ENSURE:
916 case CATCH_TYPE_RETRY:
918 case CATCH_TYPE_BREAK:
920 case CATCH_TYPE_REDO:
922 case CATCH_TYPE_NEXT:
925 rb_bug(
"unknown catch type (%d)", type);
942 enum {header_minlen = 72};
946 iseq = iseqdat->
iseq;
954 memset(
RSTRING_PTR(str) + l,
'=', header_minlen - l);
965 "| catch type: %-6s st: %04d ed: %04d sp: %04d cont: %04d\n",
967 (
int)entry->
end, (
int)entry->
sp, (
int)entry->
cont);
973 rb_str_cat2(str,
"|-------------------------------------"
974 "-----------------------------------\n");
982 "local table (size: %d, argc: %d "
983 "[opts: %d, rest: %d, post: %d, block: %d] s%d)\n",
992 char argi[0x100] =
"";
993 char opti[0x100] =
"";
998 if (i >= argc && i < argc + opts - 1) {
1004 snprintf(argi,
sizeof(argi),
"%s%s%s%s%s",
1005 iseqdat->
argc > i ?
"Arg" :
"",
1007 iseqdat->
arg_rest == i ?
"Rest" :
"",
1009 i < iseqdat->arg_post_start + iseqdat->
arg_post_len) ?
"Post" :
"",
1010 iseqdat->
arg_block == i ?
"Block" :
"");
1012 snprintf(info,
sizeof(info),
"%s%s%s%s", name ? name :
"?",
1013 *argi ?
"<" :
"", argi, *argi ?
">" :
"");
1021 for (n = 0; n <
size;) {
1062 rb_bug(
"unknown node (%d)", node);
1067 #define DECL_SYMBOL(name) \
1068 static VALUE sym_##name
1070 #define INIT_SYMBOL(name) \
1071 sym_##name = ID2SYM(rb_intern(#name))
1077 char buff[8 + (
sizeof(idx) *
CHAR_BIT * 32 / 100)];
1079 snprintf(buff,
sizeof(buff),
"label_%lu", idx);
1126 static VALUE insn_syms[VM_INSTRUCTION_SIZE];
1141 for (i=0; i<VM_INSTRUCTION_SIZE; i++) {
1156 switch(iseq->
type) {
1157 case ISEQ_TYPE_TOP: type = sym_top;
break;
1158 case ISEQ_TYPE_METHOD: type = sym_method;
break;
1159 case ISEQ_TYPE_BLOCK: type = sym_block;
break;
1160 case ISEQ_TYPE_CLASS: type = sym_class;
break;
1161 case ISEQ_TYPE_RESCUE: type = sym_rescue;
break;
1162 case ISEQ_TYPE_ENSURE: type = sym_ensure;
break;
1163 case ISEQ_TYPE_EVAL: type = sym_eval;
break;
1164 case ISEQ_TYPE_MAIN: type = sym_main;
break;
1165 case ISEQ_TYPE_DEFINED_GUARD: type = sym_defined_guard;
break;
1166 default:
rb_bug(
"unsupported iseq type");
1216 for (seq = iseq->
iseq; seq < iseq->iseq + iseq->
iseq_size; ) {
1217 VALUE insn = *seq++;
1218 int j,
len = insn_len(insn);
1219 VALUE *nseq = seq + len - 1;
1223 for (j=0; j<len-1; j++, seq++) {
1224 switch (insn_op_type(insn, j)) {
1226 unsigned long idx = nseq - iseq->
iseq + *seq;
1274 unsigned long idx = nseq - iseq->
iseq + pos;
1283 rb_bug(
"unknown operand: %c", insn_op_type(insn, j));
1318 if (
st_lookup(labels_table, pos, &label)) {
1369 iseq1->
self = newiseq;
1371 iseq1->
orig = iseqval;
1381 iseq1->
klass = newcbase;
1392 ID req, opt, rest, block;
1393 #define PARAM_TYPE(type) rb_ary_push(a = rb_ary_new2(2), ID2SYM(type))
1394 #define PARAM_ID(i) iseq->local_table[(i)]
1395 #define PARAM(i, type) ( \
1397 rb_id2name(PARAM_ID(i)) ? \
1398 rb_ary_push(a, ID2SYM(PARAM_ID(i))) : \
1404 for (i = 0; i < iseq->
argc; i++) {
1411 for (i = 0; i < iseq->
argc; i++) {
1419 for (s = i; i < r; i++) {
1457 const char **local_table,
1458 const VALUE *arg_opt_table,
1461 const char *filename,
1462 const unsigned short line_no)
1470 *iseq = *iseq_template;
1476 iseq->
self = iseqval;
1481 iseq->
iseq[
i] = BIN(opt_call_c_function);
1487 #define ALLOC_AND_COPY(dst, src, type, size) do { \
1489 (dst) = ALLOC_N(type, (size)); \
1490 MEMCPY((dst), (src), type, (size)); \