Skip to content

Commit 004d144

Browse files
author
rocky
committed
WIP - Bang on getting Stack Effects correct.
1 parent c2b6d11 commit 004d144

File tree

9 files changed

+31
-17
lines changed

9 files changed

+31
-17
lines changed

xdis/cross_dis.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,10 @@ def xstack_effect(opcode, opc, oparg: int = 0, jump=None):
473473
if opname == "BUILD_MAP" and version_tuple >= (3, 5):
474474
return 1 - (2 * oparg)
475475
elif opname in ("UNPACK_SEQUENCE", "UNPACK_EX") and version_tuple >= (3, 0):
476-
return push + oparg
476+
return (oparg & 0xFF) + (oparg >> 8)
477+
elif opname == "BUILD_INTERPOLATION":
478+
# 3.14+ only
479+
return -2 if oparg & 1 else -1
477480
elif opname in (
478481
"BUILD_LIST",
479482
"BUILD_SET",
@@ -503,6 +506,8 @@ def xstack_effect(opcode, opc, oparg: int = 0, jump=None):
503506
elif opname == "CALL_KW":
504507
return -2 - oparg
505508
elif opname == "CALL_FUNCTION_EX":
509+
if version_tuple >= (3, 14):
510+
return -3
506511
if (3, 5) <= version_tuple < (3, 11):
507512
return -2 if oparg & 1 else -1
508513
elif 0 <= oparg <= 3:

xdis/opcodes/base.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# (C) Copyright 2017, 2019-2024 by Rocky Bernstein
1+
# (C) Copyright 2017, 2019-2025 by Rocky Bernstein
22
#
33
# This program is free software; you can redistribute it and/or
44
# modify it under the terms of the GNU General Public License
@@ -26,6 +26,11 @@
2626
from xdis.cross_dis import findlabels, findlinestarts, get_jump_target_maps
2727
from xdis.version_info import IS_PYPY, PYTHON_VERSION_TRIPLE, PythonImplementation
2828

29+
# The VARYING_STACK_INT value is used to indicate that the push or pop stack value
30+
# for an operation can change. In such cases other means such as looking and an
31+
# operation's operand value may be needed.
32+
VARYING_STACK_INT = -3000
33+
2934
cpython_implementation = PythonImplementation("CPython")
3035

3136
cmp_op = (

xdis/opcodes/opcode_310graal.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
from typing import Dict, Set
2323

24-
from xdis.opcodes.base import init_opdata
24+
from xdis.opcodes.base import VARYING_STACK_INT, init_opdata
2525
from xdis.opcodes.base_graal import findlabels # noqa
2626
from xdis.opcodes.base_graal import ( # find_linestarts, # noqa
2727
binary_op_graal,
@@ -474,7 +474,7 @@
474474
# operand)
475475
#
476476
def_op_graal(
477-
loc, "UNPACK_EX", 0x48, 2, 1, 1
477+
loc, "UNPACK_EX", 0x48, 2, VARYING_STACK_INT, VARYING_STACK_INT
478478
) # (oparg, followingArgs, withJump) -> oparg + 1 + Byte.toUnsignedInt(followingArgs[0]))
479479

480480
# jumps

xdis/opcodes/opcode_311graal.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
from typing import Dict, Set
2323

24-
from xdis.opcodes.base import init_opdata
24+
from xdis.opcodes.base import VARYING_STACK_INT, init_opdata
2525
from xdis.opcodes.base_graal import findlabels # noqa
2626
from xdis.opcodes.base_graal import ( # find_linestarts, # noqa
2727
binary_op_graal,
@@ -492,7 +492,7 @@
492492
# operand)
493493
#
494494
def_op_graal(
495-
loc, "UNPACK_EX", 0x48, 2, 1, 1
495+
loc, "UNPACK_EX", 0x48, 2, VARYING_STACK_INT, VARYING_STACK_INT
496496
) # (oparg, followingArgs, withJump) -> oparg + 1 + Byte.toUnsignedInt(followingArgs[0]))
497497

498498
# jumps

xdis/opcodes/opcode_312graal.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
from typing import Dict, Set
2323

24-
from xdis.opcodes.base import init_opdata
24+
from xdis.opcodes.base import VARYING_STACK_INT, init_opdata
2525

2626
# from xdis.opcodes.base_graal import findlabels # noqa
2727
from xdis.opcodes.base_graal import ( # find_linestarts, # noqa
@@ -485,7 +485,7 @@
485485
# operand)
486486
#
487487
def_op_graal(
488-
loc, "UNPACK_EX", 0x4a, 2, 1, 1
488+
loc, "UNPACK_EX", 0x4a, 2, VARYING_STACK_INT, VARYING_STACK_INT
489489
) # (oparg, followingArgs, withJump) -> oparg + 1 + Byte.toUnsignedInt(followingArgs[0]))
490490

491491
# jumps

xdis/opcodes/opcode_312rust.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
from typing import Dict, List, Optional, Tuple
99

10+
from opcodes.base import VARYING_STACK_INT
11+
1012
import xdis.opcodes.opcode_313 as opcode_313
1113
from xdis.opcodes.base import (
1214
binary_op,
@@ -174,7 +176,7 @@ def pseudo_op(name: str, op: int, real_ops: list):
174176
name_op(loc, "DELETE_NAME", 91) # ""
175177
def_op(loc, "UNPACK_SEQUENCE", 92) # Number of tuple items
176178
jrel_op(loc, "FOR_ITER", 93)
177-
def_op(loc, "UNPACK_EX", 94)
179+
def_op(loc, "UNPACK_EX", 94, VARYING_STACK_INT, VARYING_STACK_INT)
178180
name_op(loc, "STORE_ATTR", 95) # Index in name list
179181
name_op(loc, "DELETE_ATTR", 96) # ""
180182
name_op(loc, "STORE_GLOBAL", 97) # ""

xdis/opcodes/opcode_313.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import xdis.opcodes.opcode_312 as opcode_312
88
from xdis.opcodes.base import ( # noqa
9+
VARYING_STACK_INT,
910
cpython_implementation as python_implementation,
1011
def_op,
1112
finalize_opcodes,
@@ -282,7 +283,7 @@
282283
def_op(loc, "STORE_GLOBAL" , 113 , 1 , 0)
283284
def_op(loc, "STORE_NAME" , 114 , 1 , 0)
284285
def_op(loc, "SWAP" , 115 , 0 , 0)
285-
def_op(loc, "UNPACK_EX" , 116 , 0 , 0)
286+
def_op(loc, "UNPACK_EX" , 116 , VARYING_STACK_INT, VARYING_STACK_INT)
286287
def_op(loc, "UNPACK_SEQUENCE" , 117 , 0 , -1)
287288
def_op(loc, "YIELD_VALUE" , 118 , 1 , 1)
288289
def_op(loc, "RESUME" , 149 , 0 , 0)

xdis/opcodes/opcode_314.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44

55
from xdis.opcodes.base import ( # noqa
6+
VARYING_STACK_INT,
67
binary_op,
78
call_op,
89
compare_op,
@@ -51,7 +52,7 @@
5152
def_op(loc, "FORMAT_WITH_SPEC", 13, 2, 1)
5253
def_op(loc, "GET_AITER", 14, 1, 1)
5354
def_op(loc, "GET_ANEXT", 15, 1, 2)
54-
def_op(loc, "GET_ITER", 16, 1, 2)
55+
def_op(loc, "GET_ITER", 16, 0, 0)
5556
def_op(loc, "RESERVED", 17, 0, 0)
5657
def_op(loc, "GET_LEN", 18, 1, 2)
5758
def_op(loc, "GET_YIELD_FROM_ITER", 19, 1, 1)
@@ -65,7 +66,7 @@
6566
def_op(loc, "NOP", 27, 0, 0)
6667
def_op(loc, "NOT_TAKEN", 28, 0, 0)
6768
def_op(loc, "POP_EXCEPT", 29, 1, 0)
68-
def_op(loc, "POP_ITER", 30, 2, 0)
69+
def_op(loc, "POP_ITER", 30, 1, 0)
6970
def_op(loc, "POP_TOP", 31, 1, 0)
7071
def_op(loc, "PUSH_EXC_INFO", 32, 1, 2)
7172
def_op(loc, "PUSH_NULL", 33, 0, 1)
@@ -80,7 +81,7 @@
8081
unary_op(loc, "UNARY_NOT", 42, 1, 1)
8182
def_op(loc, "WITH_EXCEPT_START", 43, 5, 6)
8283
binary_op(loc, "BINARY_OP", 44, 2, 1)
83-
def_op(loc, "BUILD_INTERPOLATION", 45, 2, 1) # pops 2 + (oparg & 1)
84+
def_op(loc, "BUILD_INTERPOLATION", 45, VARYING_STACK_INT, 1) # Either -1 or -2: pops 2 + (oparg & 1) and pushes result
8485
varargs_op(loc, "BUILD_LIST", 46, -1, 1) # TOS is count of list items
8586
varargs_op(loc, "BUILD_MAP", 47, 0, 1) # argument is dictionary count to be popped
8687
varargs_op(loc, "BUILD_SET", 48, -1, 1) # TOS is count of set items
@@ -153,8 +154,8 @@
153154
store_op(loc, "STORE_GLOBAL", 115, 1, 0, is_type="name")
154155
store_op(loc, "STORE_NAME", 116, 1, 0, is_type="name")
155156
def_op(loc, "SWAP", 117, 0, 0)
156-
varargs_op(loc, "UNPACK_EX", 118, 1, -1) # pushes 1 + (oparg & 0xFF) + (oparg >> 8)
157-
varargs_op(loc, "UNPACK_SEQUENCE", 119, 0, -1) # unpacks TOS, arg is the count
157+
varargs_op(loc, "UNPACK_EX", 118, VARYING_STACK_INT, VARYING_STACK_INT) # pushes 1 + (oparg & 0xFF) + (oparg >> 8)
158+
varargs_op(loc, "UNPACK_SEQUENCE", 119, VARYING_STACK_INT, VARYING_STACK_INT) # unpacks TOS, arg is the count
158159
def_op(loc, "YIELD_VALUE", 120, 1, 1)
159160
def_op(loc, "RESUME", 128, 0, 0)
160161

xdis/opcodes/opcode_38graal.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
from typing import Dict, Set
2323

24-
from xdis.opcodes.base import init_opdata
24+
from xdis.opcodes.base import VARYING_STACK_INT, init_opdata
2525
from xdis.opcodes.base_graal import findlabels # noqa
2626
from xdis.opcodes.base_graal import (
2727
binary_op_graal,
@@ -435,7 +435,7 @@
435435
# operand)
436436
#
437437
def_op_graal(
438-
loc, "UNPACK_EX", 0x3D, 2, 1, 1
438+
loc, "UNPACK_EX", 0x3D, 2, VARYING_STACK_INT, VARYING_STACK_INT
439439
) # (oparg, followingArgs, withJump) -> oparg + 1 + Byte.toUnsignedInt(followingArgs[0]))
440440

441441
# jumps

0 commit comments

Comments
 (0)