[perl #87708] Fix ‘$tied binop $tied’
authorFather Chrysostomos <sprout@cpan.org>
Fri, 8 Apr 2011 06:02:35 +0000 (23:02 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Fri, 8 Apr 2011 06:02:35 +0000 (23:02 -0700)
commit75ea7a126f0cb23a33771013529ef0e381ffe55d
tree66894839a7d3b81dd954fe71add39a3edf0de370
parent7d779b236fc2cb0c2dbe324bda777c76494a71a5
[perl #87708] Fix ‘$tied binop $tied’

The short story: In 5.13.1 or .2 these ops started calling get-magic
just once if the same gmagical scalar was used for both operands. Then
the same value would be used on both sides. In 5.12 FETCH would be
called twice with both return values used, but they would be swapped
in most cases (so $t/$t would return 1.5 if $t returned 2 and then
3). Now FETCH is called twice and the two operands are used in the
right order.

Up till now there have been patches to fix specific ops, but I real-
ised that the same ten or so lines of code would have to be added to
the rest of the 20+ pp_ functions, all of which use tryAMAGICbin_MG
(which calls Perl_try_amagic_bin in gv.c), so it made sense to add the
code to Perl_try_amagic_bin instead. This fixes all the ops in one
fell swoop.

The code in question checks whether the left and right operands are
the same gmagical scalar. If so, it copies the scalar into a new mor-
tal one, and then calls get-magic on the original operand to get its
new value (for the rhs). The new scalar is placed just below the top
of the stack, so it becomes the left operand.

This does slow down the bitwise integer ops slightly, but only in this
rare edge case. And the simplification of the code seems worth it.

Forthcoming are commits that revert some of the changes already made,
as this commit renders them unnecessary.
gv.c
pp.h
t/op/tie_fetch_count.t