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,
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
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,
};
STATIC I32
-S_dopoptolabel(pTHX_ const char *label)
+S_dopoptolabel(pTHX_ const char *label, STRLEN len, U32 flags)
{
dVAR;
register I32 i;
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;
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)
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;
}
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
retop = cx->blk_sub.retop;
break;
default:
- DIE(aTHX_ "panic: return");
+ DIE(aTHX_ "panic: return, type=%u", (unsigned) CxTYPE(cx));
}
TAINT_NOT;
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);
nextop = cx->blk_sub.retop;
break;
default:
- DIE(aTHX_ "panic: last");
+ DIE(aTHX_ "panic: last, type=%u", (unsigned) CxTYPE(cx));
}
TAINT_NOT;
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);
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);
}
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;
/* 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;
}
}
else
*ops++ = kid;
}
- if ((o = dofindlabel(kid, label, ops, oplimit)))
+ if ((o = dofindlabel(kid, label, len, flags, ops, oplimit)))
return o;
}
}
#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";
}
}
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;
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;
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;
}
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
* 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
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));
}
}
}
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)
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;
* 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:
*/