Skip to content

Commit a60551b

Browse files
committed
Fix handling of LOAD_SPECIAL
Load special may leave `self` on TOS. Treat it conservatively and assume it always does.
1 parent 3e6aa3f commit a60551b

3 files changed

Lines changed: 12 additions & 1 deletion

File tree

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-
%4d LOAD_FAST_BORROW 0 (c)
609+
%4d LOAD_FAST 0 (c)
610610
COPY 1
611611
LOAD_SPECIAL 3 (__aexit__)
612612
SWAP 2

Lib/test/test_peepholer.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2688,6 +2688,16 @@ def test_push_exc_info(self):
26882688
]
26892689
self.check(insts, insts)
26902690

2691+
def test_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+
26912701
def test_del_in_finally(self):
26922702
# This loads `obj` onto the stack, executes `del obj`, then returns the
26932703
# `obj` from the stack. See gh-133371 for more details.

Python/flowgraph.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2948,6 +2948,7 @@ optimize_load_fast(cfg_builder *g)
29482948
break;
29492949
}
29502950

2951+
case LOAD_SPECIAL:
29512952
case PUSH_EXC_INFO: {
29522953
ref tos = ref_stack_pop(&refs);
29532954
PUSH_REF(i, NOT_LOCAL);

0 commit comments

Comments
 (0)