This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Use pvs macros instead of pvn where possible.
[perl5.git] / op.c
diff --git a/op.c b/op.c
index 60537ad..6406b3d 100644 (file)
--- a/op.c
+++ b/op.c
@@ -1,7 +1,7 @@
 /*    op.c
  *
 /*    op.c
  *
- *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- *    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, by Larry Wall and others
+ *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
+ *    2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
@@ -90,7 +90,7 @@ recursive, but it's recursive on basic blocks, not on tree nodes.
    magic type 'H'. This magic (itself) does nothing, but its presence causes
    the values to gain magic type 'h', which has entries for set and clear.
    C<Perl_magic_sethint> updates C<PL_compiling.cop_hints_hash> with a store
    magic type 'H'. This magic (itself) does nothing, but its presence causes
    the values to gain magic type 'h', which has entries for set and clear.
    C<Perl_magic_sethint> updates C<PL_compiling.cop_hints_hash> with a store
-   record, with deletes written by C<Perl_magic_clearhint>. C<SAVE_HINTS>
+   record, with deletes written by C<Perl_magic_clearhint>. C<SAVEHINTS>
    saves the current C<PL_compiling.cop_hints_hash> on the save stack, so that
    it will be correctly restored when any inner compiling scope is exited.
 */
    saves the current C<PL_compiling.cop_hints_hash> on the save stack, so that
    it will be correctly restored when any inner compiling scope is exited.
 */
@@ -116,6 +116,7 @@ recursive, but it's recursive on basic blocks, not on tree nodes.
 void *
 Perl_Slab_Alloc(pTHX_ size_t sz)
 {
 void *
 Perl_Slab_Alloc(pTHX_ size_t sz)
 {
+    dVAR;
     /*
      * To make incrementing use count easy PL_OpSlab is an I32 *
      * To make inserting the link to slab PL_OpPtr is I32 **
     /*
      * To make incrementing use count easy PL_OpSlab is an I32 *
      * To make inserting the link to slab PL_OpPtr is I32 **
@@ -127,7 +128,7 @@ Perl_Slab_Alloc(pTHX_ size_t sz)
 #ifdef PERL_DEBUG_READONLY_OPS
        /* We need to allocate chunk by chunk so that we can control the VM
           mapping */
 #ifdef PERL_DEBUG_READONLY_OPS
        /* We need to allocate chunk by chunk so that we can control the VM
           mapping */
-       PL_OpPtr = mmap(0, PERL_SLAB_SIZE*sizeof(I32*), PROT_READ|PROT_WRITE,
+       PL_OpPtr = (I32**) mmap(0, PERL_SLAB_SIZE*sizeof(I32*), PROT_READ|PROT_WRITE,
                        MAP_ANON|MAP_PRIVATE, -1, 0);
 
        DEBUG_m(PerlIO_printf(Perl_debug_log, "mapped %lu at %p\n",
                        MAP_ANON|MAP_PRIVATE, -1, 0);
 
        DEBUG_m(PerlIO_printf(Perl_debug_log, "mapped %lu at %p\n",
@@ -159,7 +160,7 @@ Perl_Slab_Alloc(pTHX_ size_t sz)
 #ifdef PERL_DEBUG_READONLY_OPS
        /* We remember this slab.  */
        /* This implementation isn't efficient, but it is simple. */
 #ifdef PERL_DEBUG_READONLY_OPS
        /* We remember this slab.  */
        /* This implementation isn't efficient, but it is simple. */
-       PL_slabs = realloc(PL_slabs, sizeof(I32**) * (PL_slab_count + 1));
+       PL_slabs = (I32**) realloc(PL_slabs, sizeof(I32**) * (PL_slab_count + 1));
        PL_slabs[PL_slab_count++] = PL_OpSlab;
        DEBUG_m(PerlIO_printf(Perl_debug_log, "Allocate %p\n", PL_OpSlab));
 #endif
        PL_slabs[PL_slab_count++] = PL_OpSlab;
        DEBUG_m(PerlIO_printf(Perl_debug_log, "Allocate %p\n", PL_OpSlab));
 #endif
@@ -209,6 +210,9 @@ S_Slab_to_rw(pTHX_ void *op)
 {
     I32 * const * const ptr = (I32 **) op;
     I32 * const slab = ptr[-1];
 {
     I32 * const * const ptr = (I32 **) op;
     I32 * const slab = ptr[-1];
+
+    PERL_ARGS_ASSERT_SLAB_TO_RW;
+
     assert( ptr-1 > (I32 **) slab );
     assert( ptr < ( (I32 **) slab + PERL_SLAB_SIZE) );
     assert( *slab > 0 );
     assert( ptr-1 > (I32 **) slab );
     assert( ptr < ( (I32 **) slab + PERL_SLAB_SIZE) );
     assert( *slab > 0 );
@@ -232,6 +236,7 @@ Perl_op_refcnt_inc(pTHX_ OP *o)
 PADOFFSET
 Perl_op_refcnt_dec(pTHX_ OP *o)
 {
 PADOFFSET
 Perl_op_refcnt_dec(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_OP_REFCNT_DEC;
     Slab_to_rw(o);
     return --o->op_targ;
 }
     Slab_to_rw(o);
     return --o->op_targ;
 }
@@ -244,6 +249,7 @@ Perl_Slab_Free(pTHX_ void *op)
 {
     I32 * const * const ptr = (I32 **) op;
     I32 * const slab = ptr[-1];
 {
     I32 * const * const ptr = (I32 **) op;
     I32 * const slab = ptr[-1];
+    PERL_ARGS_ASSERT_SLAB_FREE;
     assert( ptr-1 > (I32 **) slab );
     assert( ptr < ( (I32 **) slab + PERL_SLAB_SIZE) );
     assert( *slab > 0 );
     assert( ptr-1 > (I32 **) slab );
     assert( ptr < ( (I32 **) slab + PERL_SLAB_SIZE) );
     assert( *slab > 0 );
@@ -259,6 +265,7 @@ Perl_Slab_Free(pTHX_ void *op)
        if (count) {
            while (count--) {
                if (PL_slabs[count] == slab) {
        if (count) {
            while (count--) {
                if (PL_slabs[count] == slab) {
+                   dVAR;
                    /* Found it. Move the entry at the end to overwrite it.  */
                    DEBUG_m(PerlIO_printf(Perl_debug_log,
                                          "Deallocate %p by moving %p from %lu to %lu\n",
                    /* Found it. Move the entry at the end to overwrite it.  */
                    DEBUG_m(PerlIO_printf(Perl_debug_log,
                                          "Deallocate %p by moving %p from %lu to %lu\n",
@@ -302,6 +309,9 @@ STATIC const char*
 S_gv_ename(pTHX_ GV *gv)
 {
     SV* const tmpsv = sv_newmortal();
 S_gv_ename(pTHX_ GV *gv)
 {
     SV* const tmpsv = sv_newmortal();
+
+    PERL_ARGS_ASSERT_GV_ENAME;
+
     gv_efullname3(tmpsv, gv, NULL);
     return SvPV_nolen_const(tmpsv);
 }
     gv_efullname3(tmpsv, gv, NULL);
     return SvPV_nolen_const(tmpsv);
 }
@@ -309,6 +319,8 @@ S_gv_ename(pTHX_ GV *gv)
 STATIC OP *
 S_no_fh_allowed(pTHX_ OP *o)
 {
 STATIC OP *
 S_no_fh_allowed(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_NO_FH_ALLOWED;
+
     yyerror(Perl_form(aTHX_ "Missing comma after first argument to %s function",
                 OP_DESC(o)));
     return o;
     yyerror(Perl_form(aTHX_ "Missing comma after first argument to %s function",
                 OP_DESC(o)));
     return o;
@@ -317,6 +329,8 @@ S_no_fh_allowed(pTHX_ OP *o)
 STATIC OP *
 S_too_few_arguments(pTHX_ OP *o, const char *name)
 {
 STATIC OP *
 S_too_few_arguments(pTHX_ OP *o, const char *name)
 {
+    PERL_ARGS_ASSERT_TOO_FEW_ARGUMENTS;
+
     yyerror(Perl_form(aTHX_ "Not enough arguments for %s", name));
     return o;
 }
     yyerror(Perl_form(aTHX_ "Not enough arguments for %s", name));
     return o;
 }
@@ -324,6 +338,8 @@ S_too_few_arguments(pTHX_ OP *o, const char *name)
 STATIC OP *
 S_too_many_arguments(pTHX_ OP *o, const char *name)
 {
 STATIC OP *
 S_too_many_arguments(pTHX_ OP *o, const char *name)
 {
+    PERL_ARGS_ASSERT_TOO_MANY_ARGUMENTS;
+
     yyerror(Perl_form(aTHX_ "Too many arguments for %s", name));
     return o;
 }
     yyerror(Perl_form(aTHX_ "Too many arguments for %s", name));
     return o;
 }
@@ -331,6 +347,8 @@ S_too_many_arguments(pTHX_ OP *o, const char *name)
 STATIC void
 S_bad_type(pTHX_ I32 n, const char *t, const char *name, const OP *kid)
 {
 STATIC void
 S_bad_type(pTHX_ I32 n, const char *t, const char *name, const OP *kid)
 {
+    PERL_ARGS_ASSERT_BAD_TYPE;
+
     yyerror(Perl_form(aTHX_ "Type of arg %d to %s must be %s (not %s)",
                 (int)n, name, t, OP_DESC(kid)));
 }
     yyerror(Perl_form(aTHX_ "Type of arg %d to %s must be %s (not %s)",
                 (int)n, name, t, OP_DESC(kid)));
 }
@@ -338,6 +356,8 @@ S_bad_type(pTHX_ I32 n, const char *t, const char *name, const OP *kid)
 STATIC void
 S_no_bareword_allowed(pTHX_ const OP *o)
 {
 STATIC void
 S_no_bareword_allowed(pTHX_ const OP *o)
 {
+    PERL_ARGS_ASSERT_NO_BAREWORD_ALLOWED;
+
     if (PL_madskills)
        return;         /* various ok barewords are hidden in extra OP_NULL */
     qerror(Perl_mess(aTHX_
     if (PL_madskills)
        return;         /* various ok barewords are hidden in extra OP_NULL */
     qerror(Perl_mess(aTHX_
@@ -354,6 +374,8 @@ Perl_allocmy(pTHX_ const char *const name)
     PADOFFSET off;
     const bool is_our = (PL_parser->in_my == KEY_our);
 
     PADOFFSET off;
     const bool is_our = (PL_parser->in_my == KEY_our);
 
+    PERL_ARGS_ASSERT_ALLOCMY;
+
     /* complain about "my $<special_var>" etc etc */
     if (*name &&
        !(is_our ||
     /* complain about "my $<special_var>" etc etc */
     if (*name &&
        !(is_our ||
@@ -363,10 +385,12 @@ Perl_allocmy(pTHX_ const char *const name)
     {
        /* name[2] is true if strlen(name) > 2  */
        if (!isPRINT(name[1]) || strchr("\t\n\r\f", name[1])) {
     {
        /* name[2] is true if strlen(name) > 2  */
        if (!isPRINT(name[1]) || strchr("\t\n\r\f", name[1])) {
-           yyerror(Perl_form(aTHX_ "Can't use global %c^%c%s in \"my\"",
-                             name[0], toCTRL(name[1]), name + 2));
+           yyerror(Perl_form(aTHX_ "Can't use global %c^%c%s in \"%s\"",
+                             name[0], toCTRL(name[1]), name + 2,
+                             PL_parser->in_my == KEY_state ? "state" : "my"));
        } else {
        } else {
-           yyerror(Perl_form(aTHX_ "Can't use global %s in \"my\"",name));
+           yyerror(Perl_form(aTHX_ "Can't use global %s in \"%s\"",name,
+                             PL_parser->in_my == KEY_state ? "state" : "my"));
        }
     }
 
        }
     }
 
@@ -393,6 +417,12 @@ Perl_allocmy(pTHX_ const char *const name)
                    0, /*  not fake */
                    PL_parser->in_my == KEY_state
     );
                    0, /*  not fake */
                    PL_parser->in_my == KEY_state
     );
+    /* anon sub prototypes contains state vars should always be cloned,
+     * otherwise the state var would be shared between anon subs */
+
+    if (PL_parser->in_my == KEY_state && CvANON(PL_compcv))
+       CvCLONE_on(PL_compcv);
+
     return off;
 }
 
     return off;
 }
 
@@ -423,7 +453,7 @@ Perl_op_free(pTHX_ OP *o)
     dVAR;
     OPCODE type;
 
     dVAR;
     OPCODE type;
 
-    if (!o || o->op_static)
+    if (!o)
        return;
     if (o->op_latefreed) {
        if (o->op_latefree)
        return;
     if (o->op_latefreed) {
        if (o->op_latefree)
@@ -465,8 +495,6 @@ Perl_op_free(pTHX_ OP *o)
            op_free(kid);
        }
     }
            op_free(kid);
        }
     }
-    if (type == OP_NULL)
-       type = (OPCODE)o->op_targ;
 
 #ifdef PERL_DEBUG_READONLY_OPS
     Slab_to_rw(o);
 
 #ifdef PERL_DEBUG_READONLY_OPS
     Slab_to_rw(o);
@@ -474,10 +502,16 @@ Perl_op_free(pTHX_ OP *o)
 
     /* COP* is not cleared by op_clear() so that we may track line
      * numbers etc even after null() */
 
     /* COP* is not cleared by op_clear() so that we may track line
      * numbers etc even after null() */
-    if (type == OP_NEXTSTATE || type == OP_SETSTATE || type == OP_DBSTATE) {
+    if (type == OP_NEXTSTATE || type == OP_DBSTATE
+           || (type == OP_NULL /* the COP might have been null'ed */
+               && ((OPCODE)o->op_targ == OP_NEXTSTATE
+                   || (OPCODE)o->op_targ == OP_DBSTATE))) {
        cop_free((COP*)o);
     }
 
        cop_free((COP*)o);
     }
 
+    if (type == OP_NULL)
+       type = (OPCODE)o->op_targ;
+
     op_clear(o);
     if (o->op_latefree) {
        o->op_latefreed = 1;
     op_clear(o);
     if (o->op_latefree) {
        o->op_latefreed = 1;
@@ -496,6 +530,9 @@ Perl_op_clear(pTHX_ OP *o)
 {
 
     dVAR;
 {
 
     dVAR;
+
+    PERL_ARGS_ASSERT_OP_CLEAR;
+
 #ifdef PERL_MAD
     /* if (o->op_madprop && o->op_madprop->mad_next)
        abort(); */
 #ifdef PERL_MAD
     /* if (o->op_madprop && o->op_madprop->mad_next)
        abort(); */
@@ -515,7 +552,7 @@ Perl_op_clear(pTHX_ OP *o)
     switch (o->op_type) {
     case OP_NULL:      /* Was holding old type, if any. */
        if (PL_madskills && o->op_targ != OP_NULL) {
     switch (o->op_type) {
     case OP_NULL:      /* Was holding old type, if any. */
        if (PL_madskills && o->op_targ != OP_NULL) {
-           o->op_type = o->op_targ;
+           o->op_type = (Optype)o->op_targ;
            o->op_targ = 0;
            goto retry;
        }
            o->op_targ = 0;
            goto retry;
        }
@@ -547,6 +584,7 @@ Perl_op_clear(pTHX_ OP *o)
        break;
     case OP_METHOD_NAMED:
     case OP_CONST:
        break;
     case OP_METHOD_NAMED:
     case OP_CONST:
+    case OP_HINTSEVAL:
        SvREFCNT_dec(cSVOPo->op_sv);
        cSVOPo->op_sv = NULL;
 #ifdef USE_ITHREADS
        SvREFCNT_dec(cSVOPo->op_sv);
        cSVOPo->op_sv = NULL;
 #ifdef USE_ITHREADS
@@ -605,21 +643,23 @@ Perl_op_clear(pTHX_ OP *o)
 clear_pmop:
        forget_pmop(cPMOPo, 1);
        cPMOPo->op_pmreplrootu.op_pmreplroot = NULL;
 clear_pmop:
        forget_pmop(cPMOPo, 1);
        cPMOPo->op_pmreplrootu.op_pmreplroot = NULL;
-        /* we use the "SAFE" version of the PM_ macros here
-         * since sv_clean_all might release some PMOPs
+        /* we use the same protection as the "SAFE" version of the PM_ macros
+         * here since sv_clean_all might release some PMOPs
          * after PL_regex_padav has been cleared
          * and the clearing of PL_regex_padav needs to
          * happen before sv_clean_all
          */
          * after PL_regex_padav has been cleared
          * and the clearing of PL_regex_padav needs to
          * happen before sv_clean_all
          */
-       ReREFCNT_dec(PM_GETRE_SAFE(cPMOPo));
-       PM_SETRE_SAFE(cPMOPo, NULL);
 #ifdef USE_ITHREADS
        if(PL_regex_pad) {        /* We could be in destruction */
 #ifdef USE_ITHREADS
        if(PL_regex_pad) {        /* We could be in destruction */
-            av_push((AV*) PL_regex_pad[0],(SV*) PL_regex_pad[(cPMOPo)->op_pmoffset]);
-            SvREADONLY_off(PL_regex_pad[(cPMOPo)->op_pmoffset]);
-           SvREPADTMP_on(PL_regex_pad[(cPMOPo)->op_pmoffset]);
-            PM_SETRE(cPMOPo, (cPMOPo)->op_pmoffset);
+           const IV offset = (cPMOPo)->op_pmoffset;
+           ReREFCNT_dec(PM_GETRE(cPMOPo));
+           PL_regex_pad[offset] = &PL_sv_undef;
+            sv_catpvn_nomg(PL_regex_pad[0], (const char *)&offset,
+                          sizeof(offset));
         }
         }
+#else
+       ReREFCNT_dec(PM_GETRE(cPMOPo));
+       PM_SETRE(cPMOPo, NULL);
 #endif
 
        break;
 #endif
 
        break;
@@ -634,7 +674,8 @@ clear_pmop:
 STATIC void
 S_cop_free(pTHX_ COP* cop)
 {
 STATIC void
 S_cop_free(pTHX_ COP* cop)
 {
-    CopLABEL_free(cop);
+    PERL_ARGS_ASSERT_COP_FREE;
+
     CopFILE_free(cop);
     CopSTASH_free(cop);
     if (! specialWARN(cop->cop_warnings))
     CopFILE_free(cop);
     CopSTASH_free(cop);
     if (! specialWARN(cop->cop_warnings))
@@ -650,6 +691,9 @@ S_forget_pmop(pTHX_ PMOP *const o
              )
 {
     HV * const pmstash = PmopSTASH(o);
              )
 {
     HV * const pmstash = PmopSTASH(o);
+
+    PERL_ARGS_ASSERT_FORGET_PMOP;
+
     if (pmstash && !SvIS_FREED(pmstash)) {
        MAGIC * const mg = mg_find((SV*)pmstash, PERL_MAGIC_symtab);
        if (mg) {
     if (pmstash && !SvIS_FREED(pmstash)) {
        MAGIC * const mg = mg_find((SV*)pmstash, PERL_MAGIC_symtab);
        if (mg) {
@@ -685,6 +729,8 @@ S_forget_pmop(pTHX_ PMOP *const o
 STATIC void
 S_find_and_forget_pmops(pTHX_ OP *o)
 {
 STATIC void
 S_find_and_forget_pmops(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_FIND_AND_FORGET_PMOPS;
+
     if (o->op_flags & OPf_KIDS) {
         OP *kid = cUNOPo->op_first;
        while (kid) {
     if (o->op_flags & OPf_KIDS) {
         OP *kid = cUNOPo->op_first;
        while (kid) {
@@ -705,6 +751,9 @@ void
 Perl_op_null(pTHX_ OP *o)
 {
     dVAR;
 Perl_op_null(pTHX_ OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_OP_NULL;
+
     if (o->op_type == OP_NULL)
        return;
     if (!PL_madskills)
     if (o->op_type == OP_NULL)
        return;
     if (!PL_madskills)
@@ -739,6 +788,8 @@ Perl_linklist(pTHX_ OP *o)
 {
     OP *first;
 
 {
     OP *first;
 
+    PERL_ARGS_ASSERT_LINKLIST;
+
     if (o->op_next)
        return o->op_next;
 
     if (o->op_next)
        return o->op_next;
 
@@ -779,6 +830,9 @@ STATIC OP *
 S_scalarboolean(pTHX_ OP *o)
 {
     dVAR;
 S_scalarboolean(pTHX_ OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_SCALARBOOLEAN;
+
     if (o->op_type == OP_SASSIGN && cBINOPo->op_first->op_type == OP_CONST) {
        if (ckWARN(WARN_SYNTAX)) {
            const line_t oldline = CopLINE(PL_curcop);
     if (o->op_type == OP_SASSIGN && cBINOPo->op_first->op_type == OP_CONST) {
        if (ckWARN(WARN_SYNTAX)) {
            const line_t oldline = CopLINE(PL_curcop);
@@ -799,7 +853,8 @@ Perl_scalar(pTHX_ OP *o)
     OP *kid;
 
     /* assumes no premature commitment */
     OP *kid;
 
     /* assumes no premature commitment */
-    if (!o || PL_error_count || (o->op_flags & OPf_WANT)
+    if (!o || (PL_parser && PL_parser->error_count)
+        || (o->op_flags & OPf_WANT)
         || o->op_type == OP_RETURN)
     {
        return o;
         || o->op_type == OP_RETURN)
     {
        return o;
@@ -859,6 +914,7 @@ Perl_scalar(pTHX_ OP *o)
     case OP_SORT:
        if (ckWARN(WARN_VOID))
            Perl_warner(aTHX_ packWARN(WARN_VOID), "Useless use of sort in scalar context");
     case OP_SORT:
        if (ckWARN(WARN_VOID))
            Perl_warner(aTHX_ packWARN(WARN_VOID), "Useless use of sort in scalar context");
+       break;
     }
     return o;
 }
     }
     return o;
 }
@@ -872,6 +928,8 @@ Perl_scalarvoid(pTHX_ OP *o)
     SV* sv;
     U8 want;
 
     SV* sv;
     U8 want;
 
+    PERL_ARGS_ASSERT_SCALARVOID;
+
     /* trailing mad null ops don't count as "there" for void processing */
     if (PL_madskills &&
        o->op_type != OP_NULL &&
     /* trailing mad null ops don't count as "there" for void processing */
     if (PL_madskills &&
        o->op_type != OP_NULL &&
@@ -888,16 +946,15 @@ Perl_scalarvoid(pTHX_ OP *o)
     }
 
     if (o->op_type == OP_NEXTSTATE
     }
 
     if (o->op_type == OP_NEXTSTATE
-       || o->op_type == OP_SETSTATE
        || o->op_type == OP_DBSTATE
        || (o->op_type == OP_NULL && (o->op_targ == OP_NEXTSTATE
        || o->op_type == OP_DBSTATE
        || (o->op_type == OP_NULL && (o->op_targ == OP_NEXTSTATE
-                                     || o->op_targ == OP_SETSTATE
                                      || o->op_targ == OP_DBSTATE)))
        PL_curcop = (COP*)o;            /* for warning below */
 
     /* assumes no premature commitment */
     want = o->op_flags & OPf_WANT;
                                      || o->op_targ == OP_DBSTATE)))
        PL_curcop = (COP*)o;            /* for warning below */
 
     /* assumes no premature commitment */
     want = o->op_flags & OPf_WANT;
-    if ((want && want != OPf_WANT_SCALAR) || PL_error_count
+    if ((want && want != OPf_WANT_SCALAR)
+        || (PL_parser && PL_parser->error_count)
         || o->op_type == OP_RETURN)
     {
        return o;
         || o->op_type == OP_RETURN)
     {
        return o;
@@ -927,6 +984,7 @@ Perl_scalarvoid(pTHX_ OP *o)
     case OP_GVSV:
     case OP_WANTARRAY:
     case OP_GV:
     case OP_GVSV:
     case OP_WANTARRAY:
     case OP_GV:
+    case OP_SMARTMATCH:
     case OP_PADSV:
     case OP_PADAV:
     case OP_PADHV:
     case OP_PADSV:
     case OP_PADAV:
     case OP_PADHV:
@@ -994,6 +1052,7 @@ Perl_scalarvoid(pTHX_ OP *o)
     case OP_PROTOTYPE:
       func_ops:
        if (!(o->op_private & (OPpLVAL_INTRO|OPpOUR_INTRO)))
     case OP_PROTOTYPE:
       func_ops:
        if (!(o->op_private & (OPpLVAL_INTRO|OPpOUR_INTRO)))
+           /* Otherwise it's "Useless use of grep iterator" */
            useless = OP_DESC(o);
        break;
 
            useless = OP_DESC(o);
        break;
 
@@ -1021,7 +1080,13 @@ Perl_scalarvoid(pTHX_ OP *o)
            no_bareword_allowed(o);
        else {
            if (ckWARN(WARN_VOID)) {
            no_bareword_allowed(o);
        else {
            if (ckWARN(WARN_VOID)) {
-               useless = "a constant";
+               if (SvOK(sv)) {
+                   SV* msv = sv_2mortal(Perl_newSVpvf(aTHX_
+                               "a constant (%"SVf")", sv));
+                   useless = SvPV_nolen(msv);
+               }
+               else
+                   useless = "a constant (undef)";
                if (o->op_private & OPpCONST_ARYBASE)
                    useless = NULL;
                /* don't warn on optimised away booleans, eg 
                if (o->op_private & OPpCONST_ARYBASE)
                    useless = NULL;
                /* don't warn on optimised away booleans, eg 
@@ -1073,6 +1138,20 @@ Perl_scalarvoid(pTHX_ OP *o)
 
     case OP_OR:
     case OP_AND:
 
     case OP_OR:
     case OP_AND:
+       kid = cLOGOPo->op_first;
+       if (kid->op_type == OP_NOT
+           && (kid->op_flags & OPf_KIDS)
+           && !PL_madskills) {
+           if (o->op_type == OP_AND) {
+               o->op_type = OP_OR;
+               o->op_ppaddr = PL_ppaddr[OP_OR];
+           } else {
+               o->op_type = OP_AND;
+               o->op_ppaddr = PL_ppaddr[OP_AND];
+           }
+           op_null(kid);
+       }
+
     case OP_DOR:
     case OP_COND_EXPR:
     case OP_ENTERGIVEN:
     case OP_DOR:
     case OP_COND_EXPR:
     case OP_ENTERGIVEN:
@@ -1142,7 +1221,8 @@ Perl_list(pTHX_ OP *o)
     OP *kid;
 
     /* assumes no premature commitment */
     OP *kid;
 
     /* assumes no premature commitment */
-    if (!o || (o->op_flags & OPf_WANT) || PL_error_count
+    if (!o || (o->op_flags & OPf_WANT)
+        || (PL_parser && PL_parser->error_count)
         || o->op_type == OP_RETURN)
     {
        return o;
         || o->op_type == OP_RETURN)
     {
        return o;
@@ -1268,7 +1348,7 @@ Perl_mod(pTHX_ OP *o, I32 type)
     /* -1 = error on localize, 0 = ignore localize, 1 = ok to localize */
     int localize = -1;
 
     /* -1 = error on localize, 0 = ignore localize, 1 = ok to localize */
     int localize = -1;
 
-    if (!o || PL_error_count)
+    if (!o || (PL_parser && PL_parser->error_count))
        return o;
 
     if ((o->op_private & OPpTARGET_MY)
        return o;
 
     if ((o->op_private & OPpTARGET_MY)
@@ -1612,6 +1692,8 @@ Perl_mod(pTHX_ OP *o, I32 type)
 STATIC bool
 S_scalar_mod_type(const OP *o, I32 type)
 {
 STATIC bool
 S_scalar_mod_type(const OP *o, I32 type)
 {
+    PERL_ARGS_ASSERT_SCALAR_MOD_TYPE;
+
     switch (type) {
     case OP_SASSIGN:
        if (o->op_type == OP_RV2GV)
     switch (type) {
     case OP_SASSIGN:
        if (o->op_type == OP_RV2GV)
@@ -1660,6 +1742,8 @@ S_scalar_mod_type(const OP *o, I32 type)
 STATIC bool
 S_is_handle_constructor(const OP *o, I32 numargs)
 {
 STATIC bool
 S_is_handle_constructor(const OP *o, I32 numargs)
 {
+    PERL_ARGS_ASSERT_IS_HANDLE_CONSTRUCTOR;
+
     switch (o->op_type) {
     case OP_PIPE_OP:
     case OP_SOCKPAIR:
     switch (o->op_type) {
     case OP_PIPE_OP:
     case OP_SOCKPAIR:
@@ -1697,7 +1781,9 @@ Perl_doref(pTHX_ OP *o, I32 type, bool set_op_ref)
     dVAR;
     OP *kid;
 
     dVAR;
     OP *kid;
 
-    if (!o || PL_error_count)
+    PERL_ARGS_ASSERT_DOREF;
+
+    if (!o || (PL_parser && PL_parser->error_count))
        return o;
 
     switch (o->op_type) {
        return o;
 
     switch (o->op_type) {
@@ -1788,6 +1874,8 @@ S_dup_attrlist(pTHX_ OP *o)
     dVAR;
     OP *rop;
 
     dVAR;
     OP *rop;
 
+    PERL_ARGS_ASSERT_DUP_ATTRLIST;
+
     /* An attrlist is either a simple OP_CONST or an OP_LIST with kids,
      * where the first kid is OP_PUSHMARK and the remaining ones
      * are OP_CONST.  We need to push the OP_CONST values.
     /* An attrlist is either a simple OP_CONST or an OP_LIST with kids,
      * where the first kid is OP_PUSHMARK and the remaining ones
      * are OP_CONST.  We need to push the OP_CONST values.
@@ -1817,6 +1905,8 @@ S_apply_attrs(pTHX_ HV *stash, SV *target, OP *attrs, bool for_my)
     dVAR;
     SV *stashsv;
 
     dVAR;
     SV *stashsv;
 
+    PERL_ARGS_ASSERT_APPLY_ATTRS;
+
     /* fake up C<use attributes $pkg,$rv,@attrs> */
     ENTER;             /* need to protect against side-effects of 'use' */
     stashsv = stash ? newSVhek(HvNAME_HEK(stash)) : &PL_sv_no;
     /* fake up C<use attributes $pkg,$rv,@attrs> */
     ENTER;             /* need to protect against side-effects of 'use' */
     stashsv = stash ? newSVhek(HvNAME_HEK(stash)) : &PL_sv_no;
@@ -1854,6 +1944,8 @@ S_apply_attrs_my(pTHX_ HV *stash, OP *target, OP *attrs, OP **imopsp)
     OP *pack, *imop, *arg;
     SV *meth, *stashsv;
 
     OP *pack, *imop, *arg;
     SV *meth, *stashsv;
 
+    PERL_ARGS_ASSERT_APPLY_ATTRS_MY;
+
     if (!attrs)
        return;
 
     if (!attrs)
        return;
 
@@ -1914,6 +2006,8 @@ Perl_apply_attrs_string(pTHX_ const char *stashpv, CV *cv,
 {
     OP *attrs = NULL;
 
 {
     OP *attrs = NULL;
 
+    PERL_ARGS_ASSERT_APPLY_ATTRS_STRING;
+
     if (!len) {
         len = strlen(attrstr);
     }
     if (!len) {
         len = strlen(attrstr);
     }
@@ -1945,7 +2039,9 @@ S_my_kid(pTHX_ OP *o, OP *attrs, OP **imopsp)
     dVAR;
     I32 type;
 
     dVAR;
     I32 type;
 
-    if (!o || PL_error_count)
+    PERL_ARGS_ASSERT_MY_KID;
+
+    if (!o || (PL_parser && PL_parser->error_count))
        return o;
 
     type = o->op_type;
        return o;
 
     type = o->op_type;
@@ -2024,6 +2120,8 @@ Perl_my_attrs(pTHX_ OP *o, OP *attrs)
     OP *rops;
     int maybe_scalar = 0;
 
     OP *rops;
     int maybe_scalar = 0;
 
+    PERL_ARGS_ASSERT_MY_ATTRS;
+
 /* [perl #17376]: this appears to be premature, and results in code such as
    C< our(%x); > executing in list mode rather than void mode */
 #if 0
 /* [perl #17376]: this appears to be premature, and results in code such as
    C< our(%x); > executing in list mode rather than void mode */
 #if 0
@@ -2054,6 +2152,8 @@ Perl_my_attrs(pTHX_ OP *o, OP *attrs)
 OP *
 Perl_my(pTHX_ OP *o)
 {
 OP *
 Perl_my(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_MY;
+
     return my_attrs(o, NULL);
 }
 
     return my_attrs(o, NULL);
 }
 
@@ -2074,6 +2174,8 @@ Perl_bind_match(pTHX_ I32 type, OP *left, OP *right)
     const OPCODE ltype = left->op_type;
     const OPCODE rtype = right->op_type;
 
     const OPCODE ltype = left->op_type;
     const OPCODE rtype = right->op_type;
 
+    PERL_ARGS_ASSERT_BIND_MATCH;
+
     if ( (ltype == OP_RV2AV || ltype == OP_RV2HV || ltype == OP_PADAV
          || ltype == OP_PADHV) && ckWARN(WARN_MISC))
     {
     if ( (ltype == OP_RV2AV || ltype == OP_RV2HV || ltype == OP_PADAV
          || ltype == OP_PADHV) && ckWARN(WARN_MISC))
     {
@@ -2209,6 +2311,9 @@ void
 Perl_newPROG(pTHX_ OP *o)
 {
     dVAR;
 Perl_newPROG(pTHX_ OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_NEWPROG;
+
     if (PL_in_eval) {
        if (PL_eval_root)
                return;
     if (PL_in_eval) {
        if (PL_eval_root)
                return;
@@ -2256,6 +2361,9 @@ OP *
 Perl_localize(pTHX_ OP *o, I32 lex)
 {
     dVAR;
 Perl_localize(pTHX_ OP *o, I32 lex)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_LOCALIZE;
+
     if (o->op_flags & OPf_PARENS)
 /* [perl #17376]: this appears to be premature, and results in code such as
    C< our(%x); > executing in list mode rather than void mode */
     if (o->op_flags & OPf_PARENS)
 /* [perl #17376]: this appears to be premature, and results in code such as
    C< our(%x); > executing in list mode rather than void mode */
@@ -2314,6 +2422,8 @@ Perl_localize(pTHX_ OP *o, I32 lex)
 OP *
 Perl_jmaybe(pTHX_ OP *o)
 {
 OP *
 Perl_jmaybe(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_JMAYBE;
+
     if (o->op_type == OP_LIST) {
        OP * const o2
            = newSVREF(newGVOP(OP_GV, 0, gv_fetchpvs(";", GV_ADD|GV_NOTQUAL, SVt_PV)));
     if (o->op_type == OP_LIST) {
        OP * const o2
            = newSVREF(newGVOP(OP_GV, 0, gv_fetchpvs(";", GV_ADD|GV_NOTQUAL, SVt_PV)));
@@ -2326,7 +2436,7 @@ OP *
 Perl_fold_constants(pTHX_ register OP *o)
 {
     dVAR;
 Perl_fold_constants(pTHX_ register OP *o)
 {
     dVAR;
-    register OP *curop;
+    register OP * VOL curop;
     OP *newop;
     VOL I32 type = o->op_type;
     SV * VOL sv = NULL;
     OP *newop;
     VOL I32 type = o->op_type;
     SV * VOL sv = NULL;
@@ -2335,8 +2445,11 @@ Perl_fold_constants(pTHX_ register OP *o)
     OP *old_next;
     SV * const oldwarnhook = PL_warnhook;
     SV * const olddiehook  = PL_diehook;
     OP *old_next;
     SV * const oldwarnhook = PL_warnhook;
     SV * const olddiehook  = PL_diehook;
+    COP not_compiling;
     dJMPENV;
 
     dJMPENV;
 
+    PERL_ARGS_ASSERT_FOLD_CONSTANTS;
+
     if (PL_opargs[type] & OA_RETSCALAR)
        scalar(o);
     if (PL_opargs[type] & OA_TARGET && !o->op_targ)
     if (PL_opargs[type] & OA_RETSCALAR)
        scalar(o);
     if (PL_opargs[type] & OA_TARGET && !o->op_targ)
@@ -2371,9 +2484,10 @@ Perl_fold_constants(pTHX_ register OP *o)
        /* XXX what about the numeric ops? */
        if (PL_hints & HINT_LOCALE)
            goto nope;
        /* XXX what about the numeric ops? */
        if (PL_hints & HINT_LOCALE)
            goto nope;
+       break;
     }
 
     }
 
-    if (PL_error_count)
+    if (PL_parser && PL_parser->error_count)
        goto nope;              /* Don't try to run w/ errors */
 
     for (curop = LINKLIST(o); curop != o; curop = LINKLIST(curop)) {
        goto nope;              /* Don't try to run w/ errors */
 
     for (curop = LINKLIST(o); curop != o; curop = LINKLIST(curop)) {
@@ -2396,6 +2510,13 @@ Perl_fold_constants(pTHX_ register OP *o)
     oldscope = PL_scopestack_ix;
     create_eval_scope(G_FAKINGEVAL);
 
     oldscope = PL_scopestack_ix;
     create_eval_scope(G_FAKINGEVAL);
 
+    /* Verify that we don't need to save it:  */
+    assert(PL_curcop == &PL_compiling);
+    StructCopy(&PL_compiling, &not_compiling, COP);
+    PL_curcop = &not_compiling;
+    /* The above ensures that we run with all the correct hints of the
+       currently compiling COP, but that IN_PERL_RUNTIME is not true. */
+    assert(IN_PERL_RUNTIME);
     PL_warnhook = PERL_WARNHOOK_FATAL;
     PL_diehook  = NULL;
     JMPENV_PUSH(ret);
     PL_warnhook = PERL_WARNHOOK_FATAL;
     PL_diehook  = NULL;
     JMPENV_PUSH(ret);
@@ -2414,7 +2535,7 @@ Perl_fold_constants(pTHX_ register OP *o)
     case 3:
        /* Something tried to die.  Abandon constant folding.  */
        /* Pretend the error never happened.  */
     case 3:
        /* Something tried to die.  Abandon constant folding.  */
        /* Pretend the error never happened.  */
-       sv_setpvn(ERRSV,"",0);
+       CLEAR_ERRSV();
        o->op_next = old_next;
        break;
     default:
        o->op_next = old_next;
        break;
     default:
@@ -2429,6 +2550,7 @@ Perl_fold_constants(pTHX_ register OP *o)
     JMPENV_POP;
     PL_warnhook = oldwarnhook;
     PL_diehook  = olddiehook;
     JMPENV_POP;
     PL_warnhook = oldwarnhook;
     PL_diehook  = olddiehook;
+    PL_curcop = &PL_compiling;
 
     if (PL_scopestack_ix > oldscope)
        delete_eval_scope();
 
     if (PL_scopestack_ix > oldscope)
        delete_eval_scope();
@@ -2459,7 +2581,7 @@ Perl_gen_constant_list(pTHX_ register OP *o)
     const I32 oldtmps_floor = PL_tmps_floor;
 
     list(o);
     const I32 oldtmps_floor = PL_tmps_floor;
 
     list(o);
-    if (PL_error_count)
+    if (PL_parser && PL_parser->error_count)
        return o;               /* Don't attempt to run with errors */
 
     PL_op = curop = LINKLIST(o);
        return o;               /* Don't attempt to run with errors */
 
     PL_op = curop = LINKLIST(o);
@@ -2629,6 +2751,8 @@ Perl_newTOKEN(pTHX_ I32 optype, YYSTYPE lval, MADPROP* madprop)
 void
 Perl_token_free(pTHX_ TOKEN* tk)
 {
 void
 Perl_token_free(pTHX_ TOKEN* tk)
 {
+    PERL_ARGS_ASSERT_TOKEN_FREE;
+
     if (tk->tk_type != 12345)
        return;
     mad_free(tk->tk_mad);
     if (tk->tk_type != 12345)
        return;
     mad_free(tk->tk_mad);
@@ -2640,6 +2764,9 @@ Perl_token_getmad(pTHX_ TOKEN* tk, OP* o, char slot)
 {
     MADPROP* mp;
     MADPROP* tm;
 {
     MADPROP* mp;
     MADPROP* tm;
+
+    PERL_ARGS_ASSERT_TOKEN_GETMAD;
+
     if (tk->tk_type != 12345) {
        Perl_warner(aTHX_ packWARN(WARN_MISC),
             "Invalid TOKEN object ignored");
     if (tk->tk_type != 12345) {
        Perl_warner(aTHX_ packWARN(WARN_MISC),
             "Invalid TOKEN object ignored");
@@ -2803,11 +2930,13 @@ Perl_addmad(pTHX_ MADPROP* tm, MADPROP** root, char slot)
 MADPROP *
 Perl_newMADsv(pTHX_ char key, SV* sv)
 {
 MADPROP *
 Perl_newMADsv(pTHX_ char key, SV* sv)
 {
+    PERL_ARGS_ASSERT_NEWMADSV;
+
     return newMADPROP(key, MAD_SV, sv, 0);
 }
 
 MADPROP *
     return newMADPROP(key, MAD_SV, sv, 0);
 }
 
 MADPROP *
-Perl_newMADPROP(pTHX_ char key, char type, void* val, I32 vlen)
+Perl_newMADPROP(pTHX_ char key, char type, const void* val, I32 vlen)
 {
     MADPROP *mp;
     Newxz(mp, 1, MADPROP);
 {
     MADPROP *mp;
     Newxz(mp, 1, MADPROP);
@@ -3020,6 +3149,9 @@ Perl_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
     const I32 squash     = o->op_private & OPpTRANS_SQUASH;
     I32 del              = o->op_private & OPpTRANS_DELETE;
     SV* swash;
     const I32 squash     = o->op_private & OPpTRANS_SQUASH;
     I32 del              = o->op_private & OPpTRANS_DELETE;
     SV* swash;
+
+    PERL_ARGS_ASSERT_PMTRANS;
+
     PL_hints |= HINT_BLOCK_SCOPE;
 
     if (SvUTF8(tstr))
     PL_hints |= HINT_BLOCK_SCOPE;
 
     if (SvUTF8(tstr))
@@ -3229,7 +3361,7 @@ Perl_pmtrans(pTHX_ OP *o, OP *expr, OP *repl)
        SvREFCNT_dec(transv);
 
        if (!del && havefinal && rlen)
        SvREFCNT_dec(transv);
 
        if (!del && havefinal && rlen)
-           (void)hv_store((HV*)SvRV(swash), "FINAL", 5,
+           (void)hv_store(MUTABLE_HV(SvRV(swash)), "FINAL", 5,
                           newSVuv((UV)final), 0);
 
        if (grows)
                           newSVuv((UV)final), 0);
 
        if (grows)
@@ -3349,14 +3481,23 @@ Perl_newPMOP(pTHX_ I32 type, I32 flags)
 
 
 #ifdef USE_ITHREADS
 
 
 #ifdef USE_ITHREADS
-    if (av_len((AV*) PL_regex_pad[0]) > -1) {
-       SV * const repointer = av_pop((AV*)PL_regex_pad[0]);
-       pmop->op_pmoffset = SvIV(repointer);
-       SvREPADTMP_off(repointer);
-       sv_setiv(repointer,0);
+    assert(SvPOK(PL_regex_pad[0]));
+    if (SvCUR(PL_regex_pad[0])) {
+       /* Pop off the "packed" IV from the end.  */
+       SV *const repointer_list = PL_regex_pad[0];
+       const char *p = SvEND(repointer_list) - sizeof(IV);
+       const IV offset = *((IV*)p);
+
+       assert(SvCUR(repointer_list) % sizeof(IV) == 0);
+
+       SvEND_set(repointer_list, p);
+
+       pmop->op_pmoffset = offset;
+       /* This slot should be free, so assert this:  */
+       assert(PL_regex_pad[offset] == &PL_sv_undef);
     } else {
     } else {
-       SV * const repointer = newSViv(0);
-       av_push(PL_regex_padav, SvREFCNT_inc_simple_NN(repointer));
+       SV * const repointer = &PL_sv_undef;
+       av_push(PL_regex_padav, repointer);
        pmop->op_pmoffset = av_len(PL_regex_padav);
        PL_regex_pad = AvARRAY(PL_regex_padav);
     }
        pmop->op_pmoffset = av_len(PL_regex_padav);
        PL_regex_pad = AvARRAY(PL_regex_padav);
     }
@@ -3387,6 +3528,8 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, bool isreg)
     OP* repl = NULL;
     bool reglist;
 
     OP* repl = NULL;
     bool reglist;
 
+    PERL_ARGS_ASSERT_PMRUNTIME;
+
     if (o->op_type == OP_SUBST || o->op_type == OP_TRANS) {
        /* last element in list is the replacement; pop it */
        OP* kid;
     if (o->op_type == OP_SUBST || o->op_type == OP_TRANS) {
        /* last element in list is the replacement; pop it */
        OP* kid;
@@ -3421,32 +3564,24 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, bool isreg)
     pm = (PMOP*)o;
 
     if (expr->op_type == OP_CONST) {
     pm = (PMOP*)o;
 
     if (expr->op_type == OP_CONST) {
-       STRLEN plen;
-       SV * const pat = ((SVOP*)expr)->op_sv;
-       const char *p = SvPV_const(pat, plen);
+       SV *pat = ((SVOP*)expr)->op_sv;
        U32 pm_flags = pm->op_pmflags & PMf_COMPILETIME;
        U32 pm_flags = pm->op_pmflags & PMf_COMPILETIME;
-       if ((o->op_flags & OPf_SPECIAL) && (plen == 1 && *p == ' ')) {
-           U32 was_readonly = SvREADONLY(pat);
-
-           if (was_readonly) {
-               if (SvFAKE(pat)) {
-                   sv_force_normal_flags(pat, 0);
-                   assert(!SvREADONLY(pat));
-                   was_readonly = 0;
-               } else {
-                   SvREADONLY_off(pat);
-               }
-           }   
 
 
-           sv_setpvn(pat, "\\s+", 3);
+       if (o->op_flags & OPf_SPECIAL)
+           pm_flags |= RXf_SPLIT;
 
 
-           SvFLAGS(pat) |= was_readonly;
-
-           p = SvPV_const(pat, plen);
-           pm_flags |= RXf_SKIPWHITE;
+       if (DO_UTF8(pat)) {
+           assert (SvUTF8(pat));
+       } else if (SvUTF8(pat)) {
+           /* Not doing UTF-8, despite what the SV says. Is this only if we're
+              trapped in use 'bytes'?  */
+           /* Make a copy of the octet sequence, but without the flag on, as
+              the compiler now honours the SvUTF8 flag on pat.  */
+           STRLEN len;
+           const char *const p = SvPV(pat, len);
+           pat = newSVpvn_flags(p, len, SVs_TEMP);
        }
        }
-        if (DO_UTF8(pat))
-           pm_flags |= RXf_UTF8;
+
        PM_SETRE(pm, CALLREGCOMP(pat, pm_flags));
 
 #ifdef PERL_MAD
        PM_SETRE(pm, CALLREGCOMP(pat, pm_flags));
 
 #ifdef PERL_MAD
@@ -3494,8 +3629,8 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, bool isreg)
        OP *curop;
        if (pm->op_pmflags & PMf_EVAL) {
            curop = NULL;
        OP *curop;
        if (pm->op_pmflags & PMf_EVAL) {
            curop = NULL;
-           if (CopLINE(PL_curcop) < (line_t)PL_multi_end)
-               CopLINE_set(PL_curcop, (line_t)PL_multi_end);
+           if (CopLINE(PL_curcop) < (line_t)PL_parser->multi_end)
+               CopLINE_set(PL_curcop, (line_t)PL_parser->multi_end);
        }
        else if (repl->op_type == OP_CONST)
            curop = repl;
        }
        else if (repl->op_type == OP_CONST)
            curop = repl;
@@ -3538,7 +3673,7 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, bool isreg)
        if (curop == repl
            && !(repl_has_vars
                 && (!PM_GETRE(pm)
        if (curop == repl
            && !(repl_has_vars
                 && (!PM_GETRE(pm)
-                    || PM_GETRE(pm)->extflags & RXf_EVAL_SEEN)))
+                    || RX_EXTFLAGS(PM_GETRE(pm)) & RXf_EVAL_SEEN)))
        {
            pm->op_pmflags |= PMf_CONST;        /* const for long enough */
            prepend_elem(o->op_type, scalar(repl), o);
        {
            pm->op_pmflags |= PMf_CONST;        /* const for long enough */
            prepend_elem(o->op_type, scalar(repl), o);
@@ -3574,6 +3709,9 @@ Perl_newSVOP(pTHX_ I32 type, I32 flags, SV *sv)
 {
     dVAR;
     SVOP *svop;
 {
     dVAR;
     SVOP *svop;
+
+    PERL_ARGS_ASSERT_NEWSVOP;
+
     NewOp(1101, svop, 1, SVOP);
     svop->op_type = (OPCODE)type;
     svop->op_ppaddr = PL_ppaddr[type];
     NewOp(1101, svop, 1, SVOP);
     svop->op_type = (OPCODE)type;
     svop->op_ppaddr = PL_ppaddr[type];
@@ -3593,6 +3731,9 @@ Perl_newPADOP(pTHX_ I32 type, I32 flags, SV *sv)
 {
     dVAR;
     PADOP *padop;
 {
     dVAR;
     PADOP *padop;
+
+    PERL_ARGS_ASSERT_NEWPADOP;
+
     NewOp(1101, padop, 1, PADOP);
     padop->op_type = (OPCODE)type;
     padop->op_ppaddr = PL_ppaddr[type];
     NewOp(1101, padop, 1, PADOP);
     padop->op_type = (OPCODE)type;
     padop->op_ppaddr = PL_ppaddr[type];
@@ -3615,7 +3756,9 @@ OP *
 Perl_newGVOP(pTHX_ I32 type, I32 flags, GV *gv)
 {
     dVAR;
 Perl_newGVOP(pTHX_ I32 type, I32 flags, GV *gv)
 {
     dVAR;
-    assert(gv);
+
+    PERL_ARGS_ASSERT_NEWGVOP;
+
 #ifdef USE_ITHREADS
     GvIN_PAD_on(gv);
     return newPADOP(type, flags, SvREFCNT_inc_simple_NN(gv));
 #ifdef USE_ITHREADS
     GvIN_PAD_on(gv);
     return newPADOP(type, flags, SvREFCNT_inc_simple_NN(gv));
@@ -3655,6 +3798,8 @@ Perl_package(pTHX_ OP *o)
     OP *pegop;
 #endif
 
     OP *pegop;
 #endif
 
+    PERL_ARGS_ASSERT_PACKAGE;
+
     save_hptr(&PL_curstash);
     save_item(PL_curstname);
 
     save_hptr(&PL_curstash);
     save_item(PL_curstname);
 
@@ -3695,6 +3840,8 @@ Perl_utilize(pTHX_ int aver, I32 floor, OP *version, OP *idop, OP *arg)
     OP *pegop = newOP(OP_NULL,0);
 #endif
 
     OP *pegop = newOP(OP_NULL,0);
 #endif
 
+    PERL_ARGS_ASSERT_UTILIZE;
+
     if (idop->op_type != OP_CONST)
        Perl_croak(aTHX_ "Module name must be constant");
 
     if (idop->op_type != OP_CONST)
        Perl_croak(aTHX_ "Module name must be constant");
 
@@ -3822,6 +3969,9 @@ void
 Perl_load_module(pTHX_ U32 flags, SV *name, SV *ver, ...)
 {
     va_list args;
 Perl_load_module(pTHX_ U32 flags, SV *name, SV *ver, ...)
 {
     va_list args;
+
+    PERL_ARGS_ASSERT_LOAD_MODULE;
+
     va_start(args, ver);
     vload_module(flags, name, ver, &args);
     va_end(args);
     va_start(args, ver);
     vload_module(flags, name, ver, &args);
     va_end(args);
@@ -3833,6 +3983,7 @@ Perl_load_module_nocontext(U32 flags, SV *name, SV *ver, ...)
 {
     dTHX;
     va_list args;
 {
     dTHX;
     va_list args;
+    PERL_ARGS_ASSERT_LOAD_MODULE_NOCONTEXT;
     va_start(args, ver);
     vload_module(flags, name, ver, &args);
     va_end(args);
     va_start(args, ver);
     vload_module(flags, name, ver, &args);
     va_end(args);
@@ -3844,8 +3995,10 @@ Perl_vload_module(pTHX_ U32 flags, SV *name, SV *ver, va_list *args)
 {
     dVAR;
     OP *veop, *imop;
 {
     dVAR;
     OP *veop, *imop;
-
     OP * const modname = newSVOP(OP_CONST, 0, name);
     OP * const modname = newSVOP(OP_CONST, 0, name);
+
+    PERL_ARGS_ASSERT_VLOAD_MODULE;
+
     modname->op_private |= OPpCONST_BARE;
     if (ver) {
        veop = newSVOP(OP_CONST, 0, ver);
     modname->op_private |= OPpCONST_BARE;
     if (ver) {
        veop = newSVOP(OP_CONST, 0, ver);
@@ -3889,6 +4042,8 @@ Perl_dofile(pTHX_ OP *term, I32 force_builtin)
     OP *doop;
     GV *gv = NULL;
 
     OP *doop;
     GV *gv = NULL;
 
+    PERL_ARGS_ASSERT_DOFILE;
+
     if (!force_builtin) {
        gv = gv_fetchpvs("do", GV_NOTQUAL, SVt_PVCV);
        if (!(gv && GvCVu(gv) && GvIMPORTED_CV(gv))) {
     if (!force_builtin) {
        gv = gv_fetchpvs("do", GV_NOTQUAL, SVt_PVCV);
        if (!(gv && GvCVu(gv) && GvIMPORTED_CV(gv))) {
@@ -3980,12 +4135,15 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
     }
 
     if (is_list_assignment(left)) {
     }
 
     if (is_list_assignment(left)) {
+       static const char no_list_state[] = "Initialization of state variables"
+           " in list context currently forbidden";
        OP *curop;
        OP *curop;
+       bool maybe_common_vars = TRUE;
 
        PL_modcount = 0;
        /* Grandfathering $[ assignment here.  Bletch.*/
        /* Only simple assignments like C<< ($[) = 1 >> are allowed */
 
        PL_modcount = 0;
        /* Grandfathering $[ assignment here.  Bletch.*/
        /* Only simple assignments like C<< ($[) = 1 >> are allowed */
-       PL_eval_start = (left->op_type == OP_CONST) ? right : 0;
+       PL_eval_start = (left->op_type == OP_CONST) ? right : NULL;
        left = mod(left, OP_AASSIGN);
        if (PL_eval_start)
            PL_eval_start = 0;
        left = mod(left, OP_AASSIGN);
        if (PL_eval_start)
            PL_eval_start = 0;
@@ -3998,6 +4156,65 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
        o = newBINOP(OP_AASSIGN, flags, list(force_list(right)), curop);
        o->op_private = (U8)(0 | (flags >> 8));
 
        o = newBINOP(OP_AASSIGN, flags, list(force_list(right)), curop);
        o->op_private = (U8)(0 | (flags >> 8));
 
+       if ((left->op_type == OP_LIST
+            || (left->op_type == OP_NULL && left->op_targ == OP_LIST)))
+       {
+           OP* lop = ((LISTOP*)left)->op_first;
+           maybe_common_vars = FALSE;
+           while (lop) {
+               if (lop->op_type == OP_PADSV ||
+                   lop->op_type == OP_PADAV ||
+                   lop->op_type == OP_PADHV ||
+                   lop->op_type == OP_PADANY) {
+                   if (!(lop->op_private & OPpLVAL_INTRO))
+                       maybe_common_vars = TRUE;
+
+                   if (lop->op_private & OPpPAD_STATE) {
+                       if (left->op_private & OPpLVAL_INTRO) {
+                           /* Each variable in state($a, $b, $c) = ... */
+                       }
+                       else {
+                           /* Each state variable in
+                              (state $a, my $b, our $c, $d, undef) = ... */
+                       }
+                       yyerror(no_list_state);
+                   } else {
+                       /* Each my variable in
+                          (state $a, my $b, our $c, $d, undef) = ... */
+                   }
+               } else if (lop->op_type == OP_UNDEF ||
+                          lop->op_type == OP_PUSHMARK) {
+                   /* undef may be interesting in
+                      (state $a, undef, state $c) */
+               } else {
+                   /* Other ops in the list. */
+                   maybe_common_vars = TRUE;
+               }
+               lop = lop->op_sibling;
+           }
+       }
+       else if ((left->op_private & OPpLVAL_INTRO)
+               && (   left->op_type == OP_PADSV
+                   || left->op_type == OP_PADAV
+                   || left->op_type == OP_PADHV
+                   || left->op_type == OP_PADANY))
+       {
+           maybe_common_vars = FALSE;
+           if (left->op_private & OPpPAD_STATE) {
+               /* All single variable list context state assignments, hence
+                  state ($a) = ...
+                  (state $a) = ...
+                  state @a = ...
+                  state (@a) = ...
+                  (state @a) = ...
+                  state %a = ...
+                  state (%a) = ...
+                  (state %a) = ...
+               */
+               yyerror(no_list_state);
+           }
+       }
+
        /* PL_generation sorcery:
         * an assignment like ($a,$b) = ($c,$d) is easier than
         * ($a,$b) = ($c,$a), since there is no need for temporary vars.
        /* PL_generation sorcery:
         * an assignment like ($a,$b) = ($c,$d) is easier than
         * ($a,$b) = ($c,$a), since there is no need for temporary vars.
@@ -4012,7 +4229,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
         * to store these values, evil chicanery is done with SvUVX().
         */
 
         * to store these values, evil chicanery is done with SvUVX().
         */
 
-       {
+       if (maybe_common_vars) {
            OP *lastop = o;
            PL_generation++;
            for (curop = LINKLIST(o); curop != o; curop = LINKLIST(curop)) {
            OP *lastop = o;
            PL_generation++;
            for (curop = LINKLIST(o); curop != o; curop = LINKLIST(curop)) {
@@ -4073,7 +4290,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
                o->op_private |= OPpASSIGN_COMMON;
        }
 
                o->op_private |= OPpASSIGN_COMMON;
        }
 
-       if (right && right->op_type == OP_SPLIT) {
+       if (right && right->op_type == OP_SPLIT && !PL_madskills) {
            OP* tmpop = ((LISTOP*)right)->op_first;
            if (tmpop && (tmpop->op_type == OP_PUSHRE)) {
                PMOP * const pm = (PMOP*)tmpop;
            OP* tmpop = ((LISTOP*)right)->op_first;
            if (tmpop && (tmpop->op_type == OP_PUSHRE)) {
                PMOP * const pm = (PMOP*)tmpop;
@@ -4103,11 +4320,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
                        tmpop = ((UNOP*)tmpop)->op_first; /* to pushmark */
                        tmpop->op_sibling = NULL;       /* don't free split */
                        right->op_next = tmpop->op_next;  /* fix starting loc */
                        tmpop = ((UNOP*)tmpop)->op_first; /* to pushmark */
                        tmpop->op_sibling = NULL;       /* don't free split */
                        right->op_next = tmpop->op_next;  /* fix starting loc */
-#ifdef PERL_MAD
-                       op_getmad(o,right,'R');         /* blow off assign */
-#else
                        op_free(o);                     /* blow off assign */
                        op_free(o);                     /* blow off assign */
-#endif
                        right->op_flags &= ~OPf_WANT;
                                /* "I don't know and I don't care." */
                        return right;
                        right->op_flags &= ~OPf_WANT;
                                /* "I don't know and I don't care." */
                        return right;
@@ -4139,10 +4352,11 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
        if (PL_eval_start)
            PL_eval_start = 0;
        else {
        if (PL_eval_start)
            PL_eval_start = 0;
        else {
-           /* FIXME for MAD */
-           op_free(o);
-           o = newSVOP(OP_CONST, 0, newSViv(CopARYBASE_get(&PL_compiling)));
-           o->op_private |= OPpCONST_ARYBASE;
+           if (!PL_madskills) { /* assignment to $[ is ignored when making a mad dump */
+               op_free(o);
+               o = newSVOP(OP_CONST, 0, newSViv(CopARYBASE_get(&PL_compiling)));
+               o->op_private |= OPpCONST_ARYBASE;
+           }
        }
     }
     return o;
        }
     }
     return o;
@@ -4172,10 +4386,6 @@ Perl_newSTATEOP(pTHX_ I32 flags, char *label, OP *o)
     CopHINTS_set(&PL_compiling, CopHINTS_get(cop));
     cop->op_next = (OP*)cop;
 
     CopHINTS_set(&PL_compiling, CopHINTS_get(cop));
     cop->op_next = (OP*)cop;
 
-    if (label) {
-       CopLABEL_set(cop, label);
-       PL_hints |= HINT_BLOCK_SCOPE;
-    }
     cop->cop_seq = seq;
     /* CopARYBASE is now "virtual", in that it's stored as a flag bit in
        CopHINTS and a possible value in cop_hints_hash, so no need to copy it.
     cop->cop_seq = seq;
     /* CopARYBASE is now "virtual", in that it's stored as a flag bit in
        CopHINTS and a possible value in cop_hints_hash, so no need to copy it.
@@ -4187,6 +4397,16 @@ Perl_newSTATEOP(pTHX_ I32 flags, char *label, OP *o)
        cop->cop_hints_hash->refcounted_he_refcnt++;
        HINTS_REFCNT_UNLOCK;
     }
        cop->cop_hints_hash->refcounted_he_refcnt++;
        HINTS_REFCNT_UNLOCK;
     }
+    if (label) {
+       cop->cop_hints_hash
+           = Perl_store_cop_label(aTHX_ cop->cop_hints_hash, label);
+                                                    
+       PL_hints |= HINT_BLOCK_SCOPE;
+       /* It seems that we need to defer freeing this pointer, as other parts
+          of the grammar end up wanting to copy it after this op has been
+          created. */
+       SAVEFREEPV(label);
+    }
 
     if (PL_parser && PL_parser->copline == NOLINE)
         CopLINE_set(cop, CopLINE(PL_curcop));
 
     if (PL_parser && PL_parser->copline == NOLINE)
         CopLINE_set(cop, CopLINE(PL_curcop));
@@ -4213,6 +4433,8 @@ Perl_newSTATEOP(pTHX_ I32 flags, char *label, OP *o)
        }
     }
 
        }
     }
 
+    if (flags & OPf_SPECIAL)
+       op_null((OP*)cop);
     return prepend_elem(OP_LINESEQ, (OP*)cop, o);
 }
 
     return prepend_elem(OP_LINESEQ, (OP*)cop, o);
 }
 
@@ -4221,48 +4443,102 @@ OP *
 Perl_newLOGOP(pTHX_ I32 type, I32 flags, OP *first, OP *other)
 {
     dVAR;
 Perl_newLOGOP(pTHX_ I32 type, I32 flags, OP *first, OP *other)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_NEWLOGOP;
+
     return new_logop(type, flags, &first, &other);
 }
 
 STATIC OP *
     return new_logop(type, flags, &first, &other);
 }
 
 STATIC OP *
+S_search_const(pTHX_ OP *o)
+{
+    PERL_ARGS_ASSERT_SEARCH_CONST;
+
+    switch (o->op_type) {
+       case OP_CONST:
+           return o;
+       case OP_NULL:
+           if (o->op_flags & OPf_KIDS)
+               return search_const(cUNOPo->op_first);
+           break;
+       case OP_LEAVE:
+       case OP_SCOPE:
+       case OP_LINESEQ:
+       {
+           OP *kid;
+           if (!(o->op_flags & OPf_KIDS))
+               return NULL;
+           kid = cLISTOPo->op_first;
+           do {
+               switch (kid->op_type) {
+                   case OP_ENTER:
+                   case OP_NULL:
+                   case OP_NEXTSTATE:
+                       kid = kid->op_sibling;
+                       break;
+                   default:
+                       if (kid != cLISTOPo->op_last)
+                           return NULL;
+                       goto last;
+               }
+           } while (kid);
+           if (!kid)
+               kid = cLISTOPo->op_last;
+last:
+           return search_const(kid);
+       }
+    }
+
+    return NULL;
+}
+
+STATIC OP *
 S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp)
 {
     dVAR;
     LOGOP *logop;
     OP *o;
 S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp)
 {
     dVAR;
     LOGOP *logop;
     OP *o;
-    OP *first = *firstp;
-    OP * const other = *otherp;
+    OP *first;
+    OP *other;
+    OP *cstop = NULL;
+    int prepend_not = 0;
+
+    PERL_ARGS_ASSERT_NEW_LOGOP;
+
+    first = *firstp;
+    other = *otherp;
 
     if (type == OP_XOR)                /* Not short circuit, but here by precedence. */
        return newBINOP(type, flags, scalar(first), scalar(other));
 
     scalarboolean(first);
 
     if (type == OP_XOR)                /* Not short circuit, but here by precedence. */
        return newBINOP(type, flags, scalar(first), scalar(other));
 
     scalarboolean(first);
-    /* optimize "!a && b" to "a || b", and "!a || b" to "a && b" */
+    /* optimize AND and OR ops that have NOTs as children */
     if (first->op_type == OP_NOT
     if (first->op_type == OP_NOT
-       && (first->op_flags & OPf_SPECIAL)
        && (first->op_flags & OPf_KIDS)
        && (first->op_flags & OPf_KIDS)
+       && ((first->op_flags & OPf_SPECIAL) /* unless ($x) { } */
+           || (other->op_type == OP_NOT))  /* if (!$x && !$y) { } */
        && !PL_madskills) {
        if (type == OP_AND || type == OP_OR) {
            if (type == OP_AND)
                type = OP_OR;
            else
                type = OP_AND;
        && !PL_madskills) {
        if (type == OP_AND || type == OP_OR) {
            if (type == OP_AND)
                type = OP_OR;
            else
                type = OP_AND;
-           o = first;
-           first = *firstp = cUNOPo->op_first;
-           if (o->op_next)
-               first->op_next = o->op_next;
-           cUNOPo->op_first = NULL;
-           op_free(o);
+           op_null(first);
+           if (other->op_type == OP_NOT) { /* !a AND|OR !b => !(a OR|AND b) */
+               op_null(other);
+               prepend_not = 1; /* prepend a NOT op later */
+           }
        }
     }
        }
     }
-    if (first->op_type == OP_CONST) {
-       if (first->op_private & OPpCONST_STRICT)
-           no_bareword_allowed(first);
-       else if ((first->op_private & OPpCONST_BARE) && ckWARN(WARN_BAREWORD))
+    /* search for a constant op that could let us fold the test */
+    if ((cstop = search_const(first))) {
+       if (cstop->op_private & OPpCONST_STRICT)
+           no_bareword_allowed(cstop);
+       else if ((cstop->op_private & OPpCONST_BARE) && ckWARN(WARN_BAREWORD))
                Perl_warner(aTHX_ packWARN(WARN_BAREWORD), "Bareword found in conditional");
                Perl_warner(aTHX_ packWARN(WARN_BAREWORD), "Bareword found in conditional");
-       if ((type == OP_AND &&  SvTRUE(((SVOP*)first)->op_sv)) ||
-           (type == OP_OR  && !SvTRUE(((SVOP*)first)->op_sv)) ||
-           (type == OP_DOR && !SvOK(((SVOP*)first)->op_sv))) {
+       if ((type == OP_AND &&  SvTRUE(((SVOP*)cstop)->op_sv)) ||
+           (type == OP_OR  && !SvTRUE(((SVOP*)cstop)->op_sv)) ||
+           (type == OP_DOR && !SvOK(((SVOP*)cstop)->op_sv))) {
            *firstp = NULL;
            if (other->op_type == OP_CONST)
                other->op_private |= OPpCONST_SHORTCIRCUIT;
            *firstp = NULL;
            if (other->op_type == OP_CONST)
                other->op_private |= OPpCONST_SHORTCIRCUIT;
@@ -4287,6 +4563,7 @@ S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp)
            if ((o2->op_type == OP_PADSV || o2->op_type == OP_PADAV
                        || o2->op_type == OP_PADHV)
                && o2->op_private & OPpLVAL_INTRO
            if ((o2->op_type == OP_PADSV || o2->op_type == OP_PADAV
                        || o2->op_type == OP_PADHV)
                && o2->op_private & OPpLVAL_INTRO
+               && !(o2->op_private & OPpPAD_STATE)
                && ckWARN(WARN_DEPRECATED))
            {
                Perl_warner(aTHX_ packWARN(WARN_DEPRECATED),
                && ckWARN(WARN_DEPRECATED))
            {
                Perl_warner(aTHX_ packWARN(WARN_DEPRECATED),
@@ -4368,7 +4645,7 @@ S_new_logop(pTHX_ I32 type, I32 flags, OP** firstp, OP** otherp)
 
     CHECKOP(type,logop);
 
 
     CHECKOP(type,logop);
 
-    o = newUNOP(OP_NULL, 0, (OP*)logop);
+    o = newUNOP(prepend_not ? OP_NOT : OP_NULL, 0, (OP*)logop);
     other->op_next = o;
 
     return o;
     other->op_next = o;
 
     return o;
@@ -4381,6 +4658,9 @@ Perl_newCONDOP(pTHX_ I32 flags, OP *first, OP *trueop, OP *falseop)
     LOGOP *logop;
     OP *start;
     OP *o;
     LOGOP *logop;
     OP *start;
     OP *o;
+    OP *cstop;
+
+    PERL_ARGS_ASSERT_NEWCONDOP;
 
     if (!falseop)
        return newLOGOP(OP_AND, 0, first, trueop);
 
     if (!falseop)
        return newLOGOP(OP_AND, 0, first, trueop);
@@ -4388,14 +4668,14 @@ Perl_newCONDOP(pTHX_ I32 flags, OP *first, OP *trueop, OP *falseop)
        return newLOGOP(OP_OR, 0, first, falseop);
 
     scalarboolean(first);
        return newLOGOP(OP_OR, 0, first, falseop);
 
     scalarboolean(first);
-    if (first->op_type == OP_CONST) {
+    if ((cstop = search_const(first))) {
        /* Left or right arm of the conditional?  */
        /* Left or right arm of the conditional?  */
-       const bool left = SvTRUE(((SVOP*)first)->op_sv);
+       const bool left = SvTRUE(((SVOP*)cstop)->op_sv);
        OP *live = left ? trueop : falseop;
        OP *const dead = left ? falseop : trueop;
        OP *live = left ? trueop : falseop;
        OP *const dead = left ? falseop : trueop;
-        if (first->op_private & OPpCONST_BARE &&
-           first->op_private & OPpCONST_STRICT) {
-           no_bareword_allowed(first);
+        if (cstop->op_private & OPpCONST_BARE &&
+           cstop->op_private & OPpCONST_STRICT) {
+           no_bareword_allowed(cstop);
        }
        if (PL_madskills) {
            /* This is all dead code when PERL_MAD is not defined.  */
        }
        if (PL_madskills) {
            /* This is all dead code when PERL_MAD is not defined.  */
@@ -4444,6 +4724,8 @@ Perl_newRANGE(pTHX_ I32 flags, OP *left, OP *right)
     OP *leftstart;
     OP *o;
 
     OP *leftstart;
     OP *o;
 
+    PERL_ARGS_ASSERT_NEWRANGE;
+
     NewOp(1101, range, 1, LOGOP);
 
     range->op_type = OP_RANGE;
     NewOp(1101, range, 1, LOGOP);
 
     range->op_type = OP_RANGE;
@@ -4655,6 +4937,8 @@ Perl_newFOROP(pTHX_ I32 flags, char *label, line_t forline, OP *sv, OP *expr, OP
     I32 iterpflags = 0;
     OP *madsv = NULL;
 
     I32 iterpflags = 0;
     OP *madsv = NULL;
 
+    PERL_ARGS_ASSERT_NEWFOROP;
+
     if (sv) {
        if (sv->op_type == OP_RV2SV) {  /* symbol table variable */
            iterpflags = sv->op_private & OPpOUR_INTRO; /* for our $x () */
     if (sv) {
        if (sv->op_type == OP_RV2SV) {  /* symbol table variable */
            iterpflags = sv->op_private & OPpOUR_INTRO; /* for our $x () */
@@ -4774,6 +5058,8 @@ Perl_newLOOPEX(pTHX_ I32 type, OP *label)
     dVAR;
     OP *o;
 
     dVAR;
     OP *o;
 
+    PERL_ARGS_ASSERT_NEWLOOPEX;
+
     if (type != OP_GOTO || label->op_type == OP_CONST) {
        /* "last()" means "last" */
        if (label->op_type == OP_STUB && (label->op_flags & OPf_PARENS))
     if (type != OP_GOTO || label->op_type == OP_CONST) {
        /* "last()" means "last" */
        if (label->op_type == OP_STUB && (label->op_flags & OPf_PARENS))
@@ -4838,8 +5124,10 @@ S_newGIVWHENOP(pTHX_ OP *cond, OP *block,
     LOGOP *enterop;
     OP *o;
 
     LOGOP *enterop;
     OP *o;
 
+    PERL_ARGS_ASSERT_NEWGIVWHENOP;
+
     NewOp(1101, enterop, 1, LOGOP);
     NewOp(1101, enterop, 1, LOGOP);
-    enterop->op_type = enter_opcode;
+    enterop->op_type = (Optype)enter_opcode;
     enterop->op_ppaddr = PL_ppaddr[enter_opcode];
     enterop->op_flags =  (U8) OPf_KIDS;
     enterop->op_targ = ((entertarg == NOT_IN_PAD) ? 0 : entertarg);
     enterop->op_ppaddr = PL_ppaddr[enter_opcode];
     enterop->op_flags =  (U8) OPf_KIDS;
     enterop->op_targ = ((entertarg == NOT_IN_PAD) ? 0 : entertarg);
@@ -4887,6 +5175,9 @@ STATIC bool
 S_looks_like_bool(pTHX_ const OP *o)
 {
     dVAR;
 S_looks_like_bool(pTHX_ const OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_LOOKS_LIKE_BOOL;
+
     switch(o->op_type) {
        case OP_OR:
            return looks_like_bool(cLOGOPo->op_first);
     switch(o->op_type) {
        case OP_OR:
            return looks_like_bool(cLOGOPo->op_first);
@@ -4896,6 +5187,11 @@ S_looks_like_bool(pTHX_ const OP *o)
                looks_like_bool(cLOGOPo->op_first)
             && looks_like_bool(cLOGOPo->op_first->op_sibling));
 
                looks_like_bool(cLOGOPo->op_first)
             && looks_like_bool(cLOGOPo->op_first->op_sibling));
 
+       case OP_NULL:
+           return (
+               o->op_flags & OPf_KIDS
+           && looks_like_bool(cUNOPo->op_first));
+
        case OP_ENTERSUB:
 
        case OP_NOT:    case OP_XOR:
        case OP_ENTERSUB:
 
        case OP_NOT:    case OP_XOR:
@@ -4943,7 +5239,7 @@ OP *
 Perl_newGIVENOP(pTHX_ OP *cond, OP *block, PADOFFSET defsv_off)
 {
     dVAR;
 Perl_newGIVENOP(pTHX_ OP *cond, OP *block, PADOFFSET defsv_off)
 {
     dVAR;
-    assert( cond );
+    PERL_ARGS_ASSERT_NEWGIVENOP;
     return newGIVWHENOP(
        ref_array_or_hash(cond),
        block,
     return newGIVWHENOP(
        ref_array_or_hash(cond),
        block,
@@ -4958,6 +5254,8 @@ Perl_newWHENOP(pTHX_ OP *cond, OP *block)
     const bool cond_llb = (!cond || looks_like_bool(cond));
     OP *cond_op;
 
     const bool cond_llb = (!cond || looks_like_bool(cond));
     OP *cond_op;
 
+    PERL_ARGS_ASSERT_NEWWHENOP;
+
     if (cond_llb)
        cond_op = cond;
     else {
     if (cond_llb)
        cond_op = cond;
     else {
@@ -4987,6 +5285,14 @@ void
 Perl_cv_undef(pTHX_ CV *cv)
 {
     dVAR;
 Perl_cv_undef(pTHX_ CV *cv)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_CV_UNDEF;
+
+    DEBUG_X(PerlIO_printf(Perl_debug_log,
+         "CV undef: cv=0x%"UVxf" comppad=0x%"UVxf"\n",
+           PTR2UV(cv), PTR2UV(PL_comppad))
+    );
+
 #ifdef USE_ITHREADS
     if (CvFILE(cv) && !CvISXSUB(cv)) {
        /* for XSUBs CvFILE point directly to static memory; __FILE__ */
 #ifdef USE_ITHREADS
     if (CvFILE(cv) && !CvISXSUB(cv)) {
        /* for XSUBs CvFILE point directly to static memory; __FILE__ */
@@ -5033,6 +5339,8 @@ void
 Perl_cv_ckproto_len(pTHX_ const CV *cv, const GV *gv, const char *p,
                    const STRLEN len)
 {
 Perl_cv_ckproto_len(pTHX_ const CV *cv, const GV *gv, const char *p,
                    const STRLEN len)
 {
+    PERL_ARGS_ASSERT_CV_CKPROTO_LEN;
+
     /* Can't just use a strcmp on the prototype, as CONSTSUBs "cheat" by
        relying on SvCUR, and doubling up the buffer to hold CvFILE().  */
     if (((!p != !SvPOK(cv)) /* One has prototype, one has not.  */
     /* Can't just use a strcmp on the prototype, as CONSTSUBs "cheat" by
        relying on SvCUR, and doubling up the buffer to hold CvFILE().  */
     if (((!p != !SvPOK(cv)) /* One has prototype, one has not.  */
@@ -5077,7 +5385,7 @@ L<perlsub/"Constant Functions">.
 =cut
 */
 SV *
 =cut
 */
 SV *
-Perl_cv_const_sv(pTHX_ CV *cv)
+Perl_cv_const_sv(pTHX_ const CV *const cv)
 {
     PERL_UNUSED_CONTEXT;
     if (!cv)
 {
     PERL_UNUSED_CONTEXT;
     if (!cv)
@@ -5113,6 +5421,9 @@ Perl_op_const_sv(pTHX_ const OP *o, CV *cv)
     dVAR;
     SV *sv = NULL;
 
     dVAR;
     SV *sv = NULL;
 
+    if (PL_madskills)
+       return NULL;
+
     if (!o)
        return NULL;
 
     if (!o)
        return NULL;
 
@@ -5258,7 +5569,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
            {
                Perl_warner(aTHX_ packWARN(WARN_PROTOTYPE), "Runaway prototype");
            }
            {
                Perl_warner(aTHX_ packWARN(WARN_PROTOTYPE), "Runaway prototype");
            }
-           cv_ckproto_len((CV*)gv, NULL, ps, ps_len);
+           cv_ckproto_len((const CV *)gv, NULL, ps, ps_len);
        }
        if (ps)
            sv_setpvn((SV*)gv, ps, ps_len);
        }
        if (ps)
            sv_setpvn((SV*)gv, ps, ps_len);
@@ -5350,7 +5661,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
        SvREFCNT_inc_simple_void_NN(const_sv);
        if (cv) {
            assert(!CvROOT(cv) && !CvCONST(cv));
        SvREFCNT_inc_simple_void_NN(const_sv);
        if (cv) {
            assert(!CvROOT(cv) && !CvCONST(cv));
-           sv_setpvn((SV*)cv, "", 0);  /* prototype is "" */
+           sv_setpvs((SV*)cv, "");  /* prototype is "" */
            CvXSUBANY(cv).any_ptr = const_sv;
            CvXSUB(cv) = const_sv_xsub;
            CvCONST_on(cv);
            CvXSUBANY(cv).any_ptr = const_sv;
            CvXSUB(cv) = const_sv_xsub;
            CvCONST_on(cv);
@@ -5459,7 +5770,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
     if (ps)
        sv_setpvn((SV*)cv, ps, ps_len);
 
     if (ps)
        sv_setpvn((SV*)cv, ps, ps_len);
 
-    if (PL_error_count) {
+    if (PL_parser && PL_parser->error_count) {
        op_free(block);
        block = NULL;
        if (name) {
        op_free(block);
        block = NULL;
        if (name) {
@@ -5530,7 +5841,8 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
                           CopFILE(PL_curcop),
                           (long)PL_subline, (long)CopLINE(PL_curcop));
            gv_efullname3(tmpstr, gv, NULL);
                           CopFILE(PL_curcop),
                           (long)PL_subline, (long)CopLINE(PL_curcop));
            gv_efullname3(tmpstr, gv, NULL);
-           hv_store(GvHV(PL_DBsub), SvPVX_const(tmpstr), SvCUR(tmpstr), sv, 0);
+           (void)hv_store(GvHV(PL_DBsub), SvPVX_const(tmpstr),
+                   SvCUR(tmpstr), sv, 0);
            hv = GvHVn(db_postponed);
            if (HvFILL(hv) > 0 && hv_exists(hv, SvPVX_const(tmpstr), SvCUR(tmpstr))) {
                CV * const pcv = GvCV(db_postponed);
            hv = GvHVn(db_postponed);
            if (HvFILL(hv) > 0 && hv_exists(hv, SvPVX_const(tmpstr), SvCUR(tmpstr))) {
                CV * const pcv = GvCV(db_postponed);
@@ -5544,7 +5856,7 @@ Perl_newATTRSUB(pTHX_ I32 floor, OP *o, OP *proto, OP *attrs, OP *block)
            }
        }
 
            }
        }
 
-       if (name && !PL_error_count)
+       if (name && ! (PL_parser && PL_parser->error_count))
            process_special_blocks(name, gv, cv);
     }
 
            process_special_blocks(name, gv, cv);
     }
 
@@ -5562,6 +5874,8 @@ S_process_special_blocks(pTHX_ const char *const fullname, GV *const gv,
     const char *const colon = strrchr(fullname,':');
     const char *const name = colon ? colon + 1 : fullname;
 
     const char *const colon = strrchr(fullname,':');
     const char *const name = colon ? colon + 1 : fullname;
 
+    PERL_ARGS_ASSERT_PROCESS_SPECIAL_BLOCKS;
+
     if (*name == 'B') {
        if (strEQ(name, "BEGIN")) {
            const I32 oldscope = PL_scopestack_ix;
     if (*name == 'B') {
        if (strEQ(name, "BEGIN")) {
            const I32 oldscope = PL_scopestack_ix;
@@ -5645,6 +5959,13 @@ Perl_newCONSTSUB(pTHX_ HV *stash, const char *name, SV *sv)
 
     ENTER;
 
 
     ENTER;
 
+    if (IN_PERL_RUNTIME) {
+       /* at runtime, it's not safe to manipulate PL_curcop: it may be
+        * an op shared between threads. Use a non-shared COP for our
+        * dirty work */
+        SAVEVPTR(PL_curcop);
+        PL_curcop = &PL_compiling;
+    }
     SAVECOPLINE(PL_curcop);
     CopLINE_set(PL_curcop, PL_parser ? PL_parser->copline : NOLINE);
 
     SAVECOPLINE(PL_curcop);
     CopLINE_set(PL_curcop, PL_parser ? PL_parser->copline : NOLINE);
 
@@ -5683,6 +6004,8 @@ Perl_newXS_flags(pTHX_ const char *name, XSUBADDR_t subaddr,
 {
     CV *cv = newXS(name, subaddr, filename);
 
 {
     CV *cv = newXS(name, subaddr, filename);
 
+    PERL_ARGS_ASSERT_NEWXS_FLAGS;
+
     if (flags & XS_DYNAMIC_FILENAME) {
        /* We need to "make arrangements" (ie cheat) to ensure that the
           filename lasts as long as the PVCV we just created, but also doesn't
     if (flags & XS_DYNAMIC_FILENAME) {
        /* We need to "make arrangements" (ie cheat) to ensure that the
           filename lasts as long as the PVCV we just created, but also doesn't
@@ -5739,6 +6062,8 @@ Perl_newXS(pTHX_ const char *name, XSUBADDR_t subaddr, const char *filename)
                        GV_ADDMULTI, SVt_PVCV);
     register CV *cv;
 
                        GV_ADDMULTI, SVt_PVCV);
     register CV *cv;
 
+    PERL_ARGS_ASSERT_NEWXS;
+
     if (!subaddr)
        Perl_croak(aTHX_ "panic: no address for '%s' in '%s'", name, filename);
 
     if (!subaddr)
        Perl_croak(aTHX_ "panic: no address for '%s' in '%s'", name, filename);
 
@@ -5778,7 +6103,7 @@ Perl_newXS(pTHX_ const char *name, XSUBADDR_t subaddr, const char *filename)
     if (cv)                            /* must reuse cv if autoloaded */
        cv_undef(cv);
     else {
     if (cv)                            /* must reuse cv if autoloaded */
        cv_undef(cv);
     else {
-       cv = (CV*)newSV_type(SVt_PVCV);
+       cv = MUTABLE_CV(newSV_type(SVt_PVCV));
        if (name) {
            GvCV(gv) = cv;
            GvCVGEN(gv) = 0;
        if (name) {
            GvCV(gv) = cv;
            GvCVGEN(gv) = 0;
@@ -5892,6 +6217,9 @@ OP *
 Perl_oopsAV(pTHX_ OP *o)
 {
     dVAR;
 Perl_oopsAV(pTHX_ OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_OOPSAV;
+
     switch (o->op_type) {
     case OP_PADSV:
        o->op_type = OP_PADAV;
     switch (o->op_type) {
     case OP_PADSV:
        o->op_type = OP_PADAV;
@@ -5916,6 +6244,9 @@ OP *
 Perl_oopsHV(pTHX_ OP *o)
 {
     dVAR;
 Perl_oopsHV(pTHX_ OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_OOPSHV;
+
     switch (o->op_type) {
     case OP_PADSV:
     case OP_PADAV:
     switch (o->op_type) {
     case OP_PADSV:
     case OP_PADAV:
@@ -5942,6 +6273,9 @@ OP *
 Perl_newAVREF(pTHX_ OP *o)
 {
     dVAR;
 Perl_newAVREF(pTHX_ OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_NEWAVREF;
+
     if (o->op_type == OP_PADANY) {
        o->op_type = OP_PADAV;
        o->op_ppaddr = PL_ppaddr[OP_PADAV];
     if (o->op_type == OP_PADANY) {
        o->op_type = OP_PADAV;
        o->op_ppaddr = PL_ppaddr[OP_PADAV];
@@ -5967,6 +6301,9 @@ OP *
 Perl_newHVREF(pTHX_ OP *o)
 {
     dVAR;
 Perl_newHVREF(pTHX_ OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_NEWHVREF;
+
     if (o->op_type == OP_PADANY) {
        o->op_type = OP_PADHV;
        o->op_ppaddr = PL_ppaddr[OP_PADHV];
     if (o->op_type == OP_PADANY) {
        o->op_type = OP_PADHV;
        o->op_ppaddr = PL_ppaddr[OP_PADHV];
@@ -5990,6 +6327,9 @@ OP *
 Perl_newSVREF(pTHX_ OP *o)
 {
     dVAR;
 Perl_newSVREF(pTHX_ OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_NEWSVREF;
+
     if (o->op_type == OP_PADANY) {
        o->op_type = OP_PADSV;
        o->op_ppaddr = PL_ppaddr[OP_PADSV];
     if (o->op_type == OP_PADANY) {
        o->op_type = OP_PADSV;
        o->op_ppaddr = PL_ppaddr[OP_PADSV];
@@ -6004,6 +6344,8 @@ Perl_newSVREF(pTHX_ OP *o)
 OP *
 Perl_ck_anoncode(pTHX_ OP *o)
 {
 OP *
 Perl_ck_anoncode(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_CK_ANONCODE;
+
     cSVOPo->op_targ = pad_add_anon(cSVOPo->op_sv, o->op_type);
     if (!PL_madskills)
        cSVOPo->op_sv = NULL;
     cSVOPo->op_targ = pad_add_anon(cSVOPo->op_sv, o->op_type);
     if (!PL_madskills)
        cSVOPo->op_sv = NULL;
@@ -6014,6 +6356,9 @@ OP *
 Perl_ck_bitop(pTHX_ OP *o)
 {
     dVAR;
 Perl_ck_bitop(pTHX_ OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_CK_BITOP;
+
 #define OP_IS_NUMCOMPARE(op) \
        ((op) == OP_LT   || (op) == OP_I_LT || \
         (op) == OP_GT   || (op) == OP_I_GT || \
 #define OP_IS_NUMCOMPARE(op) \
        ((op) == OP_LT   || (op) == OP_I_LT || \
         (op) == OP_GT   || (op) == OP_I_GT || \
@@ -6048,7 +6393,10 @@ OP *
 Perl_ck_concat(pTHX_ OP *o)
 {
     const OP * const kid = cUNOPo->op_first;
 Perl_ck_concat(pTHX_ OP *o)
 {
     const OP * const kid = cUNOPo->op_first;
+
+    PERL_ARGS_ASSERT_CK_CONCAT;
     PERL_UNUSED_CONTEXT;
     PERL_UNUSED_CONTEXT;
+
     if (kid->op_type == OP_CONCAT && !(kid->op_private & OPpTARGET_MY) &&
            !(kUNOP->op_first->op_flags & OPf_MOD))
         o->op_flags |= OPf_STACKED;
     if (kid->op_type == OP_CONCAT && !(kid->op_private & OPpTARGET_MY) &&
            !(kUNOP->op_first->op_flags & OPf_MOD))
         o->op_flags |= OPf_STACKED;
@@ -6059,6 +6407,9 @@ OP *
 Perl_ck_spair(pTHX_ OP *o)
 {
     dVAR;
 Perl_ck_spair(pTHX_ OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_CK_SPAIR;
+
     if (o->op_flags & OPf_KIDS) {
        OP* newop;
        OP* kid;
     if (o->op_flags & OPf_KIDS) {
        OP* newop;
        OP* kid;
@@ -6087,6 +6438,8 @@ Perl_ck_spair(pTHX_ OP *o)
 OP *
 Perl_ck_delete(pTHX_ OP *o)
 {
 OP *
 Perl_ck_delete(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_CK_DELETE;
+
     o = ck_fun(o);
     o->op_private = 0;
     if (o->op_flags & OPf_KIDS) {
     o = ck_fun(o);
     o->op_private = 0;
     if (o->op_flags & OPf_KIDS) {
@@ -6115,6 +6468,8 @@ Perl_ck_delete(pTHX_ OP *o)
 OP *
 Perl_ck_die(pTHX_ OP *o)
 {
 OP *
 Perl_ck_die(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_CK_DIE;
+
 #ifdef VMS
     if (VMSISH_HUSHED) o->op_private |= OPpHUSH_VMSISH;
 #endif
 #ifdef VMS
     if (VMSISH_HUSHED) o->op_private |= OPpHUSH_VMSISH;
 #endif
@@ -6126,6 +6481,8 @@ Perl_ck_eof(pTHX_ OP *o)
 {
     dVAR;
 
 {
     dVAR;
 
+    PERL_ARGS_ASSERT_CK_EOF;
+
     if (o->op_flags & OPf_KIDS) {
        if (cLISTOPo->op_first->op_type == OP_STUB) {
            OP * const newop
     if (o->op_flags & OPf_KIDS) {
        if (cLISTOPo->op_first->op_type == OP_STUB) {
            OP * const newop
@@ -6146,6 +6503,9 @@ OP *
 Perl_ck_eval(pTHX_ OP *o)
 {
     dVAR;
 Perl_ck_eval(pTHX_ OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_CK_EVAL;
+
     PL_hints |= HINT_BLOCK_SCOPE;
     if (o->op_flags & OPf_KIDS) {
        SVOP * const kid = (SVOP*)cUNOPo->op_first;
     PL_hints |= HINT_BLOCK_SCOPE;
     if (o->op_flags & OPf_KIDS) {
        SVOP * const kid = (SVOP*)cUNOPo->op_first;
@@ -6196,11 +6556,8 @@ Perl_ck_eval(pTHX_ OP *o)
     }
     o->op_targ = (PADOFFSET)PL_hints;
     if ((PL_hints & HINT_LOCALIZE_HH) != 0 && GvHV(PL_hintgv)) {
     }
     o->op_targ = (PADOFFSET)PL_hints;
     if ((PL_hints & HINT_LOCALIZE_HH) != 0 && GvHV(PL_hintgv)) {
-       /* Store a copy of %^H that pp_entereval can pick up.
-          OPf_SPECIAL flags the opcode as being for this purpose,
-          so that it in turn will return a copy at every
-          eval.*/
-       OP *hhop = newSVOP(OP_CONST, OPf_SPECIAL,
+       /* Store a copy of %^H that pp_entereval can pick up. */
+       OP *hhop = newSVOP(OP_HINTSEVAL, 0,
                           (SV*)Perl_hv_copy_hints_hv(aTHX_ GvHV(PL_hintgv)));
        cUNOPo->op_first->op_sibling = hhop;
        o->op_private |= OPpEVAL_HAS_HH;
                           (SV*)Perl_hv_copy_hints_hv(aTHX_ GvHV(PL_hintgv)));
        cUNOPo->op_first->op_sibling = hhop;
        o->op_private |= OPpEVAL_HAS_HH;
@@ -6211,6 +6568,8 @@ Perl_ck_eval(pTHX_ OP *o)
 OP *
 Perl_ck_exit(pTHX_ OP *o)
 {
 OP *
 Perl_ck_exit(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_CK_EXIT;
+
 #ifdef VMS
     HV * const table = GvHV(PL_hintgv);
     if (table) {
 #ifdef VMS
     HV * const table = GvHV(PL_hintgv);
     if (table) {
@@ -6226,6 +6585,8 @@ Perl_ck_exit(pTHX_ OP *o)
 OP *
 Perl_ck_exec(pTHX_ OP *o)
 {
 OP *
 Perl_ck_exec(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_CK_EXEC;
+
     if (o->op_flags & OPf_STACKED) {
         OP *kid;
        o = ck_fun(o);
     if (o->op_flags & OPf_STACKED) {
         OP *kid;
        o = ck_fun(o);
@@ -6242,12 +6603,16 @@ OP *
 Perl_ck_exists(pTHX_ OP *o)
 {
     dVAR;
 Perl_ck_exists(pTHX_ OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_CK_EXISTS;
+
     o = ck_fun(o);
     if (o->op_flags & OPf_KIDS) {
        OP * const kid = cUNOPo->op_first;
        if (kid->op_type == OP_ENTERSUB) {
            (void) ref(kid, o->op_type);
     o = ck_fun(o);
     if (o->op_flags & OPf_KIDS) {
        OP * const kid = cUNOPo->op_first;
        if (kid->op_type == OP_ENTERSUB) {
            (void) ref(kid, o->op_type);
-           if (kid->op_type != OP_RV2CV && !PL_error_count)
+           if (kid->op_type != OP_RV2CV
+                       && !(PL_parser && PL_parser->error_count))
                Perl_croak(aTHX_ "%s argument is not a subroutine name",
                            OP_DESC(o));
            o->op_private |= OPpEXISTS_SUB;
                Perl_croak(aTHX_ "%s argument is not a subroutine name",
                            OP_DESC(o));
            o->op_private |= OPpEXISTS_SUB;
@@ -6255,7 +6620,7 @@ Perl_ck_exists(pTHX_ OP *o)
        else if (kid->op_type == OP_AELEM)
            o->op_flags |= OPf_SPECIAL;
        else if (kid->op_type != OP_HELEM)
        else if (kid->op_type == OP_AELEM)
            o->op_flags |= OPf_SPECIAL;
        else if (kid->op_type != OP_HELEM)
-           Perl_croak(aTHX_ "%s argument is not a HASH or ARRAY element",
+           Perl_croak(aTHX_ "%s argument is not a HASH or ARRAY element or a subroutine",
                        OP_DESC(o));
        op_null(kid);
     }
                        OP_DESC(o));
        op_null(kid);
     }
@@ -6268,6 +6633,8 @@ Perl_ck_rvconst(pTHX_ register OP *o)
     dVAR;
     SVOP * const kid = (SVOP*)cUNOPo->op_first;
 
     dVAR;
     SVOP * const kid = (SVOP*)cUNOPo->op_first;
 
+    PERL_ARGS_ASSERT_CK_RVCONST;
+
     o->op_private |= (PL_hints & HINT_STRICT_REFS);
     if (o->op_type == OP_RV2CV)
        o->op_private &= ~1;
     o->op_private |= (PL_hints & HINT_STRICT_REFS);
     if (o->op_type == OP_RV2CV)
        o->op_private &= ~1;
@@ -6384,6 +6751,8 @@ Perl_ck_ftst(pTHX_ OP *o)
     dVAR;
     const I32 type = o->op_type;
 
     dVAR;
     const I32 type = o->op_type;
 
+    PERL_ARGS_ASSERT_CK_FTST;
+
     if (o->op_flags & OPf_REF) {
        NOOP;
     }
     if (o->op_flags & OPf_REF) {
        NOOP;
     }
@@ -6401,7 +6770,7 @@ Perl_ck_ftst(pTHX_ OP *o)
 #endif
            return newop;
        }
 #endif
            return newop;
        }
-       if ((PL_hints & HINT_FILETEST_ACCESS) && OP_IS_FILETEST_ACCESS(o))
+       if ((PL_hints & HINT_FILETEST_ACCESS) && OP_IS_FILETEST_ACCESS(o->op_type))
            o->op_private |= OPpFT_ACCESS;
        if (PL_check[kidtype] == MEMBER_TO_FPTR(Perl_ck_ftst)
                && kidtype != OP_STAT && kidtype != OP_LSTAT)
            o->op_private |= OPpFT_ACCESS;
        if (PL_check[kidtype] == MEMBER_TO_FPTR(Perl_ck_ftst)
                && kidtype != OP_STAT && kidtype != OP_LSTAT)
@@ -6429,6 +6798,8 @@ Perl_ck_fun(pTHX_ OP *o)
     const int type = o->op_type;
     register I32 oa = PL_opargs[type] >> OASHIFT;
 
     const int type = o->op_type;
     register I32 oa = PL_opargs[type] >> OASHIFT;
 
+    PERL_ARGS_ASSERT_CK_FUN;
+
     if (o->op_flags & OPf_STACKED) {
        if ((oa & OA_OPTIONAL) && (oa >> 4) && !((oa >> 4) & OA_OPTIONAL))
            oa &= ~OA_OPTIONAL;
     if (o->op_flags & OPf_STACKED) {
        if ((oa & OA_OPTIONAL) && (oa >> 4) && !((oa >> 4) & OA_OPTIONAL))
            oa &= ~OA_OPTIONAL;
@@ -6643,7 +7014,7 @@ Perl_ck_fun(pTHX_ OP *o)
                                namesv = PAD_SVl(targ);
                                SvUPGRADE(namesv, SVt_PV);
                                if (*name != '$')
                                namesv = PAD_SVl(targ);
                                SvUPGRADE(namesv, SVt_PV);
                                if (*name != '$')
-                                   sv_setpvn(namesv, "$", 1);
+                                   sv_setpvs(namesv, "$");
                                sv_catpvn(namesv, name, len);
                            }
                        }
                                sv_catpvn(namesv, name, len);
                            }
                        }
@@ -6704,6 +7075,8 @@ Perl_ck_glob(pTHX_ OP *o)
     dVAR;
     GV *gv;
 
     dVAR;
     GV *gv;
 
+    PERL_ARGS_ASSERT_CK_GLOB;
+
     o = ck_fun(o);
     if ((o->op_flags & OPf_KIDS) && !cLISTOPo->op_first->op_sibling)
        append_elem(OP_GLOB, o, newDEFSVOP());
     o = ck_fun(o);
     if ((o->op_flags & OPf_KIDS) && !cLISTOPo->op_first->op_sibling)
        append_elem(OP_GLOB, o, newDEFSVOP());
@@ -6762,8 +7135,10 @@ Perl_ck_grep(pTHX_ OP *o)
     const OPCODE type = o->op_type == OP_GREPSTART ? OP_GREPWHILE : OP_MAPWHILE;
     PADOFFSET offset;
 
     const OPCODE type = o->op_type == OP_GREPSTART ? OP_GREPWHILE : OP_MAPWHILE;
     PADOFFSET offset;
 
+    PERL_ARGS_ASSERT_CK_GREP;
+
     o->op_ppaddr = PL_ppaddr[OP_GREPSTART];
     o->op_ppaddr = PL_ppaddr[OP_GREPSTART];
-    /* don't allocate gwop here, as we may leak it if PL_error_count > 0 */
+    /* don't allocate gwop here, as we may leak it if PL_parser->error_count > 0 */
 
     if (o->op_flags & OPf_STACKED) {
        OP* k;
 
     if (o->op_flags & OPf_STACKED) {
        OP* k;
@@ -6784,7 +7159,7 @@ Perl_ck_grep(pTHX_ OP *o)
     else
        scalar(kid);
     o = ck_fun(o);
     else
        scalar(kid);
     o = ck_fun(o);
-    if (PL_error_count)
+    if (PL_parser && PL_parser->error_count)
        return o;
     kid = cLISTOPo->op_first->op_sibling;
     if (kid->op_type != OP_NULL)
        return o;
     kid = cLISTOPo->op_first->op_sibling;
     if (kid->op_type != OP_NULL)
@@ -6821,6 +7196,8 @@ Perl_ck_grep(pTHX_ OP *o)
 OP *
 Perl_ck_index(pTHX_ OP *o)
 {
 OP *
 Perl_ck_index(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_CK_INDEX;
+
     if (o->op_flags & OPf_KIDS) {
        OP *kid = cLISTOPo->op_first->op_sibling;       /* get past pushmark */
        if (kid)
     if (o->op_flags & OPf_KIDS) {
        OP *kid = cLISTOPo->op_first->op_sibling;       /* get past pushmark */
        if (kid)
@@ -6832,22 +7209,20 @@ Perl_ck_index(pTHX_ OP *o)
 }
 
 OP *
 }
 
 OP *
-Perl_ck_lengthconst(pTHX_ OP *o)
-{
-    /* XXX length optimization goes here */
-    return ck_fun(o);
-}
-
-OP *
 Perl_ck_lfun(pTHX_ OP *o)
 {
     const OPCODE type = o->op_type;
 Perl_ck_lfun(pTHX_ OP *o)
 {
     const OPCODE type = o->op_type;
+
+    PERL_ARGS_ASSERT_CK_LFUN;
+
     return modkids(ck_fun(o), type);
 }
 
 OP *
 Perl_ck_defined(pTHX_ OP *o)           /* 19990527 MJD */
 {
     return modkids(ck_fun(o), type);
 }
 
 OP *
 Perl_ck_defined(pTHX_ OP *o)           /* 19990527 MJD */
 {
+    PERL_ARGS_ASSERT_CK_DEFINED;
+
     if ((o->op_flags & OPf_KIDS) && ckWARN2(WARN_DEPRECATED, WARN_SYNTAX)) {
        switch (cUNOPo->op_first->op_type) {
        case OP_RV2AV:
     if ((o->op_flags & OPf_KIDS) && ckWARN2(WARN_DEPRECATED, WARN_SYNTAX)) {
        switch (cUNOPo->op_first->op_type) {
        case OP_RV2AV:
@@ -6886,6 +7261,8 @@ Perl_ck_defined(pTHX_ OP *o)              /* 19990527 MJD */
 OP *
 Perl_ck_readline(pTHX_ OP *o)
 {
 OP *
 Perl_ck_readline(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_CK_READLINE;
+
     if (!(o->op_flags & OPf_KIDS)) {
        OP * const newop
            = newUNOP(OP_READLINE, 0, newGVOP(OP_GV, 0, PL_argvgv));
     if (!(o->op_flags & OPf_KIDS)) {
        OP * const newop
            = newUNOP(OP_READLINE, 0, newGVOP(OP_GV, 0, PL_argvgv));
@@ -6903,6 +7280,9 @@ OP *
 Perl_ck_rfun(pTHX_ OP *o)
 {
     const OPCODE type = o->op_type;
 Perl_ck_rfun(pTHX_ OP *o)
 {
     const OPCODE type = o->op_type;
+
+    PERL_ARGS_ASSERT_CK_RFUN;
+
     return refkids(ck_fun(o), type);
 }
 
     return refkids(ck_fun(o), type);
 }
 
@@ -6911,6 +7291,8 @@ Perl_ck_listiob(pTHX_ OP *o)
 {
     register OP *kid;
 
 {
     register OP *kid;
 
+    PERL_ARGS_ASSERT_CK_LISTIOB;
+
     kid = cLISTOPo->op_first;
     if (!kid) {
        o = force_list(o);
     kid = cLISTOPo->op_first;
     if (!kid) {
        o = force_list(o);
@@ -6967,7 +7349,11 @@ Perl_ck_smartmatch(pTHX_ OP *o)
 OP *
 Perl_ck_sassign(pTHX_ OP *o)
 {
 OP *
 Perl_ck_sassign(pTHX_ OP *o)
 {
+    dVAR;
     OP * const kid = cLISTOPo->op_first;
     OP * const kid = cLISTOPo->op_first;
+
+    PERL_ARGS_ASSERT_CK_SASSIGN;
+
     /* has a disposable target? */
     if ((PL_opargs[kid->op_type] & OA_TARGLEX)
        && !(kid->op_flags & OPf_STACKED)
     /* has a disposable target? */
     if ((PL_opargs[kid->op_type] & OA_TARGLEX)
        && !(kid->op_flags & OPf_STACKED)
@@ -6994,6 +7380,34 @@ Perl_ck_sassign(pTHX_ OP *o)
            return kid;
        }
     }
            return kid;
        }
     }
+    if (kid->op_sibling) {
+       OP *kkid = kid->op_sibling;
+       if (kkid->op_type == OP_PADSV
+               && (kkid->op_private & OPpLVAL_INTRO)
+               && SvPAD_STATE(*av_fetch(PL_comppad_name, kkid->op_targ, FALSE))) {
+           const PADOFFSET target = kkid->op_targ;
+           OP *const other = newOP(OP_PADSV,
+                                   kkid->op_flags
+                                   | ((kkid->op_private & ~OPpLVAL_INTRO) << 8));
+           OP *const first = newOP(OP_NULL, 0);
+           OP *const nullop = newCONDOP(0, first, o, other);
+           OP *const condop = first->op_next;
+           /* hijacking PADSTALE for uninitialized state variables */
+           SvPADSTALE_on(PAD_SVl(target));
+
+           condop->op_type = OP_ONCE;
+           condop->op_ppaddr = PL_ppaddr[OP_ONCE];
+           condop->op_targ = target;
+           other->op_targ = target;
+
+           /* Because we change the type of the op here, we will skip the
+              assinment binop->op_last = binop->op_first->op_sibling; at the
+              end of Perl_newBINOP(). So need to do it here. */
+           cBINOPo->op_last = cBINOPo->op_first->op_sibling;
+
+           return nullop;
+       }
+    }
     return o;
 }
 
     return o;
 }
 
@@ -7001,6 +7415,9 @@ OP *
 Perl_ck_match(pTHX_ OP *o)
 {
     dVAR;
 Perl_ck_match(pTHX_ OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_CK_MATCH;
+
     if (o->op_type != OP_QR && PL_compcv) {
        const PADOFFSET offset = pad_findmy("$_");
        if (offset != NOT_IN_PAD && !(PAD_COMPNAME_FLAGS_isOUR(offset))) {
     if (o->op_type != OP_QR && PL_compcv) {
        const PADOFFSET offset = pad_findmy("$_");
        if (offset != NOT_IN_PAD && !(PAD_COMPNAME_FLAGS_isOUR(offset))) {
@@ -7017,6 +7434,9 @@ OP *
 Perl_ck_method(pTHX_ OP *o)
 {
     OP * const kid = cUNOPo->op_first;
 Perl_ck_method(pTHX_ OP *o)
 {
     OP * const kid = cUNOPo->op_first;
+
+    PERL_ARGS_ASSERT_CK_METHOD;
+
     if (kid->op_type == OP_CONST) {
        SV* sv = kSVOP->op_sv;
        const char * const method = SvPVX_const(sv);
     if (kid->op_type == OP_CONST) {
        SV* sv = kSVOP->op_sv;
        const char * const method = SvPVX_const(sv);
@@ -7043,6 +7463,7 @@ Perl_ck_method(pTHX_ OP *o)
 OP *
 Perl_ck_null(pTHX_ OP *o)
 {
 OP *
 Perl_ck_null(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_CK_NULL;
     PERL_UNUSED_CONTEXT;
     return o;
 }
     PERL_UNUSED_CONTEXT;
     return o;
 }
@@ -7052,10 +7473,15 @@ Perl_ck_open(pTHX_ OP *o)
 {
     dVAR;
     HV * const table = GvHV(PL_hintgv);
 {
     dVAR;
     HV * const table = GvHV(PL_hintgv);
+
+    PERL_ARGS_ASSERT_CK_OPEN;
+
     if (table) {
        SV **svp = hv_fetchs(table, "open_IN", FALSE);
        if (svp && *svp) {
     if (table) {
        SV **svp = hv_fetchs(table, "open_IN", FALSE);
        if (svp && *svp) {
-           const I32 mode = mode_from_discipline(*svp);
+           STRLEN len = 0;
+           const char *d = SvPV_const(*svp, len);
+           const I32 mode = mode_from_discipline(d, len);
            if (mode & O_BINARY)
                o->op_private |= OPpOPEN_IN_RAW;
            else if (mode & O_TEXT)
            if (mode & O_BINARY)
                o->op_private |= OPpOPEN_IN_RAW;
            else if (mode & O_TEXT)
@@ -7064,7 +7490,9 @@ Perl_ck_open(pTHX_ OP *o)
 
        svp = hv_fetchs(table, "open_OUT", FALSE);
        if (svp && *svp) {
 
        svp = hv_fetchs(table, "open_OUT", FALSE);
        if (svp && *svp) {
-           const I32 mode = mode_from_discipline(*svp);
+           STRLEN len = 0;
+           const char *d = SvPV_const(*svp, len);
+           const I32 mode = mode_from_discipline(d, len);
            if (mode & O_BINARY)
                o->op_private |= OPpOPEN_OUT_RAW;
            else if (mode & O_TEXT)
            if (mode & O_BINARY)
                o->op_private |= OPpOPEN_OUT_RAW;
            else if (mode & O_TEXT)
@@ -7109,6 +7537,8 @@ Perl_ck_open(pTHX_ OP *o)
 OP *
 Perl_ck_repeat(pTHX_ OP *o)
 {
 OP *
 Perl_ck_repeat(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_CK_REPEAT;
+
     if (cBINOPo->op_first->op_flags & OPf_PARENS) {
        o->op_private |= OPpREPEAT_DOLIST;
        cBINOPo->op_first = force_list(cBINOPo->op_first);
     if (cBINOPo->op_first->op_flags & OPf_PARENS) {
        o->op_private |= OPpREPEAT_DOLIST;
        cBINOPo->op_first = force_list(cBINOPo->op_first);
@@ -7124,6 +7554,8 @@ Perl_ck_require(pTHX_ OP *o)
     dVAR;
     GV* gv = NULL;
 
     dVAR;
     GV* gv = NULL;
 
+    PERL_ARGS_ASSERT_CK_REQUIRE;
+
     if (o->op_flags & OPf_KIDS) {      /* Shall we supply missing .pm? */
        SVOP * const kid = (SVOP*)cUNOPo->op_first;
 
     if (o->op_flags & OPf_KIDS) {      /* Shall we supply missing .pm? */
        SVOP * const kid = (SVOP*)cUNOPo->op_first;
 
@@ -7131,6 +7563,8 @@ Perl_ck_require(pTHX_ OP *o)
            SV * const sv = kid->op_sv;
            U32 was_readonly = SvREADONLY(sv);
            char *s;
            SV * const sv = kid->op_sv;
            U32 was_readonly = SvREADONLY(sv);
            char *s;
+           STRLEN len;
+           const char *end;
 
            if (was_readonly) {
                if (SvFAKE(sv)) {
 
            if (was_readonly) {
                if (SvFAKE(sv)) {
@@ -7142,14 +7576,17 @@ Perl_ck_require(pTHX_ OP *o)
                }
            }   
 
                }
            }   
 
-           for (s = SvPVX(sv); *s; s++) {
+           s = SvPVX(sv);
+           len = SvCUR(sv);
+           end = s + len;
+           for (; s < end; s++) {
                if (*s == ':' && s[1] == ':') {
                if (*s == ':' && s[1] == ':') {
-                   const STRLEN len = strlen(s+2)+1;
                    *s = '/';
                    *s = '/';
-                   Move(s+2, s+1, len, char);
-                   SvCUR_set(sv, SvCUR(sv) - 1);
+                   Move(s+2, s+1, end - s - 1, char);
+                   --end;
                }
            }
                }
            }
+           SvEND_set(sv, end);
            sv_catpvs(sv, ".pm");
            SvFLAGS(sv) |= was_readonly;
        }
            sv_catpvs(sv, ".pm");
            SvFLAGS(sv) |= was_readonly;
        }
@@ -7188,6 +7625,9 @@ OP *
 Perl_ck_return(pTHX_ OP *o)
 {
     dVAR;
 Perl_ck_return(pTHX_ OP *o)
 {
     dVAR;
+
+    PERL_ARGS_ASSERT_CK_RETURN;
+
     if (CvLVALUE(PL_compcv)) {
         OP *kid;
        for (kid = cLISTOPo->op_first->op_sibling; kid; kid = kid->op_sibling)
     if (CvLVALUE(PL_compcv)) {
         OP *kid;
        for (kid = cLISTOPo->op_first->op_sibling; kid; kid = kid->op_sibling)
@@ -7201,6 +7641,9 @@ Perl_ck_select(pTHX_ OP *o)
 {
     dVAR;
     OP* kid;
 {
     dVAR;
     OP* kid;
+
+    PERL_ARGS_ASSERT_CK_SELECT;
+
     if (o->op_flags & OPf_KIDS) {
        kid = cLISTOPo->op_first->op_sibling;   /* get past pushmark */
        if (kid && kid->op_sibling) {
     if (o->op_flags & OPf_KIDS) {
        kid = cLISTOPo->op_first->op_sibling;   /* get past pushmark */
        if (kid && kid->op_sibling) {
@@ -7223,6 +7666,8 @@ Perl_ck_shift(pTHX_ OP *o)
     dVAR;
     const I32 type = o->op_type;
 
     dVAR;
     const I32 type = o->op_type;
 
+    PERL_ARGS_ASSERT_CK_SHIFT;
+
     if (!(o->op_flags & OPf_KIDS)) {
        OP *argop;
        /* FIXME - this can be refactored to reduce code in #ifdefs  */
     if (!(o->op_flags & OPf_KIDS)) {
        OP *argop;
        /* FIXME - this can be refactored to reduce code in #ifdefs  */
@@ -7250,6 +7695,8 @@ Perl_ck_sort(pTHX_ OP *o)
     dVAR;
     OP *firstkid;
 
     dVAR;
     OP *firstkid;
 
+    PERL_ARGS_ASSERT_CK_SORT;
+
     if (o->op_type == OP_SORT && (PL_hints & HINT_LOCALIZE_HH) != 0) {
        HV * const hinthv = GvHV(PL_hintgv);
        if (hinthv) {
     if (o->op_type == OP_SORT && (PL_hints & HINT_LOCALIZE_HH) != 0) {
        HV * const hinthv = GvHV(PL_hintgv);
        if (hinthv) {
@@ -7331,6 +7778,9 @@ S_simplify_sort(pTHX_ OP *o)
     int descending;
     GV *gv;
     const char *gvname;
     int descending;
     GV *gv;
     const char *gvname;
+
+    PERL_ARGS_ASSERT_SIMPLIFY_SORT;
+
     if (!(o->op_flags & OPf_STACKED))
        return;
     GvMULTI_on(gv_fetchpvs("a", GV_ADD|GV_NOTQUAL, SVt_PV));
     if (!(o->op_flags & OPf_STACKED))
        return;
     GvMULTI_on(gv_fetchpvs("a", GV_ADD|GV_NOTQUAL, SVt_PV));
@@ -7402,6 +7852,8 @@ Perl_ck_split(pTHX_ OP *o)
     dVAR;
     register OP *kid;
 
     dVAR;
     register OP *kid;
 
+    PERL_ARGS_ASSERT_CK_SPLIT;
+
     if (o->op_flags & OPf_STACKED)
        return no_fh_allowed(o);
 
     if (o->op_flags & OPf_STACKED)
        return no_fh_allowed(o);
 
@@ -7457,11 +7909,14 @@ OP *
 Perl_ck_join(pTHX_ OP *o)
 {
     const OP * const kid = cLISTOPo->op_first->op_sibling;
 Perl_ck_join(pTHX_ OP *o)
 {
     const OP * const kid = cLISTOPo->op_first->op_sibling;
+
+    PERL_ARGS_ASSERT_CK_JOIN;
+
     if (kid && kid->op_type == OP_MATCH) {
        if (ckWARN(WARN_SYNTAX)) {
             const REGEXP *re = PM_GETRE(kPMOP);
     if (kid && kid->op_type == OP_MATCH) {
        if (ckWARN(WARN_SYNTAX)) {
             const REGEXP *re = PM_GETRE(kPMOP);
-           const char *pmstr = re ? re->precomp : "STRING";
-           const STRLEN len = re ? re->prelen : 6;
+           const char *pmstr = re ? RX_PRECOMP(re) : "STRING";
+           const STRLEN len = re ? RX_PRELEN(re) : 6;
            Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
                        "/%.*s/ should probably be written as \"%.*s\"",
                        (int)len, pmstr, (int)len, pmstr);
            Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
                        "/%.*s/ should probably be written as \"%.*s\"",
                        (int)len, pmstr, (int)len, pmstr);
@@ -7488,6 +7943,8 @@ Perl_ck_subr(pTHX_ OP *o)
     const char *e = NULL;
     bool delete_op = 0;
 
     const char *e = NULL;
     bool delete_op = 0;
 
+    PERL_ARGS_ASSERT_CK_SUBR;
+
     o->op_private |= OPpENTERSUB_HASTARG;
     for (cvop = o2; cvop->op_sibling; cvop = cvop->op_sibling) ;
     if (cvop->op_type == OP_RV2CV) {
     o->op_private |= OPpENTERSUB_HASTARG;
     for (cvop = o2; cvop->op_sibling; cvop = cvop->op_sibling) ;
     if (cvop->op_type == OP_RV2CV) {
@@ -7507,26 +7964,6 @@ Perl_ck_subr(pTHX_ OP *o)
                    proto = SvPV((SV*)cv, len);
                    proto_end = proto + len;
                }
                    proto = SvPV((SV*)cv, len);
                    proto_end = proto + len;
                }
-               if (CvASSERTION(cv)) {
-                   U32 asserthints = 0;
-                   HV *const hinthv = GvHV(PL_hintgv);
-                   if (hinthv) {
-                       SV **svp = hv_fetchs(hinthv, "assertions", FALSE);
-                       if (svp && *svp)
-                           asserthints = SvUV(*svp);
-                   }
-                   if (asserthints & HINT_ASSERTING) {
-                       if (PERLDB_ASSERTION && PL_curstash != PL_debstash)
-                           o->op_private |= OPpENTERSUB_DB;
-                   }
-                   else {
-                       delete_op = 1;
-                       if (!(asserthints & HINT_ASSERTIONSSEEN) && ckWARN(WARN_ASSERTIONS)) {
-                           Perl_warner(aTHX_ packWARN(WARN_ASSERTIONS),
-                                       "Impossible to activate assertion call");
-                       }
-                   }
-               }
            }
        }
     }
            }
        }
     }
@@ -7747,6 +8184,7 @@ Perl_ck_subr(pTHX_ OP *o)
 OP *
 Perl_ck_svconst(pTHX_ OP *o)
 {
 OP *
 Perl_ck_svconst(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_CK_SVCONST;
     PERL_UNUSED_CONTEXT;
     SvREADONLY_on(cSVOPo->op_sv);
     return o;
     PERL_UNUSED_CONTEXT;
     SvREADONLY_on(cSVOPo->op_sv);
     return o;
@@ -7771,6 +8209,8 @@ Perl_ck_chdir(pTHX_ OP *o)
 OP *
 Perl_ck_trunc(pTHX_ OP *o)
 {
 OP *
 Perl_ck_trunc(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_CK_TRUNC;
+
     if (o->op_flags & OPf_KIDS) {
        SVOP *kid = (SVOP*)cUNOPo->op_first;
 
     if (o->op_flags & OPf_KIDS) {
        SVOP *kid = (SVOP*)cUNOPo->op_first;
 
@@ -7790,6 +8230,9 @@ OP *
 Perl_ck_unpack(pTHX_ OP *o)
 {
     OP *kid = cLISTOPo->op_first;
 Perl_ck_unpack(pTHX_ OP *o)
 {
     OP *kid = cLISTOPo->op_first;
+
+    PERL_ARGS_ASSERT_CK_UNPACK;
+
     if (kid->op_sibling) {
        kid = kid->op_sibling;
        if (!kid->op_sibling)
     if (kid->op_sibling) {
        kid = kid->op_sibling;
        if (!kid->op_sibling)
@@ -7801,6 +8244,8 @@ Perl_ck_unpack(pTHX_ OP *o)
 OP *
 Perl_ck_substr(pTHX_ OP *o)
 {
 OP *
 Perl_ck_substr(pTHX_ OP *o)
 {
+    PERL_ARGS_ASSERT_CK_SUBSTR;
+
     o = ck_fun(o);
     if ((o->op_flags & OPf_KIDS) && (o->op_private == 4)) {
        OP *kid = cLISTOPo->op_first;
     o = ck_fun(o);
     if ((o->op_flags & OPf_KIDS) && (o->op_private == 4)) {
        OP *kid = cLISTOPo->op_first;
@@ -7814,6 +8259,29 @@ Perl_ck_substr(pTHX_ OP *o)
     return o;
 }
 
     return o;
 }
 
+OP *
+Perl_ck_each(pTHX_ OP *o)
+{
+    dVAR;
+    OP *kid = cLISTOPo->op_first;
+
+    PERL_ARGS_ASSERT_CK_EACH;
+
+    if (kid->op_type == OP_PADAV || kid->op_type == OP_RV2AV) {
+       const unsigned new_type = o->op_type == OP_EACH ? OP_AEACH
+           : o->op_type == OP_KEYS ? OP_AKEYS : OP_AVALUES;
+       o->op_type = new_type;
+       o->op_ppaddr = PL_ppaddr[new_type];
+    }
+    else if (!(kid->op_type == OP_PADHV || kid->op_type == OP_RV2HV
+              || (kid->op_type == OP_CONST && kid->op_private & OPpCONST_BARE)
+              )) {
+       bad_type(1, "hash or array", PL_op_desc[o->op_type], kid);
+       return o;
+    }
+    return ck_fun(o);
+}
+
 /* A peephole optimizer.  We visit the ops in the order they're to execute.
  * See the comments at the top of this file for more details about when
  * peep() is called */
 /* A peephole optimizer.  We visit the ops in the order they're to execute.
  * See the comments at the top of this file for more details about when
  * peep() is called */
@@ -7837,7 +8305,6 @@ Perl_peep(pTHX_ register OP *o)
        o->op_opt = 1;
        PL_op = o;
        switch (o->op_type) {
        o->op_opt = 1;
        PL_op = o;
        switch (o->op_type) {
-       case OP_SETSTATE:
        case OP_NEXTSTATE:
        case OP_DBSTATE:
            PL_curcop = ((COP*)o);              /* for warnings */
        case OP_NEXTSTATE:
        case OP_DBSTATE:
            PL_curcop = ((COP*)o);              /* for warnings */
@@ -7847,20 +8314,21 @@ Perl_peep(pTHX_ register OP *o)
            if (cSVOPo->op_private & OPpCONST_STRICT)
                no_bareword_allowed(o);
 #ifdef USE_ITHREADS
            if (cSVOPo->op_private & OPpCONST_STRICT)
                no_bareword_allowed(o);
 #ifdef USE_ITHREADS
+       case OP_HINTSEVAL:
        case OP_METHOD_NAMED:
            /* Relocate sv to the pad for thread safety.
             * Despite being a "constant", the SV is written to,
             * for reference counts, sv_upgrade() etc. */
            if (cSVOP->op_sv) {
                const PADOFFSET ix = pad_alloc(OP_CONST, SVs_PADTMP);
        case OP_METHOD_NAMED:
            /* Relocate sv to the pad for thread safety.
             * Despite being a "constant", the SV is written to,
             * for reference counts, sv_upgrade() etc. */
            if (cSVOP->op_sv) {
                const PADOFFSET ix = pad_alloc(OP_CONST, SVs_PADTMP);
-               if (o->op_type == OP_CONST && SvPADTMP(cSVOPo->op_sv)) {
+               if (o->op_type != OP_METHOD_NAMED && SvPADTMP(cSVOPo->op_sv)) {
                    /* If op_sv is already a PADTMP then it is being used by
                     * some pad, so make a copy. */
                    sv_setsv(PAD_SVl(ix),cSVOPo->op_sv);
                    SvREADONLY_on(PAD_SVl(ix));
                    SvREFCNT_dec(cSVOPo->op_sv);
                }
                    /* If op_sv is already a PADTMP then it is being used by
                     * some pad, so make a copy. */
                    sv_setsv(PAD_SVl(ix),cSVOPo->op_sv);
                    SvREADONLY_on(PAD_SVl(ix));
                    SvREFCNT_dec(cSVOPo->op_sv);
                }
-               else if (o->op_type == OP_CONST
+               else if (o->op_type != OP_METHOD_NAMED
                         && cSVOPo->op_sv == &PL_sv_undef) {
                    /* PL_sv_undef is hack - it's unsafe to store it in the
                       AV that is the pad, because av_fetch treats values of
                         && cSVOPo->op_sv == &PL_sv_undef) {
                    /* PL_sv_undef is hack - it's unsafe to store it in the
                       AV that is the pad, because av_fetch treats values of
@@ -7907,8 +8375,7 @@ Perl_peep(pTHX_ register OP *o)
            goto nothin;
        case OP_NULL:
            if (o->op_targ == OP_NEXTSTATE
            goto nothin;
        case OP_NULL:
            if (o->op_targ == OP_NEXTSTATE
-               || o->op_targ == OP_DBSTATE
-               || o->op_targ == OP_SETSTATE)
+               || o->op_targ == OP_DBSTATE)
            {
                PL_curcop = ((COP*)o);
            }
            {
                PL_curcop = ((COP*)o);
            }
@@ -8012,6 +8479,7 @@ Perl_peep(pTHX_ register OP *o)
        case OP_DORASSIGN:
        case OP_COND_EXPR:
        case OP_RANGE:
        case OP_DORASSIGN:
        case OP_COND_EXPR:
        case OP_RANGE:
+       case OP_ONCE:
            while (cLOGOP->op_other->op_type == OP_NULL)
                cLOGOP->op_other = cLOGOP->op_other->op_next;
            peep(cLOGOP->op_other); /* Recursive calls are not replaced by fptr calls */
            while (cLOGOP->op_other->op_type == OP_NULL)
                cLOGOP->op_other = cLOGOP->op_other->op_next;
            peep(cLOGOP->op_other); /* Recursive calls are not replaced by fptr calls */
@@ -8372,7 +8840,7 @@ Perl_peep(pTHX_ register OP *o)
            UNOP *refgen, *rv2cv;
            LISTOP *exlist;
 
            UNOP *refgen, *rv2cv;
            LISTOP *exlist;
 
-           if ((o->op_flags && OPf_WANT) != OPf_WANT_VOID)
+           if ((o->op_flags & OPf_WANT) != OPf_WANT_VOID)
                break;
 
            if ((o->op_private & ~OPpASSIGN_BACKWARDS) != 2)
                break;
 
            if ((o->op_private & ~OPpASSIGN_BACKWARDS) != 2)
@@ -8424,7 +8892,7 @@ Perl_peep(pTHX_ register OP *o)
     LEAVE;
 }
 
     LEAVE;
 }
 
-char*
+const char*
 Perl_custom_op_name(pTHX_ const OP* o)
 {
     dVAR;
 Perl_custom_op_name(pTHX_ const OP* o)
 {
     dVAR;
@@ -8432,6 +8900,8 @@ Perl_custom_op_name(pTHX_ const OP* o)
     SV* keysv;
     HE* he;
 
     SV* keysv;
     HE* he;
 
+    PERL_ARGS_ASSERT_CUSTOM_OP_NAME;
+
     if (!PL_custom_op_names) /* This probably shouldn't happen */
         return (char *)PL_op_name[OP_CUSTOM];
 
     if (!PL_custom_op_names) /* This probably shouldn't happen */
         return (char *)PL_op_name[OP_CUSTOM];
 
@@ -8444,7 +8914,7 @@ Perl_custom_op_name(pTHX_ const OP* o)
     return SvPV_nolen(HeVAL(he));
 }
 
     return SvPV_nolen(HeVAL(he));
 }
 
-char*
+const char*
 Perl_custom_op_desc(pTHX_ const OP* o)
 {
     dVAR;
 Perl_custom_op_desc(pTHX_ const OP* o)
 {
     dVAR;
@@ -8452,6 +8922,8 @@ Perl_custom_op_desc(pTHX_ const OP* o)
     SV* keysv;
     HE* he;
 
     SV* keysv;
     HE* he;
 
+    PERL_ARGS_ASSERT_CUSTOM_OP_DESC;
+
     if (!PL_custom_op_descs)
         return (char *)PL_op_desc[OP_CUSTOM];
 
     if (!PL_custom_op_descs)
         return (char *)PL_op_desc[OP_CUSTOM];