From ff2a62e0c8bedade55bf86a22861a2fe06bb0a16 Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Thu, 18 Sep 2014 16:10:01 -0700 Subject: Skip no-common-vars optimisation for aliases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ‘no common vars’ optimisation allows perl to copy the values straight from the rhs to the lhs in a list assignment. In ($a,$b) = ($c,$d), that means $c gets assigned to $a, then $d to $b. If the same variable occurs on both sides of the expression (($a,$b)=($b,$a)), then it is necessary to make temporary copies of the variables on the rhs, before assigning them to the left. If some variables have been aliased to others, then the common vars detection can be fooled: *x = *y; $x = 3; ($x, $z) = (1, $y); That assigns 1 to $x, and then goes to assign $y to $z, but $y is the same as $x, which has just been clobbered. So 1 gets assigned instead of 3. This commit solves this by recording in each typeglob whether the sca- lar is an alias of a scalar from elsewhere. If such a glob is encountered, then the entire expression is ‘tainted’ such that list assignments will assume there might be common vars. --- intrpvar.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'intrpvar.h') diff --git a/intrpvar.h b/intrpvar.h index 57918b2456..362d0cb3d3 100644 --- a/intrpvar.h +++ b/intrpvar.h @@ -60,6 +60,9 @@ PERLVAR(I, markstack, I32 *) /* stack_sp locations we're PERLVAR(I, markstack_ptr, I32 *) PERLVAR(I, markstack_max, I32 *) +PERLVARI(I, sawalias, bool, FALSE) /* must enable common-vars + pessimisation */ + #ifdef PERL_HASH_RANDOMIZE_KEYS #ifdef USE_PERL_PERTURB_KEYS PERLVARI(I, hash_rand_bits_enabled, U8, 1) /* used to randomize hash stuff 0 == no-random, 1 == random, 2 == determinsitic */ -- cgit v1.2.1