diff options
author | David Mitchell <davem@iabyn.com> | 2010-05-25 11:38:35 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2010-05-25 12:44:16 +0100 |
commit | 0824d66743a706cd268ace8fc9df03d7374c6886 (patch) | |
tree | 7900aed8090cd6e812a8b8ee3156edf8e364bb81 /op.c | |
parent | bb1bc619ea68d9703fbd3fe5bc65ae000f90151f (diff) | |
download | perl-0824d66743a706cd268ace8fc9df03d7374c6886.tar.gz |
add OPpDEREFed flag to avoid double mg_get()
The previous commit made various ops such as rv2av unconditionally do
an SvGETMAGIC(). Under some circumstances this could cause a double
mg_get() (and hence double FETCH etc). In particular, when the
proceeding op was something like aelem with OPpDEREF, the aelem would
call vivify_ref(), which would call magic. So in peep(), mark
OP_RV2[SAH]V ops with the new OPpDEREFed flag if the preceding op was
OPpDEREF. Then use this flag to avoid a second dose of magic.
Note that RV2GV probably needs this flag too, but there weren't any
spare private flag bits left for that op (I think).
Diffstat (limited to 'op.c')
-rw-r--r-- | op.c | 14 |
1 files changed, 14 insertions, 0 deletions
@@ -8877,6 +8877,20 @@ Perl_peep(pTHX_ register OP *o) } break; } + case OP_RV2SV: + case OP_RV2AV: + case OP_RV2HV: + if (oldop + && ( oldop->op_type == OP_AELEM + || oldop->op_type == OP_PADSV + || oldop->op_type == OP_RV2SV + || oldop->op_type == OP_RV2GV + || oldop->op_type == OP_HELEM + ) + && (oldop->op_private & OPpDEREF) + ) { + o->op_private |= OPpDEREFed; + } case OP_SORT: { /* will point to RV2AV or PADAV op on LHS/RHS of assign */ |