PP(pp_regcreset)
{
dVAR;
- /* XXXX Should store the old value to allow for tie/overload - and
- restore in regcomp, where marked with XXXX. */
- PL_reginterp_cnt = 0;
TAINT_NOT;
return NORMAL;
}
dVAR;
dSP;
register PMOP *pm = (PMOP*)cLOGOP->op_other;
- SV *tmpstr;
+ SV **args;
+ int nargs;
REGEXP *re = NULL;
+ REGEXP *new_re;
+ const regexp_engine *eng;
+ bool is_bare_re;
+
+ if (PL_op->op_flags & OPf_STACKED) {
+ dMARK;
+ nargs = SP - MARK;
+ args = ++MARK;
+ }
+ else {
+ nargs = 1;
+ args = SP;
+ }
/* prevent recompiling under /o and ithreads. */
#if defined(USE_ITHREADS)
if (pm->op_pmflags & PMf_KEEP && PM_GETRE(pm)) {
- if (PL_op->op_flags & OPf_STACKED) {
- dMARK;
- SP = MARK;
- }
- else
- (void)POPs;
+ SP = args-1;
RETURN;
}
#endif
-#define tryAMAGICregexp(rx) \
- STMT_START { \
- SvGETMAGIC(rx); \
- if (SvROK(rx) && SvAMAGIC(rx)) { \
- SV *sv = AMG_CALLunary(rx, regexp_amg); \
- if (sv) { \
- if (SvROK(sv)) \
- sv = SvRV(sv); \
- if (SvTYPE(sv) != SVt_REGEXP) \
- Perl_croak(aTHX_ "Overloaded qr did not return a REGEXP"); \
- rx = sv; \
- } \
- } \
- } STMT_END
-
-
- if (PL_op->op_flags & OPf_STACKED) {
- /* multiple args; concatenate them */
- dMARK; dORIGMARK;
- tmpstr = PAD_SV(ARGTARG);
- sv_setpvs(tmpstr, "");
- while (++MARK <= SP) {
- SV *msv = *MARK;
- SV *sv;
-
- tryAMAGICregexp(msv);
-
- if ((SvAMAGIC(tmpstr) || SvAMAGIC(msv)) &&
- (sv = amagic_call(tmpstr, msv, concat_amg, AMGf_assign)))
- {
- sv_setsv(tmpstr, sv);
- continue;
- }
- sv_catsv_nomg(tmpstr, msv);
+ re = PM_GETRE(pm);
+ assert (re != (REGEXP*) &PL_sv_undef);
+ eng = re ? RX_ENGINE(re) : current_re_engine();
+
+ new_re = (eng->op_comp
+ ? eng->op_comp
+ : &Perl_re_op_compile
+ )(aTHX_ args, nargs, pm->op_code_list, eng, re,
+ &is_bare_re,
+ (pm->op_pmflags & RXf_PMf_COMPILETIME),
+ pm->op_pmflags |
+ (PL_op->op_flags & OPf_SPECIAL ? PMf_USE_RE_EVAL : 0));
+ if (pm->op_pmflags & PMf_HAS_CV)
+ ((struct regexp *)SvANY(new_re))->qr_anoncv
+ = (CV*) SvREFCNT_inc(PAD_SV(PL_op->op_targ));
+
+ if (is_bare_re) {
+ REGEXP *tmp;
+ /* The match's LHS's get-magic might need to access this op's regexp
+ (e.g. $' =~ /$re/ while foo; see bug 70764). So we must call
+ get-magic now before we replace the regexp. Hopefully this hack can
+ be replaced with the approach described at
+ http://www.nntp.perl.org/group/perl.perl5.porters/2007/03/msg122415.html
+ some day. */
+ if (pm->op_type == OP_MATCH) {
+ SV *lhs;
+ const bool was_tainted = PL_tainted;
+ if (pm->op_flags & OPf_STACKED)
+ lhs = args[-1];
+ else if (pm->op_private & OPpTARGET_MY)
+ lhs = PAD_SV(pm->op_targ);
+ else lhs = DEFSV;
+ SvGETMAGIC(lhs);
+ /* Restore the previous value of PL_tainted (which may have been
+ modified by get-magic), to avoid incorrectly setting the
+ RXf_TAINTED flag further down. */
+ PL_tainted = was_tainted;
}
- SvSETMAGIC(tmpstr);
- SP = ORIGMARK;
+ tmp = reg_temp_copy(NULL, new_re);
+ ReREFCNT_dec(new_re);
+ new_re = tmp;
}
- else {
- tmpstr = POPs;
- tryAMAGICregexp(tmpstr);
- }
-
-#undef tryAMAGICregexp
-
- if (SvROK(tmpstr)) {
- SV * const sv = SvRV(tmpstr);
- if (SvTYPE(sv) == SVt_REGEXP)
- re = (REGEXP*) sv;
- }
- else if (SvTYPE(tmpstr) == SVt_REGEXP)
- re = (REGEXP*) tmpstr;
-
- if (re) {
- /* The match's LHS's get-magic might need to access this op's reg-
- exp (as is sometimes the case with $'; see bug 70764). So we
- must call get-magic now before we replace the regexp. Hopeful-
- ly this hack can be replaced with the approach described at
- http://www.nntp.perl.org/group/perl.perl5.porters/2007/03
- /msg122415.html some day. */
- if(pm->op_type == OP_MATCH) {
- SV *lhs;
- const bool was_tainted = PL_tainted;
- if (pm->op_flags & OPf_STACKED)
- lhs = TOPs;
- else if (pm->op_private & OPpTARGET_MY)
- lhs = PAD_SV(pm->op_targ);
- else lhs = DEFSV;
- SvGETMAGIC(lhs);
- /* Restore the previous value of PL_tainted (which may have been
- modified by get-magic), to avoid incorrectly setting the
- RXf_TAINTED flag further down. */
- PL_tainted = was_tainted;
- }
-
- re = reg_temp_copy(NULL, re);
- ReREFCNT_dec(PM_GETRE(pm));
- PM_SETRE(pm, re);
+ if (re != new_re) {
+ ReREFCNT_dec(re);
+ PM_SETRE(pm, new_re);
}
- else {
- STRLEN len = 0;
- const char *t = SvOK(tmpstr) ? SvPV_nomg_const(tmpstr, len) : "";
-
- re = PM_GETRE(pm);
- assert (re != (REGEXP*) &PL_sv_undef);
-
- /* Check against the last compiled regexp. */
- if (!re || !RX_PRECOMP(re) || RX_PRELEN(re) != len ||
- memNE(RX_PRECOMP(re), t, len))
- {
- const regexp_engine *eng = re ? RX_ENGINE(re) : NULL;
- U32 pm_flags = pm->op_pmflags & RXf_PMf_COMPILETIME;
- if (re) {
- ReREFCNT_dec(re);
-#ifdef USE_ITHREADS
- PM_SETRE(pm, (REGEXP*) &PL_sv_undef);
-#else
- PM_SETRE(pm, NULL); /* crucial if regcomp aborts */
-#endif
- } else if (PL_curcop->cop_hints_hash) {
- SV *ptr = cop_hints_fetch_pvs(PL_curcop, "regcomp", 0);
- if (ptr && SvIOK(ptr) && SvIV(ptr))
- eng = INT2PTR(regexp_engine*,SvIV(ptr));
- }
-
- if (PL_op->op_flags & OPf_SPECIAL)
- PL_reginterp_cnt = I32_MAX; /* Mark as safe. */
-
- 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,
- as the compiler now honours the SvUTF8 flag on tmpstr. */
- STRLEN len;
- const char *const p = SvPV(tmpstr, len);
- tmpstr = newSVpvn_flags(p, len, SVs_TEMP);
- }
- 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
- PM_SETRE(pm, CALLREGCOMP(tmpstr, pm_flags));
-
- PL_reginterp_cnt = 0; /* XXXX Be extra paranoid - needed
- inside tie/overload accessors. */
- }
- }
-
- re = PM_GETRE(pm);
#ifndef INCOMPLETE_TAINTS
- if (PL_tainting) {
- if (PL_tainted) {
- SvTAINTED_on((SV*)re);
- RX_EXTFLAGS(re) |= RXf_TAINTED;
- }
+ if (PL_tainting && PL_tainted) {
+ SvTAINTED_on((SV*)new_re);
+ RX_EXTFLAGS(new_re) |= RXf_TAINTED;
}
#endif
- if (!RX_PRELEN(PM_GETRE(pm)) && PL_curpm)
- pm = PL_curpm;
-
-
#if !defined(USE_ITHREADS)
/* can't change the optree at runtime either */
/* PMf_KEEP is handled differently under threads to avoid these problems */
+ if (!RX_PRELEN(PM_GETRE(pm)) && PL_curpm)
+ pm = PL_curpm;
if (pm->op_pmflags & PMf_KEEP) {
pm->op_private &= ~OPpRUNTIME; /* no point compiling again */
cLOGOP->op_first->op_next = PL_op->op_next;
}
#endif
+
+ SP = args-1;
RETURN;
}
+
PP(pp_substcont)
{
dVAR;
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,
targ = dstr;
}
else {
-#ifdef PERL_OLD_COPY_ON_WRITE
if (SvIsCOW(targ)) {
sv_force_normal_flags(targ, SV_COW_DROP_PV);
} else
-#endif
{
SvPV_free(targ);
}
LEAVE_SCOPE(cx->sb_oldsave);
POPSUBST(cx);
RETURNOP(pm->op_next);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
}
cx->sb_iters = saviters;
}
if (RANGE_IS_NUMERIC(left,right)) {
register IV i, j;
IV max;
- if ((SvOK(left) && SvNV(left) < IV_MIN) ||
- (SvOK(right) && SvNV(right) > IV_MAX))
+ if ((SvOK(left) && SvNV_nomg(left) < IV_MIN) ||
+ (SvOK(right) && SvNV_nomg(right) > IV_MAX))
DIE(aTHX_ "Range iterator outside integer range");
- i = SvIV(left);
- max = SvIV(right);
+ i = SvIV_nomg(left);
+ max = SvIV_nomg(right);
if (max >= i) {
j = max - i + 1;
EXTEND_MORTAL(j);
}
}
else {
- SV * const final = sv_mortalcopy(right);
- STRLEN len;
- const char * const tmps = SvPV_const(final, len);
+ STRLEN len, llen;
+ const char * const lpv = SvPV_nomg_const(left, llen);
+ const char * const tmps = SvPV_nomg_const(right, len);
- SV *sv = sv_mortalcopy(left);
- SvPV_force_nolen(sv);
+ SV *sv = newSVpvn_flags(lpv, llen, SvUTF8(left)|SVs_TEMP);
while (!SvNIOKp(sv) && SvCUR(sv) <= len) {
XPUSHs(sv);
if (strEQ(SvPVX_const(sv),tmps))
};
STATIC I32
-S_dopoptolabel(pTHX_ const char *label)
+S_dopoptolabel(pTHX_ const char *label, STRLEN len, U32 flags)
{
dVAR;
register I32 i;
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)
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 G_ARRAY;
default:
Perl_croak(aTHX_ "panic: bad gimme: %d\n", cxstack[cxix].blk_gimme);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
return 0;
}
}
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)
if (PL_in_eval) {
if (PL_in_eval & EVAL_KEEPERR) {
- Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "\t(in cleanup) %s",
- SvPV_nolen_const(err));
+ Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "\t(in cleanup) %"SVf,
+ SVfARG(err));
}
else
sv_catsv(ERRSV, err);
PL_curcop = oldcop;
if (optype == OP_REQUIRE) {
- const char* const msg = SvPVx_nolen_const(exceptsv);
(void)hv_store(GvHVn(PL_incgv),
- SvPVX_const(namesv), SvCUR(namesv),
+ SvPVX_const(namesv),
+ SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
&PL_sv_undef, 0);
/* note that unlike pp_entereval, pp_require isn't
* supposed to trap errors. So now that we've popped the
* EVAL that pp_require pushed, and processed the error
* message, rethrow the error */
- Perl_croak(aTHX_ "%sCompilation failed in require",
- *msg ? msg : "Unknown error\n");
+ Perl_croak(aTHX_ "%"SVf"Compilation failed in require",
+ SVfARG(exceptsv ? exceptsv : newSVpvs_flags("Unknown error\n",
+ SVs_TEMP)));
}
if (in_eval & EVAL_KEEPERR) {
- Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "\t(in cleanup) %s",
- SvPV_nolen_const(exceptsv));
+ Perl_ck_warner(aTHX_ packWARN(WARN_MISC), "\t(in cleanup) %"SVf,
+ SVfARG(exceptsv));
}
else {
sv_setsv(ERRSV, exceptsv);
PL_restartjmpenv = restartjmpenv;
PL_restartop = restartop;
JMPENV_JUMP(3);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
}
}
write_to_stderr(exceptsv);
my_failure_exit();
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
}
PP(pp_xor)
register const PERL_CONTEXT *cx;
const PERL_CONTEXT *dbcx;
I32 gimme;
- const char *stashname;
+ const HEK *stash_hek;
I32 count = 0;
bool has_arg = MAXARG && TOPs;
RETURN;
}
- stashname = CopSTASHPV(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 (!stashname)
+ if (!stash_hek)
PUSHs(&PL_sv_undef);
else {
dTARGET;
- sv_setpv(TARG, stashname);
+ sv_sethek(TARG, stash_hek);
PUSHs(TARG);
}
RETURN;
EXTEND(SP, 11);
- if (!stashname)
+ if (!stash_hek)
PUSHs(&PL_sv_undef);
- else
- mPUSHs(newSVpv(stashname, 0));
+ else {
+ dTARGET;
+ sv_sethek(TARG, stash_hek);
+ PUSHTARG;
+ }
mPUSHs(newSVpv(OutCopFILE(cx->blk_oldcop), 0));
mPUSHi((I32)CopLINE(cx->blk_oldcop));
if (!has_arg)
if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) {
GV * const cvgv = CvGV(dbcx->blk_sub.cv);
/* So is ccstack[dbcxix]. */
- if (isGV(cvgv)) {
+ if (cvgv && isGV(cvgv)) {
SV * const sv = newSV(0);
gv_efullname3(sv, cvgv, NULL);
mPUSHs(sv);
STATIC SV **
S_adjust_stack_on_leave(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme, U32 flags)
{
+ bool padtmp = 0;
PERL_ARGS_ASSERT_ADJUST_STACK_ON_LEAVE;
+ if (flags & SVs_PADTMP) {
+ flags &= ~SVs_PADTMP;
+ padtmp = 1;
+ }
if (gimme == G_SCALAR) {
if (MARK < SP)
- *++newsp = (SvFLAGS(*SP) & flags) ? *SP : sv_mortalcopy(*SP);
+ *++newsp = ((SvFLAGS(*SP) & flags) || (padtmp && SvPADTMP(*SP)))
+ ? *SP : sv_mortalcopy(*SP);
else {
/* MEXTEND() only updates MARK, so reuse it instead of newsp. */
MARK = newsp;
else if (gimme == G_ARRAY) {
/* in case LEAVE wipes old return values */
while (++MARK <= SP) {
- if (SvFLAGS(*MARK) & flags)
+ if ((SvFLAGS(*MARK) & flags) || (padtmp && SvPADTMP(*MARK)))
*++newsp = *MARK;
else {
*++newsp = sv_mortalcopy(*MARK);
assumptions */
assert(CxTYPE(cx) == CXt_LOOP_LAZYIV);
#ifdef NV_PRESERVES_UV
- if ((SvOK(sv) && ((SvNV(sv) < (NV)IV_MIN) ||
- (SvNV(sv) > (NV)IV_MAX)))
+ if ((SvOK(sv) && ((SvNV_nomg(sv) < (NV)IV_MIN) ||
+ (SvNV_nomg(sv) > (NV)IV_MAX)))
||
- (SvOK(right) && ((SvNV(right) > (NV)IV_MAX) ||
- (SvNV(right) < (NV)IV_MIN))))
+ (SvOK(right) && ((SvNV_nomg(right) > (NV)IV_MAX) ||
+ (SvNV_nomg(right) < (NV)IV_MIN))))
#else
- if ((SvOK(sv) && ((SvNV(sv) <= (NV)IV_MIN)
+ if ((SvOK(sv) && ((SvNV_nomg(sv) <= (NV)IV_MIN)
||
- ((SvNV(sv) > 0) &&
- ((SvUV(sv) > (UV)IV_MAX) ||
- (SvNV(sv) > (NV)UV_MAX)))))
+ ((SvNV_nomg(sv) > 0) &&
+ ((SvUV_nomg(sv) > (UV)IV_MAX) ||
+ (SvNV_nomg(sv) > (NV)UV_MAX)))))
||
- (SvOK(right) && ((SvNV(right) <= (NV)IV_MIN)
+ (SvOK(right) && ((SvNV_nomg(right) <= (NV)IV_MIN)
||
- ((SvNV(right) > 0) &&
- ((SvUV(right) > (UV)IV_MAX) ||
- (SvNV(right) > (NV)UV_MAX))))))
+ ((SvNV_nomg(right) > 0) &&
+ ((SvUV_nomg(right) > (UV)IV_MAX) ||
+ (SvNV_nomg(right) > (NV)UV_MAX))
+ ))))
#endif
DIE(aTHX_ "Range iterator outside integer range");
- cx->blk_loop.state_u.lazyiv.cur = SvIV(sv);
- cx->blk_loop.state_u.lazyiv.end = SvIV(right);
+ cx->blk_loop.state_u.lazyiv.cur = SvIV_nomg(sv);
+ cx->blk_loop.state_u.lazyiv.end = SvIV_nomg(right);
#ifdef DEBUGGING
/* for correct -Dstv display */
cx->blk_oldsp = sp - PL_stack_base;
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
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");
{
/* Unassume the success we assumed earlier. */
(void)hv_delete(GvHVn(PL_incgv),
- SvPVX_const(namesv), SvCUR(namesv),
+ SvPVX_const(namesv),
+ SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
G_DISCARD);
DIE(aTHX_ "%"SVf" did not return a true value", SVfARG(namesv));
}
retop = cx->blk_sub.retop;
break;
default:
- DIE(aTHX_ "panic: return");
+ DIE(aTHX_ "panic: return, type=%u", (unsigned) CxTYPE(cx));
}
TAINT_NOT;
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);
SvREFCNT_dec(sv);
}
}
- else if (SvTEMP(*SP) && SvREFCNT(*SP) == 1) {
+ else if (SvTEMP(*SP) && SvREFCNT(*SP) == 1
+ && !SvMAGICAL(*SP)) {
*++newsp = *SP;
}
else
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 */
}
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";
/* 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))
oldsave = PL_scopestack[PL_scopestack_ix - 1];
LEAVE_SCOPE(oldsave);
+ /* A destructor called during LEAVE_SCOPE could have undefined
+ * our precious cv. See bug #99850. */
+ if (!CvROOT(cv) && !CvXSUB(cv)) {
+ const GV * const gv = CvGV(cv);
+ if (gv) {
+ SV * const tmpstr = sv_newmortal();
+ gv_efullname3(tmpstr, gv, NULL);
+ DIE(aTHX_ "Goto undefined subroutine &%"SVf"",
+ SVfARG(tmpstr));
+ }
+ DIE(aTHX_ "Goto undefined subroutine");
+ }
+
/* Now do some callish stuff. */
SAVETMPS;
SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */
if (CvISXSUB(cv)) {
OP* const retop = cx->blk_sub.retop;
- SV **newsp __attribute__unused__;
- I32 gimme __attribute__unused__;
+ SV **newsp PERL_UNUSED_DECL;
+ I32 gimme PERL_UNUSED_DECL;
if (reified) {
I32 index;
for (index=0; index<items; index++)
}
}
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
JMPENV_POP;
PL_op = oldop;
JMPENV_JUMP(ret);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
}
JMPENV_POP;
PL_op = oldop;
return NULL;
}
-/* James Bond: Do you expect me to talk?
- Auric Goldfinger: No, Mr. Bond. I expect you to die.
-
- This code is an ugly hack, doesn't work with lexicals in subroutines that are
- called more than once, and is only used by regcomp.c, for (?{}) blocks.
-
- Currently it is not used outside the core code. Best if it stays that way.
-
- Hence it's now deprecated, and will be removed.
-*/
-OP *
-Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, const char *code, PAD** padp)
-/* sv Text to convert to OP tree. */
-/* startop op_free() this to undo. */
-/* code Short string id of the caller. */
-{
- PERL_ARGS_ASSERT_SV_COMPILE_2OP;
- return Perl_sv_compile_2op_is_broken(aTHX_ sv, startop, code, padp);
-}
-
-/* Don't use this. It will go away without warning once the regexp engine is
- refactored not to use it. */
-OP *
-Perl_sv_compile_2op_is_broken(pTHX_ SV *sv, OP **startop, const char *code,
- PAD **padp)
-{
- dVAR; dSP; /* Make POPBLOCK work. */
- PERL_CONTEXT *cx;
- SV **newsp;
- I32 gimme = G_VOID;
- I32 optype;
- OP dummy;
- char tbuf[TYPE_DIGITS(long) + 12 + 10];
- char *tmpbuf = tbuf;
- char *safestr;
- int runtime;
- CV* runcv = NULL; /* initialise to avoid compiler warnings */
- STRLEN len;
- bool need_catch;
-
- PERL_ARGS_ASSERT_SV_COMPILE_2OP_IS_BROKEN;
-
- ENTER_with_name("eval");
- lex_start(sv, NULL, LEX_START_SAME_FILTER);
- SAVETMPS;
- /* switch to eval mode */
-
- if (IN_PERL_COMPILETIME) {
- SAVECOPSTASH_FREE(&PL_compiling);
- CopSTASH_set(&PL_compiling, PL_curstash);
- }
- if (PERLDB_NAMEEVAL && CopLINE(PL_curcop)) {
- SV * const sv = sv_newmortal();
- Perl_sv_setpvf(aTHX_ sv, "_<(%.10seval %lu)[%s:%"IVdf"]",
- code, (unsigned long)++PL_evalseq,
- CopFILE(PL_curcop), (IV)CopLINE(PL_curcop));
- tmpbuf = SvPVX(sv);
- len = SvCUR(sv);
- }
- else
- len = my_snprintf(tmpbuf, sizeof(tbuf), "_<(%.10s_eval %lu)", code,
- (unsigned long)++PL_evalseq);
- SAVECOPFILE_FREE(&PL_compiling);
- CopFILE_set(&PL_compiling, tmpbuf+2);
- SAVECOPLINE(&PL_compiling);
- CopLINE_set(&PL_compiling, 1);
- /* XXX For C<eval "...">s within BEGIN {} blocks, this ends up
- deleting the eval's FILEGV from the stash before gv_check() runs
- (i.e. before run-time proper). To work around the coredump that
- ensues, we always turn GvMULTI_on for any globals that were
- introduced within evals. See force_ident(). GSAR 96-10-12 */
- safestr = savepvn(tmpbuf, len);
- SAVEDELETE(PL_defstash, safestr, len);
- SAVEHINTS();
-#ifdef OP_IN_REGISTER
- PL_opsave = op;
-#else
- SAVEVPTR(PL_op);
-#endif
-
- /* we get here either during compilation, or via pp_regcomp at runtime */
- runtime = IN_PERL_RUNTIME;
- if (runtime)
- {
- runcv = find_runcv(NULL);
-
- /* At run time, we have to fetch the hints from PL_curcop. */
- PL_hints = PL_curcop->cop_hints;
- if (PL_hints & HINT_LOCALIZE_HH) {
- /* SAVEHINTS created a new HV in PL_hintgv, which we
- need to GC */
- SvREFCNT_dec(GvHV(PL_hintgv));
- GvHV(PL_hintgv) =
- refcounted_he_chain_2hv(PL_curcop->cop_hints_hash, 0);
- hv_magic(GvHV(PL_hintgv), NULL, PERL_MAGIC_hints);
- }
- SAVECOMPILEWARNINGS();
- PL_compiling.cop_warnings = DUP_WARNINGS(PL_curcop->cop_warnings);
- cophh_free(CopHINTHASH_get(&PL_compiling));
- /* XXX Does this need to avoid copying a label? */
- PL_compiling.cop_hints_hash
- = cophh_copy(PL_curcop->cop_hints_hash);
- }
-
- PL_op = &dummy;
- PL_op->op_type = OP_ENTEREVAL;
- PL_op->op_flags = 0; /* Avoid uninit warning. */
- PUSHBLOCK(cx, CXt_EVAL|(IN_PERL_COMPILETIME ? 0 : CXp_REAL), SP);
- PUSHEVAL(cx, 0);
- need_catch = CATCH_GET;
- CATCH_SET(TRUE);
-
- if (runtime)
- (void) doeval(G_SCALAR, startop, runcv, PL_curcop->cop_seq);
- else
- (void) doeval(G_SCALAR, startop, PL_compcv, PL_cop_seqmax);
- CATCH_SET(need_catch);
- POPBLOCK(cx,PL_curpm);
- POPEVAL(cx);
-
- (*startop)->op_type = OP_NULL;
- (*startop)->op_ppaddr = PL_ppaddr[OP_NULL];
- /* XXX DAPM do this properly one year */
- *padp = MUTABLE_AV(SvREFCNT_inc_simple(PL_comppad));
- LEAVE_with_name("eval");
- if (IN_PERL_COMPILETIME)
- CopHINTS_set(&PL_compiling, PL_hints);
-#ifdef OP_IN_REGISTER
- op = PL_opsave;
-#endif
- PERL_UNUSED_VAR(newsp);
- PERL_UNUSED_VAR(optype);
-
- return PL_eval_start;
-}
-
/*
=for apidoc find_runcv
CV*
Perl_find_runcv(pTHX_ U32 *db_seqp)
{
+ return Perl_find_runcv_where(aTHX_ 0, NULL, db_seqp);
+}
+
+/* If this becomes part of the API, it might need a better name. */
+CV *
+Perl_find_runcv_where(pTHX_ U8 cond, void *arg, U32 *db_seqp)
+{
dVAR;
PERL_SI *si;
+ int level = 0;
if (db_seqp)
*db_seqp = PL_curcop->cop_seq;
I32 ix;
for (ix = si->si_cxix; ix >= 0; ix--) {
const PERL_CONTEXT *cx = &(si->si_cxstack[ix]);
+ CV *cv = NULL;
if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) {
- CV * const cv = cx->blk_sub.cv;
+ cv = cx->blk_sub.cv;
/* skip DB:: code */
if (db_seqp && PL_debstash && CvSTASH(cv) == PL_debstash) {
*db_seqp = cx->blk_oldcop->cop_seq;
continue;
}
- return cv;
}
else if (CxTYPE(cx) == CXt_EVAL && !CxTRYBLOCK(cx))
- return PL_compcv;
+ cv = cx->blk_eval.cv;
+ if (cv) {
+ switch (cond) {
+ case FIND_RUNCV_root_eq:
+ if (CvROOT(cv) != (OP *)arg) continue;
+ return cv;
+ case FIND_RUNCV_level_eq:
+ if (level++ != (IV)arg) continue;
+ /* GERONIMO! */
+ default:
+ return cv;
+ }
+ }
}
}
- return PL_main_cv;
+ return cond == FIND_RUNCV_root_eq ? NULL : PL_main_cv;
}
default:
JMPENV_POP;
JMPENV_JUMP(ret);
- /* NOTREACHED */
+ assert(0); /* NOTREACHED */
}
JMPENV_POP;
return ret;
}
-/* Compile a require/do, an eval '', or a /(?{...})/.
- * In the last case, startop is non-null, and contains the address of
- * a pointer that should be set to the just-compiled code.
+/* Compile a require/do or an eval ''.
+ *
* outside is the lexically enclosing CV (if any) that invoked us.
+ * seq is the current COP scope value.
+ * hh is the saved hints hash, if any.
+ *
* Returns a bool indicating whether the compile was successful; if so,
- * PL_eval_start contains the first op of the compiled ocde; otherwise,
- * pushes undef (also croaks if startop != NULL).
+ * PL_eval_start contains the first op of the compiled code; otherwise,
+ * pushes undef.
+ *
+ * This function is called from two places: pp_require and pp_entereval.
+ * These can be distinguished by whether PL_op is entereval.
*/
STATIC bool
-S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
+S_doeval(pTHX_ int gimme, CV* outside, U32 seq, HV *hh)
{
dVAR; dSP;
OP * const saveop = PL_op;
- bool in_require = (saveop && saveop->op_type == OP_REQUIRE);
+ bool clear_hints = saveop->op_type != OP_ENTEREVAL;
+ COP * const oldcurcop = PL_curcop;
+ bool in_require = (saveop->op_type == OP_REQUIRE);
int yystatus;
+ CV *evalcv;
PL_in_eval = (in_require
? (EVAL_INREQUIRE | (PL_in_eval & EVAL_INEVAL))
PUSHMARK(SP);
- SAVESPTR(PL_compcv);
- PL_compcv = MUTABLE_CV(newSV_type(SVt_PVCV));
- CvEVAL_on(PL_compcv);
+ evalcv = MUTABLE_CV(newSV_type(SVt_PVCV));
+ CvEVAL_on(evalcv);
assert(CxTYPE(&cxstack[cxstack_ix]) == CXt_EVAL);
- cxstack[cxstack_ix].blk_eval.cv = PL_compcv;
+ cxstack[cxstack_ix].blk_eval.cv = evalcv;
cxstack[cxstack_ix].blk_gimme = gimme;
- CvOUTSIDE_SEQ(PL_compcv) = seq;
- CvOUTSIDE(PL_compcv) = MUTABLE_CV(SvREFCNT_inc_simple(outside));
+ CvOUTSIDE_SEQ(evalcv) = seq;
+ CvOUTSIDE(evalcv) = MUTABLE_CV(SvREFCNT_inc_simple(outside));
/* set up a scratch pad */
- CvPADLIST(PL_compcv) = pad_new(padnew_SAVE);
+ CvPADLIST(evalcv) = pad_new(padnew_SAVE);
PL_op = NULL; /* avoid PL_op and PL_curpad referring to different CVs */
if (!PL_madskills)
- SAVEMORTALIZESV(PL_compcv); /* must remain until end of current statement */
+ SAVEMORTALIZESV(evalcv); /* must remain until end of current statement */
/* make sure we compile in the right package */
if (CopSTASH_ne(PL_curcop, PL_curstash)) {
- SAVESPTR(PL_curstash);
- PL_curstash = CopSTASH(PL_curcop);
+ SAVEGENERICSV(PL_curstash);
+ PL_curstash = (HV *)SvREFCNT_inc_simple(CopSTASH(PL_curcop));
}
/* XXX:ajgo do we really need to alloc an AV for begin/checkunit */
SAVESPTR(PL_beginav);
PL_madskills = 0;
#endif
+ ENTER_with_name("evalcomp");
+ SAVESPTR(PL_compcv);
+ PL_compcv = evalcv;
+
/* try to compile it */
PL_eval_root = NULL;
PL_curcop = &PL_compiling;
- if (saveop && (saveop->op_type != OP_REQUIRE) && (saveop->op_flags & OPf_SPECIAL))
+ if ((saveop->op_type != OP_REQUIRE) && (saveop->op_flags & OPf_SPECIAL))
PL_in_eval |= EVAL_KEEPERR;
else
CLEAR_ERRSV();
+ SAVEHINTS();
+ if (clear_hints) {
+ PL_hints = 0;
+ hv_clear(GvHV(PL_hintgv));
+ }
+ else {
+ PL_hints = saveop->op_private & OPpEVAL_COPHH
+ ? oldcurcop->cop_hints : saveop->op_targ;
+ if (hh) {
+ /* SAVEHINTS created a new HV in PL_hintgv, which we need to GC */
+ SvREFCNT_dec(GvHV(PL_hintgv));
+ GvHV(PL_hintgv) = hh;
+ }
+ }
+ SAVECOMPILEWARNINGS();
+ if (clear_hints) {
+ if (PL_dowarn & G_WARN_ALL_ON)
+ PL_compiling.cop_warnings = pWARN_ALL ;
+ else if (PL_dowarn & G_WARN_ALL_OFF)
+ PL_compiling.cop_warnings = pWARN_NONE ;
+ else
+ PL_compiling.cop_warnings = pWARN_STD ;
+ }
+ else {
+ PL_compiling.cop_warnings =
+ DUP_WARNINGS(oldcurcop->cop_warnings);
+ cophh_free(CopHINTHASH_get(&PL_compiling));
+ if (Perl_cop_fetch_label(aTHX_ oldcurcop, NULL, NULL)) {
+ /* The label, if present, is the first entry on the chain. So rather
+ than writing a blank label in front of it (which involves an
+ allocation), just use the next entry in the chain. */
+ PL_compiling.cop_hints_hash
+ = cophh_copy(oldcurcop->cop_hints_hash->refcounted_he_next);
+ /* Check the assumption that this removed the label. */
+ assert(Perl_cop_fetch_label(aTHX_ &PL_compiling, NULL, NULL) == NULL);
+ }
+ else
+ PL_compiling.cop_hints_hash = cophh_copy(oldcurcop->cop_hints_hash);
+ }
+
CALL_BLOCK_HOOKS(bhk_eval, saveop);
/* note that yyparse() may raise an exception, e.g. C<BEGIN{die}>,
PERL_CONTEXT *cx;
I32 optype; /* Used by POPEVAL. */
SV *namesv;
- const char *msg;
cx = NULL;
namesv = NULL;
PL_op = saveop;
if (yystatus != 3) {
if (PL_eval_root) {
+ cv_forget_slab(evalcv);
op_free(PL_eval_root);
PL_eval_root = NULL;
}
SP = PL_stack_base + POPMARK; /* pop original mark */
- if (!startop) {
- POPBLOCK(cx,PL_curpm);
- POPEVAL(cx);
- namesv = cx->blk_eval.old_namesv;
- }
- }
- if (yystatus != 3)
+ POPBLOCK(cx,PL_curpm);
+ POPEVAL(cx);
+ namesv = cx->blk_eval.old_namesv;
+ /* POPBLOCK renders LEAVE_with_name("evalcomp") unnecessary. */
LEAVE_with_name("eval"); /* pp_entereval knows about this LEAVE. */
+ }
- msg = SvPVx_nolen_const(ERRSV);
if (in_require) {
if (!cx) {
/* If cx is still NULL, it means that we didn't go in the
namesv = cx->blk_eval.old_namesv;
}
(void)hv_store(GvHVn(PL_incgv),
- SvPVX_const(namesv), SvCUR(namesv),
+ SvPVX_const(namesv),
+ SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
&PL_sv_undef, 0);
- Perl_croak(aTHX_ "%sCompilation failed in require",
- *msg ? msg : "Unknown error\n");
- }
- else if (startop) {
- if (yystatus != 3) {
- POPBLOCK(cx,PL_curpm);
- POPEVAL(cx);
- }
- Perl_croak(aTHX_ "%sCompilation failed in regexp",
- (*msg ? msg : "Unknown error\n"));
+ Perl_croak(aTHX_ "%"SVf"Compilation failed in require",
+ SVfARG(ERRSV
+ ? ERRSV
+ : newSVpvs_flags("Unknown error\n", SVs_TEMP)));
}
else {
- if (!*msg) {
+ if (!*(SvPVx_nolen_const(ERRSV))) {
sv_setpvs(ERRSV, "Compilation error");
}
}
- PUSHs(&PL_sv_undef);
+ if (gimme != G_ARRAY) PUSHs(&PL_sv_undef);
PUTBACK;
return FALSE;
}
+ else
+ LEAVE_with_name("evalcomp");
+
CopLINE_set(&PL_compiling, 0);
- if (startop) {
- *startop = PL_eval_root;
- } else
- SAVEFREEOP(PL_eval_root);
+ SAVEFREEOP(PL_eval_root);
+ cv_forget_slab(evalcv);
DEBUG_x(dump_eval());
/* Register with debugger: */
- if (PERLDB_INTER && saveop && saveop->op_type == OP_REQUIRE) {
+ if (PERLDB_INTER && saveop->op_type == OP_REQUIRE) {
CV * const cv = get_cvs("DB::postponed", 0);
if (cv) {
dSP;
/* compiled okay, so do it */
- CvDEPTH(PL_compcv) = 1;
+ CvDEPTH(evalcv) = 1;
SP = PL_stack_base + POPMARK; /* pop original mark */
PL_op = saveop; /* The caller may need it. */
PL_parser->lex_state = LEX_NOTPARSING; /* $^S needs this. */
SV *hook_sv = NULL;
SV *encoding;
OP *op;
+ int saved_errno;
sv = POPs;
if ( (SvNIOKp(sv) || SvVOK(sv)) && PL_op->op_type != OP_DOFILE) {
tryname = name;
tryrsfp = doopen_pm(sv);
}
- if (!tryrsfp) {
+ if (!tryrsfp && !(errno == EACCES && path_is_absolute(name))) {
AV * const ar = GvAVn(PL_incgv);
I32 i;
#ifdef VMS
}
break;
}
- else if (errno == EMFILE)
- /* no point in trying other paths if out of handles */
- break;
+ else if (errno == EMFILE || errno == EACCES) {
+ /* no point in trying other paths if out of handles;
+ * on the other hand, if we couldn't open one of the
+ * files, then going on with the search could lead to
+ * unexpected results; see perl #113422
+ */
+ break;
+ }
}
}
}
}
}
+ saved_errno = errno; /* sv_2mortal can realloc things */
sv_2mortal(namesv);
if (!tryrsfp) {
if (PL_op->op_type == OP_REQUIRE) {
- if(errno == EMFILE) {
+ if(saved_errno == EMFILE || saved_errno == EACCES) {
/* diag_listed_as: Can't locate %s */
- DIE(aTHX_ "Can't locate %s: %s", name, Strerror(errno));
+ DIE(aTHX_ "Can't locate %s: %s", name, Strerror(saved_errno));
} else {
if (namesv) { /* did we lookup @INC? */
AV * const ar = GvAVn(PL_incgv);
DIE(aTHX_ "Can't locate %s", name);
}
+ CLEAR_ERRSV();
RETPUSHUNDEF;
}
else
CopFILE_set(&PL_compiling, tryname);
lex_start(NULL, tryrsfp, 0);
- SAVEHINTS();
- PL_hints = 0;
- hv_clear(GvHV(PL_hintgv));
-
- SAVECOMPILEWARNINGS();
- if (PL_dowarn & G_WARN_ALL_ON)
- PL_compiling.cop_warnings = pWARN_ALL ;
- else if (PL_dowarn & G_WARN_ALL_OFF)
- PL_compiling.cop_warnings = pWARN_NONE ;
- else
- PL_compiling.cop_warnings = pWARN_STD ;
-
if (filter_sub || filter_cache) {
/* We can use the SvPV of the filter PVIO itself as our cache, rather
than hanging another SV from it. In turn, filter_add() optionally
encoding = PL_encoding;
PL_encoding = NULL;
- if (doeval(gimme, NULL, NULL, PL_curcop->cop_seq))
+ if (doeval(gimme, NULL, PL_curcop->cop_seq, NULL))
op = DOCATCH(PL_eval_start);
else
op = PL_op->op_next;
char *tmpbuf = tbuf;
STRLEN len;
CV* runcv;
- U32 seq;
+ U32 seq, lex_flags = 0;
HV *saved_hh = NULL;
+ const bool bytes = PL_op->op_private & OPpEVAL_BYTES;
if (PL_op->op_private & OPpEVAL_HAS_HH) {
saved_hh = MUTABLE_HV(SvREFCNT_inc(POPs));
}
+ else if (PL_hints & HINT_LOCALIZE_HH || (
+ PL_op->op_private & OPpEVAL_COPHH
+ && PL_curcop->cop_hints & HINT_LOCALIZE_HH
+ )) {
+ saved_hh = cop_hints_2hv(PL_curcop, 0);
+ hv_magic(saved_hh, NULL, PERL_MAGIC_hints);
+ }
sv = POPs;
if (!SvPOK(sv)) {
/* make sure we've got a plain PV (no overload etc) before testing
const char * const p = SvPV_const(sv, len);
sv = newSVpvn_flags(p, len, SVs_TEMP | SvUTF8(sv));
+ lex_flags |= LEX_START_COPIED;
+
+ if (bytes && SvUTF8(sv))
+ SvPVbyte_force(sv, len);
+ }
+ else if (bytes && SvUTF8(sv)) {
+ /* Don't modify someone else's scalar */
+ STRLEN len;
+ sv = newSVsv(sv);
+ (void)sv_2mortal(sv);
+ SvPVbyte_force(sv,len);
+ lex_flags |= LEX_START_COPIED;
}
TAINT_IF(SvTAINTED(sv));
TAINT_PROPER("eval");
ENTER_with_name("eval");
- lex_start(sv, NULL, LEX_START_SAME_FILTER);
+ lex_start(sv, NULL, lex_flags | (PL_op->op_private & OPpEVAL_UNICODE
+ ? LEX_IGNORE_UTF8_HINTS
+ : bytes ? LEX_EVALBYTES : LEX_START_SAME_FILTER
+ )
+ );
SAVETMPS;
/* switch to eval mode */
CopFILE_set(&PL_compiling, tmpbuf+2);
SAVECOPLINE(&PL_compiling);
CopLINE_set(&PL_compiling, 1);
- /* XXX For C<eval "...">s within BEGIN {} blocks, this ends up
- deleting the eval's FILEGV from the stash before gv_check() runs
- (i.e. before run-time proper). To work around the coredump that
- ensues, we always turn GvMULTI_on for any globals that were
- introduced within evals. See force_ident(). GSAR 96-10-12 */
- SAVEHINTS();
- PL_hints = PL_op->op_targ;
- if (saved_hh) {
- /* SAVEHINTS created a new HV in PL_hintgv, which we need to GC */
- SvREFCNT_dec(GvHV(PL_hintgv));
- GvHV(PL_hintgv) = saved_hh;
- }
- SAVECOMPILEWARNINGS();
- PL_compiling.cop_warnings = DUP_WARNINGS(PL_curcop->cop_warnings);
- cophh_free(CopHINTHASH_get(&PL_compiling));
- if (Perl_cop_fetch_label(aTHX_ PL_curcop, NULL, NULL)) {
- /* The label, if present, is the first entry on the chain. So rather
- than writing a blank label in front of it (which involves an
- allocation), just use the next entry in the chain. */
- PL_compiling.cop_hints_hash
- = cophh_copy(PL_curcop->cop_hints_hash->refcounted_he_next);
- /* Check the assumption that this removed the label. */
- assert(Perl_cop_fetch_label(aTHX_ &PL_compiling, NULL, NULL) == NULL);
- }
- else
- PL_compiling.cop_hints_hash = cophh_copy(PL_curcop->cop_hints_hash);
/* special case: an eval '' executed within the DB package gets lexically
* placed in the first non-DB CV rather than the current CV - this
* allows the debugger to execute code, find lexicals etc, in the
if ((PERLDB_LINE || PERLDB_SAVESRC) && PL_curstash != PL_debstash)
save_lines(CopFILEAV(&PL_compiling), PL_parser->linestr);
else {
+ /* XXX For C<eval "...">s within BEGIN {} blocks, this ends up
+ deleting the eval's FILEGV from the stash before gv_check() runs
+ (i.e. before run-time proper). To work around the coredump that
+ ensues, we always turn GvMULTI_on for any globals that were
+ introduced within evals. See force_ident(). GSAR 96-10-12 */
char *const safestr = savepvn(tmpbuf, len);
SAVEDELETE(PL_defstash, safestr, len);
saved_delete = TRUE;
PUTBACK;
- if (doeval(gimme, NULL, runcv, seq)) {
+ if (doeval(gimme, runcv, seq, saved_hh)) {
if (was != PL_breakable_sub_gen /* Some subs defined here. */
? (PERLDB_LINE || PERLDB_SAVESRC)
: PERLDB_SAVESRC_NOSUBS) {
const U8 save_flags = PL_op -> op_flags;
I32 optype;
SV *namesv;
+ CV *evalcv;
PERL_ASYNC_CHECK();
POPBLOCK(cx,newpm);
POPEVAL(cx);
namesv = cx->blk_eval.old_namesv;
retop = cx->blk_eval.retop;
+ evalcv = cx->blk_eval.cv;
TAINT_NOT;
SP = adjust_stack_on_leave((gimme == G_VOID) ? SP : newsp, SP, newsp,
PL_curpm = newpm; /* Don't pop $1 et al till now */
#ifdef DEBUGGING
- assert(CvDEPTH(PL_compcv) == 1);
+ assert(CvDEPTH(evalcv) == 1);
#endif
- CvDEPTH(PL_compcv) = 0;
+ CvDEPTH(evalcv) = 0;
if (optype == OP_REQUIRE &&
!(gimme == G_SCALAR ? SvTRUE(*SP) : SP > newsp))
{
/* Unassume the success we assumed earlier. */
(void)hv_delete(GvHVn(PL_incgv),
- SvPVX_const(namesv), SvCUR(namesv),
+ SvPVX_const(namesv),
+ SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
G_DISCARD);
retop = Perl_die(aTHX_ "%"SVf" did not return a true value",
SVfARG(namesv));
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;
cxix = dopoptogiven(cxstack_ix);
if (cxix < 0)
- DIE(aTHX_ "Can't use when() outside a topicalizer");
+ /* diag_listed_as: Can't "when" outside a topicalizer */
+ DIE(aTHX_ "Can't \"%s\" outside a topicalizer",
+ PL_op->op_flags & OPf_SPECIAL ? "default" : "when");
POPBLOCK(cx,newpm);
assert(CxTYPE(cx) == CXt_WHEN);
char *prune_from = NULL;
bool read_from_cache = FALSE;
STRLEN umaxlen;
+ SV *err = NULL;
PERL_ARGS_ASSERT_RUN_USER_FILTER;
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) {
PUSHs(filter_state);
}
PUTBACK;
- count = call_sv(filter_sub, G_SCALAR);
+ count = call_sv(filter_sub, G_SCALAR|G_EVAL);
SPAGAIN;
if (count > 0) {
if (SvOK(out)) {
status = SvIV(out);
}
+ else if (SvTRUE(ERRSV)) {
+ err = newSVsv(ERRSV);
+ }
}
PUTBACK;
LEAVE_with_name("call_filter_sub");
}
- if(SvOK(upstream)) {
+ if(!err && SvOK(upstream)) {
got_p = SvPV(upstream, got_len);
if (umaxlen) {
if (got_len > umaxlen) {
}
}
}
- if (prune_from) {
+ if (!err && prune_from) {
/* Oh. Too long. Stuff some in our cache. */
STRLEN cached_len = got_p + got_len - prune_from;
SV *const cache = datasv;
have touched the SV upstream, so it may be undefined. If we naively
concatenate it then we get a warning about use of uninitialised value.
*/
- if (upstream != buf_sv && (SvOK(upstream) || SvGMAGICAL(upstream))) {
+ if (!err && upstream != buf_sv &&
+ (SvOK(upstream) || SvGMAGICAL(upstream))) {
sv_catsv(buf_sv, upstream);
}
}
filter_del(S_run_user_filter);
}
+
+ if (err)
+ croak_sv(err);
+
if (status == 0 && read_from_cache) {
/* If we read some data from the cache (and by getting here it implies
that we emptied the cache) then we aren't yet at EOF, and mustn't
* 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:
*/