mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Fix crash when loading iseq from an array
Objects loaded during iseq deserialization using arrays need to be added to the compile time mark array so that they stay alive until iseqs finish loading. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63920 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
443773836e
commit
7aab72f736
2 changed files with 17 additions and 4 deletions
14
compile.c
14
compile.c
|
@ -2159,6 +2159,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor)
|
||||||
rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, body->is_size);
|
rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d", ic_index, body->is_size);
|
||||||
}
|
}
|
||||||
generated_iseq[code_index + 1 + j] = (VALUE)ic;
|
generated_iseq[code_index + 1 + j] = (VALUE)ic;
|
||||||
|
RB_OBJ_WRITTEN(iseq, Qundef, ic);
|
||||||
FL_SET(iseq, ISEQ_MARKABLE_ISEQ);
|
FL_SET(iseq, ISEQ_MARKABLE_ISEQ);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -7914,11 +7915,14 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
|
||||||
break;
|
break;
|
||||||
case TS_VALUE:
|
case TS_VALUE:
|
||||||
argv[j] = op;
|
argv[j] = op;
|
||||||
|
iseq_add_mark_object_compile_time(iseq, op);
|
||||||
break;
|
break;
|
||||||
case TS_ISEQ:
|
case TS_ISEQ:
|
||||||
{
|
{
|
||||||
if (op != Qnil) {
|
if (op != Qnil) {
|
||||||
argv[j] = (VALUE)iseq_build_load_iseq(iseq, op);
|
VALUE v = (VALUE)iseq_build_load_iseq(iseq, op);
|
||||||
|
argv[j] = v;
|
||||||
|
iseq_add_mark_object_compile_time(iseq, v);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
argv[j] = 0;
|
argv[j] = 0;
|
||||||
|
@ -7929,8 +7933,9 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
|
||||||
op = rb_to_symbol_type(op);
|
op = rb_to_symbol_type(op);
|
||||||
argv[j] = (VALUE)rb_global_entry(SYM2ID(op));
|
argv[j] = (VALUE)rb_global_entry(SYM2ID(op));
|
||||||
break;
|
break;
|
||||||
case TS_IC:
|
|
||||||
case TS_ISE:
|
case TS_ISE:
|
||||||
|
FL_SET(iseq, ISEQ_MARKABLE_ISEQ);
|
||||||
|
case TS_IC:
|
||||||
argv[j] = op;
|
argv[j] = op;
|
||||||
if (NUM2UINT(op) >= iseq->body->is_size) {
|
if (NUM2UINT(op) >= iseq->body->is_size) {
|
||||||
iseq->body->is_size = NUM2INT(op) + 1;
|
iseq->body->is_size = NUM2INT(op) + 1;
|
||||||
|
@ -7961,6 +7966,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor,
|
||||||
}
|
}
|
||||||
RB_GC_GUARD(op);
|
RB_GC_GUARD(op);
|
||||||
argv[j] = map;
|
argv[j] = map;
|
||||||
|
iseq_add_mark_object_compile_time(iseq, map);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TS_FUNCPTR:
|
case TS_FUNCPTR:
|
||||||
|
@ -8655,9 +8661,9 @@ ibf_load_code(const struct ibf_load *load, const rb_iseq_t *iseq, const struct r
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TS_IC:
|
|
||||||
FL_SET(iseq, ISEQ_MARKABLE_ISEQ);
|
|
||||||
case TS_ISE:
|
case TS_ISE:
|
||||||
|
FL_SET(iseq, ISEQ_MARKABLE_ISEQ);
|
||||||
|
case TS_IC:
|
||||||
code[code_index] = (VALUE)&is_entries[(int)op];
|
code[code_index] = (VALUE)&is_entries[(int)op];
|
||||||
break;
|
break;
|
||||||
case TS_CALLINFO:
|
case TS_CALLINFO:
|
||||||
|
|
|
@ -16,6 +16,13 @@ class TestIseqLoad < Test::Unit::TestCase
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_stressful_roundtrip
|
||||||
|
stress, GC.stress = GC.stress, true
|
||||||
|
test_bug8543
|
||||||
|
ensure
|
||||||
|
GC.stress = stress
|
||||||
|
end
|
||||||
|
|
||||||
def test_case_when
|
def test_case_when
|
||||||
assert_iseq_roundtrip "#{<<~"begin;"}\n#{<<~'end;'}"
|
assert_iseq_roundtrip "#{<<~"begin;"}\n#{<<~'end;'}"
|
||||||
begin;
|
begin;
|
||||||
|
|
Loading…
Add table
Reference in a new issue