summaryrefslogtreecommitdiff
path: root/variable.c
diff options
context:
space:
mode:
authorJean Boussier <jean.boussier@gmail.com>2025-08-26 09:29:08 +0200
committerJean Boussier <jean.boussier@gmail.com>2025-08-26 13:44:59 +0200
commit6a2df394cb5400d9180839f48f483507039b0c73 (patch)
treed02a2ac0550aa5ccf3e99b72f570e31bac40decd /variable.c
parent14bdf4b57dcd3169a8717dc893fd1e1be897deeb (diff)
rb_ivar_lookup: unify codepaths
Now that T_OBJECT and T_IMEMO/fields have identical layout a lot more codepaths can be shared.
Diffstat (limited to 'variable.c')
-rw-r--r--variable.c86
1 files changed, 23 insertions, 63 deletions
diff --git a/variable.c b/variable.c
index 3e908dbe3c..0d3f958526 100644
--- a/variable.c
+++ b/variable.c
@@ -1410,19 +1410,13 @@ rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
{
if (SPECIAL_CONST_P(obj)) return undef;
- shape_id_t shape_id;
- VALUE *ivar_list;
+ VALUE fields_obj;
switch (BUILTIN_TYPE(obj)) {
case T_CLASS:
case T_MODULE:
{
- VALUE val = undef;
- VALUE fields_obj = RCLASS_WRITABLE_FIELDS_OBJ(obj);
- if (fields_obj) {
- val = rb_ivar_lookup(fields_obj, id, undef);
- }
-
+ VALUE val = rb_ivar_lookup(RCLASS_WRITABLE_FIELDS_OBJ(obj), id, undef);
if (val != undef &&
rb_is_instance_id(id) &&
UNLIKELY(!rb_ractor_main_p()) &&
@@ -1434,69 +1428,35 @@ rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
}
case T_IMEMO:
// Handled like T_OBJECT
- {
- RUBY_ASSERT(IMEMO_TYPE_P(obj, imemo_fields));
- shape_id = RBASIC_SHAPE_ID(obj);
+ RUBY_ASSERT(IMEMO_TYPE_P(obj, imemo_fields));
+ fields_obj = obj;
+ break;
+ case T_OBJECT:
+ fields_obj = obj;
+ break;
+ default:
+ fields_obj = rb_obj_fields(obj, id);
+ break;
+ }
- if (rb_shape_too_complex_p(shape_id)) {
- st_table *iv_table = rb_imemo_fields_complex_tbl(obj);
- VALUE val;
- if (rb_st_lookup(iv_table, (st_data_t)id, (st_data_t *)&val)) {
- return val;
- }
- else {
- return undef;
- }
- }
+ if (!fields_obj) {
+ return undef;
+ }
- RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
- ivar_list = rb_imemo_fields_ptr(obj);
- break;
- }
- case T_OBJECT:
- {
- shape_id = RBASIC_SHAPE_ID(obj);
- if (rb_shape_too_complex_p(shape_id)) {
- st_table *iv_table = ROBJECT_FIELDS_HASH(obj);
- VALUE val;
- if (rb_st_lookup(iv_table, (st_data_t)id, (st_data_t *)&val)) {
- return val;
- }
- else {
- return undef;
- }
- }
+ shape_id_t shape_id = RBASIC_SHAPE_ID(fields_obj);
- RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
- ivar_list = ROBJECT_FIELDS(obj);
- break;
- }
- default:
- {
- shape_id = RBASIC_SHAPE_ID(obj);
- VALUE fields_obj = rb_obj_fields(obj, id);
- if (fields_obj) {
- if (rb_shape_obj_too_complex_p(fields_obj)) {
- VALUE val;
- if (rb_st_lookup(rb_imemo_fields_complex_tbl(fields_obj), (st_data_t)id, (st_data_t *)&val)) {
- return val;
- }
- else {
- return undef;
- }
- }
- ivar_list = rb_imemo_fields_ptr(fields_obj);
- }
- else {
- return undef;
- }
- break;
+ if (UNLIKELY(rb_shape_too_complex_p(shape_id))) {
+ st_table *iv_table = rb_imemo_fields_complex_tbl(fields_obj);
+ VALUE val;
+ if (rb_st_lookup(iv_table, (st_data_t)id, (st_data_t *)&val)) {
+ return val;
}
+ return undef;
}
attr_index_t index = 0;
if (rb_shape_get_iv_index(shape_id, id, &index)) {
- return ivar_list[index];
+ return rb_imemo_fields_ptr(fields_obj)[index];
}
return undef;