diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-04-18 11:52:16 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2017-04-18 11:52:16 +0900 |
| commit | f6c70bc6e8ea472f4d1620d38745da4be0722197 (patch) | |
| tree | 513b3bb83061eff3ca2156f1820d23028b9534f6 /src | |
| parent | 05fceb5992c20c30a6b31f89d2b0aa0f0698a9a2 (diff) | |
| download | mruby-f6c70bc6e8ea472f4d1620d38745da4be0722197.tar.gz mruby-f6c70bc6e8ea472f4d1620d38745da4be0722197.zip | |
`super` may call context switching method like `send`; fix #3611
Diffstat (limited to 'src')
| -rw-r--r-- | src/vm.c | 30 |
1 files changed, 24 insertions, 6 deletions
@@ -991,11 +991,14 @@ RETRY_TRY_BLOCK: CASE(OP_GETCONST) { /* A Bx R(A) := constget(Syms(Bx)) */ mrb_value val; + int a = GETARG_A(i); + int bx = GETARG_Bx(i); + mrb_sym sym = syms[bx]; ERR_PC_SET(mrb, pc); - val = mrb_vm_const_get(mrb, syms[GETARG_Bx(i)]); + val = mrb_vm_const_get(mrb, sym); ERR_PC_CLR(mrb); - regs[GETARG_A(i)] = val; + regs[a] = val; NEXT; } @@ -1276,7 +1279,6 @@ RETRY_TRY_BLOCK: result = m->body.func(mrb, recv); mrb_gc_arena_restore(mrb, ai); if (mrb->exc) goto L_RAISE; - /* pop stackpos */ ci = mrb->c->ci; if (!ci->target_class) { /* return from context modifying method (resume/yield) */ if (ci->acc == CI_ACC_RESUMED) { @@ -1292,6 +1294,7 @@ RETRY_TRY_BLOCK: } } mrb->c->stack[0] = result; + /* pop stackpos */ mrb->c->stack = ci->stackent; pc = ci->pc; cipop(mrb); @@ -1475,13 +1478,28 @@ RETRY_TRY_BLOCK: ci->nregs = n + 2; } v = m->body.func(mrb, recv); - mrb->c->stack[0] = v; mrb_gc_arena_restore(mrb, ai); if (mrb->exc) goto L_RAISE; + ci = mrb->c->ci; + if (!ci->target_class) { /* return from context modifying method (resume/yield) */ + if (ci->acc == CI_ACC_RESUMED) { + mrb->jmp = prev_jmp; + return v; + } + else { + mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc)); + proc = ci[-1].proc; + irep = proc->body.irep; + pool = irep->pool; + syms = irep->syms; + } + } + mrb->c->stack[0] = v; /* pop stackpos */ - mrb->c->stack = mrb->c->ci->stackent; + mrb->c->stack = ci->stackent; + pc = ci->pc; cipop(mrb); - NEXT; + JUMP; } else { /* fill callinfo */ |
