summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorDave Mitchell <davem@fdisolutions.com>2007-07-10 23:51:58 +0000
committerDave Mitchell <davem@fdisolutions.com>2007-07-10 23:51:58 +0000
commit410be5dba347e0340059d489e15d034982d73278 (patch)
tree693e2b2bdd6ebf4b9c21665d58a6b92260342598 /pp_ctl.c
parent131c565afbb207eedaa0a3a4458b1e0ef2716db7 (diff)
downloadperl-410be5dba347e0340059d489e15d034982d73278.tar.gz
Fix assertion failure on failed magic eval - eg FETCH {eval'('}
S_doeval()'s behaviour varies depending on whether the code compiles or not; on failure it pops the EVAL context block. This is bad because later on, S_docatch() assumes that the block is still there. Make docatch() return a boolean instead, indicating success. The value it formerly returned (the next op) can be deduced as PL_eval_start or PL_op->op_next on success/failure. p4raw-id: //depot/perl@31582
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index c6ee3f77c8..b16d97e388 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -2737,7 +2737,6 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, const char *code, PAD** padp)
I32 gimme = G_VOID;
I32 optype;
OP dummy;
- OP *rop;
char tbuf[TYPE_DIGITS(long) + 12 + 10];
char *tmpbuf = tbuf;
char *safestr;
@@ -2795,9 +2794,9 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, const char *code, PAD** padp)
PUSHEVAL(cx, 0, NULL);
if (runtime)
- rop = doeval(G_SCALAR, startop, runcv, PL_curcop->cop_seq);
+ (void) doeval(G_SCALAR, startop, runcv, PL_curcop->cop_seq);
else
- rop = doeval(G_SCALAR, startop, PL_compcv, PL_cop_seqmax);
+ (void) doeval(G_SCALAR, startop, PL_compcv, PL_cop_seqmax);
POPBLOCK(cx,PL_curpm);
POPEVAL(cx);
@@ -2815,7 +2814,7 @@ Perl_sv_compile_2op(pTHX_ SV *sv, OP** startop, const char *code, PAD** padp)
PERL_UNUSED_VAR(newsp);
PERL_UNUSED_VAR(optype);
- return rop;
+ return PL_eval_start;
}
@@ -2864,9 +2863,12 @@ Perl_find_runcv(pTHX_ U32 *db_seqp)
* In the last case, startop is non-null, and contains the address of
* a pointer that should be set to the just-compiled code.
* outside is the lexically enclosing CV (if any) that invoked us.
+ * 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).
*/
-STATIC OP *
+STATIC bool
S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
{
dVAR; dSP;
@@ -2963,7 +2965,9 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
}
}
PERL_UNUSED_VAR(newsp);
- RETPUSHUNDEF;
+ PUSHs(&PL_sv_undef);
+ PUTBACK;
+ return FALSE;
}
CopLINE_set(&PL_compiling, 0);
if (startop) {
@@ -3010,7 +3014,8 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
PL_op = saveop; /* The caller may need it. */
PL_parser->lex_state = LEX_NOTPARSING; /* $^S needs this. */
- RETURNOP(PL_eval_start);
+ PUTBACK;
+ return TRUE;
}
STATIC PerlIO *
@@ -3410,7 +3415,10 @@ PP(pp_require)
encoding = PL_encoding;
PL_encoding = NULL;
- op = DOCATCH(doeval(gimme, NULL, NULL, PL_curcop->cop_seq));
+ if (doeval(gimme, NULL, NULL, PL_curcop->cop_seq))
+ op = DOCATCH(PL_eval_start);
+ else
+ op = PL_op->op_next;
/* Restore encoding. */
PL_encoding = encoding;
@@ -3429,7 +3437,7 @@ PP(pp_entereval)
char *tmpbuf = tbuf;
char *safestr;
STRLEN len;
- OP *ret;
+ bool ok;
CV* runcv;
U32 seq;
HV *saved_hh = NULL;
@@ -3502,13 +3510,13 @@ PP(pp_entereval)
if (PERLDB_LINE && PL_curstash != PL_debstash)
save_lines(CopFILEAV(&PL_compiling), PL_parser->linestr);
PUTBACK;
- ret = doeval(gimme, NULL, runcv, seq);
+ ok = doeval(gimme, NULL, runcv, seq);
if (PERLDB_INTER && was != (I32)PL_sub_generation /* Some subs defined here. */
- && ret != PL_op->op_next) { /* Successive compilation. */
+ && ok) {
/* Copy in anything fake and short. */
my_strlcpy(safestr, fakestr, fakelen);
}
- return DOCATCH(ret);
+ return ok ? DOCATCH(PL_eval_start) : PL_op->op_next;
}
PP(pp_leaveeval)