diff options
author | David Mitchell <davem@iabyn.com> | 2019-02-04 14:11:13 +0000 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2019-02-05 14:03:05 +0000 |
commit | 7554d34485b417b08875137130152d0168feefa8 (patch) | |
tree | 6c58d0ff08d206716acf1f1fb13b34225ec3eba6 /gv.c | |
parent | 72876cce4ecc7d8756e00d284e32df0b943d0da9 (diff) | |
download | perl-7554d34485b417b08875137130152d0168feefa8.tar.gz |
Eliminate SvPADMY tests from overload code
A couple of places in the overload code do SvPADMY(TARG) to decide
whether this is a normal op like ($x op $y), where the targ will have
SVs_PADTMP set, or a lexical assignment like $lex = ($x op $y) where the
assign has been optimised away and the op is expected to directly assign
to the targ which it thinks is a PADTMP but is really $lex.
Since the SVs_PADMY flag was eliminated a while ago, SvPADMY() is just
defined as !(SvFLAGS(sv) & SVs_PADTMP). Thus the overload code is
relying on the absence of a PADTMP flag in the target to deduce that the
OPpTARGET_MY optimisation is in effect. This seems to work (at least for
the code in the test suite), but can't be regarded as robust. This
commit removes each SvPADMY() test and replaces it with the twin
if ( (PL_opargs[PL_op->op_type] & OA_TARGLEX)
&& (PL_op->op_private & OPpTARGET_MY))
tests.
Diffstat (limited to 'gv.c')
-rw-r--r-- | gv.c | 22 |
1 files changed, 19 insertions, 3 deletions
@@ -2959,8 +2959,15 @@ Perl_try_amagic_un(pTHX_ int method, int flags) { SETs(tmpsv); } else { - dTARGET; - if (SvPADMY(TARG)) { + /* where the op is of the form: + * $lex = $x op $y (where the assign is optimised away) + * then assign the returned value to targ and return that; + * otherwise return the value directly + */ + if ( (PL_opargs[PL_op->op_type] & OA_TARGLEX) + && (PL_op->op_private & OPpTARGET_MY)) + { + dTARGET; sv_setsv(TARG, tmpsv); SETTARG; } @@ -3013,7 +3020,16 @@ Perl_try_amagic_bin(pTHX_ int method, int flags) { else { dATARGET; (void)POPs; - if (mutator || SvPADMY(TARG)) { + /* where the op is one of the two forms: + * $x op= $y + * $lex = $x op $y (where the assign is optimised away) + * then assign the returned value to targ and return that; + * otherwise return the value directly + */ + if ( mutator + || ( (PL_opargs[PL_op->op_type] & OA_TARGLEX) + && (PL_op->op_private & OPpTARGET_MY))) + { sv_setsv(TARG, tmpsv); SETTARG; } |