Shared empty iv_tbl of module

This will be a partial merge of #5317 with the following changes.

- Remove `iclass->iv_c` since `iclass->iv_c` is equivalent to `iclass->c`.
- `class_iv_ptr()` returns a single pointer instead of a double pointer.
This commit is contained in:
dearblue
2024-03-27 21:39:32 +09:00
4 changed files with 125 additions and 16 deletions
+22 -13
View File
@@ -296,6 +296,12 @@ obj_iv_p(mrb_value obj)
}
}
static iv_tbl*
class_iv_ptr(struct RClass *c)
{
return c->tt == MRB_TT_ICLASS ? c->c->iv : c->iv;
}
MRB_API mrb_value
mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym)
{
@@ -593,7 +599,7 @@ mrb_mod_class_variables(mrb_state *mrb, mrb_value mod)
ary = mrb_ary_new(mrb);
c = mrb_class_ptr(mod);
while (c) {
iv_foreach(mrb, c->iv, cv_i, &ary);
iv_foreach(mrb, class_iv_ptr(c), cv_i, &ary);
if (!inherit) break;
c = c->super;
}
@@ -608,7 +614,7 @@ mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym)
int given = FALSE;
while (c) {
if (c->iv && iv_get(mrb, c->iv, sym, &v)) {
if (iv_get(mrb, class_iv_ptr(c), sym, &v)) {
given = TRUE;
}
c = c->super;
@@ -622,7 +628,7 @@ mrb_mod_cv_get(mrb_state *mrb, struct RClass *c, mrb_sym sym)
if (c->tt == MRB_TT_CLASS || c->tt == MRB_TT_MODULE) {
given = FALSE;
while (c) {
if (c->iv && iv_get(mrb, c->iv, sym, &v)) {
if (iv_get(mrb, class_iv_ptr(c), sym, &v)) {
given = TRUE;
}
c = c->super;
@@ -647,7 +653,7 @@ mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v)
struct RClass * cls = c;
while (c) {
iv_tbl *t = c->iv;
iv_tbl *t = class_iv_ptr(c);
int pos = iv_get(mrb, t, sym, NULL);
if (pos) {
@@ -674,7 +680,10 @@ mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v)
break;
}
}
else{
else if (cls && cls->tt == MRB_TT_ICLASS) {
c = cls->c;
}
else {
c = cls;
}
@@ -697,7 +706,7 @@ mrb_bool
mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym)
{
while (c) {
iv_tbl *t = c->iv;
iv_tbl *t = class_iv_ptr(c);
if (iv_get(mrb, t, sym, NULL)) return TRUE;
c = c->super;
}
@@ -765,7 +774,7 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym, mrb_bool skip)
if (skip) c = c->super;
L_RETRY:
while (c) {
if (!MRB_FLAG_TEST(c, MRB_FL_CLASS_IS_PREPENDED) && c->iv && iv_get(mrb, c->iv, sym, &v)) {
if (!MRB_FLAG_TEST(c, MRB_FL_CLASS_IS_PREPENDED) && iv_get(mrb, class_iv_ptr(c), sym, &v)) {
return v;
}
c = c->super;
@@ -801,14 +810,14 @@ mrb_vm_const_get(mrb_state *mrb, mrb_sym sym)
c = MRB_PROC_TARGET_CLASS(proc);
if (!c) c = mrb->object_class;
if (iv_get(mrb, c->iv, sym, &v)) {
if (iv_get(mrb, class_iv_ptr(c), sym, &v)) {
return v;
}
c2 = c;
while (c2 && c2->tt == MRB_TT_SCLASS) {
mrb_value klass;
if (!iv_get(mrb, c2->iv, MRB_SYM(__attached__), &klass)) {
if (!iv_get(mrb, class_iv_ptr(c2), MRB_SYM(__attached__), &klass)) {
c2 = NULL;
break;
}
@@ -819,7 +828,7 @@ mrb_vm_const_get(mrb_state *mrb, mrb_sym sym)
while (proc) {
c2 = MRB_PROC_TARGET_CLASS(proc);
if (!c2) c2 = mrb->object_class;
if (c2 && iv_get(mrb, c2->iv, sym, &v)) {
if (c2 && iv_get(mrb, class_iv_ptr(c2), sym, &v)) {
return v;
}
proc = proc->upper;
@@ -912,7 +921,7 @@ mrb_mod_constants(mrb_state *mrb, mrb_value mod)
mrb_get_args(mrb, "|b", &inherit);
ary = mrb_ary_new(mrb);
while (c) {
iv_foreach(mrb, c->iv, const_i, &ary);
iv_foreach(mrb, class_iv_ptr(c), const_i, &ary);
if (!inherit) break;
c = c->super;
if (c == mrb->object_class) break;
@@ -988,7 +997,7 @@ const_defined_0(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool exclude, mrb
tmp = klass;
retry:
while (tmp) {
if (iv_get(mrb, tmp->iv, id, NULL)) {
if (iv_get(mrb, class_iv_ptr(tmp), id, NULL)) {
return TRUE;
}
if (!recurse && (klass != mrb->object_class)) break;
@@ -1047,7 +1056,7 @@ find_class_sym(mrb_state *mrb, struct RClass *outer, struct RClass *c)
if (outer == c) return 0;
arg.c = c;
arg.sym = 0;
iv_foreach(mrb, outer->iv, csym_i, &arg);
iv_foreach(mrb, class_iv_ptr(outer), csym_i, &arg);
return arg.sym;
}