Merge pull request #6137 from dearblue/fiber-unreachable
authorYukihiro "Matz" Matsumoto <[email protected]>
Thu, 7 Mar 2024 07:13:56 +0000 (7 16:13 +0900)
committerGitHub <[email protected]>
Thu, 7 Mar 2024 07:13:56 +0000 (7 16:13 +0900)
Remove unreachable blocks in `OP_RETURN`

1  2 
src/vm.c

diff --combined src/vm.c
+++ b/src/vm.c
@@@ -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