summaryrefslogtreecommitdiff
path: root/doop.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2017-07-17 17:51:57 +0100
committerDavid Mitchell <davem@iabyn.com>2017-07-27 11:30:24 +0100
commitaf3b1cba4fa1f9302496ccf5135bf61703227009 (patch)
treed84ea620b9bf30b1356fc690e4d1313f94ba0cfa /doop.c
parente84e4286916d8a219c8a63468807b41df9cde7fe (diff)
downloadperl-af3b1cba4fa1f9302496ccf5135bf61703227009.tar.gz
create Perl_hv_pushkv() function
...and make pp_padhv(), pp_rv2hv() use it rather than using Perl_do_kv() Both pp_padhv() and pp_rv2hv() (via S_padhv_rv2hv_common()), outsource to Perl_do_kv(), the list-context pushing/flattening of a hash onto the stack. Perl_do_kv() is a big function that handles all the actions of keys, values etc. Instead, create a new function which does just the pushing of a hash onto the stack. At the same time, split it out into two loops, one for tied, one for normal: the untied one can skip extending the stack on each iteration, and use a cheaper HeVAL() instead of calling hv_iterval().
Diffstat (limited to 'doop.c')
-rw-r--r--doop.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/doop.c b/doop.c
index f10269f61b..88f8439c39 100644
--- a/doop.c
+++ b/doop.c
@@ -1243,8 +1243,6 @@ Perl_do_vop(pTHX_ I32 optype, SV *sv, SV *left, SV *right)
/* Perl_do_kv() may be:
* * called directly as the pp function for pp_keys() and pp_values();
- * * called indirectly by pp_padhv() and pp_rv2hv() to implement their
- * key-value list context functionality.
* * It may also be called directly when the op is OP_AVHVSWITCH, to
* implement CORE::keys(), CORE::values().
*
@@ -1261,24 +1259,17 @@ Perl_do_kv(pTHX)
SSize_t extend_size;
const U8 gimme = GIMME_V;
- const I32 dokv = ( PL_op->op_type == OP_RV2HV
- || PL_op->op_type == OP_PADHV);
-
- const I32 dokeys = dokv
- || (PL_op->op_type == OP_KEYS)
+ const I32 dokeys = (PL_op->op_type == OP_KEYS)
|| ( PL_op->op_type == OP_AVHVSWITCH
&& (PL_op->op_private & OPpAVHVSWITCH_MASK)
+ OP_EACH == OP_KEYS);
- const I32 dovalues = dokv
- || (PL_op->op_type == OP_VALUES)
+ const I32 dovalues = (PL_op->op_type == OP_VALUES)
|| ( PL_op->op_type == OP_AVHVSWITCH
&& (PL_op->op_private & OPpAVHVSWITCH_MASK)
+ OP_EACH == OP_VALUES);
- assert( PL_op->op_type == OP_PADHV
- || PL_op->op_type == OP_RV2HV
- || PL_op->op_type == OP_KEYS
+ assert( PL_op->op_type == OP_KEYS
|| PL_op->op_type == OP_VALUES
|| PL_op->op_type == OP_AVHVSWITCH);
@@ -1302,6 +1293,11 @@ Perl_do_kv(pTHX)
IV i;
dTARGET;
+ /* note that in 'scalar(keys %h)' the OP_KEYS is usually
+ * optimised away and the action is performed directly by the
+ * padhv or rv2hv op. We now only get here via OP_AVHVSWITCH
+ * and \&CORE::keys
+ */
if (! SvTIED_mg((const SV *)keys, PERL_MAGIC_tied) ) {
i = HvUSEDKEYS(keys);
}