diff options
author | Jean Boussier <byroot@ruby-lang.org> | 2023-10-30 12:29:59 +0100 |
---|---|---|
committer | Peter Zhu <peter@peterzhu.ca> | 2023-10-31 12:07:54 -0400 |
commit | 4aacc559d99988f395eced3534c7a6938bd356c8 (patch) | |
tree | a33af6b2ae7ae803053dad304687b321cdd73e93 /vm_insnhelper.c | |
parent | 85ad1025328989bb4e10436aed121b9136b0c8bf (diff) |
Handle running out of shapes in `Object#dup`
There is a handful of call sites where we may transition to
OBJ_TOO_COMPLEX_SHAPE if we just ran out of shapes, but that
weren't handling it properly.
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r-- | vm_insnhelper.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 2fc9b96114..1e514b7008 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -1382,18 +1382,20 @@ vm_setivar_slowpath(VALUE obj, ID id, VALUE val, const rb_iseq_t *iseq, IVC ic, { rb_ivar_set(obj, id, val); shape_id_t next_shape_id = rb_shape_get_shape_id(obj); - rb_shape_t *next_shape = rb_shape_get_shape_by_id(next_shape_id); - attr_index_t index; + if (next_shape_id != OBJ_TOO_COMPLEX_SHAPE_ID) { + rb_shape_t *next_shape = rb_shape_get_shape_by_id(next_shape_id); + attr_index_t index; - if (rb_shape_get_iv_index(next_shape, id, &index)) { // based off the hash stored in the transition tree - if (index >= MAX_IVARS) { - rb_raise(rb_eArgError, "too many instance variables"); - } + if (rb_shape_get_iv_index(next_shape, id, &index)) { // based off the hash stored in the transition tree + if (index >= MAX_IVARS) { + rb_raise(rb_eArgError, "too many instance variables"); + } - populate_cache(index, next_shape_id, id, iseq, ic, cc, is_attr); - } - else { - rb_bug("didn't find the id"); + populate_cache(index, next_shape_id, id, iseq, ic, cc, is_attr); + } + else { + rb_bug("didn't find the id"); + } } return val; |