This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
remove obsolete panic from die_unwind()
[perl5.git] / pp_ctl.c
index 111d139..93404d4 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -285,8 +285,11 @@ PP(pp_substcont)
            /* PL_tainted must be correctly set for this mg_set */
            SvSETMAGIC(TARG);
            TAINT_NOT;
-           LEAVE_SCOPE(cx->sb_oldsave);
+
+           CX_LEAVE_SCOPE(cx);
            POPSUBST(cx);
+            CX_POP(cx);
+
            PERL_ASYNC_CHECK();
            RETURNOP(pm->op_next);
            NOT_REACHED; /* NOTREACHED */
@@ -1291,7 +1294,7 @@ S_dopoptolabel(pTHX_ const char *label, STRLEN len, U32 flags)
            /* diag_listed_as: Exiting subroutine via %s */
            Perl_ck_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s",
                           context_name[CxTYPE(cx)], OP_NAME(PL_op));
-           if (CxTYPE(cx) == CXt_NULL)
+           if (CxTYPE(cx) == CXt_NULL) /* sort BLOCK */
                return -1;
            break;
        case CXt_LOOP_LAZYIV:
@@ -1438,7 +1441,7 @@ S_dopoptoloop(pTHX_ I32 startingblock)
            /* diag_listed_as: Exiting subroutine via %s */
            Perl_ck_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s",
                           context_name[CxTYPE(cx)], OP_NAME(PL_op));
-           if ((CxTYPE(cx)) == CXt_NULL)
+           if ((CxTYPE(cx)) == CXt_NULL) /* sort BLOCK */
                return -1;
            break;
        case CXt_LOOP_LAZYIV:
@@ -1501,27 +1504,25 @@ S_dopoptowhen(pTHX_ I32 startingblock)
 void
 Perl_dounwind(pTHX_ I32 cxix)
 {
-    I32 optype;
-
     if (!PL_curstackinfo) /* can happen if die during thread cloning */
        return;
 
     while (cxstack_ix > cxix) {
-       SV *sv;
         PERL_CONTEXT *cx = &cxstack[cxstack_ix];
        DEBUG_CX("UNWIND");                                             \
        /* Note: we don't need to restore the base context info till the end. */
+
+        CX_LEAVE_SCOPE(cx);
+
        switch (CxTYPE(cx)) {
        case CXt_SUBST:
            POPSUBST(cx);
-           continue;  /* not break */
+           break;
        case CXt_SUB:
-           POPSUB(cx,sv);
-           LEAVESUB(sv);
+           POPSUB(cx);
            break;
        case CXt_EVAL:
            POPEVAL(cx);
-            PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
            break;
        case CXt_BLOCK:
             POPBASICBLK(cx);
@@ -1539,6 +1540,7 @@ Perl_dounwind(pTHX_ I32 cxix)
            POPGIVEN(cx);
            break;
        case CXt_NULL:
+            /* there isn't a POPNULL ! */
            break;
        case CXt_FORMAT:
            POPFORMAT(cx);
@@ -1546,7 +1548,6 @@ Perl_dounwind(pTHX_ I32 cxix)
        }
        cxstack_ix--;
     }
-    PERL_UNUSED_VAR(optype);
 }
 
 void
@@ -1570,6 +1571,41 @@ Perl_qerror(pTHX_ SV *err)
        ++PL_parser->error_count;
 }
 
+
+
+/* pop the cx, undef or delete the %INC entry, then croak.
+ * require0 indicates that the require didn't return a true value */
+
+void
+S_undo_inc_then_croak(pTHX_ PERL_CONTEXT *cx, SV *err, bool require0)
+{
+    const char *fmt;
+    HV *inc_hv = GvHVn(PL_incgv);
+    SV *namesv = cx->blk_eval.old_namesv;
+    I32  klen  = SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv);
+    const char *key = SvPVX_const(namesv);
+
+    CX_POP(cx);
+
+    if (require0) {
+       (void)hv_delete(inc_hv, key, klen, G_DISCARD);
+       fmt = "%"SVf" did not return a true value";
+        err = namesv;
+    }
+    else {
+        (void)hv_store(inc_hv, key, klen, &PL_sv_undef, 0);
+        fmt = "%"SVf"Compilation failed in require";
+        err = err ? err : newSVpvs_flags("Unknown error\n", SVs_TEMP);
+    }
+
+    /* note that unlike pp_entereval, pp_require isn't
+     * supposed to trap errors. So now that we've popped the
+     * EVAL that pp_require pushed, and processed the error
+     * message, rethrow the error */
+    Perl_croak(aTHX_ fmt, SVfARG(err));
+}
+
+
 void
 Perl_die_unwind(pTHX_ SV *msv)
 {
@@ -1627,14 +1663,9 @@ Perl_die_unwind(pTHX_ SV *msv)
        }
 
        if (cxix >= 0) {
-           I32 optype;
-           SV *namesv;
            PERL_CONTEXT *cx;
            SV **newsp;
             I32 gimme;
-#ifdef DEBUGGING
-           COP *oldcop;
-#endif
            JMPENV *restartjmpenv;
            OP *restartop;
 
@@ -1643,47 +1674,26 @@ Perl_die_unwind(pTHX_ SV *msv)
 
             cx = &cxstack[cxstack_ix];
             assert(CxTYPE(cx) == CXt_EVAL);
+
+            /* return false to the caller of eval */
             newsp = PL_stack_base + cx->blk_oldsp;
             gimme = cx->blk_gimme;
-
            if (gimme == G_SCALAR)
                *++newsp = &PL_sv_undef;
            PL_stack_sp = newsp;
 
-
-           if (CxTYPE(cx) != CXt_EVAL) {
-               STRLEN msglen;
-               const char* message = SvPVx_const(exceptsv, msglen);
-               PerlIO_write(Perl_error_log, (const char *)"panic: die ", 11);
-               PerlIO_write(Perl_error_log, message, msglen);
-               my_exit(1);
-           }
-
-           POPBLOCK(cx,PL_curpm);
+            CX_LEAVE_SCOPE(cx);
            POPEVAL(cx);
-           namesv = cx->blk_eval.old_namesv;
-#ifdef DEBUGGING
-           oldcop = cx->blk_oldcop;
-#endif
+           POPBLOCK(cx);
+
            restartjmpenv = cx->blk_eval.cur_top_env;
            restartop = cx->blk_eval.retop;
+            if (CxOLD_OP_TYPE(cx) == OP_REQUIRE) {
+                S_undo_inc_then_croak(aTHX_ cx, exceptsv, FALSE);
+                NOT_REACHED; /* NOTREACHED */
+            }
+            CX_POP(cx);
 
-            PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
-
-           if (optype == OP_REQUIRE) {
-                assert (PL_curcop == oldcop);
-                (void)hv_store(GvHVn(PL_incgv),
-                               SvPVX_const(namesv),
-                               SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
-                               &PL_sv_undef, 0);
-               /* note that unlike pp_entereval, pp_require isn't
-                * supposed to trap errors. So now that we've popped the
-                * EVAL that pp_require pushed, and processed the error
-                * message, rethrow the error */
-               Perl_croak(aTHX_ "%"SVf"Compilation failed in require",
-                          SVfARG(exceptsv ? exceptsv : newSVpvs_flags("Unknown error\n",
-                                                                    SVs_TEMP)));
-           }
            if (!(in_eval & EVAL_KEEPERR))
                sv_setsv(ERRSV, exceptsv);
            PL_restartjmpenv = restartjmpenv;
@@ -1990,7 +2000,7 @@ PP(pp_dbstate)
            PUSHBLOCK(cx, CXt_SUB, SP);
            PUSHSUB_DB(cx);
            cx->blk_sub.retop = PL_op->op_next;
-            cx->cx_u.cx_blk.blku_old_savestack_ix = PL_savestack_ix;
+            cx->cx_old_savestack_ix = PL_savestack_ix;
 
             SAVEI32(PL_debug);
             PL_debug = 0;
@@ -2011,9 +2021,8 @@ PP(pp_dbstate)
 /* S_leave_common: Common code that many functions in this file use on
                   scope exit.
 
-   Process the return args on the stack in the range (mark+1..sp) based on
-   context, with any final args starting at newsp+1. Returns the new
-   top-of-stack position
+   Process the return args on the stack in the range (mark+1..PL_stack_sp)
+   based on context, with any final args starting at newsp+1.
    Args are mortal copied (or mortalied if lvalue) unless its safe to use
    as-is, based on whether it has the specified flags. Note that most
    callers specify flags as (SVs_PADTMP|SVs_TEMP), while leaveeval skips
@@ -2023,10 +2032,11 @@ PP(pp_dbstate)
    Also, taintedness is cleared.
 */
 
-STATIC SV **
-S_leave_common(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme,
+STATIC void
+S_leave_common(pTHX_ SV **newsp, SV **mark, I32 gimme,
                              U32 flags, bool lvalue)
 {
+    dSP;
     PERL_ARGS_ASSERT_LEAVE_COMMON;
 
     TAINT_NOT;
@@ -2038,11 +2048,8 @@ S_leave_common(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme,
                                ? sv_2mortal(SvREFCNT_inc_simple_NN(*SP))
                                : sv_mortalcopy(*SP);
        else {
-           /* MEXTEND() only updates MARK, so reuse it instead of newsp. */
-           MARK = newsp;
-           MEXTEND(MARK, 1);
-           *++MARK = &PL_sv_undef;
-           return MARK;
+           EXTEND(newsp, 1);
+           *++newsp = &PL_sv_undef;
        }
     }
     else if (gimme == G_ARRAY) {
@@ -2061,9 +2068,10 @@ S_leave_common(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme,
         * point with SP == newsp. */
     }
 
-    return newsp;
+    PL_stack_sp = newsp;
 }
 
+
 PP(pp_enter)
 {
     dSP;
@@ -2078,34 +2086,31 @@ PP(pp_enter)
 
 PP(pp_leave)
 {
-    dSP;
     PERL_CONTEXT *cx;
     SV **newsp;
-    PMOP *newpm;
     I32 gimme;
 
-    if (PL_op->op_flags & OPf_SPECIAL) {
-       cx = &cxstack[cxstack_ix];
-       cx->blk_oldpm = PL_curpm;       /* fake block should preserve $1 et al */
-    }
-
     cx = &cxstack[cxstack_ix];
     assert(CxTYPE(cx) == CXt_BLOCK);
+
+    if (PL_op->op_flags & OPf_SPECIAL)
+       cx->blk_oldpm = PL_curpm; /* fake block should preserve $1 et al */
+
     newsp = PL_stack_base + cx->blk_oldsp;
     gimme = cx->blk_gimme;
-    gimme = OP_GIMME(PL_op, (cxstack_ix >= 0) ? gimme : G_SCALAR);
 
-    SP = (gimme == G_VOID)
-        ? newsp
-        : leave_common(newsp, SP, newsp, gimme, SVs_PADTMP|SVs_TEMP,
+    if (gimme == G_VOID)
+        PL_stack_sp = newsp;
+    else
+        leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP,
                                PL_op->op_private & OPpLVALUE);
 
-    POPBLOCK(cx,newpm);
+    CX_LEAVE_SCOPE(cx);
     POPBASICBLK(cx);
+    POPBLOCK(cx);
+    CX_POP(cx);
 
-    PL_curpm = newpm;  /* Don't pop $1 et al till now */
-
-    RETURN;
+    return NORMAL;
 }
 
 static bool
@@ -2260,11 +2265,9 @@ PP(pp_enterloop)
 
 PP(pp_leaveloop)
 {
-    dSP;
     PERL_CONTEXT *cx;
     I32 gimme;
     SV **newsp;
-    PMOP *newpm;
     SV **mark;
 
     cx = &cxstack[cxstack_ix];
@@ -2273,15 +2276,16 @@ PP(pp_leaveloop)
     newsp = PL_stack_base + cx->blk_loop.resetsp;
     gimme = cx->blk_gimme;
 
-    SP = (gimme == G_VOID)
-        ? newsp
-        : leave_common(newsp, SP, MARK, gimme, SVs_PADTMP|SVs_TEMP,
+    if (gimme == G_VOID)
+        PL_stack_sp = newsp;
+    else
+        leave_common(newsp, MARK, gimme, SVs_PADTMP|SVs_TEMP,
                               PL_op->op_private & OPpLVALUE);
-    PUTBACK;
 
-    POPBLOCK(cx,newpm);
+    CX_LEAVE_SCOPE(cx);
     POPLOOP(cx);       /* Stack values are safe: release loop vars ... */
-    PL_curpm = newpm;  /* ... and pop $1 et al */
+    POPBLOCK(cx);
+    CX_POP(cx);
 
     return NORMAL;
 }
@@ -2300,12 +2304,11 @@ PP(pp_leavesublv)
     dSP;
     SV **newsp;
     SV **mark;
-    PMOP *newpm;
     I32 gimme;
     PERL_CONTEXT *cx;
-    SV *sv;
     bool ref;
     const char *what = NULL;
+    OP *retop;
 
     cx = &cxstack[cxstack_ix];
     assert(CxTYPE(cx) == CXt_SUB);
@@ -2326,7 +2329,6 @@ PP(pp_leavesublv)
     ref = !!(CxLVAL(cx) & OPpENTERSUB_INARGS);
     if (gimme == G_SCALAR) {
        if (CxLVAL(cx) && !ref) {     /* Leave it as it is if we can. */
-           SV *sv;
            if (MARK <= SP) {
                if ((SvPADTMP(TOPs) || SvREADONLY(TOPs)) &&
                    !SvSMAGICAL(TOPs)) {
@@ -2341,10 +2343,6 @@ PP(pp_leavesublv)
                what = "undef";
            }
           croak:
-           POPSUB(cx,sv);
-           cxstack_ix--;
-           PL_curpm = cx->blk_oldpm;
-           LEAVESUB(sv);
            Perl_croak(aTHX_
                      "Can't return %s from lvalue subroutine", what
            );
@@ -2411,14 +2409,13 @@ PP(pp_leavesublv)
     }
     PUTBACK;
 
-    POPBLOCK(cx,newpm);
-    cxstack_ix++; /* preserve cx entry on stack for use by POPSUB */
-    POPSUB(cx,sv);     /* Stack values are safe: release CV and @_ ... */
-    cxstack_ix--;
-    PL_curpm = newpm;  /* ... and pop $1 et al */
-    LEAVESUB(sv);
+    CX_LEAVE_SCOPE(cx);
+    POPSUB(cx);        /* Stack values are safe: release CV and @_ ... */
+    POPBLOCK(cx);
+    retop =  cx->blk_sub.retop;
+    CX_POP(cx);
 
-    return cx->blk_sub.retop;
+    return retop;
 }
 
 
@@ -2431,10 +2428,19 @@ PP(pp_return)
     assert(cxstack_ix >= 0);
     if (cxix < cxstack_ix) {
         if (cxix < 0) {
-            if (!CxMULTICALL(cxstack))
+            if (!(       PL_curstackinfo->si_type == PERLSI_SORT
+                  || (   PL_curstackinfo->si_type == PERLSI_MULTICALL
+                      && (cxstack[0].cx_type & CXp_SUB_RE_FAKE))
+                 )
+            )
                 DIE(aTHX_ "Can't return outside a subroutine");
-            /* We must be in a sort block, which is a CXt_NULL not a
-             * CXt_SUB. Handle specially. */
+            /* We must be in:
+             *  a sort block, which is a CXt_NULL not a CXt_SUB;
+             *  or a /(?{...})/ block.
+             * Handle specially. */
+            assert(CxTYPE(&cxstack[0]) == CXt_NULL
+                    || (   CxTYPE(&cxstack[0]) == CXt_SUB
+                        && (cxstack[0].cx_type & CXp_SUB_RE_FAKE)));
             if (cxstack_ix > 0) {
                 /* See comment below about context popping. Since we know
                  * we're scalar and not lvalue, we can preserve the return
@@ -2468,10 +2474,12 @@ PP(pp_return)
          * return.
          */
         cx = &cxstack[cxix];
-        SP = leave_common(PL_stack_base + cx->blk_oldsp, SP, MARK,
-                            cx->blk_gimme, SVs_TEMP|SVs_PADTMP, TRUE);
         PUTBACK;
+        leave_common(PL_stack_base + cx->blk_oldsp, MARK,
+                            cx->blk_gimme, SVs_TEMP|SVs_PADTMP, TRUE);
+        SPAGAIN;
        dounwind(cxix);
+        cx = &cxstack[cxix]; /* CX stack may have been realloced */
     }
     else {
         /* Like in the branch above, we need to handle any extra junk on
@@ -2563,13 +2571,12 @@ S_unwind_loop(pTHX_ const char * const opname)
 PP(pp_last)
 {
     PERL_CONTEXT *cx;
-    OP *nextop = NULL;
-    PMOP *newpm;
+    OP* nextop;
 
     S_unwind_loop(aTHX_ "last");
 
-    POPBLOCK(cx,newpm);
-    cxstack_ix++; /* temporarily protect top context */
+    cx = &cxstack[cxstack_ix];
+
     assert(
            CxTYPE(cx) == CXt_LOOP_LAZYIV
         || CxTYPE(cx) == CXt_LOOP_LAZYSV
@@ -2577,14 +2584,15 @@ PP(pp_last)
         || CxTYPE(cx) == CXt_LOOP_PLAIN
     );
     PL_stack_sp = PL_stack_base + cx->blk_loop.resetsp;
-    nextop = cx->blk_loop.my_op->op_lastop->op_next;
 
     TAINT_NOT;
 
-    cxstack_ix--;
     /* Stack values are safe: */
+    CX_LEAVE_SCOPE(cx);
     POPLOOP(cx);       /* release loop vars ... */
-    PL_curpm = newpm;  /* ... and pop $1 et al */
+    POPBLOCK(cx);
+    nextop = cx->blk_loop.my_op->op_lastop->op_next;
+    CX_POP(cx);
 
     return nextop;
 }
@@ -2763,8 +2771,6 @@ PP(pp_goto)
            TOPBLOCK(cx);
            SPAGAIN;
 
-            /* partial unrolled POPSUB(): */
-
             /* protect @_ during save stack unwind. */
             if (arg)
                 SvREFCNT_inc_NN(sv_2mortal(MUTABLE_SV(arg)));
@@ -2773,6 +2779,7 @@ PP(pp_goto)
             CX_LEAVE_SCOPE(cx);
 
            if (CxTYPE(cx) == CXt_SUB && CxHASARGS(cx)) {
+                /* this is POPSUB_ARGS() with minor variations */
                AV* av = MUTABLE_AV(PAD_SVl(0));
                 assert(AvARRAY(MUTABLE_AV(
                     PadlistARRAY(CvPADLIST(cx->blk_sub.cv))[
@@ -2858,7 +2865,7 @@ PP(pp_goto)
                  * this is a POPBLOCK(), less all the stuff we already did
                  * for TOPBLOCK() earlier */
                 PL_curcop = cx->blk_oldcop;
-               cxstack_ix--;
+                CX_POP(cx);
 
                /* Push a mark for the start of arglist */
                PUSHMARK(mark);
@@ -3426,53 +3433,40 @@ S_doeval(pTHX_ int gimme, CV* outside, U32 seq, HV *hh)
 
     if (yystatus || PL_parser->error_count || !PL_eval_root) {
        PERL_CONTEXT *cx;
-       I32 optype;                     /* Used by POPEVAL. */
-       SV *namesv;
-        SV *errsv = NULL;
-
-       cx = NULL;
-       namesv = NULL;
-       PERL_UNUSED_VAR(optype);
+        SV *errsv;
 
+       PL_op = saveop;
        /* note that if yystatus == 3, then the EVAL CX block has already
         * been popped, and various vars restored */
-       PL_op = saveop;
        if (yystatus != 3) {
            if (PL_eval_root) {
                op_free(PL_eval_root);
                PL_eval_root = NULL;
            }
            SP = PL_stack_base + POPMARK;       /* pop original mark */
-           POPBLOCK(cx,PL_curpm);
+            cx = &cxstack[cxstack_ix];
+            CX_LEAVE_SCOPE(cx);
            POPEVAL(cx);
-           namesv = cx->blk_eval.old_namesv;
-           /* POPBLOCK has rendered LEAVE_with_name("evalcomp") unnecessary */
-            PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
+           POPBLOCK(cx);
+            if (in_require) {
+                S_undo_inc_then_croak(aTHX_ cx, ERRSV, FALSE);
+                NOT_REACHED; /* NOTREACHED */
+            }
+            CX_POP(cx);
        }
 
        errsv = ERRSV;
        if (in_require) {
-           if (!cx) {
-               /* If cx is still NULL, it means that we didn't go in the
-                * POPEVAL branch. */
-               cx = &cxstack[cxstack_ix];
-               assert(CxTYPE(cx) == CXt_EVAL);
-               namesv = cx->blk_eval.old_namesv;
-           }
-           (void)hv_store(GvHVn(PL_incgv),
-                          SvPVX_const(namesv),
-                           SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
-                          &PL_sv_undef, 0);
-           Perl_croak(aTHX_ "%"SVf"Compilation failed in require",
-                      SVfARG(errsv
-                                ? errsv
-                                : newSVpvs_flags("Unknown error\n", SVs_TEMP)));
-       }
-       else {
-           if (!*(SvPV_nolen_const(errsv))) {
-               sv_setpvs(errsv, "Compilation error");
-           }
+            assert(yystatus == 3);
+            cx = &cxstack[cxstack_ix];
+            assert(CxTYPE(cx) == CXt_EVAL);
+            S_undo_inc_then_croak(aTHX_ cx, errsv, FALSE);
+            NOT_REACHED; /* NOTREACHED */
        }
+
+        if (!*(SvPV_nolen_const(errsv)))
+            sv_setpvs(errsv, "Compilation error");
+
        if (gimme != G_ARRAY) PUSHs(&PL_sv_undef);
        PUTBACK;
        return FALSE;
@@ -4098,7 +4092,7 @@ PP(pp_require)
     /* switch to eval mode */
     PUSHBLOCK(cx, CXt_EVAL, SP);
     PUSHEVAL(cx, name);
-    cx->cx_u.cx_blk.blku_old_savestack_ix = old_savestack_ix;
+    cx->cx_old_savestack_ix = old_savestack_ix;
     cx->blk_eval.retop = PL_op->op_next;
 
     SAVECOPLINE(&PL_compiling);
@@ -4214,7 +4208,7 @@ PP(pp_entereval)
 
     PUSHBLOCK(cx, (CXt_EVAL|CXp_REAL), SP);
     PUSHEVAL(cx, 0);
-    cx->cx_u.cx_blk.blku_old_savestack_ix = old_savestack_ix;
+    cx->cx_old_savestack_ix = old_savestack_ix;
     cx->blk_eval.retop = PL_op->op_next;
 
     /* prepare to compile string */
@@ -4262,12 +4256,10 @@ PP(pp_leaveeval)
 {
     dSP;
     SV **newsp;
-    PMOP *newpm;
     I32 gimme;
     PERL_CONTEXT *cx;
     OP *retop;
     I32 optype;
-    SV *namesv;
     CV *evalcv;
     /* grab this value before POPEVAL restores old PL_in_eval */
     bool keep = cBOOL(PL_in_eval & EVAL_KEEPERR);
@@ -4279,15 +4271,25 @@ PP(pp_leaveeval)
     newsp = PL_stack_base + cx->blk_oldsp;
     gimme = cx->blk_gimme;
 
-    if (gimme != G_VOID)
-        SP = leave_common(newsp, SP, newsp, gimme, SVs_TEMP, FALSE);
-    POPBLOCK(cx,newpm);
+    if (gimme != G_VOID) {
+        PUTBACK;
+        leave_common(newsp, newsp, gimme, SVs_TEMP, FALSE);
+        SPAGAIN;
+    }
+    /* the POPEVAL does a leavescope, which frees the optree associated
+     * with eval, which if it frees the nextstate associated with
+     * PL_curcop, sets PL_curcop to NULL. Which can mess up freeing a
+     * regex when running under 'use re Debug' because it needs PL_curcop
+     * to get the current hints. So restore it early.
+     */
+    PL_curcop = cx->blk_oldcop;
+    CX_LEAVE_SCOPE(cx);
     POPEVAL(cx);
-    namesv = cx->blk_eval.old_namesv;
+    POPBLOCK(cx);
     retop = cx->blk_eval.retop;
     evalcv = cx->blk_eval.cv;
+    optype = CxOLD_OP_TYPE(cx);
 
-    PL_curpm = newpm;  /* Don't pop $1 et al till now */
 
 #ifdef DEBUGGING
     assert(CvDEPTH(evalcv) == 1);
@@ -4298,21 +4300,15 @@ PP(pp_leaveeval)
        !(gimme == G_SCALAR ? SvTRUE(*SP) : SP > newsp))
     {
        /* Unassume the success we assumed earlier. */
-       (void)hv_delete(GvHVn(PL_incgv),
-                       SvPVX_const(namesv),
-                        SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
-                       G_DISCARD);
-        PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
-       Perl_die(aTHX_ "%"SVf" did not return a true value", SVfARG(namesv));
+        S_undo_inc_then_croak(aTHX_ cx, NULL, TRUE);
         NOT_REACHED; /* NOTREACHED */
-       /* die_unwind() did LEAVE, or we won't be here */
-    }
-    else {
-        PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
-        if (!keep)
-           CLEAR_ERRSV();
     }
 
+    CX_POP(cx);
+
+    if (!keep)
+        CLEAR_ERRSV();
+
     RETURNOP(retop);
 }
 
@@ -4321,15 +4317,13 @@ PP(pp_leaveeval)
 void
 Perl_delete_eval_scope(pTHX)
 {
-    PMOP *newpm;
     PERL_CONTEXT *cx;
-    I32 optype;
        
-    POPBLOCK(cx,newpm);
+    cx = &cxstack[cxstack_ix];
+    CX_LEAVE_SCOPE(cx);
     POPEVAL(cx);
-    PL_curpm = newpm;
-    PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
-    PERL_UNUSED_VAR(optype);
+    POPBLOCK(cx);
+    CX_POP(cx);
 }
 
 /* Common-ish code salvaged from Perl_call_sv and pp_entertry, because it was
@@ -4342,7 +4336,7 @@ Perl_create_eval_scope(pTHX_ U32 flags)
        
     PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp);
     PUSHEVAL(cx, 0);
-    cx->cx_u.cx_blk.blku_old_savestack_ix = PL_savestack_ix;
+    cx->cx_old_savestack_ix = PL_savestack_ix;
 
     PL_in_eval = EVAL_INEVAL;
     if (flags & G_KEEPERR)
@@ -4364,12 +4358,9 @@ PP(pp_entertry)
 
 PP(pp_leavetry)
 {
-    dSP;
     SV **newsp;
-    PMOP *newpm;
     I32 gimme;
     PERL_CONTEXT *cx;
-    I32 optype;
     OP *retop;
 
     PERL_ASYNC_CHECK();
@@ -4379,21 +4370,18 @@ PP(pp_leavetry)
     newsp = PL_stack_base + cx->blk_oldsp;
     gimme = cx->blk_gimme;
 
-    SP = (gimme == G_VOID)
-        ? newsp
-        : leave_common(newsp, SP, newsp, gimme,
-                              SVs_PADTMP|SVs_TEMP, FALSE);
-    POPBLOCK(cx,newpm);
-    retop = cx->blk_eval.retop;
+    if (gimme == G_VOID)
+        PL_stack_sp = newsp;
+    else
+        leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE);
+    CX_LEAVE_SCOPE(cx);
     POPEVAL(cx);
-    PERL_UNUSED_VAR(optype);
-
-    PL_curpm = newpm;  /* Don't pop $1 et al till now */
-
-    PL_tmps_floor = cx->cx_u.cx_blk.blku_old_tmpsfloor;
+    POPBLOCK(cx);
+    retop = cx->blk_eval.retop;
+    CX_POP(cx);
 
     CLEAR_ERRSV();
-    RETURNOP(retop);
+    return retop;
 }
 
 PP(pp_entergiven)
@@ -4415,11 +4403,9 @@ PP(pp_entergiven)
 
 PP(pp_leavegiven)
 {
-    dSP;
     PERL_CONTEXT *cx;
     I32 gimme;
     SV **newsp;
-    PMOP *newpm;
     PERL_UNUSED_CONTEXT;
 
     cx = &cxstack[cxstack_ix];
@@ -4427,17 +4413,17 @@ PP(pp_leavegiven)
     newsp = PL_stack_base + cx->blk_oldsp;
     gimme = cx->blk_gimme;
 
-    SP = (gimme == G_VOID)
-        ? newsp
-        : leave_common(newsp, SP, newsp, gimme,
-                              SVs_PADTMP|SVs_TEMP, FALSE);
-    POPBLOCK(cx,newpm);
-    POPGIVEN(cx);
-    assert(CxTYPE(cx) == CXt_GIVEN);
+    if (gimme == G_VOID)
+        PL_stack_sp = newsp;
+    else
+        leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE);
 
-    PL_curpm = newpm;  /* Don't pop $1 et al till now */
+    CX_LEAVE_SCOPE(cx);
+    POPGIVEN(cx);
+    POPBLOCK(cx);
+    CX_POP(cx);
 
-    RETURN;
+    return NORMAL;
 }
 
 /* Helper routines used by pp_smartmatch */
@@ -4997,7 +4983,6 @@ PP(pp_enterwhen)
 
 PP(pp_leavewhen)
 {
-    dSP;
     I32 cxix;
     PERL_CONTEXT *cx;
     I32 gimme;
@@ -5014,10 +4999,10 @@ PP(pp_leavewhen)
                   PL_op->op_flags & OPf_SPECIAL ? "default" : "when");
 
     newsp = PL_stack_base + cx->blk_oldsp;
-    SP = (gimme == G_VOID)
-        ? newsp
-        : leave_common(newsp, SP, newsp, gimme,
-                              SVs_PADTMP|SVs_TEMP, FALSE);
+    if (gimme == G_VOID)
+        PL_stack_sp = newsp;
+    else
+        leave_common(newsp, newsp, gimme, SVs_PADTMP|SVs_TEMP, FALSE);
     /* pop the WHEN, BLOCK and anything else before the GIVEN/FOR */
     assert(cxix < cxstack_ix);
     dounwind(cxix);
@@ -5034,17 +5019,15 @@ PP(pp_leavewhen)
     else {
        PERL_ASYNC_CHECK();
         assert(cx->blk_givwhen.leave_op->op_type == OP_LEAVEGIVEN);
-       RETURNOP(cx->blk_givwhen.leave_op);
+       return cx->blk_givwhen.leave_op;
     }
 }
 
 PP(pp_continue)
 {
-    dSP;
     I32 cxix;
     PERL_CONTEXT *cx;
-    PMOP *newpm;
-
+    OP *nextop;
     
     cxix = dopoptowhen(cxstack_ix); 
     if (cxix < 0)   
@@ -5053,14 +5036,16 @@ PP(pp_continue)
     if (cxix < cxstack_ix)
         dounwind(cxix);
     
-    POPBLOCK(cx,newpm);
+    cx = &cxstack[cxstack_ix];
     assert(CxTYPE(cx) == CXt_WHEN);
+    PL_stack_sp = PL_stack_base + cx->blk_oldsp;
+    CX_LEAVE_SCOPE(cx);
     POPWHEN(cx);
+    POPBLOCK(cx);
+    nextop = cx->blk_givwhen.leave_op->op_next;
+    CX_POP(cx);
 
-    SP = PL_stack_base + cx->blk_oldsp;
-    PL_curpm = newpm;   /* pop $1 et al */
-
-    RETURNOP(cx->blk_givwhen.leave_op->op_next);
+    return nextop;
 }
 
 PP(pp_break)