@@@ -265,8 -265,7 +265,8 @@@ top_proc(mrb_state *mrb, const struct R
#define CI_PROC_SET(ci, p) do {\
ci->proc = p;\
- ci->pc = (p && !MRB_PROC_CFUNC_P(p) && !MRB_PROC_ALIAS_P(p) && p->body.irep) ? p->body.irep->iseq : NULL; \
+ mrb_assert(!p || !MRB_PROC_ALIAS_P(p));\
+ ci->pc = (p && !MRB_PROC_CFUNC_P(p) && p->body.irep) ? p->body.irep->iseq : NULL;\
} while (0)
void
@@@ -1321,7 -1320,7 +1321,7 @@@ mrb_vm_run(mrb_state *mrb, const struc
nregs = stack_keep;
else {
struct REnv *e = CI_ENV(mrb->c->ci);
- if (stack_keep == 0 || (e && irep->nlocals < MRB_ENV_LEN(e))) {
+ if (e && (stack_keep == 0 || irep->nlocals < MRB_ENV_LEN(e))) {
ci_env_set(mrb->c->ci, NULL);
mrb_env_unshare(mrb, e, FALSE);
}
@@@ -1780,8 -1779,7 +1780,8 @@@ RETRY_TRY_BLOCK
}
else if (mrb->c == mrb->root_c) {
mrb->c->ci->stack = mrb->c->stbase;
- goto L_STOP;
+ mrb->jmp = prev_jmp;
+ return mrb_obj_value(mrb->exc);
}
else {
struct mrb_context *c = mrb->c;
mrb_gc_arena_shrink(mrb, ai);
if (mrb->exc) goto L_RAISE;
ci = mrb->c->ci;
- if (!ci->u.target_class) { /* return from context modifying method (resume/yield) */
+ if (!ci->u.keep_context) { /* return from context modifying method (resume/yield) */
if (ci->cci == CINFO_RESUMED) {
mrb->jmp = prev_jmp;
return recv;
if (MRB_PROC_ENV_P(dst)) {
struct REnv *e = MRB_PROC_ENV(dst);
- if (!MRB_ENV_ONSTACK_P(e) || (e->cxt && e->cxt != mrb->c)) {
+ if (!MRB_ENV_ONSTACK_P(e) || e->cxt != mrb->c) {
localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
goto L_RAISE;
}
NORMAL_RETURN:
ci = mrb->c->ci;
-
- if (ci == mrb->c->cibase) {
- struct mrb_context *c;
- c = mrb->c;
-
- if (c->prev && !c->vmexec && c->prev->ci == c->prev->cibase) {
- RAISE_LIT(mrb, E_FIBER_ERROR, "double resume");
- }
- }
-
v = regs[a];
mrb_gc_protect(mrb, v);
CHECKPOINT_RESTORE(RBREAK_TAG_BREAK) {
struct mrb_context *c = mrb->c;
if (c == mrb->root_c) {
/* toplevel return */
- regs[irep->nlocals] = v;
- goto L_STOP;
+ mrb_gc_arena_restore(mrb, ai);
+ mrb->jmp = prev_jmp;
+ return v;
}
/* fiber termination should automatic yield or transfer to root */
mrb->c = c->prev ? c->prev : mrb->root_c;
c->prev = NULL;
mrb->c->status = MRB_FIBER_RUNNING;
- if (c->vmexec) {
+ if (c->vmexec ||
+ (mrb->c == mrb->root_c && mrb->c->ci == mrb->c->cibase) /* case using Fiber#transfer in mrb_fiber_resume() */) {
mrb_gc_arena_restore(mrb, ai);
c->vmexec = FALSE;
mrb->jmp = prev_jmp;
ci = mrb->c->ci;
}
- if (mrb->c->vmexec && !CI_TARGET_CLASS(ci)) {
+ if (mrb->c->vmexec && !ci->u.keep_context) {
mrb_gc_arena_restore(mrb, ai);
mrb->c->vmexec = FALSE;
mrb->jmp = prev_jmp;
UNWIND_ENSURE(mrb, mrb->c->ci, mrb->c->ci->pc, RBREAK_TAG_STOP, mrb->c->ci, mrb_nil_value());
}
CHECKPOINT_END(RBREAK_TAG_STOP);
- L_STOP:
mrb->jmp = prev_jmp;
if (mrb->exc) {
mrb_assert(mrb->exc->tt == MRB_TT_EXCEPTION);
@@@ -3122,3 -3109,7 +3112,3 @@@ mrb_top_run(mrb_state *mrb, const struc
}
return mrb_vm_run(mrb, proc, self, stack_keep);
}
-
-#if defined(MRB_USE_CXX_EXCEPTION) && defined(__cplusplus)
-mrb_int mrb_jmpbuf_id = 0;
-#endif