This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
quadmath doesn't do locale radixes.
[perl5.git] / pp.c
diff --git a/pp.c b/pp.c
index f544c39..0e92254 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -54,7 +54,6 @@ static const STRLEN capital_iota_len = sizeof(GREEK_CAPITAL_LETTER_IOTA_UTF8) -
 
 PP(pp_stub)
 {
-    dVAR;
     dSP;
     if (GIMME_V == G_SCALAR)
        XPUSHs(&PL_sv_undef);
@@ -65,7 +64,7 @@ PP(pp_stub)
 
 PP(pp_padav)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     I32 gimme;
     assert(SvTYPE(TARG) == SVt_PVAV);
     if (UNLIKELY( PL_op->op_private & OPpLVAL_INTRO ))
@@ -117,7 +116,7 @@ PP(pp_padav)
 
 PP(pp_padhv)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     I32 gimme;
 
     assert(SvTYPE(TARG) == SVt_PVHV);
@@ -154,7 +153,7 @@ PP(pp_padhv)
 
 PP(pp_padcv)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     assert(SvTYPE(TARG) == SVt_PVCV);
     XPUSHs(TARG);
     RETURN;
@@ -162,14 +161,14 @@ PP(pp_padcv)
 
 PP(pp_introcv)
 {
-    dVAR; dTARGET;
+    dTARGET;
     SvPADSTALE_off(TARG);
     return NORMAL;
 }
 
 PP(pp_clonecv)
 {
-    dVAR; dTARGET;
+    dTARGET;
     MAGIC * const mg =
        mg_find(PadlistNAMESARRAY(CvPADLIST(find_runcv(NULL)))[ARGTARG],
                PERL_MAGIC_proto);
@@ -211,7 +210,6 @@ static SV *
 S_rv2gv(pTHX_ SV *sv, const bool vivify_sv, const bool strict,
               const bool noinit)
 {
-    dVAR;
     if (!isGV(sv) || SvFAKE(sv)) SvGETMAGIC(sv);
     if (SvROK(sv)) {
        if (SvAMAGIC(sv)) {
@@ -251,6 +249,7 @@ S_rv2gv(pTHX_ SV *sv, const bool vivify_sv, const bool strict,
                        const char * const name = CopSTASHPV(PL_curcop);
                        gv = newGVgen_flags(name,
                                 HvNAMEUTF8(CopSTASH(PL_curcop)) ? SVf_UTF8 : 0 );
+                       SvREFCNT_inc_simple_void_NN(gv);
                    }
                    prepare_SV_for_RV(sv);
                    SvRV_set(sv, MUTABLE_SV(gv));
@@ -305,7 +304,7 @@ S_rv2gv(pTHX_ SV *sv, const bool vivify_sv, const bool strict,
 
 PP(pp_rv2gv)
 {
-    dVAR; dSP; dTOPss;
+    dSP; dTOPss;
 
     sv = S_rv2gv(aTHX_
           sv, PL_op->op_private & OPpDEREF,
@@ -324,7 +323,6 @@ GV *
 Perl_softref2xv(pTHX_ SV *const sv, const char *const what,
                const svtype type, SV ***spp)
 {
-    dVAR;
     GV *gv;
 
     PERL_ARGS_ASSERT_SOFTREF2XV;
@@ -367,7 +365,7 @@ Perl_softref2xv(pTHX_ SV *const sv, const char *const what,
 
 PP(pp_rv2sv)
 {
-    dVAR; dSP; dTOPss;
+    dSP; dTOPss;
     GV *gv = NULL;
 
     SvGETMAGIC(sv);
@@ -415,7 +413,7 @@ PP(pp_rv2sv)
 
 PP(pp_av2arylen)
 {
-    dVAR; dSP;
+    dSP;
     AV * const av = MUTABLE_AV(TOPs);
     const I32 lvalue = PL_op->op_flags & OPf_MOD || LVRET;
     if (lvalue) {
@@ -433,7 +431,7 @@ PP(pp_av2arylen)
 
 PP(pp_pos)
 {
-    dVAR; dSP; dPOPss;
+    dSP; dPOPss;
 
     if (PL_op->op_flags & OPf_MOD || LVRET) {
        SV * const ret = sv_2mortal(newSV_type(SVt_PVLV));/* Not TARG RT#67838 */
@@ -459,7 +457,7 @@ PP(pp_pos)
 
 PP(pp_rv2cv)
 {
-    dVAR; dSP;
+    dSP;
     GV *gv;
     HV *stash_unused;
     const I32 flags = (PL_op->op_flags & OPf_SPECIAL)
@@ -474,7 +472,9 @@ PP(pp_rv2cv)
     CV *cv = sv_2cv(TOPs, &stash_unused, &gv, flags);
     if (cv) NOOP;
     else if ((flags == (GV_ADD|GV_NOEXPAND)) && gv && SvROK(gv)) {
-       cv = MUTABLE_CV(gv);
+       cv = SvTYPE(SvRV(gv)) == SVt_PVCV
+           ? MUTABLE_CV(SvRV(gv))
+           : MUTABLE_CV(gv);
     }    
     else
        cv = MUTABLE_CV(&PL_sv_undef);
@@ -484,7 +484,7 @@ PP(pp_rv2cv)
 
 PP(pp_prototype)
 {
-    dVAR; dSP;
+    dSP;
     CV *cv;
     HV *stash;
     GV *gv;
@@ -517,7 +517,7 @@ PP(pp_prototype)
 
 PP(pp_anoncode)
 {
-    dVAR; dSP;
+    dSP;
     CV *cv = MUTABLE_CV(PAD_SV(PL_op->op_targ));
     if (CvCLONE(cv))
        cv = MUTABLE_CV(sv_2mortal(MUTABLE_SV(cv_clone(cv))));
@@ -528,14 +528,14 @@ PP(pp_anoncode)
 
 PP(pp_srefgen)
 {
-    dVAR; dSP;
+    dSP;
     *SP = refto(*SP);
     RETURN;
 }
 
 PP(pp_refgen)
 {
-    dVAR; dSP; dMARK;
+    dSP; dMARK;
     if (GIMME != G_ARRAY) {
        if (++MARK <= SP)
            *MARK = *SP;
@@ -554,7 +554,6 @@ PP(pp_refgen)
 STATIC SV*
 S_refto(pTHX_ SV *sv)
 {
-    dVAR;
     SV* rv;
 
     PERL_ARGS_ASSERT_REFTO;
@@ -574,7 +573,6 @@ S_refto(pTHX_ SV *sv)
        SvREFCNT_inc_void_NN(sv);
     }
     else if (SvPADTMP(sv)) {
-        assert(!IS_PADGV(sv));
         sv = newSVsv(sv);
     }
     else {
@@ -590,21 +588,26 @@ S_refto(pTHX_ SV *sv)
 
 PP(pp_ref)
 {
-    dVAR; dSP; dTARGET;
-    SV * const sv = POPs;
+    dSP;
+    SV * const sv = TOPs;
 
     SvGETMAGIC(sv);
     if (!SvROK(sv))
-       RETPUSHNO;
+       SETs(&PL_sv_no);
+    else {
+       dTARGET;
+       SETs(TARG);
+       /* use the return value that is in a register, its the same as TARG */
+       TARG = sv_ref(TARG,SvRV(sv),TRUE);
+       SvSETMAGIC(TARG);
+    }
 
-    (void)sv_ref(TARG,SvRV(sv),TRUE);
-    PUSHTARG;
-    RETURN;
+    return NORMAL;
 }
 
 PP(pp_bless)
 {
-    dVAR; dSP;
+    dSP;
     HV *stash;
 
     if (MAXARG == 1)
@@ -645,7 +648,7 @@ PP(pp_bless)
 
 PP(pp_gelem)
 {
-    dVAR; dSP;
+    dSP;
 
     SV *sv = POPs;
     STRLEN len;
@@ -724,7 +727,7 @@ PP(pp_gelem)
 
 PP(pp_study)
 {
-    dVAR; dSP; dPOPss;
+    dSP; dPOPss;
     STRLEN len;
 
     (void)SvPV(sv, len);
@@ -740,7 +743,7 @@ PP(pp_study)
 
 PP(pp_trans)
 {
-    dVAR; dSP; dTARG;
+    dSP; dTARG;
     SV *sv;
 
     if (PL_op->op_flags & OPf_STACKED)
@@ -770,7 +773,6 @@ PP(pp_trans)
 static void
 S_do_chomp(pTHX_ SV *retval, SV *sv, bool chomping)
 {
-    dVAR;
     STRLEN len;
     char *s;
 
@@ -934,7 +936,7 @@ S_do_chomp(pTHX_ SV *retval, SV *sv, bool chomping)
 
 PP(pp_schop)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     const bool chomping = PL_op->op_type == OP_SCHOMP;
 
     if (chomping)
@@ -946,7 +948,7 @@ PP(pp_schop)
 
 PP(pp_chop)
 {
-    dVAR; dSP; dMARK; dTARGET; dORIGMARK;
+    dSP; dMARK; dTARGET; dORIGMARK;
     const bool chomping = PL_op->op_type == OP_CHOMP;
 
     if (chomping)
@@ -960,7 +962,7 @@ PP(pp_chop)
 
 PP(pp_undef)
 {
-    dVAR; dSP;
+    dSP;
     SV *sv;
 
     if (!PL_op->op_private) {
@@ -972,7 +974,8 @@ PP(pp_undef)
     if (!sv)
        RETPUSHUNDEF;
 
-    SV_CHECK_THINKFIRST_COW_DROP(sv);
+    if (SvTHINKFIRST(sv))
+       sv_force_normal_flags(sv, SV_COW_DROP_PV|SV_IMMEDIATE_UNREF);
 
     switch (SvTYPE(sv)) {
     case SVt_NULL:
@@ -997,18 +1000,8 @@ PP(pp_undef)
                            ));
        /* FALLTHROUGH */
     case SVt_PVFM:
-       {
            /* let user-undef'd sub keep its identity */
-           GV* const gv = CvGV((const CV *)sv);
-           HEK * const hek = CvNAME_HEK((CV *)sv);
-           if (hek) share_hek_hek(hek);
-           cv_undef(MUTABLE_CV(sv));
-           if (gv) CvGV_set(MUTABLE_CV(sv), gv);
-           else if (hek) {
-               SvANY((CV *)sv)->xcv_gv_u.xcv_hek = hek;
-               CvNAMED_on(sv);
-           }
-       }
+       cv_undef_flags(MUTABLE_CV(sv), CV_UNDEF_KEEP_NAME);
        break;
     case SVt_PVGV:
        assert(isGV_with_GP(sv));
@@ -1069,7 +1062,7 @@ PP(pp_undef)
 
 PP(pp_postinc)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     const bool inc =
        PL_op->op_type == OP_POSTINC || PL_op->op_type == OP_I_POSTINC;
     if (SvTYPE(TOPs) >= SVt_PVAV || (isGV_with_GP(TOPs) && !SvFAKE(TOPs)))
@@ -1098,7 +1091,7 @@ PP(pp_postinc)
 
 PP(pp_pow)
 {
-    dVAR; dSP; dATARGET; SV *svl, *svr;
+    dSP; dATARGET; SV *svl, *svr;
 #ifdef PERL_PRESERVE_IVUV
     bool is_int = 0;
 #endif
@@ -1265,7 +1258,7 @@ PP(pp_pow)
 
 PP(pp_multiply)
 {
-    dVAR; dSP; dATARGET; SV *svl, *svr;
+    dSP; dATARGET; SV *svl, *svr;
     tryAMAGICbin_MG(mult_amg, AMGf_assign|AMGf_numeric);
     svr = TOPs;
     svl = TOPm1s;
@@ -1387,7 +1380,7 @@ PP(pp_multiply)
 
 PP(pp_divide)
 {
-    dVAR; dSP; dATARGET; SV *svl, *svr;
+    dSP; dATARGET; SV *svl, *svr;
     tryAMAGICbin_MG(div_amg, AMGf_assign|AMGf_numeric);
     svr = TOPs;
     svl = TOPm1s;
@@ -1507,7 +1500,7 @@ PP(pp_divide)
 
 PP(pp_modulo)
 {
-    dVAR; dSP; dATARGET;
+    dSP; dATARGET;
     tryAMAGICbin_MG(modulo_amg, AMGf_assign|AMGf_numeric);
     {
        UV left  = 0;
@@ -1634,7 +1627,7 @@ PP(pp_modulo)
 
 PP(pp_repeat)
 {
-    dVAR; dSP; dATARGET;
+    dSP; dATARGET;
     IV count;
     SV *sv;
 
@@ -1656,23 +1649,25 @@ PP(pp_repeat)
              else
                   count = uv;
         } else {
-             const IV iv = SvIV_nomg(sv);
-             if (iv < 0)
-                  count = 0;
-             else
-                  count = iv;
+             count = SvIV_nomg(sv);
         }
     }
     else if (SvNOKp(sv)) {
         const NV nv = SvNV_nomg(sv);
         if (nv < 0.0)
-             count = 0;
+              count = -1;   /* An arbitrary negative integer */
         else
              count = (IV)nv;
     }
     else
         count = SvIV_nomg(sv);
 
+    if (count < 0) {
+        count = 0;
+        Perl_ck_warner(aTHX_ packWARN(WARN_NUMERIC),
+                                         "Negative repeat count does nothing");
+    }
+
     if (GIMME == G_ARRAY && PL_op->op_private & OPpREPEAT_DOLIST) {
        dMARK;
        static const char* const oom_list_extend = "Out of memory during list extend";
@@ -1713,7 +1708,6 @@ PP(pp_repeat)
 #else
                 if (*SP) {
                    if (mod && SvPADTMP(*SP)) {
-                       assert(!IS_PADGV(*SP));
                        *SP = sv_mortalcopy(*SP);
                    }
                   SvTEMP_off((*SP));
@@ -1775,7 +1769,7 @@ PP(pp_repeat)
 
 PP(pp_subtract)
 {
-    dVAR; dSP; dATARGET; bool useleft; SV *svl, *svr;
+    dSP; dATARGET; bool useleft; SV *svl, *svr;
     tryAMAGICbin_MG(subtr_amg, AMGf_assign|AMGf_numeric);
     svr = TOPs;
     svl = TOPm1s;
@@ -1894,7 +1888,7 @@ PP(pp_subtract)
 
 PP(pp_left_shift)
 {
-    dVAR; dSP; dATARGET; SV *svl, *svr;
+    dSP; dATARGET; SV *svl, *svr;
     tryAMAGICbin_MG(lshift_amg, AMGf_assign|AMGf_numeric);
     svr = POPs;
     svl = TOPs;
@@ -1914,7 +1908,7 @@ PP(pp_left_shift)
 
 PP(pp_right_shift)
 {
-    dVAR; dSP; dATARGET; SV *svl, *svr;
+    dSP; dATARGET; SV *svl, *svr;
     tryAMAGICbin_MG(rshift_amg, AMGf_assign|AMGf_numeric);
     svr = POPs;
     svl = TOPs;
@@ -1934,7 +1928,7 @@ PP(pp_right_shift)
 
 PP(pp_lt)
 {
-    dVAR; dSP;
+    dSP;
     SV *left, *right;
 
     tryAMAGICbin_MG(lt_amg, AMGf_set|AMGf_numeric);
@@ -1950,7 +1944,7 @@ PP(pp_lt)
 
 PP(pp_gt)
 {
-    dVAR; dSP;
+    dSP;
     SV *left, *right;
 
     tryAMAGICbin_MG(gt_amg, AMGf_set|AMGf_numeric);
@@ -1966,7 +1960,7 @@ PP(pp_gt)
 
 PP(pp_le)
 {
-    dVAR; dSP;
+    dSP;
     SV *left, *right;
 
     tryAMAGICbin_MG(le_amg, AMGf_set|AMGf_numeric);
@@ -1982,7 +1976,7 @@ PP(pp_le)
 
 PP(pp_ge)
 {
-    dVAR; dSP;
+    dSP;
     SV *left, *right;
 
     tryAMAGICbin_MG(ge_amg, AMGf_set|AMGf_numeric);
@@ -1998,7 +1992,7 @@ PP(pp_ge)
 
 PP(pp_ne)
 {
-    dVAR; dSP;
+    dSP;
     SV *left, *right;
 
     tryAMAGICbin_MG(ne_amg, AMGf_set|AMGf_numeric);
@@ -2021,8 +2015,6 @@ PP(pp_ne)
 I32
 Perl_do_ncmp(pTHX_ SV* const left, SV * const right)
 {
-    dVAR;
-
     PERL_ARGS_ASSERT_DO_NCMP;
 #ifdef PERL_PRESERVE_IVUV
     /* Fortunately it seems NaN isn't IOK */
@@ -2088,7 +2080,7 @@ Perl_do_ncmp(pTHX_ SV* const left, SV * const right)
 
 PP(pp_ncmp)
 {
-    dVAR; dSP;
+    dSP;
     SV *left, *right;
     I32 value;
     tryAMAGICbin_MG(ncmp_amg, AMGf_numeric);
@@ -2107,7 +2099,7 @@ PP(pp_ncmp)
 
 PP(pp_sle)
 {
-    dVAR; dSP;
+    dSP;
 
     int amg_type = sle_amg;
     int multiplier = 1;
@@ -2136,7 +2128,7 @@ PP(pp_sle)
     {
       dPOPTOPssrl;
       const int cmp =
-#ifdef USE_LC_COLLATE
+#ifdef USE_LOCALE_COLLATE
                       (IN_LC_RUNTIME(LC_COLLATE))
                      ? sv_cmp_locale_flags(left, right, 0)
                       :
@@ -2149,7 +2141,7 @@ PP(pp_sle)
 
 PP(pp_seq)
 {
-    dVAR; dSP;
+    dSP;
     tryAMAGICbin_MG(seq_amg, AMGf_set);
     {
       dPOPTOPssrl;
@@ -2160,7 +2152,7 @@ PP(pp_seq)
 
 PP(pp_sne)
 {
-    dVAR; dSP;
+    dSP;
     tryAMAGICbin_MG(sne_amg, AMGf_set);
     {
       dPOPTOPssrl;
@@ -2171,12 +2163,12 @@ PP(pp_sne)
 
 PP(pp_scmp)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     tryAMAGICbin_MG(scmp_amg, 0);
     {
       dPOPTOPssrl;
       const int cmp =
-#ifdef USE_LC_COLLATE
+#ifdef USE_LOCALE_COLLATE
                       (IN_LC_RUNTIME(LC_COLLATE))
                      ? sv_cmp_locale_flags(left, right, 0)
                      :
@@ -2189,7 +2181,7 @@ PP(pp_scmp)
 
 PP(pp_bit_and)
 {
-    dVAR; dSP; dATARGET;
+    dSP; dATARGET;
     tryAMAGICbin_MG(band_amg, AMGf_assign);
     {
       dPOPTOPssrl;
@@ -2217,7 +2209,7 @@ PP(pp_bit_and)
 
 PP(pp_bit_or)
 {
-    dVAR; dSP; dATARGET;
+    dSP; dATARGET;
     const int op_type = PL_op->op_type;
 
     tryAMAGICbin_MG((op_type == OP_BIT_OR ? bor_amg : bxor_amg), AMGf_assign);
@@ -2274,7 +2266,7 @@ S_negate_string(pTHX)
 
 PP(pp_negate)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     tryAMAGICun_MG(neg_amg, AMGf_numeric);
     if (S_negate_string(aTHX)) return NORMAL;
     {
@@ -2318,7 +2310,7 @@ PP(pp_negate)
 
 PP(pp_not)
 {
-    dVAR; dSP;
+    dSP;
     tryAMAGICun_MG(not_amg, AMGf_set);
     *PL_stack_sp = boolSV(!SvTRUE_nomg(*PL_stack_sp));
     return NORMAL;
@@ -2326,7 +2318,7 @@ PP(pp_not)
 
 PP(pp_complement)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     tryAMAGICun_MG(compl_amg, AMGf_numeric);
     {
       dTOPss;
@@ -2427,7 +2419,7 @@ PP(pp_complement)
 
 PP(pp_i_multiply)
 {
-    dVAR; dSP; dATARGET;
+    dSP; dATARGET;
     tryAMAGICbin_MG(mult_amg, AMGf_assign);
     {
       dPOPTOPiirl_nomg;
@@ -2439,7 +2431,7 @@ PP(pp_i_multiply)
 PP(pp_i_divide)
 {
     IV num;
-    dVAR; dSP; dATARGET;
+    dSP; dATARGET;
     tryAMAGICbin_MG(div_amg, AMGf_assign);
     {
       dPOPTOPssrl;
@@ -2466,7 +2458,7 @@ PP(pp_i_modulo)
 #endif
 {
      /* This is the vanilla old i_modulo. */
-     dVAR; dSP; dATARGET;
+     dSP; dATARGET;
      tryAMAGICbin_MG(modulo_amg, AMGf_assign);
      {
          dPOPTOPiirl_nomg;
@@ -2489,7 +2481,7 @@ PP(pp_i_modulo_1)
      /* 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. */
-     dVAR; dSP; dATARGET;
+     dSP; dATARGET;
      tryAMAGICbin_MG(modulo_amg, AMGf_assign);
      {
          dPOPTOPiirl_nomg;
@@ -2550,7 +2542,7 @@ PP(pp_i_modulo)
 
 PP(pp_i_add)
 {
-    dVAR; dSP; dATARGET;
+    dSP; dATARGET;
     tryAMAGICbin_MG(add_amg, AMGf_assign);
     {
       dPOPTOPiirl_ul_nomg;
@@ -2561,7 +2553,7 @@ PP(pp_i_add)
 
 PP(pp_i_subtract)
 {
-    dVAR; dSP; dATARGET;
+    dSP; dATARGET;
     tryAMAGICbin_MG(subtr_amg, AMGf_assign);
     {
       dPOPTOPiirl_ul_nomg;
@@ -2572,7 +2564,7 @@ PP(pp_i_subtract)
 
 PP(pp_i_lt)
 {
-    dVAR; dSP;
+    dSP;
     tryAMAGICbin_MG(lt_amg, AMGf_set);
     {
       dPOPTOPiirl_nomg;
@@ -2583,7 +2575,7 @@ PP(pp_i_lt)
 
 PP(pp_i_gt)
 {
-    dVAR; dSP;
+    dSP;
     tryAMAGICbin_MG(gt_amg, AMGf_set);
     {
       dPOPTOPiirl_nomg;
@@ -2594,7 +2586,7 @@ PP(pp_i_gt)
 
 PP(pp_i_le)
 {
-    dVAR; dSP;
+    dSP;
     tryAMAGICbin_MG(le_amg, AMGf_set);
     {
       dPOPTOPiirl_nomg;
@@ -2605,7 +2597,7 @@ PP(pp_i_le)
 
 PP(pp_i_ge)
 {
-    dVAR; dSP;
+    dSP;
     tryAMAGICbin_MG(ge_amg, AMGf_set);
     {
       dPOPTOPiirl_nomg;
@@ -2616,7 +2608,7 @@ PP(pp_i_ge)
 
 PP(pp_i_eq)
 {
-    dVAR; dSP;
+    dSP;
     tryAMAGICbin_MG(eq_amg, AMGf_set);
     {
       dPOPTOPiirl_nomg;
@@ -2627,7 +2619,7 @@ PP(pp_i_eq)
 
 PP(pp_i_ne)
 {
-    dVAR; dSP;
+    dSP;
     tryAMAGICbin_MG(ne_amg, AMGf_set);
     {
       dPOPTOPiirl_nomg;
@@ -2638,7 +2630,7 @@ PP(pp_i_ne)
 
 PP(pp_i_ncmp)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     tryAMAGICbin_MG(ncmp_amg, 0);
     {
       dPOPTOPiirl_nomg;
@@ -2657,7 +2649,7 @@ PP(pp_i_ncmp)
 
 PP(pp_i_negate)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     tryAMAGICun_MG(neg_amg, 0);
     if (S_negate_string(aTHX)) return NORMAL;
     {
@@ -2672,7 +2664,7 @@ PP(pp_i_negate)
 
 PP(pp_atan2)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     tryAMAGICbin_MG(atan2_amg, 0);
     {
       dPOPTOPnnrl_nomg;
@@ -2683,46 +2675,42 @@ PP(pp_atan2)
 
 PP(pp_sin)
 {
-    dVAR; dSP; dTARGET;
-    int amg_type = sin_amg;
+    dSP; dTARGET;
+    int amg_type = fallback_amg;
     const char *neg_report = NULL;
-    NV (*func)(NV) = Perl_sin;
     const int op_type = PL_op->op_type;
 
     switch (op_type) {
-    case OP_COS:
-       amg_type = cos_amg;
-       func = Perl_cos;
-       break;
-    case OP_EXP:
-       amg_type = exp_amg;
-       func = Perl_exp;
-       break;
-    case OP_LOG:
-       amg_type = log_amg;
-       func = Perl_log;
-       neg_report = "log";
-       break;
-    case OP_SQRT:
-       amg_type = sqrt_amg;
-       func = Perl_sqrt;
-       neg_report = "sqrt";
-       break;
+    case OP_SIN:  amg_type = sin_amg; break;
+    case OP_COS:  amg_type = cos_amg; break;
+    case OP_EXP:  amg_type = exp_amg; break;
+    case OP_LOG:  amg_type = log_amg;  neg_report = "log";  break;
+    case OP_SQRT: amg_type = sqrt_amg; neg_report = "sqrt"; break;
     }
 
+    assert(amg_type != fallback_amg);
 
     tryAMAGICun_MG(amg_type, 0);
     {
       SV * const arg = POPs;
       const NV value = SvNV_nomg(arg);
-      if (neg_report) {
+      NV result = NV_NAN;
+      if (neg_report) { /* log or sqrt */
          if (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);
          }
       }
-      XPUSHn(func(value));
+      switch (op_type) {
+      default:
+      case OP_SIN:  result = Perl_sin(value);  break;
+      case OP_COS:  result = Perl_cos(value);  break;
+      case OP_EXP:  result = Perl_exp(value);  break;
+      case OP_LOG:  result = Perl_log(value);  break;
+      case OP_SQRT: result = Perl_sqrt(value); break;
+      }
+      XPUSHn(result);
       RETURN;
     }
 }
@@ -2740,7 +2728,6 @@ PP(pp_sin)
 
 PP(pp_rand)
 {
-    dVAR;
     if (!PL_srand_called) {
        (void)seedDrand01((Rand_seed_t)seed());
        PL_srand_called = TRUE;
@@ -2775,7 +2762,7 @@ PP(pp_rand)
 
 PP(pp_srand)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     UV anum;
 
     if (MAXARG >= 1 && (TOPs || POPs)) {
@@ -2813,7 +2800,7 @@ PP(pp_srand)
 
 PP(pp_int)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     tryAMAGICun_MG(int_amg, AMGf_numeric);
     {
       SV * const sv = TOPs;
@@ -2855,7 +2842,7 @@ PP(pp_int)
 
 PP(pp_abs)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     tryAMAGICun_MG(abs_amg, AMGf_numeric);
     {
       SV * const sv = TOPs;
@@ -2895,7 +2882,7 @@ PP(pp_abs)
 
 PP(pp_oct)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     const char *tmps;
     I32 flags = PERL_SCAN_ALLOW_UNDERSCORES;
     STRLEN len;
@@ -2920,11 +2907,11 @@ PP(pp_oct)
         tmps++, len--;
     if (*tmps == '0')
         tmps++, len--;
-    if (*tmps == 'x' || *tmps == 'X') {
+    if (isALPHA_FOLD_EQ(*tmps, 'x')) {
     hex:
         result_uv = grok_hex (tmps, &len, &flags, &result_nv);
     }
-    else if (*tmps == 'b' || *tmps == 'B')
+    else if (isALPHA_FOLD_EQ(*tmps, 'b'))
         result_uv = grok_bin (tmps, &len, &flags, &result_nv);
     else
         result_uv = grok_oct (tmps, &len, &flags, &result_nv);
@@ -2942,7 +2929,7 @@ PP(pp_oct)
 
 PP(pp_length)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     SV * const sv = TOPs;
 
     SvGETMAGIC(sv);
@@ -2970,16 +2957,15 @@ PP(pp_length)
    always be true for an explicit 0.
 */
 bool
-Perl_translate_substr_offsets(pTHX_ STRLEN curlen, IV pos1_iv,
-                                   bool pos1_is_uv, IV len_iv,
-                                   bool len_is_uv, STRLEN *posp,
-                                   STRLEN *lenp)
+Perl_translate_substr_offsets( STRLEN curlen, IV pos1_iv,
+                               bool pos1_is_uv, IV len_iv,
+                               bool len_is_uv, STRLEN *posp,
+                               STRLEN *lenp)
 {
     IV pos2_iv;
     int    pos2_is_uv;
 
     PERL_ARGS_ASSERT_TRANSLATE_SUBSTR_OFFSETS;
-    PERL_UNUSED_CONTEXT;
 
     if (!pos1_is_uv && pos1_iv < 0 && curlen) {
        pos1_is_uv = curlen-1 > ~(UV)pos1_iv;
@@ -3035,7 +3021,7 @@ Perl_translate_substr_offsets(pTHX_ STRLEN curlen, IV pos1_iv,
 
 PP(pp_substr)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     SV *sv;
     STRLEN curlen;
     STRLEN utf8_curlen;
@@ -3174,7 +3160,7 @@ bound_fail:
 
 PP(pp_vec)
 {
-    dVAR; dSP;
+    dSP;
     const IV size   = POPi;
     const IV offset = POPi;
     SV * const src = POPs;
@@ -3202,7 +3188,7 @@ PP(pp_vec)
 
 PP(pp_index)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     SV *big;
     SV *little;
     SV *temp = NULL;
@@ -3319,7 +3305,7 @@ PP(pp_index)
 
 PP(pp_sprintf)
 {
-    dVAR; dSP; dMARK; dORIGMARK; dTARGET;
+    dSP; dMARK; dORIGMARK; dTARGET;
     SvTAINTED_off(TARG);
     do_sprintf(TARG, SP-MARK, MARK+1);
     TAINT_IF(SvTAINTED(TARG));
@@ -3330,7 +3316,7 @@ PP(pp_sprintf)
 
 PP(pp_ord)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
 
     SV *argsv = POPs;
     STRLEN len;
@@ -3352,29 +3338,38 @@ PP(pp_ord)
 
 PP(pp_chr)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     char *tmps;
     UV value;
     SV *top = POPs;
 
     SvGETMAGIC(top);
-    if (!IN_BYTES /* under bytes, chr(-1) eq chr(0xff), etc. */
-     && ((SvIOKp(top) && !SvIsUV(top) && SvIV_nomg(top) < 0)
-        ||
-        ((SvNOKp(top) || (SvOK(top) && !SvIsUV(top)))
-         && SvNV_nomg(top) < 0.0))) {
+    if (SvNOK(top) && Perl_isinfnan(SvNV(top))) {
+        if (ckWARN(WARN_UTF8)) {
+            Perl_warner(aTHX_ packWARN(WARN_UTF8),
+                        "Invalid number (%"NVgf") in chr", SvNV(top));
+        }
+        value = UNICODE_REPLACEMENT;
+    }
+    else {
+        if (!IN_BYTES /* under bytes, chr(-1) eq chr(0xff), etc. */
+            && ((SvIOKp(top) && !SvIsUV(top) && SvIV_nomg(top) < 0)
+                ||
+                ((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;
                }
-               Perl_warner(aTHX_ packWARN(WARN_UTF8),
-                          "Invalid negative number (%"SVf") in chr", SVfARG(top));
-           }
-           value = UNICODE_REPLACEMENT;
-    } else {
-       value = SvUV_nomg(top);
+                Perl_warner(aTHX_ packWARN(WARN_UTF8),
+                            "Invalid negative number (%"SVf") in chr", SVfARG(top));
+            }
+            value = UNICODE_REPLACEMENT;
+        } else {
+            value = SvUV_nomg(top);
+        }
     }
 
     SvUPGRADE(TARG,SVt_PV);
@@ -3420,7 +3415,7 @@ PP(pp_chr)
 PP(pp_crypt)
 {
 #ifdef HAS_CRYPT
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     dPOPTOPssrl;
     STRLEN len;
     const char *tmps = SvPV_const(left, len);
@@ -3476,7 +3471,6 @@ PP(pp_ucfirst)
      * take the source and change that one character and store it back, but not
      * if read-only etc, or if the length changes */
 
-    dVAR;
     dSP;
     SV *source = TOPs;
     STRLEN slen; /* slen is the byte length of the whole SV. */
@@ -3729,7 +3723,6 @@ PP(pp_ucfirst)
    of the three tight loops.  There is less and less commonality though */
 PP(pp_uc)
 {
-    dVAR;
     dSP;
     SV *source = TOPs;
     STRLEN len;
@@ -3984,7 +3977,6 @@ PP(pp_uc)
 
 PP(pp_lc)
 {
-    dVAR;
     dSP;
     SV *source = TOPs;
     STRLEN len;
@@ -4111,7 +4103,7 @@ PP(pp_lc)
 
 PP(pp_quotemeta)
 {
-    dVAR; dSP; dTARGET;
+    dSP; dTARGET;
     SV * const sv = TOPs;
     STRLEN len;
     const char *s = SvPV_const(sv,len);
@@ -4133,15 +4125,18 @@ PP(pp_quotemeta)
                    }
                }
                else if (UTF8_IS_DOWNGRADEABLE_START(*s)) {
+                   if (
 #ifdef USE_LOCALE_CTYPE
                    /* In locale, we quote all non-ASCII Latin1 chars.
                     * Otherwise use the quoting rules */
-                   if (IN_LC_RUNTIME(LC_CTYPE)
-                       || _isQUOTEMETA(TWO_BYTE_UTF8_TO_NATIVE(*s, *(s + 1))))
+                   
+                   IN_LC_RUNTIME(LC_CTYPE)
+                       ||
+#endif
+                       _isQUOTEMETA(TWO_BYTE_UTF8_TO_NATIVE(*s, *(s + 1))))
                    {
                        to_quote = TRUE;
                    }
-#endif
                }
                else if (is_QUOTEMETA_high(s)) {
                    to_quote = TRUE;
@@ -4186,7 +4181,6 @@ PP(pp_quotemeta)
 
 PP(pp_fc)
 {
-    dVAR;
     dTARGET;
     dSP;
     SV *source = TOPs;
@@ -4351,7 +4345,7 @@ PP(pp_fc)
 
 PP(pp_aslice)
 {
-    dVAR; dSP; dMARK; dORIGMARK;
+    dSP; dMARK; dORIGMARK;
     AV *const av = MUTABLE_AV(POPs);
     const I32 lval = (PL_op->op_flags & OPf_MOD || LVRET);
 
@@ -4415,7 +4409,7 @@ PP(pp_aslice)
 
 PP(pp_kvaslice)
 {
-    dVAR; dSP; dMARK;
+    dSP; dMARK;
     AV *const av = MUTABLE_AV(POPs);
     I32 lval = (PL_op->op_flags & OPf_MOD);
     SSize_t items = SP - MARK;
@@ -4461,7 +4455,6 @@ PP(pp_kvaslice)
 /* Smart dereferencing for keys, values and each */
 PP(pp_rkeys)
 {
-    dVAR;
     dSP;
     dPOPss;
 
@@ -4499,7 +4492,6 @@ PP(pp_rkeys)
 
 PP(pp_aeach)
 {
-    dVAR;
     dSP;
     AV *array = MUTABLE_AV(POPs);
     const I32 gimme = GIMME_V;
@@ -4525,7 +4517,6 @@ PP(pp_aeach)
 
 PP(pp_akeys)
 {
-    dVAR;
     dSP;
     AV *array = MUTABLE_AV(POPs);
     const I32 gimme = GIMME_V;
@@ -4561,7 +4552,6 @@ PP(pp_akeys)
 
 PP(pp_each)
 {
-    dVAR;
     dSP;
     HV * hash = MUTABLE_HV(POPs);
     HE *entry;
@@ -4594,7 +4584,6 @@ PP(pp_each)
 STATIC OP *
 S_do_delete_local(pTHX)
 {
-    dVAR;
     dSP;
     const I32 gimme = GIMME_V;
     const MAGIC *mg;
@@ -4705,7 +4694,6 @@ S_do_delete_local(pTHX)
 
 PP(pp_delete)
 {
-    dVAR;
     dSP;
     I32 gimme;
     I32 discard;
@@ -4771,7 +4759,6 @@ PP(pp_delete)
 
 PP(pp_exists)
 {
-    dVAR;
     dSP;
     SV *tmpsv;
     HV *hv;
@@ -4806,7 +4793,7 @@ PP(pp_exists)
 
 PP(pp_hslice)
 {
-    dVAR; dSP; dMARK; dORIGMARK;
+    dSP; dMARK; dORIGMARK;
     HV * const hv = MUTABLE_HV(POPs);
     const I32 lval = (PL_op->op_flags & OPf_MOD || LVRET);
     const bool localizing = PL_op->op_private & OPpLVAL_INTRO;
@@ -4863,7 +4850,7 @@ PP(pp_hslice)
 
 PP(pp_kvhslice)
 {
-    dVAR; dSP; dMARK;
+    dSP; dMARK;
     HV * const hv = MUTABLE_HV(POPs);
     I32 lval = (PL_op->op_flags & OPf_MOD);
     SSize_t items = SP - MARK;
@@ -4914,7 +4901,6 @@ PP(pp_kvhslice)
 
 PP(pp_list)
 {
-    dVAR;
     I32 markidx = POPMARK;
     if (GIMME != G_ARRAY) {
        SV **mark = PL_stack_base + markidx;
@@ -4931,7 +4917,6 @@ PP(pp_list)
 
 PP(pp_lslice)
 {
-    dVAR;
     dSP;
     SV ** const lastrelem = PL_stack_sp;
     SV ** const lastlelem = PL_stack_base + POPMARK;
@@ -4971,7 +4956,6 @@ PP(pp_lslice)
            if (!(*lelem = firstrelem[ix]))
                *lelem = &PL_sv_undef;
            else if (mod && SvPADTMP(*lelem)) {
-                assert(!IS_PADGV(*lelem));
                *lelem = firstrelem[ix] = sv_mortalcopy(*lelem);
             }
        }
@@ -4985,7 +4969,7 @@ PP(pp_lslice)
 
 PP(pp_anonlist)
 {
-    dVAR; dSP; dMARK;
+    dSP; dMARK;
     const I32 items = SP - MARK;
     SV * const av = MUTABLE_SV(av_make(items, MARK+1));
     SP = MARK;
@@ -4996,7 +4980,7 @@ PP(pp_anonlist)
 
 PP(pp_anonhash)
 {
-    dVAR; dSP; dMARK; dORIGMARK;
+    dSP; dMARK; dORIGMARK;
     HV* const hv = newHV();
     SV* const retval = sv_2mortal( PL_op->op_flags & OPf_SPECIAL
                                     ? newRV_noinc(MUTABLE_SV(hv))
@@ -5057,7 +5041,7 @@ S_deref_plain_array(pTHX_ AV *ary)
 
 PP(pp_splice)
 {
-    dVAR; dSP; dMARK; dORIGMARK;
+    dSP; dMARK; dORIGMARK;
     int num_args = (SP - MARK);
     AV *ary = DEREF_PLAIN_ARRAY(MUTABLE_AV(*++MARK));
     SV **src;
@@ -5267,7 +5251,7 @@ PP(pp_splice)
 
 PP(pp_push)
 {
-    dVAR; dSP; dMARK; dORIGMARK; dTARGET;
+    dSP; dMARK; dORIGMARK; dTARGET;
     AV * const ary = DEREF_PLAIN_ARRAY(MUTABLE_AV(*++MARK));
     const MAGIC * const mg = SvTIED_mg((const SV *)ary, PERL_MAGIC_tied);
 
@@ -5305,7 +5289,6 @@ PP(pp_push)
 
 PP(pp_shift)
 {
-    dVAR;
     dSP;
     AV * const av = PL_op->op_flags & OPf_SPECIAL
        ? MUTABLE_AV(GvAV(PL_defgv)) : DEREF_PLAIN_ARRAY(MUTABLE_AV(POPs));
@@ -5320,7 +5303,7 @@ PP(pp_shift)
 
 PP(pp_unshift)
 {
-    dVAR; dSP; dMARK; dORIGMARK; dTARGET;
+    dSP; dMARK; dORIGMARK; dTARGET;
     AV *ary = DEREF_PLAIN_ARRAY(MUTABLE_AV(*++MARK));
     const MAGIC * const mg = SvTIED_mg((const SV *)ary, PERL_MAGIC_tied);
 
@@ -5350,7 +5333,7 @@ PP(pp_unshift)
 
 PP(pp_reverse)
 {
-    dVAR; dSP; dMARK;
+    dSP; dMARK;
 
     if (GIMME == G_ARRAY) {
        if (PL_op->op_private & OPpREVERSE_INPLACE) {
@@ -5481,7 +5464,7 @@ PP(pp_reverse)
 
 PP(pp_split)
 {
-    dVAR; dSP; dTARG;
+    dSP; dTARG;
     AV *ary;
     IV limit = POPi;                   /* note, negative is forever */
     SV * const sv = POPs;
@@ -5925,7 +5908,6 @@ PP(pp_once)
 
 PP(pp_lock)
 {
-    dVAR;
     dSP;
     dTOPss;
     SV *retsv = sv;
@@ -5941,7 +5923,6 @@ PP(pp_lock)
 
 PP(unimplemented_op)
 {
-    dVAR;
     const Optype op_type = PL_op->op_type;
     /* Using OP_NAME() isn't going to be helpful here. Firstly, it doesn't cope
        with out of range op numbers - it only "special" cases op_custom.