declare ::RubyVM::InstructionSequence
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); }
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); }
static VALUE iseq_s_compile_option_get(VALUE self) { return make_compile_option_value(&COMPILE_OPTION_DEFAULT); }
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; }
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; }
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; }
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); }
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); }
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; }
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; }
static VALUE iseq_eval(VALUE self) { rb_secure(1); return rb_iseq_eval(self); }
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)); }
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.