PP(pp_wantarray)
{
- dVAR;
dSP;
I32 cxix;
const PERL_CONTEXT *cx;
PP(pp_regcreset)
{
- dVAR;
TAINT_NOT;
return NORMAL;
}
PP(pp_regcomp)
{
- dVAR;
dSP;
PMOP *pm = (PMOP*)cLOGOP->op_other;
SV **args;
const bool was_tainted = TAINT_get;
if (pm->op_flags & OPf_STACKED)
lhs = args[-1];
- else if (pm->op_private & OPpTARGET_MY)
+ else if (pm->op_targ)
lhs = PAD_SV(pm->op_targ);
else lhs = DEFSV;
SvGETMAGIC(lhs);
}
- if (TAINTING_get && TAINT_get) {
+ assert(TAINTING_get || !TAINT_get);
+ if (TAINT_get) {
SvTAINTED_on((SV*)new_re);
RX_TAINT_on(new_re);
}
PP(pp_substcont)
{
- dVAR;
dSP;
PERL_CONTEXT *cx = &cxstack[cxstack_ix];
PMOP * const pm = (PMOP*) cLOGOP->op_other;
rxres_restore(&cx->sb_rxres, rx);
if (cx->sb_iters++) {
- const I32 saviters = cx->sb_iters;
+ const SSize_t saviters = cx->sb_iters;
if (cx->sb_iters > cx->sb_maxiters)
DIE(aTHX_ "Substitution loop");
POPSUBST(cx);
PERL_ASYNC_CHECK();
RETURNOP(pm->op_next);
- assert(0); /* NOTREACHED */
+ NOT_REACHED; /* NOTREACHED */
}
cx->sb_iters = saviters;
}
SV * const sv
= (pm->op_pmflags & PMf_NONDESTRUCT) ? cx->sb_dstr : cx->sb_targ;
MAGIC *mg;
+
+ /* the string being matched against may no longer be a string,
+ * e.g. $_=0; s/.../$_++/ge */
+
+ if (!SvPOK(sv))
+ SvPV_force_nomg_nolen(sv);
+
if (!(mg = mg_find_mglob(sv))) {
mg = sv_magicext_mglob(sv);
}
- assert(SvPOK(dstr));
- MgBYTEPOS_set(mg, sv, SvPVX(dstr), m - orig);
+ MgBYTEPOS_set(mg, sv, SvPVX(sv), m - orig);
}
if (old != rx)
(void)ReREFCNT_inc(rx);
PP(pp_formline)
{
- dVAR; dSP; dMARK; dORIGMARK;
+ dSP; dMARK; dORIGMARK;
SV * const tmpForm = *++MARK;
SV *formsv; /* contains text of original format */
U32 *fpc; /* format ops program counter */
break;
}
itembytes = s - item;
+ chophere = s;
break;
}
goto append;
case FF_CHOP: /* (for ^*) chop the current item */
- {
+ if (sv != &PL_sv_no) {
const char *s = chophere;
if (chopspace) {
while (isSPACE(*s))
const char *const send = s + len;
item_is_utf8 = DO_UTF8(sv);
+ chophere = s + len;
if (!len)
break;
trans = 0;
gotsome = TRUE;
- chophere = s + len;
source = (U8 *) s;
to_copy = len;
while (s < send) {
case FF_0DECIMAL: /* like FF_DECIMAL but for 0### */
arg = *fpc++;
-#if defined(USE_LONG_DOUBLE)
- fmt = (const char *)
- ((arg & FORM_NUM_POINT) ?
- "%#0*.*" PERL_PRIfldbl : "%0*.*" PERL_PRIfldbl);
-#else
fmt = (const char *)
- ((arg & FORM_NUM_POINT) ?
- "%#0*.*f" : "%0*.*f");
-#endif
+ ((arg & FORM_NUM_POINT) ? "%#0*.*" NVff : "%0*.*" NVff);
goto ff_dec;
case FF_DECIMAL: /* do @##, ^##, where <arg>=(precision|flags) */
arg = *fpc++;
-#if defined(USE_LONG_DOUBLE)
fmt = (const char *)
- ((arg & FORM_NUM_POINT) ? "%#*.*" PERL_PRIfldbl : "%*.*" PERL_PRIfldbl);
-#else
- fmt = (const char *)
- ((arg & FORM_NUM_POINT) ? "%#*.*f" : "%*.*f");
-#endif
+ ((arg & FORM_NUM_POINT) ? "%#*.*" NVff : "%*.*" NVff);
ff_dec:
/* If the field is marked with ^ and the value is undefined,
blank it out. */
}
/* Formats aren't yet marked for locales, so assume "yes". */
{
- DECLARE_STORE_LC_NUMERIC_SET_TO_NEEDED();
+ Size_t max = SvLEN(PL_formtarget) - (t - SvPVX(PL_formtarget));
+ int len;
+ DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
+ STORE_LC_NUMERIC_SET_TO_NEEDED();
arg &= ~(FORM_NUM_POINT|FORM_NUM_BLANK);
+#ifdef USE_QUADMATH
+ {
+ const char* qfmt = quadmath_format_single(fmt);
+ int len;
+ if (!qfmt)
+ Perl_croak_nocontext("panic: quadmath invalid format \"%s\"", fmt);
+ len = quadmath_snprintf(t, max, qfmt, (int) fieldsize, (int) arg, value);
+ if (len == -1)
+ Perl_croak_nocontext("panic: quadmath_snprintf failed, format \"%s\"", qfmt);
+ if (qfmt != fmt)
+ Safefree(fmt);
+ }
+#else
/* we generate fmt ourselves so it is safe */
GCC_DIAG_IGNORE(-Wformat-nonliteral);
- PERL_UNUSED_RESULT(my_snprintf(t, SvLEN(PL_formtarget) - (t - SvPVX(PL_formtarget)), fmt, (int) fieldsize, (int) arg, value));
+ len = my_snprintf(t, max, fmt, (int) fieldsize, (int) arg, value);
GCC_DIAG_RESTORE;
+#endif
+ PERL_MY_SNPRINTF_POST_GUARD(len, max);
RESTORE_LC_NUMERIC();
}
t += fieldsize;
PP(pp_grepstart)
{
- dVAR; dSP;
+ dSP;
SV *src;
- if (PL_stack_base + *PL_markstack_ptr == SP) {
+ if (PL_stack_base + TOPMARK == SP) {
(void)POPMARK;
if (GIMME_V == G_SCALAR)
mXPUSHi(0);
RETURNOP(PL_op->op_next->op_next);
}
- PL_stack_sp = PL_stack_base + *PL_markstack_ptr + 1;
+ PL_stack_sp = PL_stack_base + TOPMARK + 1;
Perl_pp_pushmark(aTHX); /* push dst */
Perl_pp_pushmark(aTHX); /* push src */
ENTER_with_name("grep"); /* enter outer scope */
SAVETMPS;
- if (PL_op->op_private & OPpGREP_LEX)
- SAVESPTR(PAD_SVl(PL_op->op_targ));
- else
- SAVE_DEFSV;
+ SAVE_DEFSV;
ENTER_with_name("grep_item"); /* enter inner scope */
SAVEVPTR(PL_curpm);
- src = PL_stack_base[*PL_markstack_ptr];
+ src = PL_stack_base[TOPMARK];
if (SvPADTMP(src)) {
- assert(!IS_PADGV(src));
- src = PL_stack_base[*PL_markstack_ptr] = sv_mortalcopy(src);
+ src = PL_stack_base[TOPMARK] = sv_mortalcopy(src);
PL_tmps_floor++;
}
SvTEMP_off(src);
- if (PL_op->op_private & OPpGREP_LEX)
- PAD_SVl(PL_op->op_targ) = src;
- else
- DEFSV_set(src);
+ DEFSV_set(src);
PUTBACK;
if (PL_op->op_type == OP_MAPSTART)
PP(pp_mapwhile)
{
- dVAR; dSP;
+ dSP;
const I32 gimme = GIMME_V;
- I32 items = (SP - PL_stack_base) - *PL_markstack_ptr; /* how many new items */
+ I32 items = (SP - PL_stack_base) - TOPMARK; /* how many new items */
I32 count;
I32 shift;
SV** src;
LEAVE_with_name("grep_item"); /* exit inner scope */
/* All done yet? */
- if (PL_markstack_ptr[-1] > *PL_markstack_ptr) {
+ if (PL_markstack_ptr[-1] > TOPMARK) {
(void)POPMARK; /* pop top */
LEAVE_with_name("grep"); /* exit outer scope */
(void)POPMARK; /* pop dst */
SP = PL_stack_base + POPMARK; /* pop original mark */
if (gimme == G_SCALAR) {
- if (PL_op->op_private & OPpGREP_LEX) {
- SV* sv = sv_newmortal();
- sv_setiv(sv, items);
- PUSHs(sv);
- }
- else {
dTARGET;
XPUSHi(items);
- }
}
else if (gimme == G_ARRAY)
SP += items;
/* set $_ to the new source item */
src = PL_stack_base[PL_markstack_ptr[-1]];
if (SvPADTMP(src)) {
- assert(!IS_PADGV(src));
src = sv_mortalcopy(src);
}
SvTEMP_off(src);
- if (PL_op->op_private & OPpGREP_LEX)
- PAD_SVl(PL_op->op_targ) = src;
- else
- DEFSV_set(src);
+ DEFSV_set(src);
RETURNOP(cLOGOP->op_other);
}
PP(pp_range)
{
- dVAR;
- if (GIMME == G_ARRAY)
+ if (GIMME_V == G_ARRAY)
return NORMAL;
if (SvTRUEx(PAD_SV(PL_op->op_targ)))
return cLOGOP->op_other;
PP(pp_flip)
{
- dVAR;
dSP;
- if (GIMME == G_ARRAY) {
+ if (GIMME_V == G_ARRAY) {
RETURNOP(((LOGOP*)cUNOP->op_first)->op_other);
}
else {
PP(pp_flop)
{
- dVAR; dSP;
+ dSP;
- if (GIMME == G_ARRAY) {
+ if (GIMME_V == G_ARRAY) {
dPOPPOPssrl;
SvGETMAGIC(left);
/* The wraparound of signed integers is undefined
* behavior, but here we aim for count >=1, and
* negative count is just wrong. */
- if (n < 1)
+ if (n < 1
+#if IVSIZE > Size_t_size
+ || n > SSize_t_MAX
+#endif
+ )
overflow = TRUE;
}
if (overflow)
else
n = 0;
while (n--) {
- SV * const sv = sv_2mortal(newSViv(i++));
+ SV * const sv = sv_2mortal(newSViv(i));
PUSHs(sv);
+ if (n) /* avoid incrementing above IV_MAX */
+ i++;
}
}
else {
STATIC I32
S_dopoptolabel(pTHX_ const char *label, STRLEN len, U32 flags)
{
- dVAR;
I32 i;
PERL_ARGS_ASSERT_DOPOPTOLABEL;
I32
Perl_dowantarray(pTHX)
{
- dVAR;
const I32 gimme = block_gimme();
return (gimme == G_VOID) ? G_SCALAR : gimme;
}
I32
Perl_block_gimme(pTHX)
{
- dVAR;
const I32 cxix = dopoptosub(cxstack_ix);
+ U8 gimme;
if (cxix < 0)
return G_VOID;
- switch (cxstack[cxix].blk_gimme) {
- case G_VOID:
- return G_VOID;
- case G_SCALAR:
- return G_SCALAR;
- case G_ARRAY:
- return G_ARRAY;
- default:
- Perl_croak(aTHX_ "panic: bad gimme: %d\n", cxstack[cxix].blk_gimme);
- }
- NOT_REACHED; /* NOTREACHED */
+ gimme = (cxstack[cxix].blk_gimme & G_WANT);
+ if (!gimme)
+ Perl_croak(aTHX_ "panic: bad gimme: %d\n", gimme);
+ return gimme;
}
+
I32
Perl_is_lvalue_sub(pTHX)
{
- dVAR;
const I32 cxix = dopoptosub(cxstack_ix);
assert(cxix >= 0); /* We should only be called from inside subs */
I32
Perl_was_lvalue_sub(pTHX)
{
- dVAR;
const I32 cxix = dopoptosub(cxstack_ix-1);
assert(cxix >= 0); /* We should only be called from inside subs */
STATIC I32
S_dopoptosub_at(pTHX_ const PERL_CONTEXT *cxstk, I32 startingblock)
{
- dVAR;
I32 i;
PERL_ARGS_ASSERT_DOPOPTOSUB_AT;
STATIC I32
S_dopoptoeval(pTHX_ I32 startingblock)
{
- dVAR;
I32 i;
for (i = startingblock; i >= 0; i--) {
const PERL_CONTEXT *cx = &cxstack[i];
STATIC I32
S_dopoptoloop(pTHX_ I32 startingblock)
{
- dVAR;
I32 i;
for (i = startingblock; i >= 0; i--) {
const PERL_CONTEXT * const cx = &cxstack[i];
STATIC I32
S_dopoptogiven(pTHX_ I32 startingblock)
{
- dVAR;
I32 i;
for (i = startingblock; i >= 0; i--) {
const PERL_CONTEXT *cx = &cxstack[i];
STATIC I32
S_dopoptowhen(pTHX_ I32 startingblock)
{
- dVAR;
I32 i;
for (i = startingblock; i >= 0; i--) {
const PERL_CONTEXT *cx = &cxstack[i];
void
Perl_dounwind(pTHX_ I32 cxix)
{
- dVAR;
I32 optype;
if (!PL_curstackinfo) /* can happen if die during thread cloning */
void
Perl_qerror(pTHX_ SV *err)
{
- dVAR;
-
PERL_ARGS_ASSERT_QERROR;
if (PL_in_eval) {
void
Perl_die_unwind(pTHX_ SV *msv)
{
- dVAR;
SV *exceptsv = sv_mortalcopy(msv);
U8 in_eval = PL_in_eval;
PERL_ARGS_ASSERT_DIE_UNWIND;
SV *namesv;
PERL_CONTEXT *cx;
SV **newsp;
+#ifdef DEBUGGING
COP *oldcop;
+#endif
JMPENV *restartjmpenv;
OP *restartop;
}
POPEVAL(cx);
namesv = cx->blk_eval.old_namesv;
+#ifdef DEBUGGING
oldcop = cx->blk_oldcop;
+#endif
restartjmpenv = cx->blk_eval.cur_top_env;
restartop = cx->blk_eval.retop;
LEAVE;
- /* LEAVE could clobber PL_curcop (see save_re_context())
- * XXX it might be better to find a way to avoid messing with
- * PL_curcop in save_re_context() instead, but this is a more
- * minimal fix --GSAR */
- PL_curcop = oldcop;
-
if (optype == OP_REQUIRE) {
+ assert (PL_curcop == oldcop);
(void)hv_store(GvHVn(PL_incgv),
SvPVX_const(namesv),
SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
PL_restartjmpenv = restartjmpenv;
PL_restartop = restartop;
JMPENV_JUMP(3);
- assert(0); /* NOTREACHED */
+ NOT_REACHED; /* NOTREACHED */
}
}
write_to_stderr(exceptsv);
my_failure_exit();
- assert(0); /* NOTREACHED */
+ NOT_REACHED; /* NOTREACHED */
}
PP(pp_xor)
{
- dVAR; dSP; dPOPTOPssrl;
+ dSP; dPOPTOPssrl;
if (SvTRUE(left) != SvTRUE(right))
RETSETYES;
else
PP(pp_caller)
{
- dVAR;
dSP;
const PERL_CONTEXT *cx;
const PERL_CONTEXT *dbcx;
- I32 gimme;
+ I32 gimme = GIMME_V;
const HEK *stash_hek;
I32 count = 0;
bool has_arg = MAXARG && TOPs;
cx = caller_cx(count + !!(PL_op->op_private & OPpOFFBYONE), &dbcx);
if (!cx) {
- if (GIMME != G_ARRAY) {
+ if (gimme != G_ARRAY) {
EXTEND(SP, 1);
RETPUSHUNDEF;
}
stash_hek = SvTYPE(CopSTASH(cx->blk_oldcop)) == SVt_PVHV
? HvNAME_HEK((HV*)CopSTASH(cx->blk_oldcop))
: NULL;
- if (GIMME != G_ARRAY) {
+ if (gimme != G_ARRAY) {
EXTEND(SP, 1);
if (!stash_hek)
PUSHs(&PL_sv_undef);
PUSHTARG;
}
mPUSHs(newSVpv(OutCopFILE(cx->blk_oldcop), 0));
- lcop = closest_cop(cx->blk_oldcop, cx->blk_oldcop->op_sibling,
+ lcop = closest_cop(cx->blk_oldcop, OpSIBLING(cx->blk_oldcop),
cx->blk_sub.retop, TRUE);
if (!lcop)
lcop = cx->blk_oldcop;
- mPUSHi((I32)CopLINE(lcop));
+ mPUSHu(CopLINE(lcop));
if (!has_arg)
RETURN;
if (CxTYPE(cx) == CXt_SUB || CxTYPE(cx) == CXt_FORMAT) {
- GV * const cvgv = CvGV(dbcx->blk_sub.cv);
/* So is ccstack[dbcxix]. */
- if (cvgv && isGV(cvgv)) {
- SV * const sv = newSV(0);
- gv_efullname3(sv, cvgv, NULL);
- mPUSHs(sv);
+ if (CvHASGV(dbcx->blk_sub.cv)) {
+ PUSHs(cv_name(dbcx->blk_sub.cv, 0, 0));
PUSHs(boolSV(CxHASARGS(cx)));
}
else {
PP(pp_reset)
{
- dVAR;
dSP;
const char * tmps;
STRLEN len = 0;
PP(pp_dbstate)
{
- dVAR;
PL_curcop = (COP*)PL_op;
TAINT_NOT; /* Each statement is presumed innocent */
PL_stack_sp = PL_stack_base + cxstack[cxstack_ix].blk_oldsp;
PERL_ASYNC_CHECK();
if (PL_op->op_flags & OPf_SPECIAL /* breakpoint */
- || SvIV(PL_DBsingle) || SvIV(PL_DBsignal) || SvIV(PL_DBtrace))
+ || PL_DBsingle_iv || PL_DBsignal_iv || PL_DBtrace_iv)
{
dSP;
PERL_CONTEXT *cx;
return NORMAL;
}
+/* S_leave_common: Common code that many functions in this file use on
+ scope exit. */
+
/* SVs on the stack that have any of the flags passed in are left as is.
Other SVs are protected via the mortals stack if lvalue is true, and
- copied otherwise. */
+ copied otherwise.
+
+ Also, taintedness is cleared.
+*/
STATIC SV **
-S_adjust_stack_on_leave(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme,
+S_leave_common(pTHX_ SV **newsp, SV **sp, SV **mark, I32 gimme,
U32 flags, bool lvalue)
{
bool padtmp = 0;
- PERL_ARGS_ASSERT_ADJUST_STACK_ON_LEAVE;
+ PERL_ARGS_ASSERT_LEAVE_COMMON;
+ TAINT_NOT;
if (flags & SVs_PADTMP) {
flags &= ~SVs_PADTMP;
padtmp = 1;
PP(pp_enter)
{
- dVAR; dSP;
+ dSP;
PERL_CONTEXT *cx;
I32 gimme = GIMME_V;
PP(pp_leave)
{
- dVAR; dSP;
+ dSP;
PERL_CONTEXT *cx;
SV **newsp;
PMOP *newpm;
gimme = OP_GIMME(PL_op, (cxstack_ix >= 0) ? gimme : G_SCALAR);
- TAINT_NOT;
- SP = adjust_stack_on_leave(newsp, SP, newsp, gimme, SVs_PADTMP|SVs_TEMP,
+ SP = leave_common(newsp, SP, newsp, gimme, SVs_PADTMP|SVs_TEMP,
PL_op->op_private & OPpLVALUE);
PL_curpm = newpm; /* Don't pop $1 et al till now */
RETURN;
}
+static bool
+S_outside_integer(pTHX_ SV *sv)
+{
+ if (SvOK(sv)) {
+ const NV nv = SvNV_nomg(sv);
+ if (Perl_isinfnan(nv))
+ return TRUE;
+#ifdef NV_PRESERVES_UV
+ if (nv < (NV)IV_MIN || nv > (NV)IV_MAX)
+ return TRUE;
+#else
+ if (nv <= (NV)IV_MIN)
+ return TRUE;
+ if ((nv > 0) &&
+ ((nv > (NV)UV_MAX ||
+ SvUV_nomg(sv) > (UV)IV_MAX)))
+ return TRUE;
+#endif
+ }
+ return FALSE;
+}
+
PP(pp_enteriter)
{
- dVAR; dSP; dMARK;
+ dSP; dMARK;
PERL_CONTEXT *cx;
const I32 gimme = GIMME_V;
void *itervar; /* location of the iteration variable */
itervar = &PAD_SVl(PL_op->op_targ);
#endif
}
- else { /* symbol table variable */
+ else if (LIKELY(isGV(TOPs))) { /* symbol table variable */
GV * const gv = MUTABLE_GV(POPs);
SV** svp = &GvSV(gv);
save_pushptrptr(gv, SvREFCNT_inc(*svp), SAVEt_GVSV);
*svp = newSV(0);
itervar = (void *)gv;
}
+ else {
+ SV * const sv = POPs;
+ assert(SvTYPE(sv) == SVt_PVMG);
+ assert(SvMAGIC(sv));
+ assert(SvMAGIC(sv)->mg_type == PERL_MAGIC_lvref);
+ itervar = (void *)sv;
+ cxtype |= CXp_FOR_LVREF;
+ }
if (PL_op->op_private & OPpITER_DEF)
cxtype |= CXp_FOR_DEF;
if (SvTYPE(maybe_ary) != SVt_PVAV) {
dPOPss;
SV * const right = maybe_ary;
+ if (UNLIKELY(cxtype & CXp_FOR_LVREF))
+ DIE(aTHX_ "Assigned value is not a reference");
SvGETMAGIC(sv);
SvGETMAGIC(right);
if (RANGE_IS_NUMERIC(sv,right)) {
/* Make sure that no-one re-orders cop.h and breaks our
assumptions */
assert(CxTYPE(cx) == CXt_LOOP_LAZYIV);
-#ifdef NV_PRESERVES_UV
- if ((SvOK(sv) && ((SvNV_nomg(sv) < (NV)IV_MIN) ||
- (SvNV_nomg(sv) > (NV)IV_MAX)))
- ||
- (SvOK(right) && ((SvNV_nomg(right) > (NV)IV_MAX) ||
- (SvNV_nomg(right) < (NV)IV_MIN))))
-#else
- if ((SvOK(sv) && ((SvNV_nomg(sv) <= (NV)IV_MIN)
- ||
- ((SvNV_nomg(sv) > 0) &&
- ((SvUV_nomg(sv) > (UV)IV_MAX) ||
- (SvNV_nomg(sv) > (NV)UV_MAX)))))
- ||
- (SvOK(right) && ((SvNV_nomg(right) <= (NV)IV_MIN)
- ||
- ((SvNV_nomg(right) > 0) &&
- ((SvUV_nomg(right) > (UV)IV_MAX) ||
- (SvNV_nomg(right) > (NV)UV_MAX))
- ))))
-#endif
+ if (S_outside_integer(aTHX_ sv) ||
+ S_outside_integer(aTHX_ right))
DIE(aTHX_ "Range iterator outside integer range");
cx->blk_loop.state_u.lazyiv.cur = SvIV_nomg(sv);
cx->blk_loop.state_u.lazyiv.end = SvIV_nomg(right);
PP(pp_enterloop)
{
- dVAR; dSP;
+ dSP;
PERL_CONTEXT *cx;
const I32 gimme = GIMME_V;
PP(pp_leaveloop)
{
- dVAR; dSP;
+ dSP;
PERL_CONTEXT *cx;
I32 gimme;
SV **newsp;
mark = newsp;
newsp = PL_stack_base + cx->blk_loop.resetsp;
- TAINT_NOT;
- SP = adjust_stack_on_leave(newsp, SP, MARK, gimme, 0,
+ SP = leave_common(newsp, SP, MARK, gimme, 0,
PL_op->op_private & OPpLVALUE);
PUTBACK;
return NORMAL;
}
-STATIC void
-S_return_lvalues(pTHX_ SV **mark, SV **sp, SV **newsp, I32 gimme,
- PERL_CONTEXT *cx, PMOP *newpm)
+
+/* This duplicates most of pp_leavesub, but with additional code to handle
+ * return args in lvalue context. It was forked from pp_leavesub to
+ * avoid slowing down that function any further.
+ *
+ * Any changes made to this function may need to be copied to pp_leavesub
+ * and vice-versa.
+ */
+
+PP(pp_leavesublv)
{
- const bool ref = !!(CxLVAL(cx) & OPpENTERSUB_INARGS);
+ dSP;
+ SV **newsp;
+ SV **mark;
+ PMOP *newpm;
+ I32 gimme;
+ PERL_CONTEXT *cx;
+ SV *sv;
+ bool ref;
+ const char *what = NULL;
+
+ if (CxMULTICALL(&cxstack[cxstack_ix])) {
+ /* entry zero of a stack is always PL_sv_undef, which
+ * simplifies converting a '()' return into undef in scalar context */
+ assert(PL_stack_sp > PL_stack_base || *PL_stack_base == &PL_sv_undef);
+ return 0;
+ }
+
+ POPBLOCK(cx,newpm);
+ cxstack_ix++; /* preserve cx entry on stack for use by POPSUB */
+ TAINT_NOT;
+
+ mark = newsp + 1;
+
+ ref = !!(CxLVAL(cx) & OPpENTERSUB_INARGS);
if (gimme == G_SCALAR) {
if (CxLVAL(cx) && !ref) { /* Leave it as it is if we can. */
SV *sv;
- const char *what = NULL;
- if (MARK < SP) {
- assert(MARK+1 == SP);
- if ((SvPADTMP(TOPs) ||
- (SvFLAGS(TOPs) & (SVf_READONLY | SVf_FAKE))
- == SVf_READONLY
- ) &&
+ if (MARK <= SP) {
+ assert(MARK == SP);
+ if ((SvPADTMP(TOPs) || SvREADONLY(TOPs)) &&
!SvSMAGICAL(TOPs)) {
what =
SvREADONLY(TOPs) ? (TOPs == &PL_sv_undef) ? "undef"
/* sub:lvalue{} will take us here. */
what = "undef";
}
+ croak:
LEAVE;
- cxstack_ix--;
POPSUB(cx,sv);
+ cxstack_ix--;
PL_curpm = newpm;
LEAVESUB(sv);
Perl_croak(aTHX_
"Can't return %s from lvalue subroutine", what
);
}
- if (MARK < SP) {
+ if (MARK <= SP) {
copy_sv:
if (cx->blk_sub.cv && CvDEPTH(cx->blk_sub.cv) > 1) {
if (!SvPADTMP(*SP)) {
- *++newsp = SvREFCNT_inc(*SP);
+ *MARK = SvREFCNT_inc(*SP);
FREETMPS;
- sv_2mortal(*newsp);
+ sv_2mortal(*MARK);
}
else {
/* FREETMPS could clobber it */
SV *sv = SvREFCNT_inc(*SP);
FREETMPS;
- *++newsp = sv_mortalcopy(sv);
+ *MARK = sv_mortalcopy(sv);
SvREFCNT_dec(sv);
}
}
else
- *++newsp =
+ *MARK =
SvPADTMP(*SP)
? sv_mortalcopy(*SP)
: !SvTEMP(*SP)
: *SP;
}
else {
- EXTEND(newsp,1);
- *++newsp = &PL_sv_undef;
+ MEXTEND(MARK, 0);
+ *MARK = &PL_sv_undef;
}
+ SP = MARK;
+
if (CxLVAL(cx) & OPpDEREF) {
SvGETMAGIC(TOPs);
if (!SvOK(TOPs)) {
else if (gimme == G_ARRAY) {
assert (!(CxLVAL(cx) & OPpDEREF));
if (ref || !CxLVAL(cx))
- while (++MARK <= SP)
- *++newsp =
+ for (; MARK <= SP; MARK++)
+ *MARK =
SvFLAGS(*MARK) & SVs_PADTMP
? sv_mortalcopy(*MARK)
: SvTEMP(*MARK)
? *MARK
: sv_2mortal(SvREFCNT_inc_simple_NN(*MARK));
- else while (++MARK <= SP) {
+ else for (; MARK <= SP; MARK++) {
if (*MARK != &PL_sv_undef
- && (SvPADTMP(*MARK)
- || (SvFLAGS(*MARK) & (SVf_READONLY|SVf_FAKE))
- == SVf_READONLY
- )
+ && (SvPADTMP(*MARK) || SvREADONLY(*MARK))
) {
- SV *sv;
/* Might be flattened array after $#array = */
- PUTBACK;
- LEAVE;
- cxstack_ix--;
- 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");
+ what = SvREADONLY(*MARK)
+ ? "a readonly value" : "a temporary";
+ goto croak;
}
- else
- *++newsp =
- SvTEMP(*MARK)
- ? *MARK
- : sv_2mortal(SvREFCNT_inc_simple_NN(*MARK));
+ else if (!SvTEMP(*MARK))
+ *MARK = sv_2mortal(SvREFCNT_inc_simple_NN(*MARK));
}
}
- PL_stack_sp = newsp;
+ PUTBACK;
+
+ LEAVE;
+ POPSUB(cx,sv); /* Stack values are safe: release CV and @_ ... */
+ cxstack_ix--;
+ PL_curpm = newpm; /* ... and pop $1 et al */
+ LEAVESUB(sv);
+
+ return cx->blk_sub.retop;
}
+
PP(pp_return)
{
- dVAR; dSP; dMARK;
+ dSP; dMARK;
PERL_CONTEXT *cx;
- bool popsub2 = FALSE;
- bool clear_errsv = FALSE;
- bool lval = FALSE;
- I32 gimme;
- SV **newsp;
- PMOP *newpm;
- I32 optype = 0;
- SV *namesv;
- SV *sv;
- OP *retop = NULL;
-
+ SV **oldsp;
const I32 cxix = dopoptosub(cxstack_ix);
- if (cxix < 0) {
- if (CxMULTICALL(cxstack)) { /* In this case we must be in a
- * sort block, which is a CXt_NULL
- * not a CXt_SUB */
- dounwind(0);
- PL_stack_base[1] = *PL_stack_sp;
- PL_stack_sp = PL_stack_base + 1;
- return 0;
- }
- else
- DIE(aTHX_ "Can't return outside a subroutine");
- }
- if (cxix < cxstack_ix)
+ assert(cxstack_ix >= 0);
+ if (cxix < cxstack_ix) {
+ if (cxix < 0) {
+ if (CxMULTICALL(cxstack)) { /* In this case we must be in a
+ * sort block, which is a CXt_NULL
+ * not a CXt_SUB */
+ dounwind(0);
+ /* if we were in list context, we would have to splice out
+ * any junk before the return args, like we do in the general
+ * pp_return case, e.g.
+ * sub f { for (junk1, junk2) { return arg1, arg2 }}
+ */
+ assert(cxstack[0].blk_gimme == G_SCALAR);
+ return 0;
+ }
+ else
+ DIE(aTHX_ "Can't return outside a subroutine");
+ }
dounwind(cxix);
+ }
- if (CxMULTICALL(&cxstack[cxix])) {
- gimme = cxstack[cxix].blk_gimme;
- if (gimme == G_VOID)
- PL_stack_sp = PL_stack_base;
- else if (gimme == G_SCALAR) {
- PL_stack_base[1] = *PL_stack_sp;
- PL_stack_sp = PL_stack_base + 1;
- }
- return 0;
+ cx = &cxstack[cxix];
+
+ oldsp = PL_stack_base + cx->blk_oldsp;
+ if (oldsp != MARK) {
+ /* Handle extra junk on the stack. For example,
+ * for (1,2) { return 3,4 }
+ * leaves 1,2,3,4 on the stack. In list context we
+ * have to splice out the 1,2; In scalar context for
+ * for (1,2) { return }
+ * we need to set sp = oldsp so that pp_leavesub knows
+ * to push &PL_sv_undef onto the stack.
+ * Note that in pp_return we only do the extra processing
+ * required to handle junk; everything else we leave to
+ * pp_leavesub.
+ */
+ SSize_t nargs = SP - MARK;
+ if (nargs) {
+ if (cx->blk_gimme == G_ARRAY) {
+ /* shift return args to base of call stack frame */
+ Move(MARK + 1, oldsp + 1, nargs, SV*);
+ PL_stack_sp = oldsp + nargs;
+ }
+ }
+ else
+ PL_stack_sp = oldsp;
}
- POPBLOCK(cx,newpm);
+ /* fall through to a normal exit */
switch (CxTYPE(cx)) {
- case CXt_SUB:
- popsub2 = TRUE;
- lval = !!CvLVALUE(cx->blk_sub.cv);
- retop = cx->blk_sub.retop;
- cxstack_ix++; /* preserve cx entry on stack for use by POPSUB */
- break;
case CXt_EVAL:
- if (!(PL_in_eval & EVAL_KEEPERR))
- clear_errsv = TRUE;
- POPEVAL(cx);
- namesv = cx->blk_eval.old_namesv;
- retop = cx->blk_eval.retop;
- if (CxTRYBLOCK(cx))
- break;
- if (optype == OP_REQUIRE &&
- (MARK == SP || (gimme == G_SCALAR && !SvTRUE(*SP))) )
- {
- /* Unassume the success we assumed earlier. */
- (void)hv_delete(GvHVn(PL_incgv),
- SvPVX_const(namesv),
- SvUTF8(namesv) ? -(I32)SvCUR(namesv) : (I32)SvCUR(namesv),
- G_DISCARD);
- DIE(aTHX_ "%"SVf" did not return a true value", SVfARG(namesv));
- }
- break;
+ return CxTRYBLOCK(cx)
+ ? Perl_pp_leavetry(aTHX)
+ : Perl_pp_leaveeval(aTHX);
+ case CXt_SUB:
+ return CvLVALUE(cx->blk_sub.cv)
+ ? Perl_pp_leavesublv(aTHX)
+ : Perl_pp_leavesub(aTHX);
case CXt_FORMAT:
- retop = cx->blk_sub.retop;
- POPFORMAT(cx);
- break;
+ return Perl_pp_leavewrite(aTHX);
default:
DIE(aTHX_ "panic: return, type=%u", (unsigned) CxTYPE(cx));
}
-
- TAINT_NOT;
- if (lval) S_return_lvalues(aTHX_ MARK, SP, newsp, gimme, cx, newpm);
- else {
- if (gimme == G_SCALAR) {
- if (MARK < SP) {
- if (popsub2) {
- if (cx->blk_sub.cv && CvDEPTH(cx->blk_sub.cv) > 1) {
- if (SvTEMP(TOPs) && SvREFCNT(TOPs) == 1
- && !SvMAGICAL(TOPs)) {
- *++newsp = SvREFCNT_inc(*SP);
- FREETMPS;
- sv_2mortal(*newsp);
- }
- else {
- sv = SvREFCNT_inc(*SP); /* FREETMPS could clobber it */
- FREETMPS;
- *++newsp = sv_mortalcopy(sv);
- SvREFCNT_dec(sv);
- }
- }
- else if (SvTEMP(*SP) && SvREFCNT(*SP) == 1
- && !SvMAGICAL(*SP)) {
- *++newsp = *SP;
- }
- else
- *++newsp = sv_mortalcopy(*SP);
- }
- else
- *++newsp = sv_mortalcopy(*SP);
- }
- else
- *++newsp = &PL_sv_undef;
- }
- 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 */
- }
- }
- PL_stack_sp = newsp;
- }
-
- LEAVE;
- /* Stack values are safe: */
- if (popsub2) {
- cxstack_ix--;
- POPSUB(cx,sv); /* release CV and @_ ... */
- }
- else
- sv = NULL;
- PL_curpm = newpm; /* ... and pop $1 et al */
-
- LEAVESUB(sv);
- if (clear_errsv) {
- CLEAR_ERRSV();
- }
- return retop;
}
-/* This duplicates parts of pp_leavesub, so that it can share code with
- * pp_return */
-PP(pp_leavesublv)
-{
- dVAR; dSP;
- SV **newsp;
- PMOP *newpm;
- I32 gimme;
- PERL_CONTEXT *cx;
- SV *sv;
-
- if (CxMULTICALL(&cxstack[cxstack_ix]))
- return 0;
-
- POPBLOCK(cx,newpm);
- cxstack_ix++; /* temporarily protect top context */
-
- TAINT_NOT;
-
- S_return_lvalues(aTHX_ newsp, SP, newsp, gimme, cx, newpm);
-
- LEAVE;
- POPSUB(cx,sv); /* Stack values are safe: release CV and @_ ... */
- cxstack_ix--;
- PL_curpm = newpm; /* ... and pop $1 et al */
-
- LEAVESUB(sv);
- return cx->blk_sub.retop;
-}
static I32
S_unwind_loop(pTHX_ const char * const opname)
{
- dVAR;
I32 cxix;
if (PL_op->op_flags & OPf_SPECIAL) {
cxix = dopoptoloop(cxstack_ix);
PP(pp_last)
{
- dVAR;
PERL_CONTEXT *cx;
- I32 pop2 = 0;
I32 gimme;
- I32 optype;
OP *nextop = NULL;
SV **newsp;
PMOP *newpm;
- SV *sv = NULL;
S_unwind_loop(aTHX_ "last");
POPBLOCK(cx,newpm);
cxstack_ix++; /* temporarily protect top context */
- switch (CxTYPE(cx)) {
- case CXt_LOOP_LAZYIV:
- case CXt_LOOP_LAZYSV:
- case CXt_LOOP_FOR:
- case CXt_LOOP_PLAIN:
- pop2 = CxTYPE(cx);
- newsp = PL_stack_base + cx->blk_loop.resetsp;
- nextop = cx->blk_loop.my_op->op_lastop->op_next;
- break;
- case CXt_SUB:
- pop2 = CXt_SUB;
- nextop = cx->blk_sub.retop;
- break;
- case CXt_EVAL:
- POPEVAL(cx);
- nextop = cx->blk_eval.retop;
- break;
- case CXt_FORMAT:
- POPFORMAT(cx);
- nextop = cx->blk_sub.retop;
- break;
- default:
- DIE(aTHX_ "panic: last, type=%u", (unsigned) CxTYPE(cx));
- }
+ assert(
+ CxTYPE(cx) == CXt_LOOP_LAZYIV
+ || CxTYPE(cx) == CXt_LOOP_LAZYSV
+ || CxTYPE(cx) == CXt_LOOP_FOR
+ || CxTYPE(cx) == CXt_LOOP_PLAIN
+ );
+ newsp = PL_stack_base + cx->blk_loop.resetsp;
+ nextop = cx->blk_loop.my_op->op_lastop->op_next;
TAINT_NOT;
PL_stack_sp = newsp;
LEAVE;
cxstack_ix--;
/* Stack values are safe: */
- switch (pop2) {
- case CXt_LOOP_LAZYIV:
- case CXt_LOOP_PLAIN:
- case CXt_LOOP_LAZYSV:
- case CXt_LOOP_FOR:
- POPLOOP(cx); /* release loop vars ... */
- LEAVE;
- break;
- case CXt_SUB:
- POPSUB(cx,sv); /* release CV and @_ ... */
- break;
- }
+ POPLOOP(cx); /* release loop vars ... */
+ LEAVE;
PL_curpm = newpm; /* ... and pop $1 et al */
- LEAVESUB(sv);
- PERL_UNUSED_VAR(optype);
PERL_UNUSED_VAR(gimme);
return nextop;
}
PP(pp_next)
{
- dVAR;
PERL_CONTEXT *cx;
const I32 inner = PL_scopestack_ix;
PP(pp_redo)
{
- dVAR;
const I32 cxix = S_unwind_loop(aTHX_ "redo");
PERL_CONTEXT *cx;
I32 oldsave;
STATIC OP *
S_dofindlabel(pTHX_ OP *o, const char *label, STRLEN len, U32 flags, OP **opstack, OP **oplimit)
{
- dVAR;
OP **ops = opstack;
static const char* const too_deep = "Target of goto is too deeply nested";
if (o->op_flags & OPf_KIDS) {
OP *kid;
/* First try all the kids at this level, since that's likeliest. */
- for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) {
+ for (kid = cUNOPo->op_first; kid; kid = OpSIBLING(kid)) {
if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) {
STRLEN kid_label_len;
U32 kid_label_flags;
return kid;
}
}
- for (kid = cUNOPo->op_first; kid; kid = kid->op_sibling) {
+ for (kid = cUNOPo->op_first; kid; kid = OpSIBLING(kid)) {
if (kid == PL_lastgotoprobe)
continue;
if (kid->op_type == OP_NEXTSTATE || kid->op_type == OP_DBSTATE) {
return 0;
}
-PP(pp_goto) /* also pp_dump */
+
+/* also used for: pp_dump() */
+
+PP(pp_goto)
{
dVAR; dSP;
OP *retop = NULL;
SAVETMPS;
SAVEFREESV(cv); /* later, undo the 'avoid premature free' hack */
if (CvISXSUB(cv)) {
- OP* const retop = cx->blk_sub.retop;
SV **newsp;
I32 gimme;
const SSize_t items = arg ? AvFILL(arg) + 1 : 0;
SvREFCNT_dec(arg);
}
+ retop = cx->blk_sub.retop;
/* XS subs don't have a CxSUB, so pop it */
POPBLOCK(cx, PL_curpm);
/* Push a mark for the start of arglist */
PUTBACK;
(void)(*CvXSUB(cv))(aTHX_ cv);
LEAVE;
- PERL_ASYNC_CHECK();
- return retop;
+ goto _return;
}
else {
PADLIST * const padlist = CvPADLIST(cv);
}
}
}
- PERL_ASYNC_CHECK();
- RETURNOP(CvSTART(cv));
+ retop = CvSTART(cv);
+ goto putback_return;
}
}
else {
case CXt_LOOP_PLAIN:
case CXt_GIVEN:
case CXt_WHEN:
- gotoprobe = cx->blk_oldcop->op_sibling;
+ gotoprobe = OpSIBLING(cx->blk_oldcop);
break;
case CXt_SUBST:
continue;
case CXt_BLOCK:
if (ix) {
- gotoprobe = cx->blk_oldcop->op_sibling;
+ gotoprobe = OpSIBLING(cx->blk_oldcop);
in_block = TRUE;
} else
gotoprobe = PL_main_root;
break;
}
if (gotoprobe) {
+ OP *sibl1, *sibl2;
+
retop = dofindlabel(gotoprobe, label, label_len, label_flags,
enterops, enterops + GOTO_DEPTH);
if (retop)
break;
- if (gotoprobe->op_sibling &&
- gotoprobe->op_sibling->op_type == OP_UNSTACK &&
- gotoprobe->op_sibling->op_sibling) {
- retop = dofindlabel(gotoprobe->op_sibling->op_sibling,
+ if ( (sibl1 = OpSIBLING(gotoprobe)) &&
+ sibl1->op_type == OP_UNSTACK &&
+ (sibl2 = OpSIBLING(sibl1)))
+ {
+ retop = dofindlabel(sibl2,
label, label_len, label_flags, enterops,
enterops + GOTO_DEPTH);
if (retop)
PL_do_undump = FALSE;
}
+ putback_return:
+ PL_stack_sp = sp;
+ _return:
PERL_ASYNC_CHECK();
- RETURNOP(retop);
+ return retop;
}
PP(pp_exit)
{
- dVAR;
dSP;
I32 anum;
3 is used for a die caught by an inner eval - continue inner loop
-See cop.h: je_mustcatch, when set at any runlevel to TRUE, means eval ops must
+See F<cop.h>: je_mustcatch, when set at any runlevel to TRUE, means eval ops must
establish a local jmpenv to handle exception traps.
=cut
STATIC OP *
S_docatch(pTHX_ OP *o)
{
- dVAR;
int ret;
OP * const oldop = PL_op;
dJMPENV;
JMPENV_POP;
PL_op = oldop;
JMPENV_JUMP(ret);
- assert(0); /* NOTREACHED */
+ NOT_REACHED; /* NOTREACHED */
}
JMPENV_POP;
PL_op = oldop;
=for apidoc find_runcv
Locate the CV corresponding to the currently executing sub or eval.
-If db_seqp is non_null, skip CVs that are in the DB package and populate
-*db_seqp with the cop sequence number at the point that the DB:: code was
+If C<db_seqp> is non_null, skip CVs that are in the DB package and populate
+C<*db_seqp> with the cop sequence number at the point that the DB:: code was
entered. (This allows debuggers to eval in the scope of the breakpoint
rather than in the scope of the debugger itself.)
CV *
Perl_find_runcv_where(pTHX_ U8 cond, IV arg, U32 *db_seqp)
{
- dVAR;
PERL_SI *si;
int level = 0;
switch (cond) {
case FIND_RUNCV_padid_eq:
if (!CvPADLIST(cv)
- || PadlistNAMES(CvPADLIST(cv)) != INT2PTR(PADNAMELIST *, arg))
+ || CvPADLIST(cv)->xpadl_id != (U32)arg)
continue;
return cv;
case FIND_RUNCV_level_eq:
default:
JMPENV_POP;
JMPENV_JUMP(ret);
- assert(0); /* NOTREACHED */
+ NOT_REACHED; /* NOTREACHED */
}
JMPENV_POP;
return ret;
STATIC bool
S_doeval(pTHX_ int gimme, CV* outside, U32 seq, HV *hh)
{
- dVAR; dSP;
+ dSP;
OP * const saveop = PL_op;
bool clear_hints = saveop->op_type != OP_ENTEREVAL;
COP * const oldcurcop = PL_curcop;
/* set up a scratch pad */
- CvPADLIST(evalcv) = pad_new(padnew_SAVE);
+ CvPADLIST_set(evalcv, pad_new(padnew_SAVE));
PL_op = NULL; /* avoid PL_op and PL_curpad referring to different CVs */
{
Stat_t st;
STRLEN len;
+ PerlIO * retio;
const char *p = SvPV_const(name, len);
int st_rc;
/* checking here captures a reasonable error message when
* PERL_DISABLE_PMC is true, but when PMC checks are enabled, the
* user gets a confusing message about looking for the .pmc file
- * rather than for the .pm file.
+ * rather than for the .pm file so do the check in S_doopen_pm when
+ * PMC is on instead of here. S_doopen_pm calls this func.
* This check prevents a \0 in @INC causing problems.
*/
+#ifdef PERL_DISABLE_PMC
if (!IS_SAFE_PATHNAME(p, len, "require"))
return NULL;
+#endif
+ /* on Win32 stat is expensive (it does an open() and close() twice and
+ a couple other IO calls), the open will fail with a dir on its own with
+ errno EACCES, so only do a stat to separate a dir from a real EACCES
+ caused by user perms */
+#ifndef WIN32
/* we use the value of errno later to see how stat() or open() failed.
* We don't want it set if the stat succeeded but we still failed,
* such as if the name exists, but is a directory */
if (st_rc < 0 || S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode)) {
return NULL;
}
+#endif
-#if !defined(PERLIO_IS_STDIO)
- return PerlIO_openn(aTHX_ ":", PERL_SCRIPT_MODE, -1, 0, 0, NULL, 1, &name);
-#else
- return PerlIO_open(p, PERL_SCRIPT_MODE);
+ retio = PerlIO_openn(aTHX_ ":", PERL_SCRIPT_MODE, -1, 0, 0, NULL, 1, &name);
+#ifdef WIN32
+ /* EACCES stops the INC search early in pp_require to implement
+ feature RT #113422 */
+ if(!retio && errno == EACCES) { /* exists but probably a directory */
+ int eno;
+ st_rc = PerlLIO_stat(p, &st);
+ if (st_rc >= 0) {
+ if(S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode))
+ eno = 0;
+ else
+ eno = EACCES;
+ errno = eno;
+ }
+ }
#endif
+ return retio;
}
#ifndef PERL_DISABLE_PMC
if (namelen > 3 && memEQs(p + namelen - 3, 3, ".pm")) {
SV *const pmcsv = sv_newmortal();
- Stat_t pmcstat;
+ PerlIO * pmcio;
SvSetSV_nosteal(pmcsv,name);
sv_catpvs(pmcsv, "c");
- if (PerlLIO_stat(SvPV_nolen_const(pmcsv), &pmcstat) >= 0)
- return check_type_and_open(pmcsv);
+ pmcio = check_type_and_open(pmcsv);
+ if (pmcio)
+ return pmcio;
}
return check_type_and_open(name);
}
#endif /* !PERL_DISABLE_PMC */
/* require doesn't search for absolute names, or when the name is
- explicity relative the current directory */
+ explicitly relative the current directory */
PERL_STATIC_INLINE bool
S_path_is_searchable(const char *name)
{
return TRUE;
}
+
+/* also used for: pp_dofile() */
+
PP(pp_require)
{
- dVAR; dSP;
+ dSP;
PERL_CONTEXT *cx;
SV *sv;
const char *name;
SV *filter_state = NULL;
SV *filter_sub = NULL;
SV *hook_sv = NULL;
- SV *encoding;
OP *op;
int saved_errno;
bool path_searchable;
sv = POPs;
+ SvGETMAGIC(sv);
if ( (SvNIOKp(sv) || SvVOK(sv)) && PL_op->op_type != OP_DOFILE) {
sv = sv_2mortal(new_version(sv));
if (!Perl_sv_derived_from_pvn(aTHX_ PL_patchlevel, STR_WITH_LEN("version"), 0))
RETPUSHYES;
}
- name = SvPV_const(sv, len);
+ if (!SvOK(sv))
+ DIE(aTHX_ "Missing or undefined argument to require");
+ name = SvPV_nomg_const(sv, len);
if (!(name && len > 0 && *name))
- DIE(aTHX_ "Null filename used");
+ DIE(aTHX_ "Missing or undefined argument to require");
+
if (!IS_SAFE_PATHNAME(name, len, "require")) {
DIE(aTHX_ "Can't locate %s: %s",
pv_escape(newSVpvs_flags("",SVs_TEMP),SvPVX(sv),SvCUR(sv),
if (PL_op->op_type == OP_REQUIRE) {
if(saved_errno == EMFILE || saved_errno == EACCES) {
/* diag_listed_as: Can't locate %s */
- DIE(aTHX_ "Can't locate %s: %s", name, Strerror(saved_errno));
+ DIE(aTHX_ "Can't locate %s: %s: %s",
+ name, tryname, Strerror(saved_errno));
} else {
if (namesv) { /* did we lookup @INC? */
AV * const ar = GvAVn(PL_incgv);
PUTBACK;
- /* Store and reset encoding. */
- encoding = PL_encoding;
- PL_encoding = NULL;
-
if (doeval(gimme, NULL, PL_curcop->cop_seq, NULL))
op = DOCATCH(PL_eval_start);
else
op = PL_op->op_next;
- /* Restore encoding. */
- PL_encoding = encoding;
-
LOADED_FILE_PROBE(unixname);
return op;
PP(pp_hintseval)
{
- dVAR;
dSP;
mXPUSHs(MUTABLE_SV(hv_copy_hints_hv(MUTABLE_HV(cSVOP_sv))));
RETURN;
PP(pp_entereval)
{
- dVAR; dSP;
+ dSP;
PERL_CONTEXT *cx;
SV *sv;
const I32 gimme = GIMME_V;
/* prepare to compile string */
- if ((PERLDB_LINE || PERLDB_SAVESRC) && PL_curstash != PL_debstash)
+ if (PERLDB_LINE_OR_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
if (doeval(gimme, runcv, seq, saved_hh)) {
if (was != PL_breakable_sub_gen /* Some subs defined here. */
- ? (PERLDB_LINE || PERLDB_SAVESRC)
+ ? PERLDB_LINE_OR_SAVESRC
: PERLDB_SAVESRC_NOSUBS) {
/* Retain the filegv we created. */
} else if (!saved_delete) {
/* We have already left the scope set up earlier thanks to the LEAVE
in doeval(). */
if (was != PL_breakable_sub_gen /* Some subs defined here. */
- ? (PERLDB_LINE || PERLDB_SAVESRC)
+ ? PERLDB_LINE_OR_SAVESRC
: PERLDB_SAVESRC_INVALID) {
/* Retain the filegv we created. */
} else if (!saved_delete) {
PP(pp_leaveeval)
{
- dVAR; dSP;
+ dSP;
SV **newsp;
PMOP *newpm;
I32 gimme;
PERL_CONTEXT *cx;
OP *retop;
- const U8 save_flags = PL_op -> op_flags;
I32 optype;
SV *namesv;
CV *evalcv;
+ /* grab this value before POPEVAL restores old PL_in_eval */
+ bool keep = cBOOL(PL_in_eval & EVAL_KEEPERR);
PERL_ASYNC_CHECK();
POPBLOCK(cx,newpm);
retop = cx->blk_eval.retop;
evalcv = cx->blk_eval.cv;
- TAINT_NOT;
- SP = adjust_stack_on_leave((gimme == G_VOID) ? SP : newsp, SP, newsp,
+ SP = leave_common((gimme == G_VOID) ? SP : newsp, SP, newsp,
gimme, SVs_TEMP, FALSE);
PL_curpm = newpm; /* Don't pop $1 et al till now */
}
else {
LEAVE_with_name("eval");
- if (!(save_flags & OPf_SPECIAL)) {
+ if (!keep)
CLEAR_ERRSV();
- }
}
RETURNOP(retop);
PP(pp_entertry)
{
- dVAR;
PERL_CONTEXT * const cx = create_eval_scope(0);
cx->blk_eval.retop = cLOGOP->op_other->op_next;
return DOCATCH(PL_op->op_next);
PP(pp_leavetry)
{
- dVAR; dSP;
+ dSP;
SV **newsp;
PMOP *newpm;
I32 gimme;
PERL_CONTEXT *cx;
I32 optype;
+ OP *retop;
PERL_ASYNC_CHECK();
POPBLOCK(cx,newpm);
+ retop = cx->blk_eval.retop;
POPEVAL(cx);
PERL_UNUSED_VAR(optype);
- TAINT_NOT;
- SP = adjust_stack_on_leave(newsp, SP, newsp, gimme,
+ SP = leave_common(newsp, SP, newsp, gimme,
SVs_PADTMP|SVs_TEMP, FALSE);
PL_curpm = newpm; /* Don't pop $1 et al till now */
LEAVE_with_name("eval_scope");
CLEAR_ERRSV();
- RETURN;
+ RETURNOP(retop);
}
PP(pp_entergiven)
{
- dVAR; dSP;
+ dSP;
PERL_CONTEXT *cx;
const I32 gimme = GIMME_V;
ENTER_with_name("given");
SAVETMPS;
- if (PL_op->op_targ) {
- SAVEPADSVANDMORTALIZE(PL_op->op_targ);
- SvREFCNT_dec(PAD_SVl(PL_op->op_targ));
- PAD_SVl(PL_op->op_targ) = SvREFCNT_inc_NN(POPs);
- }
- else {
- SAVE_DEFSV;
- DEFSV_set(POPs);
- }
+ assert(!PL_op->op_targ); /* used to be set for lexical $_ */
+ SAVE_DEFSV;
+ DEFSV_set(POPs);
PUSHBLOCK(cx, CXt_GIVEN, SP);
PUSHGIVEN(cx);
PP(pp_leavegiven)
{
- dVAR; dSP;
+ dSP;
PERL_CONTEXT *cx;
I32 gimme;
SV **newsp;
POPBLOCK(cx,newpm);
assert(CxTYPE(cx) == CXt_GIVEN);
- TAINT_NOT;
- SP = adjust_stack_on_leave(newsp, SP, newsp, gimme,
+ SP = leave_common(newsp, SP, newsp, gimme,
SVs_PADTMP|SVs_TEMP, FALSE);
PL_curpm = newpm; /* Don't pop $1 et al till now */
STATIC PMOP *
S_make_matcher(pTHX_ REGEXP *re)
{
- dVAR;
PMOP *matcher = (PMOP *) newPMOP(OP_MATCH, OPf_WANT_SCALAR | OPf_STACKED);
PERL_ARGS_ASSERT_MAKE_MATCHER;
STATIC bool
S_matcher_matches_sv(pTHX_ PMOP *matcher, SV *sv)
{
- dVAR;
dSP;
+ bool result;
PERL_ARGS_ASSERT_MATCHER_MATCHES_SV;
PUTBACK;
(void) Perl_pp_match(aTHX);
SPAGAIN;
- return (SvTRUEx(POPs));
+ result = SvTRUEx(POPs);
+ PUTBACK;
+
+ return result;
}
STATIC void
S_destroy_matcher(pTHX_ PMOP *matcher)
{
- dVAR;
-
PERL_ARGS_ASSERT_DESTROY_MATCHER;
PERL_UNUSED_ARG(matcher);
STATIC OP *
S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other, const bool copied)
{
- dVAR;
dSP;
bool object_on_left = FALSE;
}
SP -= 2; /* Pop the values */
-
+ PUTBACK;
/* ~~ undef */
if (!SvOK(e)) {
RETPUSHYES;
}
- if (sv_isobject(e) && (SvTYPE(SvRV(e)) != SVt_REGEXP)) {
+ if (SvROK(e) && SvOBJECT(SvRV(e)) && (SvTYPE(SvRV(e)) != SVt_REGEXP)) {
DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Object\n"));
Perl_croak(aTHX_ "Smart matching a non-overloaded object breaks encapsulation");
}
- if (sv_isobject(d) && (SvTYPE(SvRV(d)) != SVt_REGEXP))
+ if (SvROK(d) && SvOBJECT(SvRV(d)) && (SvTYPE(SvRV(d)) != SVt_REGEXP))
object_on_left = TRUE;
/* ~~ sub */
(void) hv_iterinit(hv);
while ( (he = hv_iternext(hv)) ) {
DEBUG_M(Perl_deb(aTHX_ " testing key against pattern...\n"));
+ PUTBACK;
if (matcher_matches_sv(matcher, hv_iterkeysv(he))) {
+ SPAGAIN;
(void) hv_iterinit(hv);
destroy_matcher(matcher);
RETPUSHYES;
}
+ SPAGAIN;
}
destroy_matcher(matcher);
RETPUSHNO;
for(i = 0; i <= this_len; ++i) {
SV * const * const svp = av_fetch(MUTABLE_AV(SvRV(e)), i, FALSE);
DEBUG_M(Perl_deb(aTHX_ " testing element against pattern...\n"));
+ PUTBACK;
if (svp && matcher_matches_sv(matcher, *svp)) {
+ SPAGAIN;
destroy_matcher(matcher);
RETPUSHYES;
}
+ SPAGAIN;
}
destroy_matcher(matcher);
RETPUSHNO;
}
else {
PMOP * const matcher = make_matcher((REGEXP*) SvRV(e));
+ bool result;
DEBUG_M(Perl_deb(aTHX_ " applying rule Any-Regex\n"));
PUTBACK;
- PUSHs(matcher_matches_sv(matcher, d)
- ? &PL_sv_yes
- : &PL_sv_no);
+ result = matcher_matches_sv(matcher, d);
+ SPAGAIN;
+ PUSHs(result ? &PL_sv_yes : &PL_sv_no);
destroy_matcher(matcher);
RETURN;
}
PP(pp_enterwhen)
{
- dVAR; dSP;
+ dSP;
PERL_CONTEXT *cx;
const I32 gimme = GIMME_V;
PP(pp_leavewhen)
{
- dVAR; dSP;
+ dSP;
I32 cxix;
PERL_CONTEXT *cx;
I32 gimme;
POPBLOCK(cx,newpm);
assert(CxTYPE(cx) == CXt_WHEN);
- TAINT_NOT;
- SP = adjust_stack_on_leave(newsp, SP, newsp, gimme,
+ SP = leave_common(newsp, SP, newsp, gimme,
SVs_PADTMP|SVs_TEMP, FALSE);
PL_curpm = newpm; /* pop $1 et al */
PP(pp_continue)
{
- dVAR; dSP;
+ dSP;
I32 cxix;
PERL_CONTEXT *cx;
I32 gimme;
PP(pp_break)
{
- dVAR;
I32 cxix;
PERL_CONTEXT *cx;
static I32
S_run_user_filter(pTHX_ int idx, SV *buf_sv, int maxlen)
{
- dVAR;
SV * const datasv = FILTER_DATA(idx);
const int filter_has_file = IoLINES(datasv);
SV * const filter_state = MUTABLE_SV(IoTOP_GV(datasv));
umaxlen = maxlen;
/* I was having segfault trouble under Linux 2.2.5 after a
- parse error occured. (Had to hack around it with a test
+ parse error occurred. (Had to hack around it with a test
for PL_parser->error_count == 0.) Solaris doesn't segfault --
not sure where the trouble is yet. XXX */
}
/*
- * Local variables:
- * c-indentation-style: bsd
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- *
* ex: set ts=8 sts=4 sw=4 et:
*/