Reorder instructions in with/async-with exception handler to reduce the size of the exception table. #93621
Closed
Description
The dis for this function:
def f1(cm):
with cm:
x = 1
x = 2
is this:
11 0 RESUME 0
12 2 LOAD_FAST 0 (cm)
4 BEFORE_WITH
6 POP_TOP
13 8 LOAD_CONST 1 (1)
10 STORE_FAST 1 (x)
12 12 LOAD_CONST 0 (None)
14 LOAD_CONST 0 (None)
16 LOAD_CONST 0 (None)
18 CALL 2
28 POP_TOP
14 30 LOAD_CONST 2 (2)
32 STORE_FAST 1 (x)
34 LOAD_CONST 0 (None)
36 RETURN_VALUE
12 >> 38 PUSH_EXC_INFO
40 WITH_EXCEPT_START
42 POP_JUMP_FORWARD_IF_TRUE 4 (to 52)
44 RERAISE 2
>> 46 COPY 3
48 POP_EXCEPT
50 RERAISE 1
>> 52 POP_TOP
54 POP_EXCEPT
56 POP_TOP
58 POP_TOP
14 60 LOAD_CONST 2 (2)
62 STORE_FAST 1 (x)
64 LOAD_CONST 0 (None)
66 RETURN_VALUE
ExceptionTable:
6 to 10 -> 38 [1] lasti
38 to 44 -> 46 [3] lasti
52 to 52 -> 46 [3] lasti
Note the last row of the exception table: inst 52 goes to 46, same as 38-44. We can reorder the code so that this block is consecutive, and we save one entry in the exception table for each with/async with:
11 0 RESUME 0
12 2 LOAD_FAST 0 (cm)
4 BEFORE_WITH
6 POP_TOP
13 8 LOAD_CONST 1 (1)
10 STORE_FAST 1 (x)
12 12 LOAD_CONST 0 (None)
14 LOAD_CONST 0 (None)
16 LOAD_CONST 0 (None)
18 CALL 2
28 POP_TOP
14 30 LOAD_CONST 2 (2)
32 STORE_FAST 1 (x)
34 LOAD_CONST 0 (None)
36 RETURN_VALUE
12 >> 38 PUSH_EXC_INFO
40 WITH_EXCEPT_START
42 POP_JUMP_FORWARD_IF_TRUE 1 (to 46)
44 RERAISE 2
>> 46 POP_TOP
48 POP_EXCEPT
50 POP_TOP
52 POP_TOP
14 54 LOAD_CONST 2 (2)
56 STORE_FAST 1 (x)
58 LOAD_CONST 0 (None)
60 RETURN_VALUE
>> 62 COPY 3
64 POP_EXCEPT
66 RERAISE 1
ExceptionTable:
6 to 10 -> 38 [1] lasti
38 to 46 -> 62 [3] lasti