#define PERL_IN_PP_CTL_C
#include "perl.h"
-#define DOCATCH(o) ((CATCH_GET == TRUE) ? docatch(o) : (o))
+#define RUN_PP_CATCHABLY(thispp) \
+ STMT_START { if (CATCH_GET) return docatch(thispp); } STMT_END
#define dopoptosub(plop) dopoptosub_at(cxstack, (plop))
/* handle the empty pattern */
if (!RX_PRELEN(PM_GETRE(pm)) && PL_curpm) {
if (PL_curpm == PL_reg_curpm) {
- if (PL_curpm_under) {
- if (PL_curpm_under == PL_reg_curpm) {
- Perl_croak(aTHX_ "Infinite recursion via empty pattern");
- } else {
- pm = PL_curpm_under;
- }
+ if (PL_curpm_under && PL_curpm_under == PL_reg_curpm) {
+ Perl_croak(aTHX_ "Infinite recursion via empty pattern");
}
- } else {
- pm = PL_curpm;
}
}
if (PL_stack_base + TOPMARK == SP) {
(void)POPMARK;
if (GIMME_V == G_SCALAR)
- mXPUSHi(0);
+ XPUSHs(&PL_sv_zero);
RETURNOP(PL_op->op_next->op_next);
}
PL_stack_sp = PL_stack_base + TOPMARK + 1;
PP(pp_range)
{
+ dTARG;
if (GIMME_V == G_ARRAY)
return NORMAL;
- if (SvTRUEx(PAD_SV(PL_op->op_targ)))
+ GETTARGET;
+ if (SvTRUE_NN(targ))
return cLOGOP->op_other;
else
return NORMAL;
flip = SvIV(sv) == SvIV(GvSV(gv));
}
} else {
- flip = SvTRUE(sv);
+ flip = SvTRUE_NN(sv);
}
if (flip) {
sv_setiv(PAD_SV(cUNOP->op_first->op_targ), 1);
}
}
else {
- flop = SvTRUE(sv);
+ flop = SvTRUE_NN(sv);
}
if (flop) {
if (in_eval) {
I32 cxix;
- exceptsv = sv_2mortal(SvREFCNT_inc_simple_NN(exceptsv));
+ /* We need to keep this SV alive through all the stack unwinding
+ * and FREETMPSing below, while ensuing that it doesn't leak
+ * if we call out to something which then dies (e.g. sub STORE{die}
+ * when unlocalising a tied var). So we do a dance with
+ * mortalising and SAVEFREEing.
+ */
+ sv_2mortal(SvREFCNT_inc_simple_NN(exceptsv));
/*
* Historically, perl used to set ERRSV ($@) early in the die
restartjmpenv = cx->blk_eval.cur_top_env;
restartop = cx->blk_eval.retop;
+
+ /* We need a FREETMPS here to avoid late-called destructors
+ * clobbering $@ *after* we set it below, e.g.
+ * sub DESTROY { eval { die "X" } }
+ * eval { my $x = bless []; die $x = 0, "Y" };
+ * is($@, "Y")
+ * Here the clearing of the $x ref mortalises the anon array,
+ * which needs to be freed *before* $& is set to "Y",
+ * otherwise it gets overwritten with "X".
+ *
+ * However, the FREETMPS will clobber exceptsv, so preserve it
+ * on the savestack for now.
+ */
+ SAVEFREESV(SvREFCNT_inc_simple_NN(exceptsv));
+ FREETMPS;
+ /* now we're about to pop the savestack, so re-mortalise it */
+ sv_2mortal(SvREFCNT_inc_simple_NN(exceptsv));
+
/* Note that unlike pp_entereval, pp_require isn't supposed to
* trap errors. So if we're a require, after we pop the
* CXt_EVAL that pp_require pushed, rethrow the error with
PP(pp_xor)
{
dSP; dPOPTOPssrl;
- if (SvTRUE(left) != SvTRUE(right))
+ if (SvTRUE_NN(left) != SvTRUE_NN(right))
RETSETYES;
else
RETSETNO;
}
else {
PUSHs(newSVpvs_flags("(eval)", SVs_TEMP));
- mPUSHi(0);
+ PUSHs(&PL_sv_zero);
}
gimme = cx->blk_gimme;
if (gimme == G_VOID)
if (AvMAX(PL_dbargs) < AvFILLp(ary) + off)
av_extend(PL_dbargs, AvFILLp(ary) + off);
- Copy(AvALLOC(ary), AvARRAY(PL_dbargs), AvFILLp(ary) + 1 + off, SV*);
+ if (AvFILLp(ary) + 1 + off)
+ Copy(AvALLOC(ary), AvARRAY(PL_dbargs), AvFILLp(ary) + 1 + off, SV*);
AvFILLp(PL_dbargs) = AvFILLp(ary) + off;
}
mPUSHi(CopHINTS_get(cx->blk_oldcop));
dSP;
const char * tmps;
STRLEN len = 0;
- if (MAXARG < 1 || (!TOPs && !POPs))
+ if (MAXARG < 1 || (!TOPs && !POPs)) {
+ EXTEND(SP, 1);
tmps = NULL, len = 0;
+ }
else
tmps = SvPVx_const(POPs, len);
sv_resetpvn(tmps, len, CopSTASH(PL_curcop));
=cut
*/
STATIC OP *
-S_docatch(pTHX_ OP *o)
+S_docatch(pTHX_ Perl_ppaddr_t firstpp)
{
int ret;
OP * const oldop = PL_op;
dJMPENV;
-#ifdef DEBUGGING
assert(CATCH_GET == TRUE);
-#endif
- PL_op = o;
JMPENV_PUSH(ret);
switch (ret) {
case 0:
- assert(cxstack_ix >= 0);
- assert(CxTYPE(CX_CUR()) == CXt_EVAL);
- CX_CUR()->blk_eval.cur_top_env = PL_top_env;
+ PL_op = firstpp(aTHX);
redo_body:
CALLRUNOPS(aTHX);
break;
}
/* switch to eval mode */
+ assert(!CATCH_GET);
cx = cx_pushblock(CXt_EVAL, gimme, SP, old_savestack_ix);
cx_pusheval(cx, PL_op->op_next, newSVpv(name, 0));
PUTBACK;
if (doeval_compile(gimme, NULL, PL_curcop->cop_seq, NULL))
- op = DOCATCH(PL_eval_start);
+ op = PL_eval_start;
else
op = PL_op->op_next;
PP(pp_require)
{
- dSP;
- SV *sv = POPs;
- SvGETMAGIC(sv);
- PUTBACK;
- return ((SvNIOKp(sv) || SvVOK(sv)) && PL_op->op_type != OP_DOFILE)
- ? S_require_version(aTHX_ sv)
- : S_require_file(aTHX_ sv);
+ RUN_PP_CATCHABLY(Perl_pp_require);
+
+ {
+ dSP;
+ SV *sv = POPs;
+ SvGETMAGIC(sv);
+ PUTBACK;
+ return ((SvNIOKp(sv) || SvVOK(sv)) && PL_op->op_type != OP_DOFILE)
+ ? S_require_version(aTHX_ sv)
+ : S_require_file(aTHX_ sv);
+ }
}
dSP;
PERL_CONTEXT *cx;
SV *sv;
- const U8 gimme = GIMME_V;
- const U32 was = PL_breakable_sub_gen;
+ U8 gimme;
+ U32 was;
char tbuf[TYPE_DIGITS(long) + 12];
- bool saved_delete = FALSE;
- char *tmpbuf = tbuf;
+ bool saved_delete;
+ char *tmpbuf;
STRLEN len;
CV* runcv;
- U32 seq, lex_flags = 0;
- HV *saved_hh = NULL;
- const bool bytes = PL_op->op_private & OPpEVAL_BYTES;
+ U32 seq, lex_flags;
+ HV *saved_hh;
+ bool bytes;
I32 old_savestack_ix;
+ RUN_PP_CATCHABLY(Perl_pp_entereval);
+
+ gimme = GIMME_V;
+ was = PL_breakable_sub_gen;
+ saved_delete = FALSE;
+ tmpbuf = tbuf;
+ lex_flags = 0;
+ saved_hh = NULL;
+ bytes = PL_op->op_private & OPpEVAL_BYTES;
+
if (PL_op->op_private & OPpEVAL_HAS_HH) {
saved_hh = MUTABLE_HV(SvREFCNT_inc(POPs));
}
* to do the dirty work for us */
runcv = find_runcv(&seq);
+ assert(!CATCH_GET);
cx = cx_pushblock((CXt_EVAL|CXp_REAL), gimme, SP, old_savestack_ix);
cx_pusheval(cx, PL_op->op_next, NULL);
char *const safestr = savepvn(tmpbuf, len);
SAVEDELETE(PL_defstash, safestr, len);
}
- return DOCATCH(PL_eval_start);
+ return PL_eval_start;
} else {
/* We have already left the scope set up earlier thanks to the LEAVE
in doeval_compile(). */
/* did require return a false value? */
failed = CxOLD_OP_TYPE(cx) == OP_REQUIRE
&& !(gimme == G_SCALAR
- ? SvTRUE(*PL_stack_sp)
+ ? SvTRUE_NN(*PL_stack_sp)
: PL_stack_sp > oldsp);
- if (gimme == G_VOID)
+ if (gimme == G_VOID) {
PL_stack_sp = oldsp;
+ /* free now to avoid late-called destructors clobbering $@ */
+ FREETMPS;
+ }
else
leave_adjust_stacks(oldsp, oldsp, gimme, 0);
PP(pp_entertry)
{
+ RUN_PP_CATCHABLY(Perl_pp_entertry);
+
+ assert(!CATCH_GET);
create_eval_scope(cLOGOP->op_other->op_next, 0);
- return DOCATCH(PL_op->op_next);
+ return PL_op->op_next;
}
oldsp = PL_stack_base + cx->blk_oldsp;
gimme = cx->blk_gimme;
- if (gimme == G_VOID)
+ if (gimme == G_VOID) {
PL_stack_sp = oldsp;
+ /* free now to avoid late-called destructors clobbering $@ */
+ FREETMPS;
+ }
else
leave_adjust_stacks(oldsp, oldsp, gimme, 1);
CX_LEAVE_SCOPE(cx);
DEFSV_set(upstream);
PUSHMARK(SP);
- mPUSHi(0);
+ PUSHs(&PL_sv_zero);
if (filter_state) {
PUSHs(filter_state);
}