Change 33177 by [EMAIL PROTECTED] on 2008/02/01 21:32:02

        Integrate:
        [ 31582]
        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.
        
        [ 31586]
        Use Perl_croak() rather than DIE() in S_doeval() because "DIE()"
        becomes "return Perl_die()" and Perl_die() returns an OP*, which
        isn't appropriate to return from S_doeval.

Affected files ...

... //depot/maint-5.8/perl/embed.fnc#238 integrate
... //depot/maint-5.8/perl/pp_ctl.c#183 integrate
... //depot/maint-5.8/perl/proto.h#228 integrate
... //depot/maint-5.8/perl/t/op/eval.t#10 integrate

Differences ...

==== //depot/maint-5.8/perl/embed.fnc#238 (text) ====
Index: perl/embed.fnc
--- perl/embed.fnc#237~33168~   2008-02-01 08:10:22.000000000 -0800
+++ perl/embed.fnc      2008-02-01 13:32:02.000000000 -0800
@@ -1246,7 +1246,7 @@
 sR     |I32    |dopoptoloop    |I32 startingblock
 sR     |I32    |dopoptosub_at  |NN const PERL_CONTEXT* cxstk|I32 startingblock
 s      |void   |save_lines     |NULLOK AV *array|NN SV *sv
-sR     |OP*    |doeval         |int gimme|NULLOK OP** startop|NULLOK CV* 
outside|U32 seq
+s      |bool   |doeval         |int gimme|NULLOK OP** startop|NULLOK CV* 
outside|U32 seq
 sR     |PerlIO *|check_type_and_open|NN const char *name
 #ifndef PERL_DISABLE_PMC
 sR     |PerlIO *|doopen_pm     |NN const char *name|const STRLEN namelen

==== //depot/maint-5.8/perl/pp_ctl.c#183 (text) ====
Index: perl/pp_ctl.c
--- perl/pp_ctl.c#182~32384~    2007-11-17 14:34:52.000000000 -0800
+++ perl/pp_ctl.c       2008-02-01 13:32:02.000000000 -0800
@@ -2628,7 +2628,6 @@
     I32 gimme = G_VOID;
     I32 optype;
     OP dummy;
-    OP *rop;
     char tbuf[TYPE_DIGITS(long) + 12 + 10];
     char *tmpbuf = tbuf;
     char *safestr;
@@ -2686,9 +2685,9 @@
     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);
 
@@ -2706,7 +2705,7 @@
     PERL_UNUSED_VAR(newsp);
     PERL_UNUSED_VAR(optype);
 
-    return rop;
+    return PL_eval_start;
 }
 
 
@@ -2754,10 +2753,13 @@
  * 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).
  */
 
 /* With USE_5005THREADS, eval_owner must be held on entry to doeval */
-STATIC OP *
+STATIC bool
 S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
 {
     dSP;
@@ -2836,8 +2838,8 @@
        msg = SvPVx_nolen_const(ERRSV);
        if (optype == OP_REQUIRE) {
             const char* const msg = SvPVx_nolen_const(ERRSV);
-           DIE(aTHX_ "%sCompilation failed in require",
-               *msg ? msg : "Unknown error\n");
+           Perl_croak(aTHX_ "%sCompilation failed in require",
+                      *msg ? msg : "Unknown error\n");
        }
        else if (startop) {
            POPBLOCK(cx,PL_curpm);
@@ -2857,7 +2859,9 @@
        MUTEX_UNLOCK(&PL_eval_mutex);
 #endif /* USE_5005THREADS */
        PERL_UNUSED_VAR(newsp);
-       RETPUSHUNDEF;
+       PUSHs(&PL_sv_undef);
+       PUTBACK;
+       return FALSE;
     }
     CopLINE_set(&PL_compiling, 0);
     if (startop) {
@@ -2907,7 +2911,8 @@
     MUTEX_UNLOCK(&PL_eval_mutex);
 #endif /* USE_5005THREADS */
 
-    RETURNOP(PL_eval_start);
+    PUTBACK;
+    return TRUE;
 }
 
 STATIC PerlIO *
@@ -3417,7 +3422,10 @@
     encoding = PL_encoding;
     PL_encoding = NULL;
 
-    op = DOCATCH(doeval(gimme, NULL, Nullcv, 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;
@@ -3436,7 +3444,7 @@
     char *tmpbuf = tbuf;
     char *safestr;
     STRLEN len;
-    OP *ret;
+    bool ok;
     CV* runcv;
     U32 seq;
     const char * const fakestr = "_<(eval )";
@@ -3512,13 +3520,13 @@
     PL_eval_owner = thr;
     MUTEX_UNLOCK(&PL_eval_mutex);
 #endif /* USE_5005THREADS */
-    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)

==== //depot/maint-5.8/perl/proto.h#228 (text+w) ====
Index: perl/proto.h
--- perl/proto.h#227~33168~     2008-02-01 08:10:22.000000000 -0800
+++ perl/proto.h        2008-02-01 13:32:02.000000000 -0800
@@ -1785,9 +1785,7 @@
                        __attribute__warn_unused_result__;
 
 STATIC void    S_save_lines(pTHX_ AV *array, SV *sv);
-STATIC OP*     S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
-                       __attribute__warn_unused_result__;
-
+STATIC bool    S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq);
 STATIC PerlIO *        S_check_type_and_open(pTHX_ const char *name)
                        __attribute__warn_unused_result__;
 

==== //depot/maint-5.8/perl/t/op/eval.t#10 (xtext) ====
Index: perl/t/op/eval.t
--- perl/t/op/eval.t#9~32394~   2007-11-18 14:16:34.000000000 -0800
+++ perl/t/op/eval.t    2008-02-01 13:32:02.000000000 -0800
@@ -5,7 +5,7 @@
     @INC = '../lib';
 }
 
-print "1..94\n";
+print "1..95\n";
 
 eval 'print "ok 1\n";';
 
@@ -465,3 +465,24 @@
     print "ok $test # eval syntax error, no warnings \n"; $test++;
 }
 
+
+# a syntax error in an eval called magically 9eg vie tie or overload)
+# resulted in an assertion failure in S_docatch, since doeval had already
+# poppedthe EVAL context due to the failure, but S_docatch expected the
+# context to still be there.
+
+{
+    my $ok  = 0;
+    package Eval1;
+    sub STORE { eval '('; $ok = 1 }
+    sub TIESCALAR { bless [] }
+
+    my $x;
+    tie $x, bless [];
+    $x = 1;
+    print "not " unless $ok;
+    print "ok $test # eval docatch \n"; $test++;
+}
+
+
+
End of Patch.

Reply via email to