diff options
author | David Mitchell <davem@iabyn.com> | 2017-07-17 16:33:38 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2017-07-27 11:30:24 +0100 |
commit | e84e4286916d8a219c8a63468807b41df9cde7fe (patch) | |
tree | cd426bb11f4713d71bdd6a8cf8ac051c96fc03e5 | |
parent | aa36782f823c559475544c99a66db74997ce1edf (diff) | |
download | perl-e84e4286916d8a219c8a63468807b41df9cde7fe.tar.gz |
Give OP_RV2HV a targ
OP_RV2AV already has one; its not clear why OP_RV2HV didn't.
Having one means that in scalar context it can return an int value
without having to create a mortal. Ditto when its doing 'keys %h' via
OPpRV2HV_ISKEYS.
-rw-r--r-- | ext/B/t/f_map.t | 28 | ||||
-rw-r--r-- | ext/B/t/f_sort.t | 4 | ||||
-rw-r--r-- | ext/B/t/optree_samples.t | 8 | ||||
-rw-r--r-- | opcode.h | 2 | ||||
-rw-r--r-- | pp_hot.c | 18 | ||||
-rw-r--r-- | regen/opcodes | 2 |
6 files changed, 36 insertions, 26 deletions
diff --git a/ext/B/t/f_map.t b/ext/B/t/f_map.t index 96cea4a495..221f2926e2 100644 --- a/ext/B/t/f_map.t +++ b/ext/B/t/f_map.t @@ -108,7 +108,7 @@ checkOptree(note => q{}, # goto 7 # g <0> pushmark s # h <#> gv[*hash] s -# i <1> rv2hv lKRM* +# i <1> rv2hv[t2] lKRM* # j <2> aassign[t10] KS/COM_AGG # k <1> leavesub[1 ref] K/REFC,1 EOT_EOT @@ -130,7 +130,7 @@ EOT_EOT # goto 7 # g <0> pushmark s # h <$> gv(*hash) s -# i <1> rv2hv lKRM* +# i <1> rv2hv[t1] lKRM* # j <2> aassign[t5] KS/COM_AGG # k <1> leavesub[1 ref] K/REFC,1 EONT_EONT @@ -157,7 +157,7 @@ checkOptree(note => q{}, # 4 <0> pushmark s # 5 <0> pushmark s # 6 <#> gv[*hash] s -# 7 <1> rv2hv lKRM* +# 7 <1> rv2hv[t2] lKRM* # 8 <2> aassign[t3] vKS # 9 <;> nextstate(main 476 (eval 10):1) v:{ # a <0> pushmark sM @@ -190,7 +190,7 @@ EOT_EOT # 4 <0> pushmark s # 5 <0> pushmark s # 6 <$> gv(*hash) s -# 7 <1> rv2hv lKRM* +# 7 <1> rv2hv[t1] lKRM* # 8 <2> aassign[t2] vKS # 9 <;> nextstate(main 560 (eval 15):1) v:{ # a <0> pushmark sM @@ -243,7 +243,7 @@ checkOptree(note => q{}, # goto 7 # b <0> pushmark s # c <#> gv[*hash] s -# d <1> rv2hv lKRM* +# d <1> rv2hv[t2] lKRM* # e <2> aassign[t10] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EOT_EOT @@ -260,7 +260,7 @@ EOT_EOT # goto 7 # b <0> pushmark s # c <$> gv(*hash) s -# d <1> rv2hv lKRM* +# d <1> rv2hv[t1] lKRM* # e <2> aassign[t6] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EONT_EONT @@ -289,7 +289,7 @@ checkOptree(note => q{}, # goto 7 # b <0> pushmark s # c <#> gv[*hash] s -# d <1> rv2hv lKRM* +# d <1> rv2hv[t2] lKRM* # e <2> aassign[t10] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EOT_EOT @@ -306,7 +306,7 @@ EOT_EOT # goto 7 # b <0> pushmark s # c <$> gv(*hash) s -# d <1> rv2hv lKRM* +# d <1> rv2hv[t1] lKRM* # e <2> aassign[t6] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EONT_EONT @@ -335,7 +335,7 @@ checkOptree(note => q{}, # goto 7 # b <0> pushmark s # c <#> gv[*hash] s -# d <1> rv2hv lKRM* +# d <1> rv2hv[t2] lKRM* # e <2> aassign[t9] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EOT_EOT @@ -352,7 +352,7 @@ EOT_EOT # goto 7 # b <0> pushmark s # c <$> gv(*hash) s -# d <1> rv2hv lKRM* +# d <1> rv2hv[t1] lKRM* # e <2> aassign[t5] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EONT_EONT @@ -381,7 +381,7 @@ checkOptree(note => q{}, # goto 7 # b <0> pushmark s # c <#> gv[*hash] s -# d <1> rv2hv lKRM* +# d <1> rv2hv[t2] lKRM* # e <2> aassign[t8] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EOT_EOT @@ -398,7 +398,7 @@ EOT_EOT # goto 7 # b <0> pushmark s # c <$> gv(*hash) s -# d <1> rv2hv lKRM* +# d <1> rv2hv[t1] lKRM* # e <2> aassign[t5] KS/COM_AGG # f <1> leavesub[1 ref] K/REFC,1 EONT_EONT @@ -426,7 +426,7 @@ checkOptree(note => q{}, # goto 7 # a <0> pushmark s # b <#> gv[*hash] s -# c <1> rv2hv lKRM* +# c <1> rv2hv[t2] lKRM* # d <2> aassign[t6] KS/COM_AGG # e <#> gv[*array] s # f <1> rv2av[t8] K/1 @@ -445,7 +445,7 @@ EOT_EOT # goto 7 # a <0> pushmark s # b <$> gv(*hash) s -# c <1> rv2hv lKRM* +# c <1> rv2hv[t1] lKRM* # d <2> aassign[t4] KS/COM_AGG # e <$> gv(*array) s # f <1> rv2av[t5] K/1 diff --git a/ext/B/t/f_sort.t b/ext/B/t/f_sort.t index 800281fa73..45dcd93ed5 100644 --- a/ext/B/t/f_sort.t +++ b/ext/B/t/f_sort.t @@ -280,7 +280,7 @@ checkOptree(note => q{}, # 2 <0> pushmark s # 3 <0> pushmark s # 4 <#> gv[*age] s -# 5 <1> rv2hv lKRM +# 5 <1> rv2hv[t9] lKRM # 6 <1> keys[t10] lK/1 < 5.019002 # 6 <1> keys[t10] lKM/1 >=5.019002 # 7 <@> sort lKS* @@ -294,7 +294,7 @@ EOT_EOT # 2 <0> pushmark s # 3 <0> pushmark s # 4 <$> gv(*age) s -# 5 <1> rv2hv lKRM +# 5 <1> rv2hv[t3] lKRM # 6 <1> keys[t4] lK/1 < 5.019002 # 6 <1> keys[t4] lKM/1 >=5.019002 # 7 <@> sort lKS* diff --git a/ext/B/t/optree_samples.t b/ext/B/t/optree_samples.t index 121fd3eec9..7374626663 100644 --- a/ext/B/t/optree_samples.t +++ b/ext/B/t/optree_samples.t @@ -483,7 +483,7 @@ checkOptree ( name => '%h = map { getkey($_) => $_ } @a', # goto 7 # g <0> pushmark s # h <#> gv[*h] s -# i <1> rv2hv lKRM* +# i <1> rv2hv[t2] lKRM* # j <2> aassign[t10] KS/COM_AGG # k <1> leavesub[1 ref] K/REFC,1 EOT_EOT @@ -506,7 +506,7 @@ EOT_EOT # goto 7 # g <0> pushmark s # h <$> gv(*h) s -# i <1> rv2hv lKRM* +# i <1> rv2hv[t1] lKRM* # j <2> aassign[t5] KS/COM_AGG # k <1> leavesub[1 ref] K/REFC,1 EONT_EONT @@ -519,7 +519,7 @@ checkOptree ( name => '%h=(); for $_(@a){$h{getkey($_)} = $_}', # 2 <0> pushmark s # 3 <0> pushmark s # 4 <#> gv[*h] s -# 5 <1> rv2hv lKRM* +# 5 <1> rv2hv[t2] lKRM* # 6 <2> aassign[t3] vKS # 7 <;> nextstate(main 506 (eval 24):1) v:{ # 8 <0> pushmark sM @@ -549,7 +549,7 @@ EOT_EOT # 2 <0> pushmark s # 3 <0> pushmark s # 4 <$> gv(*h) s -# 5 <1> rv2hv lKRM* +# 5 <1> rv2hv[t1] lKRM* # 6 <2> aassign[t2] vKS # 7 <;> nextstate(main 506 (eval 24):1) v:{ # 8 <0> pushmark sM @@ -1938,7 +1938,7 @@ EXTCONST U32 PL_opargs[] = { 0x00004b08, /* keys */ 0x00001b00, /* delete */ 0x00001b04, /* exists */ - 0x00000140, /* rv2hv */ + 0x00000148, /* rv2hv */ 0x00014204, /* helem */ 0x00024401, /* hslice */ 0x00024401, /* kvhslice */ @@ -969,10 +969,13 @@ PP(pp_print) /* do the common parts of pp_padhv() and pp_rv2hv() * It assumes the caller has done EXTEND(SP, 1) or equivalent. * 'is_keys' indicates the OPpPADHV_ISKEYS/OPpRV2HV_ISKEYS flag is set + * 'has_targ' indicates that the op has a target - this should + * be a compile-time constant so that the code can constant-folded as + * appropriate * */ PERL_STATIC_INLINE OP* -S_padhv_rv2hv_common(pTHX_ HV *hv, U8 gimme, bool is_keys) +S_padhv_rv2hv_common(pTHX_ HV *hv, U8 gimme, bool is_keys, bool has_targ) { bool tied; dSP; @@ -1008,7 +1011,12 @@ S_padhv_rv2hv_common(pTHX_ HV *hv, U8 gimme, bool is_keys) } else i = HvUSEDKEYS(hv); - mPUSHi(i); + if (has_targ) { + dTARGET; + PUSHi(i); + } + else + mPUSHi(i); } else PUSHs(Perl_hv_scalar(aTHX_ hv)); @@ -1109,7 +1117,8 @@ PP(pp_padhv) gimme = GIMME_V; return S_padhv_rv2hv_common(aTHX_ (HV*)TARG, gimme, - cBOOL(PL_op->op_private & OPpPADHV_ISKEYS)); + cBOOL(PL_op->op_private & OPpPADHV_ISKEYS), + 0 /* has_targ*/); } @@ -1191,7 +1200,8 @@ PP(pp_rv2av) else { SP--; PUTBACK; return S_padhv_rv2hv_common(aTHX_ (HV*)sv, gimme, - cBOOL(PL_op->op_private & OPpRV2HV_ISKEYS)); + cBOOL(PL_op->op_private & OPpRV2HV_ISKEYS), + 1 /* has_targ*/); } RETURN; diff --git a/regen/opcodes b/regen/opcodes index 58d08c3f3c..137a44f6b9 100644 --- a/regen/opcodes +++ b/regen/opcodes @@ -238,7 +238,7 @@ values values ck_each dt% H keys keys ck_each t% H delete delete ck_delete % S exists exists ck_exists is% S -rv2hv hash dereference ck_rvconst d1 +rv2hv hash dereference ck_rvconst dt1 helem hash element ck_null s2 H S hslice hash slice ck_null m@ H L kvhslice key/value hash slice ck_null m@ H L |