Fix `super` from aliased methods to work correctly; fix #4718

We needed to preserve the original method name somewhere. We kept it in
the `env` structure pointed from aliased methods. #1457 and #1531 tried
to address this issue. But this patch is more memory efficient.

Limitation: this fix does not support `super` from methods defined by
`define_method`. This limitation may be addressed in the future, but
it's low priority.
parent 47add060
......@@ -1741,6 +1741,25 @@ mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b)
{
mrb_method_t m = mrb_method_search(mrb, c, b);
if (!MRB_METHOD_CFUNC_P(m)) {
struct RProc *p = MRB_METHOD_PROC(m);
if (MRB_PROC_ENV_P(p)) {
MRB_PROC_ENV(p)->mid = b;
}
else {
struct RClass *tc = MRB_PROC_TARGET_CLASS(p);
struct REnv *e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, NULL);
e->mid = b;
if (tc) {
e->c = tc;
mrb_field_write_barrier(mrb, (struct RBasic*)e, (struct RBasic*)tc);
}
p->e.env = e;
p->flags |= MRB_PROC_ENVSET;
}
}
mrb_define_method_raw(mrb, c, a, m);
}
......
......@@ -77,6 +77,9 @@ closure_setup(mrb_state *mrb, struct RProc *p)
e->c = tc;
mrb_field_write_barrier(mrb, (struct RBasic*)e, (struct RBasic*)tc);
}
if (MRB_PROC_ENV_P(up) && MRB_PROC_ENV(up)->cxt == NULL) {
e->mid = MRB_PROC_ENV(up)->mid;
}
}
if (e) {
p->e.env = e;
......
......@@ -1558,9 +1558,13 @@ RETRY_TRY_BLOCK:
struct RClass *cls;
mrb_callinfo *ci = mrb->c->ci;
mrb_value recv, blk;
struct RProc *p = ci->proc;
mrb_sym mid = ci->mid;
struct RClass* target_class = MRB_PROC_TARGET_CLASS(ci->proc);
struct RClass* target_class = MRB_PROC_TARGET_CLASS(p);
if (MRB_PROC_ENV_P(p) && p->e.env->mid && p->e.env->mid != mid) { /* alias support */
mid = p->e.env->mid; /* restore old mid */
}
mrb_assert(bidx < irep->nregs);
if (mid == 0 || !target_class) {
......@@ -2020,7 +2024,7 @@ RETRY_TRY_BLOCK:
if (MRB_PROC_ENV_P(dst)) {
struct REnv *e = MRB_PROC_ENV(dst);
if (!MRB_ENV_STACK_SHARED_P(e) || e->cxt != mrb->c) {
if (!MRB_ENV_STACK_SHARED_P(e) || (e->cxt && e->cxt != mrb->c)) {
localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
goto L_RAISE;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment