This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
pp_enter: calculate gimme earlier in XS branch
authorDavid Mitchell <davem@iabyn.com>
Sat, 6 Feb 2016 11:04:45 +0000 (11:04 +0000)
committerDavid Mitchell <davem@iabyn.com>
Sat, 6 Feb 2016 11:04:45 +0000 (11:04 +0000)
My commit 801bbf618dc make it so that pp_entersub only calculates
gimme at the point its needed, to avoid wasting register resource.
However in n the XS branch it was a bit over-enthusiatic: its possible
for an XS sub to save PL_op and change its value. The old value will
only get restored when pp_entersub soes LEAVE, which is *after* we
cacluate gimme. So grab the value before the XS sub is called.

pp_hot.c

index 8f5d82e..1a2a725 100644 (file)
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -3913,6 +3913,7 @@ PP(pp_entersub)
     }
     else {
        SSize_t markix = TOPMARK;
+        bool is_scalar;
 
         ENTER;
         /* pretend we did the ENTER earlier */
@@ -3975,12 +3976,16 @@ PP(pp_entersub)
        }
        /* Do we need to open block here? XXXX */
 
+        /* calculate gimme here as PL_op might get changed and then not
+         * restored until the LEAVE further down */
+        is_scalar = (GIMME_V == G_SCALAR);
+
        /* CvXSUB(cv) must not be NULL because newXS() refuses NULL xsub address */
        assert(CvXSUB(cv));
        CvXSUB(cv)(aTHX_ cv);
 
        /* Enforce some sanity in scalar context. */
-       if (GIMME_V == G_SCALAR) {
+       if (is_scalar) {
             SV **svp = PL_stack_base + markix + 1;
             if (svp != PL_stack_sp) {
                 *svp = svp > PL_stack_sp ? &PL_sv_undef : *PL_stack_sp;