From: Rafael Garcia-Suarez Date: Wed, 5 Jul 2006 21:00:31 +0000 (+0000) Subject: Implement handling of state variables in list assignment X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=461824dcfbc00b3c4e20590f06d6c9881e4a416b;p=p5sagit%2Fp5-mst-13.2.git Implement handling of state variables in list assignment p4raw-id: //depot/perl@28489 --- diff --git a/ext/B/B/Concise.pm b/ext/B/B/Concise.pm index d864fe5..38c8c0a 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 dd7a5f2..370a01f 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 891f3de..7a83ee7 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 6d09813..31347b1 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');