summaryrefslogtreecommitdiff
path: root/variable.c
diff options
context:
space:
mode:
Diffstat (limited to 'variable.c')
-rw-r--r--variable.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/variable.c b/variable.c
index 0f71b27418..745ace528f 100644
--- a/variable.c
+++ b/variable.c
@@ -1566,22 +1566,41 @@ rb_ivar_defined(VALUE obj, ID id)
typedef int rb_ivar_foreach_callback_func(ID key, VALUE val, st_data_t arg);
st_data_t rb_st_nth_key(st_table *tab, st_index_t index);
+struct iv_itr_data {
+ VALUE obj;
+ struct gen_ivtbl * ivtbl;
+ st_data_t arg;
+};
+
static void
-iterate_over_shapes_with_callback(rb_shape_t *shape, VALUE* iv_list, rb_ivar_foreach_callback_func *callback, st_data_t arg)
+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;
case SHAPE_IVAR:
- iterate_over_shapes_with_callback(rb_shape_get_shape_by_id(shape->parent_id), iv_list, callback, arg);
+ iterate_over_shapes_with_callback(rb_shape_get_shape_by_id(shape->parent_id), callback, itr_data);
+ VALUE * iv_list;
+ switch(BUILTIN_TYPE(itr_data->obj)) {
+ case T_OBJECT:
+ iv_list = ROBJECT_IVPTR(itr_data->obj);
+ break;
+ case T_CLASS:
+ case T_MODULE:
+ iv_list = RCLASS_IVPTR(itr_data->obj);
+ break;
+ default:
+ iv_list = itr_data->ivtbl->ivptr;
+ break;
+ }
VALUE val = iv_list[shape->next_iv_index - 1];
if (val != Qundef) {
- callback(shape->edge_name, val, arg);
+ callback(shape->edge_name, val, itr_data->arg);
}
return;
case SHAPE_IVAR_UNDEF:
case SHAPE_FROZEN:
- iterate_over_shapes_with_callback(rb_shape_get_shape_by_id(shape->parent_id), iv_list, callback, arg);
+ iterate_over_shapes_with_callback(rb_shape_get_shape_by_id(shape->parent_id), callback, itr_data);
return;
}
}
@@ -1590,7 +1609,10 @@ static void
obj_ivar_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg)
{
rb_shape_t* shape = rb_shape_get_shape(obj);
- iterate_over_shapes_with_callback(shape, ROBJECT_IVPTR(obj), func, arg);
+ struct iv_itr_data itr_data;
+ itr_data.obj = obj;
+ itr_data.arg = arg;
+ iterate_over_shapes_with_callback(shape, func, &itr_data);
}
static void
@@ -1600,7 +1622,11 @@ gen_ivar_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg)
struct gen_ivtbl *ivtbl;
if (!rb_gen_ivtbl_get(obj, 0, &ivtbl)) return;
- iterate_over_shapes_with_callback(shape, ivtbl->ivptr, func, arg);
+ struct iv_itr_data itr_data;
+ itr_data.obj = obj;
+ itr_data.ivtbl = ivtbl;
+ itr_data.arg = arg;
+ iterate_over_shapes_with_callback(shape, func, &itr_data);
}
static void
@@ -1609,7 +1635,10 @@ class_ivar_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg)
RUBY_ASSERT(RB_TYPE_P(obj, T_CLASS) || RB_TYPE_P(obj, T_MODULE));
rb_shape_t* shape = rb_shape_get_shape(obj);
- iterate_over_shapes_with_callback(shape, RCLASS_IVPTR(obj), func, arg);
+ struct iv_itr_data itr_data;
+ itr_data.obj = obj;
+ itr_data.arg = arg;
+ iterate_over_shapes_with_callback(shape, func, &itr_data);
}
void