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

Commit6b77af2

Browse files
authored
gh-134889: Fix handling of a few opcodes when optimizingLOAD_FAST (#134958)
We were incorrectly handling a few opcodes that leave their operands on the stack. Treat all of these conservatively; assume that they always leave operands on the stack.
1 parente598eec commit6b77af2

File tree

5 files changed

+117
-2
lines changed

5 files changed

+117
-2
lines changed

‎Include/internal/pycore_magic_number.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,7 @@ Known values:
280280
Python 3.15a0 3650 (Initial version)
281281
Python 3.15a1 3651 (Simplify LOAD_CONST)
282282
Python 3.15a1 3652 (Virtual iterators)
283+
Python 3.15a1 3653 (Fix handling of opcodes that may leave operands on the stack when optimizing LOAD_FAST)
283284
284285
285286
Python 3.16 will start with 3700
@@ -293,7 +294,7 @@ PC/launcher.c must also be updated.
293294
294295
*/
295296

296-
#definePYC_MAGIC_NUMBER3652
297+
#definePYC_MAGIC_NUMBER3653
297298
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
298299
(little-endian) and then appending b'\r\n'. */
299300
#definePYC_MAGIC_NUMBER_TOKEN \

‎Lib/test/test_dis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,7 @@ async def _asyncwith(c):
606606
POP_TOP
607607
L1: RESUME 0
608608
609-
%4dLOAD_FAST_BORROW 0 (c)
609+
%4dLOAD_FAST 0 (c)
610610
COPY 1
611611
LOAD_SPECIAL 3 (__aexit__)
612612
SWAP 2

‎Lib/test/test_peepholer.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2614,6 +2614,90 @@ def test_send(self):
26142614
]
26152615
self.cfg_optimization_test(insts,expected,consts=[None])
26162616

2617+
deftest_format_simple(self):
2618+
# FORMAT_SIMPLE will leave its operand on the stack if it's a unicode
2619+
# object. We treat it conservatively and assume that it always leaves
2620+
# its operand on the stack.
2621+
insts= [
2622+
("LOAD_FAST",0,1),
2623+
("FORMAT_SIMPLE",None,2),
2624+
("STORE_FAST",1,3),
2625+
]
2626+
self.check(insts,insts)
2627+
2628+
insts= [
2629+
("LOAD_FAST",0,1),
2630+
("FORMAT_SIMPLE",None,2),
2631+
("POP_TOP",None,3),
2632+
]
2633+
expected= [
2634+
("LOAD_FAST_BORROW",0,1),
2635+
("FORMAT_SIMPLE",None,2),
2636+
("POP_TOP",None,3),
2637+
]
2638+
self.check(insts,expected)
2639+
2640+
deftest_set_function_attribute(self):
2641+
# SET_FUNCTION_ATTRIBUTE leaves the function on the stack
2642+
insts= [
2643+
("LOAD_CONST",0,1),
2644+
("LOAD_FAST",0,2),
2645+
("SET_FUNCTION_ATTRIBUTE",2,3),
2646+
("STORE_FAST",1,4),
2647+
("LOAD_CONST",0,5),
2648+
("RETURN_VALUE",None,6)
2649+
]
2650+
self.cfg_optimization_test(insts,insts,consts=[None])
2651+
2652+
insts= [
2653+
("LOAD_CONST",0,1),
2654+
("LOAD_FAST",0,2),
2655+
("SET_FUNCTION_ATTRIBUTE",2,3),
2656+
("RETURN_VALUE",None,4)
2657+
]
2658+
expected= [
2659+
("LOAD_CONST",0,1),
2660+
("LOAD_FAST_BORROW",0,2),
2661+
("SET_FUNCTION_ATTRIBUTE",2,3),
2662+
("RETURN_VALUE",None,4)
2663+
]
2664+
self.cfg_optimization_test(insts,expected,consts=[None])
2665+
2666+
deftest_get_yield_from_iter(self):
2667+
# GET_YIELD_FROM_ITER may leave its operand on the stack
2668+
insts= [
2669+
("LOAD_FAST",0,1),
2670+
("GET_YIELD_FROM_ITER",None,2),
2671+
("LOAD_CONST",0,3),
2672+
send:=self.Label(),
2673+
("SEND",end:=self.Label(),5),
2674+
("YIELD_VALUE",1,6),
2675+
("RESUME",2,7),
2676+
("JUMP",send,8),
2677+
end,
2678+
("END_SEND",None,9),
2679+
("LOAD_CONST",0,10),
2680+
("RETURN_VALUE",None,11),
2681+
]
2682+
self.cfg_optimization_test(insts,insts,consts=[None])
2683+
2684+
deftest_push_exc_info(self):
2685+
insts= [
2686+
("LOAD_FAST",0,1),
2687+
("PUSH_EXC_INFO",None,2),
2688+
]
2689+
self.check(insts,insts)
2690+
2691+
deftest_load_special(self):
2692+
# LOAD_SPECIAL may leave self on the stack
2693+
insts= [
2694+
("LOAD_FAST",0,1),
2695+
("LOAD_SPECIAL",0,2),
2696+
("STORE_FAST",1,3),
2697+
]
2698+
self.check(insts,insts)
2699+
2700+
26172701
deftest_del_in_finally(self):
26182702
# This loads `obj` onto the stack, executes `del obj`, then returns the
26192703
# `obj` from the stack. See gh-133371 for more details.
@@ -2630,6 +2714,14 @@ def create_obj():
26302714
gc.collect()
26312715
self.assertEqual(obj, [42])
26322716

2717+
deftest_format_simple_unicode(self):
2718+
# Repro from gh-134889
2719+
deff():
2720+
var=f"{1}"
2721+
var=f"{var}"
2722+
returnvar
2723+
self.assertEqual(f(),"1")
2724+
26332725

26342726

26352727
if__name__=="__main__":
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix handling of a few opcodes that leave operands on the stack when
2+
optimizing ``LOAD_FAST``.

‎Python/flowgraph.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2870,9 +2870,11 @@ optimize_load_fast(cfg_builder *g)
28702870
// how many inputs should be left on the stack.
28712871

28722872
// Opcodes that consume no inputs
2873+
caseFORMAT_SIMPLE:
28732874
caseGET_ANEXT:
28742875
caseGET_ITER:
28752876
caseGET_LEN:
2877+
caseGET_YIELD_FROM_ITER:
28762878
caseIMPORT_FROM:
28772879
caseMATCH_KEYS:
28782880
caseMATCH_MAPPING:
@@ -2907,6 +2909,16 @@ optimize_load_fast(cfg_builder *g)
29072909
break;
29082910
}
29092911

2912+
caseEND_SEND:
2913+
caseSET_FUNCTION_ATTRIBUTE: {
2914+
assert(_PyOpcode_num_popped(opcode,oparg)==2);
2915+
assert(_PyOpcode_num_pushed(opcode,oparg)==1);
2916+
reftos=ref_stack_pop(&refs);
2917+
ref_stack_pop(&refs);
2918+
PUSH_REF(tos.instr,tos.local);
2919+
break;
2920+
}
2921+
29102922
// Opcodes that consume some inputs and push new values
29112923
caseCHECK_EXC_MATCH: {
29122924
ref_stack_pop(&refs);
@@ -2936,6 +2948,14 @@ optimize_load_fast(cfg_builder *g)
29362948
break;
29372949
}
29382950

2951+
caseLOAD_SPECIAL:
2952+
casePUSH_EXC_INFO: {
2953+
reftos=ref_stack_pop(&refs);
2954+
PUSH_REF(i,NOT_LOCAL);
2955+
PUSH_REF(tos.instr,tos.local);
2956+
break;
2957+
}
2958+
29392959
caseSEND: {
29402960
load_fast_push_block(&sp,instr->i_target,refs.size);
29412961
ref_stack_pop(&refs);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp