summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/B/B/Concise.pm2
-rw-r--r--op.c7
-rw-r--r--pp_hot.c6
-rw-r--r--t/op/state.t7
4 files changed, 16 insertions, 6 deletions
diff --git a/ext/B/B/Concise.pm b/ext/B/B/Concise.pm
index d864fe5a0f..38c8c0a7ef 100644
--- a/ext/B/B/Concise.pm
+++ b/ext/B/B/Concise.pm
@@ -562,7 +562,7 @@ $priv{$_}{128} = "LVINTRO"
"padav", "padhv", "enteriter");
$priv{$_}{64} = "REFC" for ("leave", "leavesub", "leavesublv", "leavewrite");
$priv{"aassign"}{64} = "COMMON";
-$priv{"aassign"}{32} = "PHASH" if $] < 5.009;
+$priv{"aassign"}{32} = $] < 5.009 ? "PHASH" : "STATE";
$priv{"sassign"}{32} = "STATE";
$priv{"sassign"}{64} = "BKWARD";
$priv{$_}{64} = "RTIME" for ("match", "subst", "substcont", "qr");
diff --git a/op.c b/op.c
index dd7a5f2dea..370a01fb59 100644
--- a/op.c
+++ b/op.c
@@ -3783,6 +3783,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
* to store these values, evil chicanery is done with SvCUR().
*/
+ {
OP *lastop = o;
PL_generation++;
for (curop = LINKLIST(o); curop != o; curop = LINKLIST(curop)) {
@@ -3799,6 +3800,11 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
curop->op_type == OP_PADHV ||
curop->op_type == OP_PADANY)
{
+ if ((left->op_private & OPpLVAL_INTRO) && (curop->op_private & OPpPAD_STATE)) {
+ o->op_private |= OPpASSIGN_STATE;
+ /* hijacking PADSTALE for uninitialized state variables */
+ SvPADSTALE_on(PAD_SVl(curop->op_targ));
+ }
if (PAD_COMPNAME_GEN(curop->op_targ)
== (STRLEN)PL_generation)
break;
@@ -3836,6 +3842,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right)
}
if (curop != o)
o->op_private |= OPpASSIGN_COMMON;
+ }
if (right && right->op_type == OP_SPLIT) {
OP* tmpop = ((LISTOP*)right)->op_first;
if (tmpop && (tmpop->op_type == OP_PUSHRE)) {
diff --git a/pp_hot.c b/pp_hot.c
index 891f3de563..7a83ee7040 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -1080,6 +1080,12 @@ PP(pp_aassign)
}
}
}
+ if (PL_op->op_private & OPpASSIGN_STATE) {
+ if (SvPADSTALE(*firstlelem))
+ SvPADSTALE_off(*firstlelem);
+ else
+ RETURN; /* ignore assignment */
+ }
relem = firstrelem;
lelem = firstlelem;
diff --git a/t/op/state.t b/t/op/state.t
index 6d09813fe1..31347b1a69 100644
--- a/t/op/state.t
+++ b/t/op/state.t
@@ -105,7 +105,7 @@ is( gen_cashier()->{bal}->(), 42, '$42 in my drawer' );
# stateless assignment to a state variable
sub stateless {
- (state $reinitme) = 42;
+ (state $reinitme, my $foo) = (42, 'bar');
++$reinitme;
}
is( stateless(), 43, 'stateless function, first time' );
@@ -151,7 +151,4 @@ sub statelist {
my $ls = statelist();
is($ls, "12/23", 'list assignment to state scalars');
$ls = statelist();
-{
- local our $TODO = 'make aassign handle state vars';
- is($ls, "13/24", 'list assignment to state scalars');
-}
+is($ls, "13/24", 'list assignment to state scalars');