if (cx->sb_iters > cx->sb_maxiters)
DIE("Substitution loop");
+ if (!cx->sb_rxtainted)
+ cx->sb_rxtainted = SvTAINTED(TOPs);
sv_catsv(dstr, POPs);
if (rx->subbase)
Safefree(rx->subbase);
(void)SvPOK_only(targ);
SvSETMAGIC(targ);
+ if (cx->sb_rxtainted)
+ SvTAINTED_on(targ);
PUSHs(sv_2mortal(newSViv((I32)cx->sb_iters - 1)));
LEAVE_SCOPE(cx->sb_oldsave);
POPSUBST(cx);
sv_catpvn(dstr, s, m-s);
cx->sb_s = rx->endp[0];
cx->sb_subbase = rx->subbase;
+ cx->sb_rxtainted |= rx->exec_tainted;
rx->subbase = Nullch; /* so recursion works */
RETURNOP(pm->op_pmreplstart);
gotsome = TRUE;
value = SvNV(sv);
/* Formats aren't yet marked for locales, so assume "yes". */
- NUMERIC_LOCAL();
+ SET_NUMERIC_LOCAL();
if (arg & 256) {
sprintf(t, "%#*.*f", (int) fieldsize, (int) arg & 255, value);
} else {
while (MARK < SP) { /* This may or may not shift down one here. */
/*SUPPRESS 560*/
if (*up = *++MARK) { /* Weed out nulls. */
- if (!SvPOK(*up))
+ SvTEMP_off(*up);
+ if (!sortcop && !SvPOK(*up))
(void)sv_2pv(*up, &na);
- else
- SvTEMP_off(*up);
up++;
}
}
SAVESPTR(GvSV(firstgv));
SAVESPTR(GvSV(secondgv));
- PUSHBLOCK(cx, CXt_LOOP, stack_base);
+ PUSHBLOCK(cx, CXt_NULL, stack_base);
sortcxix = cxstack_ix;
qsort((char*)(myorigmark+1), max, sizeof(SV*), sortcv);
if (dowarn)
warn("Exiting eval via %s", op_name[op->op_type]);
break;
+ case CXt_NULL:
+ if (dowarn)
+ warn("Exiting pseudo-block via %s", op_name[op->op_type]);
+ return -1;
case CXt_LOOP:
if (!cx->blk_loop.label ||
strNE(label, cx->blk_loop.label) ) {
switch (cx->cx_type) {
case CXt_SUBST:
if (dowarn)
- warn("Exiting substitition via %s", op_name[op->op_type]);
+ warn("Exiting substitution via %s", op_name[op->op_type]);
break;
case CXt_SUB:
if (dowarn)
if (dowarn)
warn("Exiting eval via %s", op_name[op->op_type]);
break;
+ case CXt_NULL:
+ if (dowarn)
+ warn("Exiting pseudo-block via %s", op_name[op->op_type]);
+ return -1;
case CXt_LOOP:
DEBUG_l( deb("(Found loop #%d)\n", i));
return i;
case CXt_LOOP:
POPLOOP(cx);
break;
+ case CXt_NULL:
case CXt_SUBST:
break;
}
}
}
-#ifdef I_STDARG
-OP *
-die(char* pat, ...)
-#else
-/*VARARGS0*/
-OP *
-die(pat, va_alist)
- char *pat;
- va_dcl
-#endif
-{
- va_list args;
- char *message;
- int oldrunlevel = runlevel;
- int was_in_eval = in_eval;
- HV *stash;
- GV *gv;
- CV *cv;
-
- /* We have to switch back to mainstack or die_where may try to pop
- * the eval block from the wrong stack if die is being called from a
- * signal handler. - dkindred@cs.cmu.edu */
- if (curstack != mainstack) {
- dSP;
- SWITCHSTACK(curstack, mainstack);
- }
-#ifdef I_STDARG
- va_start(args, pat);
-#else
- va_start(args);
-#endif
- message = mess(pat, &args);
- va_end(args);
- if (diehook && (cv = sv_2cv(diehook, &stash, &gv, 0)) && !CvDEPTH(cv)) {
- dSP;
-
- PUSHMARK(sp);
- EXTEND(sp, 1);
- PUSHs(sv_2mortal(newSVpv(message,0)));
- PUTBACK;
- perl_call_sv((SV*)cv, G_DISCARD);
- message = mess(pat, &args); /* Static buffer could be reused. */
- }
- restartop = die_where(message);
- if ((!restartop && was_in_eval) || oldrunlevel > 1)
- Siglongjmp(top_env, 3);
- return restartop;
-}
-
OP *
die_where(message)
char *message;
}
PerlIO_printf(PerlIO_stderr(), "%s",message);
PerlIO_flush(PerlIO_stderr());
- if (e_tmpname) {
- if (e_fp) {
- PerlIO_close(e_fp);
- e_fp = Nullfp;
- }
- (void)UNLINK(e_tmpname);
- Safefree(e_tmpname);
- e_tmpname = Nullch;
- }
- statusvalue = SHIFTSTATUS(statusvalue);
-#ifdef VMS
- my_exit((U32)vaxc$errno?vaxc$errno:errno?errno:statusvalue?statusvalue:SS$_ABORT);
-#else
- my_exit((I32)((errno&255)?errno:((statusvalue&255)?statusvalue:255)));
-#endif
+ my_failure_exit();
+ /* NOTREACHED */
return 0;
}
PUSHBLOCK(cx, CXt_LOOP, SP);
PUSHLOOP(cx, svp, MARK);
- if (op->op_flags & OPf_STACKED) {
- AV* av = (AV*)POPs;
- cx->blk_loop.iterary = av;
- cx->blk_loop.iterix = -1;
- }
+ if (op->op_flags & OPf_STACKED)
+ cx->blk_loop.iterary = (AV*)SvREFCNT_inc(POPs);
else {
cx->blk_loop.iterary = curstack;
AvFILL(curstack) = sp - stack_base;
{
dSP;
register CONTEXT *cx;
+ struct block_loop cxloop;
I32 gimme;
SV **newsp;
PMOP *newpm;
POPBLOCK(cx,newpm);
mark = newsp;
- POPLOOP(cx);
+ POPLOOP1(cx); /* Delay POPLOOP2 until stack values are safe */
+
if (gimme == G_SCALAR) {
if (op->op_private & OPpLEAVE_VOID)
;
while (mark < SP)
*++newsp = sv_mortalcopy(*++mark);
}
- curpm = newpm; /* Don't pop $1 et al till now */
- sp = newsp;
+ SP = newsp;
+ PUTBACK;
+
+ POPLOOP2(); /* Stack values are safe: release loop vars ... */
+ curpm = newpm; /* ... and pop $1 et al */
+
LEAVE;
LEAVE;
- RETURN;
+ return NORMAL;
}
PP(pp_return)
dSP; dMARK;
I32 cxix;
register CONTEXT *cx;
+ struct block_sub cxsub;
+ bool popsub2 = FALSE;
I32 gimme;
SV **newsp;
PMOP *newpm;
POPBLOCK(cx,newpm);
switch (cx->cx_type) {
case CXt_SUB:
- POPSUB(cx);
+ POPSUB1(cx); /* Delay POPSUB2 until stack values are safe */
+ popsub2 = TRUE;
break;
case CXt_EVAL:
POPEVAL(cx);
if (gimme == G_SCALAR) {
if (MARK < SP)
- *++newsp = sv_mortalcopy(*SP);
+ *++newsp = (popsub2 && SvTEMP(*SP))
+ ? *SP : sv_mortalcopy(*SP);
else
*++newsp = &sv_undef;
}
else {
- while (MARK < SP)
- *++newsp = sv_mortalcopy(*++MARK);
+ while (++MARK <= SP)
+ *++newsp = (popsub2 && SvTEMP(*MARK))
+ ? *MARK : sv_mortalcopy(*MARK);
}
- curpm = newpm; /* Don't pop $1 et al till now */
stack_sp = newsp;
+ /* Stack values are safe: */
+ if (popsub2) {
+ POPSUB2(); /* release CV and @_ ... */
+ }
+ curpm = newpm; /* ... and pop $1 et al */
+
LEAVE;
return pop_return();
}
dSP;
I32 cxix;
register CONTEXT *cx;
+ struct block_loop cxloop;
+ struct block_sub cxsub;
+ I32 pop2 = 0;
I32 gimme;
I32 optype;
OP *nextop;
POPBLOCK(cx,newpm);
switch (cx->cx_type) {
case CXt_LOOP:
- POPLOOP(cx);
- nextop = cx->blk_loop.last_op->op_next;
- LEAVE;
+ POPLOOP1(cx); /* Delay POPLOOP2 until stack values are safe */
+ pop2 = CXt_LOOP;
+ nextop = cxloop.last_op->op_next;
break;
- case CXt_EVAL:
- POPEVAL(cx);
+ case CXt_SUB:
+ POPSUB1(cx); /* Delay POPSUB2 until stack values are safe */
+ pop2 = CXt_SUB;
nextop = pop_return();
break;
- case CXt_SUB:
- POPSUB(cx);
+ case CXt_EVAL:
+ POPEVAL(cx);
nextop = pop_return();
break;
default:
}
if (gimme == G_SCALAR) {
- if (mark < SP)
- *++newsp = sv_mortalcopy(*SP);
+ if (MARK < SP)
+ *++newsp = ((pop2 == CXt_SUB) && SvTEMP(*SP))
+ ? *SP : sv_mortalcopy(*SP);
else
*++newsp = &sv_undef;
}
else {
- while (mark < SP)
- *++newsp = sv_mortalcopy(*++mark);
+ while (++MARK <= SP)
+ *++newsp = ((pop2 == CXt_SUB) && SvTEMP(*MARK))
+ ? *MARK : sv_mortalcopy(*MARK);
}
- curpm = newpm; /* Don't pop $1 et al till now */
- sp = newsp;
+ SP = newsp;
+ PUTBACK;
+
+ /* Stack values are safe: */
+ switch (pop2) {
+ case CXt_LOOP:
+ POPLOOP2(); /* release loop vars ... */
+ LEAVE;
+ break;
+ case CXt_SUB:
+ POPSUB2(); /* release CV and @_ ... */
+ break;
+ }
+ curpm = newpm; /* ... and pop $1 et al */
LEAVE;
- RETURNOP(nextop);
+ return nextop;
}
PP(pp_next)
EXTEND(stack_sp, items); /* @_ could have been extended. */
Copy(AvARRAY(av), stack_sp, items, SV*);
stack_sp += items;
+ SvREFCNT_dec(GvAV(defgv));
GvAV(defgv) = cx->blk_sub.savearray;
AvREAL_off(av);
av_clear(av);
(void)SvREFCNT_inc(cv);
else { /* save temporaries on recursion? */
if (CvDEPTH(cv) == 100 && dowarn)
- warn("Deep recursion on subroutine \"%s\"",
- GvENAME(CvGV(cv)));
+ sub_crush_depth(cv);
if (CvDEPTH(cv) > AvFILL(padlist)) {
AV *newpad = newAV();
SV **oldpad = AvARRAY(svp[CvDEPTH(cv)-1]);
for ( ;ix > 0; ix--) {
if (svp[ix] != &sv_undef) {
char *name = SvPVX(svp[ix]);
- if (SvFLAGS(svp[ix]) & SVf_FAKE) {
- /* outer lexical? */
+ if ((SvFLAGS(svp[ix]) & SVf_FAKE)
+ || *name == '&')
+ {
+ /* outer lexical or anon code */
av_store(newpad, ix,
SvREFCNT_inc(oldpad[ix]) );
}
cx->blk_sub.savearray = GvAV(defgv);
cx->blk_sub.argarray = av;
- GvAV(defgv) = cx->blk_sub.argarray;
+ GvAV(defgv) = (AV*)SvREFCNT_inc(av);
++mark;
if (items >= AvMAX(av) + 1) {
}
}
if (perldb && curstash != debstash) {
- /* &xsub is not copying @_ */
+ /*
+ * We do not care about using sv to call CV;
+ * it's for informational purposes only.
+ */
SV *sv = GvSV(DBsub);
save_item(sv);
gv_efullname3(sv, CvGV(cv), Nullch);
- /* We do not care about using sv to call CV,
- * just for info. */
}
RETURNOP(CvSTART(cv));
}
else
gotoprobe = main_root;
break;
+ case CXt_NULL:
+ DIE("Can't \"goto\" outside a block");
+ break;
default:
if (ix)
DIE("panic: goto");
dSP;
OP *saveop = op;
HV *newstash;
+ CV *caller;
AV* comppadlist;
in_eval = 1;
SAVEI32(min_intro_pending);
SAVEI32(max_intro_pending);
+ caller = compcv;
SAVESPTR(compcv);
compcv = (CV*)NEWSV(1104,0);
sv_upgrade((SV *)compcv, SVt_PVCV);
+ CvUNIQUE_on(compcv);
comppad = newAV();
comppad_name = newAV();
av_store(comppadlist, 0, (SV*)comppad_name);
av_store(comppadlist, 1, (SV*)comppad);
CvPADLIST(compcv) = comppadlist;
+
+ if (saveop->op_type != OP_REQUIRE)
+ CvOUTSIDE(compcv) = (CV*)SvREFCNT_inc(caller);
+
SAVEFREESV(compcv);
/* make sure we compile in the right package */
DEBUG_x(dump_eval());
/* Register with debugger: */
-
if (perldb && saveop->op_type == OP_REQUIRE) {
CV *cv = perl_get_cv("DB::postponed", FALSE);
-
if (cv) {
dSP;
PUSHMARK(sp);
/* compiled okay, so do it */
+ CvDEPTH(compcv) = 1;
+
SP = stack_base + POPMARK; /* pop original mark */
RETURNOP(eval_start);
}
sv = POPs;
if (SvNIOKp(sv) && !SvPOKp(sv)) {
- NUMERIC_STANDARD();
+ SET_NUMERIC_STANDARD();
if (atof(patchlevel) + 0.00000999 < SvNV(sv))
DIE("Perl %s required--this is only version %s, stopped",
SvPV(sv,na),patchlevel);
}
curpm = newpm; /* Don't pop $1 et al till now */
+#ifdef DEBUGGING
+ assert(CvDEPTH(compcv) == 1);
+#endif
+ CvDEPTH(compcv) = 0;
+
if (optype == OP_REQUIRE &&
!(gimme == G_SCALAR ? SvTRUE(*sp) : sp > newsp)) {
char *name = cx->blk_eval.old_name;
lex_end();
LEAVE;
+
if (!(save_flags & OPf_SPECIAL))
sv_setpv(GvSV(errgv),"");
skipspaces++;
arg -= skipspaces;
if (arg) {
- if (postspace) {
+ if (postspace)
*fpc++ = FF_SPACE;
- postspace = FALSE;
- }
*fpc++ = FF_LITERAL;
*fpc++ = arg;
}
+ postspace = FALSE;
if (s <= send)
skipspaces--;
if (skipspaces) {