Flowdock
disassemble() public

No documentation

This method has no description. You can help the Ruby community by adding new notes.

Hide source
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] s%d)\n",
                    iseqdat->local_size, iseqdat->argc,
                    iseqdat->arg_opts, iseqdat->arg_rest,
                    iseqdat->arg_post_len, iseqdat->arg_block,
                    iseqdat->arg_simple);

        for (i = 0; i < iseqdat->local_table_size; i++) {
            const char *name = rb_id2name(tbl[i]);
            char info[0x100];
            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" : "");

            snprintf(info, sizeof(info), "%s%s%s%s", name ? name : "?",
                     *argi ? "<" : "", argi, *argi ? ">" : "");

            rb_str_catf(str, "[%2d] %-11s", iseqdat->local_size - i, info);
        }
        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;
}
Register or log in to add new notes.