aboutsummaryrefslogtreecommitdiffstats
path: root/vm_insnhelper.c
diff options
context:
space:
mode:
authorJean Boussier <byroot@ruby-lang.org>2023-10-30 12:29:59 +0100
committerPeter Zhu <peter@peterzhu.ca>2023-10-31 12:07:54 -0400
commit4aacc559d99988f395eced3534c7a6938bd356c8 (patch)
treea33af6b2ae7ae803053dad304687b321cdd73e93 /vm_insnhelper.c
parent85ad1025328989bb4e10436aed121b9136b0c8bf (diff)
downloadruby-4aacc559d99988f395eced3534c7a6938bd356c8.tar.gz
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.c22
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;