diff options
author | David Mitchell <davem@iabyn.com> | 2017-07-21 14:32:57 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2017-07-27 11:30:24 +0100 |
commit | 8dc9003ff3914e78971f561eaece965e9ceeb49e (patch) | |
tree | 9ddb6c6946453365682c422f311a985fce2725ef /doop.c | |
parent | a16ac36c3b97d0d80762b2900667f3759f354d9f (diff) | |
download | perl-8dc9003ff3914e78971f561eaece965e9ceeb49e.tar.gz |
hv_pushkv(): handle keys() and values() too
The newish function hv_pushkv() currently just pushes all key/value pairs on
the stack. i.e. it does the equivalent of the perl code '() = %h'.
Extend it so that it can handle 'keys %h' and values %h' too.
This is basically moving the remaining list-context functionality out of
do_kv() and into hv_pushkv().
The rationale for this is that hv_pushkv() is a pure HV-related function,
while do_kv() is a pp function for several ops including OP_KEYS/VALUES,
and expects PL_op->op_flags/op_private to be valid.
Diffstat (limited to 'doop.c')
-rw-r--r-- | doop.c | 21 |
1 files changed, 3 insertions, 18 deletions
@@ -1255,8 +1255,6 @@ Perl_do_kv(pTHX) { dSP; HV * const keys = MUTABLE_HV(POPs); - HE *entry; - SSize_t extend_size; const U8 gimme = GIMME_V; const I32 dokeys = (PL_op->op_type == OP_KEYS) @@ -1317,22 +1315,9 @@ Perl_do_kv(pTHX) Perl_croak(aTHX_ "Can't modify keys in list assignment"); } - /* 2*HvUSEDKEYS() should never be big enough to truncate or wrap */ - assert(HvUSEDKEYS(keys) <= (SSize_t_MAX >> 1)); - extend_size = (SSize_t)HvUSEDKEYS(keys) * (dokeys + dovalues); - EXTEND(SP, extend_size); - - while ((entry = hv_iternext(keys))) { - if (dokeys) { - SV* const sv = hv_iterkeysv(entry); - XPUSHs(sv); - } - if (dovalues) { - SV *const sv = hv_iterval(keys,entry); - XPUSHs(sv); - } - } - RETURN; + PUTBACK; + hv_pushkv(keys, (dokeys | (dovalues << 1))); + return NORMAL; } /* |