Created
February 5, 2014 03:51
-
-
Save rondale-sc/8817174 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
VALUE | |
rb_iseq_disasm(VALUE self) | |
{ | |
rb_iseq_t *iseqdat = iseq_check(self); | |
VALUE *iseq; | |
VALUE str = rb_str_new(0, 0); | |
VALUE child = rb_ary_new(); | |
unsigned long size; | |
int i; | |
long l; | |
ID *tbl; | |
size_t n; | |
enum {header_minlen = 72}; | |
rb_secure(1); | |
iseq = iseqdat->iseq; | |
size = iseqdat->iseq_size; | |
rb_str_cat2(str, "== disasm: "); | |
rb_str_concat(str, iseq_inspect(iseqdat->self)); | |
if ((l = RSTRING_LEN(str)) < header_minlen) { | |
rb_str_resize(str, header_minlen); | |
memset(RSTRING_PTR(str) + l, '=', header_minlen - l); | |
} | |
rb_str_cat2(str, "\n"); | |
/* show catch table information */ | |
if (iseqdat->catch_table_size != 0) { | |
rb_str_cat2(str, "== catch table\n"); | |
} | |
for (i = 0; i < iseqdat->catch_table_size; i++) { | |
struct iseq_catch_table_entry *entry = &iseqdat->catch_table[i]; | |
rb_str_catf(str, | |
"| catch type: %-6s st: %04d ed: %04d sp: %04d cont: %04d\n", | |
catch_type((int)entry->type), (int)entry->start, | |
(int)entry->end, (int)entry->sp, (int)entry->cont); | |
if (entry->iseq) { | |
rb_str_concat(str, rb_iseq_disasm(entry->iseq)); | |
} | |
} | |
if (iseqdat->catch_table_size != 0) { | |
rb_str_cat2(str, "|-------------------------------------" | |
"-----------------------------------\n"); | |
} | |
/* show local table information */ | |
tbl = iseqdat->local_table; | |
if (tbl) { | |
rb_str_catf(str, | |
"local table (size: %d, argc: %d " | |
"[opts: %d, rest: %d, post: %d, block: %d, keyword: %d@%d] s%d)\n", | |
iseqdat->local_size, iseqdat->argc, | |
iseqdat->arg_opts, iseqdat->arg_rest, | |
iseqdat->arg_post_len, iseqdat->arg_block, | |
iseqdat->arg_keywords, iseqdat->local_size-iseqdat->arg_keyword, | |
iseqdat->arg_simple); | |
for (i = 0; i < iseqdat->local_table_size; i++) { | |
long width; | |
VALUE name = id_to_name(tbl[i], 0); | |
char argi[0x100] = ""; | |
char opti[0x100] = ""; | |
if (iseqdat->arg_opts) { | |
int argc = iseqdat->argc; | |
int opts = iseqdat->arg_opts; | |
if (i >= argc && i < argc + opts - 1) { | |
snprintf(opti, sizeof(opti), "Opt=%"PRIdVALUE, | |
iseqdat->arg_opt_table[i - argc]); | |
} | |
} | |
snprintf(argi, sizeof(argi), "%s%s%s%s%s", /* arg, opts, rest, post block */ | |
iseqdat->argc > i ? "Arg" : "", | |
opti, | |
iseqdat->arg_rest == i ? "Rest" : "", | |
(iseqdat->arg_post_start <= i && | |
i < iseqdat->arg_post_start + iseqdat->arg_post_len) ? "Post" : "", | |
iseqdat->arg_block == i ? "Block" : ""); | |
rb_str_catf(str, "[%2d] ", iseqdat->local_size - i); | |
width = RSTRING_LEN(str) + 11; | |
if (name) | |
rb_str_append(str, name); | |
else | |
rb_str_cat2(str, "?"); | |
if (*argi) rb_str_catf(str, "<%s>", argi); | |
if ((width -= RSTRING_LEN(str)) > 0) rb_str_catf(str, "%*s", (int)width, ""); | |
} | |
rb_str_cat2(str, "\n"); | |
} | |
/* show each line */ | |
for (n = 0; n < size;) { | |
n += rb_iseq_disasm_insn(str, iseq, n, iseqdat, child); | |
} | |
for (i = 0; i < RARRAY_LEN(child); i++) { | |
VALUE isv = rb_ary_entry(child, i); | |
rb_str_concat(str, rb_iseq_disasm(isv)); | |
} | |
return str; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment