/* pp_ctl.c
*
- * Copyright (c) 1991-1994, Larry Wall
+ * Copyright (c) 1991-1997, Larry Wall
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
#define WORD_ALIGN sizeof(U16)
#endif
-#define DOCATCH(o) (mustcatch ? docatch(o) : (o))
+#define DOCATCH(o) ((CATCH_GET == TRUE) ? docatch(o) : (o))
static OP *docatch _((OP *o));
static OP *doeval _((int gimme));
if (cxix < 0)
RETPUSHUNDEF;
- if (cxstack[cxix].blk_gimme == G_ARRAY)
+ switch (cxstack[cxix].blk_gimme) {
+ case G_ARRAY:
RETPUSHYES;
- else
+ case G_SCALAR:
RETPUSHNO;
+ default:
+ RETPUSHUNDEF;
+ }
}
PP(pp_regcmaybe)
if (!cx->sb_rxtainted)
cx->sb_rxtainted = SvTAINTED(TOPs);
sv_catsv(dstr, POPs);
- if (rx->subbase)
- Safefree(rx->subbase);
- rx->subbase = cx->sb_subbase;
/* Are we done */
if (cx->sb_once || !pregexec(rx, s, cx->sb_strend, orig,
SvLEN_set(targ, SvLEN(dstr));
SvPVX(dstr) = 0;
sv_free(dstr);
-
(void)SvPOK_only(targ);
SvSETMAGIC(targ);
SvTAINT(targ);
+
PUSHs(sv_2mortal(newSViv((I32)cx->sb_iters - 1)));
LEAVE_SCOPE(cx->sb_oldsave);
POPSUBST(cx);
cx->sb_m = m = rx->startp[0];
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);
}
if (stack_base + *markstack_ptr == sp) {
(void)POPMARK;
- if (GIMME != G_ARRAY)
+ if (GIMME_V == G_SCALAR)
XPUSHs(&sv_no);
RETURNOP(op->op_next->op_next);
}
/* All done yet? */
if (markstack_ptr[-1] > *markstack_ptr) {
I32 items;
+ I32 gimme = GIMME_V;
(void)POPMARK; /* pop top */
LEAVE; /* exit outer scope */
items = --*markstack_ptr - markstack_ptr[-1];
(void)POPMARK; /* pop dst */
SP = stack_base + POPMARK; /* pop original mark */
- if (GIMME != G_ARRAY) {
+ if (gimme == G_SCALAR) {
dTARGET;
XPUSHi(items);
- RETURN;
}
- SP += items;
+ else if (gimme == G_ARRAY)
+ SP += items;
RETURN;
}
else {
AV *oldstack;
CONTEXT *cx;
SV** newsp;
- bool oldmustcatch = mustcatch;
+ bool oldcatch = CATCH_GET;
SAVETMPS;
SAVESPTR(op);
AvREAL_off(sortstack);
av_extend(sortstack, 32);
}
- mustcatch = TRUE;
+ CATCH_SET(TRUE);
SWITCHSTACK(curstack, sortstack);
if (sortstash != stash) {
firstgv = gv_fetchpv("a", TRUE, SVt_PV);
POPBLOCK(cx,curpm);
SWITCHSTACK(sortstack, oldstack);
- mustcatch = oldmustcatch;
+ CATCH_SET(oldcatch);
}
LEAVE;
}
case CXt_LOOP:
if (!cx->blk_loop.label ||
strNE(label, cx->blk_loop.label) ) {
- DEBUG_l(deb("(Skipping label #%d %s)\n",
- i, cx->blk_loop.label));
+ DEBUG_l(deb("(Skipping label #%ld %s)\n",
+ (long)i, cx->blk_loop.label));
continue;
}
- DEBUG_l( deb("(Found label #%d %s)\n", i, label));
+ DEBUG_l( deb("(Found label #%ld %s)\n", (long)i, label));
return i;
}
}
I32
dowantarray()
{
+ I32 gimme = block_gimme();
+ return (gimme == G_VOID) ? G_SCALAR : gimme;
+}
+
+I32
+block_gimme()
+{
I32 cxix;
cxix = dopoptosub(cxstack_ix);
if (cxix < 0)
return G_SCALAR;
- if (cxstack[cxix].blk_gimme == G_ARRAY)
- return G_ARRAY;
- else
+ switch (cxstack[cxix].blk_gimme) {
+ case G_VOID:
+ return G_VOID;
+ case G_SCALAR:
return G_SCALAR;
+ case G_ARRAY:
+ return G_ARRAY;
+ default:
+ croak("panic: bad gimme: %d\n", cxstack[cxix].blk_gimme);
+ }
}
static I32
continue;
case CXt_EVAL:
case CXt_SUB:
- DEBUG_l( deb("(Found sub #%d)\n", i));
+ DEBUG_l( deb("(Found sub #%ld)\n", (long)i));
return i;
}
}
default:
continue;
case CXt_EVAL:
- DEBUG_l( deb("(Found eval #%d)\n", i));
+ DEBUG_l( deb("(Found eval #%ld)\n", (long)i));
return i;
}
}
warn("Exiting pseudo-block via %s", op_name[op->op_type]);
return -1;
case CXt_LOOP:
- DEBUG_l( deb("(Found loop #%d)\n", i));
+ DEBUG_l( deb("(Found loop #%ld)\n", (long)i));
return i;
}
}
LEAVE;
- if (optype == OP_REQUIRE)
- DIE("%s", SvPVx(GvSV(errgv), na));
+ if (optype == OP_REQUIRE) {
+ char* msg = SvPVx(GvSV(errgv), na);
+ DIE("%s", *msg ? msg : "Compilation failed in require");
+ }
return pop_return();
}
}
register I32 cxix = dopoptosub(cxstack_ix);
register CONTEXT *cx;
I32 dbcxix;
+ I32 gimme;
SV *sv;
I32 count = 0;
PUSHs(sv_2mortal(newSVpv("(eval)",0)));
PUSHs(sv_2mortal(newSViv(0)));
}
- PUSHs(sv_2mortal(newSViv((I32)cx->blk_gimme)));
+ gimme = (I32)cx->blk_gimme;
+ if (gimme == G_VOID)
+ PUSHs(&sv_undef);
+ else
+ PUSHs(sv_2mortal(newSViv(gimme & G_ARRAY)));
if (cx->cx_type == CXt_EVAL) {
if (cx->blk_eval.old_op_type == OP_ENTEREVAL) {
PUSHs(cx->blk_eval.cur_text);
const void *a;
const void *b;
{
- SV **str1 = (SV **) a;
- SV **str2 = (SV **) b;
+ SV * const *str1 = (SV * const *)a;
+ SV * const *str2 = (SV * const *)b;
I32 oldsaveix = savestack_ix;
I32 oldscopeix = scopestack_ix;
I32 result;
const void *a;
const void *b;
{
- return sv_cmp(*(SV **)a, *(SV **)b);
+ return sv_cmp(*(SV * const *)a, *(SV * const *)b);
}
static int
const void *a;
const void *b;
{
- return sv_cmp_locale(*(SV **)a, *(SV **)b);
+ return sv_cmp_locale(*(SV * const *)a, *(SV * const *)b);
}
PP(pp_reset)
{
dSP; dMARK;
register CONTEXT *cx;
- I32 gimme = GIMME;
+ I32 gimme = GIMME_V;
SV **svp;
ENTER;
{
dSP;
register CONTEXT *cx;
- I32 gimme = GIMME;
+ I32 gimme = GIMME_V;
ENTER;
SAVETMPS;
mark = newsp;
POPLOOP1(cx); /* Delay POPLOOP2 until stack values are safe */
- if (gimme == G_SCALAR) {
- if (op->op_private & OPpLEAVE_VOID)
- ;
- else {
- if (mark < SP)
- *++newsp = sv_mortalcopy(*SP);
- else
- *++newsp = &sv_undef;
- }
+ if (gimme == G_VOID)
+ ; /* do nothing */
+ else if (gimme == G_SCALAR) {
+ if (mark < SP)
+ *++newsp = sv_mortalcopy(*SP);
+ else
+ *++newsp = &sv_undef;
}
else {
while (mark < SP)
if (optype == OP_REQUIRE &&
(MARK == SP || (gimme == G_SCALAR && !SvTRUE(*SP))) )
{
+ /* Unassume the success we assumed earlier. */
char *name = cx->blk_eval.old_name;
(void)hv_delete(GvHVn(incgv), name, strlen(name), G_DISCARD);
DIE("%s did not return a true value", name);
break;
default:
DIE("panic: return");
- break;
}
if (gimme == G_SCALAR) {
else
*++newsp = &sv_undef;
}
- else {
+ else if (gimme == G_ARRAY) {
while (++MARK <= SP)
*++newsp = (popsub2 && SvTEMP(*MARK))
? *MARK : sv_mortalcopy(*MARK);
break;
default:
DIE("panic: last");
- break;
}
if (gimme == G_SCALAR) {
else
*++newsp = &sv_undef;
}
- else {
+ else if (gimme == G_ARRAY) {
while (++MARK <= SP)
*++newsp = ((pop2 == CXt_SUB) && SvTEMP(*MARK))
? *MARK : sv_mortalcopy(*MARK);
break;
case CXt_NULL:
DIE("Can't \"goto\" outside a block");
- break;
default:
if (ix)
DIE("panic: goto");
- else
- gotoprobe = main_root;
+ gotoprobe = main_root;
break;
}
retop = dofindlabel(gotoprobe, label, enterops);
if (curstack == signalstack) {
restartop = retop;
- Siglongjmp(top_env, 3);
+ JMPENV_JUMP(3);
}
RETURNOP(retop);
OP *o;
{
int ret;
- int oldrunlevel = runlevel;
+ I32 oldrunlevel = runlevel;
OP *oldop = op;
- Sigjmp_buf oldtop;
+ dJMPENV;
op = o;
- Copy(top_env, oldtop, 1, Sigjmp_buf);
#ifdef DEBUGGING
- assert(mustcatch == TRUE);
+ assert(CATCH_GET == TRUE);
+ DEBUG_l(deb("(Setting up local jumplevel, runlevel = %ld)\n", (long)runlevel+1));
#endif
- mustcatch = FALSE;
- switch ((ret = Sigsetjmp(top_env,1))) {
+ JMPENV_PUSH(ret);
+ switch (ret) {
default: /* topmost level handles it */
- Copy(oldtop, top_env, 1, Sigjmp_buf);
+ JMPENV_POP;
runlevel = oldrunlevel;
- mustcatch = TRUE;
op = oldop;
- Siglongjmp(top_env, ret);
+ JMPENV_JUMP(ret);
/* NOTREACHED */
case 3:
if (!restartop) {
PerlIO_printf(PerlIO_stderr(), "panic: restartop\n");
break;
}
- mustcatch = FALSE;
op = restartop;
restartop = 0;
/* FALL THROUGH */
runops();
break;
}
- Copy(oldtop, top_env, 1, Sigjmp_buf);
+ JMPENV_POP;
runlevel = oldrunlevel;
- mustcatch = TRUE;
op = oldop;
return Nullop;
}
pop_return();
lex_end();
LEAVE;
- if (optype == OP_REQUIRE)
- DIE("%s", SvPVx(GvSV(errgv), na));
+ if (optype == OP_REQUIRE) {
+ char* msg = SvPVx(GvSV(errgv), na);
+ DIE("%s", *msg ? msg : "Compilation failed in require");
+ }
SvREFCNT_dec(rs);
rs = SvREFCNT_inc(nrs);
RETPUSHUNDEF;
rs = SvREFCNT_inc(nrs);
compiling.cop_line = 0;
SAVEFREEOP(eval_root);
- if (gimme & G_ARRAY)
+ if (gimme & G_VOID)
+ scalarvoid(eval_root);
+ else if (gimme & G_ARRAY)
list(eval_root);
else
scalar(eval_root);
dSP;
register CONTEXT *cx;
dPOPss;
- I32 gimme = GIMME, was = sub_generation;
+ I32 gimme = GIMME_V, was = sub_generation;
char tmpbuf[32], *safestr;
STRLEN len;
OP *ret;
POPEVAL(cx);
retop = pop_return();
- if (gimme == G_SCALAR) {
- if (op->op_private & OPpLEAVE_VOID)
- MARK = newsp;
+ if (gimme == G_VOID)
+ MARK = newsp;
+ else if (gimme == G_SCALAR) {
+ MARK = newsp + 1;
+ if (MARK <= SP) {
+ if (SvFLAGS(TOPs) & SVs_TEMP)
+ *MARK = TOPs;
+ else
+ *MARK = sv_mortalcopy(TOPs);
+ }
else {
- MARK = newsp + 1;
- if (MARK <= SP) {
- if (SvFLAGS(TOPs) & SVs_TEMP)
- *MARK = TOPs;
- else
- *MARK = sv_mortalcopy(TOPs);
- }
- else {
- MEXTEND(mark,0);
- *MARK = &sv_undef;
- }
+ MEXTEND(mark,0);
+ *MARK = &sv_undef;
}
- SP = MARK;
}
else {
for (mark = newsp + 1; mark <= SP; mark++)
CvDEPTH(compcv) = 0;
if (optype == OP_REQUIRE &&
- !(gimme == G_SCALAR ? SvTRUE(*sp) : sp > newsp)) {
- char *name = cx->blk_eval.old_name;
-
+ !(gimme == G_SCALAR ? SvTRUE(*sp) : sp > newsp))
+ {
/* Unassume the success we assumed earlier. */
+ char *name = cx->blk_eval.old_name;
(void)hv_delete(GvHVn(incgv), name, strlen(name), G_DISCARD);
retop = die("%s did not return a true value", name);
}
{
dSP;
register CONTEXT *cx;
- I32 gimme = GIMME;
+ I32 gimme = GIMME_V;
ENTER;
SAVETMPS;
POPEVAL(cx);
pop_return();
- if (gimme == G_SCALAR) {
- if (op->op_private & OPpLEAVE_VOID)
- MARK = newsp;
+ if (gimme == G_VOID)
+ SP = newsp;
+ else if (gimme == G_SCALAR) {
+ MARK = newsp + 1;
+ if (MARK <= SP) {
+ if (SvFLAGS(TOPs) & (SVs_PADTMP|SVs_TEMP))
+ *MARK = TOPs;
+ else
+ *MARK = sv_mortalcopy(TOPs);
+ }
else {
- MARK = newsp + 1;
- if (MARK <= SP) {
- if (SvFLAGS(TOPs) & (SVs_PADTMP|SVs_TEMP))
- *MARK = TOPs;
- else
- *MARK = sv_mortalcopy(TOPs);
- }
- else {
- MEXTEND(mark,0);
- *MARK = &sv_undef;
- }
+ MEXTEND(mark,0);
+ *MARK = &sv_undef;
}
SP = MARK;
}