In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/a1b22abd29aa292b3a30da993984fc76d6d2e3aa?hp=2c217c4598fa36f236d5085b4d73b7282b80beb1>

- Log -----------------------------------------------------------------
commit a1b22abd29aa292b3a30da993984fc76d6d2e3aa
Author: Father Chrysostomos <[email protected]>
Date:   Mon Nov 10 20:00:53 2014 -0800

    Extend OPpTARGET_MY optimisation to state var init
    
    ck_sassign does two things:
    
    • See if $lexical = <some op> can have the assignment optimised away
      (OPpTARGET_MY/targlex).
    • See if we have state $x = foo, which needs to run only once
      per closure.
    
    The former optimisation is skipped for variable declarations (‘my $x
    = time’), because ‘my $x’ does more than just return the SV at a pad
    offset.  It also arranges for it to be cleared on scope exit.  That
    does not apply to state variable.  The OPpLVAL_INTRO flag (indicating
    the presence of ‘my’ or ‘state’ before the variable) has no run-time
    effect on state vars, so there is no need to skip the optimisation
    because of it.
    
    That optimisation destroys the assignment operator and its lhs before
    we get to the state var init code, which needs the lhs to do its
    checks.  So we change the order that these checks happen, and make the
    state var code invoke the optimisation itself.

M       lib/B/Deparse.pm
M       op.c

commit 53fd57abab4ef75c406a4b9caf3ddc7f638cae9c
Author: Father Chrysostomos <[email protected]>
Date:   Mon Nov 10 19:33:11 2014 -0800

    op.c:ck_sassign: Move targlex to static func
    
    ck_sassign does two things:
    
    • See if $lexical = <some op> can have the assignment optimised away
      (targlex).
    • See if we have state $x = foo, which needs to run only once
      per closure.
    
    Putting the former in a static routine will allow the latter to call
    it, too, sowe can extend the targlex optimisation to state variable
    initialization.

M       op.c

commit f511a28d465679812c01f3659928743bef1d3916
Author: Father Chrysostomos <[email protected]>
Date:   Mon Nov 10 19:15:27 2014 -0800

    op.c:ck_sassign: correct comment
    
    state $x = time does not have a listop.
    state $x : nifty = time does.

M       op.c

commit d6ca65d8388b907ff537a8597ee026ad42d5c00f
Author: Father Chrysostomos <[email protected]>
Date:   Mon Nov 10 18:57:45 2014 -0800

    op.c:ck_sassign: Don’t check the pad name for state
    
    The padsv op will already have its state flag set by this point, so we
    can merge two flag checks into one, resulting in smaller machine code.

M       op.c
-----------------------------------------------------------------------

Summary of changes:
 lib/B/Deparse.pm |  4 +++-
 op.c             | 34 ++++++++++++++++++++++------------
 2 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm
index 67d847e..716e671 100644
--- a/lib/B/Deparse.pm
+++ b/lib/B/Deparse.pm
@@ -3215,7 +3215,9 @@ sub pp_once {
     my $cond = $op->first;
     my $true = $cond->sibling;
 
-    return $self->deparse($true, $cx);
+    my $ret = $self->deparse($true, $cx);
+    $ret =~ s/^(\(?)\$/$1 . $self->keyword("state") . ' $'/e;
+    $ret;
 }
 
 sub loop_common {
diff --git a/op.c b/op.c
index 6042650..159296a 100644
--- a/op.c
+++ b/op.c
@@ -10139,14 +10139,11 @@ Perl_ck_smartmatch(pTHX_ OP *o)
 }
 
 
-OP *
-Perl_ck_sassign(pTHX_ OP *o)
+static OP *
+S_maybe_targlex(pTHX_ OP *o)
 {
     dVAR;
     OP * const kid = cLISTOPo->op_first;
-
-    PERL_ARGS_ASSERT_CK_SASSIGN;
-
     /* has a disposable target? */
     if ((PL_opargs[kid->op_type] & OA_TARGLEX)
        && !(kid->op_flags & OPf_STACKED)
@@ -10158,7 +10155,8 @@ Perl_ck_sassign(pTHX_ OP *o)
 
        /* Can just relocate the target. */
        if (kkid && kkid->op_type == OP_PADSV
-           && !(kkid->op_private & OPpLVAL_INTRO))
+           && (!(kkid->op_private & OPpLVAL_INTRO)
+              || kkid->op_private & OPpPAD_STATE))
        {
            kid->op_targ = kkid->op_targ;
            kkid->op_targ = 0;
@@ -10170,23 +10168,35 @@ Perl_ck_sassign(pTHX_ OP *o)
            return kid;
        }
     }
+    return o;
+}
+
+OP *
+Perl_ck_sassign(pTHX_ OP *o)
+{
+    dVAR;
+    OP * const kid = cLISTOPo->op_first;
+
+    PERL_ARGS_ASSERT_CK_SASSIGN;
+
     if (OP_HAS_SIBLING(kid)) {
        OP *kkid = OP_SIBLING(kid);
-       /* For state variable assignment, kkid is a list op whose op_last
-          is a padsv. */
+       /* For state variable assignment with attributes, kkid is a list op
+          whose op_last is a padsv. */
        if ((kkid->op_type == OP_PADSV ||
             (OP_TYPE_IS_OR_WAS(kkid, OP_LIST) &&
              (kkid = cLISTOPx(kkid)->op_last)->op_type == OP_PADSV
             )
            )
-               && (kkid->op_private & OPpLVAL_INTRO)
-               && SvPAD_STATE(PAD_COMPNAME_SV(kkid->op_targ))) {
+               && (kkid->op_private & (OPpLVAL_INTRO|OPpPAD_STATE))
+                   == (OPpLVAL_INTRO|OPpPAD_STATE)) {
            const PADOFFSET target = kkid->op_targ;
            OP *const other = newOP(OP_PADSV,
                                    kkid->op_flags
                                    | ((kkid->op_private & ~OPpLVAL_INTRO) << 
8));
            OP *const first = newOP(OP_NULL, 0);
-           OP *const nullop = newCONDOP(0, first, o, other);
+           OP *const nullop =
+               newCONDOP(0, first, S_maybe_targlex(aTHX_ o), other);
            OP *const condop = first->op_next;
 
             CHANGE_TYPE(condop, OP_ONCE);
@@ -10202,7 +10212,7 @@ Perl_ck_sassign(pTHX_ OP *o)
            return nullop;
        }
     }
-    return o;
+    return S_maybe_targlex(aTHX_ o);
 }
 
 OP *

--
Perl5 Master Repository

Reply via email to