This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
S_setup_longest(): SvTAIL() used where always 0
[perl5.git] / pp_ctl.c
index b1452cd..f7dd946 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -104,18 +104,6 @@ PP(pp_regcomp)
     assert (re != (REGEXP*) &PL_sv_undef);
     eng = re ? RX_ENGINE(re) : current_re_engine();
 
-    /*
-     In the below logic: these are basically the same - check if this regcomp is part of a split.
-
-    (PL_op->op_pmflags & PMf_split )
-    (PL_op->op_next->op_type == OP_PUSHRE)
-
-    We could add a new mask for this and copy the PMf_split, if we did
-    some bit definition fiddling first.
-
-    For now we leave this
-    */
-
     new_re = (eng->op_comp
                    ? eng->op_comp
                    : &Perl_re_op_compile
@@ -171,11 +159,24 @@ PP(pp_regcomp)
         RX_TAINT_on(new_re);
     }
 
+    /* handle the empty pattern */
+    if (!RX_PRELEN(PM_GETRE(pm)) && PL_curpm) {
+        if (PL_curpm == PL_reg_curpm) {
+            if (PL_curpm_under) {
+                if (PL_curpm_under == PL_reg_curpm) {
+                    Perl_croak(aTHX_ "Infinite recursion via empty pattern");
+                } else {
+                    pm = PL_curpm_under;
+                }
+            }
+        } else {
+            pm = PL_curpm;
+        }
+    }
+
 #if !defined(USE_ITHREADS)
     /* can't change the optree at runtime either */
     /* PMf_KEEP is handled differently under threads to avoid these problems */
-    if (!RX_PRELEN(PM_GETRE(pm)) && PL_curpm)
-       pm = PL_curpm;
     if (pm->op_pmflags & PMf_KEEP) {
        pm->op_private &= ~OPpRUNTIME;  /* no point compiling again */
        cLOGOP->op_first->op_next = PL_op->op_next;
@@ -927,6 +928,7 @@ PP(pp_formline)
     }
 }
 
+/* also used for: pp_mapstart() */
 PP(pp_grepstart)
 {
     dSP;
@@ -965,7 +967,7 @@ PP(pp_grepstart)
 PP(pp_mapwhile)
 {
     dSP;
-    const I32 gimme = GIMME_V;
+    const U8 gimme = GIMME_V;
     I32 items = (SP - PL_stack_base) - TOPMARK; /* how many new items */
     I32 count;
     I32 shift;
@@ -1150,7 +1152,7 @@ PP(pp_flip)
                RETURNOP(((LOGOP*)cUNOP->op_first)->op_other);
            }
        }
-       sv_setpvs(TARG, "");
+        SvPVCLEAR(TARG);
        SETs(targ);
        RETURN;
     }
@@ -1332,14 +1334,14 @@ S_dopoptolabel(pTHX_ const char *label, STRLEN len, U32 flags)
 
 
 
-I32
+U8
 Perl_dowantarray(pTHX)
 {
-    const I32 gimme = block_gimme();
+    const U8 gimme = block_gimme();
     return (gimme == G_VOID) ? G_SCALAR : gimme;
 }
 
-I32
+U8
 Perl_block_gimme(pTHX)
 {
     const I32 cxix = dopoptosub(cxstack_ix);
@@ -1366,7 +1368,7 @@ Perl_is_lvalue_sub(pTHX)
        return 0;
 }
 
-/* only used by PUSHSUB */
+/* only used by cx_pushsub() */
 I32
 Perl_was_lvalue_sub(pTHX)
 {
@@ -1508,7 +1510,7 @@ S_dopoptowhen(pTHX_ I32 startingblock)
 /* dounwind(): pop all contexts above (but not including) cxix.
  * Note that it clears the savestack frame associated with each popped
  * context entry, but doesn't free any temps.
- * It does a CX_POPBLOCK of the last frame that it pops, and leaves
+ * It does a cx_popblock() of the last frame that it pops, and leaves
  * cxstack_ix equal to cxix.
  */
 
@@ -1531,36 +1533,34 @@ Perl_dounwind(pTHX_ I32 cxix)
            CX_POPSUBST(cx);
            break;
        case CXt_SUB:
-           CX_POPSUB(cx);
+           cx_popsub(cx);
            break;
        case CXt_EVAL:
-           CX_POPEVAL(cx);
-           break;
-       case CXt_BLOCK:
-            CX_POPBASICBLK(cx);
+           cx_popeval(cx);
            break;
        case CXt_LOOP_PLAIN:
        case CXt_LOOP_LAZYIV:
        case CXt_LOOP_LAZYSV:
        case CXt_LOOP_LIST:
        case CXt_LOOP_ARY:
-           CX_POPLOOP(cx);
+           cx_poploop(cx);
            break;
        case CXt_WHEN:
-           CX_POPWHEN(cx);
+           cx_popwhen(cx);
            break;
        case CXt_GIVEN:
-           CX_POPGIVEN(cx);
+           cx_popgiven(cx);
            break;
+       case CXt_BLOCK:
        case CXt_NULL:
-            /* there isn't a CX_POPNULL ! */
+            /* these two don't have a POPFOO() */
            break;
        case CXt_FORMAT:
-           CX_POPFORMAT(cx);
+           cx_popformat(cx);
            break;
        }
         if (cxstack_ix == cxix + 1) {
-            CX_POPBLOCK(cx);
+            cx_popblock(cx);
         }
        cxstack_ix--;
     }
@@ -1590,42 +1590,74 @@ Perl_qerror(pTHX_ SV *err)
 
 
 
-/* undef or delete the $INC{namesv} entry, then croak.
- * require0 indicates that the require didn't return a true value */
+/* pop a CXt_EVAL context and in addition, if it was a require then
+ * based on action:
+ *     0: do nothing extra;
+ *     1: undef  $INC{$name}; croak "$name did not return a true value";
+ *     2: delete $INC{$name}; croak "$errsv: Compilation failed in require"
+ */
 
 static void
-S_undo_inc_then_croak(pTHX_ SV *namesv, SV *err, bool require0)
+S_pop_eval_context_maybe_croak(pTHX_ PERL_CONTEXT *cx, SV *errsv, int action)
 {
-    const char *fmt;
-    HV *inc_hv = GvHVn(PL_incgv);
-    I32  klen  = SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv);
-    const char *key = SvPVX_const(namesv);
+    SV  *namesv = NULL; /* init to avoid dumb compiler warning */
+    bool do_croak;
 
-    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);
+    CX_LEAVE_SCOPE(cx);
+    do_croak = action && (CxOLD_OP_TYPE(cx) == OP_REQUIRE);
+    if (do_croak) {
+        /* keep namesv alive after cx_popeval() */
+        namesv = cx->blk_eval.old_namesv;
+        cx->blk_eval.old_namesv = NULL;
+        sv_2mortal(namesv);
     }
+    cx_popeval(cx);
+    cx_popblock(cx);
+    CX_POP(cx);
+
+    if (do_croak) {
+        const char *fmt;
+        HV *inc_hv = GvHVn(PL_incgv);
+        I32  klen  = SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv);
+        const char *key = SvPVX_const(namesv);
+
+        if (action == 1) {
+            (void)hv_delete(inc_hv, key, klen, G_DISCARD);
+            fmt = "%"SVf" did not return a true value";
+            errsv = namesv;
+        }
+        else {
+            (void)hv_store(inc_hv, key, klen, &PL_sv_undef, 0);
+            fmt = "%"SVf"Compilation failed in require";
+            if (!errsv)
+                errsv = newSVpvs_flags("Unknown error\n", SVs_TEMP);
+        }
 
-    Perl_croak(aTHX_ fmt, SVfARG(err));
+        Perl_croak(aTHX_ fmt, SVfARG(errsv));
+    }
 }
 
 
+/* die_unwind(): this is the final destination for the various croak()
+ * functions. If we're in an eval, unwind the context and other stacks
+ * back to the top-most CXt_EVAL and set $@ to msv; otherwise print msv
+ * to STDERR and initiate an exit. Note that if the CXt_EVAL popped back
+ * to is a require the exception will be rethrown, as requires don't
+ * actually trap exceptions.
+ */
+
 void
 Perl_die_unwind(pTHX_ SV *msv)
 {
-    SV *exceptsv = sv_mortalcopy(msv);
+    SV *exceptsv = msv;
     U8 in_eval = PL_in_eval;
     PERL_ARGS_ASSERT_DIE_UNWIND;
 
     if (in_eval) {
        I32 cxix;
 
+        exceptsv = sv_2mortal(SvREFCNT_inc_simple_NN(exceptsv));
+
        /*
         * Historically, perl used to set ERRSV ($@) early in the die
         * process and rely on it not getting clobbered during unwinding.
@@ -1655,10 +1687,9 @@ Perl_die_unwind(pTHX_ SV *msv)
         * perls 5.13.{1..7} which had late setting of $@ without this
         * early-setting hack.
         */
-       if (!(in_eval & EVAL_KEEPERR)) {
-           SvTEMP_off(exceptsv);
-           sv_setsv(ERRSV, exceptsv);
-       }
+       if (!(in_eval & EVAL_KEEPERR))
+           sv_setsv_flags(ERRSV, exceptsv,
+                        (SV_GMAGIC|SV_DO_COW_SVSETSV|SV_NOSTEAL));
 
        if (in_eval & EVAL_KEEPERR) {
            Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "\t(in cleanup) %"SVf,
@@ -1673,10 +1704,9 @@ Perl_die_unwind(pTHX_ SV *msv)
        }
 
        if (cxix >= 0) {
-            SV *namesv = NULL;
            PERL_CONTEXT *cx;
            SV **oldsp;
-            I32 gimme;
+            U8 gimme;
            JMPENV *restartjmpenv;
            OP *restartop;
 
@@ -1693,23 +1723,15 @@ Perl_die_unwind(pTHX_ SV *msv)
                *++oldsp = &PL_sv_undef;
            PL_stack_sp = oldsp;
 
-            CX_LEAVE_SCOPE(cx);
-           CX_POPEVAL(cx);
-           CX_POPBLOCK(cx);
            restartjmpenv = cx->blk_eval.cur_top_env;
-           restartop = cx->blk_eval.retop;
-            if (CxOLD_OP_TYPE(cx) == OP_REQUIRE)
-                namesv = cx->blk_eval.old_namesv;
-            CX_POP(cx);
-
-            if (namesv) {
-                /* 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, process the error message
-                 * and rethrow the error */
-                S_undo_inc_then_croak(aTHX_ namesv, exceptsv, FALSE);
-                NOT_REACHED; /* NOTREACHED */
-            }
+           restartop     = cx->blk_eval.retop;
+            /* Note that unlike pp_entereval, pp_require isn't supposed to
+             * trap errors. So if we're a require, after we pop the
+             * CXt_EVAL that pp_require pushed, rethrow the error with
+             * croak(exceptsv). This is all handled by the call below when
+             * action == 2.
+             */
+            S_pop_eval_context_maybe_croak(aTHX_ cx, exceptsv, 2);
 
            if (!(in_eval & EVAL_KEEPERR))
                sv_setsv(ERRSV, exceptsv);
@@ -1802,7 +1824,7 @@ PP(pp_caller)
     dSP;
     const PERL_CONTEXT *cx;
     const PERL_CONTEXT *dbcx;
-    I32 gimme = GIMME_V;
+    U8 gimme = GIMME_V;
     const HEK *stash_hek;
     I32 count = 0;
     bool has_arg = MAXARG && TOPs;
@@ -1872,7 +1894,7 @@ PP(pp_caller)
        PUSHs(newSVpvs_flags("(eval)", SVs_TEMP));
        mPUSHi(0);
     }
-    gimme = (I32)cx->blk_gimme;
+    gimme = cx->blk_gimme;
     if (gimme == G_VOID)
        PUSHs(&PL_sv_undef);
     else
@@ -1986,7 +2008,7 @@ PP(pp_dbstate)
     {
        dSP;
        PERL_CONTEXT *cx;
-       const I32 gimme = G_ARRAY;
+       const U8 gimme = G_ARRAY;
        GV * const gv = PL_DBgv;
        CV * cv = NULL;
 
@@ -2013,9 +2035,12 @@ PP(pp_dbstate)
            return NORMAL;
        }
        else {
-           PUSHBLOCK(cx, CXt_SUB, gimme, SP, PL_savestack_ix);
-           PUSHSUB_DB(cx, cv, 0);
-           cx->blk_sub.retop = PL_op->op_next;
+           cx = cx_pushblock(CXt_SUB, gimme, SP, PL_savestack_ix);
+           cx_pushsub(cx, cv, PL_op->op_next, 0);
+            /* OP_DBSTATE's op_private holds hint bits rather than
+             * the lvalue-ish flags seen in OP_ENTERSUB. So cancel
+             * any CxLVAL() flags that have now been mis-calculated */
+            cx->blk_u16 = 0;
 
             SAVEI32(PL_debug);
             PL_debug = 0;
@@ -2034,27 +2059,25 @@ PP(pp_dbstate)
 
 PP(pp_enter)
 {
-    dSP;
-    PERL_CONTEXT *cx;
-    I32 gimme = GIMME_V;
-
-    PUSHBLOCK(cx, CXt_BLOCK, gimme, SP, PL_savestack_ix);
-    PUSHBASICBLK(cx);
+    U8 gimme = GIMME_V;
 
-    RETURN;
+    (void)cx_pushblock(CXt_BLOCK, gimme, PL_stack_sp, PL_savestack_ix);
+    return NORMAL;
 }
 
+
 PP(pp_leave)
 {
     PERL_CONTEXT *cx;
     SV **oldsp;
-    I32 gimme;
+    U8 gimme;
 
     cx = CX_CUR();
     assert(CxTYPE(cx) == CXt_BLOCK);
 
     if (PL_op->op_flags & OPf_SPECIAL)
-       cx->blk_oldpm = PL_curpm; /* fake block should preserve $1 et al */
+        /* fake block should preserve $1 et al; e.g.  /(...)/ while ...; */
+       cx->blk_oldpm = PL_curpm;
 
     oldsp = PL_stack_base + cx->blk_oldsp;
     gimme = cx->blk_gimme;
@@ -2066,8 +2089,7 @@ PP(pp_leave)
                                 PL_op->op_private & OPpLVALUE ? 3 : 1);
 
     CX_LEAVE_SCOPE(cx);
-    CX_POPBASICBLK(cx);
-    CX_POPBLOCK(cx);
+    cx_popblock(cx);
     CX_POP(cx);
 
     return NORMAL;
@@ -2099,7 +2121,7 @@ PP(pp_enteriter)
 {
     dSP; dMARK;
     PERL_CONTEXT *cx;
-    const I32 gimme = GIMME_V;
+    const U8 gimme = GIMME_V;
     void *itervarp; /* GV or pad slot of the iteration variable */
     SV   *itersave; /* the old var in the iterator var slot */
     U8 cxflags = 0;
@@ -2138,8 +2160,13 @@ PP(pp_enteriter)
     /* OPpITER_DEF (implicit $_) should only occur with a GV iter var */
     assert((cxflags & CXp_FOR_GV) || !(PL_op->op_private & OPpITER_DEF));
 
-    PUSHBLOCK(cx, cxflags, gimme, MARK, PL_savestack_ix);
-    PUSHLOOP_FOR(cx, itervarp, itersave);
+    /* Note that this context is initially set as CXt_NULL. Further on
+     * down it's changed to one of the CXt_LOOP_*. Before it's changed,
+     * there mustn't be anything in the blk_loop substruct that requires
+     * freeing or undoing, in case we die in the meantime. And vice-versa.
+     */
+    cx = cx_pushblock(cxflags, gimme, MARK, PL_savestack_ix);
+    cx_pushloop_for(cx, itervarp, itersave);
 
     if (PL_op->op_flags & OPf_STACKED) {
         /* OPf_STACKED implies either a single array: for(@), with a
@@ -2209,40 +2236,39 @@ PP(pp_enteriter)
 
 PP(pp_enterloop)
 {
-    dSP;
     PERL_CONTEXT *cx;
-    const I32 gimme = GIMME_V;
+    const U8 gimme = GIMME_V;
 
-    PUSHBLOCK(cx, CXt_LOOP_PLAIN, gimme, SP, PL_savestack_ix);
-    PUSHLOOP_PLAIN(cx);
-
-    RETURN;
+    cx = cx_pushblock(CXt_LOOP_PLAIN, gimme, PL_stack_sp, PL_savestack_ix);
+    cx_pushloop_plain(cx);
+    return NORMAL;
 }
 
+
 PP(pp_leaveloop)
 {
     PERL_CONTEXT *cx;
-    I32 gimme;
+    U8 gimme;
+    SV **base;
     SV **oldsp;
-    SV **mark;
 
     cx = CX_CUR();
     assert(CxTYPE_is_LOOP(cx));
-    mark = PL_stack_base + cx->blk_oldsp;
-    oldsp = CxTYPE(cx) == CXt_LOOP_LIST
+    oldsp = PL_stack_base + cx->blk_oldsp;
+    base = CxTYPE(cx) == CXt_LOOP_LIST
                 ? PL_stack_base + cx->blk_loop.state_u.stack.basesp
-                : mark;
+                : oldsp;
     gimme = cx->blk_gimme;
 
     if (gimme == G_VOID)
-        PL_stack_sp = oldsp;
+        PL_stack_sp = base;
     else
-        leave_adjust_stacks(MARK, oldsp, gimme,
+        leave_adjust_stacks(oldsp, base, gimme,
                                 PL_op->op_private & OPpLVALUE ? 3 : 1);
 
     CX_LEAVE_SCOPE(cx);
-    CX_POPLOOP(cx);    /* Stack values are safe: release loop vars ... */
-    CX_POPBLOCK(cx);
+    cx_poploop(cx);    /* Stack values are safe: release loop vars ... */
+    cx_popblock(cx);
     CX_POP(cx);
 
     return NORMAL;
@@ -2255,11 +2281,13 @@ PP(pp_leaveloop)
  *
  * Any changes made to this function may need to be copied to pp_leavesub
  * and vice-versa.
+ *
+ * also tail-called by pp_return
  */
 
 PP(pp_leavesublv)
 {
-    I32 gimme;
+    U8 gimme;
     PERL_CONTEXT *cx;
     SV **oldsp;
     OP *retop;
@@ -2348,8 +2376,8 @@ PP(pp_leavesublv)
     }
 
     CX_LEAVE_SCOPE(cx);
-    CX_POPSUB(cx);     /* Stack values are safe: release CV and @_ ... */
-    CX_POPBLOCK(cx);
+    cx_popsub(cx);     /* Stack values are safe: release CV and @_ ... */
+    cx_popblock(cx);
     retop =  cx->blk_sub.retop;
     CX_POP(cx);
 
@@ -2396,20 +2424,18 @@ PP(pp_return)
         }
 
         /* There are contexts that need popping. Doing this may free the
-         * return value(s), so preserve them first, e.g. popping the plain
+         * return value(s), so preserve them first: e.g. popping the plain
          * loop here would free $x:
          *     sub f {  { my $x = 1; return $x } }
          * We may also need to shift the args down; for example,
          *    for (1,2) { return 3,4 }
-         * leaves 1,2,3,4 on the stack. Both these actions can be done by
-         * leave_adjust_stacks().  By calling it with and lvalue "pass
-         * all" action, we just bump the ref count and mortalise the args
-         * that need it, do a FREETMPS.  The "scan the args and maybe copy
-         * them" process will be repeated by whoever we tail-call (e.g.
-         * pp_leaveeval), where any copying etc will be done. That is to
-         * say, in this code path two scans of the args will be done; the
-         * first just shifts and preserves; the second is the "real" arg
-         * processing, based on the type of return.
+         * leaves 1,2,3,4 on the stack. Both these actions will be done by
+         * leave_adjust_stacks(), along with freeing any temps. Note that
+         * whoever we tail-call (e.g. pp_leaveeval) will also call
+         * leave_adjust_stacks(); however, the second call is likely to
+         * just see a bunch of SvTEMPs with a ref count of 1, and so just
+         * pass them through, rather than copying them again. So this
+         * isn't as inefficient as it sounds.
          */
         cx = &cxstack[cxix];
         PUTBACK;
@@ -2530,8 +2556,8 @@ PP(pp_last)
 
     /* Stack values are safe: */
     CX_LEAVE_SCOPE(cx);
-    CX_POPLOOP(cx);    /* release loop vars ... */
-    CX_POPBLOCK(cx);
+    cx_poploop(cx);    /* release loop vars ... */
+    cx_popblock(cx);
     nextop = cx->blk_loop.my_op->op_lastop->op_next;
     CX_POP(cx);
 
@@ -2547,7 +2573,7 @@ PP(pp_next)
     if (!((PL_op->op_flags & OPf_SPECIAL) && CxTYPE_is_LOOP(cx)))
         cx = S_unwind_loop(aTHX);
 
-    CX_TOPBLOCK(cx);
+    cx_topblock(cx);
     PL_curcop = cx->blk_oldcop;
     PERL_ASYNC_CHECK();
     return (cx)->blk_loop.my_op->op_nextop;
@@ -2568,7 +2594,7 @@ PP(pp_redo)
 
     FREETMPS;
     CX_LEAVE_SCOPE(cx);
-    CX_TOPBLOCK(cx);
+    cx_topblock(cx);
     PL_curcop = cx->blk_oldcop;
     PERL_ASYNC_CHECK();
     return redo_op;
@@ -2713,7 +2739,7 @@ PP(pp_goto)
                dounwind(cxix);
             }
             cx = CX_CUR();
-           CX_TOPBLOCK(cx);
+           cx_topblock(cx);
            SPAGAIN;
 
             /* protect @_ during save stack unwind. */
@@ -2724,7 +2750,7 @@ PP(pp_goto)
             CX_LEAVE_SCOPE(cx);
 
            if (CxTYPE(cx) == CXt_SUB && CxHASARGS(cx)) {
-                /* this is part of CX_POPSUB_ARGS() */
+                /* this is part of cx_popsub_args() */
                AV* av = MUTABLE_AV(PAD_SVl(0));
                 assert(AvARRAY(MUTABLE_AV(
                     PadlistARRAY(CvPADLIST(cx->blk_sub.cv))[
@@ -2807,8 +2833,8 @@ PP(pp_goto)
                 PL_curpad = LIKELY(PL_comppad) ? AvARRAY(PL_comppad) : NULL;
 
                /* XS subs don't have a CXt_SUB, so pop it;
-                 * this is a CX_POPBLOCK(), less all the stuff we already did
-                 * for CX_TOPBLOCK() earlier */
+                 * this is a cx_popblock(), less all the stuff we already did
+                 * for cx_topblock() earlier */
                 PL_curcop = cx->blk_oldcop;
                 CX_POP(cx);
 
@@ -2824,7 +2850,7 @@ PP(pp_goto)
 
                 SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */
 
-                /* partial unrolled PUSHSUB(): */
+                /* partial unrolled cx_pushsub(): */
 
                cx->blk_sub.cv = cv;
                cx->blk_sub.olddepth = CvDEPTH(cv);
@@ -2996,7 +3022,7 @@ PP(pp_goto)
                DIE(aTHX_ "panic: docatch: illegal ix=%ld", (long)ix);
            dounwind(ix);
             cx = CX_CUR();
-           CX_TOPBLOCK(cx);
+           cx_topblock(cx);
        }
 
        /* push wanted frames */
@@ -3257,7 +3283,7 @@ S_try_yyparse(pTHX_ int gramtype)
  */
 
 STATIC bool
-S_doeval_compile(pTHX_ int gimme, CV* outside, U32 seq, HV *hh)
+S_doeval_compile(pTHX_ U8 gimme, CV* outside, U32 seq, HV *hh)
 {
     dSP;
     OP * const saveop = PL_op;
@@ -3329,7 +3355,7 @@ S_doeval_compile(pTHX_ int gimme, CV* outside, U32 seq, HV *hh)
     }
     else {
        PL_hints = saveop->op_private & OPpEVAL_COPHH
-                    ? oldcurcop->cop_hints : saveop->op_targ;
+                    ? oldcurcop->cop_hints : (U32)saveop->op_targ;
 
         /* making 'use re eval' not be in scope when compiling the
          * qr/mabye_has_runtime_code_block/ ensures that we don't get
@@ -3381,7 +3407,6 @@ S_doeval_compile(pTHX_ int gimme, CV* outside, U32 seq, HV *hh)
     yystatus = (!in_require && CATCH_GET) ? S_try_yyparse(aTHX_ GRAMPROG) : yyparse(GRAMPROG);
 
     if (yystatus || PL_parser->error_count || !PL_eval_root) {
-        SV *namesv = NULL; /* initialise  to avoid compiler warning */
        PERL_CONTEXT *cx;
         SV *errsv;
 
@@ -3396,25 +3421,17 @@ S_doeval_compile(pTHX_ int gimme, CV* outside, U32 seq, HV *hh)
            }
            SP = PL_stack_base + POPMARK;       /* pop original mark */
             cx = CX_CUR();
-            CX_LEAVE_SCOPE(cx);
-           CX_POPEVAL(cx);
-           CX_POPBLOCK(cx);
-            if (in_require)
-                namesv = cx->blk_eval.old_namesv;
-            CX_POP(cx);
+            assert(CxTYPE(cx) == CXt_EVAL);
+            /* pop the CXt_EVAL, and if was a require, croak */
+            S_pop_eval_context_maybe_croak(aTHX_ cx, ERRSV, 2);
        }
 
-       errsv = ERRSV;
-       if (in_require) {
-            if (yystatus == 3) {
-                cx = CX_CUR();
-                assert(CxTYPE(cx) == CXt_EVAL);
-                namesv = cx->blk_eval.old_namesv;
-            }
-            S_undo_inc_then_croak(aTHX_ namesv, errsv, FALSE);
-            NOT_REACHED; /* NOTREACHED */
-       }
+        /* die_unwind() re-croaks when in require, having popped the
+         * require EVAL context. So we should never catch a require
+         * exception here */
+       assert(!in_require);
 
+       errsv = ERRSV;
         if (!*(SvPV_nolen_const(errsv)))
             sv_setpvs(errsv, "Compilation error");
 
@@ -3580,13 +3597,80 @@ S_path_is_searchable(const char *name)
 }
 
 
-/* also used for: pp_dofile() */
+/* implement 'require 5.010001' */
 
-PP(pp_require)
+static OP *
+S_require_version(pTHX_ SV *sv)
 {
-    dSP;
+    dVAR; dSP;
+
+    sv = sv_2mortal(new_version(sv));
+    if (!Perl_sv_derived_from_pvn(aTHX_ PL_patchlevel, STR_WITH_LEN("version"), 0))
+        upg_version(PL_patchlevel, TRUE);
+    if (cUNOP->op_first->op_type == OP_CONST && cUNOP->op_first->op_private & OPpCONST_NOVER) {
+        if ( vcmp(sv,PL_patchlevel) <= 0 )
+            DIE(aTHX_ "Perls since %"SVf" too modern--this is %"SVf", stopped",
+                SVfARG(sv_2mortal(vnormal(sv))),
+                SVfARG(sv_2mortal(vnormal(PL_patchlevel)))
+            );
+    }
+    else {
+        if ( vcmp(sv,PL_patchlevel) > 0 ) {
+            I32 first = 0;
+            AV *lav;
+            SV * const req = SvRV(sv);
+            SV * const pv = *hv_fetchs(MUTABLE_HV(req), "original", FALSE);
+
+            /* get the left hand term */
+            lav = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(req), "version", FALSE)));
+
+            first  = SvIV(*av_fetch(lav,0,0));
+            if (   first > (int)PERL_REVISION    /* probably 'use 6.0' */
+                || hv_exists(MUTABLE_HV(req), "qv", 2 ) /* qv style */
+                || av_tindex(lav) > 1            /* FP with > 3 digits */
+                || strstr(SvPVX(pv),".0")        /* FP with leading 0 */
+               ) {
+                DIE(aTHX_ "Perl %"SVf" required--this is only "
+                    "%"SVf", stopped",
+                    SVfARG(sv_2mortal(vnormal(req))),
+                    SVfARG(sv_2mortal(vnormal(PL_patchlevel)))
+                );
+            }
+            else { /* probably 'use 5.10' or 'use 5.8' */
+                SV *hintsv;
+                I32 second = 0;
+
+                if (av_tindex(lav)>=1)
+                    second = SvIV(*av_fetch(lav,1,0));
+
+                second /= second >= 600  ? 100 : 10;
+                hintsv = Perl_newSVpvf(aTHX_ "v%d.%d.0",
+                                       (int)first, (int)second);
+                upg_version(hintsv, TRUE);
+
+                DIE(aTHX_ "Perl %"SVf" required (did you mean %"SVf"?)"
+                    "--this is only %"SVf", stopped",
+                    SVfARG(sv_2mortal(vnormal(req))),
+                    SVfARG(sv_2mortal(vnormal(sv_2mortal(hintsv)))),
+                    SVfARG(sv_2mortal(vnormal(PL_patchlevel)))
+                );
+            }
+        }
+    }
+
+    RETPUSHYES;
+}
+
+/* Handle C<require Foo::Bar>, C<require "Foo/Bar.pm"> and C<do "Foo.pm">.
+ * The first form will have already been converted at compile time to
+ * the second form */
+
+static OP *
+S_require_file(pTHX_ SV *const sv)
+{
+    dVAR; dSP;
+
     PERL_CONTEXT *cx;
-    SV *sv;
     const char *name;
     STRLEN len;
     char * unixname;
@@ -3597,7 +3681,7 @@ PP(pp_require)
 #endif
     const char *tryname = NULL;
     SV *namesv = NULL;
-    const I32 gimme = GIMME_V;
+    const U8 gimme = GIMME_V;
     int filter_has_file = 0;
     PerlIO *tryrsfp = NULL;
     SV *filter_cache = NULL;
@@ -3608,79 +3692,28 @@ PP(pp_require)
     int saved_errno;
     bool path_searchable;
     I32 old_savestack_ix;
+    const bool op_is_require = PL_op->op_type == OP_REQUIRE;
+    const char *const op_name = op_is_require ? "require" : "do";
 
-    sv = POPs;
-    SvGETMAGIC(sv);
-    if ( (SvNIOKp(sv) || SvVOK(sv)) && PL_op->op_type != OP_DOFILE) {
-       sv = sv_2mortal(new_version(sv));
-       if (!Perl_sv_derived_from_pvn(aTHX_ PL_patchlevel, STR_WITH_LEN("version"), 0))
-           upg_version(PL_patchlevel, TRUE);
-       if (cUNOP->op_first->op_type == OP_CONST && cUNOP->op_first->op_private & OPpCONST_NOVER) {
-           if ( vcmp(sv,PL_patchlevel) <= 0 )
-               DIE(aTHX_ "Perls since %"SVf" too modern--this is %"SVf", stopped",
-                   SVfARG(sv_2mortal(vnormal(sv))),
-                   SVfARG(sv_2mortal(vnormal(PL_patchlevel)))
-               );
-       }
-       else {
-           if ( vcmp(sv,PL_patchlevel) > 0 ) {
-               I32 first = 0;
-               AV *lav;
-               SV * const req = SvRV(sv);
-               SV * const pv = *hv_fetchs(MUTABLE_HV(req), "original", FALSE);
-
-               /* get the left hand term */
-               lav = MUTABLE_AV(SvRV(*hv_fetchs(MUTABLE_HV(req), "version", FALSE)));
-
-               first  = SvIV(*av_fetch(lav,0,0));
-               if (   first > (int)PERL_REVISION    /* probably 'use 6.0' */
-                   || hv_exists(MUTABLE_HV(req), "qv", 2 ) /* qv style */
-                   || av_tindex(lav) > 1            /* FP with > 3 digits */
-                   || strstr(SvPVX(pv),".0")        /* FP with leading 0 */
-                  ) {
-                   DIE(aTHX_ "Perl %"SVf" required--this is only "
-                       "%"SVf", stopped",
-                       SVfARG(sv_2mortal(vnormal(req))),
-                       SVfARG(sv_2mortal(vnormal(PL_patchlevel)))
-                   );
-               }
-               else { /* probably 'use 5.10' or 'use 5.8' */
-                   SV *hintsv;
-                   I32 second = 0;
-
-                   if (av_tindex(lav)>=1)
-                       second = SvIV(*av_fetch(lav,1,0));
-
-                   second /= second >= 600  ? 100 : 10;
-                   hintsv = Perl_newSVpvf(aTHX_ "v%d.%d.0",
-                                          (int)first, (int)second);
-                   upg_version(hintsv, TRUE);
-
-                   DIE(aTHX_ "Perl %"SVf" required (did you mean %"SVf"?)"
-                       "--this is only %"SVf", stopped",
-                       SVfARG(sv_2mortal(vnormal(req))),
-                       SVfARG(sv_2mortal(vnormal(sv_2mortal(hintsv)))),
-                       SVfARG(sv_2mortal(vnormal(PL_patchlevel)))
-                   );
-               }
-           }
-       }
+    assert(op_is_require || PL_op->op_type == OP_DOFILE);
 
-       RETPUSHYES;
-    }
     if (!SvOK(sv))
-        DIE(aTHX_ "Missing or undefined argument to require");
+        DIE(aTHX_ "Missing or undefined argument to %s", op_name);
     name = SvPV_nomg_const(sv, len);
     if (!(name && len > 0 && *name))
-        DIE(aTHX_ "Missing or undefined argument to require");
+        DIE(aTHX_ "Missing or undefined argument to %s", op_name);
 
-    if (!IS_SAFE_PATHNAME(name, len, "require")) {
+    if (!IS_SAFE_PATHNAME(name, len, op_name)) {
+        if (!op_is_require) {
+            CLEAR_ERRSV();
+            RETPUSHUNDEF;
+        }
         DIE(aTHX_ "Can't locate %s:   %s",
-            pv_escape(newSVpvs_flags("",SVs_TEMP),SvPVX(sv),SvCUR(sv),
-                      SvCUR(sv)*2,NULL, SvUTF8(sv)?PERL_PV_ESCAPE_UNI:0),
+            pv_escape(newSVpvs_flags("",SVs_TEMP),name,len,len*2,
+                      NULL, SvUTF8(sv)?PERL_PV_ESCAPE_UNI:0),
             Strerror(ENOENT));
     }
-    TAINT_PROPER("require");
+    TAINT_PROPER(op_name);
 
     path_searchable = path_is_searchable(name);
 
@@ -3707,7 +3740,7 @@ PP(pp_require)
        unixname = (char *) name;
        unixlen = len;
     }
-    if (PL_op->op_type == OP_REQUIRE) {
+    if (op_is_require) {
        SV * const * const svp = hv_fetch(GvHVn(PL_incgv),
                                          unixname, unixlen, 0);
        if ( svp ) {
@@ -3717,9 +3750,49 @@ PP(pp_require)
                DIE(aTHX_ "Attempt to reload %s aborted.\n"
                            "Compilation failed in require", unixname);
        }
+
+        if (PL_op->op_flags & OPf_KIDS) {
+            SVOP * const kid = (SVOP*)cUNOP->op_first;
+
+            if (kid->op_type == OP_CONST && (kid->op_private & OPpCONST_BARE)) {
+                /* require foo (or use foo) with a bareword.
+                   Perl_load_module fakes up the identical optree, but its
+                   arguments aren't restricted by the parser to real barewords.
+                */
+                const STRLEN package_len = len - 3;
+                const char slashdot[2] = {'/', '.'};
+#ifdef DOSISH
+                const char backslashdot[2] = {'\\', '.'};
+#endif
+
+                /* Disallow *purported* barewords that map to absolute
+                   filenames, filenames relative to the current or parent
+                   directory, or (*nix) hidden filenames.  Also sanity check
+                   that the generated filename ends .pm  */
+                if (!path_searchable || len < 3 || name[0] == '.'
+                    || !memEQ(name + package_len, ".pm", 3))
+                    DIE(aTHX_ "Bareword in require maps to disallowed filename \"%"SVf"\"", sv);
+                if (memchr(name, 0, package_len)) {
+                    /* diag_listed_as: Bareword in require contains "%s" */
+                    DIE(aTHX_ "Bareword in require contains \"\\0\"");
+                }
+                if (ninstr(name, name + package_len, slashdot,
+                           slashdot + sizeof(slashdot))) {
+                    /* diag_listed_as: Bareword in require contains "%s" */
+                    DIE(aTHX_ "Bareword in require contains \"/.\"");
+                }
+#ifdef DOSISH
+                if (ninstr(name, name + package_len, backslashdot,
+                           backslashdot + sizeof(backslashdot))) {
+                    /* diag_listed_as: Bareword in require contains "%s" */
+                    DIE(aTHX_ "Bareword in require contains \"\\.\"");
+                }
+#endif
+            }
+        }
     }
 
-    LOADING_FILE_PROBE(unixname);
+    PERL_DTRACE_PROBE_FILE_LOADING(unixname);
 
     /* prepare to compile file */
 
@@ -3882,7 +3955,7 @@ PP(pp_require)
                        dirlen = 0;
                    }
 
-                   if (!IS_SAFE_SYSCALL(dir, dirlen, "@INC entry", "require"))
+                   if (!IS_SAFE_SYSCALL(dir, dirlen, "@INC entry", op_name))
                        continue;
 #ifdef VMS
                    if ((unixdir =
@@ -3933,7 +4006,7 @@ PP(pp_require)
                    }
 #  endif
 #endif
-                   TAINT_PROPER("require");
+                   TAINT_PROPER(op_name);
                    tryname = SvPVX_const(namesv);
                    tryrsfp = doopen_pm(namesv);
                    if (tryrsfp) {
@@ -3959,7 +4032,7 @@ PP(pp_require)
     saved_errno = errno; /* sv_2mortal can realloc things */
     sv_2mortal(namesv);
     if (!tryrsfp) {
-       if (PL_op->op_type == OP_REQUIRE) {
+       if (op_is_require) {
            if(saved_errno == EMFILE || saved_errno == EACCES) {
                /* diag_listed_as: Can't locate %s */
                DIE(aTHX_ "Can't locate %s:   %s: %s",
@@ -4042,8 +4115,8 @@ PP(pp_require)
     }
 
     /* switch to eval mode */
-    PUSHBLOCK(cx, CXt_EVAL, gimme, SP, old_savestack_ix);
-    PUSHEVAL(cx, PL_op->op_next, name);
+    cx = cx_pushblock(CXt_EVAL, gimme, SP, old_savestack_ix);
+    cx_pusheval(cx, PL_op->op_next, newSVpv(name, 0));
 
     SAVECOPLINE(&PL_compiling);
     CopLINE_set(&PL_compiling, 0);
@@ -4055,11 +4128,26 @@ PP(pp_require)
     else
        op = PL_op->op_next;
 
-    LOADED_FILE_PROBE(unixname);
+    PERL_DTRACE_PROBE_FILE_LOADED(unixname);
 
     return op;
 }
 
+
+/* also used for: pp_dofile() */
+
+PP(pp_require)
+{
+    dSP;
+    SV *sv = POPs;
+    SvGETMAGIC(sv);
+    PUTBACK;
+    return ((SvNIOKp(sv) || SvVOK(sv)) && PL_op->op_type != OP_DOFILE)
+        ? S_require_version(aTHX_ sv)
+        : S_require_file(aTHX_ sv);
+}
+
+
 /* This is a op added to hold the hints hash for
    pp_entereval. The hash can be modified by the code
    being eval'ed, so we return a copy instead. */
@@ -4077,7 +4165,7 @@ PP(pp_entereval)
     dSP;
     PERL_CONTEXT *cx;
     SV *sv;
-    const I32 gimme = GIMME_V;
+    const U8 gimme = GIMME_V;
     const U32 was = PL_breakable_sub_gen;
     char tbuf[TYPE_DIGITS(long) + 12];
     bool saved_delete = FALSE;
@@ -4156,8 +4244,8 @@ PP(pp_entereval)
      * to do the dirty work for us */
     runcv = find_runcv(&seq);
 
-    PUSHBLOCK(cx, (CXt_EVAL|CXp_REAL), gimme, SP, old_savestack_ix);
-    PUSHEVAL(cx, PL_op->op_next, 0);
+    cx = cx_pushblock((CXt_EVAL|CXp_REAL), gimme, SP, old_savestack_ix);
+    cx_pusheval(cx, PL_op->op_next, NULL);
 
     /* prepare to compile string */
 
@@ -4200,16 +4288,18 @@ PP(pp_entereval)
     }
 }
 
+
+/* also tail-called by pp_return */
+
 PP(pp_leaveeval)
 {
     SV **oldsp;
-    I32 gimme;
+    U8 gimme;
     PERL_CONTEXT *cx;
     OP *retop;
-    SV *namesv = NULL;
+    int failed;
     CV *evalcv;
-    /* grab this value before CX_POPEVAL restores old PL_in_eval */
-    bool keep = cBOOL(PL_in_eval & EVAL_KEEPERR);
+    bool keep;
 
     PERL_ASYNC_CHECK();
 
@@ -4220,19 +4310,17 @@ PP(pp_leaveeval)
     gimme = cx->blk_gimme;
 
     /* did require return a false value? */
-    if (       CxOLD_OP_TYPE(cx) == OP_REQUIRE
-            && !(gimme == G_SCALAR
+    failed =    CxOLD_OP_TYPE(cx) == OP_REQUIRE
+             && !(gimme == G_SCALAR
                     ? SvTRUE(*PL_stack_sp)
-                : PL_stack_sp > oldsp)
-    )
-        namesv = cx->blk_eval.old_namesv;
+                    : PL_stack_sp > oldsp);
 
     if (gimme == G_VOID)
         PL_stack_sp = oldsp;
     else
         leave_adjust_stacks(oldsp, oldsp, gimme, 0);
 
-    /* the CX_POPEVAL does a leavescope, which frees the optree associated
+    /* the cx_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
@@ -4240,23 +4328,17 @@ PP(pp_leaveeval)
      */
     PL_curcop = cx->blk_oldcop;
 
-    CX_LEAVE_SCOPE(cx);
-    CX_POPEVAL(cx);
-    CX_POPBLOCK(cx);
+    /* grab this value before cx_popeval restores the old PL_in_eval */
+    keep = cBOOL(PL_in_eval & EVAL_KEEPERR);
     retop = cx->blk_eval.retop;
     evalcv = cx->blk_eval.cv;
-    CX_POP(cx);
-
 #ifdef DEBUGGING
     assert(CvDEPTH(evalcv) == 1);
 #endif
     CvDEPTH(evalcv) = 0;
 
-    if (namesv) { /* require returned false */
-       /* Unassume the success we assumed earlier. */
-        S_undo_inc_then_croak(aTHX_ namesv, NULL, TRUE);
-        NOT_REACHED; /* NOTREACHED */
-    }
+    /* pop the CXt_EVAL, and if a require failed, croak */
+    S_pop_eval_context_maybe_croak(aTHX_ cx, NULL, failed);
 
     if (!keep)
         CLEAR_ERRSV();
@@ -4273,8 +4355,8 @@ Perl_delete_eval_scope(pTHX)
        
     cx = CX_CUR();
     CX_LEAVE_SCOPE(cx);
-    CX_POPEVAL(cx);
-    CX_POPBLOCK(cx);
+    cx_popeval(cx);
+    cx_popblock(cx);
     CX_POP(cx);
 }
 
@@ -4284,10 +4366,11 @@ void
 Perl_create_eval_scope(pTHX_ OP *retop, U32 flags)
 {
     PERL_CONTEXT *cx;
-    const I32 gimme = GIMME_V;
+    const U8 gimme = GIMME_V;
        
-    PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), gimme, PL_stack_sp, PL_savestack_ix);
-    PUSHEVAL(cx, retop, 0);
+    cx = cx_pushblock((CXt_EVAL|CXp_TRYBLOCK), gimme,
+                    PL_stack_sp, PL_savestack_ix);
+    cx_pusheval(cx, retop, NULL);
 
     PL_in_eval = EVAL_INEVAL;
     if (flags & G_KEEPERR)
@@ -4305,10 +4388,13 @@ PP(pp_entertry)
     return DOCATCH(PL_op->op_next);
 }
 
+
+/* also tail-called by pp_return */
+
 PP(pp_leavetry)
 {
     SV **oldsp;
-    I32 gimme;
+    U8 gimme;
     PERL_CONTEXT *cx;
     OP *retop;
 
@@ -4324,8 +4410,8 @@ PP(pp_leavetry)
     else
         leave_adjust_stacks(oldsp, oldsp, gimme, 1);
     CX_LEAVE_SCOPE(cx);
-    CX_POPEVAL(cx);
-    CX_POPBLOCK(cx);
+    cx_popeval(cx);
+    cx_popblock(cx);
     retop = cx->blk_eval.retop;
     CX_POP(cx);
 
@@ -4337,15 +4423,15 @@ PP(pp_entergiven)
 {
     dSP;
     PERL_CONTEXT *cx;
-    const I32 gimme = GIMME_V;
+    const U8 gimme = GIMME_V;
     SV *origsv = DEFSV;
     SV *newsv = POPs;
     
     assert(!PL_op->op_targ); /* used to be set for lexical $_ */
     GvSV(PL_defgv) = SvREFCNT_inc(newsv);
 
-    PUSHBLOCK(cx, CXt_GIVEN, gimme, SP, PL_savestack_ix);
-    PUSHGIVEN(cx, origsv);
+    cx = cx_pushblock(CXt_GIVEN, gimme, SP, PL_savestack_ix);
+    cx_pushgiven(cx, origsv);
 
     RETURN;
 }
@@ -4353,7 +4439,7 @@ PP(pp_entergiven)
 PP(pp_leavegiven)
 {
     PERL_CONTEXT *cx;
-    I32 gimme;
+    U8 gimme;
     SV **oldsp;
     PERL_UNUSED_CONTEXT;
 
@@ -4368,8 +4454,8 @@ PP(pp_leavegiven)
         leave_adjust_stacks(oldsp, oldsp, gimme, 1);
 
     CX_LEAVE_SCOPE(cx);
-    CX_POPGIVEN(cx);
-    CX_POPBLOCK(cx);
+    cx_popgiven(cx);
+    cx_popblock(cx);
     CX_POP(cx);
 
     return NORMAL;
@@ -4913,7 +4999,7 @@ PP(pp_enterwhen)
 {
     dSP;
     PERL_CONTEXT *cx;
-    const I32 gimme = GIMME_V;
+    const U8 gimme = GIMME_V;
 
     /* This is essentially an optimization: if the match
        fails, we don't want to push a context and then
@@ -4921,11 +5007,11 @@ PP(pp_enterwhen)
        to the op that follows the leavewhen.
        RETURNOP calls PUTBACK which restores the stack pointer after the POPs.
     */
-    if ((0 == (PL_op->op_flags & OPf_SPECIAL)) && !SvTRUEx(POPs))
+    if (!(PL_op->op_flags & OPf_SPECIAL) && !SvTRUEx(POPs))
        RETURNOP(cLOGOP->op_other->op_next);
 
-    PUSHBLOCK(cx, CXt_WHEN, gimme, SP, PL_savestack_ix);
-    PUSHWHEN(cx);
+    cx = cx_pushblock(CXt_WHEN, gimme, SP, PL_savestack_ix);
+    cx_pushwhen(cx);
 
     RETURN;
 }
@@ -4934,7 +5020,7 @@ PP(pp_leavewhen)
 {
     I32 cxix;
     PERL_CONTEXT *cx;
-    I32 gimme;
+    U8 gimme;
     SV **oldsp;
 
     cx = CX_CUR();
@@ -4963,7 +5049,7 @@ PP(pp_leavewhen)
         /* emulate pp_next. Note that any stack(s) cleanup will be
          * done by the pp_unstack which op_nextop should point to */
         cx = CX_CUR();
-       CX_TOPBLOCK(cx);
+       cx_topblock(cx);
        PL_curcop = cx->blk_oldcop;
        return cx->blk_loop.my_op->op_nextop;
     }
@@ -4991,8 +5077,8 @@ PP(pp_continue)
     assert(CxTYPE(cx) == CXt_WHEN);
     PL_stack_sp = PL_stack_base + cx->blk_oldsp;
     CX_LEAVE_SCOPE(cx);
-    CX_POPWHEN(cx);
-    CX_POPBLOCK(cx);
+    cx_popwhen(cx);
+    cx_popblock(cx);
     nextop = cx->blk_givwhen.leave_op->op_next;
     CX_POP(cx);