Change 27742 by [EMAIL PROTECTED] on 2006/04/08 17:28:28

        Integrate:
        [ 27615]
        If constant folding fails, don't fold constants, rather than reporting
        the error at compile time. This allows illegal constant expressions in
        dead code to be ignored.
        
        [ 27616]
        It helps to actually add the files you add to MANIFEST. (Thanks Dave
        for spotting my mistake).

Affected files ...

... //depot/maint-5.8/perl/MANIFEST#280 integrate
... //depot/maint-5.8/perl/op.c#125 integrate
... //depot/maint-5.8/perl/pod/perldiag.pod#85 integrate
... //depot/maint-5.8/perl/pod/perltodo.pod#22 integrate
... //depot/maint-5.8/perl/t/comp/fold.t#1 branch

Differences ...

==== //depot/maint-5.8/perl/MANIFEST#280 (text) ====
Index: perl/MANIFEST
--- perl/MANIFEST#279~27604~    2006-03-25 07:15:28.000000000 -0800
+++ perl/MANIFEST       2006-04-08 10:28:28.000000000 -0700
@@ -2540,6 +2540,7 @@
 t/comp/cpp.aux                 main file for cpp.t
 t/comp/cpp.t                   See if C preprocessor works
 t/comp/decl.t                  See if declarations work
+t/comp/fold.t                  See if constant folding works
 t/comp/hints.t                 See if %^H works
 t/comp/multiline.t             See if multiline strings work
 t/comp/opsubs.t                        See if q() etc. are not parsed as 
functions

==== //depot/maint-5.8/perl/op.c#125 (text) ====
Index: perl/op.c
--- perl/op.c#124~27310~        2006-02-24 05:20:45.000000000 -0800
+++ perl/op.c   2006-04-08 10:28:28.000000000 -0700
@@ -2065,6 +2065,10 @@
     register OP *curop;
     I32 type = o->op_type;
     SV *sv;
+    int ret = 0;
+    I32 oldscope;
+    OP *old_next;
+    dJMPENV;
 
     if (PL_opargs[type] & OA_RETSCALAR)
        scalar(o);
@@ -2118,22 +2122,78 @@
     }
 
     curop = LINKLIST(o);
+    old_next = o->op_next;
     o->op_next = 0;
     PL_op = curop;
-    CALLRUNOPS(aTHX);
-    sv = *(PL_stack_sp--);
-    if (o->op_targ && sv == PAD_SV(o->op_targ))        /* grab pad temp? */
-       pad_swipe(o->op_targ,  FALSE);
-    else if (SvTEMP(sv)) {                     /* grab mortal temp? */
-       (void)SvREFCNT_inc(sv);
-       SvTEMP_off(sv);
+
+    oldscope = PL_scopestack_ix;
+
+       /* we're trying to emulate pp_entertry() here */
+       {
+           register PERL_CONTEXT *cx;
+           const I32 gimme = GIMME_V;
+       
+           ENTER;
+           SAVETMPS;
+       
+           PUSHBLOCK(cx, (CXt_EVAL|CXp_TRYBLOCK), PL_stack_sp);
+           PUSHEVAL(cx, 0, 0);
+           PL_eval_root = PL_op;             /* Only needed so that goto works 
right. */
+       
+           PL_in_eval = EVAL_INEVAL;
+           sv_setpvn(ERRSV,"",0);
+       }
+    JMPENV_PUSH(ret);
+
+    switch (ret) {
+    case 0:
+       CALLRUNOPS(aTHX);
+       sv = *(PL_stack_sp--);
+       if (o->op_targ && sv == PAD_SV(o->op_targ))     /* grab pad temp? */
+           pad_swipe(o->op_targ,  FALSE);
+       else if (SvTEMP(sv)) {                  /* grab mortal temp? */
+           SvREFCNT_inc(sv);
+           SvTEMP_off(sv);
+       }
+       break;
+    case 3:
+       /* Something tried to die.  Abandon constant folding.  */
+       /* Pretend the error never happened.  */
+       sv_setpvn(ERRSV,"",0);
+       o->op_next = old_next;
+       break;
+    default:
+       JMPENV_POP;
+       /* Don't expect 1 (setjmp failed) or 2 (something called my_exit)  */
+       Perl_croak(aTHX_ "panic: fold_constants JMPENV_PUSH returned %d", ret);
+    }
+
+    JMPENV_POP;
+    if (PL_scopestack_ix > oldscope) {
+       SV **newsp;
+       PMOP *newpm;
+       I32 gimme;
+       register PERL_CONTEXT *cx;
+       I32 optype;
+       
+       POPBLOCK(cx,newpm);
+           POPEVAL(cx);
+           PL_curpm = newpm;
+           LEAVE;
+           PERL_UNUSED_VAR(newsp);
+           PERL_UNUSED_VAR(gimme);
+           PERL_UNUSED_VAR(optype);
     }
+
+    if (ret)
+       goto nope;
+
     op_free(o);
     if (type == OP_RV2GV)
        return newGVOP(OP_GV, 0, (GV*)sv);
     return newSVOP(OP_CONST, 0, sv);
 
-  nope:
+ nope:
     return o;
 }
 

==== //depot/maint-5.8/perl/pod/perldiag.pod#85 (text) ====
Index: perl/pod/perldiag.pod
--- perl/pod/perldiag.pod#84~27315~     2006-02-24 06:55:44.000000000 -0800
+++ perl/pod/perldiag.pod       2006-04-08 10:28:28.000000000 -0700
@@ -2754,6 +2754,11 @@
 (P) The internal do_trans routines were called with invalid operational
 data.
 
+=item panic: fold_constants JMPENV_PUSH returned %d
+
+(P) While attemtping folding constants an exception other than an C<eval>
+failure was caught.
+
 =item panic: frexp
 
 (P) The library function frexp() failed, making printf("%f") impossible.

==== //depot/maint-5.8/perl/pod/perltodo.pod#22 (text) ====
Index: perl/pod/perltodo.pod
--- perl/pod/perltodo.pod#21~27317~     2006-02-24 08:36:54.000000000 -0800
+++ perl/pod/perltodo.pod       2006-04-08 10:28:28.000000000 -0700
@@ -541,13 +541,6 @@
 debugger on a running Perl program, although I'm not sure how it would be
 done." ssh and screen do this with named pipes in /tmp. Maybe we can too.
 
-=head2 Constant folding
-
-The peephole optimiser should trap errors during constant folding, and give
-up on the folding, rather than bailing out at compile time.  It is quite
-possible that the unfoldable constant is in unreachable code, eg something
-akin to C<$a = 0/0 if 0;>
-
 =head2 LVALUE functions for lists
 
 The old perltodo notes that lvalue functions don't work for list or hash

==== //depot/maint-5.8/perl/t/comp/fold.t#1 (text) ====
Index: perl/t/comp/fold.t
--- /dev/null   2005-11-29 02:13:17.616583056 -0800
+++ perl/t/comp/fold.t  2006-04-08 10:28:28.000000000 -0700
@@ -0,0 +1,38 @@
+#!./perl
+
+BEGIN {
+    chdir 't';
+    @INC = '../lib';
+    require './test.pl';
+}
+use strict;
+use warnings;
+
+plan (8);
+
+# Historically constant folding was performed by evaluating the ops, and if
+# they threw an exception compilation failed. This was seen as buggy, because
+# even illegal constants in unreachable code would cause failure. So now
+# illegal expressions are reported at runtime, if the expression is reached,
+# making constant folding consistent with many other languages, and purely an
+# optimisation rather than a behaviour change.
+
+my $a;
+$a = eval '$b = 0/0 if 0; 3';
+is ($a, 3);
+is ($@, "");
+
+my $b = 0;
+$a = eval 'if ($b) {return sqrt -3} 3';
+is ($a, 3);
+is ($@, "");
+
+$a = eval q{
+       $b = eval q{if ($b) {return log 0} 4};
+       is ($b, 4);
+       is ($@, "");
+       5;
+};
+is ($a, 5);
+is ($@, "");
+
End of Patch.

Reply via email to