summaryrefslogtreecommitdiff
path: root/iseq.c
diff options
context:
space:
mode:
Diffstat (limited to 'iseq.c')
-rw-r--r--iseq.c24
1 files changed, 20 insertions, 4 deletions
diff --git a/iseq.c b/iseq.c
index c9fef82aef..8285aadf9b 100644
--- a/iseq.c
+++ b/iseq.c
@@ -2099,6 +2099,12 @@ iseq_inspect(const rb_iseq_t *iseq)
}
}
+static const rb_data_type_t tmp_set = {
+ "tmpset",
+ {(void (*)(void *))rb_mark_set, (void (*)(void *))st_free_table, 0, 0,},
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
static VALUE
rb_iseq_disasm_recursive(const rb_iseq_t *iseq, VALUE indent)
{
@@ -2112,6 +2118,7 @@ rb_iseq_disasm_recursive(const rb_iseq_t *iseq, VALUE indent)
size_t n;
enum {header_minlen = 72};
st_table *done_iseq = 0;
+ VALUE done_iseq_wrapper = Qnil;
const char *indent_str;
long indent_len;
@@ -2151,7 +2158,10 @@ rb_iseq_disasm_recursive(const rb_iseq_t *iseq, VALUE indent)
(int)entry->end, (int)entry->sp, (int)entry->cont);
if (entry->iseq && !(done_iseq && st_is_member(done_iseq, (st_data_t)entry->iseq))) {
rb_str_concat(str, rb_iseq_disasm_recursive(rb_iseq_check(entry->iseq), indent));
- if (!done_iseq) done_iseq = st_init_numtable();
+ if (!done_iseq) {
+ done_iseq = st_init_numtable();
+ done_iseq_wrapper = TypedData_Wrap_Struct(0, &tmp_set, done_iseq);
+ }
st_insert(done_iseq, (st_data_t)entry->iseq, (st_data_t)0);
indent_str = RSTRING_PTR(indent);
}
@@ -2231,7 +2241,7 @@ rb_iseq_disasm_recursive(const rb_iseq_t *iseq, VALUE indent)
rb_str_concat(str, rb_iseq_disasm_recursive(rb_iseq_check((rb_iseq_t *)isv), indent));
indent_str = RSTRING_PTR(indent);
}
- if (done_iseq) st_free_table(done_iseq);
+ RB_GC_GUARD(done_iseq_wrapper);
return str;
}
@@ -2544,6 +2554,12 @@ cdhash_each(VALUE key, VALUE value, VALUE ary)
return ST_CONTINUE;
}
+static const rb_data_type_t label_wrapper = {
+ "label_wrapper",
+ {(void (*)(void *))rb_mark_tbl, (void (*)(void *))st_free_table, 0, 0,},
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
+};
+
static VALUE
iseq_data_to_ary(const rb_iseq_t *iseq)
{
@@ -2566,6 +2582,7 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
static ID insn_syms[VM_INSTRUCTION_SIZE/2]; /* w/o-trace only */
struct st_table *labels_table = st_init_numtable();
+ VALUE labels_wrapper = TypedData_Wrap_Struct(0, &label_wrapper, labels_table);
DECL_SYMBOL(top);
DECL_SYMBOL(method);
@@ -2841,8 +2858,7 @@ iseq_data_to_ary(const rb_iseq_t *iseq)
pos += RARRAY_LENINT(ary); /* reject too huge data */
}
RB_GC_GUARD(nbody);
-
- st_free_table(labels_table);
+ RB_GC_GUARD(labels_wrapper);
rb_hash_aset(misc, ID2SYM(rb_intern("arg_size")), INT2FIX(iseq_body->param.size));
rb_hash_aset(misc, ID2SYM(rb_intern("local_size")), INT2FIX(iseq_body->local_table_size));