Skip to content

Commit 7c8d192

Browse files
committed
Perl_scalarvoid: turn OP_STUB into OP_NULL
An OP_STUB in void context is functionally identical to an OP_NULL. It's straightforward and safe to transform an OP_STUB into an OP_NULL by adding an extra `case` within `Perl_scalarvoid`. In doing so: * The redundant OPs are more likely to be omitted from the op_next chain. * The OP tree is more consistent with `assert` expectations in `Perl_rpeep`. (The programs in GH #17228 no longer trigger assertions.)
1 parent 3858926 commit 7c8d192

File tree

4 files changed

+155
-164
lines changed

4 files changed

+155
-164
lines changed

ext/B/t/optree_for.t

Lines changed: 126 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -23,28 +23,26 @@ checkOptree ( name => 'for (@a)',
2323
3 <#> gv[*a] s
2424
4 <1> rv2av[t2] sKRM/1
2525
5 <#> gv[*_] s
26-
6 <{> enteriter(next->8 last->b redo->7) KS/DEF
27-
9 <0> iter s
28-
a <|> and(other->7) K/1
29-
7 <0> stub v
30-
8 <0> unstack s
31-
goto 9
32-
b <2> leaveloop K/2
33-
c <1> leavesub[1 ref] K/REFC,1
26+
6 <{> enteriter(next->7 last->a redo->7) KS/DEF
27+
8 <0> iter s
28+
9 <|> and(other->7) K/1
29+
7 <0> unstack s
30+
goto 8
31+
a <2> leaveloop K/2
32+
b <1> leavesub[1 ref] K/REFC,1
3433
EOT_EOT
3534
1 <;> nextstate(main 424 optree_for.t:14) v:>,<,%
3635
2 <0> pushmark sM
3736
3 <$> gv(*a) s
3837
4 <1> rv2av[t1] sKRM/1
3938
5 <$> gv(*_) s
40-
6 <{> enteriter(next->8 last->b redo->7) KS/DEF
41-
9 <0> iter s
42-
a <|> and(other->7) K/1
43-
7 <0> stub v
44-
8 <0> unstack s
45-
goto 9
46-
b <2> leaveloop K/2
47-
c <1> leavesub[1 ref] K/REFC,1
39+
6 <{> enteriter(next->7 last->a redo->7) KS/DEF
40+
8 <0> iter s
41+
9 <|> and(other->7) K/1
42+
7 <0> unstack s
43+
goto 8
44+
a <2> leaveloop K/2
45+
b <1> leavesub[1 ref] K/REFC,1
4846
EONT_EONT
4947

5048
my @lexical;
@@ -58,27 +56,25 @@ checkOptree ( name => 'for (@lexical)',
5856
2 <0> pushmark sM
5957
3 <0> padav[@lexical:FAKE::7] sRM
6058
4 <#> gv[*_] s
61-
5 <{> enteriter(next->7 last->a redo->6) KS/DEF
62-
8 <0> iter s
63-
9 <|> and(other->6) K/1
64-
6 <0> stub v
65-
7 <0> unstack s
66-
goto 8
67-
a <2> leaveloop K/2
68-
b <1> leavesub[2 refs] K/REFC,1
59+
5 <{> enteriter(next->6 last->9 redo->6) KS/DEF
60+
7 <0> iter s
61+
8 <|> and(other->6) K/1
62+
6 <0> unstack s
63+
goto 7
64+
9 <2> leaveloop K/2
65+
a <1> leavesub[2 refs] K/REFC,1
6966
EOT_EOT
7067
1 <;> nextstate(main 424 optree_for.t:14) v:>,<,%
7168
2 <0> pushmark sM
7269
3 <0> padav[@lexical:FAKE::2] sRM
7370
4 <$> gv(*_) s
74-
5 <{> enteriter(next->7 last->a redo->6) KS/DEF
75-
8 <0> iter s
76-
9 <|> and(other->6) K/1
77-
6 <0> stub v
78-
7 <0> unstack s
79-
goto 8
80-
a <2> leaveloop K/2
81-
b <1> leavesub[2 refs] K/REFC,1
71+
5 <{> enteriter(next->6 last->9 redo->6) KS/DEF
72+
7 <0> iter s
73+
8 <|> and(other->6) K/1
74+
6 <0> unstack s
75+
goto 7
76+
9 <2> leaveloop K/2
77+
a <1> leavesub[2 refs] K/REFC,1
8278
EONT_EONT
8379

8480
checkOptree ( name => 'for $var (@a)',
@@ -92,29 +88,27 @@ checkOptree ( name => 'for $var (@a)',
9288
4 <1> rv2av[t3] sKRM/1
9389
5 <#> gv[*var] s
9490
6 <1> rv2gv sKRM/1
95-
7 <{> enteriter(next->9 last->c redo->8) KS
96-
a <0> iter s
97-
b <|> and(other->8) K/1
98-
8 <0> stub v
99-
9 <0> unstack s
100-
goto a
101-
c <2> leaveloop KP/2
102-
d <1> leavesub[1 ref] K/REFC,1
91+
7 <{> enteriter(next->8 last->b redo->8) KS
92+
9 <0> iter s
93+
a <|> and(other->8) K/1
94+
8 <0> unstack s
95+
goto 9
96+
b <2> leaveloop KP/2
97+
c <1> leavesub[1 ref] K/REFC,1
10398
EOT_EOT
10499
1 <;> nextstate(main 1453 optree_for.t:67) v:{
105100
2 <0> pushmark sM
106101
3 <$> gv(*a) s
107102
4 <1> rv2av[t1] sKRM/1
108103
5 <$> gv(*var) s
109104
6 <1> rv2gv sKRM/1
110-
7 <{> enteriter(next->9 last->c redo->8) KS
111-
a <0> iter s
112-
b <|> and(other->8) K/1
113-
8 <0> stub v
114-
9 <0> unstack s
115-
goto a
116-
c <2> leaveloop KP/2
117-
d <1> leavesub[1 ref] K/REFC,1
105+
7 <{> enteriter(next->8 last->b redo->8) KS
106+
9 <0> iter s
107+
a <|> and(other->8) K/1
108+
8 <0> unstack s
109+
goto 9
110+
b <2> leaveloop KP/2
111+
c <1> leavesub[1 ref] K/REFC,1
118112
EONT_EONT
119113

120114
checkOptree ( name => 'for my $var (@a)',
@@ -126,27 +120,25 @@ checkOptree ( name => 'for my $var (@a)',
126120
2 <0> pushmark sM
127121
3 <#> gv[*a] s
128122
4 <1> rv2av[t3] sKRM/1
129-
5 <{> enteriter(next->7 last->a redo->6)[$var:1460,1463] KS/LVINTRO
130-
8 <0> iter s
131-
9 <|> and(other->6) K/1
132-
6 <0> stub v
133-
7 <0> unstack s
134-
goto 8
135-
a <2> leaveloop K/2
136-
b <1> leavesub[1 ref] K/REFC,1
123+
5 <{> enteriter(next->6 last->9 redo->6)[$var:1460,1463] KS/LVINTRO
124+
7 <0> iter s
125+
8 <|> and(other->6) K/1
126+
6 <0> unstack s
127+
goto 7
128+
9 <2> leaveloop K/2
129+
a <1> leavesub[1 ref] K/REFC,1
137130
EOT_EOT
138131
1 <;> nextstate(main 424 optree_for.t:14) v:>,<,%
139132
2 <0> pushmark sM
140133
3 <$> gv(*a) s
141134
4 <1> rv2av[t2] sKRM/1
142-
5 <{> enteriter(next->7 last->a redo->6)[$var:1460,1463] KS/LVINTRO
143-
8 <0> iter s
144-
9 <|> and(other->6) K/1
145-
6 <0> stub v
146-
7 <0> unstack s
147-
goto 8
148-
a <2> leaveloop K/2
149-
b <1> leavesub[1 ref] K/REFC,1
135+
5 <{> enteriter(next->6 last->9 redo->6)[$var:1460,1463] KS/LVINTRO
136+
7 <0> iter s
137+
8 <|> and(other->6) K/1
138+
6 <0> unstack s
139+
goto 7
140+
9 <2> leaveloop K/2
141+
a <1> leavesub[1 ref] K/REFC,1
150142
EONT_EONT
151143

152144
checkOptree ( name => 'for our $var (@a)',
@@ -160,29 +152,27 @@ checkOptree ( name => 'for our $var (@a)',
160152
4 <1> rv2av[t4] sKRM/1
161153
5 <#> gv[*var] s
162154
6 <1> rv2gv sK/FAKE,1
163-
7 <{> enteriter(next->9 last->c redo->8) KS/OURINTR
164-
a <0> iter s
165-
b <|> and(other->8) K/1
166-
8 <0> stub v
167-
9 <0> unstack s
168-
goto a
169-
c <2> leaveloop K/2
170-
d <1> leavesub[1 ref] K/REFC,1
155+
7 <{> enteriter(next->8 last->b redo->8) KS/OURINTR
156+
9 <0> iter s
157+
a <|> and(other->8) K/1
158+
8 <0> unstack s
159+
goto 9
160+
b <2> leaveloop K/2
161+
c <1> leavesub[1 ref] K/REFC,1
171162
EOT_EOT
172163
1 <;> nextstate(main 424 optree_for.t:111) v:>,<,%
173164
2 <0> pushmark sM
174165
3 <$> gv(*a) s
175166
4 <1> rv2av[t2] sKRM/1
176167
5 <$> gv(*var) s
177168
6 <1> rv2gv sK/FAKE,1
178-
7 <{> enteriter(next->9 last->c redo->8) KS/OURINTR
179-
a <0> iter s
180-
b <|> and(other->8) K/1
181-
8 <0> stub v
182-
9 <0> unstack s
183-
goto a
184-
c <2> leaveloop K/2
185-
d <1> leavesub[1 ref] K/REFC,1
169+
7 <{> enteriter(next->8 last->b redo->8) KS/OURINTR
170+
9 <0> iter s
171+
a <|> and(other->8) K/1
172+
8 <0> unstack s
173+
goto 9
174+
b <2> leaveloop K/2
175+
c <1> leavesub[1 ref] K/REFC,1
186176
EONT_EONT
187177

188178
checkOptree ( name => 'for my ($var) (@a)',
@@ -194,27 +184,25 @@ checkOptree ( name => 'for my ($var) (@a)',
194184
2 <0> pushmark sM
195185
3 <#> gv[*a] s
196186
4 <1> rv2av[t3] sKRM/1
197-
5 <{> enteriter(next->7 last->a redo->6)[$var:1474,1477] KPS/LVINTRO
198-
8 <0> iter s
199-
9 <|> and(other->6) K/1
200-
6 <0> stub v
201-
7 <0> unstack s
202-
goto 8
203-
a <2> leaveloop K/2
204-
b <1> leavesub[1 ref] K/REFC,1
187+
5 <{> enteriter(next->6 last->9 redo->6)[$var:1474,1477] KPS/LVINTRO
188+
7 <0> iter s
189+
8 <|> and(other->6) K/1
190+
6 <0> unstack s
191+
goto 7
192+
9 <2> leaveloop K/2
193+
a <1> leavesub[1 ref] K/REFC,1
205194
EOT_EOT
206195
1 <;> nextstate(main 424 optree_for.t:111) v:>,<,%
207196
2 <0> pushmark sM
208197
3 <$> gv(*a) s
209198
4 <1> rv2av[t2] sKRM/1
210-
5 <{> enteriter(next->7 last->a redo->6)[$var:1474,1477] KPS/LVINTRO
211-
8 <0> iter s
212-
9 <|> and(other->6) K/1
213-
6 <0> stub v
214-
7 <0> unstack s
215-
goto 8
216-
a <2> leaveloop K/2
217-
b <1> leavesub[1 ref] K/REFC,1
199+
5 <{> enteriter(next->6 last->9 redo->6)[$var:1474,1477] KPS/LVINTRO
200+
7 <0> iter s
201+
8 <|> and(other->6) K/1
202+
6 <0> unstack s
203+
goto 7
204+
9 <2> leaveloop K/2
205+
a <1> leavesub[1 ref] K/REFC,1
218206
EONT_EONT
219207

220208
checkOptree ( name => 'for my ($var) (@lexical)',
@@ -225,26 +213,24 @@ checkOptree ( name => 'for my ($var) (@lexical)',
225213
1 <;> nextstate(main 1466 optree_for.t:100) v
226214
2 <0> pushmark sM
227215
3 <0> padav[@lexical:FAKE::7] sRM
228-
4 <{> enteriter(next->6 last->9 redo->5)[$var:1481,1484] KPS/LVINTRO
229-
7 <0> iter s
230-
8 <|> and(other->5) K/1
231-
5 <0> stub v
232-
6 <0> unstack s
233-
goto 7
234-
9 <2> leaveloop K/2
235-
a <1> leavesub[2 refs] K/REFC,1
216+
4 <{> enteriter(next->5 last->8 redo->5)[$var:1481,1484] KPS/LVINTRO
217+
6 <0> iter s
218+
7 <|> and(other->5) K/1
219+
5 <0> unstack s
220+
goto 6
221+
8 <2> leaveloop K/2
222+
9 <1> leavesub[2 refs] K/REFC,1
236223
EOT_EOT
237224
1 <;> nextstate(main 424 optree_for.t:111) v:>,<,%
238225
2 <0> pushmark sM
239226
3 <0> padav[@lexical:FAKE::2] sRM
240-
4 <{> enteriter(next->6 last->9 redo->5)[$var:1481,1484] KPS/LVINTRO
241-
7 <0> iter s
242-
8 <|> and(other->5) K/1
243-
5 <0> stub v
244-
6 <0> unstack s
245-
goto 7
246-
9 <2> leaveloop K/2
247-
a <1> leavesub[2 refs] K/REFC,1
227+
4 <{> enteriter(next->5 last->8 redo->5)[$var:1481,1484] KPS/LVINTRO
228+
6 <0> iter s
229+
7 <|> and(other->5) K/1
230+
5 <0> unstack s
231+
goto 6
232+
8 <2> leaveloop K/2
233+
9 <1> leavesub[2 refs] K/REFC,1
248234
EONT_EONT
249235

250236
checkOptree ( name => 'for my ($key, $value) (%h)',
@@ -256,27 +242,25 @@ checkOptree ( name => 'for my ($key, $value) (%h)',
256242
2 <0> pushmark sM
257243
3 <#> gv[*h] s
258244
4 <1> rv2hv[t4] lKM
259-
5 <{> enteriter(next->7 last->a redo->6)[$key:1488,1491; $value:1488,1491] KP/LVINTRO
260-
8 <0> iter s
261-
9 <|> and(other->6) K/1
262-
6 <0> stub v
263-
7 <0> unstack s
264-
goto 8
265-
a <2> leaveloop K/2
266-
b <1> leavesub[1 ref] K/REFC,1
245+
5 <{> enteriter(next->6 last->9 redo->6)[$key:1488,1491; $value:1488,1491] KP/LVINTRO
246+
7 <0> iter s
247+
8 <|> and(other->6) K/1
248+
6 <0> unstack s
249+
goto 7
250+
9 <2> leaveloop K/2
251+
a <1> leavesub[1 ref] K/REFC,1
267252
EOT_EOT
268253
1 <;> nextstate(main 424 optree_for.t:111) v:>,<,%
269254
2 <0> pushmark sM
270255
3 <$> gv(*h) s
271256
4 <1> rv2hv[t3] lKM
272-
5 <{> enteriter(next->7 last->a redo->6)[$key:1488,1491; $value:1488,1491] KP/LVINTRO
273-
8 <0> iter s
274-
9 <|> and(other->6) K/1
275-
6 <0> stub v
276-
7 <0> unstack s
277-
goto 8
278-
a <2> leaveloop K/2
279-
b <1> leavesub[1 ref] K/REFC,1
257+
5 <{> enteriter(next->6 last->9 redo->6)[$key:1488,1491; $value:1488,1491] KP/LVINTRO
258+
7 <0> iter s
259+
8 <|> and(other->6) K/1
260+
6 <0> unstack s
261+
goto 7
262+
9 <2> leaveloop K/2
263+
a <1> leavesub[1 ref] K/REFC,1
280264
EONT_EONT
281265

282266
checkOptree ( name => 'for my ($foo, $bar, $baz) (@a)',
@@ -288,25 +272,23 @@ checkOptree ( name => 'for my ($foo, $bar, $baz) (@a)',
288272
2 <0> pushmark sM
289273
3 <#> gv[*a] s
290274
4 <1> rv2av[t5] sKRM/1
291-
5 <{> enteriter(next->7 last->a redo->6)[$foo:1495,1498; $bar:1495,1498; $baz:1495,1498] KPS/LVINTRO
292-
8 <0> iter s
293-
9 <|> and(other->6) K/1
294-
6 <0> stub v
295-
7 <0> unstack s
296-
goto 8
297-
a <2> leaveloop K/2
298-
b <1> leavesub[1 ref] K/REFC,1
275+
5 <{> enteriter(next->6 last->9 redo->6)[$foo:1495,1498; $bar:1495,1498; $baz:1495,1498] KPS/LVINTRO
276+
7 <0> iter s
277+
8 <|> and(other->6) K/1
278+
6 <0> unstack s
279+
goto 7
280+
9 <2> leaveloop K/2
281+
a <1> leavesub[1 ref] K/REFC,1
299282
EOT_EOT
300283
1 <;> nextstate(main 424 optree_for.t:111) v:>,<,%
301284
2 <0> pushmark sM
302285
3 <$> gv(*a) s
303286
4 <1> rv2av[t4] sKRM/1
304-
5 <{> enteriter(next->7 last->a redo->6)[$foo:1495,1498; $bar:1495,1498; $baz:1495,1498] KPS/LVINTRO
305-
8 <0> iter s
306-
9 <|> and(other->6) K/1
307-
6 <0> stub v
308-
7 <0> unstack s
309-
goto 8
310-
a <2> leaveloop K/2
311-
b <1> leavesub[1 ref] K/REFC,1
287+
5 <{> enteriter(next->6 last->9 redo->6)[$foo:1495,1498; $bar:1495,1498; $baz:1495,1498] KPS/LVINTRO
288+
7 <0> iter s
289+
8 <|> and(other->6) K/1
290+
6 <0> unstack s
291+
goto 7
292+
9 <2> leaveloop K/2
293+
a <1> leavesub[1 ref] K/REFC,1
312294
EONT_EONT

0 commit comments

Comments
 (0)