From 61c4feda620a9ff1f1546e316d4a772f46df4151 Mon Sep 17 00:00:00 2001 From: Richard Leach Date: Fri, 8 Jul 2022 14:52:19 +0000 Subject: [PATCH] Implement OP_PADSV_STORE - combined sassign/padsv OP This commit introduces a new OP to replace simple cases of OP_SASSIGN and OP_PADSV. For example, 'my $x = 1' is currently implemented as: 1 <;> nextstate(main 1 -e:1) v:{ 2 <$> const(IV 1) s 3 <0> padsv[$x:1,2] sRM*/LVINTRO 4 <2> sassign vKS/2 But now will be turned into: 1 <;> nextstate(main 1 -e:1) v:{ 2 <$> const(IV 1) s 3 <1> padsv_store[$x:1,2] vKMS/LVINTRO This intended to be a transparent performance optimization. It should be applicable for RHS optrees of varying complexity. --- ext/B/t/b.t | 2 +- ext/B/t/optree_concise.t | 4 +- ext/B/t/optree_samples.t | 132 ++++--- ext/B/t/optree_varinit.t | 48 ++- ext/Opcode/Opcode.pm | 4 +- lib/B/Deparse.pm | 14 +- lib/B/Op_private.pm | 9 +- opcode.h | 491 +++++++++++------------ opnames.h | 813 ++++++++++++++++++++------------------- peep.c | 52 +++ pp_hot.c | 42 ++ pp_proto.h | 1 + regen/op_private | 5 +- regen/opcodes | 1 + t/perf/opcount.t | 12 +- 15 files changed, 875 insertions(+), 755 deletions(-) diff --git a/ext/B/t/b.t b/ext/B/t/b.t index aa67fd375581..bdf831881d3a 100644 --- a/ext/B/t/b.t +++ b/ext/B/t/b.t @@ -306,7 +306,7 @@ is(B::opnumber("pp_null"), 0, "Testing opnumber with opname (pp_null)"); is(B::class(bless {}, "Wibble::Bibble"), "Bibble", "Testing B::class()"); is(B::cast_I32(3.14), 3, "Testing B::cast_I32()"); -is(B::opnumber("chop"), 38, "Testing opnumber with opname (chop)"); +is(B::opnumber("chop"), 39, "Testing opnumber with opname (chop)"); { no warnings 'once'; diff --git a/ext/B/t/optree_concise.t b/ext/B/t/optree_concise.t index cf93bd105655..b3227c62bc6d 100644 --- a/ext/B/t/optree_concise.t +++ b/ext/B/t/optree_concise.t @@ -178,13 +178,13 @@ checkOptree ( name => "terse basic", UNOP (0x82b0918) leavesub [1] LISTOP (0x82b08d8) lineseq COP (0x82b0880) nextstate - UNOP (0x82b0860) null [14] + UNOP (0x82b0860) null [15] PADOP (0x82b0840) gvsv GV (0x82a818c) *a EOT_EOT # UNOP (0x8282310) leavesub [1] # LISTOP (0x82822f0) lineseq # COP (0x82822b8) nextstate -# UNOP (0x812fc20) null [14] +# UNOP (0x812fc20) null [15] # SVOP (0x812fc00) gvsv GV (0x814692c) *a EONT_EONT diff --git a/ext/B/t/optree_samples.t b/ext/B/t/optree_samples.t index 5e489d698d7b..329a85b34d81 100644 --- a/ext/B/t/optree_samples.t +++ b/ext/B/t/optree_samples.t @@ -67,49 +67,49 @@ checkOptree ( name => '-basic (see above, with my $a = shift)', }, strip_open_hints => 1, expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); -# b <1> leavesub[1 ref] K/REFC,1 ->(end) -# - <@> lineseq KP ->b +# a <1> leavesub[1 ref] K/REFC,1 ->(end) +# - <@> lineseq KP ->a # 1 <;> nextstate(main 666 optree_samples.t:70) v:>,<,% ->2 -# 4 <2> sassign vKS/2 ->5 +# 3 <1> padsv_store[$a:666,670] vKS/LVINTRO ->4 # 2 <0> shift s* ->3 -# 3 <0> padsv[$a:666,670] sRM*/LVINTRO ->4 -# 5 <;> nextstate(main 670 optree_samples.t:71) v:>,<,% ->6 +# - <0> ex-padsv sRM*/LVINTRO ->3 +# 4 <;> nextstate(main 670 optree_samples.t:71) v:>,<,% ->5 # - <1> null K/1 ->- -# 7 <|> cond_expr(other->8) K/1 ->c -# 6 <0> padsv[$a:666,670] s ->7 +# 6 <|> cond_expr(other->7) K/1 ->b +# 5 <0> padsv[$a:666,670] s ->6 # - <@> scope K ->- -# - <;> ex-nextstate(main 1603 optree_samples.t:70) v:>,<,% ->8 -# a <@> print sK ->b -# 8 <0> pushmark s ->9 -# 9 <$> const[PV "foo"] s ->a -# h <@> leave KP ->b -# c <0> enter ->d -# d <;> nextstate(main 668 optree_samples.t:72) v:>,<,% ->e -# g <@> print sK ->h -# e <0> pushmark s ->f -# f <$> const[PV "bar"] s ->g +# - <;> ex-nextstate(main 1510 optree_samples.t:66) v:>,<,% ->7 +# 9 <@> print sK ->a +# 7 <0> pushmark s ->8 +# 8 <$> const[PV "foo"] s ->9 +# g <@> leave KP ->a +# b <0> enter ->c +# c <;> nextstate(main 1510 optree_samples.t:66) v:>,<,% ->d +# f <@> print sK ->g +# d <0> pushmark s ->e +# e <$> const[PV "bar"] s ->f EOT_EOT -# b <1> leavesub[1 ref] K/REFC,1 ->(end) -# - <@> lineseq KP ->b -# 1 <;> nextstate(main 666 optree_samples.t:72) v:>,<,% ->2 -# 4 <2> sassign vKS/2 ->5 +# a <1> leavesub[1 ref] K/REFC,1 ->(end) +# - <@> lineseq KP ->a +# 1 <;> nextstate(main 666 optree_samples.t:70) v:>,<,% ->2 +# 3 <1> padsv_store[$a:666,670] vKS/LVINTRO ->4 # 2 <0> shift s* ->3 -# 3 <0> padsv[$a:666,670] sRM*/LVINTRO ->4 -# 5 <;> nextstate(main 670 optree_samples.t:73) v:>,<,% ->6 +# - <0> ex-padsv sRM*/LVINTRO ->3 +# 4 <;> nextstate(main 670 optree_samples.t:71) v:>,<,% ->5 # - <1> null K/1 ->- -# 7 <|> cond_expr(other->8) K/1 ->c -# 6 <0> padsv[$a:666,670] s ->7 +# 6 <|> cond_expr(other->7) K/1 ->b +# 5 <0> padsv[$a:666,670] s ->6 # - <@> scope K ->- -# - <;> ex-nextstate(main 1603 optree_samples.t:70) v:>,<,% ->8 -# a <@> print sK ->b -# 8 <0> pushmark s ->9 -# 9 <$> const(PV "foo") s ->a -# h <@> leave KP ->b -# c <0> enter ->d -# d <;> nextstate(main 668 optree_samples.t:74) v:>,<,% ->e -# g <@> print sK ->h -# e <0> pushmark s ->f -# f <$> const(PV "bar") s ->g +# - <;> ex-nextstate(main 1510 optree_samples.t:70) v:>,<,% ->7 +# 9 <@> print sK ->a +# 7 <0> pushmark s ->8 +# 8 <$> const(PV "foo") s ->9 +# g <@> leave KP ->a +# b <0> enter ->c +# c <;> nextstate(main 668 optree_samples.t:72) v:>,<,% ->d +# f <@> print sK ->g +# d <0> pushmark s ->e +# e <$> const(PV "bar") s ->f EONT_EONT checkOptree ( name => '-exec sub {if shift print then,else}', @@ -160,41 +160,39 @@ checkOptree ( name => '-exec (see above, with my $a = shift)', expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); # 1 <;> nextstate(main 675 optree_samples.t:165) v:>,<,% # 2 <0> shift s* -# 3 <0> padsv[$a:675,679] sRM*/LVINTRO -# 4 <2> sassign vKS/2 -# 5 <;> nextstate(main 679 optree_samples.t:166) v:>,<,% -# 6 <0> padsv[$a:675,679] s -# 7 <|> cond_expr(other->8) K/1 -# 8 <0> pushmark s -# 9 <$> const[PV "foo"] s -# a <@> print sK -# goto b -# c <0> enter -# d <;> nextstate(main 677 optree_samples.t:167) v:>,<,% -# e <0> pushmark s -# f <$> const[PV "bar"] s -# g <@> print sK -# h <@> leave KP -# b <1> leavesub[1 ref] K/REFC,1 +# 3 <1> padsv_store[$a:1522,1529] vKS/LVINTRO +# 4 <;> nextstate(main 679 optree_samples.t:166) v:>,<,% +# 5 <0> padsv[$a:675,679] s +# 6 <|> cond_expr(other->7) K/1 +# 7 <0> pushmark s +# 8 <$> const[PV "foo"] s +# 9 <@> print sK +# goto a +# b <0> enter +# c <;> nextstate(main 677 optree_samples.t:167) v:>,<,% +# d <0> pushmark s +# e <$> const[PV "bar"] s +# f <@> print sK +# g <@> leave KP +# a <1> leavesub[1 ref] K/REFC,1 EOT_EOT # 1 <;> nextstate(main 675 optree_samples.t:171) v:>,<,% # 2 <0> shift s* -# 3 <0> padsv[$a:675,679] sRM*/LVINTRO -# 4 <2> sassign vKS/2 -# 5 <;> nextstate(main 679 optree_samples.t:172) v:>,<,% -# 6 <0> padsv[$a:675,679] s -# 7 <|> cond_expr(other->8) K/1 -# 8 <0> pushmark s -# 9 <$> const(PV "foo") s -# a <@> print sK -# goto b -# c <0> enter -# d <;> nextstate(main 677 optree_samples.t:173) v:>,<,% -# e <0> pushmark s -# f <$> const(PV "bar") s -# g <@> print sK -# h <@> leave KP -# b <1> leavesub[1 ref] K/REFC,1 +# 3 <1> padsv_store[$a:1522,1529] vKS/LVINTRO +# 4 <;> nextstate(main 679 optree_samples.t:172) v:>,<,% +# 5 <0> padsv[$a:675,679] s +# 6 <|> cond_expr(other->7) K/1 +# 7 <0> pushmark s +# 8 <$> const(PV "foo") s +# 9 <@> print sK +# goto a +# b <0> enter +# c <;> nextstate(main 677 optree_samples.t:173) v:>,<,% +# d <0> pushmark s +# e <$> const(PV "bar") s +# f <@> print sK +# g <@> leave KP +# a <1> leavesub[1 ref] K/REFC,1 EONT_EONT checkOptree ( name => '-exec sub { print (shift) ? "foo" : "bar" }', diff --git a/ext/B/t/optree_varinit.t b/ext/B/t/optree_varinit.t index d89afc24f337..36a2a5f2aac1 100644 --- a/ext/B/t/optree_varinit.t +++ b/ext/B/t/optree_varinit.t @@ -129,19 +129,19 @@ checkOptree ( name => 'sub {my $a=undef}', bcopts => '-basic', strip_open_hints => 1, expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); -5 <1> leavesub[1 ref] K/REFC,1 ->(end) -- <@> lineseq KP ->5 +4 <1> leavesub[1 ref] K/REFC,1 ->(end) +- <@> lineseq KP ->4 1 <;> nextstate(main 641 optree_varinit.t:130) v:>,<,% ->2 -4 <2> sassign sKS/2 ->5 +3 <1> padsv_store[$a:1508,1509] sKS/LVINTRO ->4 2 <0> undef s ->3 -3 <0> padsv[$a:641,642] sRM*/LVINTRO ->4 +- <0> ex-padsv sRM*/LVINTRO ->3 EOT_EOT -# 5 <1> leavesub[1 ref] K/REFC,1 ->(end) -# - <@> lineseq KP ->5 +# 4 <1> leavesub[1 ref] K/REFC,1 ->(end) +# - <@> lineseq KP ->4 # 1 <;> nextstate(main 641 optree_varinit.t:130) v:>,<,% ->2 -# 4 <2> sassign sKS/2 ->5 +# 3 <1> padsv_store[$a:1508,1509] sKS/LVINTRO ->4 # 2 <0> undef s ->3 -# 3 <0> padsv[$a:641,642] sRM*/LVINTRO ->4 +# - <0> ex-padsv sRM*/LVINTRO ->3 EONT_EONT checkOptree ( name => 'sub {our $a=undef}', @@ -195,19 +195,19 @@ checkOptree ( name => 'my $a=undef', bcopts => '-basic', strip_open_hints => 1, expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); -6 <@> leave[1 ref] vKP/REFC ->(end) +5 <@> leave[1 ref] vKP/REFC ->(end) 1 <0> enter v ->2 2 <;> nextstate(main 1 -e:1) v:>,<,%,{ ->3 -5 <2> sassign vKS/2 ->6 +4 <1> padsv_store[$a:1,2] vKS/LVINTRO ->5 3 <0> undef s ->4 -4 <0> padsv[$a:1,2] sRM*/LVINTRO ->5 +- <0> ex-padsv sRM*/LVINTRO ->4 EOT_EOT -# 6 <@> leave[1 ref] vKP/REFC ->(end) +# 5 <@> leave[1 ref] vKP/REFC ->(end) # 1 <0> enter v ->2 # 2 <;> nextstate(main 1 -e:1) v:>,<,%,{ ->3 -# 5 <2> sassign vKS/2 ->6 +# 4 <1> padsv_store[$a:1,2] vKS/LVINTRO ->5 # 3 <0> undef s ->4 -# 4 <0> padsv[$a:1,2] sRM*/LVINTRO ->5 +# - <0> ex-padsv sRM*/LVINTRO ->4 EONT_EONT checkOptree ( name => 'our $a=undef', @@ -264,15 +264,13 @@ checkOptree ( name => 'sub {my $a=()}', expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT'); 1 <;> nextstate(main -439 optree.t:105) v:>,<,% 2 <0> stub sP -3 <0> padsv[$a:-439,-438] sRM*/LVINTRO -4 <2> sassign sKS/2 -5 <1> leavesub[1 ref] K/REFC,1 +3 <1> padsv_store[$a:1516,1517] sKS/LVINTRO +4 <1> leavesub[1 ref] K/REFC,1 EOT_EOT # 1 <;> nextstate(main 438 optree_varinit.t:247) v:>,<,% # 2 <0> stub sP -# 3 <0> padsv[$a:438,439] sRM*/LVINTRO -# 4 <2> sassign sKS/2 -# 5 <1> leavesub[1 ref] K/REFC,1 +# 3 <1> padsv_store[$a:1516,1517] sKS/LVINTRO +# 4 <1> leavesub[1 ref] K/REFC,1 EONT_EONT checkOptree ( name => 'sub {our $a=()}', @@ -321,16 +319,14 @@ checkOptree ( name => 'my $a=()', 1 <0> enter v 2 <;> nextstate(main 1 -e:1) v:>,<,%,{ 3 <0> stub sP -4 <0> padsv[$a:1,2] sRM*/LVINTRO -5 <2> sassign vKS/2 -6 <@> leave[1 ref] vKP/REFC +4 <1> padsv_store[$a:1516,1517] vKS/LVINTRO +5 <@> leave[1 ref] vKP/REFC EOT_EOT # 1 <0> enter v # 2 <;> nextstate(main 1 -e:1) v:>,<,%,{ # 3 <0> stub sP -# 4 <0> padsv[$a:1,2] sRM*/LVINTRO -# 5 <2> sassign vKS/2 -# 6 <@> leave[1 ref] vKP/REFC +# 4 <1> padsv_store[$a:1516,1517] vKS/LVINTRO +# 5 <@> leave[1 ref] vKP/REFC EONT_EONT checkOptree ( name => 'our $a=()', diff --git a/ext/Opcode/Opcode.pm b/ext/Opcode/Opcode.pm index b70960101591..7a675d3b7b1c 100644 --- a/ext/Opcode/Opcode.pm +++ b/ext/Opcode/Opcode.pm @@ -1,4 +1,4 @@ -package Opcode 1.59; +package Opcode 1.60; use strict; @@ -302,7 +302,7 @@ invert_opset function. null stub scalar pushmark wantarray const defined undef - rv2sv sassign + rv2sv sassign padsv_store rv2av aassign aelem aelemfast aelemfast_lex aslice kvaslice av2arylen diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm index ca37d110b2ec..52eec0f77f47 100644 --- a/lib/B/Deparse.pm +++ b/lib/B/Deparse.pm @@ -7,7 +7,7 @@ # This is based on the module of the same name by Malcolm Beattie, # but essentially none of his code remains. -package B::Deparse 1.67; +package B::Deparse 1.68; use strict; use Carp; use B qw(class main_root main_start main_cv svref_2object opnumber perlstring @@ -3092,6 +3092,18 @@ sub pp_isa { binop(@_, "isa", 15) } sub pp_sassign { binop(@_, "=", 7, SWAP_CHILDREN) } sub pp_aassign { binop(@_, "=", 7, SWAP_CHILDREN | LIST_CONTEXT) } +sub pp_padsv_store { + my $self = shift; + my ($op, $cx, $forbid_parens, @args) = @_; + my $targ = $op->targ; + my $var = $self->maybe_my($op, $cx, $self->padname($targ), + $self->padname_sv($targ), + $forbid_parens); + + my $val = $self->deparse($op->first, 7); + return $self->maybe_parens("$var = $val", $cx, 7); +} + sub pp_smartmatch { my ($self, $op, $cx) = @_; if (($op->flags & OPf_SPECIAL) && $self->{expand} < 2) { diff --git a/lib/B/Op_private.pm b/lib/B/Op_private.pm index afa1e80f798d..84befff941ff 100644 --- a/lib/B/Op_private.pm +++ b/lib/B/Op_private.pm @@ -134,7 +134,7 @@ $bits{$_}{6} = 'OPpINDEX_BOOLNEG' for qw(index rindex); $bits{$_}{1} = 'OPpITER_REVERSED' for qw(enteriter iter); $bits{$_}{7} = 'OPpLVALUE' for qw(leave leaveloop); $bits{$_}{6} = 'OPpLVAL_DEFER' for qw(aelem helem multideref); -$bits{$_}{7} = 'OPpLVAL_INTRO' for qw(aelem aslice cond_expr delete enteriter entersub gvsv helem hslice list lvavref lvref lvrefslice multiconcat multideref padav padhv padrange padsv pushmark refassign rv2av rv2gv rv2hv rv2sv split); +$bits{$_}{7} = 'OPpLVAL_INTRO' for qw(aelem aslice cond_expr delete enteriter entersub gvsv helem hslice list lvavref lvref lvrefslice multiconcat multideref padav padhv padrange padsv padsv_store pushmark refassign rv2av rv2gv rv2hv rv2sv split); $bits{$_}{2} = 'OPpLVREF_ELEM' for qw(lvref refassign); $bits{$_}{3} = 'OPpLVREF_ITER' for qw(lvref refassign); $bits{$_}{3} = 'OPpMAYBE_LVSUB' for qw(aassign aelem akeys aslice av2arylen avhvswitch helem hslice keys kvaslice kvhslice multideref padav padhv pos rv2av rv2gv rv2hv substr values vec); @@ -145,7 +145,7 @@ $bits{$_}{4} = 'OPpOPEN_IN_RAW' for qw(backtick open); $bits{$_}{7} = 'OPpOPEN_OUT_CRLF' for qw(backtick open); $bits{$_}{6} = 'OPpOPEN_OUT_RAW' for qw(backtick open); $bits{$_}{6} = 'OPpOUR_INTRO' for qw(enteriter gvsv rv2av rv2hv rv2sv split); -$bits{$_}{6} = 'OPpPAD_STATE' for qw(lvavref lvref padav padhv padsv pushmark refassign); +$bits{$_}{6} = 'OPpPAD_STATE' for qw(lvavref lvref padav padhv padsv padsv_store pushmark refassign); $bits{$_}{7} = 'OPpPV_IS_UTF8' for qw(dump goto last next redo); $bits{$_}{6} = 'OPpREFCOUNTED' for qw(leave leaveeval leavesub leavesublv leavewrite); $bits{$_}{2} = 'OPpSLICEWARNING' for qw(aslice hslice padav padhv rv2av rv2hv); @@ -465,6 +465,7 @@ $bits{ord}{0} = $bf[0]; $bits{padhv}{0} = 'OPpPADHV_ISKEYS'; @{$bits{padrange}}{6,5,4,3,2,1,0} = ($bf[5], $bf[5], $bf[5], $bf[5], $bf[5], $bf[5], $bf[5]); @{$bits{padsv}}{5,4} = ($bf[8], $bf[8]); +$bits{padsv_store}{0} = $bf[0]; @{$bits{pipe_op}}{3,2,1,0} = ($bf[4], $bf[4], $bf[4], $bf[4]); $bits{pop}{0} = $bf[0]; $bits{pos}{0} = $bf[0]; @@ -830,7 +831,7 @@ our %ops_using = ( OPpLIST_GUESSED => [qw(list)], OPpLVALUE => [qw(leave leaveloop)], OPpLVAL_DEFER => [qw(aelem helem multideref)], - OPpLVAL_INTRO => [qw(aelem aslice cond_expr delete enteriter entersub gvsv helem hslice list lvavref lvref lvrefslice multiconcat multideref padav padhv padrange padsv pushmark refassign rv2av rv2gv rv2hv rv2sv split)], + OPpLVAL_INTRO => [qw(aelem aslice cond_expr delete enteriter entersub gvsv helem hslice list lvavref lvref lvrefslice multiconcat multideref padav padhv padrange padsv padsv_store pushmark refassign rv2av rv2gv rv2hv rv2sv split)], OPpLVREF_ELEM => [qw(lvref refassign)], OPpMAYBE_LVSUB => [qw(aassign aelem akeys aslice av2arylen avhvswitch helem hslice keys kvaslice kvhslice multideref padav padhv pos rv2av rv2gv rv2hv substr values vec)], OPpMAYBE_TRUEBOOL => [qw(blessed padhv ref rv2hv)], @@ -840,7 +841,7 @@ our %ops_using = ( OPpOPEN_IN_CRLF => [qw(backtick open)], OPpOUR_INTRO => [qw(enteriter gvsv rv2av rv2hv rv2sv split)], OPpPADHV_ISKEYS => [qw(padhv)], - OPpPAD_STATE => [qw(lvavref lvref padav padhv padsv pushmark refassign)], + OPpPAD_STATE => [qw(lvavref lvref padav padhv padsv padsv_store pushmark refassign)], OPpPV_IS_UTF8 => [qw(dump goto last next redo)], OPpREFCOUNTED => [qw(leave leaveeval leavesub leavesublv leavewrite)], OPpREPEAT_DOLIST => [qw(repeat)], diff --git a/opcode.h b/opcode.h index 7e2d07c3c19e..161b94387ddc 100644 --- a/opcode.h +++ b/opcode.h @@ -159,6 +159,7 @@ EXTCONST char* const PL_op_name[] = { "gv", "gelem", "padsv", + "padsv_store", "padav", "padhv", "padany", @@ -582,6 +583,7 @@ EXTCONST char* const PL_op_desc[] = { "glob value", "glob elem", "private variable", + "padsv scalar assignment", "private array", "private hash", "private value", @@ -1008,6 +1010,7 @@ EXT Perl_ppaddr_t PL_ppaddr[] /* or perlvars.h */ Perl_pp_gv, Perl_pp_gelem, Perl_pp_padsv, + Perl_pp_padsv_store, Perl_pp_padav, Perl_pp_padhv, Perl_pp_padany, /* implemented by Perl_unimplemented_op */ @@ -1430,6 +1433,7 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */ Perl_ck_null, /* gv */ Perl_ck_null, /* gelem */ Perl_ck_null, /* padsv */ + Perl_ck_sassign, /* padsv_store */ Perl_ck_null, /* padav */ Perl_ck_null, /* padhv */ Perl_ck_null, /* padany */ @@ -1853,6 +1857,7 @@ EXTCONST U32 PL_opargs[] = { 0x00000644, /* gv */ 0x00011244, /* gelem */ 0x00000044, /* padsv */ + 0x00011104, /* padsv_store */ 0x00000040, /* padav */ 0x00000040, /* padhv */ 0x00000040, /* padany */ @@ -2535,21 +2540,22 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 11, /* gv */ 12, /* gelem */ 13, /* padsv */ - 16, /* padav */ - 21, /* padhv */ + 16, /* padsv_store */ + 19, /* padav */ + 24, /* padhv */ -1, /* padany */ - 28, /* rv2gv */ - 35, /* rv2sv */ - 40, /* av2arylen */ - 42, /* rv2cv */ + 31, /* rv2gv */ + 38, /* rv2sv */ + 43, /* av2arylen */ + 45, /* rv2cv */ -1, /* anoncode */ 0, /* prototype */ 0, /* refgen */ 0, /* srefgen */ - 49, /* ref */ - 52, /* bless */ - 53, /* backtick */ - 52, /* glob */ + 52, /* ref */ + 55, /* bless */ + 56, /* backtick */ + 55, /* glob */ 0, /* readline */ -1, /* rcatline */ 0, /* regcmaybe */ @@ -2557,20 +2563,20 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 0, /* regcomp */ -1, /* match */ -1, /* qr */ - 58, /* subst */ + 61, /* subst */ 0, /* substcont */ - 59, /* trans */ - 59, /* transr */ - 66, /* sassign */ - 69, /* aassign */ + 62, /* trans */ + 62, /* transr */ + 69, /* sassign */ + 72, /* aassign */ 0, /* chop */ 0, /* schop */ - 75, /* chomp */ - 75, /* schomp */ + 78, /* chomp */ + 78, /* schomp */ 0, /* defined */ 0, /* undef */ 0, /* study */ - 77, /* pos */ + 80, /* pos */ 0, /* preinc */ 0, /* i_preinc */ 0, /* predec */ @@ -2579,23 +2585,23 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 0, /* i_postinc */ 0, /* postdec */ 0, /* i_postdec */ - 80, /* pow */ - 80, /* multiply */ - 80, /* i_multiply */ - 80, /* divide */ - 80, /* i_divide */ - 80, /* modulo */ - 80, /* i_modulo */ - 82, /* repeat */ - 80, /* add */ - 80, /* i_add */ - 80, /* subtract */ - 80, /* i_subtract */ - 84, /* concat */ - 87, /* multiconcat */ - 93, /* stringify */ - 95, /* left_shift */ - 95, /* right_shift */ + 83, /* pow */ + 83, /* multiply */ + 83, /* i_multiply */ + 83, /* divide */ + 83, /* i_divide */ + 83, /* modulo */ + 83, /* i_modulo */ + 85, /* repeat */ + 83, /* add */ + 83, /* i_add */ + 83, /* subtract */ + 83, /* i_subtract */ + 87, /* concat */ + 90, /* multiconcat */ + 96, /* stringify */ + 98, /* left_shift */ + 98, /* right_shift */ 12, /* lt */ 12, /* i_lt */ 12, /* gt */ @@ -2617,126 +2623,126 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 12, /* seq */ 12, /* sne */ 12, /* scmp */ - 97, /* bit_and */ - 97, /* bit_xor */ - 97, /* bit_or */ - 95, /* nbit_and */ - 95, /* nbit_xor */ - 95, /* nbit_or */ - 97, /* sbit_and */ - 97, /* sbit_xor */ - 97, /* sbit_or */ + 100, /* bit_and */ + 100, /* bit_xor */ + 100, /* bit_or */ + 98, /* nbit_and */ + 98, /* nbit_xor */ + 98, /* nbit_or */ + 100, /* sbit_and */ + 100, /* sbit_xor */ + 100, /* sbit_or */ 0, /* negate */ 0, /* i_negate */ 0, /* not */ - 97, /* complement */ - 95, /* ncomplement */ - 75, /* scomplement */ + 100, /* complement */ + 98, /* ncomplement */ + 78, /* scomplement */ 12, /* smartmatch */ - 93, /* atan2 */ - 75, /* sin */ - 75, /* cos */ - 93, /* rand */ - 93, /* srand */ - 75, /* exp */ - 75, /* log */ - 75, /* sqrt */ - 75, /* int */ - 75, /* hex */ - 75, /* oct */ - 75, /* abs */ - 98, /* length */ - 101, /* substr */ - 104, /* vec */ - 106, /* index */ - 106, /* rindex */ - 52, /* sprintf */ - 52, /* formline */ - 75, /* ord */ - 75, /* chr */ - 93, /* crypt */ + 96, /* atan2 */ + 78, /* sin */ + 78, /* cos */ + 96, /* rand */ + 96, /* srand */ + 78, /* exp */ + 78, /* log */ + 78, /* sqrt */ + 78, /* int */ + 78, /* hex */ + 78, /* oct */ + 78, /* abs */ + 101, /* length */ + 104, /* substr */ + 107, /* vec */ + 109, /* index */ + 109, /* rindex */ + 55, /* sprintf */ + 55, /* formline */ + 78, /* ord */ + 78, /* chr */ + 96, /* crypt */ 0, /* ucfirst */ 0, /* lcfirst */ 0, /* uc */ 0, /* lc */ 0, /* quotemeta */ - 110, /* rv2av */ - 117, /* aelemfast */ - 117, /* aelemfast_lex */ - 118, /* aelem */ - 123, /* aslice */ - 126, /* kvaslice */ + 113, /* rv2av */ + 120, /* aelemfast */ + 120, /* aelemfast_lex */ + 121, /* aelem */ + 126, /* aslice */ + 129, /* kvaslice */ 0, /* aeach */ 0, /* avalues */ - 40, /* akeys */ + 43, /* akeys */ 0, /* each */ - 40, /* values */ - 40, /* keys */ - 127, /* delete */ - 131, /* exists */ - 133, /* rv2hv */ - 118, /* helem */ - 123, /* hslice */ - 126, /* kvhslice */ - 141, /* multideref */ - 52, /* unpack */ - 52, /* pack */ - 148, /* split */ - 52, /* join */ - 153, /* list */ + 43, /* values */ + 43, /* keys */ + 130, /* delete */ + 134, /* exists */ + 136, /* rv2hv */ + 121, /* helem */ + 126, /* hslice */ + 129, /* kvhslice */ + 144, /* multideref */ + 55, /* unpack */ + 55, /* pack */ + 151, /* split */ + 55, /* join */ + 156, /* list */ 12, /* lslice */ - 52, /* anonlist */ - 52, /* anonhash */ - 52, /* splice */ - 93, /* push */ + 55, /* anonlist */ + 55, /* anonhash */ + 55, /* splice */ + 96, /* push */ 0, /* pop */ 0, /* shift */ - 93, /* unshift */ - 155, /* sort */ - 160, /* reverse */ + 96, /* unshift */ + 158, /* sort */ + 163, /* reverse */ 0, /* grepstart */ - 162, /* grepwhile */ + 165, /* grepwhile */ 0, /* mapstart */ 0, /* mapwhile */ 0, /* range */ - 164, /* flip */ - 164, /* flop */ + 167, /* flip */ + 167, /* flop */ 0, /* and */ 0, /* or */ 12, /* xor */ 0, /* dor */ - 166, /* cond_expr */ + 169, /* cond_expr */ 0, /* andassign */ 0, /* orassign */ 0, /* dorassign */ - 168, /* entersub */ - 175, /* leavesub */ - 175, /* leavesublv */ + 171, /* entersub */ + 178, /* leavesub */ + 178, /* leavesublv */ 0, /* argcheck */ - 177, /* argelem */ + 180, /* argelem */ 0, /* argdefelem */ - 179, /* caller */ - 52, /* warn */ - 52, /* die */ - 52, /* reset */ + 182, /* caller */ + 55, /* warn */ + 55, /* die */ + 55, /* reset */ -1, /* lineseq */ - 181, /* nextstate */ - 181, /* dbstate */ + 184, /* nextstate */ + 184, /* dbstate */ -1, /* unstack */ -1, /* enter */ - 182, /* leave */ + 185, /* leave */ -1, /* scope */ - 184, /* enteriter */ - 188, /* iter */ + 187, /* enteriter */ + 191, /* iter */ -1, /* enterloop */ - 189, /* leaveloop */ + 192, /* leaveloop */ -1, /* return */ - 191, /* last */ - 191, /* next */ - 191, /* redo */ - 191, /* dump */ - 191, /* goto */ - 52, /* exit */ + 194, /* last */ + 194, /* next */ + 194, /* redo */ + 194, /* dump */ + 194, /* goto */ + 55, /* exit */ 0, /* method */ 0, /* method_named */ 0, /* method_super */ @@ -2748,143 +2754,143 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 0, /* leavewhen */ -1, /* break */ -1, /* continue */ - 193, /* open */ - 52, /* close */ - 52, /* pipe_op */ - 52, /* fileno */ - 52, /* umask */ - 52, /* binmode */ - 52, /* tie */ + 196, /* open */ + 55, /* close */ + 55, /* pipe_op */ + 55, /* fileno */ + 55, /* umask */ + 55, /* binmode */ + 55, /* tie */ 0, /* untie */ 0, /* tied */ - 52, /* dbmopen */ + 55, /* dbmopen */ 0, /* dbmclose */ - 52, /* sselect */ - 52, /* select */ - 52, /* getc */ - 52, /* read */ - 52, /* enterwrite */ - 175, /* leavewrite */ + 55, /* sselect */ + 55, /* select */ + 55, /* getc */ + 55, /* read */ + 55, /* enterwrite */ + 178, /* leavewrite */ -1, /* prtf */ -1, /* print */ -1, /* say */ - 52, /* sysopen */ - 52, /* sysseek */ - 52, /* sysread */ - 52, /* syswrite */ - 52, /* eof */ - 52, /* tell */ - 52, /* seek */ - 52, /* truncate */ - 52, /* fcntl */ - 52, /* ioctl */ - 93, /* flock */ - 52, /* send */ - 52, /* recv */ - 52, /* socket */ - 52, /* sockpair */ - 52, /* bind */ - 52, /* connect */ - 52, /* listen */ - 52, /* accept */ - 52, /* shutdown */ - 52, /* gsockopt */ - 52, /* ssockopt */ + 55, /* sysopen */ + 55, /* sysseek */ + 55, /* sysread */ + 55, /* syswrite */ + 55, /* eof */ + 55, /* tell */ + 55, /* seek */ + 55, /* truncate */ + 55, /* fcntl */ + 55, /* ioctl */ + 96, /* flock */ + 55, /* send */ + 55, /* recv */ + 55, /* socket */ + 55, /* sockpair */ + 55, /* bind */ + 55, /* connect */ + 55, /* listen */ + 55, /* accept */ + 55, /* shutdown */ + 55, /* gsockopt */ + 55, /* ssockopt */ 0, /* getsockname */ 0, /* getpeername */ 0, /* lstat */ 0, /* stat */ - 198, /* ftrread */ - 198, /* ftrwrite */ - 198, /* ftrexec */ - 198, /* fteread */ - 198, /* ftewrite */ - 198, /* fteexec */ - 203, /* ftis */ - 203, /* ftsize */ - 203, /* ftmtime */ - 203, /* ftatime */ - 203, /* ftctime */ - 203, /* ftrowned */ - 203, /* fteowned */ - 203, /* ftzero */ - 203, /* ftsock */ - 203, /* ftchr */ - 203, /* ftblk */ - 203, /* ftfile */ - 203, /* ftdir */ - 203, /* ftpipe */ - 203, /* ftsuid */ - 203, /* ftsgid */ - 203, /* ftsvtx */ - 203, /* ftlink */ - 203, /* fttty */ - 203, /* fttext */ - 203, /* ftbinary */ - 93, /* chdir */ - 93, /* chown */ - 75, /* chroot */ - 93, /* unlink */ - 93, /* chmod */ - 93, /* utime */ - 93, /* rename */ - 93, /* link */ - 93, /* symlink */ + 201, /* ftrread */ + 201, /* ftrwrite */ + 201, /* ftrexec */ + 201, /* fteread */ + 201, /* ftewrite */ + 201, /* fteexec */ + 206, /* ftis */ + 206, /* ftsize */ + 206, /* ftmtime */ + 206, /* ftatime */ + 206, /* ftctime */ + 206, /* ftrowned */ + 206, /* fteowned */ + 206, /* ftzero */ + 206, /* ftsock */ + 206, /* ftchr */ + 206, /* ftblk */ + 206, /* ftfile */ + 206, /* ftdir */ + 206, /* ftpipe */ + 206, /* ftsuid */ + 206, /* ftsgid */ + 206, /* ftsvtx */ + 206, /* ftlink */ + 206, /* fttty */ + 206, /* fttext */ + 206, /* ftbinary */ + 96, /* chdir */ + 96, /* chown */ + 78, /* chroot */ + 96, /* unlink */ + 96, /* chmod */ + 96, /* utime */ + 96, /* rename */ + 96, /* link */ + 96, /* symlink */ 0, /* readlink */ - 93, /* mkdir */ - 75, /* rmdir */ - 52, /* open_dir */ + 96, /* mkdir */ + 78, /* rmdir */ + 55, /* open_dir */ 0, /* readdir */ 0, /* telldir */ - 52, /* seekdir */ + 55, /* seekdir */ 0, /* rewinddir */ 0, /* closedir */ -1, /* fork */ - 207, /* wait */ - 93, /* waitpid */ - 93, /* system */ - 93, /* exec */ - 93, /* kill */ - 207, /* getppid */ - 93, /* getpgrp */ - 93, /* setpgrp */ - 93, /* getpriority */ - 93, /* setpriority */ - 207, /* time */ + 210, /* wait */ + 96, /* waitpid */ + 96, /* system */ + 96, /* exec */ + 96, /* kill */ + 210, /* getppid */ + 96, /* getpgrp */ + 96, /* setpgrp */ + 96, /* getpriority */ + 96, /* setpriority */ + 210, /* time */ -1, /* tms */ 0, /* localtime */ - 52, /* gmtime */ + 55, /* gmtime */ 0, /* alarm */ - 93, /* sleep */ - 52, /* shmget */ - 52, /* shmctl */ - 52, /* shmread */ - 52, /* shmwrite */ - 52, /* msgget */ - 52, /* msgctl */ - 52, /* msgsnd */ - 52, /* msgrcv */ - 52, /* semop */ - 52, /* semget */ - 52, /* semctl */ + 96, /* sleep */ + 55, /* shmget */ + 55, /* shmctl */ + 55, /* shmread */ + 55, /* shmwrite */ + 55, /* msgget */ + 55, /* msgctl */ + 55, /* msgsnd */ + 55, /* msgrcv */ + 55, /* semop */ + 55, /* semget */ + 55, /* semctl */ 0, /* require */ 0, /* dofile */ -1, /* hintseval */ - 208, /* entereval */ - 175, /* leaveeval */ + 211, /* entereval */ + 178, /* leaveeval */ 0, /* entertry */ -1, /* leavetry */ 0, /* ghbyname */ - 52, /* ghbyaddr */ + 55, /* ghbyaddr */ -1, /* ghostent */ 0, /* gnbyname */ - 52, /* gnbyaddr */ + 55, /* gnbyaddr */ -1, /* gnetent */ 0, /* gpbyname */ - 52, /* gpbynumber */ + 55, /* gpbynumber */ -1, /* gprotoent */ - 52, /* gsbyname */ - 52, /* gsbyport */ + 55, /* gsbyname */ + 55, /* gsbyport */ -1, /* gservent */ 0, /* shostent */ 0, /* snetent */ @@ -2905,22 +2911,22 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { -1, /* sgrent */ -1, /* egrent */ -1, /* getlogin */ - 52, /* syscall */ + 55, /* syscall */ 0, /* lock */ 0, /* once */ -1, /* custom */ - 214, /* coreargs */ - 218, /* avhvswitch */ + 217, /* coreargs */ + 221, /* avhvswitch */ 3, /* runcv */ 0, /* fc */ -1, /* padcv */ -1, /* introcv */ -1, /* clonecv */ - 220, /* padrange */ - 222, /* refassign */ - 228, /* lvref */ - 234, /* lvrefslice */ - 235, /* lvavref */ + 223, /* padrange */ + 225, /* refassign */ + 231, /* lvref */ + 237, /* lvrefslice */ + 16, /* lvavref */ 0, /* anonconst */ 12, /* isa */ 0, /* cmpchain_and */ @@ -2934,11 +2940,11 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 0, /* is_weak */ 0, /* weaken */ 0, /* unweaken */ - 49, /* blessed */ - 75, /* refaddr */ - 75, /* reftype */ - 75, /* ceil */ - 75, /* floor */ + 52, /* blessed */ + 78, /* refaddr */ + 78, /* reftype */ + 78, /* ceil */ + 78, /* floor */ 0, /* is_tainted */ }; @@ -2966,6 +2972,7 @@ EXTCONST U16 PL_op_private_bitdefs[] = { 0x18b5, /* gv */ 0x0067, /* gelem, lt, i_lt, gt, i_gt, le, i_le, ge, i_ge, eq, i_eq, ne, i_ne, ncmp, i_ncmp, slt, sgt, sle, sge, seq, sne, scmp, smartmatch, lslice, xor, isa */ 0x30dc, 0x41d8, 0x03d7, /* padsv */ + 0x30dc, 0x41d8, 0x0003, /* padsv_store, lvavref */ 0x30dc, 0x41d8, 0x05b4, 0x31cc, 0x3fa9, /* padav */ 0x30dc, 0x41d8, 0x05b4, 0x0650, 0x31cc, 0x3fa8, 0x2c41, /* padhv */ 0x30dc, 0x1c38, 0x03d6, 0x31cc, 0x3528, 0x4284, 0x0003, /* rv2gv */ @@ -3029,7 +3036,6 @@ EXTCONST U16 PL_op_private_bitdefs[] = { 0x30dc, 0x41d8, 0x04f6, 0x2bac, 0x19a8, 0x0067, /* refassign */ 0x30dc, 0x41d8, 0x04f6, 0x2bac, 0x19a8, 0x0003, /* lvref */ 0x30dd, /* lvrefslice */ - 0x30dc, 0x41d8, 0x0003, /* lvavref */ 0x1cdc, 0x0003, /* pushdefer */ }; @@ -3049,6 +3055,7 @@ EXTCONST U8 PL_op_private_valid[] = { /* GV */ (OPpEARLY_CV), /* GELEM */ (OPpARG2_MASK), /* PADSV */ (OPpDEREF|OPpPAD_STATE|OPpLVAL_INTRO), + /* PADSV_STORE */ (OPpARG1_MASK|OPpPAD_STATE|OPpLVAL_INTRO), /* PADAV */ (OPpSLICEWARNING|OPpMAYBE_LVSUB|OPpTRUEBOOL|OPpPAD_STATE|OPpLVAL_INTRO), /* PADHV */ (OPpPADHV_ISKEYS|OPpSLICEWARNING|OPpMAYBE_LVSUB|OPpMAYBE_TRUEBOOL|OPpTRUEBOOL|OPpPAD_STATE|OPpLVAL_INTRO), /* PADANY */ (0), diff --git a/opnames.h b/opnames.h index e269a9703ca8..24c0245ea2a9 100644 --- a/opnames.h +++ b/opnames.h @@ -24,415 +24,416 @@ typedef enum opcode { OP_GV = 7, OP_GELEM = 8, OP_PADSV = 9, - OP_PADAV = 10, - OP_PADHV = 11, - OP_PADANY = 12, - OP_RV2GV = 13, - OP_RV2SV = 14, - OP_AV2ARYLEN = 15, - OP_RV2CV = 16, - OP_ANONCODE = 17, - OP_PROTOTYPE = 18, - OP_REFGEN = 19, - OP_SREFGEN = 20, - OP_REF = 21, - OP_BLESS = 22, - OP_BACKTICK = 23, - OP_GLOB = 24, - OP_READLINE = 25, - OP_RCATLINE = 26, - OP_REGCMAYBE = 27, - OP_REGCRESET = 28, - OP_REGCOMP = 29, - OP_MATCH = 30, - OP_QR = 31, - OP_SUBST = 32, - OP_SUBSTCONT = 33, - OP_TRANS = 34, - OP_TRANSR = 35, - OP_SASSIGN = 36, - OP_AASSIGN = 37, - OP_CHOP = 38, - OP_SCHOP = 39, - OP_CHOMP = 40, - OP_SCHOMP = 41, - OP_DEFINED = 42, - OP_UNDEF = 43, - OP_STUDY = 44, - OP_POS = 45, - OP_PREINC = 46, - OP_I_PREINC = 47, - OP_PREDEC = 48, - OP_I_PREDEC = 49, - OP_POSTINC = 50, - OP_I_POSTINC = 51, - OP_POSTDEC = 52, - OP_I_POSTDEC = 53, - OP_POW = 54, - OP_MULTIPLY = 55, - OP_I_MULTIPLY = 56, - OP_DIVIDE = 57, - OP_I_DIVIDE = 58, - OP_MODULO = 59, - OP_I_MODULO = 60, - OP_REPEAT = 61, - OP_ADD = 62, - OP_I_ADD = 63, - OP_SUBTRACT = 64, - OP_I_SUBTRACT = 65, - OP_CONCAT = 66, - OP_MULTICONCAT = 67, - OP_STRINGIFY = 68, - OP_LEFT_SHIFT = 69, - OP_RIGHT_SHIFT = 70, - OP_LT = 71, - OP_I_LT = 72, - OP_GT = 73, - OP_I_GT = 74, - OP_LE = 75, - OP_I_LE = 76, - OP_GE = 77, - OP_I_GE = 78, - OP_EQ = 79, - OP_I_EQ = 80, - OP_NE = 81, - OP_I_NE = 82, - OP_NCMP = 83, - OP_I_NCMP = 84, - OP_SLT = 85, - OP_SGT = 86, - OP_SLE = 87, - OP_SGE = 88, - OP_SEQ = 89, - OP_SNE = 90, - OP_SCMP = 91, - OP_BIT_AND = 92, - OP_BIT_XOR = 93, - OP_BIT_OR = 94, - OP_NBIT_AND = 95, - OP_NBIT_XOR = 96, - OP_NBIT_OR = 97, - OP_SBIT_AND = 98, - OP_SBIT_XOR = 99, - OP_SBIT_OR = 100, - OP_NEGATE = 101, - OP_I_NEGATE = 102, - OP_NOT = 103, - OP_COMPLEMENT = 104, - OP_NCOMPLEMENT = 105, - OP_SCOMPLEMENT = 106, - OP_SMARTMATCH = 107, - OP_ATAN2 = 108, - OP_SIN = 109, - OP_COS = 110, - OP_RAND = 111, - OP_SRAND = 112, - OP_EXP = 113, - OP_LOG = 114, - OP_SQRT = 115, - OP_INT = 116, - OP_HEX = 117, - OP_OCT = 118, - OP_ABS = 119, - OP_LENGTH = 120, - OP_SUBSTR = 121, - OP_VEC = 122, - OP_INDEX = 123, - OP_RINDEX = 124, - OP_SPRINTF = 125, - OP_FORMLINE = 126, - OP_ORD = 127, - OP_CHR = 128, - OP_CRYPT = 129, - OP_UCFIRST = 130, - OP_LCFIRST = 131, - OP_UC = 132, - OP_LC = 133, - OP_QUOTEMETA = 134, - OP_RV2AV = 135, - OP_AELEMFAST = 136, - OP_AELEMFAST_LEX = 137, - OP_AELEM = 138, - OP_ASLICE = 139, - OP_KVASLICE = 140, - OP_AEACH = 141, - OP_AVALUES = 142, - OP_AKEYS = 143, - OP_EACH = 144, - OP_VALUES = 145, - OP_KEYS = 146, - OP_DELETE = 147, - OP_EXISTS = 148, - OP_RV2HV = 149, - OP_HELEM = 150, - OP_HSLICE = 151, - OP_KVHSLICE = 152, - OP_MULTIDEREF = 153, - OP_UNPACK = 154, - OP_PACK = 155, - OP_SPLIT = 156, - OP_JOIN = 157, - OP_LIST = 158, - OP_LSLICE = 159, - OP_ANONLIST = 160, - OP_ANONHASH = 161, - OP_SPLICE = 162, - OP_PUSH = 163, - OP_POP = 164, - OP_SHIFT = 165, - OP_UNSHIFT = 166, - OP_SORT = 167, - OP_REVERSE = 168, - OP_GREPSTART = 169, - OP_GREPWHILE = 170, - OP_MAPSTART = 171, - OP_MAPWHILE = 172, - OP_RANGE = 173, - OP_FLIP = 174, - OP_FLOP = 175, - OP_AND = 176, - OP_OR = 177, - OP_XOR = 178, - OP_DOR = 179, - OP_COND_EXPR = 180, - OP_ANDASSIGN = 181, - OP_ORASSIGN = 182, - OP_DORASSIGN = 183, - OP_ENTERSUB = 184, - OP_LEAVESUB = 185, - OP_LEAVESUBLV = 186, - OP_ARGCHECK = 187, - OP_ARGELEM = 188, - OP_ARGDEFELEM = 189, - OP_CALLER = 190, - OP_WARN = 191, - OP_DIE = 192, - OP_RESET = 193, - OP_LINESEQ = 194, - OP_NEXTSTATE = 195, - OP_DBSTATE = 196, - OP_UNSTACK = 197, - OP_ENTER = 198, - OP_LEAVE = 199, - OP_SCOPE = 200, - OP_ENTERITER = 201, - OP_ITER = 202, - OP_ENTERLOOP = 203, - OP_LEAVELOOP = 204, - OP_RETURN = 205, - OP_LAST = 206, - OP_NEXT = 207, - OP_REDO = 208, - OP_DUMP = 209, - OP_GOTO = 210, - OP_EXIT = 211, - OP_METHOD = 212, - OP_METHOD_NAMED = 213, - OP_METHOD_SUPER = 214, - OP_METHOD_REDIR = 215, - OP_METHOD_REDIR_SUPER = 216, - OP_ENTERGIVEN = 217, - OP_LEAVEGIVEN = 218, - OP_ENTERWHEN = 219, - OP_LEAVEWHEN = 220, - OP_BREAK = 221, - OP_CONTINUE = 222, - OP_OPEN = 223, - OP_CLOSE = 224, - OP_PIPE_OP = 225, - OP_FILENO = 226, - OP_UMASK = 227, - OP_BINMODE = 228, - OP_TIE = 229, - OP_UNTIE = 230, - OP_TIED = 231, - OP_DBMOPEN = 232, - OP_DBMCLOSE = 233, - OP_SSELECT = 234, - OP_SELECT = 235, - OP_GETC = 236, - OP_READ = 237, - OP_ENTERWRITE = 238, - OP_LEAVEWRITE = 239, - OP_PRTF = 240, - OP_PRINT = 241, - OP_SAY = 242, - OP_SYSOPEN = 243, - OP_SYSSEEK = 244, - OP_SYSREAD = 245, - OP_SYSWRITE = 246, - OP_EOF = 247, - OP_TELL = 248, - OP_SEEK = 249, - OP_TRUNCATE = 250, - OP_FCNTL = 251, - OP_IOCTL = 252, - OP_FLOCK = 253, - OP_SEND = 254, - OP_RECV = 255, - OP_SOCKET = 256, - OP_SOCKPAIR = 257, - OP_BIND = 258, - OP_CONNECT = 259, - OP_LISTEN = 260, - OP_ACCEPT = 261, - OP_SHUTDOWN = 262, - OP_GSOCKOPT = 263, - OP_SSOCKOPT = 264, - OP_GETSOCKNAME = 265, - OP_GETPEERNAME = 266, - OP_LSTAT = 267, - OP_STAT = 268, - OP_FTRREAD = 269, - OP_FTRWRITE = 270, - OP_FTREXEC = 271, - OP_FTEREAD = 272, - OP_FTEWRITE = 273, - OP_FTEEXEC = 274, - OP_FTIS = 275, - OP_FTSIZE = 276, - OP_FTMTIME = 277, - OP_FTATIME = 278, - OP_FTCTIME = 279, - OP_FTROWNED = 280, - OP_FTEOWNED = 281, - OP_FTZERO = 282, - OP_FTSOCK = 283, - OP_FTCHR = 284, - OP_FTBLK = 285, - OP_FTFILE = 286, - OP_FTDIR = 287, - OP_FTPIPE = 288, - OP_FTSUID = 289, - OP_FTSGID = 290, - OP_FTSVTX = 291, - OP_FTLINK = 292, - OP_FTTTY = 293, - OP_FTTEXT = 294, - OP_FTBINARY = 295, - OP_CHDIR = 296, - OP_CHOWN = 297, - OP_CHROOT = 298, - OP_UNLINK = 299, - OP_CHMOD = 300, - OP_UTIME = 301, - OP_RENAME = 302, - OP_LINK = 303, - OP_SYMLINK = 304, - OP_READLINK = 305, - OP_MKDIR = 306, - OP_RMDIR = 307, - OP_OPEN_DIR = 308, - OP_READDIR = 309, - OP_TELLDIR = 310, - OP_SEEKDIR = 311, - OP_REWINDDIR = 312, - OP_CLOSEDIR = 313, - OP_FORK = 314, - OP_WAIT = 315, - OP_WAITPID = 316, - OP_SYSTEM = 317, - OP_EXEC = 318, - OP_KILL = 319, - OP_GETPPID = 320, - OP_GETPGRP = 321, - OP_SETPGRP = 322, - OP_GETPRIORITY = 323, - OP_SETPRIORITY = 324, - OP_TIME = 325, - OP_TMS = 326, - OP_LOCALTIME = 327, - OP_GMTIME = 328, - OP_ALARM = 329, - OP_SLEEP = 330, - OP_SHMGET = 331, - OP_SHMCTL = 332, - OP_SHMREAD = 333, - OP_SHMWRITE = 334, - OP_MSGGET = 335, - OP_MSGCTL = 336, - OP_MSGSND = 337, - OP_MSGRCV = 338, - OP_SEMOP = 339, - OP_SEMGET = 340, - OP_SEMCTL = 341, - OP_REQUIRE = 342, - OP_DOFILE = 343, - OP_HINTSEVAL = 344, - OP_ENTEREVAL = 345, - OP_LEAVEEVAL = 346, - OP_ENTERTRY = 347, - OP_LEAVETRY = 348, - OP_GHBYNAME = 349, - OP_GHBYADDR = 350, - OP_GHOSTENT = 351, - OP_GNBYNAME = 352, - OP_GNBYADDR = 353, - OP_GNETENT = 354, - OP_GPBYNAME = 355, - OP_GPBYNUMBER = 356, - OP_GPROTOENT = 357, - OP_GSBYNAME = 358, - OP_GSBYPORT = 359, - OP_GSERVENT = 360, - OP_SHOSTENT = 361, - OP_SNETENT = 362, - OP_SPROTOENT = 363, - OP_SSERVENT = 364, - OP_EHOSTENT = 365, - OP_ENETENT = 366, - OP_EPROTOENT = 367, - OP_ESERVENT = 368, - OP_GPWNAM = 369, - OP_GPWUID = 370, - OP_GPWENT = 371, - OP_SPWENT = 372, - OP_EPWENT = 373, - OP_GGRNAM = 374, - OP_GGRGID = 375, - OP_GGRENT = 376, - OP_SGRENT = 377, - OP_EGRENT = 378, - OP_GETLOGIN = 379, - OP_SYSCALL = 380, - OP_LOCK = 381, - OP_ONCE = 382, - OP_CUSTOM = 383, - OP_COREARGS = 384, - OP_AVHVSWITCH = 385, - OP_RUNCV = 386, - OP_FC = 387, - OP_PADCV = 388, - OP_INTROCV = 389, - OP_CLONECV = 390, - OP_PADRANGE = 391, - OP_REFASSIGN = 392, - OP_LVREF = 393, - OP_LVREFSLICE = 394, - OP_LVAVREF = 395, - OP_ANONCONST = 396, - OP_ISA = 397, - OP_CMPCHAIN_AND = 398, - OP_CMPCHAIN_DUP = 399, - OP_ENTERTRYCATCH = 400, - OP_LEAVETRYCATCH = 401, - OP_POPTRY = 402, - OP_CATCH = 403, - OP_PUSHDEFER = 404, - OP_IS_BOOL = 405, - OP_IS_WEAK = 406, - OP_WEAKEN = 407, - OP_UNWEAKEN = 408, - OP_BLESSED = 409, - OP_REFADDR = 410, - OP_REFTYPE = 411, - OP_CEIL = 412, - OP_FLOOR = 413, - OP_IS_TAINTED = 414, + OP_PADSV_STORE = 10, + OP_PADAV = 11, + OP_PADHV = 12, + OP_PADANY = 13, + OP_RV2GV = 14, + OP_RV2SV = 15, + OP_AV2ARYLEN = 16, + OP_RV2CV = 17, + OP_ANONCODE = 18, + OP_PROTOTYPE = 19, + OP_REFGEN = 20, + OP_SREFGEN = 21, + OP_REF = 22, + OP_BLESS = 23, + OP_BACKTICK = 24, + OP_GLOB = 25, + OP_READLINE = 26, + OP_RCATLINE = 27, + OP_REGCMAYBE = 28, + OP_REGCRESET = 29, + OP_REGCOMP = 30, + OP_MATCH = 31, + OP_QR = 32, + OP_SUBST = 33, + OP_SUBSTCONT = 34, + OP_TRANS = 35, + OP_TRANSR = 36, + OP_SASSIGN = 37, + OP_AASSIGN = 38, + OP_CHOP = 39, + OP_SCHOP = 40, + OP_CHOMP = 41, + OP_SCHOMP = 42, + OP_DEFINED = 43, + OP_UNDEF = 44, + OP_STUDY = 45, + OP_POS = 46, + OP_PREINC = 47, + OP_I_PREINC = 48, + OP_PREDEC = 49, + OP_I_PREDEC = 50, + OP_POSTINC = 51, + OP_I_POSTINC = 52, + OP_POSTDEC = 53, + OP_I_POSTDEC = 54, + OP_POW = 55, + OP_MULTIPLY = 56, + OP_I_MULTIPLY = 57, + OP_DIVIDE = 58, + OP_I_DIVIDE = 59, + OP_MODULO = 60, + OP_I_MODULO = 61, + OP_REPEAT = 62, + OP_ADD = 63, + OP_I_ADD = 64, + OP_SUBTRACT = 65, + OP_I_SUBTRACT = 66, + OP_CONCAT = 67, + OP_MULTICONCAT = 68, + OP_STRINGIFY = 69, + OP_LEFT_SHIFT = 70, + OP_RIGHT_SHIFT = 71, + OP_LT = 72, + OP_I_LT = 73, + OP_GT = 74, + OP_I_GT = 75, + OP_LE = 76, + OP_I_LE = 77, + OP_GE = 78, + OP_I_GE = 79, + OP_EQ = 80, + OP_I_EQ = 81, + OP_NE = 82, + OP_I_NE = 83, + OP_NCMP = 84, + OP_I_NCMP = 85, + OP_SLT = 86, + OP_SGT = 87, + OP_SLE = 88, + OP_SGE = 89, + OP_SEQ = 90, + OP_SNE = 91, + OP_SCMP = 92, + OP_BIT_AND = 93, + OP_BIT_XOR = 94, + OP_BIT_OR = 95, + OP_NBIT_AND = 96, + OP_NBIT_XOR = 97, + OP_NBIT_OR = 98, + OP_SBIT_AND = 99, + OP_SBIT_XOR = 100, + OP_SBIT_OR = 101, + OP_NEGATE = 102, + OP_I_NEGATE = 103, + OP_NOT = 104, + OP_COMPLEMENT = 105, + OP_NCOMPLEMENT = 106, + OP_SCOMPLEMENT = 107, + OP_SMARTMATCH = 108, + OP_ATAN2 = 109, + OP_SIN = 110, + OP_COS = 111, + OP_RAND = 112, + OP_SRAND = 113, + OP_EXP = 114, + OP_LOG = 115, + OP_SQRT = 116, + OP_INT = 117, + OP_HEX = 118, + OP_OCT = 119, + OP_ABS = 120, + OP_LENGTH = 121, + OP_SUBSTR = 122, + OP_VEC = 123, + OP_INDEX = 124, + OP_RINDEX = 125, + OP_SPRINTF = 126, + OP_FORMLINE = 127, + OP_ORD = 128, + OP_CHR = 129, + OP_CRYPT = 130, + OP_UCFIRST = 131, + OP_LCFIRST = 132, + OP_UC = 133, + OP_LC = 134, + OP_QUOTEMETA = 135, + OP_RV2AV = 136, + OP_AELEMFAST = 137, + OP_AELEMFAST_LEX = 138, + OP_AELEM = 139, + OP_ASLICE = 140, + OP_KVASLICE = 141, + OP_AEACH = 142, + OP_AVALUES = 143, + OP_AKEYS = 144, + OP_EACH = 145, + OP_VALUES = 146, + OP_KEYS = 147, + OP_DELETE = 148, + OP_EXISTS = 149, + OP_RV2HV = 150, + OP_HELEM = 151, + OP_HSLICE = 152, + OP_KVHSLICE = 153, + OP_MULTIDEREF = 154, + OP_UNPACK = 155, + OP_PACK = 156, + OP_SPLIT = 157, + OP_JOIN = 158, + OP_LIST = 159, + OP_LSLICE = 160, + OP_ANONLIST = 161, + OP_ANONHASH = 162, + OP_SPLICE = 163, + OP_PUSH = 164, + OP_POP = 165, + OP_SHIFT = 166, + OP_UNSHIFT = 167, + OP_SORT = 168, + OP_REVERSE = 169, + OP_GREPSTART = 170, + OP_GREPWHILE = 171, + OP_MAPSTART = 172, + OP_MAPWHILE = 173, + OP_RANGE = 174, + OP_FLIP = 175, + OP_FLOP = 176, + OP_AND = 177, + OP_OR = 178, + OP_XOR = 179, + OP_DOR = 180, + OP_COND_EXPR = 181, + OP_ANDASSIGN = 182, + OP_ORASSIGN = 183, + OP_DORASSIGN = 184, + OP_ENTERSUB = 185, + OP_LEAVESUB = 186, + OP_LEAVESUBLV = 187, + OP_ARGCHECK = 188, + OP_ARGELEM = 189, + OP_ARGDEFELEM = 190, + OP_CALLER = 191, + OP_WARN = 192, + OP_DIE = 193, + OP_RESET = 194, + OP_LINESEQ = 195, + OP_NEXTSTATE = 196, + OP_DBSTATE = 197, + OP_UNSTACK = 198, + OP_ENTER = 199, + OP_LEAVE = 200, + OP_SCOPE = 201, + OP_ENTERITER = 202, + OP_ITER = 203, + OP_ENTERLOOP = 204, + OP_LEAVELOOP = 205, + OP_RETURN = 206, + OP_LAST = 207, + OP_NEXT = 208, + OP_REDO = 209, + OP_DUMP = 210, + OP_GOTO = 211, + OP_EXIT = 212, + OP_METHOD = 213, + OP_METHOD_NAMED = 214, + OP_METHOD_SUPER = 215, + OP_METHOD_REDIR = 216, + OP_METHOD_REDIR_SUPER = 217, + OP_ENTERGIVEN = 218, + OP_LEAVEGIVEN = 219, + OP_ENTERWHEN = 220, + OP_LEAVEWHEN = 221, + OP_BREAK = 222, + OP_CONTINUE = 223, + OP_OPEN = 224, + OP_CLOSE = 225, + OP_PIPE_OP = 226, + OP_FILENO = 227, + OP_UMASK = 228, + OP_BINMODE = 229, + OP_TIE = 230, + OP_UNTIE = 231, + OP_TIED = 232, + OP_DBMOPEN = 233, + OP_DBMCLOSE = 234, + OP_SSELECT = 235, + OP_SELECT = 236, + OP_GETC = 237, + OP_READ = 238, + OP_ENTERWRITE = 239, + OP_LEAVEWRITE = 240, + OP_PRTF = 241, + OP_PRINT = 242, + OP_SAY = 243, + OP_SYSOPEN = 244, + OP_SYSSEEK = 245, + OP_SYSREAD = 246, + OP_SYSWRITE = 247, + OP_EOF = 248, + OP_TELL = 249, + OP_SEEK = 250, + OP_TRUNCATE = 251, + OP_FCNTL = 252, + OP_IOCTL = 253, + OP_FLOCK = 254, + OP_SEND = 255, + OP_RECV = 256, + OP_SOCKET = 257, + OP_SOCKPAIR = 258, + OP_BIND = 259, + OP_CONNECT = 260, + OP_LISTEN = 261, + OP_ACCEPT = 262, + OP_SHUTDOWN = 263, + OP_GSOCKOPT = 264, + OP_SSOCKOPT = 265, + OP_GETSOCKNAME = 266, + OP_GETPEERNAME = 267, + OP_LSTAT = 268, + OP_STAT = 269, + OP_FTRREAD = 270, + OP_FTRWRITE = 271, + OP_FTREXEC = 272, + OP_FTEREAD = 273, + OP_FTEWRITE = 274, + OP_FTEEXEC = 275, + OP_FTIS = 276, + OP_FTSIZE = 277, + OP_FTMTIME = 278, + OP_FTATIME = 279, + OP_FTCTIME = 280, + OP_FTROWNED = 281, + OP_FTEOWNED = 282, + OP_FTZERO = 283, + OP_FTSOCK = 284, + OP_FTCHR = 285, + OP_FTBLK = 286, + OP_FTFILE = 287, + OP_FTDIR = 288, + OP_FTPIPE = 289, + OP_FTSUID = 290, + OP_FTSGID = 291, + OP_FTSVTX = 292, + OP_FTLINK = 293, + OP_FTTTY = 294, + OP_FTTEXT = 295, + OP_FTBINARY = 296, + OP_CHDIR = 297, + OP_CHOWN = 298, + OP_CHROOT = 299, + OP_UNLINK = 300, + OP_CHMOD = 301, + OP_UTIME = 302, + OP_RENAME = 303, + OP_LINK = 304, + OP_SYMLINK = 305, + OP_READLINK = 306, + OP_MKDIR = 307, + OP_RMDIR = 308, + OP_OPEN_DIR = 309, + OP_READDIR = 310, + OP_TELLDIR = 311, + OP_SEEKDIR = 312, + OP_REWINDDIR = 313, + OP_CLOSEDIR = 314, + OP_FORK = 315, + OP_WAIT = 316, + OP_WAITPID = 317, + OP_SYSTEM = 318, + OP_EXEC = 319, + OP_KILL = 320, + OP_GETPPID = 321, + OP_GETPGRP = 322, + OP_SETPGRP = 323, + OP_GETPRIORITY = 324, + OP_SETPRIORITY = 325, + OP_TIME = 326, + OP_TMS = 327, + OP_LOCALTIME = 328, + OP_GMTIME = 329, + OP_ALARM = 330, + OP_SLEEP = 331, + OP_SHMGET = 332, + OP_SHMCTL = 333, + OP_SHMREAD = 334, + OP_SHMWRITE = 335, + OP_MSGGET = 336, + OP_MSGCTL = 337, + OP_MSGSND = 338, + OP_MSGRCV = 339, + OP_SEMOP = 340, + OP_SEMGET = 341, + OP_SEMCTL = 342, + OP_REQUIRE = 343, + OP_DOFILE = 344, + OP_HINTSEVAL = 345, + OP_ENTEREVAL = 346, + OP_LEAVEEVAL = 347, + OP_ENTERTRY = 348, + OP_LEAVETRY = 349, + OP_GHBYNAME = 350, + OP_GHBYADDR = 351, + OP_GHOSTENT = 352, + OP_GNBYNAME = 353, + OP_GNBYADDR = 354, + OP_GNETENT = 355, + OP_GPBYNAME = 356, + OP_GPBYNUMBER = 357, + OP_GPROTOENT = 358, + OP_GSBYNAME = 359, + OP_GSBYPORT = 360, + OP_GSERVENT = 361, + OP_SHOSTENT = 362, + OP_SNETENT = 363, + OP_SPROTOENT = 364, + OP_SSERVENT = 365, + OP_EHOSTENT = 366, + OP_ENETENT = 367, + OP_EPROTOENT = 368, + OP_ESERVENT = 369, + OP_GPWNAM = 370, + OP_GPWUID = 371, + OP_GPWENT = 372, + OP_SPWENT = 373, + OP_EPWENT = 374, + OP_GGRNAM = 375, + OP_GGRGID = 376, + OP_GGRENT = 377, + OP_SGRENT = 378, + OP_EGRENT = 379, + OP_GETLOGIN = 380, + OP_SYSCALL = 381, + OP_LOCK = 382, + OP_ONCE = 383, + OP_CUSTOM = 384, + OP_COREARGS = 385, + OP_AVHVSWITCH = 386, + OP_RUNCV = 387, + OP_FC = 388, + OP_PADCV = 389, + OP_INTROCV = 390, + OP_CLONECV = 391, + OP_PADRANGE = 392, + OP_REFASSIGN = 393, + OP_LVREF = 394, + OP_LVREFSLICE = 395, + OP_LVAVREF = 396, + OP_ANONCONST = 397, + OP_ISA = 398, + OP_CMPCHAIN_AND = 399, + OP_CMPCHAIN_DUP = 400, + OP_ENTERTRYCATCH = 401, + OP_LEAVETRYCATCH = 402, + OP_POPTRY = 403, + OP_CATCH = 404, + OP_PUSHDEFER = 405, + OP_IS_BOOL = 406, + OP_IS_WEAK = 407, + OP_WEAKEN = 408, + OP_UNWEAKEN = 409, + OP_BLESSED = 410, + OP_REFADDR = 411, + OP_REFTYPE = 412, + OP_CEIL = 413, + OP_FLOOR = 414, + OP_IS_TAINTED = 415, OP_max } opcode; -#define MAXO 415 +#define MAXO 416 #define OP_FREED MAXO /* the OP_IS_* macros are optimized to a simple range check because diff --git a/peep.c b/peep.c index 454d16b50035..7f8c52c2aa70 100644 --- a/peep.c +++ b/peep.c @@ -3840,6 +3840,58 @@ Perl_rpeep(pTHX_ OP *o) } } } + OP* rhs = cBINOPx(o)->op_first; + OP* lval = cBINOPx(o)->op_last; + + /* Combine a simple SASSIGN OP with a PADSV lvalue child OP + * into a single OP. */ + + /* This optimization covers arbitrarily complicated RHS OP + * trees. Separate optimizations may exist for specific, + * single RHS OPs, such as: + * "my $foo = undef;" or "my $bar = $other_padsv;" */ + + if (!(o->op_private & (OPpASSIGN_BACKWARDS|OPpASSIGN_CV_TO_GV)) + && lval && (lval->op_type == OP_PADSV) && + !(lval->op_private & OPpDEREF) + ) { + + /* SASSIGN's bitfield flags, such as op_moresib and + * op_slabbed, will be carried over unchanged. */ + OpTYPE_set(o, OP_PADSV_STORE); + + /* Explicitly craft the new OP's op_flags, carrying + * some bits over from the SASSIGN */ + o->op_flags = ( + OPf_KIDS | OPf_STACKED | + (o->op_flags & (OPf_WANT|OPf_PARENS)) + ); + + /* Reset op_private flags, taking relevant private flags + * from the PADSV */ + o->op_private = (lval->op_private & + (OPpLVAL_INTRO|OPpPAD_STATE|OPpDEREF)); + + /* Steal the targ from the PADSV */ + o->op_targ = lval->op_targ; lval->op_targ = 0; + + /* Fixup op_next ptrs */ + /* oldoldop can be arbitrarily deep in the RHS OP tree */ + oldoldop->op_next = o; + + /* Even when (rhs != oldoldop), rhs might still have a + * relevant op_next ptr to lval. This is definitely true + * when rhs is OP_NULL with a LOGOP kid (e.g. orassign). + * There may be other cases. */ + if (rhs->op_next == lval) + rhs->op_next = o; + + /* Now null-out the PADSV */ + op_null(lval); + + /* NULL the previous op ptrs, so rpeep can continue */ + oldoldop = NULL; oldop = NULL; + } break; case OP_AASSIGN: { diff --git a/pp_hot.c b/pp_hot.c index 97985b7b5eb7..2866af1c6973 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -123,6 +123,48 @@ PP(pp_and) } } +/* + * Mashup of simple padsv + sassign OPs + * Doesn't support the following lengthy and unlikely sassign case: + * (UNLIKELY(PL_op->op_private & OPpASSIGN_CV_TO_GV)) + * These cases have a separate optimization, so are not handled here: + * (PL_op->op_private & OPpASSIGN_BACKWARDS) {or,and,dor}assign +*/ + +PP(pp_padsv_store) +{ + dSP; + OP * const op = PL_op; + SV** const padentry = &PAD_SVl(op->op_targ); + SV* targ = *padentry; /* lvalue to assign into */ + SV* const val = TOPs; /* RHS value to assign */ + + /* !OPf_STACKED is not handled by this OP */ + assert(op->op_flags & OPf_STACKED); + + /* Inlined, simplified pp_padsv here */ + if ((op->op_private & (OPpLVAL_INTRO|OPpPAD_STATE)) == OPpLVAL_INTRO) { + save_clearsv(padentry); + } + + /* Inlined, simplified pp_sassign from here */ + assert(TAINTING_get || !TAINT_get); + if (UNLIKELY(TAINT_get) && !SvTAINTED(val)) + TAINT_NOT; + + if ( + UNLIKELY(SvTEMP(targ)) && !SvSMAGICAL(targ) && SvREFCNT(targ) == 1 && + (!isGV_with_GP(targ) || SvFAKE(targ)) && ckWARN(WARN_MISC) + ) + Perl_warner(aTHX_ + packWARN(WARN_MISC), "Useless assignment to a temporary" + ); + SvSetMagicSV(targ, val); + + SETs(targ); + RETURN; +} + PP(pp_sassign) { dSP; diff --git a/pp_proto.h b/pp_proto.h index 83516cdf66dd..c89828a56be1 100644 --- a/pp_proto.h +++ b/pp_proto.h @@ -199,6 +199,7 @@ PERL_CALLCONV OP *Perl_pp_padcv(pTHX) __attribute__visibility__("hidden"); PERL_CALLCONV OP *Perl_pp_padhv(pTHX) __attribute__visibility__("hidden"); PERL_CALLCONV OP *Perl_pp_padrange(pTHX) __attribute__visibility__("hidden"); PERL_CALLCONV OP *Perl_pp_padsv(pTHX) __attribute__visibility__("hidden"); +PERL_CALLCONV OP *Perl_pp_padsv_store(pTHX) __attribute__visibility__("hidden"); PERL_CALLCONV OP *Perl_pp_pipe_op(pTHX) __attribute__visibility__("hidden"); PERL_CALLCONV OP *Perl_pp_poptry(pTHX) __attribute__visibility__("hidden"); PERL_CALLCONV OP *Perl_pp_pos(pTHX) __attribute__visibility__("hidden"); diff --git a/regen/op_private b/regen/op_private index 4300856cde2c..172e7c2dc796 100644 --- a/regen/op_private +++ b/regen/op_private @@ -318,7 +318,7 @@ addbits($_, 7 => qw(OPpLVAL_INTRO LVINTRO)) for qw(gvsv rv2sv rv2hv rv2gv rv2av aelem helem aslice split hslice delete padsv padav padhv enteriter entersub padrange pushmark cond_expr refassign lvref lvrefslice lvavref multideref - multiconcat), + multiconcat padsv_store), 'list', # this gets set in my_attrs() for some reason ; @@ -499,7 +499,8 @@ addbits($_, 7 => qw(OPpPV_IS_UTF8 UTF)) for qw(last redo next goto dump); # \state $foo = ... addbits($_, 6 => qw(OPpPAD_STATE STATE)) for qw(padav padhv padsv lvavref - lvref refassign pushmark); + lvref refassign pushmark + padsv_store); # NB: both sassign and aassign use the 'OPpASSIGN' naming convention # for their private flags diff --git a/regen/opcodes b/regen/opcodes index 3f33f3dcddc7..80fbe149c392 100644 --- a/regen/opcodes +++ b/regen/opcodes @@ -53,6 +53,7 @@ gvsv scalar variable ck_null ds$ gv glob value ck_null ds$ gelem glob elem ck_null ds2 S S padsv private variable ck_null ds0 +padsv_store padsv scalar assignment ck_sassign s1 S S padav private array ck_null d0 padhv private hash ck_null d0 padany private value ck_null d0 diff --git a/t/perf/opcount.t b/t/perf/opcount.t index 30e0676660ac..0c21247bd2bf 100644 --- a/t/perf/opcount.t +++ b/t/perf/opcount.t @@ -712,8 +712,8 @@ test_opcount(0, "builtin::is_bool is replaced with direct opcode", { entersub => 0, is_bool => 1, - padsv => 4, - sassign => 1, + padsv => 3, + padsv_store => 1, }); test_opcount(0, "builtin::is_bool gets constant-folded", @@ -788,4 +788,12 @@ test_opcount(0, "builtin::is_tainted is replaced with direct opcode", is_tainted => 1, }); +# sassign + padsv combinations are replaced by padsv_store +test_opcount(0, "sassign + padsv replaced by padsv_store", + sub { my $y; my $z = $y = 3; }, + { + padsv => 1, + padsv_store => 2, + }); + done_testing();