Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop rb_ivar_foreach #7962

Merged
merged 2 commits into from
Jun 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
16 changes: 1 addition & 15 deletions marshal.c
Original file line number Diff line number Diff line change
Expand Up @@ -1803,20 +1803,6 @@ r_object0(struct load_arg *arg, bool partial, int *ivp, VALUE extmod)
return r_object_for(arg, partial, ivp, extmod, type);
}

static int
r_move_ivar(st_data_t k, st_data_t v, st_data_t d)
{
ID key = (ID)k;
VALUE value = (VALUE)v;
VALUE dest = (VALUE)d;

if (rb_is_instance_id(key)) {
rb_ivar_set(dest, key, value);
return ST_DELETE;
}
return ST_CONTINUE;
}

static VALUE
r_object_for(struct load_arg *arg, bool partial, int *ivp, VALUE extmod, int type)
{
Expand Down Expand Up @@ -2034,7 +2020,7 @@ r_object_for(struct load_arg *arg, bool partial, int *ivp, VALUE extmod, int typ
rb_str_set_len(str, dst - ptr);
}
VALUE regexp = rb_reg_new_str(str, options);
rb_ivar_foreach(str, r_move_ivar, regexp);
r_copy_ivar(regexp, str);

v = r_entry0(regexp, idx, arg);
v = r_leave(v, arg, partial);
Expand Down
26 changes: 19 additions & 7 deletions variable.c
Original file line number Diff line number Diff line change
Expand Up @@ -1633,14 +1633,19 @@ struct iv_itr_data {
rb_ivar_foreach_callback_func *func;
};

static void
/*
* Returns a flag to stop iterating depending on the result of +callback+.
*/
static bool
iterate_over_shapes_with_callback(rb_shape_t *shape, rb_ivar_foreach_callback_func *callback, struct iv_itr_data * itr_data)
{
switch ((enum shape_type)shape->type) {
case SHAPE_ROOT:
return;
return false;
case SHAPE_IVAR:
iterate_over_shapes_with_callback(rb_shape_get_parent(shape), callback, itr_data);
ASSUME(callback);
if (iterate_over_shapes_with_callback(rb_shape_get_parent(shape), callback, itr_data))
return true;
VALUE * iv_list;
switch (BUILTIN_TYPE(itr_data->obj)) {
case T_OBJECT:
Expand All @@ -1657,15 +1662,22 @@ iterate_over_shapes_with_callback(rb_shape_t *shape, rb_ivar_foreach_callback_fu
}
VALUE val = iv_list[shape->next_iv_index - 1];
if (!UNDEF_P(val)) {
callback(shape->edge_name, val, itr_data->arg);
switch (callback(shape->edge_name, val, itr_data->arg)) {
case ST_CHECK:
case ST_CONTINUE:
break;
case ST_STOP:
return true;
default:
rb_bug("unreachable");
}
}
return;
return false;
case SHAPE_INITIAL_CAPACITY:
case SHAPE_CAPACITY_CHANGE:
case SHAPE_FROZEN:
case SHAPE_T_OBJECT:
iterate_over_shapes_with_callback(rb_shape_get_parent(shape), callback, itr_data);
return;
return iterate_over_shapes_with_callback(rb_shape_get_parent(shape), callback, itr_data);
case SHAPE_OBJ_TOO_COMPLEX:
rb_bug("Unreachable");
}
Expand Down