Skip to content

Commit 9de4086

Browse files
author
rocky
committed
First cut at RustPython disassembly
1 parent 2136d33 commit 9de4086

File tree

8 files changed

+552
-5
lines changed

8 files changed

+552
-5
lines changed

xdis/codetype/code313rust.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ def __init__(
5858
co_name: str,
5959
co_qualname: str,
6060
co_firstlineno: int,
61-
co_linetable: tuple[SourceLocation],
62-
co_freevars,
63-
co_cellvars,
61+
co_linetable: bytes,
62+
co_freevars: tuple,
63+
co_cellvars: tuple,
6464
co_exceptiontable = tuple(),
6565
collection_order: Dict[Union[set, frozenset, dict], Tuple[Any]] = {},
6666
version_triple: Tuple[int, int, int] = (0, 0, 0),

xdis/cross_dis.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ def op_has_argument(opcode: int, opc) -> bool:
259259
"""
260260
Return True if `opcode` instruction has an operand.
261261
"""
262-
return opcode >= opc.HAVE_ARGUMENT
262+
return opcode in opc.hasarg if hasattr(opc, "hasarg") else opcode >= opc.HAVE_ARGUMENT
263263

264264

265265
def pretty_flags(flags, python_implementation=PYTHON_IMPLEMENTATION) -> str:

xdis/disasm.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ def get_opcode(
6868
lookup = "3.12.7Graal"
6969
else:
7070
lookup += "Graal"
71+
elif python_implementation == PythonImplementation.RustPython:
72+
lookup += "Rust"
7173
if lookup in op_imports.keys():
7274
if alternate_opmap is not None:
7375
# TODO: change bytecode version number comment line to indicate altered

xdis/load.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,6 @@ def load_module_from_file_object(
224224

225225
timestamp = 0
226226
file_offsets = {}
227-
python_implementation = PythonImplementation.CPython
228227
try:
229228
magic = fp.read(4)
230229
magic_int = magic2int(magic)
@@ -354,6 +353,7 @@ def load_module_from_file_object(
354353
finally:
355354
fp.close()
356355

356+
python_implementation = PythonImplementation.RustPython if magic_int in RUSTPYTHON_MAGICS else PythonImplementation.CPython
357357
if is_pypy(magic_int, filename):
358358
python_implementation = PythonImplementation.PyPy
359359

xdis/op_imports.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
opcode_312,
6565
opcode_312graal,
6666
opcode_313,
67+
opcode_313rust,
6768
opcode_314,
6869
)
6970
from xdis.version_info import PythonImplementation, version_tuple_to_str
@@ -187,6 +188,7 @@
187188
"3.12.0rc2": opcode_312,
188189
"3.12.0": opcode_312,
189190
"3.13.0rc3": opcode_313,
191+
"3.13.0Rust": opcode_313rust,
190192
"3.14b3": opcode_314,
191193
"3.14.0": opcode_314,
192194
"3.14": opcode_314,

xdis/opcodes/base.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,11 +188,15 @@ def call_op(
188188
Put opcode in the class of instructions that perform calls.
189189
"""
190190
loc["callop"].add(opcode)
191+
if "hasarg" in loc:
192+
loc["hasarg"].append(opcode)
191193
nargs_op(loc, name, opcode, pop, push, fallthrough)
192194

193195

194196
def compare_op(loc: dict, name: str, opcode: int, pop: int = 2, push: int = 1) -> None:
195197
def_op(loc, name, opcode, pop, push)
198+
if "hasarg" in loc:
199+
loc["hasarg"].append(opcode)
196200
loc["hascompare"].append(opcode)
197201
loc["binaryop"].add(opcode)
198202

@@ -203,6 +207,8 @@ def conditional_op(loc: dict, name: str, opcode: int) -> None:
203207

204208
def const_op(loc: dict, name: str, opcode: int, pop: int = 0, push: int = 1) -> None:
205209
def_op(loc, name, opcode, pop, push)
210+
if "hasarg" in loc:
211+
loc["hasarg"].append(opcode)
206212
loc["hasconst"].append(opcode)
207213
loc["nullaryop"].add(opcode)
208214

@@ -225,6 +231,8 @@ def def_op(
225231

226232
def free_op(loc: dict, name: str, opcode: int, pop: int = 0, push: int = 1) -> None:
227233
def_op(loc, name, opcode, pop, push)
234+
if "hasarg" in loc:
235+
loc["hasarg"].append(opcode)
228236
loc["hasfree"].append(opcode)
229237

230238

@@ -242,6 +250,8 @@ def jabs_op(
242250
"""
243251
def_op(loc, name, opcode, pop, push, fallthrough=fallthrough)
244252
loc["hasjabs"].append(opcode)
253+
if "hasarg" in loc:
254+
loc["hasarg"].append(opcode)
245255
if conditional:
246256
loc["hascondition"].append(opcode)
247257

@@ -252,12 +262,16 @@ def jrel_op(loc, name: str, opcode: int, pop: int=0, push: int=0, conditional=Fa
252262
"""
253263
def_op(loc, name, opcode, pop, push, fallthrough)
254264
loc["hasjrel"].append(opcode)
265+
if "hasarg" in loc:
266+
loc["hasarg"].append(opcode)
255267
if conditional:
256268
loc["hascondition"].append(opcode)
257269

258270

259271
def local_op(loc, name, opcode: int, pop=0, push=1) -> None:
260272
def_op(loc, name, opcode, pop, push)
273+
if "hasarg" in loc:
274+
loc["hasarg"].append(opcode)
261275
loc["haslocal"].append(opcode)
262276
loc["nullaryop"].add(opcode)
263277

@@ -268,6 +282,8 @@ def name_op(loc: dict, op_name, opcode: int, pop=-2, push=-2) -> None:
268282
"""
269283
def_op(loc, op_name, opcode, pop, push)
270284
loc["hasname"].append(opcode)
285+
if "hasarg" in loc:
286+
loc["hasarg"].append(opcode)
271287
loc["nullaryop"].add(opcode)
272288

273289

@@ -278,6 +294,8 @@ def nargs_op(
278294
Put opcode in the class of instructions that have a variable number of (or *n*) arguments
279295
"""
280296
def_op(loc, name, opcode, pop, push, fallthrough=fallthrough)
297+
if "hasarg" in loc:
298+
loc["hasarg"].append(opcode)
281299
loc["hasnargs"].append(opcode)
282300

283301

0 commit comments

Comments
 (0)