This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Revert 4 regex commits to ease rebasing
[perl5.git] / pp_ctl.c
index a9012ee..2cde665 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -205,7 +205,9 @@ PP(pp_regcomp)
            if (PL_op->op_flags & OPf_SPECIAL)
                PL_reginterp_cnt = I32_MAX; /* Mark as safe.  */
 
-           if (!DO_UTF8(tmpstr) && SvUTF8(tmpstr)) {
+           if (DO_UTF8(tmpstr)) {
+               assert (SvUTF8(tmpstr));
+           } else if (SvUTF8(tmpstr)) {
                /* Not doing UTF-8, despite what the SV says. Is this only if
                   we're trapped in use 'bytes'?  */
                /* Make a copy of the octet sequence, but without the flag on,
@@ -214,11 +216,19 @@ PP(pp_regcomp)
                const char *const p = SvPV(tmpstr, len);
                tmpstr = newSVpvn_flags(p, len, SVs_TEMP);
            }
-           else if (SvAMAGIC(tmpstr) || SvGMAGICAL(tmpstr)) {
+           else if (SvAMAGIC(tmpstr)) {
                /* make a copy to avoid extra stringifies */
                tmpstr = newSVpvn_flags(t, len, SVs_TEMP | SvUTF8(tmpstr));
            }
 
+           /* If it is gmagical, create a mortal copy, but without calling
+              get-magic, as we have already done that. */
+           if(SvGMAGICAL(tmpstr)) {
+               SV *mortalcopy = sv_newmortal();
+               sv_setsv_flags(mortalcopy, tmpstr, 0);
+               tmpstr = mortalcopy;
+           }
+
            if (eng)
                PM_SETRE(pm, CALLREGCOMP_ENG(eng, tmpstr, pm_flags));
            else
@@ -295,13 +305,6 @@ PP(pp_substcont)
        s -= RX_GOFS(rx);
 
        /* Are we done */
-       /* I believe that we can't set REXEC_SCREAM here if
-          SvSCREAM(cx->sb_targ) is true because SvPVX(cx->sb_targ) isn't always
-          equal to s.  [See the comment before Perl_re_intuit_start(), which is
-          called from Perl_regexec_flags(), which says that it should be when
-          SvSCREAM() is true.]  s, cx->sb_strend and orig will be consistent
-          with SvPVX(cx->sb_targ), as substconst doesn't modify cx->sb_targ
-          during the match.  */
        if (CxONCE(cx) || s < orig ||
                !CALLREGEXEC(rx, s, cx->sb_strend, orig,
                             (s == m) + RX_GOFS(rx), cx->sb_targ, NULL,
@@ -1379,7 +1382,7 @@ static const char * const context_name[] = {
 };
 
 STATIC I32
-S_dopoptolabel(pTHX_ const char *label)
+S_dopoptolabel(pTHX_ const char *label, STRLEN len, U32 flags)
 {
     dVAR;
     register I32 i;
@@ -1394,6 +1397,7 @@ S_dopoptolabel(pTHX_ const char *label)
        case CXt_FORMAT:
        case CXt_EVAL:
        case CXt_NULL:
+           /* diag_listed_as: Exiting subroutine via %s */
            Perl_ck_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s",
                           context_name[CxTYPE(cx)], OP_NAME(PL_op));
            if (CxTYPE(cx) == CXt_NULL)
@@ -1404,8 +1408,20 @@ S_dopoptolabel(pTHX_ const char *label)
        case CXt_LOOP_FOR:
        case CXt_LOOP_PLAIN:
          {
-           const char *cx_label = CxLABEL(cx);
-           if (!cx_label || strNE(label, cx_label) ) {
+            STRLEN cx_label_len = 0;
+            U32 cx_label_flags = 0;
+           const char *cx_label = CxLABEL_len_flags(cx, &cx_label_len, &cx_label_flags);
+           if (!cx_label || !(
+                    ( (cx_label_flags & SVf_UTF8) != (flags & SVf_UTF8) ) ?
+                        (flags & SVf_UTF8)
+                            ? (bytes_cmp_utf8(
+                                        (const U8*)cx_label, cx_label_len,
+                                        (const U8*)label, len) == 0)
+                            : (bytes_cmp_utf8(
+                                        (const U8*)label, len,
+                                        (const U8*)cx_label, cx_label_len) == 0)
+                    : (len == cx_label_len && ((cx_label == label)
+                                    || memEQ(cx_label, label, len))) )) {
                DEBUG_l(Perl_deb(aTHX_ "(poptolabel(): skipping label at cx=%ld %s)\n",
                        (long)i, cx_label));
                continue;
@@ -1531,6 +1547,7 @@ S_dopoptoloop(pTHX_ I32 startingblock)
        case CXt_FORMAT:
        case CXt_EVAL:
        case CXt_NULL:
+           /* diag_listed_as: Exiting subroutine via %s */
            Perl_ck_warner(aTHX_ packWARN(WARN_EXITING), "Exiting %s via %s",
                           context_name[CxTYPE(cx)], OP_NAME(PL_op));
            if ((CxTYPE(cx)) == CXt_NULL)
@@ -1876,7 +1893,11 @@ PP(pp_caller)
        RETURN;
     }
 
-    stash_hek = HvNAME_HEK((HV*)CopSTASH(cx->blk_oldcop));
+    DEBUG_CX("CALLER");
+    assert(CopSTASH(cx->blk_oldcop));
+    stash_hek = SvTYPE(CopSTASH(cx->blk_oldcop)) == SVt_PVHV
+      ? HvNAME_HEK((HV*)CopSTASH(cx->blk_oldcop))
+      : NULL;
     if (GIMME != G_ARRAY) {
         EXTEND(SP, 1);
        if (!stash_hek)
@@ -2349,13 +2370,24 @@ S_return_lvalues(pTHX_ SV **mark, SV **sp, SV **newsp, I32 gimme,
        if (MARK < SP) {
              copy_sv:
                if (cx->blk_sub.cv && CvDEPTH(cx->blk_sub.cv) > 1) {
+                   if (!SvPADTMP(*SP)) {
                        *++newsp = SvREFCNT_inc(*SP);
                        FREETMPS;
                        sv_2mortal(*newsp);
+                   }
+                   else {
+                       /* FREETMPS could clobber it */
+                       SV *sv = SvREFCNT_inc(*SP);
+                       FREETMPS;
+                       *++newsp = sv_mortalcopy(sv);
+                       SvREFCNT_dec(sv);
+                   }
                }
                else
                    *++newsp =
-                       !SvTEMP(*SP)
+                     SvPADTMP(*SP)
+                      ? sv_mortalcopy(*SP)
+                      : !SvTEMP(*SP)
                          ? sv_2mortal(SvREFCNT_inc_simple_NN(*SP))
                          : *SP;
        }
@@ -2375,10 +2407,10 @@ S_return_lvalues(pTHX_ SV **mark, SV **sp, SV **newsp, I32 gimme,
        if (ref || !CxLVAL(cx))
            while (++MARK <= SP)
                *++newsp =
-                    SvTEMP(*MARK)
-                      ? *MARK
-                      : ref && SvFLAGS(*MARK) & SVs_PADTMP
+                      SvFLAGS(*MARK) & SVs_PADTMP
                           ? sv_mortalcopy(*MARK)
+                    : SvTEMP(*MARK)
+                          ? *MARK
                           : sv_2mortal(SvREFCNT_inc_simple_NN(*MARK));
        else while (++MARK <= SP) {
            if (*MARK != &PL_sv_undef
@@ -2395,6 +2427,7 @@ S_return_lvalues(pTHX_ SV **mark, SV **sp, SV **newsp, I32 gimme,
                    POPSUB(cx,sv);
                    PL_curpm = newpm;
                    LEAVESUB(sv);
+              /* diag_listed_as: Can't return %s from lvalue subroutine */
                    Perl_croak(aTHX_
                        "Can't return a %s from lvalue subroutine",
                        SvREADONLY(TOPs) ? "readonly value" : "temporary");
@@ -2484,7 +2517,7 @@ PP(pp_return)
        retop = cx->blk_sub.retop;
        break;
     default:
-       DIE(aTHX_ "panic: return");
+       DIE(aTHX_ "panic: return, type=%u", (unsigned) CxTYPE(cx));
     }
 
     TAINT_NOT;
@@ -2494,7 +2527,8 @@ PP(pp_return)
        if (MARK < SP) {
            if (popsub2) {
                if (cx->blk_sub.cv && CvDEPTH(cx->blk_sub.cv) > 1) {
-                   if (SvTEMP(TOPs) && SvREFCNT(TOPs) == 1) {
+                   if (SvTEMP(TOPs) && SvREFCNT(TOPs) == 1
+                        && !SvMAGICAL(TOPs)) {
                        *++newsp = SvREFCNT_inc(*SP);
                        FREETMPS;
                        sv_2mortal(*newsp);
@@ -2506,7 +2540,8 @@ PP(pp_return)
                        SvREFCNT_dec(sv);
                    }
                }
-               else if (SvTEMP(*SP) && SvREFCNT(*SP) == 1) {
+               else if (SvTEMP(*SP) && SvREFCNT(*SP) == 1
+                         && !SvMAGICAL(*SP)) {
                    *++newsp = *SP;
                }
                else
@@ -2521,6 +2556,7 @@ PP(pp_return)
       else if (gimme == G_ARRAY) {
        while (++MARK <= SP) {
            *++newsp = popsub2 && SvTEMP(*MARK) && SvREFCNT(*MARK) == 1
+                              && !SvGMAGICAL(*MARK)
                        ? *MARK : sv_mortalcopy(*MARK);
            TAINT_NOT;          /* Each item is independent */
        }
@@ -2596,9 +2632,14 @@ PP(pp_last)
            DIE(aTHX_ "Can't \"last\" outside a loop block");
     }
     else {
-       cxix = dopoptolabel(cPVOP->op_pv);
+        cxix = dopoptolabel(cPVOP->op_pv, strlen(cPVOP->op_pv),
+                           (cPVOP->op_private & OPpPV_IS_UTF8) ? SVf_UTF8 : 0);
        if (cxix < 0)
-           DIE(aTHX_ "Label not found for \"last %s\"", cPVOP->op_pv);
+           DIE(aTHX_ "Label not found for \"last %"SVf"\"",
+                                        SVfARG(newSVpvn_flags(cPVOP->op_pv,
+                                                    strlen(cPVOP->op_pv),
+                                                    ((cPVOP->op_private & OPpPV_IS_UTF8)
+                                                    ? SVf_UTF8 : 0) | SVs_TEMP)));
     }
     if (cxix < cxstack_ix)
        dounwind(cxix);
@@ -2628,7 +2669,7 @@ PP(pp_last)
        nextop = cx->blk_sub.retop;
        break;
     default:
-       DIE(aTHX_ "panic: last");
+       DIE(aTHX_ "panic: last, type=%u", (unsigned) CxTYPE(cx));
     }
 
     TAINT_NOT;
@@ -2672,9 +2713,14 @@ PP(pp_next)
            DIE(aTHX_ "Can't \"next\" outside a loop block");
     }
     else {
-       cxix = dopoptolabel(cPVOP->op_pv);
-       if (cxix < 0)
-           DIE(aTHX_ "Label not found for \"next %s\"", cPVOP->op_pv);
+       cxix = dopoptolabel(cPVOP->op_pv, strlen(cPVOP->op_pv),
+                           (cPVOP->op_private & OPpPV_IS_UTF8) ? SVf_UTF8 : 0);
+       if (cxix < 0)
+           DIE(aTHX_ "Label not found for \"next %"SVf"\"",
+                                        SVfARG(newSVpvn_flags(cPVOP->op_pv, 
+                                                    strlen(cPVOP->op_pv),
+                                                    ((cPVOP->op_private & OPpPV_IS_UTF8)
+                                                    ? SVf_UTF8 : 0) | SVs_TEMP)));
     }
     if (cxix < cxstack_ix)
        dounwind(cxix);
@@ -2703,9 +2749,14 @@ PP(pp_redo)
            DIE(aTHX_ "Can't \"redo\" outside a loop block");
     }
     else {
-       cxix = dopoptolabel(cPVOP->op_pv);
-       if (cxix < 0)
-           DIE(aTHX_ "Label not found for \"redo %s\"", cPVOP->op_pv);
+       cxix = dopoptolabel(cPVOP->op_pv, strlen(cPVOP->op_pv),
+                           (cPVOP->op_private & OPpPV_IS_UTF8) ? SVf_UTF8 : 0);
+       if (cxix < 0)
+           DIE(aTHX_ "Label not found for \"redo %"SVf"\"",
+                                        SVfARG(newSVpvn_flags(cPVOP->op_pv,
+                                                    strlen(cPVOP->op_pv),
+                                                    ((cPVOP->op_private & OPpPV_IS_UTF8)
+                                                    ? SVf_UTF8 : 0) | SVs_TEMP)));
     }
     if (cxix < cxstack_ix)
        dounwind(cxix);
@@ -2727,7 +2778,7 @@ PP(pp_redo)
 }
 
 STATIC OP *
-S_dofindlabel(pTHX_ OP *o, const char *label, OP **opstack, OP **oplimit)
+S_dofindlabel(pTHX_ OP *o, const char *label, STRLEN len, U32 flags, OP **opstack, OP **oplimit)
 {
     dVAR;
     OP **ops = opstack;
@@ -2753,8 +2804,21 @@ S_dofindlabel(pTHX_ OP *o, const char *label, OP **opstack, OP **oplimit)
        /* First try all the kids at this level, since that's likeliest. */
        for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) {
            if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) {
-               const char *kid_label = CopLABEL(kCOP);
-               if (kid_label && strEQ(kid_label, label))
+                STRLEN kid_label_len;
+                U32 kid_label_flags;
+               const char *kid_label = CopLABEL_len_flags(kCOP,
+                                                    &kid_label_len, &kid_label_flags);
+               if (kid_label && (
+                    ( (kid_label_flags & SVf_UTF8) != (flags & SVf_UTF8) ) ?
+                        (flags & SVf_UTF8)
+                            ? (bytes_cmp_utf8(
+                                        (const U8*)kid_label, kid_label_len,
+                                        (const U8*)label, len) == 0)
+                            : (bytes_cmp_utf8(
+                                        (const U8*)label, len,
+                                        (const U8*)kid_label, kid_label_len) == 0)
+                    : ( len == kid_label_len && ((kid_label == label)
+                                    || memEQ(kid_label, label, len)))))
                    return kid;
            }
        }
@@ -2770,7 +2834,7 @@ S_dofindlabel(pTHX_ OP *o, const char *label, OP **opstack, OP **oplimit)
                else
                    *ops++ = kid;
            }
-           if ((o = dofindlabel(kid, label, ops, oplimit)))
+           if ((o = dofindlabel(kid, label, len, flags, ops, oplimit)))
                return o;
        }
     }
@@ -2787,6 +2851,8 @@ PP(pp_goto)
 #define GOTO_DEPTH 64
     OP *enterops[GOTO_DEPTH];
     const char *label = NULL;
+    STRLEN label_len = 0;
+    U32 label_flags = 0;
     const bool do_dump = (PL_op->op_type == OP_DUMP);
     static const char must_have_label[] = "goto must have label";
 
@@ -2837,8 +2903,10 @@ PP(pp_goto)
            /* ban goto in eval: see <20050521150056.GC20213@iabyn.com> */
            if (CxTYPE(cx) == CXt_EVAL) {
                if (CxREALEVAL(cx))
+               /* diag_listed_as: Can't goto subroutine from an eval-%s */
                    DIE(aTHX_ "Can't goto subroutine from an eval-string");
                else
+               /* diag_listed_as: Can't goto subroutine from an eval-%s */
                    DIE(aTHX_ "Can't goto subroutine from an eval-block");
            }
            else if (CxMULTICALL(cx))
@@ -2985,21 +3053,20 @@ PP(pp_goto)
            }
        }
        else {
-           label = SvPV_nolen_const(sv);
-           if (!(do_dump || *label))
-               DIE(aTHX_ must_have_label);
+           label       = SvPV_const(sv, label_len);
+            label_flags = SvUTF8(sv);
        }
     }
-    else if (PL_op->op_flags & OPf_SPECIAL) {
-       if (! do_dump)
-           DIE(aTHX_ must_have_label);
+    else if (!(PL_op->op_flags & OPf_SPECIAL)) {
+       label       = cPVOP->op_pv;
+        label_flags = (cPVOP->op_private & OPpPV_IS_UTF8) ? SVf_UTF8 : 0;
+        label_len   = strlen(label);
     }
-    else
-       label = cPVOP->op_pv;
+    if (!(do_dump || label_len)) DIE(aTHX_ must_have_label);
 
     PERL_ASYNC_CHECK();
 
-    if (label && *label) {
+    if (label_len) {
        OP *gotoprobe = NULL;
        bool leaving_eval = FALSE;
        bool in_block = FALSE;
@@ -3050,12 +3117,13 @@ PP(pp_goto)
                DIE(aTHX_ "Can't \"goto\" out of a pseudo block");
            default:
                if (ix)
-                   DIE(aTHX_ "panic: goto");
+                   DIE(aTHX_ "panic: goto, type=%u, ix=%ld",
+                       CxTYPE(cx), (long) ix);
                gotoprobe = PL_main_root;
                break;
            }
            if (gotoprobe) {
-               retop = dofindlabel(gotoprobe, label,
+               retop = dofindlabel(gotoprobe, label, label_len, label_flags,
                                    enterops, enterops + GOTO_DEPTH);
                if (retop)
                    break;
@@ -3063,7 +3131,8 @@ PP(pp_goto)
                        gotoprobe->op_sibling->op_type == OP_UNSTACK &&
                        gotoprobe->op_sibling->op_sibling) {
                    retop = dofindlabel(gotoprobe->op_sibling->op_sibling,
-                                       label, enterops, enterops + GOTO_DEPTH);
+                                       label, label_len, label_flags, enterops,
+                                       enterops + GOTO_DEPTH);
                    if (retop)
                        break;
                }
@@ -3071,7 +3140,9 @@ PP(pp_goto)
            PL_lastgotoprobe = gotoprobe;
        }
        if (!retop)
-           DIE(aTHX_ "Can't find label %s", label);
+           DIE(aTHX_ "Can't find label %"SVf,
+                            SVfARG(newSVpvn_flags(label, label_len,
+                                        SVs_TEMP | label_flags)));
 
        /* if we're leaving an eval, check before we pop any frames
            that we're not going to punt, otherwise the error
@@ -3466,11 +3537,11 @@ S_try_yyparse(pTHX_ int gramtype)
  * pushes undef (also croaks if startop != NULL).
  */
 
-/* This function is called from three places, sv_compile_2op, pp_return
+/* This function is called from three places, sv_compile_2op, pp_require
  * and pp_entereval.  These can be distinguished as follows:
  *    sv_compile_2op - startop is non-null
- *    pp_require     - startop is null; in_require is true
- *    pp_entereval   - stortop is null; in_require is false
+ *    pp_require     - startop is null; saveop is not entereval
+ *    pp_entereval   - startop is null; saveop is entereval
  */
 
 STATIC bool
@@ -3540,8 +3611,9 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq, HV *hh)
        CLEAR_ERRSV();
 
     if (!startop) {
+       bool clear_hints = saveop->op_type != OP_ENTEREVAL;
        SAVEHINTS();
-       if (in_require) {
+       if (clear_hints) {
            PL_hints = 0;
            hv_clear(GvHV(PL_hintgv));
        }
@@ -3555,7 +3627,7 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq, HV *hh)
            }
        }
        SAVECOMPILEWARNINGS();
-       if (in_require) {
+       if (clear_hints) {
            if (PL_dowarn & G_WARN_ALL_ON)
                PL_compiling.cop_warnings = pWARN_ALL ;
            else if (PL_dowarn & G_WARN_ALL_OFF)
@@ -4545,7 +4617,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other, const bool copied)
        DEBUG_M(Perl_deb(aTHX_ "    applying rule Any-Object\n"));
        DEBUG_M(Perl_deb(aTHX_ "        attempting overload\n"));
 
-       tmpsv = amagic_call(d, e, smart_amg, 0);
+       tmpsv = amagic_call(d, e, smart_amg, AMGf_noleft);
        if (tmpsv) {
            SPAGAIN;
            (void)POPs;
@@ -5469,14 +5541,11 @@ S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
        int count;
 
        ENTER_with_name("call_filter_sub");
-       save_gp(PL_defgv, 0);
-       GvINTRO_off(PL_defgv);
-       SAVEGENERICSV(GvSV(PL_defgv));
+       SAVE_DEFSV;
        SAVETMPS;
        EXTEND(SP, 2);
 
        DEFSV_set(upstream);
-       SvREFCNT_inc_simple_void_NN(upstream);
        PUSHMARK(SP);
        mPUSHi(0);
        if (filter_state) {
@@ -5596,8 +5665,8 @@ S_path_is_absolute(const char *name)
  * Local variables:
  * c-indentation-style: bsd
  * c-basic-offset: 4
- * indent-tabs-mode: t
+ * indent-tabs-mode: nil
  * End:
  *
- * ex: set ts=8 sts=4 sw=4 noet:
+ * ex: set ts=8 sts=4 sw=4 et:
  */