In perl.git, the branch blead has been updated

<https://perl5.git.perl.org/perl.git/commitdiff/66ff4fb5827047a9962893be6bdf6c6439b7af2c?hp=51d22a816ecfc587acee9913de2de6a113718dcd>

- Log -----------------------------------------------------------------
commit 66ff4fb5827047a9962893be6bdf6c6439b7af2c
Author: Tony Cook <t...@develop-help.com>
Date:   Mon Jun 24 10:01:42 2019 +1000

    use hex for the call_*()/eval_sv() flag definitions
    
    while I expect most C programmers have these powers of two engraved
    into their brains, using hex makes this more obvious

commit fb81daf0179f156be3f2a95cd5cf1d27e9f7ebbb
Author: Tony Cook <t...@develop-help.com>
Date:   Thu Jun 20 15:26:22 2019 +1000

    (perl #134177) add G_RETHROW flag to eval_sv()
    
    and update eval_pv() to use it.

-----------------------------------------------------------------------

Summary of changes:
 cop.h                      | 23 ++++++++++++-----------
 ext/XS-APItest/Makefile.PL |  2 +-
 ext/XS-APItest/t/call.t    | 26 +++++++++++++++++++++++++-
 perl.c                     | 25 ++++++++++++++++---------
 4 files changed, 54 insertions(+), 22 deletions(-)

diff --git a/cop.h b/cop.h
index b9b61faa76..243f70094d 100644
--- a/cop.h
+++ b/cop.h
@@ -956,23 +956,24 @@ L<perlcall>.
 #define G_WANT         3
 
 /* extra flags for Perl_call_* routines */
-#define G_DISCARD      4       /* Call FREETMPS.
+#define G_DISCARD         0x4  /* Call FREETMPS.
                                   Don't change this without consulting the
                                   hash actions codes defined in hv.h */
-#define G_EVAL         8       /* Assume eval {} around subroutine call. */
-#define G_NOARGS       16      /* Don't construct a @_ array. */
-#define G_KEEPERR      32      /* Warn for errors, don't overwrite $@ */
-#define G_NODEBUG      64      /* Disable debugging at toplevel.  */
-#define G_METHOD      128       /* Calling method. */
-#define G_FAKINGEVAL  256      /* Faking an eval context for call_sv or
+#define G_EVAL           0x8   /* Assume eval {} around subroutine call. */
+#define G_NOARGS         0x10  /* Don't construct a @_ array. */
+#define G_KEEPERR        0x20  /* Warn for errors, don't overwrite $@ */
+#define G_NODEBUG        0x40  /* Disable debugging at toplevel.  */
+#define G_METHOD         0x80   /* Calling method. */
+#define G_FAKINGEVAL    0x100  /* Faking an eval context for call_sv or
                                   fold_constants. */
-#define G_UNDEF_FILL  512      /* Fill the stack with &PL_sv_undef
+#define G_UNDEF_FILL    0x200  /* Fill the stack with &PL_sv_undef
                                   A special case for UNSHIFT in
                                   Perl_magic_methcall().  */
-#define G_WRITING_TO_STDERR 1024 /* Perl_write_to_stderr() is calling
+#define G_WRITING_TO_STDERR 0x400 /* Perl_write_to_stderr() is calling
                                    Perl_magic_methcall().  */
-#define G_RE_REPARSING 0x800     /* compiling a run-time /(?{..})/ */
-#define G_METHOD_NAMED 4096    /* calling named method, eg without :: or ' */
+#define G_RE_REPARSING  0x800   /* compiling a run-time /(?{..})/ */
+#define G_METHOD_NAMED 0x1000  /* calling named method, eg without :: or ' */
+#define G_RETHROW      0x2000  /* eval_sv(): re-throw any error */
 
 /* flag bits for PL_in_eval */
 #define EVAL_NULL      0       /* not in an eval */
diff --git a/ext/XS-APItest/Makefile.PL b/ext/XS-APItest/Makefile.PL
index d79ba1150e..3fe5e397a8 100644
--- a/ext/XS-APItest/Makefile.PL
+++ b/ext/XS-APItest/Makefile.PL
@@ -23,7 +23,7 @@ WriteMakefile(
 my @names = (qw(HV_DELETE HV_DISABLE_UVAR_XKEY HV_FETCH_ISSTORE
                HV_FETCH_ISEXISTS HV_FETCH_LVALUE HV_FETCH_JUST_SV
                G_SCALAR G_ARRAY G_VOID G_DISCARD G_EVAL G_NOARGS
-               G_KEEPERR G_NODEBUG G_METHOD G_FAKINGEVAL
+               G_KEEPERR G_NODEBUG G_METHOD G_FAKINGEVAL G_RETHROW
                GV_NOADD_NOINIT
                IS_NUMBER_IN_UV IS_NUMBER_GREATER_THAN_UV_MAX
                IS_NUMBER_NOT_INT IS_NUMBER_NEG IS_NUMBER_INFINITY
diff --git a/ext/XS-APItest/t/call.t b/ext/XS-APItest/t/call.t
index 632a421d4f..e4228077cb 100644
--- a/ext/XS-APItest/t/call.t
+++ b/ext/XS-APItest/t/call.t
@@ -11,7 +11,7 @@ use strict;
 
 BEGIN {
     require '../../t/test.pl';
-    plan(530);
+    plan(538);
     use_ok('XS::APItest')
 };
 
@@ -228,6 +228,30 @@ is(eval { eval_pv(q/die $obj/, 1) }, undef,
 ok(ref $@, "object thrown");
 is($@, $obj, "check object rethrown");
 
+package False {
+    use overload
+      bool => sub { 0 },
+      '""' => sub { "Foo" };
+    sub new { bless {}, shift }
+};
+my $false = False->new;
+ok(!$false, "our false object is actually false");
+is(eval { eval_pv(q/die $false;/, 1); 1 }, undef,
+   "check false objects are rethrown");
+is(overload::StrVal($@), overload::StrVal($false),
+   "check we got the expected object");
+
+is(eval { eval_sv(q/die $false/, G_RETHROW); 1 }, undef,
+   "check G_RETHROW for thrown object");
+is(overload::StrVal($@), overload::StrVal($false),
+   "check we got the expected object");
+is(eval { eval_sv(q/"unterminated/, G_RETHROW); 1 }, undef,
+   "check G_RETHROW for syntax error");
+like($@, qr/Can't find string terminator/,
+     "check error rethrown");
+ok(eq_array([ eval { eval_sv(q/"working code"/, G_RETHROW) } ], [ "working 
code", 1 ]),
+   "check for spurious rethrow");
+
 # #3719 - check that the eval call variants handle exceptions correctly,
 # and do the right thing with $@, both with and without G_KEEPERR set.
 
diff --git a/perl.c b/perl.c
index 2e80cfe940..e642f2e76d 100644
--- a/perl.c
+++ b/perl.c
@@ -3097,6 +3097,9 @@ Perl_call_sv(pTHX_ SV *sv, volatile I32 flags)
 Tells Perl to C<eval> the string in the SV.  It supports the same flags
 as C<call_sv>, with the obvious exception of C<G_EVAL>.  See L<perlcall>.
 
+The C<G_RETHROW> flag can be used if you only need eval_sv() to
+execute code specified by a string, but not catch any errors.
+
 =cut
 */
 
@@ -3178,6 +3181,11 @@ Perl_eval_sv(pTHX_ SV *sv, I32 flags)
            goto redo_body;
        }
       fail:
+        if (flags & G_RETHROW) {
+            JMPENV_POP;
+            croak_sv(ERRSV);
+        }
+
        PL_stack_sp = PL_stack_base + oldmark;
        if ((flags & G_WANT) == G_ARRAY)
            retval = 0;
@@ -3214,8 +3222,14 @@ Perl_eval_pv(pTHX_ const char *p, I32 croak_on_error)
 
     PERL_ARGS_ASSERT_EVAL_PV;
 
-    eval_sv(sv, G_SCALAR);
-    SvREFCNT_dec(sv);
+    if (croak_on_error) {
+        sv_2mortal(sv);
+        eval_sv(sv, G_SCALAR | G_RETHROW);
+    }
+    else {
+        eval_sv(sv, G_SCALAR);
+        SvREFCNT_dec(sv);
+    }
 
     {
         dSP;
@@ -3223,13 +3237,6 @@ Perl_eval_pv(pTHX_ const char *p, I32 croak_on_error)
         PUTBACK;
     }
 
-    /* just check empty string or undef? */
-    if (croak_on_error) {
-       SV * const errsv = ERRSV;
-       if(SvTRUE_NN(errsv))
-            croak_sv(errsv);
-    }
-
     return sv;
 }
 

-- 
Perl5 Master Repository

Reply via email to