Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5282b3b

Browse files
bpo-37213: Handle negative line deltas correctly in the peephole optimizer (GH-13969)
The peephole optimizer was not optimizing correctly bytecode after negative deltas were introduced. This is due to the fact that some special values (255) were being searched for in both instruction pointer delta and line number deltas.(cherry picked from commit3498c64)Co-authored-by: Pablo Galindo <Pablogsal@gmail.com>
1 parentec3839a commit5282b3b

File tree

6 files changed

+4229
-4145
lines changed

6 files changed

+4229
-4145
lines changed

‎Lib/test/test_peepholer.py‎

Lines changed: 80 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
importdis
22
importunittest
3+
importtypes
4+
importtextwrap
35

46
fromtest.bytecode_helperimportBytecodeTestCase
57

@@ -18,6 +20,27 @@ def count_instr_recursively(f, opname):
1820

1921
classTestTranforms(BytecodeTestCase):
2022

23+
defcheck_jump_targets(self,code):
24+
instructions=list(dis.get_instructions(code))
25+
targets= {instr.offset:instrforinstrininstructions}
26+
forinstrininstructions:
27+
if'JUMP_'notininstr.opname:
28+
continue
29+
tgt=targets[instr.argval]
30+
# jump to unconditional jump
31+
iftgt.opnamein ('JUMP_ABSOLUTE','JUMP_FORWARD'):
32+
self.fail(f'{instr.opname} at{instr.offset} '
33+
f'jumps to{tgt.opname} at{tgt.offset}')
34+
# unconditional jump to RETURN_VALUE
35+
if (instr.opnamein ('JUMP_ABSOLUTE','JUMP_FORWARD')and
36+
tgt.opname=='RETURN_VALUE'):
37+
self.fail(f'{instr.opname} at{instr.offset} '
38+
f'jumps to{tgt.opname} at{tgt.offset}')
39+
# JUMP_IF_*_OR_POP jump to conditional jump
40+
if'_OR_POP'ininstr.opnameand'JUMP_IF_'intgt.opname:
41+
self.fail(f'{instr.opname} at{instr.offset} '
42+
f'jumps to{tgt.opname} at{tgt.offset}')
43+
2144
deftest_unot(self):
2245
# UNARY_NOT POP_JUMP_IF_FALSE --> POP_JUMP_IF_TRUE'
2346
defunot(x):
@@ -259,13 +282,69 @@ def f(x):
259282
deftest_elim_jump_to_return(self):
260283
# JUMP_FORWARD to RETURN --> RETURN
261284
deff(cond,true_value,false_value):
262-
returntrue_valueifcondelsefalse_value
285+
# Intentionally use two-line expression to test issue37213.
286+
return (true_valueifcond
287+
elsefalse_value)
288+
self.check_jump_targets(f)
263289
self.assertNotInBytecode(f,'JUMP_FORWARD')
264290
self.assertNotInBytecode(f,'JUMP_ABSOLUTE')
265291
returns= [instrforinstrindis.get_instructions(f)
266292
ifinstr.opname=='RETURN_VALUE']
267293
self.assertEqual(len(returns),2)
268294

295+
deftest_elim_jump_to_uncond_jump(self):
296+
# POP_JUMP_IF_FALSE to JUMP_FORWARD --> POP_JUMP_IF_FALSE to non-jump
297+
deff():
298+
ifa:
299+
# Intentionally use two-line expression to test issue37213.
300+
if (c
301+
ord):
302+
foo()
303+
else:
304+
baz()
305+
self.check_jump_targets(f)
306+
307+
deftest_elim_jump_to_uncond_jump2(self):
308+
# POP_JUMP_IF_FALSE to JUMP_ABSOLUTE --> POP_JUMP_IF_FALSE to non-jump
309+
deff():
310+
whilea:
311+
# Intentionally use two-line expression to test issue37213.
312+
if (c
313+
ord):
314+
a=foo()
315+
self.check_jump_targets(f)
316+
317+
deftest_elim_jump_to_uncond_jump3(self):
318+
# Intentionally use two-line expressions to test issue37213.
319+
# JUMP_IF_FALSE_OR_POP to JUMP_IF_FALSE_OR_POP --> JUMP_IF_FALSE_OR_POP to non-jump
320+
deff(a,b,c):
321+
return ((aandb)
322+
andc)
323+
self.check_jump_targets(f)
324+
self.assertEqual(count_instr_recursively(f,'JUMP_IF_FALSE_OR_POP'),2)
325+
# JUMP_IF_TRUE_OR_POP to JUMP_IF_TRUE_OR_POP --> JUMP_IF_TRUE_OR_POP to non-jump
326+
deff(a,b,c):
327+
return ((aorb)
328+
orc)
329+
self.check_jump_targets(f)
330+
self.assertEqual(count_instr_recursively(f,'JUMP_IF_TRUE_OR_POP'),2)
331+
# JUMP_IF_FALSE_OR_POP to JUMP_IF_TRUE_OR_POP --> POP_JUMP_IF_FALSE to non-jump
332+
deff(a,b,c):
333+
return ((aandb)
334+
orc)
335+
self.check_jump_targets(f)
336+
self.assertNotInBytecode(f,'JUMP_IF_FALSE_OR_POP')
337+
self.assertInBytecode(f,'JUMP_IF_TRUE_OR_POP')
338+
self.assertInBytecode(f,'POP_JUMP_IF_FALSE')
339+
# JUMP_IF_TRUE_OR_POP to JUMP_IF_FALSE_OR_POP --> POP_JUMP_IF_TRUE to non-jump
340+
deff(a,b,c):
341+
return ((aorb)
342+
andc)
343+
self.check_jump_targets(f)
344+
self.assertNotInBytecode(f,'JUMP_IF_TRUE_OR_POP')
345+
self.assertInBytecode(f,'JUMP_IF_FALSE_OR_POP')
346+
self.assertInBytecode(f,'POP_JUMP_IF_TRUE')
347+
269348
deftest_elim_jump_after_return1(self):
270349
# Eliminate dead code: jumps immediately after returns can't be reached
271350
deff(cond1,cond2):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Handle correctly negative line offsets in the peephole optimizer. Patch by
2+
Pablo Galindo.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2026 Movatter.jp