summaryrefslogtreecommitdiff
path: root/gv.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2019-02-04 14:11:13 +0000
committerDavid Mitchell <davem@iabyn.com>2019-02-05 14:03:05 +0000
commit7554d34485b417b08875137130152d0168feefa8 (patch)
tree6c58d0ff08d206716acf1f1fb13b34225ec3eba6 /gv.c
parent72876cce4ecc7d8756e00d284e32df0b943d0da9 (diff)
downloadperl-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.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/gv.c b/gv.c
index f7ffbfa9ed..7808c53c8e 100644
--- a/gv.c
+++ b/gv.c
@@ -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;
}