This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perlop - Invocant only needs to be an object or class name for method calls
[perl5.git] / pp.c
diff --git a/pp.c b/pp.c
index 42b111e..f70d832 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -38,7 +38,7 @@ PP(pp_stub)
 {
     dSP;
     if (GIMME_V == G_SCALAR)
-       XPUSHs(&PL_sv_undef);
+        XPUSHs(&PL_sv_undef);
     RETURN;
 }
 
@@ -65,24 +65,24 @@ PP(pp_clonecv)
 {
     dTARGET;
     CV * const protocv = PadnamePROTOCV(
-       PadlistNAMESARRAY(CvPADLIST(find_runcv(NULL)))[ARGTARG]
+        PadlistNAMESARRAY(CvPADLIST(find_runcv(NULL)))[ARGTARG]
     );
     assert(SvTYPE(TARG) == SVt_PVCV);
     assert(protocv);
     if (CvISXSUB(protocv)) { /* constant */
-       /* XXX Should we clone it here? */
-       /* If this changes to use SAVECLEARSV, we can move the SAVECLEARSV
-          to introcv and remove the SvPADSTALE_off. */
-       SAVEPADSVANDMORTALIZE(ARGTARG);
-       PAD_SVl(ARGTARG) = SvREFCNT_inc_simple_NN(protocv);
+        /* XXX Should we clone it here? */
+        /* If this changes to use SAVECLEARSV, we can move the SAVECLEARSV
+           to introcv and remove the SvPADSTALE_off. */
+        SAVEPADSVANDMORTALIZE(ARGTARG);
+        PAD_SVl(ARGTARG) = SvREFCNT_inc_simple_NN(protocv);
     }
     else {
-       if (CvROOT(protocv)) {
-           assert(CvCLONE(protocv));
-           assert(!CvCLONED(protocv));
-       }
-       cv_clone_into(protocv,(CV *)TARG);
-       SAVECLEARSV(PAD_SVl(ARGTARG));
+        if (CvROOT(protocv)) {
+            assert(CvCLONE(protocv));
+            assert(!CvCLONED(protocv));
+        }
+        cv_clone_into(protocv,(CV *)TARG);
+        SAVECLEARSV(PAD_SVl(ARGTARG));
     }
     return NORMAL;
 }
@@ -103,65 +103,65 @@ S_rv2gv(pTHX_ SV *sv, const bool vivify_sv, const bool strict,
 {
     if (!isGV(sv) || SvFAKE(sv)) SvGETMAGIC(sv);
     if (SvROK(sv)) {
-       if (SvAMAGIC(sv)) {
-           sv = amagic_deref_call(sv, to_gv_amg);
-       }
+        if (SvAMAGIC(sv)) {
+            sv = amagic_deref_call(sv, to_gv_amg);
+        }
       wasref:
-       sv = SvRV(sv);
-       if (SvTYPE(sv) == SVt_PVIO) {
-           GV * const gv = MUTABLE_GV(sv_newmortal());
-           gv_init(gv, 0, "__ANONIO__", 10, 0);
-           GvIOp(gv) = MUTABLE_IO(sv);
-           SvREFCNT_inc_void_NN(sv);
-           sv = MUTABLE_SV(gv);
-       }
-       else if (!isGV_with_GP(sv)) {
-           Perl_die(aTHX_ "Not a GLOB reference");
+        sv = SvRV(sv);
+        if (SvTYPE(sv) == SVt_PVIO) {
+            GV * const gv = MUTABLE_GV(sv_newmortal());
+            gv_init(gv, 0, "__ANONIO__", 10, 0);
+            GvIOp(gv) = MUTABLE_IO(sv);
+            SvREFCNT_inc_void_NN(sv);
+            sv = MUTABLE_SV(gv);
+        }
+        else if (!isGV_with_GP(sv)) {
+            Perl_die(aTHX_ "Not a GLOB reference");
         }
     }
     else {
-       if (!isGV_with_GP(sv)) {
-           if (!SvOK(sv)) {
-               /* If this is a 'my' scalar and flag is set then vivify
-                * NI-S 1999/05/07
-                */
-               if (vivify_sv && sv != &PL_sv_undef) {
-                   GV *gv;
-                   HV *stash;
-                   if (SvREADONLY(sv))
-                       Perl_croak_no_modify();
-                   gv = MUTABLE_GV(newSV(0));
-                   stash = CopSTASH(PL_curcop);
-                   if (SvTYPE(stash) != SVt_PVHV) stash = NULL;
-                   if (cUNOP->op_targ) {
-                       SV * const namesv = PAD_SV(cUNOP->op_targ);
-                       gv_init_sv(gv, stash, namesv, 0);
-                   }
-                   else {
-                       gv_init_pv(gv, stash, "__ANONIO__", 0);
-                   }
-                   prepare_SV_for_RV(sv);
-                   SvRV_set(sv, MUTABLE_SV(gv));
-                   SvROK_on(sv);
-                   SvSETMAGIC(sv);
-                   goto wasref;
-               }
-               if (PL_op->op_flags & OPf_REF || strict) {
-                   Perl_die(aTHX_ PL_no_usym, "a symbol");
+        if (!isGV_with_GP(sv)) {
+            if (!SvOK(sv)) {
+                /* If this is a 'my' scalar and flag is set then vivify
+                 * NI-S 1999/05/07
+                 */
+                if (vivify_sv && sv != &PL_sv_undef) {
+                    GV *gv;
+                    HV *stash;
+                    if (SvREADONLY(sv))
+                        Perl_croak_no_modify();
+                    gv = MUTABLE_GV(newSV(0));
+                    stash = CopSTASH(PL_curcop);
+                    if (SvTYPE(stash) != SVt_PVHV) stash = NULL;
+                    if (cUNOP->op_targ) {
+                        SV * const namesv = PAD_SV(cUNOP->op_targ);
+                        gv_init_sv(gv, stash, namesv, 0);
+                    }
+                    else {
+                        gv_init_pv(gv, stash, "__ANONIO__", 0);
+                    }
+                    prepare_SV_for_RV(sv);
+                    SvRV_set(sv, MUTABLE_SV(gv));
+                    SvROK_on(sv);
+                    SvSETMAGIC(sv);
+                    goto wasref;
                 }
-               if (ckWARN(WARN_UNINITIALIZED))
-                   report_uninit(sv);
-               return &PL_sv_undef;
-           }
-           if (noinit)
-           {
-               if (!(sv = MUTABLE_SV(gv_fetchsv_nomg(
-                          sv, GV_ADDMG, SVt_PVGV
-                  ))))
-                   return &PL_sv_undef;
-           }
-           else {
-               if (strict) {
+                if (PL_op->op_flags & OPf_REF || strict) {
+                    Perl_die(aTHX_ PL_no_usym, "a symbol");
+                }
+                if (ckWARN(WARN_UNINITIALIZED))
+                    report_uninit(sv);
+                return &PL_sv_undef;
+            }
+            if (noinit)
+            {
+                if (!(sv = MUTABLE_SV(gv_fetchsv_nomg(
+                           sv, GV_ADDMG, SVt_PVGV
+                   ))))
+                    return &PL_sv_undef;
+            }
+            else {
+                if (strict) {
                     Perl_die(aTHX_
                              PL_no_symref_sv,
                              sv,
@@ -169,24 +169,24 @@ S_rv2gv(pTHX_ SV *sv, const bool vivify_sv, const bool strict,
                              "a symbol"
                              );
                 }
-               if ((PL_op->op_private & (OPpLVAL_INTRO|OPpDONT_INIT_GV))
-                   == OPpDONT_INIT_GV) {
-                   /* We are the target of a coderef assignment.  Return
-                      the scalar unchanged, and let pp_sasssign deal with
-                      things.  */
-                   return sv;
-               }
-               sv = MUTABLE_SV(gv_fetchsv_nomg(sv, GV_ADD, SVt_PVGV));
-           }
-           /* FAKE globs in the symbol table cause weird bugs (#77810) */
-           SvFAKE_off(sv);
-       }
+                if ((PL_op->op_private & (OPpLVAL_INTRO|OPpDONT_INIT_GV))
+                    == OPpDONT_INIT_GV) {
+                    /* We are the target of a coderef assignment.  Return
+                       the scalar unchanged, and let pp_sasssign deal with
+                       things.  */
+                    return sv;
+                }
+                sv = MUTABLE_SV(gv_fetchsv_nomg(sv, GV_ADD, SVt_PVGV));
+            }
+            /* FAKE globs in the symbol table cause weird bugs (#77810) */
+            SvFAKE_off(sv);
+        }
     }
     if (SvFAKE(sv) && !(PL_op->op_private & OPpALLOW_FAKE)) {
-       SV *newsv = sv_newmortal();
-       sv_setsv_flags(newsv, sv, 0);
-       SvFAKE_off(newsv);
-       sv = newsv;
+        SV *newsv = sv_newmortal();
+        sv_setsv_flags(newsv, sv, 0);
+        SvFAKE_off(newsv);
+        sv = newsv;
     }
     return sv;
 }
@@ -202,7 +202,7 @@ PP(pp_rv2gv)
              || PL_op->op_type == OP_READLINE
          );
     if (PL_op->op_private & OPpLVAL_INTRO)
-       save_gp(MUTABLE_GV(sv), !(PL_op->op_flags & OPf_SPECIAL));
+        save_gp(MUTABLE_GV(sv), !(PL_op->op_flags & OPf_SPECIAL));
     SETs(sv);
     RETURN;
 }
@@ -210,44 +210,44 @@ PP(pp_rv2gv)
 /* Helper function for pp_rv2sv and pp_rv2av  */
 GV *
 Perl_softref2xv(pTHX_ SV *const sv, const char *const what,
-               const svtype type, SV ***spp)
+                const svtype type, SV ***spp)
 {
     GV *gv;
 
     PERL_ARGS_ASSERT_SOFTREF2XV;
 
     if (PL_op->op_private & HINT_STRICT_REFS) {
-       if (SvOK(sv))
-           Perl_die(aTHX_ PL_no_symref_sv, sv,
-                    (SvPOKp(sv) && SvCUR(sv)>32 ? "..." : ""), what);
-       else
-           Perl_die(aTHX_ PL_no_usym, what);
+        if (SvOK(sv))
+            Perl_die(aTHX_ PL_no_symref_sv, sv,
+                     (SvPOKp(sv) && SvCUR(sv)>32 ? "..." : ""), what);
+        else
+            Perl_die(aTHX_ PL_no_usym, what);
     }
     if (!SvOK(sv)) {
-       if (
-         PL_op->op_flags & OPf_REF
-       )
-           Perl_die(aTHX_ PL_no_usym, what);
-       if (ckWARN(WARN_UNINITIALIZED))
-           report_uninit(sv);
-       if (type != SVt_PV && GIMME_V == G_ARRAY) {
-           (*spp)--;
-           return NULL;
-       }
-       **spp = &PL_sv_undef;
-       return NULL;
+        if (
+          PL_op->op_flags & OPf_REF
+        )
+            Perl_die(aTHX_ PL_no_usym, what);
+        if (ckWARN(WARN_UNINITIALIZED))
+            report_uninit(sv);
+        if (type != SVt_PV && GIMME_V == G_LIST) {
+            (*spp)--;
+            return NULL;
+        }
+        **spp = &PL_sv_undef;
+        return NULL;
     }
     if ((PL_op->op_flags & OPf_SPECIAL) &&
-       !(PL_op->op_flags & OPf_MOD))
-       {
-           if (!(gv = gv_fetchsv_nomg(sv, GV_ADDMG, type)))
-               {
-                   **spp = &PL_sv_undef;
-                   return NULL;
-               }
-       }
+        !(PL_op->op_flags & OPf_MOD))
+        {
+            if (!(gv = gv_fetchsv_nomg(sv, GV_ADDMG, type)))
+                {
+                    **spp = &PL_sv_undef;
+                    return NULL;
+                }
+        }
     else {
-       gv = gv_fetchsv_nomg(sv, GV_ADD, type);
+        gv = gv_fetchsv_nomg(sv, GV_ADD, type);
     }
     return gv;
 }
@@ -259,35 +259,35 @@ PP(pp_rv2sv)
 
     SvGETMAGIC(sv);
     if (SvROK(sv)) {
-       if (SvAMAGIC(sv)) {
-           sv = amagic_deref_call(sv, to_sv_amg);
-       }
+        if (SvAMAGIC(sv)) {
+            sv = amagic_deref_call(sv, to_sv_amg);
+        }
 
-       sv = SvRV(sv);
-       if (SvTYPE(sv) >= SVt_PVAV)
-           DIE(aTHX_ "Not a SCALAR reference");
+        sv = SvRV(sv);
+        if (SvTYPE(sv) >= SVt_PVAV)
+            DIE(aTHX_ "Not a SCALAR reference");
     }
     else {
-       gv = MUTABLE_GV(sv);
+        gv = MUTABLE_GV(sv);
 
-       if (!isGV_with_GP(gv)) {
-           gv = Perl_softref2xv(aTHX_ sv, "a SCALAR", SVt_PV, &sp);
-           if (!gv)
-               RETURN;
-       }
-       sv = GvSVn(gv);
+        if (!isGV_with_GP(gv)) {
+            gv = Perl_softref2xv(aTHX_ sv, "a SCALAR", SVt_PV, &sp);
+            if (!gv)
+                RETURN;
+        }
+        sv = GvSVn(gv);
     }
     if (PL_op->op_flags & OPf_MOD) {
-       if (PL_op->op_private & OPpLVAL_INTRO) {
-           if (cUNOP->op_first->op_type == OP_NULL)
-               sv = save_scalar(MUTABLE_GV(TOPs));
-           else if (gv)
-               sv = save_scalar(gv);
-           else
-               Perl_croak(aTHX_ "%s", PL_no_localize_ref);
-       }
-       else if (PL_op->op_private & OPpDEREF)
-           sv = vivify_ref(sv, PL_op->op_private & OPpDEREF);
+        if (PL_op->op_private & OPpLVAL_INTRO) {
+            if (cUNOP->op_first->op_type == OP_NULL)
+                sv = save_scalar(MUTABLE_GV(TOPs));
+            else if (gv)
+                sv = save_scalar(gv);
+            else
+                Perl_croak(aTHX_ "%s", PL_no_localize_ref);
+        }
+        else if (PL_op->op_private & OPpDEREF)
+            sv = vivify_ref(sv, PL_op->op_private & OPpDEREF);
     }
     SPAGAIN; /* in case chasing soft refs reallocated the stack */
     SETs(sv);
@@ -300,14 +300,14 @@ PP(pp_av2arylen)
     AV * const av = MUTABLE_AV(TOPs);
     const I32 lvalue = PL_op->op_flags & OPf_MOD || LVRET;
     if (lvalue) {
-       SV ** const svp = Perl_av_arylen_p(aTHX_ MUTABLE_AV(av));
-       if (!*svp) {
-           *svp = newSV_type(SVt_PVMG);
-           sv_magic(*svp, MUTABLE_SV(av), PERL_MAGIC_arylen, NULL, 0);
-       }
-       SETs(*svp);
+        SV ** const svp = Perl_av_arylen_p(aTHX_ MUTABLE_AV(av));
+        if (!*svp) {
+            *svp = newSV_type(SVt_PVMG);
+            sv_magic(*svp, MUTABLE_SV(av), PERL_MAGIC_arylen, NULL, 0);
+        }
+        SETs(*svp);
     } else {
-       SETs(sv_2mortal(newSViv(AvFILL(MUTABLE_AV(av)))));
+        SETs(sv_2mortal(newSViv(AvFILL(MUTABLE_AV(av)))));
     }
     RETURN;
 }
@@ -317,16 +317,16 @@ PP(pp_pos)
     dSP; dTOPss;
 
     if (PL_op->op_flags & OPf_MOD || LVRET) {
-       SV * const ret = sv_2mortal(newSV_type(SVt_PVLV));/* Not TARG RT#67838 */
-       sv_magic(ret, NULL, PERL_MAGIC_pos, NULL, 0);
-       LvTYPE(ret) = '.';
-       LvTARG(ret) = SvREFCNT_inc_simple(sv);
-       SETs(ret);    /* no SvSETMAGIC */
+        SV * const ret = sv_2mortal(newSV_type(SVt_PVLV));/* Not TARG RT#67838 */
+        sv_magic(ret, NULL, PERL_MAGIC_pos, NULL, 0);
+        LvTYPE(ret) = '.';
+        LvTARG(ret) = SvREFCNT_inc_simple(sv);
+        SETs(ret);    /* no SvSETMAGIC */
     }
     else {
-           const MAGIC * const mg = mg_find_mglob(sv);
-           if (mg && mg->mg_len != -1) {
-               STRLEN i = mg->mg_len;
+            const MAGIC * const mg = mg_find_mglob(sv);
+            if (mg && mg->mg_len != -1) {
+                STRLEN i = mg->mg_len;
                 if (PL_op->op_private & OPpTRUEBOOL)
                     SETs(i ? &PL_sv_yes : &PL_sv_zero);
                 else {
@@ -335,9 +335,9 @@ PP(pp_pos)
                         i = sv_pos_b2u_flags(sv, i, SV_GMAGIC|SV_CONST_RETURN);
                     SETu(i);
                 }
-               return NORMAL;
-           }
-           SETs(&PL_sv_undef);
+                return NORMAL;
+            }
+            SETs(&PL_sv_undef);
     }
     return NORMAL;
 }
@@ -348,23 +348,23 @@ PP(pp_rv2cv)
     GV *gv;
     HV *stash_unused;
     const I32 flags = (PL_op->op_flags & OPf_SPECIAL)
-       ? GV_ADDMG
-       : ((PL_op->op_private & (OPpLVAL_INTRO|OPpMAY_RETURN_CONSTANT))
+        ? GV_ADDMG
+        : ((PL_op->op_private & (OPpLVAL_INTRO|OPpMAY_RETURN_CONSTANT))
                                                     == OPpMAY_RETURN_CONSTANT)
-           ? GV_ADD|GV_NOEXPAND
-           : GV_ADD;
+            ? GV_ADD|GV_NOEXPAND
+            : GV_ADD;
     /* We usually try to add a non-existent subroutine in case of AUTOLOAD. */
     /* (But not in defined().) */
 
     CV *cv = sv_2cv(TOPs, &stash_unused, &gv, flags);
     if (cv) NOOP;
     else if ((flags == (GV_ADD|GV_NOEXPAND)) && gv && SvROK(gv)) {
-       cv = SvTYPE(SvRV(gv)) == SVt_PVCV
-           ? MUTABLE_CV(SvRV(gv))
-           : MUTABLE_CV(gv);
+        cv = SvTYPE(SvRV(gv)) == SVt_PVCV
+            ? MUTABLE_CV(SvRV(gv))
+            : MUTABLE_CV(gv);
     }
     else
-       cv = MUTABLE_CV(&PL_sv_undef);
+        cv = MUTABLE_CV(&PL_sv_undef);
     SETs(MUTABLE_SV(cv));
     return NORMAL;
 }
@@ -379,24 +379,24 @@ PP(pp_prototype)
 
     if (SvGMAGICAL(TOPs)) SETs(sv_mortalcopy(TOPs));
     if (SvPOK(TOPs) && SvCUR(TOPs) >= 7) {
-       const char * s = SvPVX_const(TOPs);
+        const char * s = SvPVX_const(TOPs);
         if (memBEGINs(s, SvCUR(TOPs), "CORE::")) {
-           const int code = keyword(s + 6, SvCUR(TOPs) - 6, 1);
-           if (!code)
-               DIE(aTHX_ "Can't find an opnumber for \"%" UTF8f "\"",
-                  UTF8fARG(SvFLAGS(TOPs) & SVf_UTF8, SvCUR(TOPs)-6, s+6));
-           {
-               SV * const sv = core_prototype(NULL, s + 6, code, NULL);
-               if (sv) ret = sv;
-           }
-           goto set;
-       }
+            const int code = keyword(s + 6, SvCUR(TOPs) - 6, 1);
+            if (!code)
+                DIE(aTHX_ "Can't find an opnumber for \"%" UTF8f "\"",
+                   UTF8fARG(SvFLAGS(TOPs) & SVf_UTF8, SvCUR(TOPs)-6, s+6));
+            {
+                SV * const sv = core_prototype(NULL, s + 6, code, NULL);
+                if (sv) ret = sv;
+            }
+            goto set;
+        }
     }
     cv = sv_2cv(TOPs, &stash, &gv, 0);
     if (cv && SvPOK(cv))
-       ret = newSVpvn_flags(
-           CvPROTO(cv), CvPROTOLEN(cv), SVs_TEMP | SvUTF8(cv)
-       );
+        ret = newSVpvn_flags(
+            CvPROTO(cv), CvPROTOLEN(cv), SVs_TEMP | SvUTF8(cv)
+        );
   set:
     SETs(ret);
     RETURN;
@@ -407,7 +407,7 @@ PP(pp_anoncode)
     dSP;
     CV *cv = MUTABLE_CV(PAD_SV(PL_op->op_targ));
     if (CvCLONE(cv))
-       cv = MUTABLE_CV(sv_2mortal(MUTABLE_SV(cv_clone(cv))));
+        cv = MUTABLE_CV(sv_2mortal(MUTABLE_SV(cv_clone(cv))));
     EXTEND(SP,1);
     PUSHs(MUTABLE_SV(cv));
     RETURN;
@@ -423,21 +423,21 @@ PP(pp_srefgen)
 PP(pp_refgen)
 {
     dSP; dMARK;
-    if (GIMME_V != G_ARRAY) {
-       if (++MARK <= SP)
-           *MARK = *SP;
-       else
-       {
-           MEXTEND(SP, 1);
-           *MARK = &PL_sv_undef;
-       }
-       *MARK = refto(*MARK);
-       SP = MARK;
-       RETURN;
+    if (GIMME_V != G_LIST) {
+        if (++MARK <= SP)
+            *MARK = *SP;
+        else
+        {
+            MEXTEND(SP, 1);
+            *MARK = &PL_sv_undef;
+        }
+        *MARK = refto(*MARK);
+        SP = MARK;
+        RETURN;
     }
     EXTEND_MORTAL(SP - MARK);
     while (++MARK <= SP)
-       *MARK = refto(*MARK);
+        *MARK = refto(*MARK);
     RETURN;
 }
 
@@ -449,18 +449,18 @@ S_refto(pTHX_ SV *sv)
     PERL_ARGS_ASSERT_REFTO;
 
     if (SvTYPE(sv) == SVt_PVLV && LvTYPE(sv) == 'y') {
-       if (LvTARGLEN(sv))
-           vivify_defelem(sv);
-       if (!(sv = LvTARG(sv)))
-           sv = &PL_sv_undef;
-       else
-           SvREFCNT_inc_void_NN(sv);
+        if (LvTARGLEN(sv))
+            vivify_defelem(sv);
+        if (!(sv = LvTARG(sv)))
+            sv = &PL_sv_undef;
+        else
+            SvREFCNT_inc_void_NN(sv);
     }
     else if (SvTYPE(sv) == SVt_PVAV) {
-       if (!AvREAL((const AV *)sv) && AvREIFY((const AV *)sv))
-           av_reify(MUTABLE_AV(sv));
-       SvTEMP_off(sv);
-       SvREFCNT_inc_void_NN(sv);
+        if (!AvREAL((const AV *)sv) && AvREIFY((const AV *)sv))
+            av_reify(MUTABLE_AV(sv));
+        SvTEMP_off(sv);
+        SvREFCNT_inc_void_NN(sv);
     }
     else if (SvPADTMP(sv)) {
         sv = newSVsv(sv);
@@ -468,8 +468,8 @@ S_refto(pTHX_ SV *sv)
     else if (UNLIKELY(SvSMAGICAL(sv) && mg_find(sv, PERL_MAGIC_nonelem)))
         sv_unmagic(SvREFCNT_inc_simple_NN(sv), PERL_MAGIC_nonelem);
     else {
-       SvTEMP_off(sv);
-       SvREFCNT_inc_void_NN(sv);
+        SvTEMP_off(sv);
+        SvREFCNT_inc_void_NN(sv);
     }
     rv = sv_newmortal();
     sv_upgrade(rv, SVt_IV);
@@ -485,7 +485,7 @@ PP(pp_ref)
 
     SvGETMAGIC(sv);
     if (!SvROK(sv)) {
-       SETs(&PL_sv_no);
+        SETs(&PL_sv_no);
         return NORMAL;
     }
 
@@ -518,11 +518,11 @@ PP(pp_ref)
 
   do_sv_ref:
     {
-       dTARGET;
-       SETs(TARG);
-       sv_ref(TARG, SvRV(sv), TRUE);
-       SvSETMAGIC(TARG);
-       return NORMAL;
+        dTARGET;
+        SETs(TARG);
+        sv_ref(TARG, SvRV(sv), TRUE);
+        SvSETMAGIC(TARG);
+        return NORMAL;
     }
 
 }
@@ -536,33 +536,33 @@ PP(pp_bless)
     if (MAXARG == 1)
     {
       curstash:
-       stash = CopSTASH(PL_curcop);
-       if (SvTYPE(stash) != SVt_PVHV)
-           Perl_croak(aTHX_ "Attempt to bless into a freed package");
+        stash = CopSTASH(PL_curcop);
+        if (SvTYPE(stash) != SVt_PVHV)
+            Perl_croak(aTHX_ "Attempt to bless into a freed package");
     }
     else {
-       SV * const ssv = POPs;
-       STRLEN len;
-       const char *ptr;
-
-       if (!ssv) goto curstash;
-       SvGETMAGIC(ssv);
-       if (SvROK(ssv)) {
-         if (!SvAMAGIC(ssv)) {
-          frog:
-           Perl_croak(aTHX_ "Attempt to bless into a reference");
-         }
-         /* SvAMAGIC is on here, but it only means potentially overloaded,
-            so after stringification: */
-         ptr = SvPV_nomg_const(ssv,len);
-         /* We need to check the flag again: */
-         if (!SvAMAGIC(ssv)) goto frog;
-       }
-       else ptr = SvPV_nomg_const(ssv,len);
-       if (len == 0)
-           Perl_ck_warner(aTHX_ packWARN(WARN_MISC),
-                          "Explicit blessing to '' (assuming package main)");
-       stash = gv_stashpvn(ptr, len, GV_ADD|SvUTF8(ssv));
+        SV * const ssv = POPs;
+        STRLEN len;
+        const char *ptr;
+
+        if (!ssv) goto curstash;
+        SvGETMAGIC(ssv);
+        if (SvROK(ssv)) {
+          if (!SvAMAGIC(ssv)) {
+           frog:
+            Perl_croak(aTHX_ "Attempt to bless into a reference");
+          }
+          /* SvAMAGIC is on here, but it only means potentially overloaded,
+             so after stringification: */
+          ptr = SvPV_nomg_const(ssv,len);
+          /* We need to check the flag again: */
+          if (!SvAMAGIC(ssv)) goto frog;
+        }
+        else ptr = SvPV_nomg_const(ssv,len);
+        if (len == 0)
+            Perl_ck_warner(aTHX_ packWARN(WARN_MISC),
+                           "Explicit blessing to '' (assuming package main)");
+        stash = gv_stashpvn(ptr, len, GV_ADD|SvUTF8(ssv));
     }
 
     (void)sv_bless(TOPs, stash);
@@ -581,64 +581,64 @@ PP(pp_gelem)
 
     sv = NULL;
     if (elem) {
-       /* elem will always be NUL terminated.  */
-       switch (*elem) {
-       case 'A':
-           if (memEQs(elem, len, "ARRAY"))
-           {
-               tmpRef = MUTABLE_SV(GvAV(gv));
-               if (tmpRef && !AvREAL((const AV *)tmpRef)
-                && AvREIFY((const AV *)tmpRef))
-                   av_reify(MUTABLE_AV(tmpRef));
-           }
-           break;
-       case 'C':
-           if (memEQs(elem, len, "CODE"))
-               tmpRef = MUTABLE_SV(GvCVu(gv));
-           break;
-       case 'F':
-           if (memEQs(elem, len, "FILEHANDLE")) {
-               tmpRef = MUTABLE_SV(GvIOp(gv));
-           }
-           else
-               if (memEQs(elem, len, "FORMAT"))
-                   tmpRef = MUTABLE_SV(GvFORM(gv));
-           break;
-       case 'G':
-           if (memEQs(elem, len, "GLOB"))
-               tmpRef = MUTABLE_SV(gv);
-           break;
-       case 'H':
-           if (memEQs(elem, len, "HASH"))
-               tmpRef = MUTABLE_SV(GvHV(gv));
-           break;
-       case 'I':
-           if (memEQs(elem, len, "IO"))
-               tmpRef = MUTABLE_SV(GvIOp(gv));
-           break;
-       case 'N':
-           if (memEQs(elem, len, "NAME"))
-               sv = newSVhek(GvNAME_HEK(gv));
-           break;
-       case 'P':
-           if (memEQs(elem, len, "PACKAGE")) {
-               const HV * const stash = GvSTASH(gv);
-               const HEK * const hek = stash ? HvNAME_HEK(stash) : NULL;
-               sv = hek ? newSVhek(hek) : newSVpvs("__ANON__");
-           }
-           break;
-       case 'S':
-           if (memEQs(elem, len, "SCALAR"))
-               tmpRef = GvSVn(gv);
-           break;
-       }
+        /* elem will always be NUL terminated.  */
+        switch (*elem) {
+        case 'A':
+            if (memEQs(elem, len, "ARRAY"))
+            {
+                tmpRef = MUTABLE_SV(GvAV(gv));
+                if (tmpRef && !AvREAL((const AV *)tmpRef)
+                 && AvREIFY((const AV *)tmpRef))
+                    av_reify(MUTABLE_AV(tmpRef));
+            }
+            break;
+        case 'C':
+            if (memEQs(elem, len, "CODE"))
+                tmpRef = MUTABLE_SV(GvCVu(gv));
+            break;
+        case 'F':
+            if (memEQs(elem, len, "FILEHANDLE")) {
+                tmpRef = MUTABLE_SV(GvIOp(gv));
+            }
+            else
+                if (memEQs(elem, len, "FORMAT"))
+                    tmpRef = MUTABLE_SV(GvFORM(gv));
+            break;
+        case 'G':
+            if (memEQs(elem, len, "GLOB"))
+                tmpRef = MUTABLE_SV(gv);
+            break;
+        case 'H':
+            if (memEQs(elem, len, "HASH"))
+                tmpRef = MUTABLE_SV(GvHV(gv));
+            break;
+        case 'I':
+            if (memEQs(elem, len, "IO"))
+                tmpRef = MUTABLE_SV(GvIOp(gv));
+            break;
+        case 'N':
+            if (memEQs(elem, len, "NAME"))
+                sv = newSVhek(GvNAME_HEK(gv));
+            break;
+        case 'P':
+            if (memEQs(elem, len, "PACKAGE")) {
+                const HV * const stash = GvSTASH(gv);
+                const HEK * const hek = stash ? HvNAME_HEK(stash) : NULL;
+                sv = hek ? newSVhek(hek) : newSVpvs("__ANON__");
+            }
+            break;
+        case 'S':
+            if (memEQs(elem, len, "SCALAR"))
+                tmpRef = GvSVn(gv);
+            break;
+        }
     }
     if (tmpRef)
-       sv = newRV(tmpRef);
+        sv = newRV(tmpRef);
     if (sv)
-       sv_2mortal(sv);
+        sv_2mortal(sv);
     else
-       sv = &PL_sv_undef;
+        sv = &PL_sv_undef;
     SETs(sv);
     RETURN;
 }
@@ -652,9 +652,9 @@ PP(pp_study)
 
     (void)SvPV(sv, len);
     if (len == 0 || len > I32_MAX || !SvPOK(sv) || SvUTF8(sv) || SvVALID(sv)) {
-       /* Historically, study was skipped in these cases. */
-       SETs(&PL_sv_no);
-       return NORMAL;
+        /* Historically, study was skipped in these cases. */
+        SETs(&PL_sv_no);
+        return NORMAL;
     }
 
     /* Make study a no-op. It's no longer useful and its existence
@@ -672,25 +672,25 @@ PP(pp_trans)
     SV *sv;
 
     if (PL_op->op_flags & OPf_STACKED)
-       sv = POPs;
+        sv = POPs;
     else {
-       EXTEND(SP,1);
-       if (ARGTARG)
-           sv = PAD_SV(ARGTARG);
-       else {
-           sv = DEFSV;
-       }
+        EXTEND(SP,1);
+        if (ARGTARG)
+            sv = PAD_SV(ARGTARG);
+        else {
+            sv = DEFSV;
+        }
     }
     if(PL_op->op_type == OP_TRANSR) {
-       STRLEN len;
-       const char * const pv = SvPV(sv,len);
-       SV * const newsv = newSVpvn_flags(pv, len, SVs_TEMP|SvUTF8(sv));
-       do_trans(newsv);
-       PUSHs(newsv);
+        STRLEN len;
+        const char * const pv = SvPV(sv,len);
+        SV * const newsv = newSVpvn_flags(pv, len, SVs_TEMP|SvUTF8(sv));
+        do_trans(newsv);
+        PUSHs(newsv);
     }
     else {
-       Size_t i = do_trans(sv);
-       mPUSHi((UV)i);
+        Size_t i = do_trans(sv);
+        mPUSHi((UV)i);
     }
     RETURN;
 }
@@ -707,26 +707,26 @@ S_do_chomp(pTHX_ SV *retval, SV *sv, bool chomping)
     PERL_ARGS_ASSERT_DO_CHOMP;
 
     if (chomping && (RsSNARF(PL_rs) || RsRECORD(PL_rs)))
-       return 0;
+        return 0;
     if (SvTYPE(sv) == SVt_PVAV) {
-       I32 i;
-       AV *const av = MUTABLE_AV(sv);
-       const I32 max = AvFILL(av);
-
-       for (i = 0; i <= max; i++) {
-           sv = MUTABLE_SV(av_fetch(av, i, FALSE));
-           if (sv && ((sv = *(SV**)sv), sv != &PL_sv_undef))
-               count += do_chomp(retval, sv, chomping);
-       }
+        I32 i;
+        AV *const av = MUTABLE_AV(sv);
+        const I32 max = AvFILL(av);
+
+        for (i = 0; i <= max; i++) {
+            sv = MUTABLE_SV(av_fetch(av, i, FALSE));
+            if (sv && ((sv = *(SV**)sv), sv != &PL_sv_undef))
+                count += do_chomp(retval, sv, chomping);
+        }
         return count;
     }
     else if (SvTYPE(sv) == SVt_PVHV) {
-       HV* const hv = MUTABLE_HV(sv);
-       HE* entry;
+        HV* const hv = MUTABLE_HV(sv);
+        HE* entry;
         (void)hv_iterinit(hv);
         while ((entry = hv_iternext(hv)))
             count += do_chomp(retval, hv_iterval(hv,entry), chomping);
-       return count;
+        return count;
     }
     else if (SvREADONLY(sv)) {
             Perl_croak_no_modify();
@@ -734,110 +734,110 @@ S_do_chomp(pTHX_ SV *retval, SV *sv, bool chomping)
 
     s = SvPV(sv, len);
     if (chomping) {
-       if (s && len) {
-           char *temp_buffer = NULL;
-           SV *svrecode = NULL;
-           s += --len;
-           if (RsPARA(PL_rs)) {
-               if (*s != '\n')
-                   goto nope_free_nothing;
-               ++count;
-               while (len && s[-1] == '\n') {
-                   --len;
-                   --s;
-                   ++count;
-               }
-           }
-           else {
-               STRLEN rslen, rs_charlen;
-               const char *rsptr = SvPV_const(PL_rs, rslen);
-
-               rs_charlen = SvUTF8(PL_rs)
-                   ? sv_len_utf8(PL_rs)
-                   : rslen;
-
-               if (SvUTF8(PL_rs) != SvUTF8(sv)) {
-                   /* Assumption is that rs is shorter than the scalar.  */
-                   if (SvUTF8(PL_rs)) {
-                       /* RS is utf8, scalar is 8 bit.  */
-                       bool is_utf8 = TRUE;
-                       temp_buffer = (char*)bytes_from_utf8((U8*)rsptr,
-                                                            &rslen, &is_utf8);
-                       if (is_utf8) {
-                           /* Cannot downgrade, therefore cannot possibly match.
-                              At this point, temp_buffer is not alloced, and
-                              is the buffer inside PL_rs, so dont free it.
-                            */
-                           assert (temp_buffer == rsptr);
-                           goto nope_free_sv;
-                       }
-                       rsptr = temp_buffer;
-                   }
-                   else {
-                       /* RS is 8 bit, scalar is utf8.  */
-                       temp_buffer = (char*)bytes_to_utf8((U8*)rsptr, &rslen);
-                       rsptr = temp_buffer;
-                   }
-               }
-               if (rslen == 1) {
-                   if (*s != *rsptr)
-                       goto nope_free_all;
-                   ++count;
-               }
-               else {
-                   if (len < rslen - 1)
-                       goto nope_free_all;
-                   len -= rslen - 1;
-                   s -= rslen - 1;
-                   if (memNE(s, rsptr, rslen))
-                       goto nope_free_all;
-                   count += rs_charlen;
-               }
-           }
-           SvPV_force_nomg_nolen(sv);
-           SvCUR_set(sv, len);
-           *SvEND(sv) = '\0';
-           SvNIOK_off(sv);
-           SvSETMAGIC(sv);
-
-           nope_free_all:
-           Safefree(temp_buffer);
-           nope_free_sv:
-           SvREFCNT_dec(svrecode);
-           nope_free_nothing: ;
-       }
+        if (s && len) {
+            char *temp_buffer = NULL;
+            SV *svrecode = NULL;
+            s += --len;
+            if (RsPARA(PL_rs)) {
+                if (*s != '\n')
+                    goto nope_free_nothing;
+                ++count;
+                while (len && s[-1] == '\n') {
+                    --len;
+                    --s;
+                    ++count;
+                }
+            }
+            else {
+                STRLEN rslen, rs_charlen;
+                const char *rsptr = SvPV_const(PL_rs, rslen);
+
+                rs_charlen = SvUTF8(PL_rs)
+                    ? sv_len_utf8(PL_rs)
+                    : rslen;
+
+                if (SvUTF8(PL_rs) != SvUTF8(sv)) {
+                    /* Assumption is that rs is shorter than the scalar.  */
+                    if (SvUTF8(PL_rs)) {
+                        /* RS is utf8, scalar is 8 bit.  */
+                        bool is_utf8 = TRUE;
+                        temp_buffer = (char*)bytes_from_utf8((U8*)rsptr,
+                                                             &rslen, &is_utf8);
+                        if (is_utf8) {
+                            /* Cannot downgrade, therefore cannot possibly match.
+                               At this point, temp_buffer is not alloced, and
+                               is the buffer inside PL_rs, so dont free it.
+                             */
+                            assert (temp_buffer == rsptr);
+                            goto nope_free_sv;
+                        }
+                        rsptr = temp_buffer;
+                    }
+                    else {
+                        /* RS is 8 bit, scalar is utf8.  */
+                        temp_buffer = (char*)bytes_to_utf8((U8*)rsptr, &rslen);
+                        rsptr = temp_buffer;
+                    }
+                }
+                if (rslen == 1) {
+                    if (*s != *rsptr)
+                        goto nope_free_all;
+                    ++count;
+                }
+                else {
+                    if (len < rslen - 1)
+                        goto nope_free_all;
+                    len -= rslen - 1;
+                    s -= rslen - 1;
+                    if (memNE(s, rsptr, rslen))
+                        goto nope_free_all;
+                    count += rs_charlen;
+                }
+            }
+            SvPV_force_nomg_nolen(sv);
+            SvCUR_set(sv, len);
+            *SvEND(sv) = '\0';
+            SvNIOK_off(sv);
+            SvSETMAGIC(sv);
+
+            nope_free_all:
+            Safefree(temp_buffer);
+            nope_free_sv:
+            SvREFCNT_dec(svrecode);
+            nope_free_nothing: ;
+        }
     } else {
-       if (len && (!SvPOK(sv) || SvIsCOW(sv)))
-           s = SvPV_force_nomg(sv, len);
-       if (DO_UTF8(sv)) {
-           if (s && len) {
-               char * const send = s + len;
-               char * const start = s;
-               s = send - 1;
-               while (s > start && UTF8_IS_CONTINUATION(*s))
-                   s--;
-               if (is_utf8_string((U8*)s, send - s)) {
-                   sv_setpvn(retval, s, send - s);
-                   *s = '\0';
-                   SvCUR_set(sv, s - start);
-                   SvNIOK_off(sv);
-                   SvUTF8_on(retval);
-               }
-           }
-           else
+        if (len && (!SvPOK(sv) || SvIsCOW(sv)))
+            s = SvPV_force_nomg(sv, len);
+        if (DO_UTF8(sv)) {
+            if (s && len) {
+                char * const send = s + len;
+                char * const start = s;
+                s = send - 1;
+                while (s > start && UTF8_IS_CONTINUATION(*s))
+                    s--;
+                if (is_utf8_string((U8*)s, send - s)) {
+                    sv_setpvn(retval, s, send - s);
+                    *s = '\0';
+                    SvCUR_set(sv, s - start);
+                    SvNIOK_off(sv);
+                    SvUTF8_on(retval);
+                }
+            }
+            else
                 SvPVCLEAR(retval);
-       }
-       else if (s && len) {
-           s += --len;
-           sv_setpvn(retval, s, 1);
-           *s = '\0';
-           SvCUR_set(sv, len);
-           SvUTF8_off(sv);
-           SvNIOK_off(sv);
-       }
-       else
+        }
+        else if (s && len) {
+            s += --len;
+            sv_setpvn(retval, s, 1);
+            *s = '\0';
+            SvCUR_set(sv, len);
+            SvUTF8_off(sv);
+            SvNIOK_off(sv);
+        }
+        else
             SvPVCLEAR(retval);
-       SvSETMAGIC(sv);
+        SvSETMAGIC(sv);
     }
     return count;
 }
@@ -852,7 +852,7 @@ PP(pp_schop)
 
     const size_t count = do_chomp(TARG, TOPs, chomping);
     if (chomping)
-       sv_setiv(TARG, count);
+        sv_setiv(TARG, count);
     SETTARG;
     return NORMAL;
 }
@@ -867,9 +867,9 @@ PP(pp_chop)
     size_t count = 0;
 
     while (MARK < SP)
-       count += do_chomp(TARG, *++MARK, chomping);
+        count += do_chomp(TARG, *++MARK, chomping);
     if (chomping)
-       sv_setiv(TARG, count);
+        sv_setiv(TARG, count);
     SP = ORIGMARK;
     XPUSHTARG;
     RETURN;
@@ -881,34 +881,34 @@ PP(pp_undef)
     SV *sv;
 
     if (!PL_op->op_private) {
-       EXTEND(SP, 1);
-       RETPUSHUNDEF;
+        EXTEND(SP, 1);
+        RETPUSHUNDEF;
     }
 
     sv = TOPs;
     if (!sv)
     {
-       SETs(&PL_sv_undef);
-       return NORMAL;
+        SETs(&PL_sv_undef);
+        return NORMAL;
     }
 
     if (SvTHINKFIRST(sv))
-       sv_force_normal_flags(sv, SV_COW_DROP_PV|SV_IMMEDIATE_UNREF);
+        sv_force_normal_flags(sv, SV_COW_DROP_PV|SV_IMMEDIATE_UNREF);
 
     switch (SvTYPE(sv)) {
     case SVt_NULL:
-       break;
+        break;
     case SVt_PVAV:
-       av_undef(MUTABLE_AV(sv));
-       break;
+        av_undef(MUTABLE_AV(sv));
+        break;
     case SVt_PVHV:
-       hv_undef(MUTABLE_HV(sv));
-       break;
+        hv_undef(MUTABLE_HV(sv));
+        break;
     case SVt_PVCV:
-       if (cv_const_sv((const CV *)sv))
-           Perl_ck_warner(aTHX_ packWARN(WARN_MISC),
+        if (cv_const_sv((const CV *)sv))
+            Perl_ck_warner(aTHX_ packWARN(WARN_MISC),
                           "Constant subroutine %" SVf " undefined",
-                          SVfARG(CvANON((const CV *)sv)
+                           SVfARG(CvANON((const CV *)sv)
                              ? newSVpvs_flags("(anonymous)", SVs_TEMP)
                              : sv_2mortal(newSVhek(
                                 CvNAMED(sv)
@@ -916,22 +916,22 @@ PP(pp_undef)
                                  : GvENAME_HEK(CvGV((const CV *)sv))
                                ))
                            ));
-       /* FALLTHROUGH */
+        /* FALLTHROUGH */
     case SVt_PVFM:
-           /* let user-undef'd sub keep its identity */
-       cv_undef_flags(MUTABLE_CV(sv), CV_UNDEF_KEEP_NAME);
-       break;
+            /* let user-undef'd sub keep its identity */
+        cv_undef_flags(MUTABLE_CV(sv), CV_UNDEF_KEEP_NAME);
+        break;
     case SVt_PVGV:
-       assert(isGV_with_GP(sv));
-       assert(!SvFAKE(sv));
-       {
-           GP *gp;
+        assert(isGV_with_GP(sv));
+        assert(!SvFAKE(sv));
+        {
+            GP *gp;
             HV *stash;
 
             /* undef *Pkg::meth_name ... */
             bool method_changed
              =   GvCVu((const GV *)sv) && (stash = GvSTASH((const GV *)sv))
-             && HvENAME_get(stash);
+              && HvENAME_get(stash);
             /* undef *Foo:: */
             if((stash = GvHV((const GV *)sv))) {
                 if(HvENAME_get(stash))
@@ -939,16 +939,16 @@ PP(pp_undef)
                 else stash = NULL;
             }
 
-           SvREFCNT_inc_simple_void_NN(sv_2mortal(sv));
-           gp_free(MUTABLE_GV(sv));
-           Newxz(gp, 1, GP);
-           GvGP_set(sv, gp_ref(gp));
+            SvREFCNT_inc_simple_void_NN(sv_2mortal(sv));
+            gp_free(MUTABLE_GV(sv));
+            Newxz(gp, 1, GP);
+            GvGP_set(sv, gp_ref(gp));
 #ifndef PERL_DONT_CREATE_GVSV
-           GvSV(sv) = newSV(0);
+            GvSV(sv) = newSV(0);
 #endif
-           GvLINE(sv) = CopLINE(PL_curcop);
-           GvEGV(sv) = MUTABLE_GV(sv);
-           GvMULTI_on(sv);
+            GvLINE(sv) = CopLINE(PL_curcop);
+            GvEGV(sv) = MUTABLE_GV(sv);
+            GvMULTI_on(sv);
 
             if(stash)
                 mro_package_moved(NULL, stash, (const GV *)sv, 0);
@@ -963,16 +963,16 @@ PP(pp_undef)
                  GvSTASH((const GV *)sv)
                 );
 
-           break;
-       }
+            break;
+        }
     default:
-       if (SvTYPE(sv) >= SVt_PV && SvPVX_const(sv) && SvLEN(sv)) {
-           SvPV_free(sv);
-           SvPV_set(sv, NULL);
-           SvLEN_set(sv, 0);
-       }
-       SvOK_off(sv);
-       SvSETMAGIC(sv);
+        if (SvTYPE(sv) >= SVt_PV && SvPVX_const(sv) && SvLEN(sv)) {
+            SvPV_free(sv);
+            SvPV_set(sv, NULL);
+            SvLEN_set(sv, 0);
+        }
+        SvOK_off(sv);
+        SvSETMAGIC(sv);
     }
 
     SETs(&PL_sv_undef);
@@ -987,19 +987,19 @@ S_postincdec_common(pTHX_ SV *sv, SV *targ)
 {
     dSP;
     const bool inc =
-       PL_op->op_type == OP_POSTINC || PL_op->op_type == OP_I_POSTINC;
+        PL_op->op_type == OP_POSTINC || PL_op->op_type == OP_I_POSTINC;
 
     if (SvROK(sv))
-       TARG = sv_newmortal();
+        TARG = sv_newmortal();
     sv_setsv(TARG, sv);
     if (inc)
-       sv_inc_nomg(sv);
+        sv_inc_nomg(sv);
     else
         sv_dec_nomg(sv);
     SvSETMAGIC(sv);
     /* special case for undef: see thread at 2003-03/msg00536.html in archive */
     if (inc && !SvOK(TARG))
-       sv_setiv(TARG, 0);
+        sv_setiv(TARG, 0);
     SETTARG;
     return NORMAL;
 }
@@ -1020,7 +1020,7 @@ PP(pp_postinc)
         && SvIVX(sv) != IV_MAX)
     {
         IV iv = SvIVX(sv);
-       SvIV_set(sv,  iv + 1);
+        SvIV_set(sv,  iv + 1);
         TARGi(iv, 0); /* arg not GMG, so can't be tainted */
         SETs(TARG);
         return NORMAL;
@@ -1045,7 +1045,7 @@ PP(pp_postdec)
         && SvIVX(sv) != IV_MIN)
     {
         IV iv = SvIVX(sv);
-       SvIV_set(sv,  iv - 1);
+        SvIV_set(sv,  iv - 1);
         TARGi(iv, 0); /* arg not GMG, so can't be tainted */
         SETs(TARG);
         return NORMAL;
@@ -1071,33 +1071,33 @@ PP(pp_pow)
        we're sure it is safe; otherwise we call pow() and try to convert to
        integer afterwards. */
     if (SvIV_please_nomg(svr) && SvIV_please_nomg(svl)) {
-               UV power;
-               bool baseuok;
-               UV baseuv;
-
-               if (SvUOK(svr)) {
-                   power = SvUVX(svr);
-               } else {
-                   const IV iv = SvIVX(svr);
-                   if (iv >= 0) {
-                       power = iv;
-                   } else {
-                       goto float_it; /* Can't do negative powers this way.  */
-                   }
-               }
-
-               baseuok = SvUOK(svl);
-               if (baseuok) {
-                   baseuv = SvUVX(svl);
-               } else {
-                   const IV iv = SvIVX(svl);
-                   if (iv >= 0) {
-                       baseuv = iv;
-                       baseuok = TRUE; /* effectively it's a UV now */
-                   } else {
-                       baseuv = -iv; /* abs, baseuok == false records sign */
-                   }
-               }
+                UV power;
+                bool baseuok;
+                UV baseuv;
+
+                if (SvUOK(svr)) {
+                    power = SvUVX(svr);
+                } else {
+                    const IV iv = SvIVX(svr);
+                    if (iv >= 0) {
+                        power = iv;
+                    } else {
+                        goto float_it; /* Can't do negative powers this way.  */
+                    }
+                }
+
+                baseuok = SvUOK(svl);
+                if (baseuok) {
+                    baseuv = SvUVX(svl);
+                } else {
+                    const IV iv = SvIVX(svl);
+                    if (iv >= 0) {
+                        baseuv = iv;
+                        baseuok = TRUE; /* effectively it's a UV now */
+                    } else {
+                        baseuv = -iv; /* abs, baseuok == false records sign */
+                    }
+                }
                 /* now we have integer ** positive integer. */
                 is_int = 1;
 
@@ -1114,67 +1114,67 @@ PP(pp_pow)
                     NV result = 1.0;
                     NV base = baseuok ? baseuv : -(NV)baseuv;
 
-                   if (power & 1) {
-                       result *= base;
-                   }
-                   while (power >>= 1) {
-                       base *= base;
-                       if (power & 1) {
-                           result *= base;
-                       }
-                   }
+                    if (power & 1) {
+                        result *= base;
+                    }
+                    while (power >>= 1) {
+                        base *= base;
+                        if (power & 1) {
+                            result *= base;
+                        }
+                    }
                     SP--;
                     SETn( result );
                     SvIV_please_nomg(svr);
                     RETURN;
-               } else {
-                   unsigned int highbit = 8 * sizeof(UV);
-                   unsigned int diff = 8 * sizeof(UV);
-                   while (diff >>= 1) {
-                       highbit -= diff;
-                       if (baseuv >> highbit) {
-                           highbit += diff;
-                       }
-                   }
-                   /* we now have baseuv < 2 ** highbit */
-                   if (power * highbit <= 8 * sizeof(UV)) {
-                       /* result will definitely fit in UV, so use UV math
-                          on same algorithm as above */
-                       UV result = 1;
-                       UV base = baseuv;
-                       const bool odd_power = cBOOL(power & 1);
-                       if (odd_power) {
-                           result *= base;
-                       }
-                       while (power >>= 1) {
-                           base *= base;
-                           if (power & 1) {
-                               result *= base;
-                           }
-                       }
-                       SP--;
-                       if (baseuok || !odd_power)
-                           /* answer is positive */
-                           SETu( result );
-                       else if (result <= (UV)IV_MAX)
-                           /* answer negative, fits in IV */
-                           SETi( -(IV)result );
-                       else if (result == (UV)IV_MIN)
-                           /* 2's complement assumption: special case IV_MIN */
-                           SETi( IV_MIN );
-                       else
-                           /* answer negative, doesn't fit */
-                           SETn( -(NV)result );
-                       RETURN;
-                   }
-               }
+                } else {
+                    unsigned int highbit = 8 * sizeof(UV);
+                    unsigned int diff = 8 * sizeof(UV);
+                    while (diff >>= 1) {
+                        highbit -= diff;
+                        if (baseuv >> highbit) {
+                            highbit += diff;
+                        }
+                    }
+                    /* we now have baseuv < 2 ** highbit */
+                    if (power * highbit <= 8 * sizeof(UV)) {
+                        /* result will definitely fit in UV, so use UV math
+                           on same algorithm as above */
+                        UV result = 1;
+                        UV base = baseuv;
+                        const bool odd_power = cBOOL(power & 1);
+                        if (odd_power) {
+                            result *= base;
+                        }
+                        while (power >>= 1) {
+                            base *= base;
+                            if (power & 1) {
+                                result *= base;
+                            }
+                        }
+                        SP--;
+                        if (baseuok || !odd_power)
+                            /* answer is positive */
+                            SETu( result );
+                        else if (result <= (UV)IV_MAX)
+                            /* answer negative, fits in IV */
+                            SETi( -(IV)result );
+                        else if (result == (UV)IV_MIN)
+                            /* 2's complement assumption: special case IV_MIN */
+                            SETi( IV_MIN );
+                        else
+                            /* answer negative, doesn't fit */
+                            SETn( -(NV)result );
+                        RETURN;
+                    }
+                }
     }
   float_it:
 #endif
     {
-       NV right = SvNV_nomg(svr);
-       NV left  = SvNV_nomg(svl);
-       (void)POPs;
+        NV right = SvNV_nomg(svr);
+        NV left  = SvNV_nomg(svl);
+        (void)POPs;
 
 #if defined(USE_LONG_DOUBLE) && defined(HAS_AIX_POWL_NEG_BASE_BUG)
     /*
@@ -1184,43 +1184,43 @@ PP(pp_pow)
     03/06/2006.  The problem exists in at least the following versions
     of AIX and the libm fileset, and no doubt others as well:
 
-       AIX 4.3.3-ML10      bos.adt.libm 4.3.3.50
-       AIX 5.1.0-ML04      bos.adt.libm 5.1.0.29
-       AIX 5.2.0           bos.adt.libm 5.2.0.85
+        AIX 4.3.3-ML10      bos.adt.libm 4.3.3.50
+        AIX 5.1.0-ML04      bos.adt.libm 5.1.0.29
+        AIX 5.2.0           bos.adt.libm 5.2.0.85
 
     So, until IBM fixes powl(), we provide the following workaround to
     handle the problem ourselves.  Our logic is as follows: for
     negative bases (left), we use fmod(right, 2) to check if the
     exponent is an odd or even integer:
 
-       - if odd,  powl(left, right) == -powl(-left, right)
-       - if even, powl(left, right) ==  powl(-left, right)
+        - if odd,  powl(left, right) == -powl(-left, right)
+        - if even, powl(left, right) ==  powl(-left, right)
 
     If the exponent is not an integer, the result is rightly NaNQ, so
     we just return that (as NV_NAN).
     */
 
-       if (left < 0.0) {
-           NV mod2 = Perl_fmod( right, 2.0 );
-           if (mod2 == 1.0 || mod2 == -1.0) {  /* odd integer */
-               SETn( -Perl_pow( -left, right) );
-           } else if (mod2 == 0.0) {           /* even integer */
-               SETn( Perl_pow( -left, right) );
-           } else {                            /* fractional power */
-               SETn( NV_NAN );
-           }
-       } else {
-           SETn( Perl_pow( left, right) );
-       }
+        if (left < 0.0) {
+            NV mod2 = Perl_fmod( right, 2.0 );
+            if (mod2 == 1.0 || mod2 == -1.0) { /* odd integer */
+                SETn( -Perl_pow( -left, right) );
+            } else if (mod2 == 0.0) {          /* even integer */
+                SETn( Perl_pow( -left, right) );
+            } else {                           /* fractional power */
+                SETn( NV_NAN );
+            }
+        } else {
+            SETn( Perl_pow( left, right) );
+        }
 #else
-       SETn( Perl_pow( left, right) );
+        SETn( Perl_pow( left, right) );
 #endif  /* HAS_AIX_POWL_NEG_BASE_BUG */
 
 #ifdef PERL_PRESERVE_IVUV
-       if (is_int)
-           SvIV_please_nomg(svr);
+        if (is_int)
+            SvIV_please_nomg(svr);
 #endif
-       RETURN;
+        RETURN;
     }
 }
 
@@ -1268,16 +1268,10 @@ PP(pp_multiply)
             NV nr = SvNVX(svr);
             NV result;
 
-            if (
-#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
-                !Perl_isnan(nl) && nl == (NV)(il = (IV)nl)
-                && !Perl_isnan(nr) && nr == (NV)(ir = (IV)nr)
-#else
-                nl == (NV)(il = (IV)nl) && nr == (NV)(ir = (IV)nr)
-#endif
-                )
+            if (lossless_NV_to_IV(nl, &il) && lossless_NV_to_IV(nr, &ir)) {
                 /* nothing was lost by converting to IVs */
                 goto do_iv;
+            }
             SP--;
             result = nl * nr;
 #  if defined(__sgi) && defined(USE_LONG_DOUBLE) && LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BE_BE && NVSIZE == 16
@@ -1294,116 +1288,117 @@ PP(pp_multiply)
   generic:
 
     if (SvIV_please_nomg(svr)) {
-       /* Unless the left argument is integer in range we are going to have to
-          use NV maths. Hence only attempt to coerce the right argument if
-          we know the left is integer.  */
-       /* Left operand is defined, so is it IV? */
-       if (SvIV_please_nomg(svl)) {
-           bool auvok = SvUOK(svl);
-           bool buvok = SvUOK(svr);
-           const UV topmask = (~ (UV)0) << (4 * sizeof (UV));
-           const UV botmask = ~((~ (UV)0) << (4 * sizeof (UV)));
-           UV alow;
-           UV ahigh;
-           UV blow;
-           UV bhigh;
-
-           if (auvok) {
-               alow = SvUVX(svl);
-           } else {
-               const IV aiv = SvIVX(svl);
-               if (aiv >= 0) {
-                   alow = aiv;
-                   auvok = TRUE; /* effectively it's a UV now */
-               } else {
-                    /* abs, auvok == false records sign */
-                   alow = -(UV)aiv;
-               }
-           }
-           if (buvok) {
-               blow = SvUVX(svr);
-           } else {
-               const IV biv = SvIVX(svr);
-               if (biv >= 0) {
-                   blow = biv;
-                   buvok = TRUE; /* effectively it's a UV now */
-               } else {
+        /* Unless the left argument is integer in range we are going to have to
+           use NV maths. Hence only attempt to coerce the right argument if
+           we know the left is integer.  */
+        /* Left operand is defined, so is it IV? */
+        if (SvIV_please_nomg(svl)) {
+            bool auvok = SvUOK(svl);
+            bool buvok = SvUOK(svr);
+            const UV topmask = (~ (UV)0) << (4 * sizeof (UV));
+            const UV botmask = ~((~ (UV)0) << (4 * sizeof (UV)));
+            UV alow;
+            UV ahigh;
+            UV blow;
+            UV bhigh;
+
+            if (auvok) {
+                alow = SvUVX(svl);
+            } else {
+                const IV aiv = SvIVX(svl);
+                if (aiv >= 0) {
+                    alow = aiv;
+                    auvok = TRUE; /* effectively it's a UV now */
+                } else {
+                    /* abs, auvok == false records sign; Using 0- here and
+                     * later to silence bogus warning from MS VC */
+                    alow = (UV) (0 - (UV) aiv);
+                }
+            }
+            if (buvok) {
+                blow = SvUVX(svr);
+            } else {
+                const IV biv = SvIVX(svr);
+                if (biv >= 0) {
+                    blow = biv;
+                    buvok = TRUE; /* effectively it's a UV now */
+                } else {
                     /* abs, buvok == false records sign */
-                   blow = -(UV)biv;
-               }
-           }
-
-           /* If this does sign extension on unsigned it's time for plan B  */
-           ahigh = alow >> (4 * sizeof (UV));
-           alow &= botmask;
-           bhigh = blow >> (4 * sizeof (UV));
-           blow &= botmask;
-           if (ahigh && bhigh) {
-               NOOP;
-               /* eg 32 bit is at least 0x10000 * 0x10000 == 0x100000000
-                  which is overflow. Drop to NVs below.  */
-           } else if (!ahigh && !bhigh) {
-               /* eg 32 bit is at most 0xFFFF * 0xFFFF == 0xFFFE0001
-                  so the unsigned multiply cannot overflow.  */
-               const UV product = alow * blow;
-               if (auvok == buvok) {
-                   /* -ve * -ve or +ve * +ve gives a +ve result.  */
-                   SP--;
-                   SETu( product );
-                   RETURN;
-               } else if (product <= (UV)IV_MIN) {
-                   /* 2s complement assumption that (UV)-IV_MIN is correct.  */
-                   /* -ve result, which could overflow an IV  */
-                   SP--;
+                    blow = (UV) (0 - (UV) biv);
+                }
+            }
+
+            /* If this does sign extension on unsigned it's time for plan B  */
+            ahigh = alow >> (4 * sizeof (UV));
+            alow &= botmask;
+            bhigh = blow >> (4 * sizeof (UV));
+            blow &= botmask;
+            if (ahigh && bhigh) {
+                NOOP;
+                /* eg 32 bit is at least 0x10000 * 0x10000 == 0x100000000
+                   which is overflow. Drop to NVs below.  */
+            } else if (!ahigh && !bhigh) {
+                /* eg 32 bit is at most 0xFFFF * 0xFFFF == 0xFFFE0001
+                   so the unsigned multiply cannot overflow.  */
+                const UV product = alow * blow;
+                if (auvok == buvok) {
+                    /* -ve * -ve or +ve * +ve gives a +ve result.  */
+                    SP--;
+                    SETu( product );
+                    RETURN;
+                } else if (product <= (UV)IV_MIN) {
+                    /* 2s complement assumption that (UV)-IV_MIN is correct.  */
+                    /* -ve result, which could overflow an IV  */
+                    SP--;
                     /* can't negate IV_MIN, but there are aren't two
                      * integers such that !ahigh && !bhigh, where the
                      * product equals 0x800....000 */
                     assert(product != (UV)IV_MIN);
-                   SETi( -(IV)product );
-                   RETURN;
-               } /* else drop to NVs below. */
-           } else {
-               /* One operand is large, 1 small */
-               UV product_middle;
-               if (bhigh) {
-                   /* swap the operands */
-                   ahigh = bhigh;
-                   bhigh = blow; /* bhigh now the temp var for the swap */
-                   blow = alow;
-                   alow = bhigh;
-               }
-               /* now, ((ahigh * blow) << half_UV_len) + (alow * blow)
-                  multiplies can't overflow. shift can, add can, -ve can.  */
-               product_middle = ahigh * blow;
-               if (!(product_middle & topmask)) {
-                   /* OK, (ahigh * blow) won't lose bits when we shift it.  */
-                   UV product_low;
-                   product_middle <<= (4 * sizeof (UV));
-                   product_low = alow * blow;
-
-                   /* as for pp_add, UV + something mustn't get smaller.
-                      IIRC ANSI mandates this wrapping *behaviour* for
-                      unsigned whatever the actual representation*/
-                   product_low += product_middle;
-                   if (product_low >= product_middle) {
-                       /* didn't overflow */
-                       if (auvok == buvok) {
-                           /* -ve * -ve or +ve * +ve gives a +ve result.  */
-                           SP--;
-                           SETu( product_low );
-                           RETURN;
-                       } else if (product_low <= (UV)IV_MIN) {
-                           /* 2s complement assumption again  */
-                           /* -ve result, which could overflow an IV  */
-                           SP--;
-                           SETi(product_low == (UV)IV_MIN
+                    SETi( -(IV)product );
+                    RETURN;
+                } /* else drop to NVs below. */
+            } else {
+                /* One operand is large, 1 small */
+                UV product_middle;
+                if (bhigh) {
+                    /* swap the operands */
+                    ahigh = bhigh;
+                    bhigh = blow; /* bhigh now the temp var for the swap */
+                    blow = alow;
+                    alow = bhigh;
+                }
+                /* now, ((ahigh * blow) << half_UV_len) + (alow * blow)
+                   multiplies can't overflow. shift can, add can, -ve can.  */
+                product_middle = ahigh * blow;
+                if (!(product_middle & topmask)) {
+                    /* OK, (ahigh * blow) won't lose bits when we shift it.  */
+                    UV product_low;
+                    product_middle <<= (4 * sizeof (UV));
+                    product_low = alow * blow;
+
+                    /* as for pp_add, UV + something mustn't get smaller.
+                       IIRC ANSI mandates this wrapping *behaviour* for
+                       unsigned whatever the actual representation*/
+                    product_low += product_middle;
+                    if (product_low >= product_middle) {
+                        /* didn't overflow */
+                        if (auvok == buvok) {
+                            /* -ve * -ve or +ve * +ve gives a +ve result.  */
+                            SP--;
+                            SETu( product_low );
+                            RETURN;
+                        } else if (product_low <= (UV)IV_MIN) {
+                            /* 2s complement assumption again  */
+                            /* -ve result, which could overflow an IV  */
+                            SP--;
+                            SETi(product_low == (UV)IV_MIN
                                     ? IV_MIN : -(IV)product_low);
-                           RETURN;
-                       } /* else drop to NVs below. */
-                   }
-               } /* product_middle too large */
-           } /* ahigh && bhigh */
-       } /* SvIOK(svl) */
+                            RETURN;
+                        } /* else drop to NVs below. */
+                    }
+                } /* product_middle too large */
+            } /* ahigh && bhigh */
+        } /* SvIOK(svl) */
     } /* SvIOK(svr) */
 #endif
     {
@@ -1453,13 +1448,13 @@ PP(pp_divide)
             if (right_non_neg) {
                 right = SvUVX(svr);
             }
-           else {
-               const IV biv = SvIVX(svr);
+            else {
+                const IV biv = SvIVX(svr);
                 if (biv >= 0) {
                     right = biv;
                     right_non_neg = TRUE; /* effectively it's a UV now */
                 }
-               else {
+                else {
                     right = -(UV)biv;
                 }
             }
@@ -1474,13 +1469,13 @@ PP(pp_divide)
             if (left_non_neg) {
                 left = SvUVX(svl);
             }
-           else {
-               const IV aiv = SvIVX(svl);
+            else {
+                const IV aiv = SvIVX(svl);
                 if (aiv >= 0) {
                     left = aiv;
                     left_non_neg = TRUE; /* effectively it's a UV now */
                 }
-               else {
+                else {
                     left = -(UV)aiv;
                 }
             }
@@ -1504,7 +1499,7 @@ PP(pp_divide)
 
                 /* Modern compilers optimize division followed by
                  * modulo into a single div instruction */
-               const UV result = left / right;
+                const UV result = left / right;
                 if (left % right == 0) {
                     SP--; /* result is valid */
                     if (left_non_neg == right_non_neg) {
@@ -1525,17 +1520,17 @@ PP(pp_divide)
     } /* one operand wasn't SvIOK */
 #endif /* PERL_TRY_UV_DIVIDE */
     {
-       NV right = SvNV_nomg(svr);
-       NV left  = SvNV_nomg(svl);
-       (void)POPs;(void)POPs;
+        NV right = SvNV_nomg(svr);
+        NV left  = SvNV_nomg(svl);
+        (void)POPs;(void)POPs;
 #if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
-       if (! Perl_isnan(right) && right == 0.0)
+        if (! Perl_isnan(right) && right == 0.0)
 #else
-       if (right == 0.0)
+        if (right == 0.0)
 #endif
-           DIE(aTHX_ "Illegal division by zero");
-       PUSHn( left / right );
-       RETURN;
+            DIE(aTHX_ "Illegal division by zero");
+        PUSHn( left / right );
+        RETURN;
     }
 }
 
@@ -1544,69 +1539,69 @@ PP(pp_modulo)
     dSP; dATARGET;
     tryAMAGICbin_MG(modulo_amg, AMGf_assign|AMGf_numeric);
     {
-       UV left  = 0;
-       UV right = 0;
-       bool left_neg = FALSE;
-       bool right_neg = FALSE;
-       bool use_double = FALSE;
-       bool dright_valid = FALSE;
-       NV dright = 0.0;
-       NV dleft  = 0.0;
-       SV * const svr = TOPs;
-       SV * const svl = TOPm1s;
+        UV left  = 0;
+        UV right = 0;
+        bool left_neg = FALSE;
+        bool right_neg = FALSE;
+        bool use_double = FALSE;
+        bool dright_valid = FALSE;
+        NV dright = 0.0;
+        NV dleft  = 0.0;
+        SV * const svr = TOPs;
+        SV * const svl = TOPm1s;
         if (SvIV_please_nomg(svr)) {
             right_neg = !SvUOK(svr);
             if (!right_neg) {
                 right = SvUVX(svr);
             } else {
-               const IV biv = SvIVX(svr);
+                const IV biv = SvIVX(svr);
                 if (biv >= 0) {
                     right = biv;
                     right_neg = FALSE; /* effectively it's a UV now */
                 } else {
-                    right = -(UV)biv;
+                    right = (UV) (0 - (UV) biv);
                 }
             }
         }
         else {
-           dright = SvNV_nomg(svr);
-           right_neg = dright < 0;
-           if (right_neg)
-               dright = -dright;
+            dright = SvNV_nomg(svr);
+            right_neg = dright < 0;
+            if (right_neg)
+                dright = -dright;
             if (dright < UV_MAX_P1) {
                 right = U_V(dright);
                 dright_valid = TRUE; /* In case we need to use double below.  */
             } else {
                 use_double = TRUE;
             }
-       }
+        }
 
         /* At this point use_double is only true if right is out of range for
            a UV.  In range NV has been rounded down to nearest UV and
            use_double false.  */
-       if (!use_double && SvIV_please_nomg(svl)) {
+        if (!use_double && SvIV_please_nomg(svl)) {
                 left_neg = !SvUOK(svl);
                 if (!left_neg) {
                     left = SvUVX(svl);
                 } else {
-                   const IV aiv = SvIVX(svl);
+                    const IV aiv = SvIVX(svl);
                     if (aiv >= 0) {
                         left = aiv;
                         left_neg = FALSE; /* effectively it's a UV now */
                     } else {
-                        left = -(UV)aiv;
+                        left = (UV) (0 - (UV) aiv);
                     }
                 }
         }
-       else {
-           dleft = SvNV_nomg(svl);
-           left_neg = dleft < 0;
-           if (left_neg)
-               dleft = -dleft;
+        else {
+            dleft = SvNV_nomg(svl);
+            left_neg = dleft < 0;
+            if (left_neg)
+                dleft = -dleft;
 
             /* This should be exactly the 5.6 behaviour - if left and right are
                both in range for UV then use U_V() rather than floor.  */
-           if (!use_double) {
+            if (!use_double) {
                 if (dleft < UV_MAX_P1) {
                     /* right was in range, so is dleft, so use UVs not double.
                      */
@@ -1627,42 +1622,42 @@ PP(pp_modulo)
                 }
             }
         }
-       sp -= 2;
-       if (use_double) {
-           NV dans;
-
-           if (!dright)
-               DIE(aTHX_ "Illegal modulus zero");
-
-           dans = Perl_fmod(dleft, dright);
-           if ((left_neg != right_neg) && dans)
-               dans = dright - dans;
-           if (right_neg)
-               dans = -dans;
-           sv_setnv(TARG, dans);
-       }
-       else {
-           UV ans;
-
-           if (!right)
-               DIE(aTHX_ "Illegal modulus zero");
-
-           ans = left % right;
-           if ((left_neg != right_neg) && ans)
-               ans = right - ans;
-           if (right_neg) {
-               /* XXX may warn: unary minus operator applied to unsigned type */
-               /* could change -foo to be (~foo)+1 instead     */
-               if (ans <= ~((UV)IV_MAX)+1)
-                   sv_setiv(TARG, ~ans+1);
-               else
-                   sv_setnv(TARG, -(NV)ans);
-           }
-           else
-               sv_setuv(TARG, ans);
-       }
-       PUSHTARG;
-       RETURN;
+        sp -= 2;
+        if (use_double) {
+            NV dans;
+
+            if (!dright)
+                DIE(aTHX_ "Illegal modulus zero");
+
+            dans = Perl_fmod(dleft, dright);
+            if ((left_neg != right_neg) && dans)
+                dans = dright - dans;
+            if (right_neg)
+                dans = -dans;
+            sv_setnv(TARG, dans);
+        }
+        else {
+            UV ans;
+
+            if (!right)
+                DIE(aTHX_ "Illegal modulus zero");
+
+            ans = left % right;
+            if ((left_neg != right_neg) && ans)
+                ans = right - ans;
+            if (right_neg) {
+                /* XXX may warn: unary minus operator applied to unsigned type */
+                /* could change -foo to be (~foo)+1 instead    */
+                if (ans <= ~((UV)IV_MAX)+1)
+                    sv_setiv(TARG, ~ans+1);
+                else
+                    sv_setnv(TARG, -(NV)ans);
+            }
+            else
+                sv_setuv(TARG, ans);
+        }
+        PUSHTARG;
+        RETURN;
     }
 }
 
@@ -1674,46 +1669,46 @@ PP(pp_repeat)
     bool infnan = FALSE;
     const U8 gimme = GIMME_V;
 
-    if (gimme == G_ARRAY && PL_op->op_private & OPpREPEAT_DOLIST) {
-       /* TODO: think of some way of doing list-repeat overloading ??? */
-       sv = POPs;
-       SvGETMAGIC(sv);
+    if (gimme == G_LIST && PL_op->op_private & OPpREPEAT_DOLIST) {
+        /* TODO: think of some way of doing list-repeat overloading ??? */
+        sv = POPs;
+        SvGETMAGIC(sv);
     }
     else {
-       if (UNLIKELY(PL_op->op_private & OPpREPEAT_DOLIST)) {
-           /* The parser saw this as a list repeat, and there
-              are probably several items on the stack. But we're
-              in scalar/void context, and there's no pp_list to save us
-              now. So drop the rest of the items -- robin@kitsite.com
-            */
-           dMARK;
-           if (MARK + 1 < SP) {
-               MARK[1] = TOPm1s;
-               MARK[2] = TOPs;
-           }
-           else {
-               dTOPss;
-               ASSUME(MARK + 1 == SP);
+        if (UNLIKELY(PL_op->op_private & OPpREPEAT_DOLIST)) {
+            /* The parser saw this as a list repeat, and there
+               are probably several items on the stack. But we're
+               in scalar/void context, and there's no pp_list to save us
+               now. So drop the rest of the items -- robin@kitsite.com
+             */
+            dMARK;
+            if (MARK + 1 < SP) {
+                MARK[1] = TOPm1s;
+                MARK[2] = TOPs;
+            }
+            else {
+                dTOPss;
+                ASSUME(MARK + 1 == SP);
                 MEXTEND(SP, 1);
                 PUSHs(sv);
-               MARK[1] = &PL_sv_undef;
-           }
-           SP = MARK + 2;
-       }
-       tryAMAGICbin_MG(repeat_amg, AMGf_assign);
-       sv = POPs;
+                MARK[1] = &PL_sv_undef;
+            }
+            SP = MARK + 2;
+        }
+        tryAMAGICbin_MG(repeat_amg, AMGf_assign);
+        sv = POPs;
     }
 
     if (SvIOKp(sv)) {
-        if (SvUOK(sv)) {
-             const UV uv = SvUV_nomg(sv);
-             if (uv > IV_MAX)
-                  count = IV_MAX; /* The best we can do? */
-             else
-                  count = uv;
-        } else {
-             count = SvIV_nomg(sv);
-        }
+         if (SvUOK(sv)) {
+              const UV uv = SvUV_nomg(sv);
+              if (uv > IV_MAX)
+                   count = IV_MAX; /* The best we can do? */
+              else
+                   count = uv;
+         } else {
+              count = SvIV_nomg(sv);
+         }
     }
     else if (SvNOKp(sv)) {
         const NV nv = SvNV_nomg(sv);
@@ -1728,7 +1723,7 @@ PP(pp_repeat)
         }
     }
     else
-       count = SvIV_nomg(sv);
+        count = SvIV_nomg(sv);
 
     if (infnan) {
         Perl_ck_warner(aTHX_ packWARN(WARN_NUMERIC),
@@ -1739,13 +1734,13 @@ PP(pp_repeat)
                        "Negative repeat count does nothing");
     }
 
-    if (gimme == G_ARRAY && PL_op->op_private & OPpREPEAT_DOLIST) {
-       dMARK;
-       const SSize_t items = SP - MARK;
-       const U8 mod = PL_op->op_flags & OPf_MOD;
+    if (gimme == G_LIST && PL_op->op_private & OPpREPEAT_DOLIST) {
+        dMARK;
+        const SSize_t items = SP - MARK;
+        const U8 mod = PL_op->op_flags & OPf_MOD;
 
-       if (count > 1) {
-           SSize_t max;
+        if (count > 1) {
+            SSize_t max;
 
             if (  items > SSize_t_MAX / count   /* max would overflow */
                                                 /* repeatcpy would overflow */
@@ -1755,57 +1750,57 @@ PP(pp_repeat)
             max = items * count;
             MEXTEND(MARK, max);
 
-           while (SP > MARK) {
+            while (SP > MARK) {
                 if (*SP) {
                    if (mod && SvPADTMP(*SP)) {
                        *SP = sv_mortalcopy(*SP);
                    }
-                  SvTEMP_off((*SP));
-               }
-               SP--;
-           }
-           MARK++;
-           repeatcpy((char*)(MARK + items), (char*)MARK,
-               items * sizeof(const SV *), count - 1);
-           SP += max;
-       }
-       else if (count <= 0)
-           SP = MARK;
+                   SvTEMP_off((*SP));
+                }
+                SP--;
+            }
+            MARK++;
+            repeatcpy((char*)(MARK + items), (char*)MARK,
+                items * sizeof(const SV *), count - 1);
+            SP += max;
+        }
+        else if (count <= 0)
+            SP = MARK;
     }
     else {     /* Note: mark already snarfed by pp_list */
-       SV * const tmpstr = POPs;
-       STRLEN len;
-       bool isutf;
-
-       if (TARG != tmpstr)
-           sv_setsv_nomg(TARG, tmpstr);
-       SvPV_force_nomg(TARG, len);
-       isutf = DO_UTF8(TARG);
-       if (count != 1) {
-           if (count < 1)
-               SvCUR_set(TARG, 0);
-           else {
-               STRLEN max;
-
-               if (   len > (MEM_SIZE_MAX-1) / (UV)count /* max would overflow */
-                   || len > (U32)I32_MAX  /* repeatcpy would overflow */
+        SV * const tmpstr = POPs;
+        STRLEN len;
+        bool isutf;
+
+        if (TARG != tmpstr)
+            sv_setsv_nomg(TARG, tmpstr);
+        SvPV_force_nomg(TARG, len);
+        isutf = DO_UTF8(TARG);
+        if (count != 1) {
+            if (count < 1)
+                SvCUR_set(TARG, 0);
+            else {
+                STRLEN max;
+
+                if (   len > (MEM_SIZE_MAX-1) / (UV)count /* max would overflow */
+                    || len > (U32)I32_MAX  /* repeatcpy would overflow */
                 )
-                    Perl_croak(aTHX_ "%s",
+                     Perl_croak(aTHX_ "%s",
                                         "Out of memory during string extend");
-               max = (UV)count * len + 1;
-               SvGROW(TARG, max);
+                max = (UV)count * len + 1;
+                SvGROW(TARG, max);
 
-               repeatcpy(SvPVX(TARG) + len, SvPVX(TARG), len, count - 1);
-               SvCUR_set(TARG, SvCUR(TARG) * count);
-           }
-           *SvEND(TARG) = '\0';
-       }
-       if (isutf)
-           (void)SvPOK_only_UTF8(TARG);
-       else
-           (void)SvPOK_only(TARG);
+                repeatcpy(SvPVX(TARG) + len, SvPVX(TARG), len, count - 1);
+                SvCUR_set(TARG, SvCUR(TARG) * count);
+            }
+            *SvEND(TARG) = '\0';
+        }
+        if (isutf)
+            (void)SvPOK_only_UTF8(TARG);
+        else
+            (void)SvPOK_only(TARG);
 
-       PUSHTARG;
+        PUSHTARG;
     }
     RETURN;
 }
@@ -1848,16 +1843,10 @@ PP(pp_subtract)
             NV nl = SvNVX(svl);
             NV nr = SvNVX(svr);
 
-            if (
-#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
-                !Perl_isnan(nl) && nl == (NV)(il = (IV)nl)
-                && !Perl_isnan(nr) && nr == (NV)(ir = (IV)nr)
-#else
-                nl == (NV)(il = (IV)nl) && nr == (NV)(ir = (IV)nr)
-#endif
-                )
+            if (lossless_NV_to_IV(nl, &il) && lossless_NV_to_IV(nr, &ir)) {
                 /* nothing was lost by converting to IVs */
                 goto do_iv;
+            }
             SP--;
             TARGn(nl - nr, 0); /* args not GMG, so can't be tainted */
             SETs(TARG);
@@ -1871,126 +1860,142 @@ PP(pp_subtract)
     /* See comments in pp_add (in pp_hot.c) about Overflow, and how
        "bad things" happen if you rely on signed integers wrapping.  */
     if (SvIV_please_nomg(svr)) {
-       /* Unless the left argument is integer in range we are going to have to
-          use NV maths. Hence only attempt to coerce the right argument if
-          we know the left is integer.  */
-       UV auv = 0;
-       bool auvok = FALSE;
-       bool a_valid = 0;
-
-       if (!useleft) {
-           auv = 0;
-           a_valid = auvok = 1;
-           /* left operand is undef, treat as zero.  */
-       } else {
-           /* Left operand is defined, so is it IV? */
-           if (SvIV_please_nomg(svl)) {
-               if ((auvok = SvUOK(svl)))
-                   auv = SvUVX(svl);
-               else {
-                   const IV aiv = SvIVX(svl);
-                   if (aiv >= 0) {
-                       auv = aiv;
-                       auvok = 1;      /* Now acting as a sign flag.  */
-                   } else {
-                       auv = -(UV)aiv;
-                   }
-               }
-               a_valid = 1;
-           }
-       }
-       if (a_valid) {
-           bool result_good = 0;
-           UV result;
-           UV buv;
-           bool buvok = SvUOK(svr);
-
-           if (buvok)
-               buv = SvUVX(svr);
-           else {
-               const IV biv = SvIVX(svr);
-               if (biv >= 0) {
-                   buv = biv;
-                   buvok = 1;
-               } else
-                    buv = -(UV)biv;
-           }
-           /* ?uvok if value is >= 0. basically, flagged as UV if it's +ve,
-              else "IV" now, independent of how it came in.
-              if a, b represents positive, A, B negative, a maps to -A etc
-              a - b =>  (a - b)
-              A - b => -(a + b)
-              a - B =>  (a + b)
-              A - B => -(a - b)
-              all UV maths. negate result if A negative.
-              subtract if signs same, add if signs differ. */
-
-           if (auvok ^ buvok) {
-               /* Signs differ.  */
-               result = auv + buv;
-               if (result >= auv)
-                   result_good = 1;
-           } else {
-               /* Signs same */
-               if (auv >= buv) {
-                   result = auv - buv;
-                   /* Must get smaller */
-                   if (result <= auv)
-                       result_good = 1;
-               } else {
-                   result = buv - auv;
-                   if (result <= buv) {
-                       /* result really should be -(auv-buv). as its negation
-                          of true value, need to swap our result flag  */
-                       auvok = !auvok;
-                       result_good = 1;
-                   }
-               }
-           }
-           if (result_good) {
-               SP--;
-               if (auvok)
-                   SETu( result );
-               else {
-                   /* Negate result */
-                   if (result <= (UV)IV_MIN)
+        /* Unless the left argument is integer in range we are going to have to
+           use NV maths. Hence only attempt to coerce the right argument if
+           we know the left is integer.  */
+        UV auv = 0;
+        bool auvok = FALSE;
+        bool a_valid = 0;
+
+        if (!useleft) {
+            auv = 0;
+            a_valid = auvok = 1;
+            /* left operand is undef, treat as zero.  */
+        } else {
+            /* Left operand is defined, so is it IV? */
+            if (SvIV_please_nomg(svl)) {
+                if ((auvok = SvUOK(svl)))
+                    auv = SvUVX(svl);
+                else {
+                    const IV aiv = SvIVX(svl);
+                    if (aiv >= 0) {
+                        auv = aiv;
+                        auvok = 1;     /* Now acting as a sign flag.  */
+                    } else {
+                        auv = (UV) (0 - (UV) aiv);
+                    }
+                }
+                a_valid = 1;
+            }
+        }
+        if (a_valid) {
+            bool result_good = 0;
+            UV result;
+            UV buv;
+            bool buvok = SvUOK(svr);
+
+            if (buvok)
+                buv = SvUVX(svr);
+            else {
+                const IV biv = SvIVX(svr);
+                if (biv >= 0) {
+                    buv = biv;
+                    buvok = 1;
+                } else
+                    buv = (UV) (0 - (UV) biv);
+            }
+            /* ?uvok if value is >= 0. basically, flagged as UV if it's +ve,
+               else "IV" now, independent of how it came in.
+               if a, b represents positive, A, B negative, a maps to -A etc
+               a - b =>  (a - b)
+               A - b => -(a + b)
+               a - B =>  (a + b)
+               A - B => -(a - b)
+               all UV maths. negate result if A negative.
+               subtract if signs same, add if signs differ. */
+
+            if (auvok ^ buvok) {
+                /* Signs differ.  */
+                result = auv + buv;
+                if (result >= auv)
+                    result_good = 1;
+            } else {
+                /* Signs same */
+                if (auv >= buv) {
+                    result = auv - buv;
+                    /* Must get smaller */
+                    if (result <= auv)
+                        result_good = 1;
+                } else {
+                    result = buv - auv;
+                    if (result <= buv) {
+                        /* result really should be -(auv-buv). as its negation
+                           of true value, need to swap our result flag  */
+                        auvok = !auvok;
+                        result_good = 1;
+                    }
+                }
+            }
+            if (result_good) {
+                SP--;
+                if (auvok)
+                    SETu( result );
+                else {
+                    /* Negate result */
+                    if (result <= (UV)IV_MIN)
                         SETi(result == (UV)IV_MIN
                                 ? IV_MIN : -(IV)result);
-                   else {
-                       /* result valid, but out of range for IV.  */
-                       SETn( -(NV)result );
-                   }
-               }
-               RETURN;
-           } /* Overflow, drop through to NVs.  */
-       }
+                    else {
+                        /* result valid, but out of range for IV.  */
+                        SETn( -(NV)result );
+                    }
+                }
+                RETURN;
+            } /* Overflow, drop through to NVs.  */
+        }
     }
 #else
     useleft = USE_LEFT(svl);
 #endif
     {
-       NV value = SvNV_nomg(svr);
-       (void)POPs;
+        NV value = SvNV_nomg(svr);
+        (void)POPs;
 
-       if (!useleft) {
-           /* left operand is undef, treat as zero - value */
-           SETn(-value);
-           RETURN;
-       }
-       SETn( SvNV_nomg(svl) - value );
-       RETURN;
+        if (!useleft) {
+            /* left operand is undef, treat as zero - value */
+            SETn(-value);
+            RETURN;
+        }
+        SETn( SvNV_nomg(svl) - value );
+        RETURN;
     }
 }
 
 #define IV_BITS (IVSIZE * 8)
 
+/* Taking the right operand of bitwise shift operators, returns an int
+ * indicating the shift amount clipped to the range [-IV_BITS, +IV_BITS].
+ */
+static int
+S_shift_amount(pTHX_ SV *const svr)
+{
+    const IV iv = SvIV_nomg(svr);
+
+    /* Note that [INT_MIN, INT_MAX] cannot be used as the clipping bound;
+     * INT_MIN will cause overflow in "shift = -shift;" in S_{iv,uv}_shift.
+     */
+    if (SvIsUV(svr))
+        return SvUVX(svr) > IV_BITS ? IV_BITS : (int)SvUVX(svr);
+    return iv < -IV_BITS ? -IV_BITS : iv > IV_BITS ? IV_BITS : (int)iv;
+}
+
 static UV S_uv_shift(UV uv, int shift, bool left)
 {
    if (shift < 0) {
        shift = -shift;
        left = !left;
    }
-   if (shift >= IV_BITS) {
+   if (UNLIKELY(shift >= IV_BITS)) {
        return 0;
    }
    return left ? uv << shift : uv >> shift;
@@ -1998,14 +2003,31 @@ static UV S_uv_shift(UV uv, int shift, bool left)
 
 static IV S_iv_shift(IV iv, int shift, bool left)
 {
-   if (shift < 0) {
-       shift = -shift;
-       left = !left;
-   }
-   if (shift >= IV_BITS) {
-       return iv < 0 && !left ? -1 : 0;
-   }
-   return left ? iv << shift : iv >> shift;
+    if (shift < 0) {
+        shift = -shift;
+        left = !left;
+    }
+
+    if (UNLIKELY(shift >= IV_BITS)) {
+        return iv < 0 && !left ? -1 : 0;
+    }
+
+    /* For left shifts, perl 5 has chosen to treat the value as unsigned for
+     * the purposes of shifting, then cast back to signed.  This is very
+     * different from Raku:
+     *
+     * $ raku -e 'say -2 +< 5'
+     * -64
+     *
+     * $ ./perl -le 'print -2 << 5'
+     * 18446744073709551552
+     * */
+    if (left) {
+        return (IV) (((UV) iv) << shift);
+    }
+
+    /* Here is right shift */
+    return iv >> shift;
 }
 
 #define UV_LEFT_SHIFT(uv, shift) S_uv_shift(uv, shift, TRUE)
@@ -2020,12 +2042,12 @@ PP(pp_left_shift)
     svr = POPs;
     svl = TOPs;
     {
-      const IV shift = SvIV_nomg(svr);
+      const int shift = S_shift_amount(aTHX_ svr);
       if (PL_op->op_private & HINT_INTEGER) {
           SETi(IV_LEFT_SHIFT(SvIV_nomg(svl), shift));
       }
       else {
-         SETu(UV_LEFT_SHIFT(SvUV_nomg(svl), shift));
+          SETu(UV_LEFT_SHIFT(SvUV_nomg(svl), shift));
       }
       RETURN;
     }
@@ -2038,9 +2060,9 @@ PP(pp_right_shift)
     svr = POPs;
     svl = TOPs;
     {
-      const IV shift = SvIV_nomg(svr);
+      const int shift = S_shift_amount(aTHX_ svr);
       if (PL_op->op_private & HINT_INTEGER) {
-         SETi(IV_RIGHT_SHIFT(SvIV_nomg(svl), shift));
+          SETi(IV_RIGHT_SHIFT(SvIV_nomg(svl), shift));
       }
       else {
           SETu(UV_RIGHT_SHIFT(SvUV_nomg(svl), shift));
@@ -2053,14 +2075,20 @@ PP(pp_lt)
 {
     dSP;
     SV *left, *right;
+    U32 flags_and, flags_or;
 
     tryAMAGICbin_MG(lt_amg, AMGf_numeric);
     right = POPs;
     left  = TOPs;
+    flags_and = SvFLAGS(left) & SvFLAGS(right);
+    flags_or  = SvFLAGS(left) | SvFLAGS(right);
+
     SETs(boolSV(
-       (SvIOK_notUV(left) && SvIOK_notUV(right))
-       ? (SvIVX(left) < SvIVX(right))
-       : (do_ncmp(left, right) == -1)
+        ( (flags_and & SVf_IOK) && ((flags_or & SVf_IVisUV) ==0 ) )
+        ?    (SvIVX(left) < SvIVX(right))
+        : (flags_and & SVf_NOK)
+        ?    (SvNVX(left) < SvNVX(right))
+        : (do_ncmp(left, right) == -1)
     ));
     RETURN;
 }
@@ -2069,14 +2097,20 @@ PP(pp_gt)
 {
     dSP;
     SV *left, *right;
+    U32 flags_and, flags_or;
 
     tryAMAGICbin_MG(gt_amg, AMGf_numeric);
     right = POPs;
     left  = TOPs;
+    flags_and = SvFLAGS(left) & SvFLAGS(right);
+    flags_or  = SvFLAGS(left) | SvFLAGS(right);
+
     SETs(boolSV(
-       (SvIOK_notUV(left) && SvIOK_notUV(right))
-       ? (SvIVX(left) > SvIVX(right))
-       : (do_ncmp(left, right) == 1)
+        ( (flags_and & SVf_IOK) && ((flags_or & SVf_IVisUV) ==0 ) )
+        ?    (SvIVX(left) > SvIVX(right))
+        : (flags_and & SVf_NOK)
+        ?    (SvNVX(left) > SvNVX(right))
+        : (do_ncmp(left, right) == 1)
     ));
     RETURN;
 }
@@ -2085,14 +2119,20 @@ PP(pp_le)
 {
     dSP;
     SV *left, *right;
+    U32 flags_and, flags_or;
 
     tryAMAGICbin_MG(le_amg, AMGf_numeric);
     right = POPs;
     left  = TOPs;
+    flags_and = SvFLAGS(left) & SvFLAGS(right);
+    flags_or  = SvFLAGS(left) | SvFLAGS(right);
+
     SETs(boolSV(
-       (SvIOK_notUV(left) && SvIOK_notUV(right))
-       ? (SvIVX(left) <= SvIVX(right))
-       : (do_ncmp(left, right) <= 0)
+        ( (flags_and & SVf_IOK) && ((flags_or & SVf_IVisUV) ==0 ) )
+        ?    (SvIVX(left) <= SvIVX(right))
+        : (flags_and & SVf_NOK)
+        ?    (SvNVX(left) <= SvNVX(right))
+        : (do_ncmp(left, right) <= 0)
     ));
     RETURN;
 }
@@ -2101,14 +2141,20 @@ PP(pp_ge)
 {
     dSP;
     SV *left, *right;
+    U32 flags_and, flags_or;
 
     tryAMAGICbin_MG(ge_amg, AMGf_numeric);
     right = POPs;
     left  = TOPs;
+    flags_and = SvFLAGS(left) & SvFLAGS(right);
+    flags_or  = SvFLAGS(left) | SvFLAGS(right);
+
     SETs(boolSV(
-       (SvIOK_notUV(left) && SvIOK_notUV(right))
-       ? (SvIVX(left) >= SvIVX(right))
-       : ( (do_ncmp(left, right) & 2) == 0)
+        ( (flags_and & SVf_IOK) && ((flags_or & SVf_IVisUV) ==0 ) )
+        ?    (SvIVX(left) >= SvIVX(right))
+        : (flags_and & SVf_NOK)
+        ?    (SvNVX(left) >= SvNVX(right))
+        : ( (do_ncmp(left, right) & 2) == 0)
     ));
     RETURN;
 }
@@ -2117,14 +2163,20 @@ PP(pp_ne)
 {
     dSP;
     SV *left, *right;
+    U32 flags_and, flags_or;
 
     tryAMAGICbin_MG(ne_amg, AMGf_numeric);
     right = POPs;
     left  = TOPs;
+    flags_and = SvFLAGS(left) & SvFLAGS(right);
+    flags_or  = SvFLAGS(left) | SvFLAGS(right);
+
     SETs(boolSV(
-       (SvIOK_notUV(left) && SvIOK_notUV(right))
-       ? (SvIVX(left) != SvIVX(right))
-       : (do_ncmp(left, right) != 0)
+        ( (flags_and & SVf_IOK) && ((flags_or & SVf_IVisUV) ==0 ) )
+        ?    (SvIVX(left) != SvIVX(right))
+        : (flags_and & SVf_NOK)
+        ?    (SvNVX(left) != SvNVX(right))
+        : (do_ncmp(left, right) != 0)
     ));
     RETURN;
 }
@@ -2142,41 +2194,41 @@ Perl_do_ncmp(pTHX_ SV* const left, SV * const right)
 #ifdef PERL_PRESERVE_IVUV
     /* Fortunately it seems NaN isn't IOK */
     if (SvIV_please_nomg(right) && SvIV_please_nomg(left)) {
-           if (!SvUOK(left)) {
-               const IV leftiv = SvIVX(left);
-               if (!SvUOK(right)) {
-                   /* ## IV <=> IV ## */
-                   const IV rightiv = SvIVX(right);
-                   return (leftiv > rightiv) - (leftiv < rightiv);
-               }
-               /* ## IV <=> UV ## */
-               if (leftiv < 0)
-                   /* As (b) is a UV, it's >=0, so it must be < */
-                   return -1;
-               {
-                   const UV rightuv = SvUVX(right);
-                   return ((UV)leftiv > rightuv) - ((UV)leftiv < rightuv);
-               }
-           }
-
-           if (SvUOK(right)) {
-               /* ## UV <=> UV ## */
-               const UV leftuv = SvUVX(left);
-               const UV rightuv = SvUVX(right);
-               return (leftuv > rightuv) - (leftuv < rightuv);
-           }
-           /* ## UV <=> IV ## */
-           {
-               const IV rightiv = SvIVX(right);
-               if (rightiv < 0)
-                   /* As (a) is a UV, it's >=0, so it cannot be < */
-                   return 1;
-               {
-                   const UV leftuv = SvUVX(left);
-                   return (leftuv > (UV)rightiv) - (leftuv < (UV)rightiv);
-               }
-           }
-           NOT_REACHED; /* NOTREACHED */
+            if (!SvUOK(left)) {
+                const IV leftiv = SvIVX(left);
+                if (!SvUOK(right)) {
+                    /* ## IV <=> IV ## */
+                    const IV rightiv = SvIVX(right);
+                    return (leftiv > rightiv) - (leftiv < rightiv);
+                }
+                /* ## IV <=> UV ## */
+                if (leftiv < 0)
+                    /* As (b) is a UV, it's >=0, so it must be < */
+                    return -1;
+                {
+                    const UV rightuv = SvUVX(right);
+                    return ((UV)leftiv > rightuv) - ((UV)leftiv < rightuv);
+                }
+            }
+
+            if (SvUOK(right)) {
+                /* ## UV <=> UV ## */
+                const UV leftuv = SvUVX(left);
+                const UV rightuv = SvUVX(right);
+                return (leftuv > rightuv) - (leftuv < rightuv);
+            }
+            /* ## UV <=> IV ## */
+            {
+                const IV rightiv = SvIVX(right);
+                if (rightiv < 0)
+                    /* As (a) is a UV, it's >=0, so it cannot be < */
+                    return 1;
+                {
+                    const UV leftuv = SvUVX(left);
+                    return (leftuv > (UV)rightiv) - (leftuv < (UV)rightiv);
+                }
+            }
+            NOT_REACHED; /* NOTREACHED */
     }
 #endif
     {
@@ -2185,16 +2237,16 @@ Perl_do_ncmp(pTHX_ SV* const left, SV * const right)
 
 #if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
       if (Perl_isnan(lnv) || Perl_isnan(rnv)) {
-         return 2;
+          return 2;
        }
       return (lnv > rnv) - (lnv < rnv);
 #else
       if (lnv < rnv)
-       return -1;
+        return -1;
       if (lnv > rnv)
-       return 1;
+        return 1;
       if (lnv == rnv)
-       return 0;
+        return 0;
       return 2;
 #endif
     }
@@ -2211,11 +2263,11 @@ PP(pp_ncmp)
     left  = TOPs;
     value = do_ncmp(left, right);
     if (value == 2) {
-       SETs(&PL_sv_undef);
+        SETs(&PL_sv_undef);
     }
     else {
-       dTARGET;
-       SETi(value);
+        dTARGET;
+        SETi(value);
     }
     RETURN;
 }
@@ -2233,21 +2285,21 @@ PP(pp_sle)
 
     switch (PL_op->op_type) {
     case OP_SLT:
-       amg_type = slt_amg;
-       /* cmp < 0 */
-       rhs = 0;
-       break;
+        amg_type = slt_amg;
+        /* cmp < 0 */
+        rhs = 0;
+        break;
     case OP_SGT:
-       amg_type = sgt_amg;
-       /* cmp > 0 */
-       multiplier = -1;
-       rhs = 0;
-       break;
+        amg_type = sgt_amg;
+        /* cmp > 0 */
+        multiplier = -1;
+        rhs = 0;
+        break;
     case OP_SGE:
-       amg_type = sge_amg;
-       /* cmp >= 0 */
-       multiplier = -1;
-       break;
+        amg_type = sge_amg;
+        /* cmp >= 0 */
+        multiplier = -1;
+        break;
     }
 
     tryAMAGICbin_MG(amg_type, 0);
@@ -2256,10 +2308,10 @@ PP(pp_sle)
       const int cmp =
 #ifdef USE_LOCALE_COLLATE
                       (IN_LC_RUNTIME(LC_COLLATE))
-                     ? sv_cmp_locale_flags(left, right, 0)
+                      ? sv_cmp_locale_flags(left, right, 0)
                       :
 #endif
-                       sv_cmp_flags(left, right, 0);
+                        sv_cmp_flags(left, right, 0);
       SETs(boolSV(cmp * multiplier < rhs));
       RETURN;
     }
@@ -2296,8 +2348,8 @@ PP(pp_scmp)
       const int cmp =
 #ifdef USE_LOCALE_COLLATE
                       (IN_LC_RUNTIME(LC_COLLATE))
-                     ? sv_cmp_locale_flags(left, right, 0)
-                     :
+                      ? sv_cmp_locale_flags(left, right, 0)
+                      :
 #endif
                         sv_cmp_flags(left, right, 0);
       SETi( cmp );
@@ -2312,22 +2364,22 @@ PP(pp_bit_and)
     {
       dPOPTOPssrl;
       if (SvNIOKp(left) || SvNIOKp(right)) {
-       const bool left_ro_nonnum  = !SvNIOKp(left) && SvREADONLY(left);
-       const bool right_ro_nonnum = !SvNIOKp(right) && SvREADONLY(right);
-       if (PL_op->op_private & HINT_INTEGER) {
-         const IV i = SvIV_nomg(left) & SvIV_nomg(right);
-         SETi(i);
-       }
-       else {
-         const UV u = SvUV_nomg(left) & SvUV_nomg(right);
-         SETu(u);
-       }
-       if (left_ro_nonnum && left != TARG) SvNIOK_off(left);
-       if (right_ro_nonnum) SvNIOK_off(right);
+        const bool left_ro_nonnum  = !SvNIOKp(left) && SvREADONLY(left);
+        const bool right_ro_nonnum = !SvNIOKp(right) && SvREADONLY(right);
+        if (PL_op->op_private & HINT_INTEGER) {
+          const IV i = SvIV_nomg(left) & SvIV_nomg(right);
+          SETi(i);
+        }
+        else {
+          const UV u = SvUV_nomg(left) & SvUV_nomg(right);
+          SETu(u);
+        }
+        if (left_ro_nonnum && left != TARG) SvNIOK_off(left);
+        if (right_ro_nonnum) SvNIOK_off(right);
       }
       else {
-       do_vop(PL_op->op_type, TARG, left, right);
-       SETTARG;
+        do_vop(PL_op->op_type, TARG, left, right);
+        SETTARG;
       }
       RETURN;
     }
@@ -2338,15 +2390,15 @@ PP(pp_nbit_and)
     dSP;
     tryAMAGICbin_MG(band_amg, AMGf_assign|AMGf_numarg);
     {
-       dATARGET; dPOPTOPssrl;
-       if (PL_op->op_private & HINT_INTEGER) {
-         const IV i = SvIV_nomg(left) & SvIV_nomg(right);
-         SETi(i);
-       }
-       else {
-         const UV u = SvUV_nomg(left) & SvUV_nomg(right);
-         SETu(u);
-       }
+        dATARGET; dPOPTOPssrl;
+        if (PL_op->op_private & HINT_INTEGER) {
+          const IV i = SvIV_nomg(left) & SvIV_nomg(right);
+          SETi(i);
+        }
+        else {
+          const UV u = SvUV_nomg(left) & SvUV_nomg(right);
+          SETu(u);
+        }
     }
     RETURN;
 }
@@ -2356,9 +2408,9 @@ PP(pp_sbit_and)
     dSP;
     tryAMAGICbin_MG(sband_amg, AMGf_assign);
     {
-       dATARGET; dPOPTOPssrl;
-       do_vop(OP_BIT_AND, TARG, left, right);
-       RETSETTARG;
+        dATARGET; dPOPTOPssrl;
+        do_vop(OP_BIT_AND, TARG, left, right);
+        RETSETTARG;
     }
 }
 
@@ -2373,26 +2425,26 @@ PP(pp_bit_or)
     {
       dPOPTOPssrl;
       if (SvNIOKp(left) || SvNIOKp(right)) {
-       const bool left_ro_nonnum  = !SvNIOKp(left) && SvREADONLY(left);
-       const bool right_ro_nonnum = !SvNIOKp(right) && SvREADONLY(right);
-       if (PL_op->op_private & HINT_INTEGER) {
-         const IV l = (USE_LEFT(left) ? SvIV_nomg(left) : 0);
-         const IV r = SvIV_nomg(right);
-         const IV result = op_type == OP_BIT_OR ? (l | r) : (l ^ r);
-         SETi(result);
-       }
-       else {
-         const UV l = (USE_LEFT(left) ? SvUV_nomg(left) : 0);
-         const UV r = SvUV_nomg(right);
-         const UV result = op_type == OP_BIT_OR ? (l | r) : (l ^ r);
-         SETu(result);
-       }
-       if (left_ro_nonnum && left != TARG) SvNIOK_off(left);
-       if (right_ro_nonnum) SvNIOK_off(right);
+        const bool left_ro_nonnum  = !SvNIOKp(left) && SvREADONLY(left);
+        const bool right_ro_nonnum = !SvNIOKp(right) && SvREADONLY(right);
+        if (PL_op->op_private & HINT_INTEGER) {
+          const IV l = (USE_LEFT(left) ? SvIV_nomg(left) : 0);
+          const IV r = SvIV_nomg(right);
+          const IV result = op_type == OP_BIT_OR ? (l | r) : (l ^ r);
+          SETi(result);
+        }
+        else {
+          const UV l = (USE_LEFT(left) ? SvUV_nomg(left) : 0);
+          const UV r = SvUV_nomg(right);
+          const UV result = op_type == OP_BIT_OR ? (l | r) : (l ^ r);
+          SETu(result);
+        }
+        if (left_ro_nonnum && left != TARG) SvNIOK_off(left);
+        if (right_ro_nonnum) SvNIOK_off(right);
       }
       else {
-       do_vop(op_type, TARG, left, right);
-       SETTARG;
+        do_vop(op_type, TARG, left, right);
+        SETTARG;
       }
       RETURN;
     }
@@ -2406,21 +2458,21 @@ PP(pp_nbit_or)
     const int op_type = PL_op->op_type;
 
     tryAMAGICbin_MG((op_type == OP_NBIT_OR ? bor_amg : bxor_amg),
-                   AMGf_assign|AMGf_numarg);
+                    AMGf_assign|AMGf_numarg);
     {
-       dATARGET; dPOPTOPssrl;
-       if (PL_op->op_private & HINT_INTEGER) {
-         const IV l = (USE_LEFT(left) ? SvIV_nomg(left) : 0);
-         const IV r = SvIV_nomg(right);
-         const IV result = op_type == OP_NBIT_OR ? (l | r) : (l ^ r);
-         SETi(result);
-       }
-       else {
-         const UV l = (USE_LEFT(left) ? SvUV_nomg(left) : 0);
-         const UV r = SvUV_nomg(right);
-         const UV result = op_type == OP_NBIT_OR ? (l | r) : (l ^ r);
-         SETu(result);
-       }
+        dATARGET; dPOPTOPssrl;
+        if (PL_op->op_private & HINT_INTEGER) {
+          const IV l = (USE_LEFT(left) ? SvIV_nomg(left) : 0);
+          const IV r = SvIV_nomg(right);
+          const IV result = op_type == OP_NBIT_OR ? (l | r) : (l ^ r);
+          SETi(result);
+        }
+        else {
+          const UV l = (USE_LEFT(left) ? SvUV_nomg(left) : 0);
+          const UV r = SvUV_nomg(right);
+          const UV result = op_type == OP_NBIT_OR ? (l | r) : (l ^ r);
+          SETu(result);
+        }
     }
     RETURN;
 }
@@ -2433,12 +2485,12 @@ PP(pp_sbit_or)
     const int op_type = PL_op->op_type;
 
     tryAMAGICbin_MG((op_type == OP_SBIT_OR ? sbor_amg : sbxor_amg),
-                   AMGf_assign);
+                    AMGf_assign);
     {
-       dATARGET; dPOPTOPssrl;
-       do_vop(op_type == OP_SBIT_OR ? OP_BIT_OR : OP_BIT_XOR, TARG, left,
-              right);
-       RETSETTARG;
+        dATARGET; dPOPTOPssrl;
+        do_vop(op_type == OP_SBIT_OR ? OP_BIT_OR : OP_BIT_XOR, TARG, left,
+               right);
+        RETSETTARG;
     }
 }
 
@@ -2450,15 +2502,15 @@ S_negate_string(pTHX)
     const char *s;
     SV * const sv = TOPs;
     if (!SvPOKp(sv) || SvNIOK(sv) || (!SvPOK(sv) && SvNIOKp(sv)))
-       return FALSE;
+        return FALSE;
     s = SvPV_nomg_const(sv, len);
     if (isIDFIRST(*s)) {
-       sv_setpvs(TARG, "-");
-       sv_catsv(TARG, sv);
+        sv_setpvs(TARG, "-");
+        sv_catsv(TARG, sv);
     }
     else if (*s == '+' || (*s == '-' && !looks_like_number(sv))) {
-       sv_setsv_nomg(TARG, sv);
-       *SvPV_force_nomg(TARG, len) = *s == '-' ? '+' : '-';
+        sv_setsv_nomg(TARG, sv);
+        *SvPV_force_nomg(TARG, len) = *s == '-' ? '+' : '-';
     }
     else return FALSE;
     SETTARG;
@@ -2471,40 +2523,40 @@ PP(pp_negate)
     tryAMAGICun_MG(neg_amg, AMGf_numeric);
     if (S_negate_string(aTHX)) return NORMAL;
     {
-       SV * const sv = TOPs;
-
-       if (SvIOK(sv)) {
-           /* It's publicly an integer */
-       oops_its_an_int:
-           if (SvIsUV(sv)) {
-               if (SvIVX(sv) == IV_MIN) {
-                   /* 2s complement assumption. */
+        SV * const sv = TOPs;
+
+        if (SvIOK(sv)) {
+            /* It's publicly an integer */
+        oops_its_an_int:
+            if (SvIsUV(sv)) {
+                if (SvIVX(sv) == IV_MIN) {
+                    /* 2s complement assumption. */
                     SETi(SvIVX(sv));   /* special case: -((UV)IV_MAX+1) ==
                                            IV_MIN */
                     return NORMAL;
-               }
-               else if (SvUVX(sv) <= IV_MAX) {
-                   SETi(-SvIVX(sv));
-                   return NORMAL;
-               }
-           }
-           else if (SvIVX(sv) != IV_MIN) {
-               SETi(-SvIVX(sv));
-               return NORMAL;
-           }
+                }
+                else if (SvUVX(sv) <= IV_MAX) {
+                    SETi(-SvIVX(sv));
+                    return NORMAL;
+                }
+            }
+            else if (SvIVX(sv) != IV_MIN) {
+                SETi(-SvIVX(sv));
+                return NORMAL;
+            }
 #ifdef PERL_PRESERVE_IVUV
-           else {
-               SETu((UV)IV_MIN);
-               return NORMAL;
-           }
+            else {
+                SETu((UV)IV_MIN);
+                return NORMAL;
+            }
 #endif
-       }
-       if (SvNIOKp(sv) && (SvNIOK(sv) || !SvPOK(sv)))
-           SETn(-SvNV_nomg(sv));
-       else if (SvPOKp(sv) && SvIV_please_nomg(sv))
-                 goto oops_its_an_int;
-       else
-           SETn(-SvNV_nomg(sv));
+        }
+        if (SvNIOKp(sv) && (SvNIOK(sv) || !SvPOK(sv)))
+            SETn(-SvNV_nomg(sv));
+        else if (SvPOKp(sv) && SvIV_please_nomg(sv))
+                  goto oops_its_an_int;
+        else
+            SETn(-SvNV_nomg(sv));
     }
     return NORMAL;
 }
@@ -2523,36 +2575,35 @@ PP(pp_not)
 static void
 S_scomplement(pTHX_ SV *targ, SV *sv)
 {
-       U8 *tmps;
-       I32 anum;
-       STRLEN len;
+        U8 *tmps;
+        I32 anum;
+        STRLEN len;
 
-       sv_copypv_nomg(TARG, sv);
-       tmps = (U8*)SvPV_nomg(TARG, len);
+        sv_copypv_nomg(TARG, sv);
+        tmps = (U8*)SvPV_nomg(TARG, len);
 
-       if (SvUTF8(TARG)) {
+        if (SvUTF8(TARG)) {
             if (len && ! utf8_to_bytes(tmps, &len)) {
                 Perl_croak(aTHX_ FATAL_ABOVE_FF_MSG, PL_op_desc[PL_op->op_type]);
             }
-            SvCUR(TARG) = len;
+            SvCUR_set(TARG, len);
             SvUTF8_off(TARG);
         }
 
-       anum = len;
+        anum = len;
 
-#ifdef LIBERAL
-       {
-           long *tmpl;
-           for ( ; anum && (unsigned long)tmps % sizeof(long); anum--, tmps++)
-               *tmps = ~*tmps;
-           tmpl = (long*)tmps;
-           for ( ; anum >= (I32)sizeof(long); anum -= (I32)sizeof(long), tmpl++)
-               *tmpl = ~*tmpl;
-           tmps = (U8*)tmpl;
-       }
-#endif
-       for ( ; anum > 0; anum--, tmps++)
-           *tmps = ~*tmps;
+        {
+            long *tmpl;
+            for ( ; anum && PTR2nat(tmps) % sizeof(long); anum--, tmps++)
+                *tmps = ~*tmps;
+            tmpl = (long*)tmps;
+            for ( ; anum >= (I32)sizeof(long); anum -= (I32)sizeof(long), tmpl++)
+                *tmpl = ~*tmpl;
+            tmps = (U8*)tmpl;
+        }
+
+        for ( ; anum > 0; anum--, tmps++)
+            *tmps = ~*tmps;
 }
 
 PP(pp_complement)
@@ -2562,18 +2613,18 @@ PP(pp_complement)
     {
       dTOPss;
       if (SvNIOKp(sv)) {
-       if (PL_op->op_private & HINT_INTEGER) {
-         const IV i = ~SvIV_nomg(sv);
-         SETi(i);
-       }
-       else {
-         const UV u = ~SvUV_nomg(sv);
-         SETu(u);
-       }
+        if (PL_op->op_private & HINT_INTEGER) {
+          const IV i = ~SvIV_nomg(sv);
+          SETi(i);
+        }
+        else {
+          const UV u = ~SvUV_nomg(sv);
+          SETu(u);
+        }
       }
       else {
-       S_scomplement(aTHX_ TARG, sv);
-       SETTARG;
+        S_scomplement(aTHX_ TARG, sv);
+        SETTARG;
       }
       return NORMAL;
     }
@@ -2584,15 +2635,15 @@ PP(pp_ncomplement)
     dSP;
     tryAMAGICun_MG(compl_amg, AMGf_numeric|AMGf_numarg);
     {
-       dTARGET; dTOPss;
-       if (PL_op->op_private & HINT_INTEGER) {
-         const IV i = ~SvIV_nomg(sv);
-         SETi(i);
-       }
-       else {
-         const UV u = ~SvUV_nomg(sv);
-         SETu(u);
-       }
+        dTARGET; dTOPss;
+        if (PL_op->op_private & HINT_INTEGER) {
+          const IV i = ~SvIV_nomg(sv);
+          SETi(i);
+        }
+        else {
+          const UV u = ~SvUV_nomg(sv);
+          SETu(u);
+        }
     }
     return NORMAL;
 }
@@ -2602,10 +2653,10 @@ PP(pp_scomplement)
     dSP;
     tryAMAGICun_MG(scompl_amg, AMGf_numeric);
     {
-       dTARGET; dTOPss;
-       S_scomplement(aTHX_ TARG, sv);
-       SETTARG;
-       return NORMAL;
+        dTARGET; dTOPss;
+        S_scomplement(aTHX_ TARG, sv);
+        SETTARG;
+        return NORMAL;
     }
 }
 
@@ -2631,7 +2682,7 @@ PP(pp_i_divide)
       dPOPTOPssrl;
       IV value = SvIV_nomg(right);
       if (value == 0)
-         DIE(aTHX_ "Illegal division by zero");
+          DIE(aTHX_ "Illegal division by zero");
       num = SvIV_nomg(left);
 
       /* avoid FPE_INTOVF on some platforms when num is IV_MIN */
@@ -2646,46 +2697,21 @@ PP(pp_i_divide)
 
 PP(pp_i_modulo)
 {
-     /* This is the vanilla old i_modulo. */
      dSP; dATARGET;
      tryAMAGICbin_MG(modulo_amg, AMGf_assign);
      {
-         dPOPTOPiirl_nomg;
-         if (!right)
-              DIE(aTHX_ "Illegal modulus zero");
-         /* avoid FPE_INTOVF on some platforms when left is IV_MIN */
-         if (right == -1)
-             SETi( 0 );
-         else
-             SETi( left % right );
-         RETURN;
+          dPOPTOPiirl_nomg;
+          if (!right)
+               DIE(aTHX_ "Illegal modulus zero");
+          /* avoid FPE_INTOVF on some platforms when left is IV_MIN */
+          if (right == -1)
+              SETi( 0 );
+          else
+              SETi( left % right );
+          RETURN;
      }
 }
 
-#if defined(__GLIBC__) && IVSIZE == 8 \
-    && ( __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 8))
-
-PP(pp_i_modulo_glibc_bugfix)
-{
-     /* This is the i_modulo with the workaround for the _moddi3 bug
-      * in (at least) glibc 2.2.5 (the PERL_ABS() the workaround).
-      * See below for pp_i_modulo. */
-     dSP; dATARGET;
-     tryAMAGICbin_MG(modulo_amg, AMGf_assign);
-     {
-         dPOPTOPiirl_nomg;
-         if (!right)
-              DIE(aTHX_ "Illegal modulus zero");
-         /* avoid FPE_INTOVF on some platforms when left is IV_MIN */
-         if (right == -1)
-             SETi( 0 );
-         else
-             SETi( left % PERL_ABS(right) );
-         RETURN;
-     }
-}
-#endif
-
 PP(pp_i_add)
 {
     dSP; dATARGET;
@@ -2783,11 +2809,11 @@ PP(pp_i_ncmp)
       I32 value;
 
       if (left > right)
-       value = 1;
+        value = 1;
       else if (left < right)
-       value = -1;
+        value = -1;
       else
-       value = 0;
+        value = 0;
       SETi(value);
       RETURN;
     }
@@ -2799,10 +2825,10 @@ PP(pp_i_negate)
     tryAMAGICun_MG(neg_amg, 0);
     if (S_negate_string(aTHX)) return NORMAL;
     {
-       SV * const sv = TOPs;
-       IV const i = SvIV_nomg(sv);
-       SETi(-i);
-       return NORMAL;
+        SV * const sv = TOPs;
+        IV const i = SvIV_nomg(sv);
+        SETi(-i);
+        return NORMAL;
     }
 }
 
@@ -2849,15 +2875,15 @@ PP(pp_sin)
       NV result = 0.0;
 #endif
       if (neg_report) { /* log or sqrt */
-         if (
+          if (
 #if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
-             ! Perl_isnan(value) &&
+              ! Perl_isnan(value) &&
 #endif
-             (op_type == OP_LOG ? (value <= 0.0) : (value < 0.0))) {
-             SET_NUMERIC_STANDARD();
-             /* diag_listed_as: Can't take log of %g */
-             DIE(aTHX_ "Can't take %s of %" NVgf, neg_report, value);
-         }
+              (op_type == OP_LOG ? (value <= 0.0) : (value < 0.0))) {
+              SET_NUMERIC_STANDARD();
+              /* diag_listed_as: Can't take log of %g */
+              DIE(aTHX_ "Can't take %s of %" NVgf, neg_report, value);
+          }
       }
       switch (op_type) {
       default:
@@ -2886,39 +2912,39 @@ PP(pp_sin)
 PP(pp_rand)
 {
     if (!PL_srand_called) {
-       (void)seedDrand01((Rand_seed_t)seed());
-       PL_srand_called = TRUE;
+        (void)seedDrand01((Rand_seed_t)seed());
+        PL_srand_called = TRUE;
     }
     {
-       dSP;
-       NV value;
-
-       if (MAXARG < 1)
-       {
-           EXTEND(SP, 1);
-           value = 1.0;
-       }
-       else {
-           SV * const sv = POPs;
-           if(!sv)
-               value = 1.0;
-           else
-               value = SvNV(sv);
-       }
+        dSP;
+        NV value;
+
+        if (MAXARG < 1)
+        {
+            EXTEND(SP, 1);
+            value = 1.0;
+        }
+        else {
+            SV * const sv = POPs;
+            if(!sv)
+                value = 1.0;
+            else
+                value = SvNV(sv);
+        }
     /* 1 of 2 things can be carried through SvNV, SP or TARG, SP was carried */
 #if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
-       if (! Perl_isnan(value) && value == 0.0)
+        if (! Perl_isnan(value) && value == 0.0)
 #else
-       if (value == 0.0)
+        if (value == 0.0)
 #endif
-           value = 1.0;
-       {
-           dTARGET;
-           PUSHs(TARG);
-           PUTBACK;
-           value *= Drand01();
-           sv_setnv_mg(TARG, value);
-       }
+            value = 1.0;
+        {
+            dTARGET;
+            PUSHs(TARG);
+            PUTBACK;
+            value *= Drand01();
+            sv_setnv_mg(TARG, value);
+        }
     }
     return NORMAL;
 }
@@ -2951,12 +2977,12 @@ PP(pp_srand)
     (void)seedDrand01((Rand_seed_t)anum);
     PL_srand_called = TRUE;
     if (anum)
-       XPUSHu(anum);
+        XPUSHu(anum);
     else {
-       /* Historically srand always returned true. We can avoid breaking
-          that like this:  */
-       sv_setpvs(TARG, "0 but true");
-       XPUSHTARG;
+        /* Historically srand always returned true. We can avoid breaking
+           that like this:  */
+        sv_setpvs(TARG, "0 but true");
+        XPUSHTARG;
     }
     RETURN;
 }
@@ -2969,37 +2995,37 @@ PP(pp_int)
       SV * const sv = TOPs;
       const IV iv = SvIV_nomg(sv);
       /* XXX it's arguable that compiler casting to IV might be subtly
-        different from modf (for numbers inside (IV_MIN,UV_MAX)) in which
-        else preferring IV has introduced a subtle behaviour change bug. OTOH
-        relying on floating point to be accurate is a bug.  */
+         different from modf (for numbers inside (IV_MIN,UV_MAX)) in which
+         else preferring IV has introduced a subtle behaviour change bug. OTOH
+         relying on floating point to be accurate is a bug.  */
 
       if (!SvOK(sv)) {
         SETu(0);
       }
       else if (SvIOK(sv)) {
-       if (SvIsUV(sv))
-           SETu(SvUV_nomg(sv));
-       else
-           SETi(iv);
+        if (SvIsUV(sv))
+            SETu(SvUV_nomg(sv));
+        else
+            SETi(iv);
       }
       else {
-         const NV value = SvNV_nomg(sv);
-         if (UNLIKELY(Perl_isinfnan(value)))
-             SETn(value);
-         else if (value >= 0.0) {
-             if (value < (NV)UV_MAX + 0.5) {
-                 SETu(U_V(value));
-             } else {
-                 SETn(Perl_floor(value));
-             }
-         }
-         else {
-             if (value > (NV)IV_MIN - 0.5) {
-                 SETi(I_V(value));
-             } else {
-                 SETn(Perl_ceil(value));
-             }
-         }
+          const NV value = SvNV_nomg(sv);
+          if (UNLIKELY(Perl_isinfnan(value)))
+              SETn(value);
+          else if (value >= 0.0) {
+              if (value < (NV)UV_MAX + 0.5) {
+                  SETu(U_V(value));
+              } else {
+                  SETn(Perl_floor(value));
+              }
+          }
+          else {
+              if (value > (NV)IV_MIN - 0.5) {
+                  SETi(I_V(value));
+              } else {
+                  SETn(Perl_ceil(value));
+              }
+          }
       }
     }
     return NORMAL;
@@ -3018,28 +3044,28 @@ PP(pp_abs)
         SETu(0);
       }
       else if (SvIOK(sv)) {
-       /* IVX is precise  */
-       if (SvIsUV(sv)) {
-         SETu(SvUV_nomg(sv));  /* force it to be numeric only */
-       } else {
-         if (iv >= 0) {
-           SETi(iv);
-         } else {
-           if (iv != IV_MIN) {
-             SETi(-iv);
-           } else {
-             /* 2s complement assumption. Also, not really needed as
-                IV_MIN and -IV_MIN should both be %100...00 and NV-able  */
-             SETu((UV)IV_MIN);
-           }
-         }
-       }
+        /* IVX is precise  */
+        if (SvIsUV(sv)) {
+          SETu(SvUV_nomg(sv)); /* force it to be numeric only */
+        } else {
+          if (iv >= 0) {
+            SETi(iv);
+          } else {
+            if (iv != IV_MIN) {
+              SETi(-iv);
+            } else {
+              /* 2s complement assumption. Also, not really needed as
+                 IV_MIN and -IV_MIN should both be %100...00 and NV-able  */
+              SETu((UV)IV_MIN);
+            }
+          }
+        }
       } else{
-       const NV value = SvNV_nomg(sv);
-       if (value < 0.0)
-         SETn(-value);
-       else
-         SETn(value);
+        const NV value = SvNV_nomg(sv);
+        if (value < 0.0)
+          SETn(-value);
+        else
+          SETn(value);
       }
     }
     return NORMAL;
@@ -3060,29 +3086,38 @@ PP(pp_oct)
 
     tmps = (SvPV_const(sv, len));
     if (DO_UTF8(sv)) {
-        /* If Unicode, try to downgrade
-         * If not possible, croak. */
-        SV* const tsv = sv_2mortal(newSVsv(sv));
+         /* If Unicode, try to downgrade
+          * If not possible, croak. */
+         SV* const tsv = sv_2mortal(newSVsv(sv));
 
-        SvUTF8_on(tsv);
-        sv_utf8_downgrade(tsv, FALSE);
-        tmps = SvPV_const(tsv, len);
+         SvUTF8_on(tsv);
+         sv_utf8_downgrade(tsv, FALSE);
+         tmps = SvPV_const(tsv, len);
     }
     if (PL_op->op_type == OP_HEX)
-       goto hex;
+        goto hex;
 
     while (*tmps && len && isSPACE(*tmps))
         tmps++, len--;
     if (*tmps == '0')
         tmps++, len--;
     if (isALPHA_FOLD_EQ(*tmps, 'x')) {
+        tmps++, len--;
+        flags |= PERL_SCAN_DISALLOW_PREFIX;
     hex:
         result_uv = grok_hex (tmps, &len, &flags, &result_nv);
     }
-    else if (isALPHA_FOLD_EQ(*tmps, 'b'))
+    else if (isALPHA_FOLD_EQ(*tmps, 'b')) {
+        tmps++, len--;
+        flags |= PERL_SCAN_DISALLOW_PREFIX;
         result_uv = grok_bin (tmps, &len, &flags, &result_nv);
-    else
+    }
+    else {
+        if (isALPHA_FOLD_EQ(*tmps, 'o')) {
+            tmps++, len--;
+        }
         result_uv = grok_oct (tmps, &len, &flags, &result_nv);
+    }
 
     if (flags & PERL_SCAN_GREATER_THAN_UV_MAX) {
         SETn(result_nv);
@@ -3120,7 +3155,7 @@ PP(pp_length)
 
     if (SvOK(sv)) {
         STRLEN len;
-       if (!IN_BYTES) { /* reread to avoid using an C auto/register */
+        if (!IN_BYTES) { /* reread to avoid using an C auto/register */
             if ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == SVf_POK)
                 goto simple_pv;
             if ( SvPOK(sv) && (PL_op->op_private & OPpTRUEBOOL)) {
@@ -3128,9 +3163,9 @@ PP(pp_length)
                 len = SvCUR(sv);
                 goto return_bool;
             }
-           len = sv_len_utf8_nomg(sv);
+            len = sv_len_utf8_nomg(sv);
         }
-       else {
+        else {
             /* unrolled SvPV_nomg_const(sv,len) */
             if (SvPOK_nog(sv)) {
               simple_pv:
@@ -3144,15 +3179,15 @@ PP(pp_length)
             else {
                 (void)sv_2pv_flags(sv, &len, 0|SV_CONST_RETURN);
             }
-       }
+        }
         TARGi((IV)(len), 1);
     }
     else {
-       if (!SvPADTMP(TARG)) {
+        if (!SvPADTMP(TARG)) {
             /* OPpTARGET_MY: targ is var in '$lex = length()' */
             sv_set_undef(TARG);
             SvSETMAGIC(TARG);
-       }
+        }
         else
             /* TARG is on stack at this point and is overwriten by SETs.
              * This branch is the odd one out, so put TARG by default on
@@ -3169,9 +3204,9 @@ PP(pp_length)
 */
 bool
 Perl_translate_substr_offsets( STRLEN curlen, IV pos1_iv,
-                               bool pos1_is_uv, IV len_iv,
-                               bool len_is_uv, STRLEN *posp,
-                               STRLEN *lenp)
+                                bool pos1_is_uv, IV len_iv,
+                                bool len_is_uv, STRLEN *posp,
+                                STRLEN *lenp)
 {
     IV pos2_iv;
     int    pos2_is_uv;
@@ -3179,49 +3214,49 @@ Perl_translate_substr_offsets( STRLEN curlen, IV pos1_iv,
     PERL_ARGS_ASSERT_TRANSLATE_SUBSTR_OFFSETS;
 
     if (!pos1_is_uv && pos1_iv < 0 && curlen) {
-       pos1_is_uv = curlen-1 > ~(UV)pos1_iv;
-       pos1_iv += curlen;
+        pos1_is_uv = curlen-1 > ~(UV)pos1_iv;
+        pos1_iv += curlen;
     }
     if ((pos1_is_uv || pos1_iv > 0) && (UV)pos1_iv > curlen)
-       return FALSE;
+        return FALSE;
 
     if (len_iv || len_is_uv) {
-       if (!len_is_uv && len_iv < 0) {
-           pos2_iv = curlen + len_iv;
-           if (curlen)
-               pos2_is_uv = curlen-1 > ~(UV)len_iv;
-           else
-               pos2_is_uv = 0;
-       } else {  /* len_iv >= 0 */
-           if (!pos1_is_uv && pos1_iv < 0) {
-               pos2_iv = pos1_iv + len_iv;
-               pos2_is_uv = (UV)len_iv > (UV)IV_MAX;
-           } else {
-               if ((UV)len_iv > curlen-(UV)pos1_iv)
-                   pos2_iv = curlen;
-               else
-                   pos2_iv = pos1_iv+len_iv;
-               pos2_is_uv = 1;
-           }
-       }
+        if (!len_is_uv && len_iv < 0) {
+            pos2_iv = curlen + len_iv;
+            if (curlen)
+                pos2_is_uv = curlen-1 > ~(UV)len_iv;
+            else
+                pos2_is_uv = 0;
+        } else {  /* len_iv >= 0 */
+            if (!pos1_is_uv && pos1_iv < 0) {
+                pos2_iv = pos1_iv + len_iv;
+                pos2_is_uv = (UV)len_iv > (UV)IV_MAX;
+            } else {
+                if ((UV)len_iv > curlen-(UV)pos1_iv)
+                    pos2_iv = curlen;
+                else
+                    pos2_iv = pos1_iv+len_iv;
+                pos2_is_uv = 1;
+            }
+        }
     }
     else {
-       pos2_iv = curlen;
-       pos2_is_uv = 1;
+        pos2_iv = curlen;
+        pos2_is_uv = 1;
     }
 
     if (!pos2_is_uv && pos2_iv < 0) {
-       if (!pos1_is_uv && pos1_iv < 0)
-           return FALSE;
-       pos2_iv = 0;
+        if (!pos1_is_uv && pos1_iv < 0)
+            return FALSE;
+        pos2_iv = 0;
     }
     else if (!pos1_is_uv && pos1_iv < 0)
-       pos1_iv = 0;
+        pos1_iv = 0;
 
     if ((UV)pos2_iv < (UV)pos1_iv)
-       pos2_iv = pos1_iv;
+        pos2_iv = pos1_iv;
     if ((UV)pos2_iv > curlen)
-       pos2_iv = curlen;
+        pos2_iv = curlen;
 
     /* pos1_iv and pos2_iv both in 0..curlen, so the cast is safe */
     *posp = (STRLEN)( (UV)pos1_iv );
@@ -3252,120 +3287,120 @@ PP(pp_substr)
     bool repl_need_utf8_upgrade = FALSE;
 
     if (num_args > 2) {
-       if (num_args > 3) {
-         if(!(repl_sv = POPs)) num_args--;
-       }
-       if ((len_sv = POPs)) {
-           len_iv    = SvIV(len_sv);
-           len_is_uv = len_iv ? SvIOK_UV(len_sv) : 1;
-       }
-       else num_args--;
+        if (num_args > 3) {
+          if(!(repl_sv = POPs)) num_args--;
+        }
+        if ((len_sv = POPs)) {
+            len_iv    = SvIV(len_sv);
+            len_is_uv = len_iv ? SvIOK_UV(len_sv) : 1;
+        }
+        else num_args--;
     }
     pos_sv     = POPs;
     pos1_iv    = SvIV(pos_sv);
     pos1_is_uv = SvIOK_UV(pos_sv);
     sv = POPs;
     if (PL_op->op_private & OPpSUBSTR_REPL_FIRST) {
-       assert(!repl_sv);
-       repl_sv = POPs;
+        assert(!repl_sv);
+        repl_sv = POPs;
     }
     if (lvalue && !repl_sv) {
-       SV * ret;
-       ret = sv_2mortal(newSV_type(SVt_PVLV));  /* Not TARG RT#67838 */
-       sv_magic(ret, NULL, PERL_MAGIC_substr, NULL, 0);
-       LvTYPE(ret) = 'x';
-       LvTARG(ret) = SvREFCNT_inc_simple(sv);
-       LvTARGOFF(ret) =
-           pos1_is_uv || pos1_iv >= 0
-               ? (STRLEN)(UV)pos1_iv
-               : (LvFLAGS(ret) |= LVf_NEG_OFF, (STRLEN)(UV)-pos1_iv);
-       LvTARGLEN(ret) =
-           len_is_uv || len_iv > 0
-               ? (STRLEN)(UV)len_iv
-               : (LvFLAGS(ret) |= LVf_NEG_LEN, (STRLEN)(UV)-len_iv);
-
-       PUSHs(ret);    /* avoid SvSETMAGIC here */
-       RETURN;
+        SV * ret;
+        ret = sv_2mortal(newSV_type(SVt_PVLV));  /* Not TARG RT#67838 */
+        sv_magic(ret, NULL, PERL_MAGIC_substr, NULL, 0);
+        LvTYPE(ret) = 'x';
+        LvTARG(ret) = SvREFCNT_inc_simple(sv);
+        LvTARGOFF(ret) =
+            pos1_is_uv || pos1_iv >= 0
+                ? (STRLEN)(UV)pos1_iv
+                : (LvFLAGS(ret) |= LVf_NEG_OFF, (STRLEN)(UV)-pos1_iv);
+        LvTARGLEN(ret) =
+            len_is_uv || len_iv > 0
+                ? (STRLEN)(UV)len_iv
+                : (LvFLAGS(ret) |= LVf_NEG_LEN, (STRLEN)(UV)-len_iv);
+
+        PUSHs(ret);    /* avoid SvSETMAGIC here */
+        RETURN;
     }
     if (repl_sv) {
-       repl = SvPV_const(repl_sv, repl_len);
-       SvGETMAGIC(sv);
-       if (SvROK(sv))
-           Perl_ck_warner(aTHX_ packWARN(WARN_SUBSTR),
-                           "Attempt to use reference as lvalue in substr"
-           );
-       tmps = SvPV_force_nomg(sv, curlen);
-       if (DO_UTF8(repl_sv) && repl_len) {
-           if (!DO_UTF8(sv)) {
+        repl = SvPV_const(repl_sv, repl_len);
+        SvGETMAGIC(sv);
+        if (SvROK(sv))
+            Perl_ck_warner(aTHX_ packWARN(WARN_SUBSTR),
+                            "Attempt to use reference as lvalue in substr"
+            );
+        tmps = SvPV_force_nomg(sv, curlen);
+        if (DO_UTF8(repl_sv) && repl_len) {
+            if (!DO_UTF8(sv)) {
                 /* Upgrade the dest, and recalculate tmps in case the buffer
                  * got reallocated; curlen may also have been changed */
-               sv_utf8_upgrade_nomg(sv);
-               tmps = SvPV_nomg(sv, curlen);
-           }
-       }
-       else if (DO_UTF8(sv))
-           repl_need_utf8_upgrade = TRUE;
+                sv_utf8_upgrade_nomg(sv);
+                tmps = SvPV_nomg(sv, curlen);
+            }
+        }
+        else if (DO_UTF8(sv))
+            repl_need_utf8_upgrade = TRUE;
     }
     else tmps = SvPV_const(sv, curlen);
     if (DO_UTF8(sv)) {
         utf8_curlen = sv_or_pv_len_utf8(sv, tmps, curlen);
-       if (utf8_curlen == curlen)
-           utf8_curlen = 0;
-       else
-           curlen = utf8_curlen;
+        if (utf8_curlen == curlen)
+            utf8_curlen = 0;
+        else
+            curlen = utf8_curlen;
     }
     else
-       utf8_curlen = 0;
+        utf8_curlen = 0;
 
     {
-       STRLEN pos, len, byte_len, byte_pos;
+        STRLEN pos, len, byte_len, byte_pos;
 
-       if (!translate_substr_offsets(
-               curlen, pos1_iv, pos1_is_uv, len_iv, len_is_uv, &pos, &len
-       )) goto bound_fail;
+        if (!translate_substr_offsets(
+                curlen, pos1_iv, pos1_is_uv, len_iv, len_is_uv, &pos, &len
+        )) goto bound_fail;
 
-       byte_len = len;
-       byte_pos = utf8_curlen
-           ? sv_or_pv_pos_u2b(sv, tmps, pos, &byte_len) : pos;
+        byte_len = len;
+        byte_pos = utf8_curlen
+            ? sv_or_pv_pos_u2b(sv, tmps, pos, &byte_len) : pos;
 
-       tmps += byte_pos;
+        tmps += byte_pos;
 
-       if (rvalue) {
-           SvTAINTED_off(TARG);                        /* decontaminate */
-           SvUTF8_off(TARG);                   /* decontaminate */
-           sv_setpvn(TARG, tmps, byte_len);
+        if (rvalue) {
+            SvTAINTED_off(TARG);                       /* decontaminate */
+            SvUTF8_off(TARG);                  /* decontaminate */
+            sv_setpvn(TARG, tmps, byte_len);
 #ifdef USE_LOCALE_COLLATE
-           sv_unmagic(TARG, PERL_MAGIC_collxfrm);
+            sv_unmagic(TARG, PERL_MAGIC_collxfrm);
 #endif
-           if (utf8_curlen)
-               SvUTF8_on(TARG);
-       }
-
-       if (repl) {
-           SV* repl_sv_copy = NULL;
-
-           if (repl_need_utf8_upgrade) {
-               repl_sv_copy = newSVsv(repl_sv);
-               sv_utf8_upgrade(repl_sv_copy);
-               repl = SvPV_const(repl_sv_copy, repl_len);
-           }
-           if (!SvOK(sv))
+            if (utf8_curlen)
+                SvUTF8_on(TARG);
+        }
+
+        if (repl) {
+            SV* repl_sv_copy = NULL;
+
+            if (repl_need_utf8_upgrade) {
+                repl_sv_copy = newSVsv(repl_sv);
+                sv_utf8_upgrade(repl_sv_copy);
+                repl = SvPV_const(repl_sv_copy, repl_len);
+            }
+            if (!SvOK(sv))
                 SvPVCLEAR(sv);
-           sv_insert_flags(sv, byte_pos, byte_len, repl, repl_len, 0);
-           SvREFCNT_dec(repl_sv_copy);
-       }
+            sv_insert_flags(sv, byte_pos, byte_len, repl, repl_len, 0);
+            SvREFCNT_dec(repl_sv_copy);
+        }
     }
     if (PL_op->op_private & OPpSUBSTR_REPL_FIRST)
-       SP++;
+        SP++;
     else if (rvalue) {
-       SvSETMAGIC(TARG);
-       PUSHs(TARG);
+        SvSETMAGIC(TARG);
+        PUSHs(TARG);
     }
     RETURN;
 
   bound_fail:
     if (repl)
-       Perl_croak(aTHX_ "substr outside of string");
+        Perl_croak(aTHX_ "substr outside of string");
     Perl_ck_warner(aTHX_ packWARN(WARN_SUBSTR), "substr outside of string");
     RETPUSHUNDEF;
 }
@@ -3403,23 +3438,23 @@ PP(pp_vec)
     retuv = errflags ? 0 : do_vecget(src, offset, size);
 
     if (lvalue) {                      /* it's an lvalue! */
-       ret = sv_2mortal(newSV_type(SVt_PVLV));  /* Not TARG RT#67838 */
-       sv_magic(ret, NULL, PERL_MAGIC_vec, NULL, 0);
-       LvTYPE(ret) = 'v';
-       LvTARG(ret) = SvREFCNT_inc_simple(src);
-       LvTARGOFF(ret) = offset;
-       LvTARGLEN(ret) = size;
-       LvFLAGS(ret)   = errflags;
+        ret = sv_2mortal(newSV_type(SVt_PVLV));  /* Not TARG RT#67838 */
+        sv_magic(ret, NULL, PERL_MAGIC_vec, NULL, 0);
+        LvTYPE(ret) = 'v';
+        LvTARG(ret) = SvREFCNT_inc_simple(src);
+        LvTARGOFF(ret) = offset;
+        LvTARGLEN(ret) = size;
+        LvFLAGS(ret)   = errflags;
     }
     else {
-       dTARGET;
-       SvTAINTED_off(TARG);            /* decontaminate */
-       ret = TARG;
+        dTARGET;
+        SvTAINTED_off(TARG);           /* decontaminate */
+        ret = TARG;
     }
 
     sv_setuv(ret, retuv);
     if (!lvalue)
-       SvSETMAGIC(ret);
+        SvSETMAGIC(ret);
     PUSHs(ret);
     RETURN;
 }
@@ -3445,7 +3480,7 @@ PP(pp_index)
     const bool threeargs = MAXARG >= 3 && (TOPs || ((void)POPs,0));
 
     if (threeargs)
-       offset = POPi;
+        offset = POPi;
     little = POPs;
     big = POPs;
     big_p = SvPV_const(big, biglen);
@@ -3454,89 +3489,94 @@ PP(pp_index)
     big_utf8 = DO_UTF8(big);
     little_utf8 = DO_UTF8(little);
     if (big_utf8 ^ little_utf8) {
-       /* One needs to be upgraded.  */
-       if (little_utf8) {
-           /* Well, maybe instead we might be able to downgrade the small
-              string?  */
-           char * const pv = (char*)bytes_from_utf8((U8 *)little_p, &llen,
-                                                    &little_utf8);
-           if (little_utf8) {
-               /* If the large string is ISO-8859-1, and it's not possible to
-                  convert the small string to ISO-8859-1, then there is no
-                  way that it could be found anywhere by index.  */
-               retval = -1;
-               goto push_result;
-           }
-
-           /* At this point, pv is a malloc()ed string. So donate it to temp
-              to ensure it will get free()d  */
-           little = temp = newSV(0);
-           sv_usepvn(temp, pv, llen);
-           little_p = SvPVX(little);
-       } else {
-           temp = newSVpvn(little_p, llen);
-
-           sv_utf8_upgrade(temp);
-           little = temp;
-           little_p = SvPV_const(little, llen);
-       }
+        /* One needs to be upgraded.  */
+        if (little_utf8) {
+            /* Well, maybe instead we might be able to downgrade the small
+               string?  */
+            char * const pv = (char*)bytes_from_utf8((U8 *)little_p, &llen,
+                                                     &little_utf8);
+            if (little_utf8) {
+                /* If the large string is ISO-8859-1, and it's not possible to
+                   convert the small string to ISO-8859-1, then there is no
+                   way that it could be found anywhere by index.  */
+                retval = -1;
+                goto push_result;
+            }
+
+            /* At this point, pv is a malloc()ed string. So donate it to temp
+               to ensure it will get free()d  */
+            little = temp = newSV(0);
+            sv_usepvn(temp, pv, llen);
+            little_p = SvPVX(little);
+        } else {
+            temp = newSVpvn(little_p, llen);
+
+            sv_utf8_upgrade(temp);
+            little = temp;
+            little_p = SvPV_const(little, llen);
+        }
     }
     if (SvGAMAGIC(big)) {
-       /* Life just becomes a lot easier if I use a temporary here.
-          Otherwise I need to avoid calls to sv_pos_u2b(), which (dangerously)
-          will trigger magic and overloading again, as will fbm_instr()
-       */
-       big = newSVpvn_flags(big_p, biglen,
-                            SVs_TEMP | (big_utf8 ? SVf_UTF8 : 0));
-       big_p = SvPVX(big);
+        /* Life just becomes a lot easier if I use a temporary here.
+           Otherwise I need to avoid calls to sv_pos_u2b(), which (dangerously)
+           will trigger magic and overloading again, as will fbm_instr()
+        */
+        big = newSVpvn_flags(big_p, biglen,
+                             SVs_TEMP | (big_utf8 ? SVf_UTF8 : 0));
+        big_p = SvPVX(big);
     }
     if (SvGAMAGIC(little) || (is_index && !SvOK(little))) {
-       /* index && SvOK() is a hack. fbm_instr() calls SvPV_const, which will
-          warn on undef, and we've already triggered a warning with the
-          SvPV_const some lines above. We can't remove that, as we need to
-          call some SvPV to trigger overloading early and find out if the
-          string is UTF-8.
-          This is all getting too messy. The API isn't quite clean enough,
-          because data access has side effects.
-       */
-       little = newSVpvn_flags(little_p, llen,
-                               SVs_TEMP | (little_utf8 ? SVf_UTF8 : 0));
-       little_p = SvPVX(little);
+        /* index && SvOK() is a hack. fbm_instr() calls SvPV_const, which will
+           warn on undef, and we've already triggered a warning with the
+           SvPV_const some lines above. We can't remove that, as we need to
+           call some SvPV to trigger overloading early and find out if the
+           string is UTF-8.
+           This is all getting too messy. The API isn't quite clean enough,
+           because data access has side effects.
+        */
+        little = newSVpvn_flags(little_p, llen,
+                                SVs_TEMP | (little_utf8 ? SVf_UTF8 : 0));
+        little_p = SvPVX(little);
     }
 
     if (!threeargs)
-       offset = is_index ? 0 : biglen;
+        offset = is_index ? 0 : biglen;
     else {
-       if (big_utf8 && offset > 0)
-           offset = sv_pos_u2b_flags(big, offset, 0, SV_CONST_RETURN);
-       if (!is_index)
-           offset += llen;
+        if (big_utf8 && offset > 0)
+            offset = sv_pos_u2b_flags(big, offset, 0, SV_CONST_RETURN);
+        if (!is_index)
+            offset += llen;
     }
     if (offset < 0)
-       offset = 0;
+        offset = 0;
     else if (offset > (SSize_t)biglen)
-       offset = biglen;
+        offset = biglen;
     if (!(little_p = is_index
-         ? fbm_instr((unsigned char*)big_p + offset,
-                     (unsigned char*)big_p + biglen, little, 0)
-         : rninstr(big_p,  big_p  + offset,
-                   little_p, little_p + llen)))
-       retval = -1;
+          ? fbm_instr((unsigned char*)big_p + offset,
+                      (unsigned char*)big_p + biglen, little, 0)
+          : rninstr(big_p,  big_p  + offset,
+                    little_p, little_p + llen)))
+        retval = -1;
     else {
-       retval = little_p - big_p;
-       if (retval > 1 && big_utf8)
-           retval = sv_pos_b2u_flags(big, retval, SV_CONST_RETURN);
+        retval = little_p - big_p;
+        if (retval > 1 && big_utf8)
+            retval = sv_pos_b2u_flags(big, retval, SV_CONST_RETURN);
     }
     SvREFCNT_dec(temp);
 
   push_result:
     /* OPpTRUEBOOL indicates an '== -1' has been optimised away */
     if (PL_op->op_private & OPpTRUEBOOL) {
-        PUSHs( ((retval != -1) ^ cBOOL(PL_op->op_private & OPpINDEX_BOOLNEG))
-                    ? &PL_sv_yes : &PL_sv_no);
-        if (PL_op->op_private & OPpTARGET_MY)
+        SV *result = ((retval != -1) ^ cBOOL(PL_op->op_private & OPpINDEX_BOOLNEG))
+            ? &PL_sv_yes : &PL_sv_no;
+        if (PL_op->op_private & OPpTARGET_MY) {
             /* $lex = (index() == -1) */
-            sv_setsv(TARG, TOPs);
+            sv_setsv_mg(TARG, result);
+            PUSHs(TARG);
+        }
+        else {
+            PUSHs(result);
+        }
     }
     else
         PUSHi(retval);
@@ -3578,7 +3618,7 @@ PP(pp_chr)
 
     SvGETMAGIC(top);
     if (UNLIKELY(SvAMAGIC(top)))
-       top = sv_2num(top);
+        top = sv_2num(top);
     if (UNLIKELY(isinfnansv(top)))
         Perl_croak(aTHX_ "Cannot chr %" NVgf, SvNV(top));
     else {
@@ -3588,12 +3628,12 @@ PP(pp_chr)
                 ((SvNOKp(top) || (SvOK(top) && !SvIsUV(top)))
                  && SvNV_nomg(top) < 0.0)))
         {
-           if (ckWARN(WARN_UTF8)) {
-               if (SvGMAGICAL(top)) {
-                   SV *top2 = sv_newmortal();
-                   sv_setsv_nomg(top2, top);
-                   top = top2;
-               }
+            if (ckWARN(WARN_UTF8)) {
+                if (SvGMAGICAL(top)) {
+                    SV *top2 = sv_newmortal();
+                    sv_setsv_nomg(top2, top);
+                    top = top2;
+                }
                 Perl_warner(aTHX_ packWARN(WARN_UTF8),
                             "Invalid negative number (%" SVf ") in chr", SVfARG(top));
             }
@@ -3606,14 +3646,14 @@ PP(pp_chr)
     SvUPGRADE(TARG,SVt_PV);
 
     if (value > 255 && !IN_BYTES) {
-       SvGROW(TARG, (STRLEN)UVCHR_SKIP(value)+1);
-       tmps = (char*)uvchr_to_utf8_flags((U8*)SvPVX(TARG), value, 0);
-       SvCUR_set(TARG, tmps - SvPVX_const(TARG));
-       *tmps = '\0';
-       (void)SvPOK_only(TARG);
-       SvUTF8_on(TARG);
-       SETTARG;
-       return NORMAL;
+        SvGROW(TARG, (STRLEN)UVCHR_SKIP(value)+1);
+        tmps = (char*)uvchr_to_utf8_flags((U8*)SvPVX(TARG), value, 0);
+        SvCUR_set(TARG, tmps - SvPVX_const(TARG));
+        *tmps = '\0';
+        (void)SvPOK_only(TARG);
+        SvUTF8_on(TARG);
+        SETTARG;
+        return NORMAL;
     }
 
     SvGROW(TARG,2);
@@ -3637,40 +3677,32 @@ PP(pp_crypt)
 
     if (DO_UTF8(left)) {
          /* If Unicode, try to downgrade.
-         * If not possible, croak.
-         * Yes, we made this up.  */
-        SV* const tsv = newSVpvn_flags(tmps, len, SVf_UTF8|SVs_TEMP);
+          * If not possible, croak.
+          * Yes, we made this up.  */
+         SV* const tsv = newSVpvn_flags(tmps, len, SVf_UTF8|SVs_TEMP);
 
-        sv_utf8_downgrade(tsv, FALSE);
-        tmps = SvPV_const(tsv, len);
+         sv_utf8_downgrade(tsv, FALSE);
+         tmps = SvPV_const(tsv, len);
     }
-#   ifdef USE_ITHREADS
-#     ifdef HAS_CRYPT_R
+#  ifdef USE_ITHREADS
+#    ifdef HAS_CRYPT_R
     if (!PL_reentrant_buffer->_crypt_struct_buffer) {
       /* This should be threadsafe because in ithreads there is only
        * one thread per interpreter.  If this would not be true,
        * we would need a mutex to protect this malloc. */
         PL_reentrant_buffer->_crypt_struct_buffer =
-         (struct crypt_data *)safemalloc(sizeof(struct crypt_data));
-#if defined(__GLIBC__) || defined(__EMX__)
-       if (PL_reentrant_buffer->_crypt_struct_buffer) {
-           PL_reentrant_buffer->_crypt_struct_buffer->initialized = 0;
-#if (defined(__GLIBC__) && __GLIBC__ == 2) && \
-    (defined(__GLIBC_MINOR__) && __GLIBC_MINOR__ >= 2 && __GLIBC_MINOR__ < 4)
-           /* work around glibc-2.2.5 bug, has been fixed at some
-            * time in glibc-2.3.X */
-           PL_reentrant_buffer->_crypt_struct_buffer->current_saltbits = 0;
-#endif
-       }
-#endif
+          (struct crypt_data *)safemalloc(sizeof(struct crypt_data));
+#      if defined(__GLIBC__) || defined(__EMX__)
+        if (PL_reentrant_buffer->_crypt_struct_buffer) {
+            PL_reentrant_buffer->_crypt_struct_buffer->initialized = 0;
+        }
+#      endif
     }
-#     endif /* HAS_CRYPT_R */
-#   endif /* USE_ITHREADS */
-#   ifdef FCRYPT
-    sv_setpv(TARG, fcrypt(tmps, SvPV_nolen_const(right)));
-#   else
+#    endif /* HAS_CRYPT_R */
+#  endif /* USE_ITHREADS */
+
     sv_setpv(TARG, PerlProc_crypt(tmps, SvPV_nolen_const(right)));
-#   endif
+
     SvUTF8_off(TARG);
     SETTARG;
     RETURN;
@@ -3706,10 +3738,10 @@ PP(pp_ucfirst)
     U8 *d;
     U8 tmpbuf[UTF8_MAXBYTES_CASE+1];
     STRLEN ulen;    /* ulen is the byte length of the original Unicode character
-                    * stored as UTF-8 at s. */
+                     * stored as UTF-8 at s. */
     STRLEN tculen;  /* tculen is the byte length of the freshly titlecased (or
-                    * lowercased) character stored in tmpbuf.  May be either
-                    * UTF-8 or not, but in either case is the number of bytes */
+                     * lowercased) character stored in tmpbuf.  May be either
+                     * UTF-8 or not, but in either case is the number of bytes */
     bool remove_dot_above = FALSE;
 
     s = (const U8*)SvPV_const(source, slen);
@@ -3732,25 +3764,26 @@ PP(pp_ucfirst)
      * or even if have to convert the dest to UTF-8 when the source isn't */
 
     if (! slen) {   /* If empty */
-       need = 1; /* still need a trailing NUL */
-       ulen = 0;
+        need = 1; /* still need a trailing NUL */
+        ulen = 0;
         *tmpbuf = '\0';
     }
     else if (DO_UTF8(source)) {        /* Is the source utf8? */
-       doing_utf8 = TRUE;
+        doing_utf8 = TRUE;
         ulen = UTF8SKIP(s);
+
         if (op_type == OP_UCFIRST) {
 #ifdef USE_LOCALE_CTYPE
-           _toTITLE_utf8_flags(s, s +slen, tmpbuf, &tculen, IN_LC_RUNTIME(LC_CTYPE));
+            _toTITLE_utf8_flags(s, s +slen, tmpbuf, &tculen, IN_LC_RUNTIME(LC_CTYPE));
 #else
-           _toTITLE_utf8_flags(s, s +slen, tmpbuf, &tculen, 0);
+            _toTITLE_utf8_flags(s, s +slen, tmpbuf, &tculen, 0);
 #endif
-       }
+        }
         else {
 
 #ifdef USE_LOCALE_CTYPE
 
-           _toLOWER_utf8_flags(s, s + slen, tmpbuf, &tculen, IN_LC_RUNTIME(LC_CTYPE));
+            _toLOWER_utf8_flags(s, s + slen, tmpbuf, &tculen, IN_LC_RUNTIME(LC_CTYPE));
 
             /* In turkic locales, lower casing an 'I' normally yields U+0131,
              * LATIN SMALL LETTER DOTLESS I, but not if the grapheme also
@@ -3782,7 +3815,7 @@ PP(pp_ucfirst)
 #else
             PERL_UNUSED_VAR(remove_dot_above);
 
-           _toLOWER_utf8_flags(s, s + slen, tmpbuf, &tculen, 0);
+            _toLOWER_utf8_flags(s, s + slen, tmpbuf, &tculen, 0);
 #endif
 
         }
@@ -3792,12 +3825,12 @@ PP(pp_ucfirst)
         need = slen + 1 - ulen + tculen;
     }
     else { /* Non-zero length, non-UTF-8,  Need to consider locale and if
-           * latin1 is treated as caseless.  Note that a locale takes
-           * precedence */
-       ulen = 1;       /* Original character is 1 byte */
-       tculen = 1;     /* Most characters will require one byte, but this will
-                        * need to be overridden for the tricky ones */
-       need = slen + 1;
+            * latin1 is treated as caseless.  Note that a locale takes
+            * precedence */
+        ulen = 1;      /* Original character is 1 byte */
+        tculen = 1;    /* Most characters will require one byte, but this will
+                         * need to be overridden for the tricky ones */
+        need = slen + 1;
 
 
 #ifdef USE_LOCALE_CTYPE
@@ -3856,85 +3889,85 @@ PP(pp_ucfirst)
             /* Here, is ucfirst non-UTF-8, not in locale (unless that locale is
              * non-turkic UTF-8, which we treat as not in locale), and cased
              * latin1 */
-           UV title_ord;
+            UV title_ord;
 #ifdef USE_LOCALE_CTYPE
       do_uni_rules:
 #endif
 
-           title_ord = _to_upper_title_latin1(*s, tmpbuf, &tculen, 's');
-           if (tculen > 1) {
-               assert(tculen == 2);
+            title_ord = _to_upper_title_latin1(*s, tmpbuf, &tculen, 's');
+            if (tculen > 1) {
+                assert(tculen == 2);
 
                 /* If the result is an upper Latin1-range character, it can
                  * still be represented in one byte, which is its ordinal */
-               if (UTF8_IS_DOWNGRADEABLE_START(*tmpbuf)) {
-                   *tmpbuf = (U8) title_ord;
-                   tculen = 1;
-               }
-               else {
+                if (UTF8_IS_DOWNGRADEABLE_START(*tmpbuf)) {
+                    *tmpbuf = (U8) title_ord;
+                    tculen = 1;
+                }
+                else {
                     /* Otherwise it became more than one ASCII character (in
                      * the case of LATIN_SMALL_LETTER_SHARP_S) or changed to
                      * beyond Latin1, so the number of bytes changed, so can't
                      * replace just the first character in place. */
-                   inplace = FALSE;
+                    inplace = FALSE;
 
                     /* If the result won't fit in a byte, the entire result
                      * will have to be in UTF-8.  Allocate enough space for the
                      * expanded first byte, and if UTF-8, the rest of the input
                      * string, some or all of which may also expand to two
                      * bytes, plus the terminating NUL. */
-                   if (title_ord > 255) {
-                       doing_utf8 = TRUE;
-                       convert_source_to_utf8 = TRUE;
-                       need = slen
+                    if (title_ord > 255) {
+                        doing_utf8 = TRUE;
+                        convert_source_to_utf8 = TRUE;
+                        need = slen
                             + variant_under_utf8_count(s, s + slen)
                             + 1;
 
                         /* The (converted) UTF-8 and UTF-EBCDIC lengths of all
                          * characters whose title case is above 255 is
                          * 2. */
-                       ulen = 2;
-                   }
+                        ulen = 2;
+                    }
                     else { /* LATIN_SMALL_LETTER_SHARP_S expands by 1 byte */
-                       need = slen + 1 + 1;
-                   }
-               }
-           }
-       } /* End of use Unicode (Latin1) semantics */
+                        need = slen + 1 + 1;
+                    }
+                }
+            }
+        } /* End of use Unicode (Latin1) semantics */
     } /* End of changing the case of the first character */
 
     /* Here, have the first character's changed case stored in tmpbuf.  Ready to
      * generate the result */
     if (inplace) {
 
-       /* We can convert in place.  This means we change just the first
-        * character without disturbing the rest; no need to grow */
-       dest = source;
-       s = d = (U8*)SvPV_force_nomg(source, slen);
+        /* We can convert in place.  This means we change just the first
+         * character without disturbing the rest; no need to grow */
+        dest = source;
+        s = d = (U8*)SvPV_force_nomg(source, slen);
     } else {
-       dTARGET;
+        dTARGET;
 
-       dest = TARG;
+        dest = TARG;
 
-       /* Here, we can't convert in place; we earlier calculated how much
-        * space we will need, so grow to accommodate that */
-       SvUPGRADE(dest, SVt_PV);
-       d = (U8*)SvGROW(dest, need);
-       (void)SvPOK_only(dest);
+        /* Here, we can't convert in place; we earlier calculated how much
+         * space we will need, so grow to accommodate that */
+        SvUPGRADE(dest, SVt_PV);
+        d = (U8*)SvGROW(dest, need);
+        (void)SvPOK_only(dest);
 
-       SETs(dest);
+        SETs(dest);
     }
 
     if (doing_utf8) {
-       if (! inplace) {
-           if (! convert_source_to_utf8) {
+        if (! inplace) {
+            if (! convert_source_to_utf8) {
 
-               /* Here  both source and dest are in UTF-8, but have to create
-                * the entire output.  We initialize the result to be the
-                * title/lower cased first character, and then append the rest
-                * of the string. */
-               sv_setpvn(dest, (char*)tmpbuf, tculen);
-               if (slen > ulen) {
+                /* Here  both source and dest are in UTF-8, but have to create
+                 * the entire output.  We initialize the result to be the
+                 * title/lower cased first character, and then append the rest
+                 * of the string. */
+                sv_setpvn(dest, (char*)tmpbuf, tculen);
+                if (slen > ulen) {
 
                     /* But this boolean being set means we are in a turkic
                      * locale, and there is a DOT character that needs to be
@@ -3958,68 +3991,68 @@ PP(pp_ucfirst)
 
                     /* The rest of the string can be concatenated unchanged,
                      * all at once */
-                   sv_catpvn(dest, (char*)(s + ulen), slen - ulen);
-               }
-           }
-           else {
-               const U8 *const send = s + slen;
-
-               /* Here the dest needs to be in UTF-8, but the source isn't,
-                * except we earlier UTF-8'd the first character of the source
-                * into tmpbuf.  First put that into dest, and then append the
-                * rest of the source, converting it to UTF-8 as we go. */
-
-               /* Assert tculen is 2 here because the only characters that
-                * get to this part of the code have 2-byte UTF-8 equivalents */
+                    sv_catpvn(dest, (char*)(s + ulen), slen - ulen);
+                }
+            }
+            else {
+                const U8 *const send = s + slen;
+
+                /* Here the dest needs to be in UTF-8, but the source isn't,
+                 * except we earlier UTF-8'd the first character of the source
+                 * into tmpbuf.  First put that into dest, and then append the
+                 * rest of the source, converting it to UTF-8 as we go. */
+
+                /* Assert tculen is 2 here because the only characters that
+                 * get to this part of the code have 2-byte UTF-8 equivalents */
                 assert(tculen == 2);
-               *d++ = *tmpbuf;
-               *d++ = *(tmpbuf + 1);
-               s++;    /* We have just processed the 1st char */
+                *d++ = *tmpbuf;
+                *d++ = *(tmpbuf + 1);
+                s++;   /* We have just processed the 1st char */
 
                 while (s < send) {
                     append_utf8_from_native_byte(*s, &d);
                     s++;
                 }
 
-               *d = '\0';
-               SvCUR_set(dest, d - (U8*)SvPVX_const(dest));
-           }
-           SvUTF8_on(dest);
-       }
-       else {   /* in-place UTF-8.  Just overwrite the first character */
-           Copy(tmpbuf, d, tculen, U8);
-           SvCUR_set(dest, need - 1);
-       }
+                *d = '\0';
+                SvCUR_set(dest, d - (U8*)SvPVX_const(dest));
+            }
+            SvUTF8_on(dest);
+        }
+        else {   /* in-place UTF-8.  Just overwrite the first character */
+            Copy(tmpbuf, d, tculen, U8);
+            SvCUR_set(dest, need - 1);
+        }
 
     }
     else {  /* Neither source nor dest are, nor need to be UTF-8 */
-       if (slen) {
-           if (inplace) {  /* in-place, only need to change the 1st char */
-               *d = *tmpbuf;
-           }
-           else {      /* Not in-place */
-
-               /* Copy the case-changed character(s) from tmpbuf */
-               Copy(tmpbuf, d, tculen, U8);
-               d += tculen - 1; /* Code below expects d to point to final
-                                 * character stored */
-           }
-       }
-       else {  /* empty source */
-           /* See bug #39028: Don't taint if empty  */
-           *d = *s;
-       }
-
-       /* In a "use bytes" we don't treat the source as UTF-8, but, still want
-        * the destination to retain that flag */
-       if (DO_UTF8(source))
-           SvUTF8_on(dest);
-
-       if (!inplace) { /* Finish the rest of the string, unchanged */
-           /* This will copy the trailing NUL  */
-           Copy(s + 1, d + 1, slen, U8);
-           SvCUR_set(dest, need - 1);
-       }
+        if (slen) {
+            if (inplace) {  /* in-place, only need to change the 1st char */
+                *d = *tmpbuf;
+            }
+            else {     /* Not in-place */
+
+                /* Copy the case-changed character(s) from tmpbuf */
+                Copy(tmpbuf, d, tculen, U8);
+                d += tculen - 1; /* Code below expects d to point to final
+                                  * character stored */
+            }
+        }
+        else { /* empty source */
+            /* See bug #39028: Don't taint if empty  */
+            *d = *s;
+        }
+
+        /* In a "use bytes" we don't treat the source as UTF-8, but, still want
+         * the destination to retain that flag */
+        if (DO_UTF8(source))
+            SvUTF8_on(dest);
+
+        if (!inplace) {        /* Finish the rest of the string, unchanged */
+            /* This will copy the trailing NUL  */
+            Copy(s + 1, d + 1, slen, U8);
+            SvCUR_set(dest, need - 1);
+        }
     }
 #ifdef USE_LOCALE_CTYPE
     if (IN_LC_RUNTIME(LC_CTYPE)) {
@@ -4028,14 +4061,13 @@ PP(pp_ucfirst)
     }
 #endif
     if (dest != source && SvTAINTED(source))
-       SvTAINT(dest);
+        SvTAINT(dest);
     SvSETMAGIC(dest);
     return NORMAL;
 }
 
 PP(pp_uc)
 {
-    dVAR;
     dSP;
     SV *source = TOPs;
     STRLEN len;
@@ -4047,9 +4079,9 @@ PP(pp_uc)
     SvGETMAGIC(source);
 
     if (   SvPADTMP(source)
-       && !SvREADONLY(source) && SvPOK(source)
-       && !DO_UTF8(source)
-       && (
+        && !SvREADONLY(source) && SvPOK(source)
+        && !DO_UTF8(source)
+        && (
 #ifdef USE_LOCALE_CTYPE
             (IN_LC_RUNTIME(LC_CTYPE))
             ? ! IN_UTF8_CTYPE_LOCALE
@@ -4067,22 +4099,22 @@ PP(pp_uc)
          * that latter becomes irrelevant in the above test; instead for
          * locale, the size can't normally change, except if the locale is a
          * UTF-8 one */
-       dest = source;
-       s = d = (U8*)SvPV_force_nomg(source, len);
-       min = len + 1;
+        dest = source;
+        s = d = (U8*)SvPV_force_nomg(source, len);
+        min = len + 1;
     } else {
-       dTARGET;
+        dTARGET;
 
-       dest = TARG;
+        dest = TARG;
 
-       s = (const U8*)SvPV_nomg_const(source, len);
-       min = len + 1;
+        s = (const U8*)SvPV_nomg_const(source, len);
+        min = len + 1;
 
-       SvUPGRADE(dest, SVt_PV);
-       d = (U8*)SvGROW(dest, min);
-       (void)SvPOK_only(dest);
+        SvUPGRADE(dest, SVt_PV);
+        d = (U8*)SvGROW(dest, min);
+        (void)SvPOK_only(dest);
 
-       SETs(dest);
+        SETs(dest);
     }
 
 #ifdef USE_LOCALE_CTYPE
@@ -4097,28 +4129,28 @@ PP(pp_uc)
        to check DO_UTF8 again here.  */
 
     if (DO_UTF8(source)) {
-       const U8 *const send = s + len;
-       U8 tmpbuf[UTF8_MAXBYTES_CASE+1];
+        const U8 *const send = s + len;
+        U8 tmpbuf[UTF8_MAXBYTES_CASE+1];
 
 #define GREEK_CAPITAL_LETTER_IOTA 0x0399
 #define COMBINING_GREEK_YPOGEGRAMMENI 0x0345
-       /* All occurrences of these are to be moved to follow any other marks.
-        * This is context-dependent.  We may not be passed enough context to
-        * move the iota subscript beyond all of them, but we do the best we can
-        * with what we're given.  The result is always better than if we
-        * hadn't done this.  And, the problem would only arise if we are
-        * passed a character without all its combining marks, which would be
-        * the caller's mistake.  The information this is based on comes from a
-        * comment in Unicode SpecialCasing.txt, (and the Standard's text
-        * itself) and so can't be checked properly to see if it ever gets
-        * revised.  But the likelihood of it changing is remote */
-       bool in_iota_subscript = FALSE;
-
-       while (s < send) {
-           STRLEN u;
-           STRLEN ulen;
-           UV uv;
-           if (UNLIKELY(in_iota_subscript)) {
+        /* All occurrences of these are to be moved to follow any other marks.
+         * This is context-dependent.  We may not be passed enough context to
+         * move the iota subscript beyond all of them, but we do the best we can
+         * with what we're given.  The result is always better than if we
+         * hadn't done this.  And, the problem would only arise if we are
+         * passed a character without all its combining marks, which would be
+         * the caller's mistake.  The information this is based on comes from a
+         * comment in Unicode SpecialCasing.txt, (and the Standard's text
+         * itself) and so can't be checked properly to see if it ever gets
+         * revised.  But the likelihood of it changing is remote */
+        bool in_iota_subscript = FALSE;
+
+        while (s < send) {
+            STRLEN u;
+            STRLEN ulen;
+            UV uv;
+            if (UNLIKELY(in_iota_subscript)) {
                 UV cp = utf8_to_uvchr_buf(s, send, NULL);
 
                 if (! _invlist_contains_cp(PL_utf8_mark, cp)) {
@@ -4162,47 +4194,47 @@ PP(pp_uc)
                 d += ulen;
             }
             s += u;
-       }
-       if (in_iota_subscript) {
+        }
+        if (in_iota_subscript) {
             *d++ = UTF8_TWO_BYTE_HI(GREEK_CAPITAL_LETTER_IOTA);
             *d++ = UTF8_TWO_BYTE_LO(GREEK_CAPITAL_LETTER_IOTA);
-       }
-       SvUTF8_on(dest);
-       *d = '\0';
+        }
+        SvUTF8_on(dest);
+        *d = '\0';
 
-       SvCUR_set(dest, d - (U8*)SvPVX_const(dest));
+        SvCUR_set(dest, d - (U8*)SvPVX_const(dest));
     }
     else {     /* Not UTF-8 */
-       if (len) {
-           const U8 *const send = s + len;
+        if (len) {
+            const U8 *const send = s + len;
 
-           /* Use locale casing if in locale; regular style if not treating
-            * latin1 as having case; otherwise the latin1 casing.  Do the
-            * whole thing in a tight loop, for speed, */
+            /* Use locale casing if in locale; regular style if not treating
+             * latin1 as having case; otherwise the latin1 casing.  Do the
+             * whole thing in a tight loop, for speed, */
 #ifdef USE_LOCALE_CTYPE
-           if (IN_LC_RUNTIME(LC_CTYPE)) {
+            if (IN_LC_RUNTIME(LC_CTYPE)) {
                 if (IN_UTF8_CTYPE_LOCALE) {
                     goto do_uni_rules;
                 }
-               for (; s < send; d++, s++)
+                for (; s < send; d++, s++)
                     *d = (U8) toUPPER_LC(*s);
-           }
-           else
+            }
+            else
 #endif
                  if (! IN_UNI_8_BIT) {
-               for (; s < send; d++, s++) {
-                   *d = toUPPER(*s);
-               }
-           }
-           else {
+                for (; s < send; d++, s++) {
+                    *d = toUPPER(*s);
+                }
+            }
+            else {
 #ifdef USE_LOCALE_CTYPE
           do_uni_rules:
 #endif
-               for (; s < send; d++, s++) {
+                for (; s < send; d++, s++) {
                     Size_t extra;
 
-                   *d = toUPPER_LATIN1_MOD(*s);
-                   if (   LIKELY(*d != LATIN_SMALL_LETTER_Y_WITH_DIAERESIS)
+                    *d = toUPPER_LATIN1_MOD(*s);
+                    if (   LIKELY(*d != LATIN_SMALL_LETTER_Y_WITH_DIAERESIS)
 
 #ifdef USE_LOCALE_CTYPE
 
@@ -4215,7 +4247,7 @@ PP(pp_uc)
                         continue;
                     }
 
-                   /* The mainstream case is the tight loop above.  To avoid
+                    /* The mainstream case is the tight loop above.  To avoid
                      * extra tests in that, all three characters that always
                      * require special handling are mapped by the MOD to the
                      * one tested just above.  Use the source to distinguish
@@ -4224,22 +4256,22 @@ PP(pp_uc)
 #if    UNICODE_MAJOR_VERSION > 2                                        \
    || (UNICODE_MAJOR_VERSION == 2 && UNICODE_DOT_VERSION >= 1          \
                                   && UNICODE_DOT_DOT_VERSION >= 8)
-                   if (*s == LATIN_SMALL_LETTER_SHARP_S) {
-
-                       /* uc() of this requires 2 characters, but they are
-                        * ASCII.  If not enough room, grow the string */
-                       if (SvLEN(dest) < ++min) {
-                           const UV o = d - (U8*)SvPVX_const(dest);
-                           d = o + (U8*) SvGROW(dest, min);
-                       }
-                       *d++ = 'S'; *d = 'S'; /* upper case is 'SS' */
-                       continue;   /* Back to the tight loop; still in ASCII */
-                   }
+                    if (*s == LATIN_SMALL_LETTER_SHARP_S) {
+
+                        /* uc() of this requires 2 characters, but they are
+                         * ASCII.  If not enough room, grow the string */
+                        if (SvLEN(dest) < ++min) {
+                            const UV o = d - (U8*)SvPVX_const(dest);
+                            d = o + (U8*) SvGROW(dest, min);
+                        }
+                        *d++ = 'S'; *d = 'S'; /* upper case is 'SS' */
+                        continue;   /* Back to the tight loop; still in ASCII */
+                    }
 #endif
 
-                   /* The other special handling characters have their
-                    * upper cases outside the latin1 range, hence need to be
-                    * in UTF-8, so the whole result needs to be in UTF-8.
+                    /* The other special handling characters have their
+                     * upper cases outside the latin1 range, hence need to be
+                     * in UTF-8, so the whole result needs to be in UTF-8.
                      *
                      * So, here we are somewhere in the middle of processing a
                      * non-UTF-8 string, and realize that we will have to
@@ -4290,19 +4322,19 @@ PP(pp_uc)
 #endif
 
                     /* Convert what we have so far into UTF-8, telling the
-                    * function that we know it should be converted, and to
-                    * allow extra space for what we haven't processed yet.
+                     * function that we know it should be converted, and to
+                     * allow extra space for what we haven't processed yet.
                      *
                      * This may cause the string pointer to move, so need to
                      * save and re-find it. */
 
-                   len = d - (U8*)SvPVX_const(dest);
-                   SvCUR_set(dest, len);
-                   len = sv_utf8_upgrade_flags_grow(dest,
-                                               SV_GMAGIC|SV_FORCE_UTF8_UPGRADE,
+                    len = d - (U8*)SvPVX_const(dest);
+                    SvCUR_set(dest, len);
+                    len = sv_utf8_upgrade_flags_grow(dest,
+                                                SV_GMAGIC|SV_FORCE_UTF8_UPGRADE,
                                                 extra
                                               + 1 /* trailing NUL */ );
-                   d = (U8*)SvPVX(dest) + len;
+                    d = (U8*)SvPVX(dest) + len;
 
                     /* Now process the remainder of the source, simultaneously
                      * converting to upper and UTF-8.
@@ -4336,15 +4368,15 @@ PP(pp_uc)
                     /* Here have processed the whole source; no need to
                      * continue with the outer loop.  Each character has been
                      * converted to upper case and converted to UTF-8. */
-                   break;
-               } /* End of processing all latin1-style chars */
-           } /* End of processing all chars */
-       } /* End of source is not empty */
-
-       if (source != dest) {
-           *d = '\0';  /* Here d points to 1 after last char, add NUL */
-           SvCUR_set(dest, d - (U8*)SvPVX_const(dest));
-       }
+                    break;
+                } /* End of processing all latin1-style chars */
+            } /* End of processing all chars */
+        } /* End of source is not empty */
+
+        if (source != dest) {
+            *d = '\0';  /* Here d points to 1 after last char, add NUL */
+            SvCUR_set(dest, d - (U8*)SvPVX_const(dest));
+        }
     } /* End of isn't utf8 */
 #ifdef USE_LOCALE_CTYPE
     if (IN_LC_RUNTIME(LC_CTYPE)) {
@@ -4353,7 +4385,7 @@ PP(pp_uc)
     }
 #endif
     if (dest != source && SvTAINTED(source))
-       SvTAINT(dest);
+        SvTAINT(dest);
     SvSETMAGIC(dest);
     return NORMAL;
 }
@@ -4372,8 +4404,8 @@ PP(pp_lc)
     SvGETMAGIC(source);
 
     if (   SvPADTMP(source)
-       && !SvREADONLY(source) && SvPOK(source)
-       && !DO_UTF8(source)
+        && !SvREADONLY(source) && SvPOK(source)
+        && !DO_UTF8(source)
 
 #ifdef USE_LOCALE_CTYPE
 
@@ -4387,22 +4419,22 @@ PP(pp_lc)
         /* We can convert in place, as, outside of Turkic UTF-8 locales,
          * lowercasing anything in the latin1 range (or else DO_UTF8 would have
          * been on) doesn't lengthen it. */
-       dest = source;
-       s = d = (U8*)SvPV_force_nomg(source, len);
-       min = len + 1;
+        dest = source;
+        s = d = (U8*)SvPV_force_nomg(source, len);
+        min = len + 1;
     } else {
-       dTARGET;
+        dTARGET;
 
-       dest = TARG;
+        dest = TARG;
 
-       s = (const U8*)SvPV_nomg_const(source, len);
-       min = len + 1;
+        s = (const U8*)SvPV_nomg_const(source, len);
+        min = len + 1;
 
-       SvUPGRADE(dest, SVt_PV);
-       d = (U8*)SvGROW(dest, min);
-       (void)SvPOK_only(dest);
+        SvUPGRADE(dest, SVt_PV);
+        d = (U8*)SvGROW(dest, min);
+        (void)SvPOK_only(dest);
 
-       SETs(dest);
+        SETs(dest);
     }
 
 #ifdef USE_LOCALE_CTYPE
@@ -4442,23 +4474,25 @@ PP(pp_lc)
         }
     }
 
+#else
+    PERL_UNUSED_VAR(has_turkic_I);
 #endif
 
     /* Overloaded values may have toggled the UTF-8 flag on source, so we need
        to check DO_UTF8 again here.  */
 
     if (DO_UTF8(source)) {
-       const U8 *const send = s + len;
-       U8 tmpbuf[UTF8_MAXBYTES_CASE+1];
+        const U8 *const send = s + len;
+        U8 tmpbuf[UTF8_MAXBYTES_CASE+1];
         bool remove_dot_above = FALSE;
 
-       while (s < send) {
-           const STRLEN u = UTF8SKIP(s);
-           STRLEN ulen;
+        while (s < send) {
+            const STRLEN u = UTF8SKIP(s);
+            STRLEN ulen;
 
 #ifdef USE_LOCALE_CTYPE
 
-           _toLOWER_utf8_flags(s, send, tmpbuf, &ulen, IN_LC_RUNTIME(LC_CTYPE));
+            _toLOWER_utf8_flags(s, send, tmpbuf, &ulen, IN_LC_RUNTIME(LC_CTYPE));
 
             /* If we are in a Turkic locale, we have to do more work.  As noted
              * in the comments for lcfirst, there is a special case if a 'I'
@@ -4486,44 +4520,44 @@ PP(pp_lc)
 #else
             PERL_UNUSED_VAR(remove_dot_above);
 
-           _toLOWER_utf8_flags(s, send, tmpbuf, &ulen, 0);
+            _toLOWER_utf8_flags(s, send, tmpbuf, &ulen, 0);
 #endif
 
             /* Here is where we would do context-sensitive actions for the
              * Greek final sigma.  See the commit message for 86510fb15 for why
              * there isn't any */
 
-           if (ulen > u && (SvLEN(dest) < (min += ulen - u))) {
-
-               /* If the eventually required minimum size outgrows the
-                * available space, we need to grow. */
-               const UV o = d - (U8*)SvPVX_const(dest);
-
-               /* If someone lowercases one million U+0130s we SvGROW() one
-                * million times.  Or we could try guessing how much to
-                * allocate without allocating too much.  Such is life.
-                * Another option would be to grow an extra byte or two more
-                * each time we need to grow, which would cut down the million
-                * to 500K, with little waste */
-               d = o + (U8*) SvGROW(dest, min);
-           }
-
-           /* Copy the newly lowercased letter to the output buffer we're
-            * building */
-           Copy(tmpbuf, d, ulen, U8);
-           d += ulen;
-           s += u;
-       }   /* End of looping through the source string */
-       SvUTF8_on(dest);
-       *d = '\0';
-       SvCUR_set(dest, d - (U8*)SvPVX_const(dest));
+            if (ulen > u && (SvLEN(dest) < (min += ulen - u))) {
+
+                /* If the eventually required minimum size outgrows the
+                 * available space, we need to grow. */
+                const UV o = d - (U8*)SvPVX_const(dest);
+
+                /* If someone lowercases one million U+0130s we SvGROW() one
+                 * million times.  Or we could try guessing how much to
+                 * allocate without allocating too much.  Such is life.
+                 * Another option would be to grow an extra byte or two more
+                 * each time we need to grow, which would cut down the million
+                 * to 500K, with little waste */
+                d = o + (U8*) SvGROW(dest, min);
+            }
+
+            /* Copy the newly lowercased letter to the output buffer we're
+             * building */
+            Copy(tmpbuf, d, ulen, U8);
+            d += ulen;
+            s += u;
+        }   /* End of looping through the source string */
+        SvUTF8_on(dest);
+        *d = '\0';
+        SvCUR_set(dest, d - (U8*)SvPVX_const(dest));
     } else {   /* 'source' not utf8 */
-       if (len) {
-           const U8 *const send = s + len;
+        if (len) {
+            const U8 *const send = s + len;
 
-           /* Use locale casing if in locale; regular style if not treating
-            * latin1 as having case; otherwise the latin1 casing.  Do the
-            * whole thing in a tight loop, for speed, */
+            /* Use locale casing if in locale; regular style if not treating
+             * latin1 as having case; otherwise the latin1 casing.  Do the
+             * whole thing in a tight loop, for speed, */
 #ifdef USE_LOCALE_CTYPE
             if (IN_LC_RUNTIME(LC_CTYPE)) {
                 if (LIKELY( ! has_turkic_I)) {
@@ -4543,23 +4577,23 @@ PP(pp_lc)
                     }
                 }
             }
-           else
+            else
 #endif
             if (! IN_UNI_8_BIT) {
-               for (; s < send; d++, s++) {
-                   *d = toLOWER(*s);
-               }
-           }
-           else {
-               for (; s < send; d++, s++) {
-                   *d = toLOWER_LATIN1(*s);
-               }
-           }
-       }
-       if (source != dest) {
-           *d = '\0';
-           SvCUR_set(dest, d - (U8*)SvPVX_const(dest));
-       }
+                for (; s < send; d++, s++) {
+                    *d = toLOWER(*s);
+                }
+            }
+            else {
+                for (; s < send; d++, s++) {
+                    *d = toLOWER_LATIN1(*s);
+                }
+            }
+        }
+        if (source != dest) {
+            *d = '\0';
+            SvCUR_set(dest, d - (U8*)SvPVX_const(dest));
+        }
     }
 #ifdef USE_LOCALE_CTYPE
     if (IN_LC_RUNTIME(LC_CTYPE)) {
@@ -4568,7 +4602,7 @@ PP(pp_lc)
     }
 #endif
     if (dest != source && SvTAINTED(source))
-       SvTAINT(dest);
+        SvTAINT(dest);
     SvSETMAGIC(dest);
     return NORMAL;
 }
@@ -4582,71 +4616,71 @@ PP(pp_quotemeta)
 
     SvUTF8_off(TARG);                          /* decontaminate */
     if (len) {
-       char *d;
-       SvUPGRADE(TARG, SVt_PV);
-       SvGROW(TARG, (len * 2) + 1);
-       d = SvPVX(TARG);
-       if (DO_UTF8(sv)) {
-           while (len) {
-               STRLEN ulen = UTF8SKIP(s);
-               bool to_quote = FALSE;
-
-               if (UTF8_IS_INVARIANT(*s)) {
-                   if (_isQUOTEMETA(*s)) {
-                       to_quote = TRUE;
-                   }
-               }
-               else if (UTF8_IS_NEXT_CHAR_DOWNGRADEABLE(s, s + len)) {
-                   if (
+        char *d;
+        SvUPGRADE(TARG, SVt_PV);
+        SvGROW(TARG, (len * 2) + 1);
+        d = SvPVX(TARG);
+        if (DO_UTF8(sv)) {
+            while (len) {
+                STRLEN ulen = UTF8SKIP(s);
+                bool to_quote = FALSE;
+
+                if (UTF8_IS_INVARIANT(*s)) {
+                    if (_isQUOTEMETA(*s)) {
+                        to_quote = TRUE;
+                    }
+                }
+                else if (UTF8_IS_NEXT_CHAR_DOWNGRADEABLE(s, s + len)) {
+                    if (
 #ifdef USE_LOCALE_CTYPE
-                   /* In locale, we quote all non-ASCII Latin1 chars.
-                    * Otherwise use the quoting rules */
+                    /* In locale, we quote all non-ASCII Latin1 chars.
+                     * Otherwise use the quoting rules */
 
-                   IN_LC_RUNTIME(LC_CTYPE)
-                       ||
+                    IN_LC_RUNTIME(LC_CTYPE)
+                        ||
 #endif
-                       _isQUOTEMETA(EIGHT_BIT_UTF8_TO_NATIVE(*s, *(s + 1))))
-                   {
-                       to_quote = TRUE;
-                   }
-               }
-               else if (is_QUOTEMETA_high(s)) {
-                   to_quote = TRUE;
-               }
-
-               if (to_quote) {
-                   *d++ = '\\';
-               }
-               if (ulen > len)
-                   ulen = len;
-               len -= ulen;
-               while (ulen--)
-                   *d++ = *s++;
-           }
-           SvUTF8_on(TARG);
-       }
-       else if (IN_UNI_8_BIT) {
-           while (len--) {
-               if (_isQUOTEMETA(*s))
-                   *d++ = '\\';
-               *d++ = *s++;
-           }
-       }
-       else {
-           /* For non UNI_8_BIT (and hence in locale) just quote all \W
-            * including everything above ASCII */
-           while (len--) {
-               if (!isWORDCHAR_A(*s))
-                   *d++ = '\\';
-               *d++ = *s++;
-           }
-       }
-       *d = '\0';
-       SvCUR_set(TARG, d - SvPVX_const(TARG));
-       (void)SvPOK_only_UTF8(TARG);
+                        _isQUOTEMETA(EIGHT_BIT_UTF8_TO_NATIVE(*s, *(s + 1))))
+                    {
+                        to_quote = TRUE;
+                    }
+                }
+                else if (is_QUOTEMETA_high(s)) {
+                    to_quote = TRUE;
+                }
+
+                if (to_quote) {
+                    *d++ = '\\';
+                }
+                if (ulen > len)
+                    ulen = len;
+                len -= ulen;
+                while (ulen--)
+                    *d++ = *s++;
+            }
+            SvUTF8_on(TARG);
+        }
+        else if (IN_UNI_8_BIT) {
+            while (len--) {
+                if (_isQUOTEMETA(*s))
+                    *d++ = '\\';
+                *d++ = *s++;
+            }
+        }
+        else {
+            /* For non UNI_8_BIT (and hence in locale) just quote all \W
+             * including everything above ASCII */
+            while (len--) {
+                if (!isWORDCHAR_A(*s))
+                    *d++ = '\\';
+                *d++ = *s++;
+            }
+        }
+        *d = '\0';
+        SvCUR_set(TARG, d - SvPVX_const(TARG));
+        (void)SvPOK_only_UTF8(TARG);
     }
     else
-       sv_setpvn(TARG, s, len);
+        sv_setpvn(TARG, s, len);
     SETTARG;
     return NORMAL;
 }
@@ -4689,9 +4723,9 @@ PP(pp_fc)
         s = (const U8*)SvPV_nomg_const(source, len);
     } else {
         if (ckWARN(WARN_UNINITIALIZED))
-           report_uninit(source);
-       s = (const U8*)"";
-       len = 0;
+            report_uninit(source);
+        s = (const U8*)"";
+        len = 0;
     }
 
     min = len + 1;
@@ -4794,7 +4828,7 @@ PP(pp_fc)
                         do {
                             extra++;
 
-                            s_peek = (U8 *) memchr(s_peek + 1, 'i',
+                            s_peek = (U8 *) memchr(s_peek + 1, 'I',
                                                    send - (s_peek + 1));
                         } while (s_peek != NULL);
                     }
@@ -4809,8 +4843,14 @@ PP(pp_fc)
                                               + 1 /* Trailing NUL */ );
                     d = (U8*)SvPVX(dest) + len;
 
-                    *d++ = UTF8_TWO_BYTE_HI(GREEK_SMALL_LETTER_MU);
-                    *d++ = UTF8_TWO_BYTE_LO(GREEK_SMALL_LETTER_MU);
+                    if (*s == 'I') {
+                        *d++ = UTF8_TWO_BYTE_HI(LATIN_SMALL_LETTER_DOTLESS_I);
+                        *d++ = UTF8_TWO_BYTE_LO(LATIN_SMALL_LETTER_DOTLESS_I);
+                    }
+                    else {
+                        *d++ = UTF8_TWO_BYTE_HI(GREEK_SMALL_LETTER_MU);
+                        *d++ = UTF8_TWO_BYTE_LO(GREEK_SMALL_LETTER_MU);
+                    }
                     s++;
 
                     for (; s < send; s++) {
@@ -4848,7 +4888,7 @@ PP(pp_fc)
     }
 #endif
     if (SvTAINTED(source))
-       SvTAINT(dest);
+        SvTAINT(dest);
     SvSETMAGIC(dest);
     RETURN;
 }
@@ -4862,59 +4902,59 @@ PP(pp_aslice)
     const I32 lval = (PL_op->op_flags & OPf_MOD || LVRET);
 
     if (SvTYPE(av) == SVt_PVAV) {
-       const bool localizing = PL_op->op_private & OPpLVAL_INTRO;
-       bool can_preserve = FALSE;
-
-       if (localizing) {
-           MAGIC *mg;
-           HV *stash;
-
-           can_preserve = SvCANEXISTDELETE(av);
-       }
-
-       if (lval && localizing) {
-           SV **svp;
-           SSize_t max = -1;
-           for (svp = MARK + 1; svp <= SP; svp++) {
-               const SSize_t elem = SvIV(*svp);
-               if (elem > max)
-                   max = elem;
-           }
-           if (max > AvMAX(av))
-               av_extend(av, max);
-       }
-
-       while (++MARK <= SP) {
-           SV **svp;
-           SSize_t elem = SvIV(*MARK);
-           bool preeminent = TRUE;
-
-           if (localizing && can_preserve) {
-               /* If we can determine whether the element exist,
-                * Try to preserve the existenceness of a tied array
-                * element by using EXISTS and DELETE if possible.
-                * Fallback to FETCH and STORE otherwise. */
-               preeminent = av_exists(av, elem);
-           }
-
-           svp = av_fetch(av, elem, lval);
-           if (lval) {
-               if (!svp || !*svp)
-                   DIE(aTHX_ PL_no_aelem, elem);
-               if (localizing) {
-                   if (preeminent)
-                       save_aelem(av, elem, svp);
-                   else
-                       SAVEADELETE(av, elem);
-               }
-           }
-           *MARK = svp ? *svp : &PL_sv_undef;
-       }
-    }
-    if (GIMME_V != G_ARRAY) {
-       MARK = ORIGMARK;
-       *++MARK = SP > ORIGMARK ? *SP : &PL_sv_undef;
-       SP = MARK;
+        const bool localizing = PL_op->op_private & OPpLVAL_INTRO;
+        bool can_preserve = FALSE;
+
+        if (localizing) {
+            MAGIC *mg;
+            HV *stash;
+
+            can_preserve = SvCANEXISTDELETE(av);
+        }
+
+        if (lval && localizing) {
+            SV **svp;
+            SSize_t max = -1;
+            for (svp = MARK + 1; svp <= SP; svp++) {
+                const SSize_t elem = SvIV(*svp);
+                if (elem > max)
+                    max = elem;
+            }
+            if (max > AvMAX(av))
+                av_extend(av, max);
+        }
+
+        while (++MARK <= SP) {
+            SV **svp;
+            SSize_t elem = SvIV(*MARK);
+            bool preeminent = TRUE;
+
+            if (localizing && can_preserve) {
+                /* If we can determine whether the element exist,
+                 * Try to preserve the existenceness of a tied array
+                 * element by using EXISTS and DELETE if possible.
+                 * Fallback to FETCH and STORE otherwise. */
+                preeminent = av_exists(av, elem);
+            }
+
+            svp = av_fetch(av, elem, lval);
+            if (lval) {
+                if (!svp || !*svp)
+                    DIE(aTHX_ PL_no_aelem, elem);
+                if (localizing) {
+                    if (preeminent)
+                        save_aelem(av, elem, svp);
+                    else
+                        SAVEADELETE(av, elem);
+                }
+            }
+            *MARK = svp ? *svp : &PL_sv_undef;
+        }
+    }
+    if (GIMME_V != G_LIST) {
+        MARK = ORIGMARK;
+        *++MARK = SP > ORIGMARK ? *SP : &PL_sv_undef;
+        SP = MARK;
     }
     RETURN;
 }
@@ -4931,15 +4971,15 @@ PP(pp_kvaslice)
        if (flags) {
            if (!(flags & OPpENTERSUB_INARGS))
                /* diag_listed_as: Can't modify %s in %s */
-              Perl_croak(aTHX_ "Can't modify index/value array slice in list assignment");
-          lval = flags;
+               Perl_croak(aTHX_ "Can't modify index/value array slice in list assignment");
+           lval = flags;
        }
     }
 
     MEXTEND(SP,items);
     while (items > 1) {
-       *(MARK+items*2-1) = *(MARK+items);
-       items--;
+        *(MARK+items*2-1) = *(MARK+items);
+        items--;
     }
     items = SP-MARK;
     SP += items;
@@ -4947,19 +4987,19 @@ PP(pp_kvaslice)
     while (++MARK <= SP) {
         SV **svp;
 
-       svp = av_fetch(av, SvIV(*MARK), lval);
+        svp = av_fetch(av, SvIV(*MARK), lval);
         if (lval) {
             if (!svp || !*svp || *svp == &PL_sv_undef) {
                 DIE(aTHX_ PL_no_aelem, SvIV(*MARK));
             }
-           *MARK = sv_mortalcopy(*MARK);
+            *MARK = sv_mortalcopy(*MARK);
         }
-       *++MARK = svp ? *svp : &PL_sv_undef;
+        *++MARK = svp ? *svp : &PL_sv_undef;
     }
-    if (GIMME_V != G_ARRAY) {
-       MARK = SP - items*2;
-       *++MARK = items > 0 ? *SP : &PL_sv_undef;
-       SP = MARK;
+    if (GIMME_V != G_LIST) {
+        MARK = SP - items*2;
+        *++MARK = items > 0 ? *SP : &PL_sv_undef;
+        SP = MARK;
     }
     RETURN;
 }
@@ -4973,18 +5013,18 @@ PP(pp_aeach)
     IV *iterp = Perl_av_iter_p(aTHX_ array);
     const IV current = (*iterp)++;
 
-    if (current > av_tindex(array)) {
-       *iterp = 0;
-       if (gimme == G_SCALAR)
-           RETPUSHUNDEF;
-       else
-           RETURN;
+    if (current > av_top_index(array)) {
+        *iterp = 0;
+        if (gimme == G_SCALAR)
+            RETPUSHUNDEF;
+        else
+            RETURN;
     }
 
     EXTEND(SP, 2);
     mPUSHi(current);
-    if (gimme == G_ARRAY) {
-       SV **const element = av_fetch(array, current, 0);
+    if (gimme == G_LIST) {
+        SV **const element = av_fetch(array, current, 0);
         PUSHs(element ? *element : &PL_sv_undef);
     }
     RETURN;
@@ -5000,10 +5040,10 @@ PP(pp_akeys)
     *Perl_av_iter_p(aTHX_ array) = 0;
 
     if (gimme == G_SCALAR) {
-       dTARGET;
-       PUSHi(av_tindex(array) + 1);
+        dTARGET;
+        PUSHi(av_count(array));
     }
-    else if (gimme == G_ARRAY) {
+    else if (gimme == G_LIST) {
       if (UNLIKELY(PL_op->op_private & OPpMAYBE_LVSUB)) {
         const I32 flags = is_lvalue_sub();
         if (flags && !(flags & OPpENTERSUB_INARGS))
@@ -5012,25 +5052,25 @@ PP(pp_akeys)
                       "Can't modify keys on array in list assignment");
       }
       {
-        IV n = Perl_av_len(aTHX_ array);
+        IV n = av_top_index(array);
         IV i;
 
         EXTEND(SP, n + 1);
 
-       if (  PL_op->op_type == OP_AKEYS
-          || (  PL_op->op_type == OP_AVHVSWITCH
-             && (PL_op->op_private & 3) + OP_AEACH == OP_AKEYS  ))
-       {
-           for (i = 0;  i <= n;  i++) {
-               mPUSHi(i);
-           }
-       }
-       else {
-           for (i = 0;  i <= n;  i++) {
-               SV *const *const elem = Perl_av_fetch(aTHX_ array, i, 0);
-               PUSHs(elem ? *elem : &PL_sv_undef);
-           }
-       }
+        if (  PL_op->op_type == OP_AKEYS
+           || (  PL_op->op_type == OP_AVHVSWITCH
+              && (PL_op->op_private & 3) + OP_AEACH == OP_AKEYS  ))
+        {
+            for (i = 0;  i <= n;  i++) {
+                mPUSHi(i);
+            }
+        }
+        else {
+            for (i = 0;  i <= n;  i++) {
+                SV *const *const elem = Perl_av_fetch(aTHX_ array, i, 0);
+                PUSHs(elem ? *elem : &PL_sv_undef);
+            }
+        }
       }
     }
     RETURN;
@@ -5049,16 +5089,16 @@ PP(pp_each)
 
     EXTEND(SP, 2);
     if (entry) {
-       SV* const sv = hv_iterkeysv(entry);
-       PUSHs(sv);
-       if (gimme == G_ARRAY) {
-           SV *val;
-           val = hv_iterval(hash, entry);
-           PUSHs(val);
-       }
+        SV* const sv = hv_iterkeysv(entry);
+        PUSHs(sv);
+        if (gimme == G_LIST) {
+            SV *val;
+            val = hv_iterval(hash, entry);
+            PUSHs(val);
+        }
     }
     else if (gimme == G_SCALAR)
-       RETPUSHUNDEF;
+        RETPUSHUNDEF;
 
     RETURN;
 }
@@ -5076,100 +5116,100 @@ S_do_delete_local(pTHX)
     SV **mark = sliced ? PL_stack_base + POPMARK : unsliced_keysv-1;
     dORIGMARK;
     const bool tied = SvRMAGICAL(osv)
-                           && mg_find((const SV *)osv, PERL_MAGIC_tied);
+                            && mg_find((const SV *)osv, PERL_MAGIC_tied);
     const bool can_preserve = SvCANEXISTDELETE(osv);
     const U32 type = SvTYPE(osv);
     SV ** const end = sliced ? SP : unsliced_keysv;
 
     if (type == SVt_PVHV) {                    /* hash element */
-           HV * const hv = MUTABLE_HV(osv);
-           while (++MARK <= end) {
-               SV * const keysv = *MARK;
-               SV *sv = NULL;
-               bool preeminent = TRUE;
-               if (can_preserve)
-                   preeminent = hv_exists_ent(hv, keysv, 0);
-               if (tied) {
-                   HE *he = hv_fetch_ent(hv, keysv, 1, 0);
-                   if (he)
-                       sv = HeVAL(he);
-                   else
-                       preeminent = FALSE;
-               }
-               else {
-                   sv = hv_delete_ent(hv, keysv, 0, 0);
-                   if (preeminent)
-                       SvREFCNT_inc_simple_void(sv); /* De-mortalize */
-               }
-               if (preeminent) {
-                   if (!sv) DIE(aTHX_ PL_no_helem_sv, SVfARG(keysv));
-                   save_helem_flags(hv, keysv, &sv, SAVEf_KEEPOLDELEM);
-                   if (tied) {
-                       *MARK = sv_mortalcopy(sv);
-                       mg_clear(sv);
-                   } else
-                       *MARK = sv;
-               }
-               else {
-                   SAVEHDELETE(hv, keysv);
-                   *MARK = &PL_sv_undef;
-               }
-           }
+            HV * const hv = MUTABLE_HV(osv);
+            while (++MARK <= end) {
+                SV * const keysv = *MARK;
+                SV *sv = NULL;
+                bool preeminent = TRUE;
+                if (can_preserve)
+                    preeminent = hv_exists_ent(hv, keysv, 0);
+                if (tied) {
+                    HE *he = hv_fetch_ent(hv, keysv, 1, 0);
+                    if (he)
+                        sv = HeVAL(he);
+                    else
+                        preeminent = FALSE;
+                }
+                else {
+                    sv = hv_delete_ent(hv, keysv, 0, 0);
+                    if (preeminent)
+                        SvREFCNT_inc_simple_void(sv); /* De-mortalize */
+                }
+                if (preeminent) {
+                    if (!sv) DIE(aTHX_ PL_no_helem_sv, SVfARG(keysv));
+                    save_helem_flags(hv, keysv, &sv, SAVEf_KEEPOLDELEM);
+                    if (tied) {
+                        *MARK = sv_mortalcopy(sv);
+                        mg_clear(sv);
+                    } else
+                        *MARK = sv;
+                }
+                else {
+                    SAVEHDELETE(hv, keysv);
+                    *MARK = &PL_sv_undef;
+                }
+            }
     }
     else if (type == SVt_PVAV) {                  /* array element */
-           if (PL_op->op_flags & OPf_SPECIAL) {
-               AV * const av = MUTABLE_AV(osv);
-               while (++MARK <= end) {
-                   SSize_t idx = SvIV(*MARK);
-                   SV *sv = NULL;
-                   bool preeminent = TRUE;
-                   if (can_preserve)
-                       preeminent = av_exists(av, idx);
-                   if (tied) {
-                       SV **svp = av_fetch(av, idx, 1);
-                       if (svp)
-                           sv = *svp;
-                       else
-                           preeminent = FALSE;
-                   }
-                   else {
-                       sv = av_delete(av, idx, 0);
-                       if (preeminent)
-                          SvREFCNT_inc_simple_void(sv); /* De-mortalize */
-                   }
-                   if (preeminent) {
-                       save_aelem_flags(av, idx, &sv, SAVEf_KEEPOLDELEM);
-                       if (tied) {
-                           *MARK = sv_mortalcopy(sv);
-                           mg_clear(sv);
-                       } else
-                           *MARK = sv;
-                   }
-                   else {
-                       SAVEADELETE(av, idx);
-                       *MARK = &PL_sv_undef;
-                   }
-               }
-           }
-           else
-               DIE(aTHX_ "panic: avhv_delete no longer supported");
+            if (PL_op->op_flags & OPf_SPECIAL) {
+                AV * const av = MUTABLE_AV(osv);
+                while (++MARK <= end) {
+                    SSize_t idx = SvIV(*MARK);
+                    SV *sv = NULL;
+                    bool preeminent = TRUE;
+                    if (can_preserve)
+                        preeminent = av_exists(av, idx);
+                    if (tied) {
+                        SV **svp = av_fetch(av, idx, 1);
+                        if (svp)
+                            sv = *svp;
+                        else
+                            preeminent = FALSE;
+                    }
+                    else {
+                        sv = av_delete(av, idx, 0);
+                        if (preeminent)
+                           SvREFCNT_inc_simple_void(sv); /* De-mortalize */
+                    }
+                    if (preeminent) {
+                        save_aelem_flags(av, idx, &sv, SAVEf_KEEPOLDELEM);
+                        if (tied) {
+                            *MARK = sv_mortalcopy(sv);
+                            mg_clear(sv);
+                        } else
+                            *MARK = sv;
+                    }
+                    else {
+                        SAVEADELETE(av, idx);
+                        *MARK = &PL_sv_undef;
+                    }
+                }
+            }
+            else
+                DIE(aTHX_ "panic: avhv_delete no longer supported");
     }
     else
-           DIE(aTHX_ "Not a HASH reference");
+            DIE(aTHX_ "Not a HASH reference");
     if (sliced) {
-       if (gimme == G_VOID)
-           SP = ORIGMARK;
-       else if (gimme == G_SCALAR) {
-           MARK = ORIGMARK;
-           if (SP > MARK)
-               *++MARK = *SP;
-           else
-               *++MARK = &PL_sv_undef;
-           SP = MARK;
-       }
+        if (gimme == G_VOID)
+            SP = ORIGMARK;
+        else if (gimme == G_SCALAR) {
+            MARK = ORIGMARK;
+            if (SP > MARK)
+                *++MARK = *SP;
+            else
+                *++MARK = &PL_sv_undef;
+            SP = MARK;
+        }
     }
     else if (gimme != G_VOID)
-       PUSHs(*unsliced_keysv);
+        PUSHs(*unsliced_keysv);
 
     RETURN;
 }
@@ -5181,15 +5221,15 @@ PP(pp_delete)
     I32 discard;
 
     if (PL_op->op_private & OPpLVAL_INTRO)
-       return do_delete_local();
+        return do_delete_local();
 
     gimme = GIMME_V;
     discard = (gimme == G_VOID) ? G_DISCARD : 0;
 
     if (PL_op->op_private & (OPpSLICE|OPpKVSLICE)) {
-       dMARK; dORIGMARK;
-       HV * const hv = MUTABLE_HV(POPs);
-       const U32 hvtype = SvTYPE(hv);
+        dMARK; dORIGMARK;
+        HV * const hv = MUTABLE_HV(POPs);
+        const U32 hvtype = SvTYPE(hv);
         int skip = 0;
         if (PL_op->op_private & OPpKVSLICE) {
             SSize_t items = SP - MARK;
@@ -5203,51 +5243,51 @@ PP(pp_delete)
             SP += items;
             skip = 1;
         }
-       if (hvtype == SVt_PVHV) {                       /* hash element */
+        if (hvtype == SVt_PVHV) {                      /* hash element */
             while ((MARK += (1+skip)) <= SP) {
                 SV * const sv = hv_delete_ent(hv, *(MARK-skip), discard, 0);
-               *MARK = sv ? sv : &PL_sv_undef;
-           }
-       }
-       else if (hvtype == SVt_PVAV) {                  /* array element */
+                *MARK = sv ? sv : &PL_sv_undef;
+            }
+        }
+        else if (hvtype == SVt_PVAV) {                  /* array element */
             if (PL_op->op_flags & OPf_SPECIAL) {
                 while ((MARK += (1+skip)) <= SP) {
                     SV * const sv = av_delete(MUTABLE_AV(hv), SvIV(*(MARK-skip)), discard);
                     *MARK = sv ? sv : &PL_sv_undef;
                 }
             }
-       }
-       else
-           DIE(aTHX_ "Not a HASH reference");
-       if (discard)
-           SP = ORIGMARK;
-       else if (gimme == G_SCALAR) {
-           MARK = ORIGMARK;
-           if (SP > MARK)
-               *++MARK = *SP;
-           else
-               *++MARK = &PL_sv_undef;
-           SP = MARK;
-       }
+        }
+        else
+            DIE(aTHX_ "Not a HASH reference");
+        if (discard)
+            SP = ORIGMARK;
+        else if (gimme == G_SCALAR) {
+            MARK = ORIGMARK;
+            if (SP > MARK)
+                *++MARK = *SP;
+            else
+                *++MARK = &PL_sv_undef;
+            SP = MARK;
+        }
     }
     else {
-       SV *keysv = POPs;
-       HV * const hv = MUTABLE_HV(POPs);
-       SV *sv = NULL;
-       if (SvTYPE(hv) == SVt_PVHV)
-           sv = hv_delete_ent(hv, keysv, discard, 0);
-       else if (SvTYPE(hv) == SVt_PVAV) {
-           if (PL_op->op_flags & OPf_SPECIAL)
-               sv = av_delete(MUTABLE_AV(hv), SvIV(keysv), discard);
-           else
-               DIE(aTHX_ "panic: avhv_delete no longer supported");
-       }
-       else
-           DIE(aTHX_ "Not a HASH reference");
-       if (!sv)
-           sv = &PL_sv_undef;
-       if (!discard)
-           PUSHs(sv);
+        SV *keysv = POPs;
+        HV * const hv = MUTABLE_HV(POPs);
+        SV *sv = NULL;
+        if (SvTYPE(hv) == SVt_PVHV)
+            sv = hv_delete_ent(hv, keysv, discard, 0);
+        else if (SvTYPE(hv) == SVt_PVAV) {
+            if (PL_op->op_flags & OPf_SPECIAL)
+                sv = av_delete(MUTABLE_AV(hv), SvIV(keysv), discard);
+            else
+                DIE(aTHX_ "panic: avhv_delete no longer supported");
+        }
+        else
+            DIE(aTHX_ "Not a HASH reference");
+        if (!sv)
+            sv = &PL_sv_undef;
+        if (!discard)
+            PUSHs(sv);
     }
     RETURN;
 }
@@ -5259,29 +5299,29 @@ PP(pp_exists)
     HV *hv;
 
     if (UNLIKELY( PL_op->op_private & OPpEXISTS_SUB )) {
-       GV *gv;
-       SV * const sv = POPs;
-       CV * const cv = sv_2cv(sv, &hv, &gv, 0);
-       if (cv)
-           RETPUSHYES;
-       if (gv && isGV(gv) && GvCV(gv) && !GvCVGEN(gv))
-           RETPUSHYES;
-       RETPUSHNO;
+        GV *gv;
+        SV * const sv = POPs;
+        CV * const cv = sv_2cv(sv, &hv, &gv, 0);
+        if (cv)
+            RETPUSHYES;
+        if (gv && isGV(gv) && GvCV(gv) && !GvCVGEN(gv))
+            RETPUSHYES;
+        RETPUSHNO;
     }
     tmpsv = POPs;
     hv = MUTABLE_HV(POPs);
     if (LIKELY( SvTYPE(hv) == SVt_PVHV )) {
-       if (hv_exists_ent(hv, tmpsv, 0))
-           RETPUSHYES;
+        if (hv_exists_ent(hv, tmpsv, 0))
+            RETPUSHYES;
     }
     else if (SvTYPE(hv) == SVt_PVAV) {
-       if (PL_op->op_flags & OPf_SPECIAL) {            /* array element */
-           if (av_exists(MUTABLE_AV(hv), SvIV(tmpsv)))
-               RETPUSHYES;
-       }
+        if (PL_op->op_flags & OPf_SPECIAL) {           /* array element */
+            if (av_exists(MUTABLE_AV(hv), SvIV(tmpsv)))
+                RETPUSHYES;
+        }
     }
     else {
-       DIE(aTHX_ "Not a HASH reference");
+        DIE(aTHX_ "Not a HASH reference");
     }
     RETPUSHNO;
 }
@@ -5298,8 +5338,8 @@ PP(pp_hslice)
         MAGIC *mg;
         HV *stash;
 
-       if (SvCANEXISTDELETE(hv))
-           can_preserve = TRUE;
+        if (SvCANEXISTDELETE(hv))
+            can_preserve = TRUE;
     }
 
     while (++MARK <= SP) {
@@ -5309,7 +5349,7 @@ PP(pp_hslice)
         bool preeminent = TRUE;
 
         if (localizing && can_preserve) {
-           /* If we can determine whether the element exist,
+            /* If we can determine whether the element exist,
              * try to preserve the existenceness of a tied hash
              * element by using EXISTS and DELETE if possible.
              * Fallback to FETCH and STORE otherwise. */
@@ -5324,21 +5364,21 @@ PP(pp_hslice)
                 DIE(aTHX_ PL_no_helem_sv, SVfARG(keysv));
             }
             if (localizing) {
-               if (HvNAME_get(hv) && isGV_or_RVCV(*svp))
-                   save_gp(MUTABLE_GV(*svp), !(PL_op->op_flags & OPf_SPECIAL));
-               else if (preeminent)
-                   save_helem_flags(hv, keysv, svp,
-                        (PL_op->op_flags & OPf_SPECIAL) ? 0 : SAVEf_SETMAGIC);
-               else
-                   SAVEHDELETE(hv, keysv);
+                if (HvNAME_get(hv) && isGV_or_RVCV(*svp))
+                    save_gp(MUTABLE_GV(*svp), !(PL_op->op_flags & OPf_SPECIAL));
+                else if (preeminent)
+                    save_helem_flags(hv, keysv, svp,
+                         (PL_op->op_flags & OPf_SPECIAL) ? 0 : SAVEf_SETMAGIC);
+                else
+                    SAVEHDELETE(hv, keysv);
             }
         }
         *MARK = svp && *svp ? *svp : &PL_sv_undef;
     }
-    if (GIMME_V != G_ARRAY) {
-       MARK = ORIGMARK;
-       *++MARK = SP > ORIGMARK ? *SP : &PL_sv_undef;
-       SP = MARK;
+    if (GIMME_V != G_LIST) {
+        MARK = ORIGMARK;
+        *++MARK = SP > ORIGMARK ? *SP : &PL_sv_undef;
+        SP = MARK;
     }
     RETURN;
 }
@@ -5355,16 +5395,16 @@ PP(pp_kvhslice)
        if (flags) {
            if (!(flags & OPpENTERSUB_INARGS))
                /* diag_listed_as: Can't modify %s in %s */
-              Perl_croak(aTHX_ "Can't modify key/value hash slice in %s assignment",
-                                GIMME_V == G_ARRAY ? "list" : "scalar");
-          lval = flags;
+               Perl_croak(aTHX_ "Can't modify key/value hash slice in %s assignment",
+                                 GIMME_V == G_LIST ? "list" : "scalar");
+           lval = flags;
        }
     }
 
     MEXTEND(SP,items);
     while (items > 1) {
-       *(MARK+items*2-1) = *(MARK+items);
-       items--;
+        *(MARK+items*2-1) = *(MARK+items);
+        items--;
     }
     items = SP-MARK;
     SP += items;
@@ -5381,14 +5421,14 @@ PP(pp_kvhslice)
             if (!svp || !*svp || *svp == &PL_sv_undef) {
                 DIE(aTHX_ PL_no_helem_sv, SVfARG(keysv));
             }
-           *MARK = sv_mortalcopy(*MARK);
+            *MARK = sv_mortalcopy(*MARK);
         }
         *++MARK = svp && *svp ? *svp : &PL_sv_undef;
     }
-    if (GIMME_V != G_ARRAY) {
-       MARK = SP - items*2;
-       *++MARK = items > 0 ? *SP : &PL_sv_undef;
-       SP = MARK;
+    if (GIMME_V != G_LIST) {
+        MARK = SP - items*2;
+        *++MARK = items > 0 ? *SP : &PL_sv_undef;
+        SP = MARK;
     }
     RETURN;
 }
@@ -5398,18 +5438,18 @@ PP(pp_kvhslice)
 PP(pp_list)
 {
     I32 markidx = POPMARK;
-    if (GIMME_V != G_ARRAY) {
+    if (GIMME_V != G_LIST) {
         /* don't initialize mark here, EXTEND() may move the stack */
         SV **mark;
-       dSP;
+        dSP;
         EXTEND(SP, 1);          /* in case no arguments, as in @empty */
         mark = PL_stack_base + markidx;
-       if (++MARK <= SP)
-           *MARK = *SP;                /* unwanted list, return last item */
-       else
-           *MARK = &PL_sv_undef;
-       SP = MARK;
-       PUTBACK;
+        if (++MARK <= SP)
+            *MARK = *SP;               /* unwanted list, return last item */
+        else
+            *MARK = &PL_sv_undef;
+        SP = MARK;
+        PUTBACK;
     }
     return NORMAL;
 }
@@ -5426,7 +5466,7 @@ PP(pp_lslice)
     const I32 max = lastrelem - lastlelem;
     SV **lelem;
 
-    if (GIMME_V != G_ARRAY) {
+    if (GIMME_V != G_LIST) {
         if (lastlelem < firstlelem) {
             EXTEND(SP, 1);
             *firstlelem = &PL_sv_undef;
@@ -5445,23 +5485,23 @@ PP(pp_lslice)
     }
 
     if (max == 0) {
-       SP = firstlelem - 1;
-       RETURN;
+        SP = firstlelem - 1;
+        RETURN;
     }
 
     for (lelem = firstlelem; lelem <= lastlelem; lelem++) {
-       I32 ix = SvIV(*lelem);
-       if (ix < 0)
-           ix += max;
-       if (ix < 0 || ix >= max)
-           *lelem = &PL_sv_undef;
-       else {
-           if (!(*lelem = firstrelem[ix]))
-               *lelem = &PL_sv_undef;
-           else if (mod && SvPADTMP(*lelem)) {
-               *lelem = firstrelem[ix] = sv_mortalcopy(*lelem);
-            }
-       }
+        I32 ix = SvIV(*lelem);
+        if (ix < 0)
+            ix += max;
+        if (ix < 0 || ix >= max)
+            *lelem = &PL_sv_undef;
+        else {
+            if (!(*lelem = firstrelem[ix]))
+                *lelem = &PL_sv_undef;
+            else if (mod && SvPADTMP(*lelem)) {
+                *lelem = firstrelem[ix] = sv_mortalcopy(*lelem);
+            }
+        }
     }
     SP = lastlelem;
     RETURN;
@@ -5474,7 +5514,7 @@ PP(pp_anonlist)
     SV * const av = MUTABLE_SV(av_make(items, MARK+1));
     SP = MARK;
     mXPUSHs((PL_op->op_flags & OPf_SPECIAL)
-           ? newRV_noinc(av) : av);
+            ? newRV_noinc(av) : av);
     RETURN;
 }
 
@@ -5487,22 +5527,22 @@ PP(pp_anonhash)
                                     : MUTABLE_SV(hv) );
 
     while (MARK < SP) {
-       SV * const key =
-           (MARK++, SvGMAGICAL(*MARK) ? sv_mortalcopy(*MARK) : *MARK);
-       SV *val;
-       if (MARK < SP)
-       {
-           MARK++;
-           SvGETMAGIC(*MARK);
-           val = newSV(0);
-           sv_setsv_nomg(val, *MARK);
-       }
-       else
-       {
-           Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "Odd number of elements in anonymous hash");
-           val = newSV(0);
-       }
-       (void)hv_store_ent(hv,key,val,0);
+        SV * const key =
+            (MARK++, SvGMAGICAL(*MARK) ? sv_mortalcopy(*MARK) : *MARK);
+        SV *val;
+        if (MARK < SP)
+        {
+            MARK++;
+            SvGETMAGIC(*MARK);
+            val = newSV(0);
+            sv_setsv_nomg(val, *MARK);
+        }
+        else
+        {
+            Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "Odd number of elements in anonymous hash");
+            val = newSV(0);
+        }
+        (void)hv_store_ent(hv,key,val,0);
     }
     SP = ORIGMARK;
     XPUSHs(retval);
@@ -5525,9 +5565,9 @@ PP(pp_splice)
     const MAGIC * const mg = SvTIED_mg((const SV *)ary, PERL_MAGIC_tied);
 
     if (mg) {
-       return Perl_tied_method(aTHX_ SV_CONST(SPLICE), mark - 1, MUTABLE_SV(ary), mg,
-                                   GIMME_V | TIED_METHOD_ARGUMENTS_ON_STACK,
-                                   sp - mark);
+        return Perl_tied_method(aTHX_ SV_CONST(SPLICE), mark - 1, MUTABLE_SV(ary), mg,
+                                    GIMME_V | TIED_METHOD_ARGUMENTS_ON_STACK,
+                                    sp - mark);
     }
 
     if (SvREADONLY(ary))
@@ -5536,37 +5576,37 @@ PP(pp_splice)
     SP++;
 
     if (++MARK < SP) {
-       offset = i = SvIV(*MARK);
-       if (offset < 0)
-           offset += AvFILLp(ary) + 1;
-       if (offset < 0)
-           DIE(aTHX_ PL_no_aelem, i);
-       if (++MARK < SP) {
-           length = SvIVx(*MARK++);
-           if (length < 0) {
-               length += AvFILLp(ary) - offset + 1;
-               if (length < 0)
-                   length = 0;
-           }
-       }
-       else
-           length = AvMAX(ary) + 1;            /* close enough to infinity */
+        offset = i = SvIV(*MARK);
+        if (offset < 0)
+            offset += AvFILLp(ary) + 1;
+        if (offset < 0)
+            DIE(aTHX_ PL_no_aelem, i);
+        if (++MARK < SP) {
+            length = SvIVx(*MARK++);
+            if (length < 0) {
+                length += AvFILLp(ary) - offset + 1;
+                if (length < 0)
+                    length = 0;
+            }
+        }
+        else
+            length = AvMAX(ary) + 1;           /* close enough to infinity */
     }
     else {
-       offset = 0;
-       length = AvMAX(ary) + 1;
+        offset = 0;
+        length = AvMAX(ary) + 1;
     }
     if (offset > AvFILLp(ary) + 1) {
-       if (num_args > 2)
-           Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "splice() offset past end of array" );
-       offset = AvFILLp(ary) + 1;
+        if (num_args > 2)
+            Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "splice() offset past end of array" );
+        offset = AvFILLp(ary) + 1;
     }
     after = AvFILLp(ary) + 1 - (offset + length);
     if (after < 0) {                           /* not that much array */
-       length += after;                        /* offset+length now in array */
-       after = 0;
-       if (!AvALLOC(ary))
-           av_extend(ary, 0);
+        length += after;                       /* offset+length now in array */
+        after = 0;
+        if (!AvALLOC(ary))
+            av_extend(ary, 0);
     }
 
     /* At this point, MARK .. SP-1 is our new LIST */
@@ -5574,153 +5614,153 @@ PP(pp_splice)
     newlen = SP - MARK;
     diff = newlen - length;
     if (newlen && !AvREAL(ary) && AvREIFY(ary))
-       av_reify(ary);
+        av_reify(ary);
 
     /* make new elements SVs now: avoid problems if they're from the array */
     for (dst = MARK, i = newlen; i; i--) {
         SV * const h = *dst;
-       *dst++ = newSVsv(h);
+        *dst++ = newSVsv(h);
     }
 
     if (diff < 0) {                            /* shrinking the area */
-       SV **tmparyval = NULL;
-       if (newlen) {
-           Newx(tmparyval, newlen, SV*);       /* so remember insertion */
-           Copy(MARK, tmparyval, newlen, SV*);
-       }
-
-       MARK = ORIGMARK + 1;
-       if (GIMME_V == G_ARRAY) {               /* copy return vals to stack */
-           const bool real = cBOOL(AvREAL(ary));
-           MEXTEND(MARK, length);
-           if (real)
-               EXTEND_MORTAL(length);
-           for (i = 0, dst = MARK; i < length; i++) {
-               if ((*dst = AvARRAY(ary)[i+offset])) {
-                 if (real)
-                   sv_2mortal(*dst);   /* free them eventually */
-               }
-               else
-                   *dst = &PL_sv_undef;
-               dst++;
-           }
-           MARK += length - 1;
-       }
-       else {
-           *MARK = AvARRAY(ary)[offset+length-1];
-           if (AvREAL(ary)) {
-               sv_2mortal(*MARK);
-               for (i = length - 1, dst = &AvARRAY(ary)[offset]; i > 0; i--)
-                   SvREFCNT_dec(*dst++);       /* free them now */
-           }
-           if (!*MARK)
-               *MARK = &PL_sv_undef;
-       }
-       AvFILLp(ary) += diff;
-
-       /* pull up or down? */
-
-       if (offset < after) {                   /* easier to pull up */
-           if (offset) {                       /* esp. if nothing to pull */
-               src = &AvARRAY(ary)[offset-1];
-               dst = src - diff;               /* diff is negative */
-               for (i = offset; i > 0; i--)    /* can't trust Copy */
-                   *dst-- = *src--;
-           }
-           dst = AvARRAY(ary);
-           AvARRAY(ary) = AvARRAY(ary) - diff; /* diff is negative */
-           AvMAX(ary) += diff;
-       }
-       else {
-           if (after) {                        /* anything to pull down? */
-               src = AvARRAY(ary) + offset + length;
-               dst = src + diff;               /* diff is negative */
-               Move(src, dst, after, SV*);
-           }
-           dst = &AvARRAY(ary)[AvFILLp(ary)+1];
-                                               /* avoid later double free */
-       }
-       i = -diff;
-       while (i)
-           dst[--i] = NULL;
-
-       if (newlen) {
-           Copy( tmparyval, AvARRAY(ary) + offset, newlen, SV* );
-           Safefree(tmparyval);
-       }
+        SV **tmparyval = NULL;
+        if (newlen) {
+            Newx(tmparyval, newlen, SV*);      /* so remember insertion */
+            Copy(MARK, tmparyval, newlen, SV*);
+        }
+
+        MARK = ORIGMARK + 1;
+        if (GIMME_V == G_LIST) {               /* copy return vals to stack */
+            const bool real = cBOOL(AvREAL(ary));
+            MEXTEND(MARK, length);
+            if (real)
+                EXTEND_MORTAL(length);
+            for (i = 0, dst = MARK; i < length; i++) {
+                if ((*dst = AvARRAY(ary)[i+offset])) {
+                  if (real)
+                    sv_2mortal(*dst);  /* free them eventually */
+                }
+                else
+                    *dst = &PL_sv_undef;
+                dst++;
+            }
+            MARK += length - 1;
+        }
+        else {
+            *MARK = AvARRAY(ary)[offset+length-1];
+            if (AvREAL(ary)) {
+                sv_2mortal(*MARK);
+                for (i = length - 1, dst = &AvARRAY(ary)[offset]; i > 0; i--)
+                    SvREFCNT_dec(*dst++);      /* free them now */
+            }
+            if (!*MARK)
+                *MARK = &PL_sv_undef;
+        }
+        AvFILLp(ary) += diff;
+
+        /* pull up or down? */
+
+        if (offset < after) {                  /* easier to pull up */
+            if (offset) {                      /* esp. if nothing to pull */
+                src = &AvARRAY(ary)[offset-1];
+                dst = src - diff;              /* diff is negative */
+                for (i = offset; i > 0; i--)   /* can't trust Copy */
+                    *dst-- = *src--;
+            }
+            dst = AvARRAY(ary);
+            AvARRAY(ary) = AvARRAY(ary) - diff; /* diff is negative */
+            AvMAX(ary) += diff;
+        }
+        else {
+            if (after) {                       /* anything to pull down? */
+                src = AvARRAY(ary) + offset + length;
+                dst = src + diff;              /* diff is negative */
+                Move(src, dst, after, SV*);
+            }
+            dst = &AvARRAY(ary)[AvFILLp(ary)+1];
+                                                /* avoid later double free */
+        }
+        i = -diff;
+        while (i)
+            dst[--i] = NULL;
+
+        if (newlen) {
+            Copy( tmparyval, AvARRAY(ary) + offset, newlen, SV* );
+            Safefree(tmparyval);
+        }
     }
     else {                                     /* no, expanding (or same) */
-       SV** tmparyval = NULL;
-       if (length) {
-           Newx(tmparyval, length, SV*);       /* so remember deletion */
-           Copy(AvARRAY(ary)+offset, tmparyval, length, SV*);
-       }
-
-       if (diff > 0) {                         /* expanding */
-           /* push up or down? */
-           if (offset < after && diff <= AvARRAY(ary) - AvALLOC(ary)) {
-               if (offset) {
-                   src = AvARRAY(ary);
-                   dst = src - diff;
-                   Move(src, dst, offset, SV*);
-               }
-               AvARRAY(ary) = AvARRAY(ary) - diff;/* diff is positive */
-               AvMAX(ary) += diff;
-               AvFILLp(ary) += diff;
-           }
-           else {
-               if (AvFILLp(ary) + diff >= AvMAX(ary))  /* oh, well */
-                   av_extend(ary, AvFILLp(ary) + diff);
-               AvFILLp(ary) += diff;
-
-               if (after) {
-                   dst = AvARRAY(ary) + AvFILLp(ary);
-                   src = dst - diff;
-                   for (i = after; i; i--) {
-                       *dst-- = *src--;
-                   }
-               }
-           }
-       }
-
-       if (newlen) {
-           Copy( MARK, AvARRAY(ary) + offset, newlen, SV* );
-       }
-
-       MARK = ORIGMARK + 1;
-       if (GIMME_V == G_ARRAY) {               /* copy return vals to stack */
-           if (length) {
-               const bool real = cBOOL(AvREAL(ary));
-               if (real)
-                   EXTEND_MORTAL(length);
-               for (i = 0, dst = MARK; i < length; i++) {
-                   if ((*dst = tmparyval[i])) {
-                     if (real)
-                       sv_2mortal(*dst);       /* free them eventually */
-                   }
-                   else *dst = &PL_sv_undef;
-                   dst++;
-               }
-           }
-           MARK += length - 1;
-       }
-       else if (length--) {
-           *MARK = tmparyval[length];
-           if (AvREAL(ary)) {
-               sv_2mortal(*MARK);
-               while (length-- > 0)
-                   SvREFCNT_dec(tmparyval[length]);
-           }
-           if (!*MARK)
-               *MARK = &PL_sv_undef;
-       }
-       else
-           *MARK = &PL_sv_undef;
-       Safefree(tmparyval);
+        SV** tmparyval = NULL;
+        if (length) {
+            Newx(tmparyval, length, SV*);      /* so remember deletion */
+            Copy(AvARRAY(ary)+offset, tmparyval, length, SV*);
+        }
+
+        if (diff > 0) {                                /* expanding */
+            /* push up or down? */
+            if (offset < after && diff <= AvARRAY(ary) - AvALLOC(ary)) {
+                if (offset) {
+                    src = AvARRAY(ary);
+                    dst = src - diff;
+                    Move(src, dst, offset, SV*);
+                }
+                AvARRAY(ary) = AvARRAY(ary) - diff;/* diff is positive */
+                AvMAX(ary) += diff;
+                AvFILLp(ary) += diff;
+            }
+            else {
+                if (AvFILLp(ary) + diff >= AvMAX(ary)) /* oh, well */
+                    av_extend(ary, AvFILLp(ary) + diff);
+                AvFILLp(ary) += diff;
+
+                if (after) {
+                    dst = AvARRAY(ary) + AvFILLp(ary);
+                    src = dst - diff;
+                    for (i = after; i; i--) {
+                        *dst-- = *src--;
+                    }
+                }
+            }
+        }
+
+        if (newlen) {
+            Copy( MARK, AvARRAY(ary) + offset, newlen, SV* );
+        }
+
+        MARK = ORIGMARK + 1;
+        if (GIMME_V == G_LIST) {               /* copy return vals to stack */
+            if (length) {
+                const bool real = cBOOL(AvREAL(ary));
+                if (real)
+                    EXTEND_MORTAL(length);
+                for (i = 0, dst = MARK; i < length; i++) {
+                    if ((*dst = tmparyval[i])) {
+                      if (real)
+                        sv_2mortal(*dst);      /* free them eventually */
+                    }
+                    else *dst = &PL_sv_undef;
+                    dst++;
+                }
+            }
+            MARK += length - 1;
+        }
+        else if (length--) {
+            *MARK = tmparyval[length];
+            if (AvREAL(ary)) {
+                sv_2mortal(*MARK);
+                while (length-- > 0)
+                    SvREFCNT_dec(tmparyval[length]);
+            }
+            if (!*MARK)
+                *MARK = &PL_sv_undef;
+        }
+        else
+            *MARK = &PL_sv_undef;
+        Safefree(tmparyval);
     }
 
     if (SvMAGICAL(ary))
-       mg_set(MUTABLE_SV(ary));
+        mg_set(MUTABLE_SV(ary));
 
     SP = MARK;
     RETURN;
@@ -5733,36 +5773,36 @@ PP(pp_push)
     const MAGIC * const mg = SvTIED_mg((const SV *)ary, PERL_MAGIC_tied);
 
     if (mg) {
-       *MARK-- = SvTIED_obj(MUTABLE_SV(ary), mg);
-       PUSHMARK(MARK);
-       PUTBACK;
-       ENTER_with_name("call_PUSH");
-       call_sv(SV_CONST(PUSH),G_SCALAR|G_DISCARD|G_METHOD_NAMED);
-       LEAVE_with_name("call_PUSH");
-       /* SPAGAIN; not needed: SP is assigned to immediately below */
+        *MARK-- = SvTIED_obj(MUTABLE_SV(ary), mg);
+        PUSHMARK(MARK);
+        PUTBACK;
+        ENTER_with_name("call_PUSH");
+        call_sv(SV_CONST(PUSH),G_SCALAR|G_DISCARD|G_METHOD_NAMED);
+        LEAVE_with_name("call_PUSH");
+        /* SPAGAIN; not needed: SP is assigned to immediately below */
     }
     else {
         /* PL_delaymagic is restored by JUMPENV_POP on dieing, so we
          * only need to save locally, not on the save stack */
         U16 old_delaymagic = PL_delaymagic;
 
-       if (SvREADONLY(ary) && MARK < SP) Perl_croak_no_modify();
-       PL_delaymagic = DM_DELAY;
-       for (++MARK; MARK <= SP; MARK++) {
-           SV *sv;
-           if (*MARK) SvGETMAGIC(*MARK);
-           sv = newSV(0);
-           if (*MARK)
-               sv_setsv_nomg(sv, *MARK);
-           av_store(ary, AvFILLp(ary)+1, sv);
-       }
-       if (PL_delaymagic & DM_ARRAY_ISA)
-           mg_set(MUTABLE_SV(ary));
+        if (SvREADONLY(ary) && MARK < SP) Perl_croak_no_modify();
+        PL_delaymagic = DM_DELAY;
+        for (++MARK; MARK <= SP; MARK++) {
+            SV *sv;
+            if (*MARK) SvGETMAGIC(*MARK);
+            sv = newSV(0);
+            if (*MARK)
+                sv_setsv_nomg(sv, *MARK);
+            av_store(ary, AvFILLp(ary)+1, sv);
+        }
+        if (PL_delaymagic & DM_ARRAY_ISA)
+            mg_set(MUTABLE_SV(ary));
         PL_delaymagic = old_delaymagic;
     }
     SP = ORIGMARK;
     if (OP_GIMME(PL_op, 0) != G_VOID) {
-       PUSHi( AvFILL(ary) + 1 );
+        PUSHi( AvFILL(ary) + 1 );
     }
     RETURN;
 }
@@ -5772,12 +5812,12 @@ PP(pp_shift)
 {
     dSP;
     AV * const av = PL_op->op_flags & OPf_SPECIAL
-       ? MUTABLE_AV(GvAVn(PL_defgv)) : MUTABLE_AV(POPs);
+        ? MUTABLE_AV(GvAVn(PL_defgv)) : MUTABLE_AV(POPs);
     SV * const sv = PL_op->op_type == OP_SHIFT ? av_shift(av) : av_pop(av);
     EXTEND(SP, 1);
     assert (sv);
     if (AvREAL(av))
-       (void)sv_2mortal(sv);
+        (void)sv_2mortal(sv);
     PUSHs(sv);
     RETURN;
 }
@@ -5789,33 +5829,33 @@ PP(pp_unshift)
     const MAGIC * const mg = SvTIED_mg((const SV *)ary, PERL_MAGIC_tied);
 
     if (mg) {
-       *MARK-- = SvTIED_obj(MUTABLE_SV(ary), mg);
-       PUSHMARK(MARK);
-       PUTBACK;
-       ENTER_with_name("call_UNSHIFT");
-       call_sv(SV_CONST(UNSHIFT),G_SCALAR|G_DISCARD|G_METHOD_NAMED);
-       LEAVE_with_name("call_UNSHIFT");
-       /* SPAGAIN; not needed: SP is assigned to immediately below */
+        *MARK-- = SvTIED_obj(MUTABLE_SV(ary), mg);
+        PUSHMARK(MARK);
+        PUTBACK;
+        ENTER_with_name("call_UNSHIFT");
+        call_sv(SV_CONST(UNSHIFT),G_SCALAR|G_DISCARD|G_METHOD_NAMED);
+        LEAVE_with_name("call_UNSHIFT");
+        /* SPAGAIN; not needed: SP is assigned to immediately below */
     }
     else {
         /* PL_delaymagic is restored by JUMPENV_POP on dieing, so we
          * only need to save locally, not on the save stack */
         U16 old_delaymagic = PL_delaymagic;
-       SSize_t i = 0;
+        SSize_t i = 0;
 
-       av_unshift(ary, SP - MARK);
+        av_unshift(ary, SP - MARK);
         PL_delaymagic = DM_DELAY;
-       while (MARK < SP) {
-           SV * const sv = newSVsv(*++MARK);
-           (void)av_store(ary, i++, sv);
-       }
+        while (MARK < SP) {
+            SV * const sv = newSVsv(*++MARK);
+            (void)av_store(ary, i++, sv);
+        }
         if (PL_delaymagic & DM_ARRAY_ISA)
             mg_set(MUTABLE_SV(ary));
         PL_delaymagic = old_delaymagic;
     }
     SP = ORIGMARK;
     if (OP_GIMME(PL_op, 0) != G_VOID) {
-       PUSHi( AvFILL(ary) + 1 );
+        PUSHi( AvFILL(ary) + 1 );
     }
     RETURN;
 }
@@ -5824,132 +5864,133 @@ PP(pp_reverse)
 {
     dSP; dMARK;
 
-    if (GIMME_V == G_ARRAY) {
-       if (PL_op->op_private & OPpREVERSE_INPLACE) {
-           AV *av;
-
-           /* See pp_sort() */
-           assert( MARK+1 == SP && *SP && SvTYPE(*SP) == SVt_PVAV);
-           (void)POPMARK; /* remove mark associated with ex-OP_AASSIGN */
-           av = MUTABLE_AV((*SP));
-           /* In-place reversing only happens in void context for the array
-            * assignment. We don't need to push anything on the stack. */
-           SP = MARK;
-
-           if (SvMAGICAL(av)) {
-               SSize_t i, j;
-               SV *tmp = sv_newmortal();
-               /* For SvCANEXISTDELETE */
-               HV *stash;
-               const MAGIC *mg;
-               bool can_preserve = SvCANEXISTDELETE(av);
-
-               for (i = 0, j = av_tindex(av); i < j; ++i, --j) {
-                   SV *begin, *end;
-
-                   if (can_preserve) {
-                       if (!av_exists(av, i)) {
-                           if (av_exists(av, j)) {
-                               SV *sv = av_delete(av, j, 0);
-                               begin = *av_fetch(av, i, TRUE);
-                               sv_setsv_mg(begin, sv);
-                           }
-                           continue;
-                       }
-                       else if (!av_exists(av, j)) {
-                           SV *sv = av_delete(av, i, 0);
-                           end = *av_fetch(av, j, TRUE);
-                           sv_setsv_mg(end, sv);
-                           continue;
-                       }
-                   }
-
-                   begin = *av_fetch(av, i, TRUE);
-                   end   = *av_fetch(av, j, TRUE);
-                   sv_setsv(tmp,      begin);
-                   sv_setsv_mg(begin, end);
-                   sv_setsv_mg(end,   tmp);
-               }
-           }
-           else {
-               SV **begin = AvARRAY(av);
-
-               if (begin) {
-                   SV **end   = begin + AvFILLp(av);
-
-                   while (begin < end) {
-                       SV * const tmp = *begin;
-                       *begin++ = *end;
-                       *end--   = tmp;
-                   }
-               }
-           }
-       }
-       else {
-           SV **oldsp = SP;
-           MARK++;
-           while (MARK < SP) {
-               SV * const tmp = *MARK;
-               *MARK++ = *SP;
-               *SP--   = tmp;
-           }
-           /* safe as long as stack cannot get extended in the above */
-           SP = oldsp;
-       }
+    if (GIMME_V == G_LIST) {
+        if (PL_op->op_private & OPpREVERSE_INPLACE) {
+            AV *av;
+
+            /* See pp_sort() */
+            assert( MARK+1 == SP && *SP && SvTYPE(*SP) == SVt_PVAV);
+            (void)POPMARK; /* remove mark associated with ex-OP_AASSIGN */
+            av = MUTABLE_AV((*SP));
+            /* In-place reversing only happens in void context for the array
+             * assignment. We don't need to push anything on the stack. */
+            SP = MARK;
+
+            if (SvMAGICAL(av)) {
+                SSize_t i, j;
+                SV *tmp = sv_newmortal();
+                /* For SvCANEXISTDELETE */
+                HV *stash;
+                const MAGIC *mg;
+                bool can_preserve = SvCANEXISTDELETE(av);
+
+                for (i = 0, j = av_top_index(av); i < j; ++i, --j) {
+                    SV *begin, *end;
+
+                    if (can_preserve) {
+                        if (!av_exists(av, i)) {
+                            if (av_exists(av, j)) {
+                                SV *sv = av_delete(av, j, 0);
+                                begin = *av_fetch(av, i, TRUE);
+                                sv_setsv_mg(begin, sv);
+                            }
+                            continue;
+                        }
+                        else if (!av_exists(av, j)) {
+                            SV *sv = av_delete(av, i, 0);
+                            end = *av_fetch(av, j, TRUE);
+                            sv_setsv_mg(end, sv);
+                            continue;
+                        }
+                    }
+
+                    begin = *av_fetch(av, i, TRUE);
+                    end   = *av_fetch(av, j, TRUE);
+                    sv_setsv(tmp,      begin);
+                    sv_setsv_mg(begin, end);
+                    sv_setsv_mg(end,   tmp);
+                }
+            }
+            else {
+                SV **begin = AvARRAY(av);
+
+                if (begin) {
+                    SV **end   = begin + AvFILLp(av);
+
+                    while (begin < end) {
+                        SV * const tmp = *begin;
+                        *begin++ = *end;
+                        *end--   = tmp;
+                    }
+                }
+            }
+        }
+        else {
+            SV **oldsp = SP;
+            MARK++;
+            while (MARK < SP) {
+                SV * const tmp = *MARK;
+                *MARK++ = *SP;
+                *SP--   = tmp;
+            }
+            /* safe as long as stack cannot get extended in the above */
+            SP = oldsp;
+        }
     }
     else {
-       char *up;
-       dTARGET;
-       STRLEN len;
-
-       SvUTF8_off(TARG);                               /* decontaminate */
-       if (SP - MARK > 1) {
-           do_join(TARG, &PL_sv_no, MARK, SP);
-           SP = MARK + 1;
-           SETs(TARG);
-       } else if (SP > MARK) {
-           sv_setsv(TARG, *SP);
-           SETs(TARG);
+        char *up;
+        dTARGET;
+        STRLEN len;
+
+        SvUTF8_off(TARG);                              /* decontaminate */
+        if (SP - MARK > 1) {
+            do_join(TARG, &PL_sv_no, MARK, SP);
+            SP = MARK + 1;
+            SETs(TARG);
+        } else if (SP > MARK) {
+            sv_setsv(TARG, *SP);
+            SETs(TARG);
         } else {
-           sv_setsv(TARG, DEFSV);
-           XPUSHs(TARG);
-       }
+            sv_setsv(TARG, DEFSV);
+            XPUSHs(TARG);
+        }
+        SvSETMAGIC(TARG); /* remove any utf8 length magic */
 
-       up = SvPV_force(TARG, len);
-       if (len > 1) {
+        up = SvPV_force(TARG, len);
+        if (len > 1) {
             char *down;
-           if (DO_UTF8(TARG)) {        /* first reverse each character */
-               U8* s = (U8*)SvPVX(TARG);
-               const U8* send = (U8*)(s + len);
-               while (s < send) {
-                   if (UTF8_IS_INVARIANT(*s)) {
-                       s++;
-                       continue;
-                   }
-                   else {
-                       if (!utf8_to_uvchr_buf(s, send, 0))
-                           break;
-                       up = (char*)s;
-                       s += UTF8SKIP(s);
-                       down = (char*)(s - 1);
-                       /* reverse this character */
-                       while (down > up) {
+            if (DO_UTF8(TARG)) {       /* first reverse each character */
+                U8* s = (U8*)SvPVX(TARG);
+                const U8* send = (U8*)(s + len);
+                while (s < send) {
+                    if (UTF8_IS_INVARIANT(*s)) {
+                        s++;
+                        continue;
+                    }
+                    else {
+                        if (!utf8_to_uvchr_buf(s, send, 0))
+                            break;
+                        up = (char*)s;
+                        s += UTF8SKIP(s);
+                        down = (char*)(s - 1);
+                        /* reverse this character */
+                        while (down > up) {
                             const char tmp = *up;
-                           *up++ = *down;
+                            *up++ = *down;
                             *down-- = tmp;
-                       }
-                   }
-               }
-               up = SvPVX(TARG);
-           }
-           down = SvPVX(TARG) + len - 1;
-           while (down > up) {
+                        }
+                    }
+                }
+                up = SvPVX(TARG);
+            }
+            down = SvPVX(TARG) + len - 1;
+            while (down > up) {
                 const char tmp = *up;
-               *up++ = *down;
+                *up++ = *down;
                 *down-- = tmp;
-           }
-           (void)SvPOK_only_UTF8(TARG);
-       }
+            }
+            (void)SvPOK_only_UTF8(TARG);
+        }
     }
     RETURN;
 }
@@ -5979,13 +6020,13 @@ PP(pp_split)
     I32 trailing_empty = 0;
     const char *orig;
     const IV origlimit = limit;
-    I32 realarray = 0;
+    bool realarray = 0;
     I32 base;
     const U8 gimme = GIMME_V;
     bool gimme_scalar;
     I32 oldsave = PL_savestack_ix;
-    U32 make_mortal = SVs_TEMP;
-    bool multiline = 0;
+    U32 flags = (do_utf8 ? SVf_UTF8 : 0) |
+         SVs_TEMP; /* Make mortal SVs by default */
     MAGIC *mg = NULL;
 
     rx = PM_GETRE(pm);
@@ -5995,6 +6036,7 @@ PP(pp_split)
 
     /* handle @ary = split(...) optimisation */
     if (PL_op->op_private & OPpSPLIT_ASSIGN) {
+        realarray = 1;
         if (!(PL_op->op_flags & OPf_STACKED)) {
             if (PL_op->op_private & OPpSPLIT_LEX) {
                 if (PL_op->op_private & OPpLVAL_INTRO)
@@ -6017,76 +6059,60 @@ PP(pp_split)
             oldsave = PL_savestack_ix;
         }
 
-       realarray = 1;
-       PUTBACK;
-       av_extend(ary,0);
-       (void)sv_2mortal(SvREFCNT_inc_simple_NN(sv));
-       av_clear(ary);
-       SPAGAIN;
-       if ((mg = SvTIED_mg((const SV *)ary, PERL_MAGIC_tied))) {
-           PUSHMARK(SP);
-           XPUSHs(SvTIED_obj(MUTABLE_SV(ary), mg));
-       }
-       else {
-           if (!AvREAL(ary)) {
-               I32 i;
-               AvREAL_on(ary);
-               AvREIFY_off(ary);
-               for (i = AvFILLp(ary); i >= 0; i--)
-                   AvARRAY(ary)[i] = &PL_sv_undef; /* don't free mere refs */
-           }
-           /* temporarily switch stacks */
-           SAVESWITCHSTACK(PL_curstack, ary);
-           make_mortal = 0;
-       }
+        /* Some defence against stack-not-refcounted bugs */
+        (void)sv_2mortal(SvREFCNT_inc_simple_NN(ary));
+
+        if ((mg = SvTIED_mg((const SV *)ary, PERL_MAGIC_tied))) {
+            PUSHMARK(SP);
+            XPUSHs(SvTIED_obj(MUTABLE_SV(ary), mg));
+        } else {
+            flags &= ~SVs_TEMP; /* SVs will not be mortal */
+        }
     }
 
     base = SP - PL_stack_base;
     orig = s;
     if (RX_EXTFLAGS(rx) & RXf_SKIPWHITE) {
-       if (do_utf8) {
-           while (s < strend && isSPACE_utf8_safe(s, strend))
-               s += UTF8SKIP(s);
-       }
-       else if (get_regex_charset(RX_EXTFLAGS(rx)) == REGEX_LOCALE_CHARSET) {
-           while (s < strend && isSPACE_LC(*s))
-               s++;
-       }
+        if (do_utf8) {
+            while (s < strend && isSPACE_utf8_safe(s, strend))
+                s += UTF8SKIP(s);
+        }
+        else if (get_regex_charset(RX_EXTFLAGS(rx)) == REGEX_LOCALE_CHARSET) {
+            while (s < strend && isSPACE_LC(*s))
+                s++;
+        }
         else if (in_uni_8_bit) {
             while (s < strend && isSPACE_L1(*s))
                 s++;
         }
-       else {
-           while (s < strend && isSPACE(*s))
-               s++;
-       }
-    }
-    if (RX_EXTFLAGS(rx) & RXf_PMf_MULTILINE) {
-       multiline = 1;
+        else {
+            while (s < strend && isSPACE(*s))
+                s++;
+        }
     }
 
     gimme_scalar = gimme == G_SCALAR && !ary;
 
     if (!limit)
-       limit = maxiters + 2;
+        limit = maxiters + 2;
     if (RX_EXTFLAGS(rx) & RXf_WHITE) {
-       while (--limit) {
-           m = s;
-           /* this one uses 'm' and is a negative test */
-           if (do_utf8) {
-               while (m < strend && ! isSPACE_utf8_safe(m, strend) ) {
-                   const int t = UTF8SKIP(m);
-                   /* isSPACE_utf8_safe returns FALSE for malform utf8 */
-                   if (strend - m < t)
-                       m = strend;
-                   else
-                       m += t;
-               }
-           }
-           else if (get_regex_charset(RX_EXTFLAGS(rx)) == REGEX_LOCALE_CHARSET)
+        while (--limit) {
+            m = s;
+            /* this one uses 'm' and is a negative test */
+            if (do_utf8) {
+                while (m < strend && ! isSPACE_utf8_safe(m, strend) ) {
+                    const int t = UTF8SKIP(m);
+                    /* isSPACE_utf8_safe returns FALSE for malform utf8 */
+                    if (strend - m < t)
+                        m = strend;
+                    else
+                        m += t;
+                }
+            }
+            else if (get_regex_charset(RX_EXTFLAGS(rx)) == REGEX_LOCALE_CHARSET)
             {
-               while (m < strend && !isSPACE_LC(*m))
-                   ++m;
+                while (m < strend && !isSPACE_LC(*m))
+                    ++m;
             }
             else if (in_uni_8_bit) {
                 while (m < strend && !isSPACE_L1(*m))
@@ -6095,36 +6121,35 @@ PP(pp_split)
                 while (m < strend && !isSPACE(*m))
                     ++m;
             }
-           if (m >= strend)
-               break;
-
-           if (gimme_scalar) {
-               iters++;
-               if (m-s == 0)
-                   trailing_empty++;
-               else
-                   trailing_empty = 0;
-           } else {
-               dstr = newSVpvn_flags(s, m-s,
-                                     (do_utf8 ? SVf_UTF8 : 0) | make_mortal);
-               XPUSHs(dstr);
-           }
-
-           /* skip the whitespace found last */
-           if (do_utf8)
-               s = m + UTF8SKIP(m);
-           else
-               s = m + 1;
-
-           /* this one uses 's' and is a positive test */
-           if (do_utf8) {
-               while (s < strend && isSPACE_utf8_safe(s, strend) )
-                   s +=  UTF8SKIP(s);
-           }
-           else if (get_regex_charset(RX_EXTFLAGS(rx)) == REGEX_LOCALE_CHARSET)
+            if (m >= strend)
+                break;
+
+            if (gimme_scalar) {
+                iters++;
+                if (m-s == 0)
+                    trailing_empty++;
+                else
+                    trailing_empty = 0;
+            } else {
+                dstr = newSVpvn_flags(s, m-s, flags);
+                XPUSHs(dstr);
+            }
+
+            /* skip the whitespace found last */
+            if (do_utf8)
+                s = m + UTF8SKIP(m);
+            else
+                s = m + 1;
+
+            /* this one uses 's' and is a positive test */
+            if (do_utf8) {
+                while (s < strend && isSPACE_utf8_safe(s, strend) )
+                    s +=  UTF8SKIP(s);
+            }
+            else if (get_regex_charset(RX_EXTFLAGS(rx)) == REGEX_LOCALE_CHARSET)
             {
-               while (s < strend && isSPACE_LC(*s))
-                   ++s;
+                while (s < strend && isSPACE_LC(*s))
+                    ++s;
             }
             else if (in_uni_8_bit) {
                 while (s < strend && isSPACE_L1(*s))
@@ -6133,279 +6158,291 @@ PP(pp_split)
                 while (s < strend && isSPACE(*s))
                     ++s;
             }
-       }
+        }
     }
     else if (RX_EXTFLAGS(rx) & RXf_START_ONLY) {
-       while (--limit) {
-           for (m = s; m < strend && *m != '\n'; m++)
-               ;
-           m++;
-           if (m >= strend)
-               break;
-
-           if (gimme_scalar) {
-               iters++;
-               if (m-s == 0)
-                   trailing_empty++;
-               else
-                   trailing_empty = 0;
-           } else {
-               dstr = newSVpvn_flags(s, m-s,
-                                     (do_utf8 ? SVf_UTF8 : 0) | make_mortal);
-               XPUSHs(dstr);
-           }
-           s = m;
-       }
+        while (--limit) {
+            for (m = s; m < strend && *m != '\n'; m++)
+                ;
+            m++;
+            if (m >= strend)
+                break;
+
+            if (gimme_scalar) {
+                iters++;
+                if (m-s == 0)
+                    trailing_empty++;
+                else
+                    trailing_empty = 0;
+            } else {
+                dstr = newSVpvn_flags(s, m-s, flags);
+                XPUSHs(dstr);
+            }
+            s = m;
+        }
     }
     else if (RX_EXTFLAGS(rx) & RXf_NULL && !(s >= strend)) {
-        /*
-          Pre-extend the stack, either the number of bytes or
-          characters in the string or a limited amount, triggered by:
-
-          my ($x, $y) = split //, $str;
-            or
-          split //, $str, $i;
-        */
-       if (!gimme_scalar) {
-           const IV items = limit - 1;
-            /* setting it to -1 will trigger a panic in EXTEND() */
-            const SSize_t sslen = slen > SSize_t_MAX ?  -1 : (SSize_t)slen;
-           if (items >=0 && items < sslen)
-               EXTEND(SP, items);
-           else
-               EXTEND(SP, sslen);
-       }
-
-        if (do_utf8) {
-            while (--limit) {
-                /* keep track of how many bytes we skip over */
-                m = s;
-                s += UTF8SKIP(s);
-               if (gimme_scalar) {
-                   iters++;
-                   if (s-m == 0)
-                       trailing_empty++;
-                   else
-                       trailing_empty = 0;
-               } else {
-                   dstr = newSVpvn_flags(m, s-m, SVf_UTF8 | make_mortal);
-
-                   PUSHs(dstr);
-               }
-
-                if (s >= strend)
-                    break;
+        /* This case boils down to deciding which is the smaller of:
+         * limit - effectively a number of characters
+         * slen - which already contains the number of characters in s
+         *
+         * The resulting number is the number of iters (for gimme_scalar)
+         * or the number of SVs to create (!gimme_scalar). */
+
+        /* setting it to -1 will trigger a panic in EXTEND() */
+        const SSize_t sslen = slen > SSize_t_MAX ?  -1 : (SSize_t)slen;
+        const IV items = limit - 1;
+        if (sslen < items || items < 0) {
+            iters = slen -1;
+            limit = slen + 1;
+            /* Note: The same result is returned if the following block
+             * is removed, because of the "keep field after final delim?"
+             * adjustment, but having the following makes the "correct"
+             * behaviour more apparent. */
+            if (gimme_scalar) {
+                s = strend;
+                iters++;
             }
         } else {
-            while (--limit) {
-               if (gimme_scalar) {
-                   iters++;
-               } else {
-                   dstr = newSVpvn(s, 1);
-
-
-                   if (make_mortal)
-                       sv_2mortal(dstr);
-
-                   PUSHs(dstr);
-               }
-
-                s++;
-
-                if (s >= strend)
-                    break;
+            iters = items;
+        }
+        if (!gimme_scalar) {
+            /*
+              Pre-extend the stack, either the number of bytes or
+              characters in the string or a limited amount, triggered by:
+              my ($x, $y) = split //, $str;
+                or
+              split //, $str, $i;
+            */
+            EXTEND(SP, limit);
+            if (do_utf8) {
+                while (--limit) {
+                    m = s;
+                    s += UTF8SKIP(s);
+                    dstr = newSVpvn_flags(m, s-m, flags);
+                    PUSHs(dstr);
+                }
+            } else {
+                while (--limit) {
+                    dstr = newSVpvn_flags(s, 1, flags);
+                    PUSHs(dstr);
+                    s++;
+                }
             }
         }
     }
     else if (do_utf8 == (RX_UTF8(rx) != 0) &&
-            (RX_EXTFLAGS(rx) & RXf_USE_INTUIT) && !RX_NPARENS(rx)
-            && (RX_EXTFLAGS(rx) & RXf_CHECK_ALL)
+             (RX_EXTFLAGS(rx) & RXf_USE_INTUIT) && !RX_NPARENS(rx)
+             && (RX_EXTFLAGS(rx) & RXf_CHECK_ALL)
              && !(RX_EXTFLAGS(rx) & RXf_IS_ANCHORED)) {
-       const int tail = (RX_EXTFLAGS(rx) & RXf_INTUIT_TAIL);
-       SV * const csv = CALLREG_INTUIT_STRING(rx);
-
-       len = RX_MINLENRET(rx);
-       if (len == 1 && !RX_UTF8(rx) && !tail) {
-           const char c = *SvPV_nolen_const(csv);
-           while (--limit) {
-               for (m = s; m < strend && *m != c; m++)
-                   ;
-               if (m >= strend)
-                   break;
-               if (gimme_scalar) {
-                   iters++;
-                   if (m-s == 0)
-                       trailing_empty++;
-                   else
-                       trailing_empty = 0;
-               } else {
-                   dstr = newSVpvn_flags(s, m-s,
-                                        (do_utf8 ? SVf_UTF8 : 0) | make_mortal);
-                   XPUSHs(dstr);
-               }
-               /* The rx->minlen is in characters but we want to step
-                * s ahead by bytes. */
-               if (do_utf8)
-                   s = (char*)utf8_hop((U8*)m, len);
-               else
-                   s = m + len; /* Fake \n at the end */
-           }
-       }
-       else {
-           while (s < strend && --limit &&
-             (m = fbm_instr((unsigned char*)s, (unsigned char*)strend,
-                            csv, multiline ? FBMrf_MULTILINE : 0)) )
-           {
-               if (gimme_scalar) {
-                   iters++;
-                   if (m-s == 0)
-                       trailing_empty++;
-                   else
-                       trailing_empty = 0;
-               } else {
-                   dstr = newSVpvn_flags(s, m-s,
-                                        (do_utf8 ? SVf_UTF8 : 0) | make_mortal);
-                   XPUSHs(dstr);
-               }
-               /* The rx->minlen is in characters but we want to step
-                * s ahead by bytes. */
-               if (do_utf8)
-                   s = (char*)utf8_hop((U8*)m, len);
-               else
-                   s = m + len; /* Fake \n at the end */
-           }
-       }
+        const int tail = (RX_EXTFLAGS(rx) & RXf_INTUIT_TAIL);
+        SV * const csv = CALLREG_INTUIT_STRING(rx);
+
+        len = RX_MINLENRET(rx);
+        if (len == 1 && !RX_UTF8(rx) && !tail) {
+            const char c = *SvPV_nolen_const(csv);
+            while (--limit) {
+                for (m = s; m < strend && *m != c; m++)
+                    ;
+                if (m >= strend)
+                    break;
+                if (gimme_scalar) {
+                    iters++;
+                    if (m-s == 0)
+                        trailing_empty++;
+                    else
+                        trailing_empty = 0;
+                } else {
+                    dstr = newSVpvn_flags(s, m-s, flags);
+                    XPUSHs(dstr);
+                }
+                /* The rx->minlen is in characters but we want to step
+                 * s ahead by bytes. */
+                if (do_utf8)
+                    s = (char*)utf8_hop_forward((U8*) m, len, (U8*) strend);
+                else
+                    s = m + len; /* Fake \n at the end */
+            }
+        }
+        else {
+            const bool multiline = (RX_EXTFLAGS(rx) & RXf_PMf_MULTILINE) ? 1 : 0;
+
+            while (s < strend && --limit &&
+              (m = fbm_instr((unsigned char*)s, (unsigned char*)strend,
+                             csv, multiline ? FBMrf_MULTILINE : 0)) )
+            {
+                if (gimme_scalar) {
+                    iters++;
+                    if (m-s == 0)
+                        trailing_empty++;
+                    else
+                        trailing_empty = 0;
+                } else {
+                    dstr = newSVpvn_flags(s, m-s, flags);
+                    XPUSHs(dstr);
+                }
+                /* The rx->minlen is in characters but we want to step
+                 * s ahead by bytes. */
+                if (do_utf8)
+                    s = (char*)utf8_hop_forward((U8*)m, len, (U8 *) strend);
+                else
+                    s = m + len; /* Fake \n at the end */
+            }
+        }
     }
     else {
-       maxiters += slen * RX_NPARENS(rx);
-       while (s < strend && --limit)
-       {
-           I32 rex_return;
-           PUTBACK;
-           rex_return = CALLREGEXEC(rx, (char*)s, (char*)strend, (char*)orig, 1,
-                                    sv, NULL, 0);
-           SPAGAIN;
-           if (rex_return == 0)
-               break;
-           TAINT_IF(RX_MATCH_TAINTED(rx));
+        maxiters += slen * RX_NPARENS(rx);
+        while (s < strend && --limit)
+        {
+            I32 rex_return;
+            PUTBACK;
+            rex_return = CALLREGEXEC(rx, (char*)s, (char*)strend, (char*)orig, 1,
+                                     sv, NULL, 0);
+            SPAGAIN;
+            if (rex_return == 0)
+                break;
+            TAINT_IF(RX_MATCH_TAINTED(rx));
             /* we never pass the REXEC_COPY_STR flag, so it should
              * never get copied */
             assert(!RX_MATCH_COPIED(rx));
-           m = RX_OFFS(rx)[0].start + orig;
-
-           if (gimme_scalar) {
-               iters++;
-               if (m-s == 0)
-                   trailing_empty++;
-               else
-                   trailing_empty = 0;
-           } else {
-               dstr = newSVpvn_flags(s, m-s,
-                                     (do_utf8 ? SVf_UTF8 : 0) | make_mortal);
-               XPUSHs(dstr);
-           }
-           if (RX_NPARENS(rx)) {
-               I32 i;
-               for (i = 1; i <= (I32)RX_NPARENS(rx); i++) {
-                   s = RX_OFFS(rx)[i].start + orig;
-                   m = RX_OFFS(rx)[i].end + orig;
-
-                   /* japhy (07/27/01) -- the (m && s) test doesn't catch
-                      parens that didn't match -- they should be set to
-                      undef, not the empty string */
-                   if (gimme_scalar) {
-                       iters++;
-                       if (m-s == 0)
-                           trailing_empty++;
-                       else
-                           trailing_empty = 0;
-                   } else {
-                       if (m >= orig && s >= orig) {
-                           dstr = newSVpvn_flags(s, m-s,
-                                                (do_utf8 ? SVf_UTF8 : 0)
-                                                 | make_mortal);
-                       }
-                       else
-                           dstr = &PL_sv_undef;  /* undef, not "" */
-                       XPUSHs(dstr);
-                   }
-
-               }
-           }
-           s = RX_OFFS(rx)[0].end + orig;
-       }
+            m = RX_OFFS(rx)[0].start + orig;
+
+            if (gimme_scalar) {
+                iters++;
+                if (m-s == 0)
+                    trailing_empty++;
+                else
+                    trailing_empty = 0;
+            } else {
+                dstr = newSVpvn_flags(s, m-s, flags);
+                XPUSHs(dstr);
+            }
+            if (RX_NPARENS(rx)) {
+                I32 i;
+                for (i = 1; i <= (I32)RX_NPARENS(rx); i++) {
+                    s = RX_OFFS(rx)[i].start + orig;
+                    m = RX_OFFS(rx)[i].end + orig;
+
+                    /* japhy (07/27/01) -- the (m && s) test doesn't catch
+                       parens that didn't match -- they should be set to
+                       undef, not the empty string */
+                    if (gimme_scalar) {
+                        iters++;
+                        if (m-s == 0)
+                            trailing_empty++;
+                        else
+                            trailing_empty = 0;
+                    } else {
+                        if (m >= orig && s >= orig) {
+                            dstr = newSVpvn_flags(s, m-s, flags);
+                        }
+                        else
+                            dstr = &PL_sv_undef;  /* undef, not "" */
+                        XPUSHs(dstr);
+                    }
+
+                }
+            }
+            s = RX_OFFS(rx)[0].end + orig;
+        }
     }
 
     if (!gimme_scalar) {
-       iters = (SP - PL_stack_base) - base;
+        iters = (SP - PL_stack_base) - base;
     }
     if (iters > maxiters)
-       DIE(aTHX_ "Split loop");
+        DIE(aTHX_ "Split loop");
 
     /* keep field after final delim? */
     if (s < strend || (iters && origlimit)) {
-       if (!gimme_scalar) {
-           const STRLEN l = strend - s;
-           dstr = newSVpvn_flags(s, l, (do_utf8 ? SVf_UTF8 : 0) | make_mortal);
-           XPUSHs(dstr);
-       }
-       iters++;
+        if (!gimme_scalar) {
+            const STRLEN l = strend - s;
+            dstr = newSVpvn_flags(s, l, flags);
+            XPUSHs(dstr);
+        }
+        iters++;
     }
     else if (!origlimit) {
-       if (gimme_scalar) {
-           iters -= trailing_empty;
-       } else {
-           while (iters > 0 && (!TOPs || !SvANY(TOPs) || SvCUR(TOPs) == 0)) {
-               if (TOPs && !make_mortal)
-                   sv_2mortal(TOPs);
-               *SP-- = NULL;
-               iters--;
-           }
-       }
+        if (gimme_scalar) {
+            iters -= trailing_empty;
+        } else {
+            while (iters > 0 && (!TOPs || !SvANY(TOPs) || SvCUR(TOPs) == 0)) {
+                if (TOPs && !(flags & SVs_TEMP))
+                    sv_2mortal(TOPs);
+                *SP-- = NULL;
+                iters--;
+            }
+        }
     }
 
     PUTBACK;
-    LEAVE_SCOPE(oldsave); /* may undo an earlier SWITCHSTACK */
+    LEAVE_SCOPE(oldsave);
     SPAGAIN;
     if (realarray) {
-       if (!mg) {
-           if (SvSMAGICAL(ary)) {
-               PUTBACK;
-               mg_set(MUTABLE_SV(ary));
-               SPAGAIN;
-           }
-           if (gimme == G_ARRAY) {
-               EXTEND(SP, iters);
-               Copy(AvARRAY(ary), SP + 1, iters, SV*);
-               SP += iters;
-               RETURN;
-           }
-       }
-       else {
-           PUTBACK;
-           ENTER_with_name("call_PUSH");
-           call_sv(SV_CONST(PUSH),G_SCALAR|G_DISCARD|G_METHOD_NAMED);
-           LEAVE_with_name("call_PUSH");
-           SPAGAIN;
-           if (gimme == G_ARRAY) {
-               SSize_t i;
-               /* EXTEND should not be needed - we just popped them */
-               EXTEND(SP, iters);
-               for (i=0; i < iters; i++) {
-                   SV **svp = av_fetch(ary, i, FALSE);
-                   PUSHs((svp) ? *svp : &PL_sv_undef);
-               }
-               RETURN;
-           }
-       }
-    }
-    else {
-       if (gimme == G_ARRAY)
-           RETURN;
+        if (!mg) {
+            PUTBACK;
+            if(AvREAL(ary)) {
+                if (av_count(ary) > 0)
+                    av_clear(ary);
+            } else {
+                AvREAL_on(ary);
+                AvREIFY_off(ary);
+
+                if (AvMAX(ary) > -1) {
+                    /* don't free mere refs */
+                    Zero(AvARRAY(ary), AvMAX(ary), SV*);
+                }
+            }
+            if(AvMAX(ary) < iters)
+                av_extend(ary,iters);
+            SPAGAIN;
+
+            /* Need to copy the SV*s from the stack into ary */
+            Copy(SP + 1 - iters, AvARRAY(ary), iters, SV*);
+            AvFILLp(ary) = iters - 1;
+
+            if (SvSMAGICAL(ary)) {
+                PUTBACK;
+                mg_set(MUTABLE_SV(ary));
+                SPAGAIN;
+            }
+
+            if (gimme != G_LIST) {
+                /* SP points to the final SV* pushed to the stack. But the SV*  */
+                /* are not going to be used from the stack. Point SP to below   */
+                /* the first of these SV*.                                      */
+                SP -= iters;
+                PUTBACK;
+            }
+        }
+        else {
+            PUTBACK;
+            av_extend(ary,iters);
+            av_clear(ary);
+
+            ENTER_with_name("call_PUSH");
+            call_sv(SV_CONST(PUSH),G_SCALAR|G_DISCARD|G_METHOD_NAMED);
+            LEAVE_with_name("call_PUSH");
+            SPAGAIN;
+
+            if (gimme == G_LIST) {
+                SSize_t i;
+                /* EXTEND should not be needed - we just popped them */
+                EXTEND_SKIP(SP, iters);
+                for (i=0; i < iters; i++) {
+                    SV **svp = av_fetch(ary, i, FALSE);
+                    PUSHs((svp) ? *svp : &PL_sv_undef);
+                }
+                RETURN;
+            }
+        }
     }
 
-    GETTARGET;
-    XPUSHi(iters);
+    if (gimme != G_LIST) {
+        GETTARGET;
+        XPUSHi(iters);
+     }
+
     RETURN;
 }
 
@@ -6415,9 +6452,9 @@ PP(pp_once)
     SV *const sv = PAD_SVl(PL_op->op_targ);
 
     if (SvPADSTALE(sv)) {
-       /* First time. */
-       SvPADSTALE_off(sv);
-       RETURNOP(cLOGOP->op_other);
+        /* First time. */
+        SvPADSTALE_off(sv);
+        RETURNOP(cLOGOP->op_other);
     }
     RETURNOP(cLOGOP->op_next);
 }
@@ -6430,7 +6467,7 @@ PP(pp_lock)
     SvLOCK(sv);
     if (SvTYPE(retsv) == SVt_PVAV || SvTYPE(retsv) == SVt_PVHV
      || SvTYPE(retsv) == SVt_PVCV) {
-       retsv = refto(retsv);
+        retsv = refto(retsv);
     }
     SETs(retsv);
     RETURN;
@@ -6448,13 +6485,13 @@ PP(unimplemented_op)
        Secondly, as the three ops we "panic" on are padmy, mapstart and custom,
        if we get here for a custom op then that means that the custom op didn't
        have an implementation. Given that OP_NAME() looks up the custom op
-       by its pp_addr, likely it will return NULL, unless someone (unhelpfully)
-       registers &PL_unimplemented_op as the address of their custom op.
+       by its op_ppaddr, likely it will return NULL, unless someone (unhelpfully)
+       registers &Perl_unimplemented_op as the address of their custom op.
        NULL doesn't generate a useful error message. "custom" does. */
     const char *const name = op_type >= OP_max
-       ? "[out of range]" : PL_op_name[PL_op->op_type];
+        ? "[out of range]" : PL_op_name[op_type];
     if(OP_IS_SOCKET(op_type))
-       DIE(aTHX_ PL_no_sock_func, name);
+        DIE(aTHX_ PL_no_sock_func, name);
     DIE(aTHX_ "panic: unimplemented op %s (#%d) called", name, op_type);
 }
 
@@ -6462,11 +6499,11 @@ static void
 S_maybe_unwind_defav(pTHX)
 {
     if (CX_CUR()->cx_type & CXp_HASARGS) {
-       PERL_CONTEXT *cx = CX_CUR();
+        PERL_CONTEXT *cx = CX_CUR();
 
         assert(CxHASARGS(cx));
         cx_popsub_args(cx);
-       cx->cx_type &= ~CXp_HASARGS;
+        cx->cx_type &= ~CXp_HASARGS;
     }
 }
 
@@ -6487,21 +6524,21 @@ PP(pp_coreargs)
     /* Count how many args there are first, to get some idea how far to
        extend the stack. */
     while (oa) {
-       if ((oa & 7) == OA_LIST) { maxargs = I32_MAX; break; }
-       maxargs++;
-       if (oa & OA_OPTIONAL) seen_question = 1;
-       if (!seen_question) minargs++;
-       oa >>= 4;
+        if ((oa & 7) == OA_LIST) { maxargs = I32_MAX; break; }
+        maxargs++;
+        if (oa & OA_OPTIONAL) seen_question = 1;
+        if (!seen_question) minargs++;
+        oa >>= 4;
     }
 
     if(numargs < minargs) err = "Not enough";
     else if(numargs > maxargs) err = "Too many";
     if (err)
-       /* diag_listed_as: Too many arguments for %s */
-       Perl_croak(aTHX_
-         "%s arguments for %s", err,
-          opnum ? PL_op_desc[opnum] : SvPV_nolen_const(cSVOP_sv)
-       );
+        /* diag_listed_as: Too many arguments for %s */
+        Perl_croak(aTHX_
+          "%s arguments for %s", err,
+           opnum ? PL_op_desc[opnum] : SvPV_nolen_const(cSVOP_sv)
+        );
 
     /* Reset the stack pointer.  Without this, we end up returning our own
        arguments in list context, in addition to the values we are supposed
@@ -6516,8 +6553,8 @@ PP(pp_coreargs)
        to come in between two things this function does (stack reset and
        arg pushing).  This seems the easiest way to do it. */
     if (pushmark) {
-       PUTBACK;
-       (void)Perl_pp_pushmark(aTHX);
+        PUTBACK;
+        (void)Perl_pp_pushmark(aTHX);
     }
 
     EXTEND(SP, maxargs == I32_MAX ? numargs : maxargs);
@@ -6525,109 +6562,109 @@ PP(pp_coreargs)
 
     oa = PL_opargs[opnum] >> OASHIFT;
     for (; oa&&(numargs||!pushmark); (void)(numargs&&(++svp,--numargs))) {
-       whicharg++;
-       switch (oa & 7) {
-       case OA_SCALAR:
-         try_defsv:
-           if (!numargs && defgv && whicharg == minargs + 1) {
-               PUSHs(DEFSV);
-           }
-           else PUSHs(numargs ? svp && *svp ? *svp : &PL_sv_undef : NULL);
-           break;
-       case OA_LIST:
-           while (numargs--) {
-               PUSHs(svp && *svp ? *svp : &PL_sv_undef);
-               svp++;
-           }
-           RETURN;
-       case OA_AVREF:
-           if (!numargs) {
-               GV *gv;
-               if (CvUNIQUE(find_runcv_where(FIND_RUNCV_level_eq,1,NULL)))
-                   gv = PL_argvgv;
-               else {
-                   S_maybe_unwind_defav(aTHX);
-                   gv = PL_defgv;
-               }
-               PUSHs((SV *)GvAVn(gv));
-               break;
-           }
-           if (!svp || !*svp || !SvROK(*svp)
-            || SvTYPE(SvRV(*svp)) != SVt_PVAV)
-               DIE(aTHX_
-               /* diag_listed_as: Type of arg %d to &CORE::%s must be %s*/
-                "Type of arg %d to &CORE::%s must be array reference",
-                 whicharg, PL_op_desc[opnum]
-               );
-           PUSHs(SvRV(*svp));
-           break;
-       case OA_HVREF:
-           if (!svp || !*svp || !SvROK(*svp)
-            || (  SvTYPE(SvRV(*svp)) != SVt_PVHV
-               && (  opnum == OP_DBMCLOSE || opnum == OP_DBMOPEN
-                  || SvTYPE(SvRV(*svp)) != SVt_PVAV  )))
-               DIE(aTHX_
-               /* diag_listed_as: Type of arg %d to &CORE::%s must be %s*/
-                "Type of arg %d to &CORE::%s must be hash%s reference",
-                 whicharg, PL_op_desc[opnum],
-                 opnum == OP_DBMCLOSE || opnum == OP_DBMOPEN
-                    ? ""
-                    : " or array"
-               );
-           PUSHs(SvRV(*svp));
-           break;
-       case OA_FILEREF:
-           if (!numargs) PUSHs(NULL);
-           else if(svp && *svp && SvROK(*svp) && isGV_with_GP(SvRV(*svp)))
-               /* no magic here, as the prototype will have added an extra
-                  refgen and we just want what was there before that */
-               PUSHs(SvRV(*svp));
-           else {
-               const bool constr = PL_op->op_private & whicharg;
-               PUSHs(S_rv2gv(aTHX_
-                   svp && *svp ? *svp : &PL_sv_undef,
-                   constr, cBOOL(CopHINTS_get(PL_curcop) & HINT_STRICT_REFS),
-                   !constr
-               ));
-           }
-           break;
-       case OA_SCALARREF:
-         if (!numargs) goto try_defsv;
-         else {
-           const bool wantscalar =
-               PL_op->op_private & OPpCOREARGS_SCALARMOD;
-           if (!svp || !*svp || !SvROK(*svp)
-               /* We have to permit globrefs even for the \$ proto, as
-                  *foo is indistinguishable from ${\*foo}, and the proto-
-                  type permits the latter. */
-            || SvTYPE(SvRV(*svp)) > (
-                    wantscalar       ? SVt_PVLV
-                  : opnum == OP_LOCK || opnum == OP_UNDEF
-                                     ? SVt_PVCV
-                  :                    SVt_PVHV
-               )
-              )
-               DIE(aTHX_
-                "Type of arg %d to &CORE::%s must be %s",
-                 whicharg, PL_op_name[opnum],
-                 wantscalar
-                   ? "scalar reference"
-                   : opnum == OP_LOCK || opnum == OP_UNDEF
-                      ? "reference to one of [$@%&*]"
-                      : "reference to one of [$@%*]"
-               );
-           PUSHs(SvRV(*svp));
-           if (opnum == OP_UNDEF && SvRV(*svp) == (SV *)PL_defgv) {
-               /* Undo @_ localisation, so that sub exit does not undo
-                  part of our undeffing. */
-               S_maybe_unwind_defav(aTHX);
-           }
-         }
-         break;
-       default:
-           DIE(aTHX_ "panic: unknown OA_*: %x", (unsigned)(oa&7));
-       }
-       oa = oa >> 4;
+        whicharg++;
+        switch (oa & 7) {
+        case OA_SCALAR:
+          try_defsv:
+            if (!numargs && defgv && whicharg == minargs + 1) {
+                PUSHs(DEFSV);
+            }
+            else PUSHs(numargs ? svp && *svp ? *svp : &PL_sv_undef : NULL);
+            break;
+        case OA_LIST:
+            while (numargs--) {
+                PUSHs(svp && *svp ? *svp : &PL_sv_undef);
+                svp++;
+            }
+            RETURN;
+        case OA_AVREF:
+            if (!numargs) {
+                GV *gv;
+                if (CvUNIQUE(find_runcv_where(FIND_RUNCV_level_eq,1,NULL)))
+                    gv = PL_argvgv;
+                else {
+                    S_maybe_unwind_defav(aTHX);
+                    gv = PL_defgv;
+                }
+                PUSHs((SV *)GvAVn(gv));
+                break;
+            }
+            if (!svp || !*svp || !SvROK(*svp)
+             || SvTYPE(SvRV(*svp)) != SVt_PVAV)
+                DIE(aTHX_
+                /* diag_listed_as: Type of arg %d to &CORE::%s must be %s*/
+                 "Type of arg %d to &CORE::%s must be array reference",
+                  whicharg, PL_op_desc[opnum]
+                );
+            PUSHs(SvRV(*svp));
+            break;
+        case OA_HVREF:
+            if (!svp || !*svp || !SvROK(*svp)
+             || (  SvTYPE(SvRV(*svp)) != SVt_PVHV
+                && (  opnum == OP_DBMCLOSE || opnum == OP_DBMOPEN
+                   || SvTYPE(SvRV(*svp)) != SVt_PVAV  )))
+                DIE(aTHX_
+                /* diag_listed_as: Type of arg %d to &CORE::%s must be %s*/
+                 "Type of arg %d to &CORE::%s must be hash%s reference",
+                  whicharg, PL_op_desc[opnum],
+                  opnum == OP_DBMCLOSE || opnum == OP_DBMOPEN
+                     ? ""
+                     : " or array"
+                );
+            PUSHs(SvRV(*svp));
+            break;
+        case OA_FILEREF:
+            if (!numargs) PUSHs(NULL);
+            else if(svp && *svp && SvROK(*svp) && isGV_with_GP(SvRV(*svp)))
+                /* no magic here, as the prototype will have added an extra
+                   refgen and we just want what was there before that */
+                PUSHs(SvRV(*svp));
+            else {
+                const bool constr = PL_op->op_private & whicharg;
+                PUSHs(S_rv2gv(aTHX_
+                    svp && *svp ? *svp : &PL_sv_undef,
+                    constr, cBOOL(CopHINTS_get(PL_curcop) & HINT_STRICT_REFS),
+                    !constr
+                ));
+            }
+            break;
+        case OA_SCALARREF:
+          if (!numargs) goto try_defsv;
+          else {
+            const bool wantscalar =
+                PL_op->op_private & OPpCOREARGS_SCALARMOD;
+            if (!svp || !*svp || !SvROK(*svp)
+                /* We have to permit globrefs even for the \$ proto, as
+                   *foo is indistinguishable from ${\*foo}, and the proto-
+                   type permits the latter. */
+             || SvTYPE(SvRV(*svp)) > (
+                     wantscalar       ? SVt_PVLV
+                   : opnum == OP_LOCK || opnum == OP_UNDEF
+                                      ? SVt_PVCV
+                   :                    SVt_PVHV
+                )
+               )
+                DIE(aTHX_
+                 "Type of arg %d to &CORE::%s must be %s",
+                  whicharg, PL_op_name[opnum],
+                  wantscalar
+                    ? "scalar reference"
+                    : opnum == OP_LOCK || opnum == OP_UNDEF
+                       ? "reference to one of [$@%&*]"
+                       : "reference to one of [$@%*]"
+                );
+            PUSHs(SvRV(*svp));
+            if (opnum == OP_UNDEF && SvRV(*svp) == (SV *)PL_defgv) {
+                /* Undo @_ localisation, so that sub exit does not undo
+                   part of our undeffing. */
+                S_maybe_unwind_defav(aTHX);
+            }
+          }
+          break;
+        default:
+            DIE(aTHX_ "panic: unknown OA_*: %x", (unsigned)(oa&7));
+        }
+        oa = oa >> 4;
     }
 
     RETURN;
@@ -6648,11 +6685,11 @@ PP(pp_coreargs)
 
 PP(pp_avhvswitch)
 {
-    dVAR; dSP;
+    dSP;
     return PL_ppaddr[
-               (SvTYPE(TOPs) == SVt_PVAV ? OP_AEACH : OP_EACH)
-                   + (PL_op->op_private & OPpAVHVSWITCH_MASK)
-          ](aTHX);
+                (SvTYPE(TOPs) == SVt_PVAV ? OP_AEACH : OP_EACH)
+                    + (PL_op->op_private & OPpAVHVSWITCH_MASK)
+           ](aTHX);
 }
 
 PP(pp_runcv)
@@ -6660,7 +6697,7 @@ PP(pp_runcv)
     dSP;
     CV *cv;
     if (PL_op->op_private & OPpOFFBYONE) {
-       cv = find_runcv_where(FIND_RUNCV_level_eq, 1, NULL);
+        cv = find_runcv_where(FIND_RUNCV_level_eq, 1, NULL);
     }
     else cv = find_runcv(NULL);
     XPUSHs(CvEVAL(cv) ? &PL_sv_undef : sv_2mortal(newRV((SV *)cv)));
@@ -6669,49 +6706,49 @@ PP(pp_runcv)
 
 static void
 S_localise_aelem_lval(pTHX_ AV * const av, SV * const keysv,
-                           const bool can_preserve)
+                            const bool can_preserve)
 {
     const SSize_t ix = SvIV(keysv);
     if (can_preserve ? av_exists(av, ix) : TRUE) {
-       SV ** const svp = av_fetch(av, ix, 1);
-       if (!svp || !*svp)
-           Perl_croak(aTHX_ PL_no_aelem, ix);
-       save_aelem(av, ix, svp);
+        SV ** const svp = av_fetch(av, ix, 1);
+        if (!svp || !*svp)
+            Perl_croak(aTHX_ PL_no_aelem, ix);
+        save_aelem(av, ix, svp);
     }
     else
-       SAVEADELETE(av, ix);
+        SAVEADELETE(av, ix);
 }
 
 static void
 S_localise_helem_lval(pTHX_ HV * const hv, SV * const keysv,
-                           const bool can_preserve)
+                            const bool can_preserve)
 {
     if (can_preserve ? hv_exists_ent(hv, keysv, 0) : TRUE) {
-       HE * const he = hv_fetch_ent(hv, keysv, 1, 0);
-       SV ** const svp = he ? &HeVAL(he) : NULL;
-       if (!svp || !*svp)
-           Perl_croak(aTHX_ PL_no_helem_sv, SVfARG(keysv));
-       save_helem_flags(hv, keysv, svp, 0);
+        HE * const he = hv_fetch_ent(hv, keysv, 1, 0);
+        SV ** const svp = he ? &HeVAL(he) : NULL;
+        if (!svp || !*svp)
+            Perl_croak(aTHX_ PL_no_helem_sv, SVfARG(keysv));
+        save_helem_flags(hv, keysv, svp, 0);
     }
     else
-       SAVEHDELETE(hv, keysv);
+        SAVEHDELETE(hv, keysv);
 }
 
 static void
 S_localise_gv_slot(pTHX_ GV *gv, U8 type)
 {
     if (type == OPpLVREF_SV) {
-       save_pushptrptr(gv, SvREFCNT_inc_simple(GvSV(gv)), SAVEt_GVSV);
-       GvSV(gv) = 0;
+        save_pushptrptr(gv, SvREFCNT_inc_simple(GvSV(gv)), SAVEt_GVSV);
+        GvSV(gv) = 0;
     }
     else if (type == OPpLVREF_AV)
-       /* XXX Inefficient, as it creates a new AV, which we are
-              about to clobber.  */
-       save_ary(gv);
+        /* XXX Inefficient, as it creates a new AV, which we are
+               about to clobber.  */
+        save_ary(gv);
     else {
-       assert(type == OPpLVREF_HV);
-       /* XXX Likewise inefficient.  */
-       save_hash(gv);
+        assert(type == OPpLVREF_HV);
+        /* XXX Likewise inefficient.  */
+        save_hash(gv);
     }
 }
 
@@ -6727,63 +6764,63 @@ PP(pp_refassign)
     if (!SvROK(sv)) DIE(aTHX_ "Assigned value is not a reference");
     switch (type) {
     case OPpLVREF_SV:
-       if (SvTYPE(SvRV(sv)) > SVt_PVLV)
-           bad = " SCALAR";
-       break;
+        if (SvTYPE(SvRV(sv)) > SVt_PVLV)
+            bad = " SCALAR";
+        break;
     case OPpLVREF_AV:
-       if (SvTYPE(SvRV(sv)) != SVt_PVAV)
-           bad = "n ARRAY";
-       break;
+        if (SvTYPE(SvRV(sv)) != SVt_PVAV)
+            bad = "n ARRAY";
+        break;
     case OPpLVREF_HV:
-       if (SvTYPE(SvRV(sv)) != SVt_PVHV)
-           bad = " HASH";
-       break;
+        if (SvTYPE(SvRV(sv)) != SVt_PVHV)
+            bad = " HASH";
+        break;
     case OPpLVREF_CV:
-       if (SvTYPE(SvRV(sv)) != SVt_PVCV)
-           bad = " CODE";
+        if (SvTYPE(SvRV(sv)) != SVt_PVCV)
+            bad = " CODE";
     }
     if (bad)
-       /* diag_listed_as: Assigned value is not %s reference */
-       DIE(aTHX_ "Assigned value is not a%s reference", bad);
+        /* diag_listed_as: Assigned value is not %s reference */
+        DIE(aTHX_ "Assigned value is not a%s reference", bad);
     {
     MAGIC *mg;
     HV *stash;
     switch (left ? SvTYPE(left) : 0) {
     case 0:
     {
-       SV * const old = PAD_SV(ARGTARG);
-       PAD_SETSV(ARGTARG, SvREFCNT_inc_NN(SvRV(sv)));
-       SvREFCNT_dec(old);
-       if ((PL_op->op_private & (OPpLVAL_INTRO|OPpPAD_STATE))
-               == OPpLVAL_INTRO)
-           SAVECLEARSV(PAD_SVl(ARGTARG));
-       break;
+        SV * const old = PAD_SV(ARGTARG);
+        PAD_SETSV(ARGTARG, SvREFCNT_inc_NN(SvRV(sv)));
+        SvREFCNT_dec(old);
+        if ((PL_op->op_private & (OPpLVAL_INTRO|OPpPAD_STATE))
+                == OPpLVAL_INTRO)
+            SAVECLEARSV(PAD_SVl(ARGTARG));
+        break;
     }
     case SVt_PVGV:
-       if (PL_op->op_private & OPpLVAL_INTRO) {
-           S_localise_gv_slot(aTHX_ (GV *)left, type);
-       }
-       gv_setref(left, sv);
-       SvSETMAGIC(left);
-       break;
+        if (PL_op->op_private & OPpLVAL_INTRO) {
+            S_localise_gv_slot(aTHX_ (GV *)left, type);
+        }
+        gv_setref(left, sv);
+        SvSETMAGIC(left);
+        break;
     case SVt_PVAV:
         assert(key);
-       if (UNLIKELY(PL_op->op_private & OPpLVAL_INTRO)) {
-           S_localise_aelem_lval(aTHX_ (AV *)left, key,
-                                       SvCANEXISTDELETE(left));
-       }
-       av_store((AV *)left, SvIV(key), SvREFCNT_inc_simple_NN(SvRV(sv)));
-       break;
+        if (UNLIKELY(PL_op->op_private & OPpLVAL_INTRO)) {
+            S_localise_aelem_lval(aTHX_ (AV *)left, key,
+                                        SvCANEXISTDELETE(left));
+        }
+        av_store((AV *)left, SvIV(key), SvREFCNT_inc_simple_NN(SvRV(sv)));
+        break;
     case SVt_PVHV:
         if (UNLIKELY(PL_op->op_private & OPpLVAL_INTRO)) {
             assert(key);
-           S_localise_helem_lval(aTHX_ (HV *)left, key,
-                                       SvCANEXISTDELETE(left));
+            S_localise_helem_lval(aTHX_ (HV *)left, key,
+                                        SvCANEXISTDELETE(left));
         }
-       (void)hv_store_ent((HV *)left, key, SvREFCNT_inc_simple_NN(SvRV(sv)), 0);
+        (void)hv_store_ent((HV *)left, key, SvREFCNT_inc_simple_NN(SvRV(sv)), 0);
     }
     if (PL_op->op_flags & OPf_MOD)
-       SETs(sv_2mortal(newSVsv(sv)));
+        SETs(sv_2mortal(newSVsv(sv)));
     /* XXX else can weak references go stale before they are read, e.g.,
        in leavesub?  */
     RETURN;
@@ -6797,11 +6834,11 @@ PP(pp_lvref)
     SV * const elem = PL_op->op_private & OPpLVREF_ELEM ? POPs : NULL;
     SV * const arg = PL_op->op_flags & OPf_STACKED ? POPs : NULL;
     MAGIC * const mg = sv_magicext(ret, arg, PERL_MAGIC_lvref,
-                                  &PL_vtbl_lvref, (char *)elem,
-                                  elem ? HEf_SVKEY : (I32)ARGTARG);
+                                   &PL_vtbl_lvref, (char *)elem,
+                                   elem ? HEf_SVKEY : (I32)ARGTARG);
     mg->mg_private = PL_op->op_private;
     if (PL_op->op_private & OPpLVREF_ITER)
-       mg->mg_flags |= MGf_PERSIST;
+        mg->mg_flags |= MGf_PERSIST;
     if (UNLIKELY(PL_op->op_private & OPpLVAL_INTRO)) {
       if (elem) {
         MAGIC *mg;
@@ -6816,11 +6853,11 @@ PP(pp_lvref)
         }
       }
       else if (arg) {
-       S_localise_gv_slot(aTHX_ (GV *)arg,
-                                PL_op->op_private & OPpLVREF_TYPE);
+        S_localise_gv_slot(aTHX_ (GV *)arg,
+                                 PL_op->op_private & OPpLVREF_TYPE);
       }
       else if (!(PL_op->op_private & OPpPAD_STATE))
-       SAVECLEARSV(PAD_SVl(ARGTARG));
+        SAVECLEARSV(PAD_SVl(ARGTARG));
     }
     XPUSHs(ret);
     RETURN;
@@ -6834,35 +6871,35 @@ PP(pp_lvrefslice)
     bool can_preserve = FALSE;
 
     if (UNLIKELY(localizing)) {
-       MAGIC *mg;
-       HV *stash;
-       SV **svp;
+        MAGIC *mg;
+        HV *stash;
+        SV **svp;
 
-       can_preserve = SvCANEXISTDELETE(av);
+        can_preserve = SvCANEXISTDELETE(av);
 
-       if (SvTYPE(av) == SVt_PVAV) {
-           SSize_t max = -1;
+        if (SvTYPE(av) == SVt_PVAV) {
+            SSize_t max = -1;
 
-           for (svp = MARK + 1; svp <= SP; svp++) {
-               const SSize_t elem = SvIV(*svp);
-               if (elem > max)
-                   max = elem;
-           }
-           if (max > AvMAX(av))
-               av_extend(av, max);
-       }
+            for (svp = MARK + 1; svp <= SP; svp++) {
+                const SSize_t elem = SvIV(*svp);
+                if (elem > max)
+                    max = elem;
+            }
+            if (max > AvMAX(av))
+                av_extend(av, max);
+        }
     }
 
     while (++MARK <= SP) {
-       SV * const elemsv = *MARK;
+        SV * const elemsv = *MARK;
         if (UNLIKELY(localizing)) {
             if (SvTYPE(av) == SVt_PVAV)
                 S_localise_aelem_lval(aTHX_ av, elemsv, can_preserve);
             else
                 S_localise_helem_lval(aTHX_ (HV *)av, elemsv, can_preserve);
         }
-       *MARK = sv_2mortal(newSV_type(SVt_PVMG));
-       sv_magic(*MARK,(SV *)av,PERL_MAGIC_lvref,(char *)elemsv,HEf_SVKEY);
+        *MARK = sv_2mortal(newSV_type(SVt_PVMG));
+        sv_magic(*MARK,(SV *)av,PERL_MAGIC_lvref,(char *)elemsv,HEf_SVKEY);
     }
     RETURN;
 }
@@ -6870,15 +6907,15 @@ PP(pp_lvrefslice)
 PP(pp_lvavref)
 {
     if (PL_op->op_flags & OPf_STACKED)
-       Perl_pp_rv2av(aTHX);
+        Perl_pp_rv2av(aTHX);
     else
-       Perl_pp_padav(aTHX);
+        Perl_pp_padav(aTHX);
     {
-       dSP;
-       dTOPss;
-       SETs(0); /* special alias marker that aassign recognises */
-       XPUSHs(sv);
-       RETURN;
+        dSP;
+        dTOPss;
+        SETs(0); /* special alias marker that aassign recognises */
+        XPUSHs(sv);
+        RETURN;
     }
 }
 
@@ -6887,9 +6924,9 @@ PP(pp_anonconst)
     dSP;
     dTOPss;
     SETs(sv_2mortal((SV *)newCONSTSUB(SvTYPE(CopSTASH(PL_curcop))==SVt_PVHV
-                                       ? CopSTASH(PL_curcop)
-                                       : NULL,
-                                     NULL, SvREFCNT_inc_simple_NN(sv))));
+                                        ? CopSTASH(PL_curcop)
+                                        : NULL,
+                                      NULL, SvREFCNT_inc_simple_NN(sv))));
     RETURN;
 }
 
@@ -7100,7 +7137,7 @@ S_find_runcv_name(void)
     return sv;
 }
 
-/* Check a  a subs arguments - i.e. that it has the correct number of args
+/* Check a sub's arguments - i.e. that it has the correct number of args
  * (and anything else we might think of in future). Typically used with
  * signatured subs.
  */
@@ -7108,23 +7145,30 @@ S_find_runcv_name(void)
 PP(pp_argcheck)
 {
     OP * const o       = PL_op;
-    UNOP_AUX_item *aux = cUNOP_AUXo->op_aux;
-    IV   params        = aux[0].iv;
-    IV   opt_params    = aux[1].iv;
-    char slurpy        = (char)(aux[2].iv);
+    struct op_argcheck_aux *aux = (struct op_argcheck_aux *)cUNOP_AUXo->op_aux;
+    UV   params        = aux->params;
+    UV   opt_params    = aux->opt_params;
+    char slurpy        = aux->slurpy;
     AV  *defav         = GvAV(PL_defgv); /* @_ */
-    IV   argc;
+    UV   argc;
     bool too_few;
 
     assert(!SvMAGICAL(defav));
-    argc = (AvFILLp(defav) + 1);
+    argc = (UV)(AvFILLp(defav) + 1);
     too_few = (argc < (params - opt_params));
 
     if (UNLIKELY(too_few || (!slurpy && argc > params)))
-        /* diag_listed_as: Too few arguments for subroutine '%s' */
-        /* diag_listed_as: Too many arguments for subroutine '%s' */
-        Perl_croak_caller("Too %s arguments for subroutine '%" SVf "'",
-                          too_few ? "few" : "many", S_find_runcv_name());
+
+        /* diag_listed_as: Too few arguments for subroutine '%s' (got %d; expected %d) */
+        /* diag_listed_as: Too few arguments for subroutine '%s' (got %d; expected at least %d) */
+        /* diag_listed_as: Too many arguments for subroutine '%s' (got %d; expected %d) */
+        /* diag_listed_as: Too many arguments for subroutine '%s' (got %d; expected at most %d)*/
+        Perl_croak_caller("Too %s arguments for subroutine '%" SVf "' (got %" UVuf "; expected %s%" UVuf ")",
+                          too_few ? "few" : "many",
+                          S_find_runcv_name(),
+                          argc,
+                          too_few ? (slurpy || opt_params ? "at least " : "") : (opt_params ? "at most " : ""),
+                          too_few ? (params - opt_params) : params);
 
     if (UNLIKELY(slurpy == '%' && argc > params && (argc - params) % 2))
         /* diag_listed_as: Odd name/value argument for subroutine '%s' */
@@ -7134,6 +7178,42 @@ PP(pp_argcheck)
     return NORMAL;
 }
 
+PP(pp_isa)
+{
+    dSP;
+    SV *left, *right;
+
+    right = POPs;
+    left  = TOPs;
+
+    SETs(boolSV(sv_isa_sv(left, right)));
+    RETURN;
+}
+
+PP(pp_cmpchain_and)
+{
+    dSP;
+    SV *result = POPs;
+    PUTBACK;
+    if (SvTRUE_NN(result)) {
+        return cLOGOP->op_other;
+    } else {
+        TOPs = result;
+        return NORMAL;
+    }
+}
+
+PP(pp_cmpchain_dup)
+{
+    dSP;
+    SV *right = TOPs;
+    SV *left = TOPm1s;
+    TOPm1s = right;
+    TOPs = left;
+    XPUSHs(right);
+    RETURN;
+}
+
 /*
  * ex: set ts=8 sts=4 sw=4 et:
  */