Feature #14605 ยป 0001-Remove-original_iseq-from-rb_iseq_constant_body.patch
compile.c | ||
---|---|---|
}
|
||
#endif
|
||
VALUE *
|
||
rb_iseq_original_iseq(const rb_iseq_t *iseq) /* cold path */
|
||
typedef void * iseq_original_seq_t(void *ctx, const rb_iseq_t *iseq, VALUE * original_code);
|
||
void *
|
||
rb_iseq_with_original_iseq(const rb_iseq_t *iseq, iseq_original_seq_t * cb, void *ctx)
|
||
{
|
||
VALUE *original_code;
|
||
if (ISEQ_ORIGINAL_ISEQ(iseq)) return ISEQ_ORIGINAL_ISEQ(iseq);
|
||
original_code = ISEQ_ORIGINAL_ISEQ_ALLOC(iseq, iseq->body->iseq_size);
|
||
VALUE str = rb_str_tmp_new(iseq->body->iseq_size * sizeof(VALUE));
|
||
original_code = (VALUE *)RSTRING_PTR(str);
|
||
MEMCPY(original_code, iseq->body->iseq_encoded, VALUE, iseq->body->iseq_size);
|
||
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
|
||
... | ... | |
}
|
||
}
|
||
#endif
|
||
return original_code;
|
||
return cb(ctx, iseq, original_code);
|
||
}
|
||
/*********************************************/
|
||
... | ... | |
return (VALUE)rb_global_entry(gid);
|
||
}
|
||
static VALUE *
|
||
ibf_dump_code(struct ibf_dump *dump, const rb_iseq_t *iseq)
|
||
static void *
|
||
ibf_dump_code_i(void *ctx, const rb_iseq_t *iseq, VALUE * orig_code)
|
||
{
|
||
struct ibf_dump *dump = (struct ibf_dump *)ctx;
|
||
const int iseq_size = iseq->body->iseq_size;
|
||
int code_index;
|
||
VALUE *code;
|
||
const VALUE *orig_code = rb_iseq_original_iseq(iseq);
|
||
code = ALLOCA_N(VALUE, iseq_size);
|
||
... | ... | |
return IBF_W(code, VALUE, iseq_size);
|
||
}
|
||
static VALUE *
|
||
ibf_dump_code(struct ibf_dump *dump, const rb_iseq_t *iseq)
|
||
{
|
||
return (VALUE *)(rb_iseq_with_original_iseq(iseq, ibf_dump_code_i, (void *)dump));
|
||
}
|
||
static VALUE *
|
||
ibf_load_code(const struct ibf_load *load, const rb_iseq_t *iseq, const struct rb_iseq_constant_body *body)
|
||
{
|
||
... | ... | |
dump_body.ci_entries = ibf_dump_ci_entries(dump, iseq);
|
||
dump_body.cc_entries = NULL;
|
||
dump_body.variable.coverage = Qnil;
|
||
dump_body.variable.original_iseq = Qnil;
|
||
return ibf_dump_write(dump, &dump_body, sizeof(dump_body));
|
||
}
|
||
... | ... | |
load_body->insns_info.size = body->insns_info.size;
|
||
ISEQ_COVERAGE_SET(iseq, Qnil);
|
||
ISEQ_ORIGINAL_ISEQ_CLEAR(iseq);
|
||
iseq->body->variable.flip_count = body->variable.flip_count;
|
||
{
|
iseq.c | ||
---|---|---|
}
|
||
rb_gc_mark(body->variable.coverage);
|
||
rb_gc_mark(body->variable.original_iseq);
|
||
rb_gc_mark(body->location.label);
|
||
rb_gc_mark(body->location.base_label);
|
||
rb_gc_mark(body->location.pathobj);
|
||
... | ... | |
RB_OBJ_WRITE(iseq, &iseq->body->location.base_label, iseq->body->local_iseq->body->location.label);
|
||
}
|
||
ISEQ_COVERAGE_SET(iseq, Qnil);
|
||
ISEQ_ORIGINAL_ISEQ_CLEAR(iseq);
|
||
iseq->body->variable.flip_count = 0;
|
||
ISEQ_COMPILE_DATA_ALLOC(iseq);
|
||
... | ... | |
}
|
||
}
|
||
struct iseq_disasm_iter_ctx {
|
||
VALUE str;
|
||
VALUE child;
|
||
};
|
||
static void *
|
||
iseq_disasm_iter(void *ctx, const rb_iseq_t *iseq, VALUE *code)
|
||
{
|
||
size_t n;
|
||
unsigned int size;
|
||
struct iseq_disasm_iter_ctx *ictx = (struct iseq_disasm_iter_ctx *)ctx;
|
||
VALUE str = ictx->str;
|
||
VALUE child = ictx->child;
|
||
size = iseq->body->iseq_size;
|
||
for (n = 0; n < size;) {
|
||
n += rb_iseq_disasm_insn(str, code, n, iseq, child);
|
||
}
|
||
return NULL;
|
||
}
|
||
VALUE
|
||
rb_iseq_disasm(const rb_iseq_t *iseq)
|
||
{
|
||
VALUE *code;
|
||
VALUE str = rb_str_new(0, 0);
|
||
VALUE child = rb_ary_tmp_new(3);
|
||
unsigned int size;
|
||
unsigned int i;
|
||
long l;
|
||
size_t n;
|
||
... | ... | |
rb_secure(1);
|
||
size = iseq->body->iseq_size;
|
||
rb_str_cat2(str, "== disasm: ");
|
||
rb_str_concat(str, iseq_inspect(iseq));
|
||
... | ... | |
}
|
||
/* show each line */
|
||
code = rb_iseq_original_iseq(iseq);
|
||
for (n = 0; n < size;) {
|
||
n += rb_iseq_disasm_insn(str, code, n, iseq, child);
|
||
}
|
||
struct iseq_disasm_iter_ctx ctx;
|
||
ctx.str = str;
|
||
ctx.child = child;
|
||
rb_iseq_with_original_iseq(iseq, iseq_disasm_iter, (void *)&ctx);
|
||
for (l = 0; l < RARRAY_LEN(child); l++) {
|
||
VALUE isv = rb_ary_entry(child, l);
|
||
... | ... | |
return str;
|
||
}
|
||
static VALUE
|
||
rb_iseq_all_children(const rb_iseq_t *iseq)
|
||
static void *
|
||
rb_iseq_all_children_i(void *ctx, const rb_iseq_t *iseq, VALUE * code)
|
||
{
|
||
unsigned int i;
|
||
VALUE *code = rb_iseq_original_iseq(iseq);
|
||
VALUE all_children = rb_obj_hide(rb_ident_hash_new());
|
||
VALUE child;
|
||
... | ... | |
}
|
||
i += len;
|
||
}
|
||
return all_children;
|
||
return (void *)all_children;
|
||
}
|
||
static VALUE
|
||
rb_iseq_all_children(const rb_iseq_t *iseq)
|
||
{
|
||
return (VALUE)rb_iseq_with_original_iseq(iseq, rb_iseq_all_children_i, NULL);
|
||
}
|
||
/*
|
||
... | ... | |
return ST_CONTINUE;
|
||
}
|
||
struct iseq_data_to_ary_ctx {
|
||
VALUE * insn_syms;
|
||
struct st_table *labels_table;
|
||
VALUE body;
|
||
};
|
||
static void *
|
||
iseq_data_to_ary_i(void * _ctx, const rb_iseq_t *iseq, VALUE * iseq_original)
|
||
{
|
||
struct iseq_data_to_ary_ctx * ctx;
|
||
VALUE *seq;
|
||
VALUE *insn_syms;
|
||
VALUE body;
|
||
struct st_table *labels_table;
|
||
ctx = (struct iseq_data_to_ary_ctx *)_ctx;
|
||
body = rb_ary_new(); /* [[:insn1, ...], ...] */
|
||
insn_syms = ctx->insn_syms;
|
||
labels_table = ctx->labels_table;
|
||
for (seq = iseq_original; seq < iseq_original + iseq->body->iseq_size; ) {
|
||
VALUE insn = *seq++;
|
||
int j, len = insn_len(insn);
|
||
VALUE *nseq = seq + len - 1;
|
||
VALUE ary = rb_ary_new2(len);
|
||
rb_ary_push(ary, insn_syms[insn%numberof(insn_syms)]);
|
||
for (j=0; j<len-1; j++, seq++) {
|
||
switch (insn_op_type(insn, j)) {
|
||
case TS_OFFSET: {
|
||
unsigned long idx = nseq - iseq_original + *seq;
|
||
rb_ary_push(ary, register_label(labels_table, idx));
|
||
break;
|
||
}
|
||
case TS_LINDEX:
|
||
case TS_NUM:
|
||
rb_ary_push(ary, INT2FIX(*seq));
|
||
break;
|
||
case TS_VALUE:
|
||
rb_ary_push(ary, obj_resurrect(*seq));
|
||
break;
|
||
case TS_ISEQ:
|
||
{
|
||
const rb_iseq_t *iseq = (rb_iseq_t *)*seq;
|
||
if (iseq) {
|
||
VALUE val = iseq_data_to_ary(rb_iseq_check(iseq));
|
||
rb_ary_push(ary, val);
|
||
}
|
||
else {
|
||
rb_ary_push(ary, Qnil);
|
||
}
|
||
}
|
||
break;
|
||
case TS_GENTRY:
|
||
{
|
||
struct rb_global_entry *entry = (struct rb_global_entry *)*seq;
|
||
rb_ary_push(ary, ID2SYM(entry->id));
|
||
}
|
||
break;
|
||
case TS_IC:
|
||
case TS_ISE:
|
||
{
|
||
union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)*seq;
|
||
rb_ary_push(ary, INT2FIX(is - iseq->body->is_entries));
|
||
}
|
||
break;
|
||
case TS_CALLINFO:
|
||
{
|
||
struct rb_call_info *ci = (struct rb_call_info *)*seq;
|
||
VALUE e = rb_hash_new();
|
||
int orig_argc = ci->orig_argc;
|
||
rb_hash_aset(e, ID2SYM(rb_intern("mid")), ci->mid ? ID2SYM(ci->mid) : Qnil);
|
||
rb_hash_aset(e, ID2SYM(rb_intern("flag")), UINT2NUM(ci->flag));
|
||
if (ci->flag & VM_CALL_KWARG) {
|
||
struct rb_call_info_with_kwarg *ci_kw = (struct rb_call_info_with_kwarg *)ci;
|
||
int i;
|
||
VALUE kw = rb_ary_new2((long)ci_kw->kw_arg->keyword_len);
|
||
orig_argc -= ci_kw->kw_arg->keyword_len;
|
||
for (i = 0; i < ci_kw->kw_arg->keyword_len; i++) {
|
||
rb_ary_push(kw, ci_kw->kw_arg->keywords[i]);
|
||
}
|
||
rb_hash_aset(e, ID2SYM(rb_intern("kw_arg")), kw);
|
||
}
|
||
rb_hash_aset(e, ID2SYM(rb_intern("orig_argc")),
|
||
INT2FIX(orig_argc));
|
||
rb_ary_push(ary, e);
|
||
}
|
||
break;
|
||
case TS_CALLCACHE:
|
||
rb_ary_push(ary, Qfalse);
|
||
break;
|
||
case TS_ID:
|
||
rb_ary_push(ary, ID2SYM(*seq));
|
||
break;
|
||
case TS_CDHASH:
|
||
{
|
||
VALUE hash = *seq;
|
||
VALUE val = rb_ary_new();
|
||
int i;
|
||
rb_hash_foreach(hash, cdhash_each, val);
|
||
for (i=0; i<RARRAY_LEN(val); i+=2) {
|
||
VALUE pos = FIX2INT(rb_ary_entry(val, i+1));
|
||
unsigned long idx = nseq - iseq_original + pos;
|
||
rb_ary_store(val, i+1,
|
||
register_label(labels_table, idx));
|
||
}
|
||
rb_ary_push(ary, val);
|
||
}
|
||
break;
|
||
case TS_FUNCPTR:
|
||
{
|
||
#if SIZEOF_VALUE <= SIZEOF_LONG
|
||
VALUE val = LONG2NUM((SIGNED_VALUE)*seq);
|
||
#else
|
||
VALUE val = LL2NUM((SIGNED_VALUE)*seq);
|
||
#endif
|
||
rb_ary_push(ary, val);
|
||
}
|
||
break;
|
||
default:
|
||
rb_bug("unknown operand: %c", insn_op_type(insn, j));
|
||
}
|
||
}
|
||
rb_ary_push(body, ary);
|
||
}
|
||
return (void *)body;
|
||
}
|
||
static VALUE
|
||
iseq_data_to_ary(const rb_iseq_t *iseq)
|
||
{
|
||
... | ... | |
const struct iseq_insn_info_entry *prev_insn_info;
|
||
unsigned int pos;
|
||
int last_line = 0;
|
||
VALUE *seq, *iseq_original;
|
||
VALUE val = rb_ary_new();
|
||
VALUE type; /* Symbol */
|
||
VALUE locals = rb_ary_new();
|
||
VALUE params = rb_hash_new();
|
||
VALUE body = rb_ary_new(); /* [[:insn1, ...], ...] */
|
||
VALUE body;
|
||
VALUE nbody;
|
||
VALUE exception = rb_ary_new(); /* [[....]] */
|
||
VALUE misc = rb_hash_new();
|
||
... | ... | |
}
|
||
/* body */
|
||
iseq_original = rb_iseq_original_iseq((rb_iseq_t *)iseq);
|
||
for (seq = iseq_original; seq < iseq_original + iseq->body->iseq_size; ) {
|
||
VALUE insn = *seq++;
|
||
int j, len = insn_len(insn);
|
||
VALUE *nseq = seq + len - 1;
|
||
VALUE ary = rb_ary_new2(len);
|
||
rb_ary_push(ary, insn_syms[insn%numberof(insn_syms)]);
|
||
for (j=0; j<len-1; j++, seq++) {
|
||
switch (insn_op_type(insn, j)) {
|
||
case TS_OFFSET: {
|
||
unsigned long idx = nseq - iseq_original + *seq;
|
||
rb_ary_push(ary, register_label(labels_table, idx));
|
||
break;
|
||
}
|
||
case TS_LINDEX:
|
||
case TS_NUM:
|
||
rb_ary_push(ary, INT2FIX(*seq));
|
||
break;
|
||
case TS_VALUE:
|
||
rb_ary_push(ary, obj_resurrect(*seq));
|
||
break;
|
||
case TS_ISEQ:
|
||
{
|
||
const rb_iseq_t *iseq = (rb_iseq_t *)*seq;
|
||
if (iseq) {
|
||
VALUE val = iseq_data_to_ary(rb_iseq_check(iseq));
|
||
rb_ary_push(ary, val);
|
||
}
|
||
else {
|
||
rb_ary_push(ary, Qnil);
|
||
}
|
||
}
|
||
break;
|
||
case TS_GENTRY:
|
||
{
|
||
struct rb_global_entry *entry = (struct rb_global_entry *)*seq;
|
||
rb_ary_push(ary, ID2SYM(entry->id));
|
||
}
|
||
break;
|
||
case TS_IC:
|
||
case TS_ISE:
|
||
{
|
||
union iseq_inline_storage_entry *is = (union iseq_inline_storage_entry *)*seq;
|
||
rb_ary_push(ary, INT2FIX(is - iseq->body->is_entries));
|
||
}
|
||
break;
|
||
case TS_CALLINFO:
|
||
{
|
||
struct rb_call_info *ci = (struct rb_call_info *)*seq;
|
||
VALUE e = rb_hash_new();
|
||
int orig_argc = ci->orig_argc;
|
||
rb_hash_aset(e, ID2SYM(rb_intern("mid")), ci->mid ? ID2SYM(ci->mid) : Qnil);
|
||
rb_hash_aset(e, ID2SYM(rb_intern("flag")), UINT2NUM(ci->flag));
|
||
if (ci->flag & VM_CALL_KWARG) {
|
||
struct rb_call_info_with_kwarg *ci_kw = (struct rb_call_info_with_kwarg *)ci;
|
||
int i;
|
||
VALUE kw = rb_ary_new2((long)ci_kw->kw_arg->keyword_len);
|
||
orig_argc -= ci_kw->kw_arg->keyword_len;
|
||
for (i = 0; i < ci_kw->kw_arg->keyword_len; i++) {
|
||
rb_ary_push(kw, ci_kw->kw_arg->keywords[i]);
|
||
}
|
||
rb_hash_aset(e, ID2SYM(rb_intern("kw_arg")), kw);
|
||
}
|
||
rb_hash_aset(e, ID2SYM(rb_intern("orig_argc")),
|
||
INT2FIX(orig_argc));
|
||
rb_ary_push(ary, e);
|
||
}
|
||
break;
|
||
case TS_CALLCACHE:
|
||
rb_ary_push(ary, Qfalse);
|
||
break;
|
||
case TS_ID:
|
||
rb_ary_push(ary, ID2SYM(*seq));
|
||
break;
|
||
case TS_CDHASH:
|
||
{
|
||
VALUE hash = *seq;
|
||
VALUE val = rb_ary_new();
|
||
int i;
|
||
rb_hash_foreach(hash, cdhash_each, val);
|
||
for (i=0; i<RARRAY_LEN(val); i+=2) {
|
||
VALUE pos = FIX2INT(rb_ary_entry(val, i+1));
|
||
unsigned long idx = nseq - iseq_original + pos;
|
||
rb_ary_store(val, i+1,
|
||
register_label(labels_table, idx));
|
||
}
|
||
rb_ary_push(ary, val);
|
||
}
|
||
break;
|
||
case TS_FUNCPTR:
|
||
{
|
||
#if SIZEOF_VALUE <= SIZEOF_LONG
|
||
VALUE val = LONG2NUM((SIGNED_VALUE)*seq);
|
||
#else
|
||
VALUE val = LL2NUM((SIGNED_VALUE)*seq);
|
||
#endif
|
||
rb_ary_push(ary, val);
|
||
}
|
||
break;
|
||
default:
|
||
rb_bug("unknown operand: %c", insn_op_type(insn, j));
|
||
}
|
||
}
|
||
rb_ary_push(body, ary);
|
||
}
|
||
nbody = body;
|
||
struct iseq_data_to_ary_ctx ctx;
|
||
ctx.insn_syms = insn_syms;
|
||
ctx.labels_table = labels_table;
|
||
nbody = (VALUE)rb_iseq_with_original_iseq(iseq, iseq_data_to_ary_i, &ctx);
|
||
RB_GC_GUARD(nbody);
|
||
/* exception */
|
||
if (iseq->body->catch_table) for (i=0; i<iseq->body->catch_table->size; i++) {
|
||
... | ... | |
#define INSN_CODE(insn) (insn)
|
||
#endif
|
||
static void *
|
||
rb_iseq_trace_set_i(void * ctx, const rb_iseq_t *iseq, VALUE *code)
|
||
{
|
||
unsigned int i;
|
||
rb_event_flag_t turnon_events = *(rb_event_flag_t*)ctx;
|
||
VALUE *iseq_encoded = (VALUE *)iseq->body->iseq_encoded;
|
||
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
|
||
const void * const *table = rb_vm_get_insns_address_table();
|
||
#endif
|
||
((rb_iseq_t *)iseq)->aux.trace_events = turnon_events;
|
||
for (i=0; i<iseq->body->iseq_size;) {
|
||
int insn = (int)code[i];
|
||
rb_event_flag_t events = rb_iseq_event_flags(iseq, i);
|
||
/* code represents before transformation */
|
||
VM_ASSERT(insn < VM_INSTRUCTION_SIZE/2);
|
||
if (events & turnon_events) {
|
||
if (!TRACE_INSN_P(insn)) {
|
||
iseq_encoded[i] = INSN_CODE(insn + VM_INSTRUCTION_SIZE/2);
|
||
}
|
||
}
|
||
else if (TRACE_INSN_P(insn)) {
|
||
iseq_encoded[i] = INSN_CODE(insn - VM_INSTRUCTION_SIZE/2);
|
||
}
|
||
i += insn_len(insn);
|
||
}
|
||
return NULL;
|
||
}
|
||
void
|
||
rb_iseq_trace_set(const rb_iseq_t *iseq, rb_event_flag_t turnon_events)
|
||
{
|
||
... | ... | |
return;
|
||
}
|
||
else {
|
||
unsigned int i;
|
||
VALUE *iseq_encoded = (VALUE *)iseq->body->iseq_encoded;
|
||
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
|
||
VALUE *code = rb_iseq_original_iseq(iseq);
|
||
const void * const *table = rb_vm_get_insns_address_table();
|
||
#else
|
||
const VALUE *code = iseq->body->iseq_encoded;
|
||
#endif
|
||
((rb_iseq_t *)iseq)->aux.trace_events = turnon_events;
|
||
for (i=0; i<iseq->body->iseq_size;) {
|
||
int insn = (int)code[i];
|
||
rb_event_flag_t events = rb_iseq_event_flags(iseq, i);
|
||
if (events & turnon_events) {
|
||
if (!TRACE_INSN_P(insn)) {
|
||
iseq_encoded[i] = INSN_CODE(insn + VM_INSTRUCTION_SIZE/2);
|
||
}
|
||
}
|
||
else if (TRACE_INSN_P(insn)) {
|
||
iseq_encoded[i] = INSN_CODE(insn - VM_INSTRUCTION_SIZE/2);
|
||
}
|
||
i += insn_len(insn);
|
||
}
|
||
/* clear for debugging: ISEQ_ORIGINAL_ISEQ_CLEAR(iseq); */
|
||
rb_iseq_with_original_iseq(iseq, rb_iseq_trace_set_i, &turnon_events);
|
||
}
|
||
}
|
||
iseq.h | ||
---|---|---|
return cnt;
|
||
}
|
||
static inline VALUE *
|
||
ISEQ_ORIGINAL_ISEQ(const rb_iseq_t *iseq)
|
||
{
|
||
VALUE str = iseq->body->variable.original_iseq;
|
||
if (RTEST(str)) return (VALUE *)RSTRING_PTR(str);
|
||
return NULL;
|
||
}
|
||
static inline void
|
||
ISEQ_ORIGINAL_ISEQ_CLEAR(const rb_iseq_t *iseq)
|
||
{
|
||
RB_OBJ_WRITE(iseq, &iseq->body->variable.original_iseq, Qnil);
|
||
}
|
||
static inline VALUE *
|
||
ISEQ_ORIGINAL_ISEQ_ALLOC(const rb_iseq_t *iseq, long size)
|
||
{
|
||
VALUE str = rb_str_tmp_new(size * sizeof(VALUE));
|
||
RB_OBJ_WRITE(iseq, &iseq->body->variable.original_iseq, str);
|
||
return (VALUE *)RSTRING_PTR(str);
|
||
}
|
||
#define ISEQ_TRACE_EVENTS (RUBY_EVENT_LINE | \
|
||
RUBY_EVENT_CLASS | \
|
||
RUBY_EVENT_END | \
|
||
... | ... | |
VALUE rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node);
|
||
VALUE rb_iseq_compile_ifunc(rb_iseq_t *iseq, const struct vm_ifunc *ifunc);
|
||
int rb_iseq_translate_threaded_code(rb_iseq_t *iseq);
|
||
VALUE *rb_iseq_original_iseq(const rb_iseq_t *iseq);
|
||
typedef void * iseq_original_seq_t(void *ctx, const rb_iseq_t *iseq, VALUE * original_code);
|
||
void * rb_iseq_with_original_iseq(const rb_iseq_t *iseq, iseq_original_seq_t * cb, void *ctx);
|
||
void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc,
|
||
VALUE locals, VALUE args,
|
||
VALUE exception, VALUE body);
|
vm_core.h | ||
---|---|---|
struct {
|
||
rb_snum_t flip_count;
|
||
VALUE coverage;
|
||
VALUE original_iseq;
|
||
} variable;
|
||
unsigned int local_table_size;
|
vm_dump.c | ||
---|---|---|
rb_vmdebug_debug_print_register(rb_thread_ptr(thval)->ec);
|
||
}
|
||
static void *
|
||
rb_vmdebug_debug_print_pre_i(void * ctx, const rb_iseq_t *iseq, VALUE * iseq_original)
|
||
{
|
||
size_t pc = *(size_t *)ctx;
|
||
rb_iseq_disasm_insn(0, iseq_original, (size_t)pc, iseq, 0);
|
||
return NULL;
|
||
}
|
||
void
|
||
rb_vmdebug_debug_print_pre(const rb_execution_context_t *ec, const rb_control_frame_t *cfp, const VALUE *_pc)
|
||
{
|
||
... | ... | |
/* printf("%3"PRIdPTRDIFF" ", VM_CFP_CNT(ec, cfp)); */
|
||
if (pc >= 0) {
|
||
const VALUE *iseq_original = rb_iseq_original_iseq((rb_iseq_t *)iseq);
|
||
rb_iseq_disasm_insn(0, iseq_original, (size_t)pc, iseq, 0);
|
||
rb_iseq_with_original_iseq(iseq, rb_vmdebug_debug_print_pre_i, &pc);
|
||
}
|
||
}
|
||