In Files

RubyVM::InstructionSequence

Public Class Methods

compile(p1, p2 = v2, p3 = v3, p4 = v4, p5 = v5) click to toggle source
 
               static VALUE
iseq_s_compile(int argc, VALUE *argv, VALUE self)
{
    VALUE src, file = Qnil, path = Qnil, line = INT2FIX(1), opt = Qnil;

    rb_secure(1);

    rb_scan_args(argc, argv, "14", &src, &file, &path, &line, &opt);
    if (NIL_P(file)) file = rb_str_new2("<compiled>");
    if (NIL_P(line)) line = INT2FIX(1);

    return rb_iseq_compile_with_option(src, file, path, line, opt);
}
            
compile_file(p1, p2 = v2) click to toggle source
 
               static VALUE
iseq_s_compile_file(int argc, VALUE *argv, VALUE self)
{
    VALUE file, line = INT2FIX(1), opt = Qnil;
    VALUE parser;
    VALUE f;
    NODE *node;
    const char *fname;
    rb_compile_option_t option;

    rb_secure(1);
    rb_scan_args(argc, argv, "11", &file, &opt);
    FilePathValue(file);
    fname = StringValueCStr(file);

    f = rb_file_open_str(file, "r");

    parser = rb_parser_new();
    node = rb_parser_compile_file(parser, fname, f, NUM2INT(line));
    make_compile_option(&option, opt);
    return rb_iseq_new_with_opt(node, rb_str_new2("<main>"), file,
                                rb_realpath_internal(Qnil, file, 1), line, Qfalse,
                                ISEQ_TYPE_TOP, &option);
}
            
compile_option() click to toggle source
 
               static VALUE
iseq_s_compile_option_get(VALUE self)
{
    return make_compile_option_value(&COMPILE_OPTION_DEFAULT);
}
            
compile_option=(p1) click to toggle source
 
               static VALUE
iseq_s_compile_option_set(VALUE self, VALUE opt)
{
    rb_compile_option_t option;
    rb_secure(1);
    make_compile_option(&option, opt);
    COMPILE_OPTION_DEFAULT = option;
    return opt;
}
            
disasm(p1) click to toggle source
 
               static VALUE
iseq_s_disasm(VALUE klass, VALUE body)
{
    VALUE ret = Qnil;
    rb_iseq_t *iseq;

    rb_secure(1);

    if (rb_obj_is_proc(body)) {
        rb_proc_t *proc;
        GetProcPtr(body, proc);
        iseq = proc->block.iseq;
        if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
            ret = rb_iseq_disasm(iseq->self);
        }
    }
    else if ((iseq = rb_method_get_iseq(body)) != 0) {
        ret = rb_iseq_disasm(iseq->self);
    }

    return ret;
}
            
disassemble(p1) click to toggle source
 
               static VALUE
iseq_s_disasm(VALUE klass, VALUE body)
{
    VALUE ret = Qnil;
    rb_iseq_t *iseq;

    rb_secure(1);

    if (rb_obj_is_proc(body)) {
        rb_proc_t *proc;
        GetProcPtr(body, proc);
        iseq = proc->block.iseq;
        if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
            ret = rb_iseq_disasm(iseq->self);
        }
    }
    else if ((iseq = rb_method_get_iseq(body)) != 0) {
        ret = rb_iseq_disasm(iseq->self);
    }

    return ret;
}
            
load(p1, p2 = v2) click to toggle source
 
               static VALUE
iseq_s_load(int argc, VALUE *argv, VALUE self)
{
    VALUE data, opt=Qnil;
    rb_scan_args(argc, argv, "11", &data, &opt);

    return iseq_load(self, data, 0, opt);
}
            
new(p1, p2 = v2, p3 = v3, p4 = v4, p5 = v5) click to toggle source
 
               static VALUE
iseq_s_compile(int argc, VALUE *argv, VALUE self)
{
    VALUE src, file = Qnil, path = Qnil, line = INT2FIX(1), opt = Qnil;

    rb_secure(1);

    rb_scan_args(argc, argv, "14", &src, &file, &path, &line, &opt);
    if (NIL_P(file)) file = rb_str_new2("<compiled>");
    if (NIL_P(line)) line = INT2FIX(1);

    return rb_iseq_compile_with_option(src, file, path, line, opt);
}
            

Public Instance Methods

disasm() click to toggle 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;
}
            
disassemble() click to toggle 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;
}
            
eval() click to toggle source
 
               static VALUE
iseq_eval(VALUE self)
{
    rb_secure(1);
    return rb_iseq_eval(self);
}
            
inspect() click to toggle source
 
               static VALUE
iseq_inspect(VALUE self)
{
    rb_iseq_t *iseq;
    GetISeqPtr(self, iseq);
    if (!iseq->name) {
        return rb_sprintf("#<%s: uninitialized>", rb_obj_classname(self));
    }

    return rb_sprintf("<%s:%s@%s>",
                      rb_obj_classname(self),
                      RSTRING_PTR(iseq->name), RSTRING_PTR(iseq->filename));
}
            
to_a() click to toggle source
 
               static VALUE
iseq_to_a(VALUE self)
{
    rb_iseq_t *iseq = iseq_check(self);
    rb_secure(1);
    return iseq_data_to_ary(iseq);
}
            

Commenting is here to help enhance the documentation. For example, sample code, or clarification of the documentation.

If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.

If you wish to post a correction of the docs, please do so, but also file bug report so that it can be corrected for the next release. Thank you.

blog comments powered by Disqus