Refactor rb_obj_field_get
to handle complex shapes
This allow to get or set fields without having to worry about the shape type.
This commit is contained in:
parent
d9502a8386
commit
6dd7a7bb41
Notes:
git
2025-05-10 14:56:46 +00:00
40
variable.c
40
variable.c
@ -1302,25 +1302,53 @@ VALUE
|
|||||||
rb_obj_field_get(VALUE obj, rb_shape_t *target_shape)
|
rb_obj_field_get(VALUE obj, rb_shape_t *target_shape)
|
||||||
{
|
{
|
||||||
RUBY_ASSERT(!SPECIAL_CONST_P(obj));
|
RUBY_ASSERT(!SPECIAL_CONST_P(obj));
|
||||||
RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
|
|
||||||
RUBY_ASSERT(target_shape->type == SHAPE_IVAR || target_shape->type == SHAPE_OBJ_ID);
|
RUBY_ASSERT(target_shape->type == SHAPE_IVAR || target_shape->type == SHAPE_OBJ_ID);
|
||||||
|
|
||||||
attr_index_t attr_index = target_shape->next_field_index - 1;
|
if (rb_shape_too_complex_p(target_shape)) {
|
||||||
|
st_table *fields_hash;
|
||||||
switch (BUILTIN_TYPE(obj)) {
|
switch (BUILTIN_TYPE(obj)) {
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
ASSERT_vm_locking();
|
ASSERT_vm_locking();
|
||||||
return RCLASS_FIELDS(obj)[attr_index];
|
fields_hash = RCLASS_FIELDS_HASH(obj);
|
||||||
|
break;
|
||||||
case T_OBJECT:
|
case T_OBJECT:
|
||||||
return ROBJECT_FIELDS(obj)[attr_index];
|
fields_hash = ROBJECT_FIELDS_HASH(obj);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
RUBY_ASSERT(FL_TEST_RAW(obj, FL_EXIVAR));
|
RUBY_ASSERT(FL_TEST_RAW(obj, FL_EXIVAR));
|
||||||
struct gen_fields_tbl *fields_tbl = NULL;
|
struct gen_fields_tbl *fields_tbl = NULL;
|
||||||
rb_ivar_generic_fields_tbl_lookup(obj, &fields_tbl);
|
rb_ivar_generic_fields_tbl_lookup(obj, &fields_tbl);
|
||||||
RUBY_ASSERT(fields_tbl);
|
RUBY_ASSERT(fields_tbl);
|
||||||
return fields_tbl->as.shape.fields[attr_index];
|
fields_hash = fields_tbl->as.complex.table;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
VALUE value = Qundef;
|
||||||
|
st_lookup(fields_hash, target_shape->edge_name, &value);
|
||||||
|
RUBY_ASSERT(!UNDEF_P(value));
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
attr_index_t attr_index = target_shape->next_field_index - 1;
|
||||||
|
VALUE *fields;
|
||||||
|
switch (BUILTIN_TYPE(obj)) {
|
||||||
|
case T_CLASS:
|
||||||
|
case T_MODULE:
|
||||||
|
ASSERT_vm_locking();
|
||||||
|
fields = RCLASS_FIELDS(obj);
|
||||||
|
break;
|
||||||
|
case T_OBJECT:
|
||||||
|
fields = ROBJECT_FIELDS(obj);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
RUBY_ASSERT(FL_TEST_RAW(obj, FL_EXIVAR));
|
||||||
|
struct gen_fields_tbl *fields_tbl = NULL;
|
||||||
|
rb_ivar_generic_fields_tbl_lookup(obj, &fields_tbl);
|
||||||
|
RUBY_ASSERT(fields_tbl);
|
||||||
|
fields = fields_tbl->as.shape.fields;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return fields[attr_index];
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user