Skip to content

Commit f19046b

Browse files
author
rocky
committed
Finish going over rust 3.13 opcodes
1 parent f00f107 commit f19046b

File tree

3 files changed

+47
-114
lines changed

3 files changed

+47
-114
lines changed

xdis/codetype/code313rust.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,18 @@
1717
from dataclasses import dataclass
1818
from typing import Any, Dict, Tuple, Union
1919

20-
from xdis.codetype.base import CodeBase
20+
from xdis.codetype.code311 import Code311
2121

2222

2323
@dataclass
2424
class SourceLocation:
25-
# line: 1-based int
26-
line: int
27-
# character_offset: 1-based int (constructed from a zero-indexed stored value)
28-
character_offset: int
25+
# 1-based integer line number
26+
line_number: int
27+
# column offset in line: 1-based int (constructed from a zero-indexed stored value)
28+
column_offset: int
2929

3030

31-
class Code313Rust(CodeBase):
31+
class Code313Rust(Code311):
3232
"""Class for a RustPython 3.13 code object used when a Python
3333
interpreter is not RustPython 3.13 but working on RustPython 3.13 bytecode. It
3434
also functions as an object that can be used to build or write a
@@ -61,9 +61,10 @@ def __init__(
6161
co_linetable: bytes,
6262
co_freevars: tuple,
6363
co_cellvars: tuple,
64+
version_triple: Tuple[int, int, int],
65+
locations: tuple,
6466
co_exceptiontable = tuple(),
6567
collection_order: Dict[Union[set, frozenset, dict], Tuple[Any]] = {},
66-
version_triple: Tuple[int, int, int] = (0, 0, 0),
6768
) -> None:
6869
self.co_argcount = co_argcount
6970
self.co_posonlyargcount = co_posonlyargcount
@@ -85,7 +86,5 @@ def __init__(
8586
self.co_freevars= co_freevars
8687
self.co_exceptiontable = co_exceptiontable
8788
self.co_collection_order = collection_order
88-
version_triple = version_triple
89-
90-
def co_lines(self):
91-
return [(sl.line, sl.character_offset, sl.character_offset) for sl in self.co_linetable]
89+
self.version_triple = version_triple
90+
self.locations = locations

xdis/opcodes/opcode_313rust.py

Lines changed: 28 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# (C) Copyright 2019-2023, 2025 by Rocky Bernstein
1+
# (C) Copyright 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
@@ -14,14 +14,15 @@
1414
# along with this program; if not, write to the Free Software
1515
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1616
"""
17-
RustPython 3.13 bytecode opcodes
18-
17+
RustPython 3.13 bytecode opcodes for version 0.40. There are other Rust 3.13 with different opcodes!
1918
"""
2019

2120
#FIXME: this needs a lot of going over.
2221

2322
from typing import Dict, List, Optional, Tuple
2423

24+
import xdis.opcodes.opcode_311 as opcode_311
25+
2526
# import xdis.opcodes.opcode_313 as opcode_313
2627
from xdis.opcodes.base import (
2728
VARYING_STACK_INT,
@@ -153,9 +154,12 @@ def pseudo_op(name: str, op: int, real_ops: list):
153154
name_op(loc, "IMPORT_FROM", 3)
154155

155156
local_op(loc, "LOAD_FAST", 4)
156-
name_op(loc, "LOAD_NAME_ANY", 5)
157+
name_op(loc, "LOAD_NAME", 5)
157158
name_op(loc, "LOAD_GLOBAL", 6)
158159
free_op(loc, "LOAD_DEREF", 7)
160+
loc["nullaryop"].add(7)
161+
loc["nullaryloadop"].add(7)
162+
159163
def_op(loc, "LOAD_CLASS_DEREF", 8)
160164

161165
store_op(loc, "STORE_FAST", 9, 1, 0, is_type="local") # Local variable
@@ -249,97 +253,28 @@ def pseudo_op(name: str, op: int, real_ops: list):
249253
varargs_op(loc, "BUILD_SET_FROM_TUPLES", 83, 1, VARYING_STACK_INT) # Number of list items
250254
varargs_op(loc, "BUILD_MAP", 84, 1, VARYING_STACK_INT) # Number of dict entries
251255
varargs_op(loc, "BUILD_MAP_FOR_CALL", 85, 1, VARYING_STACK_INT) # Number of dict entries
252-
253-
def_op(loc, "ASYNC_GEN_WRAP", 88)
254-
def_op(loc, "LIST_APPEND", 89)
255-
def_op(loc, "SET_ADD", 90)
256-
def_op(loc, "MAP_ADD", 91)
257-
def_op(loc, "PRINT_EXPR", 92)
258-
def_op(loc, "LOAD_BUILD_CLASS", 93)
259-
varargs_op(loc, "UNPACK_SEQUENCE", 94, 1, VARYING_STACK_INT) # Number of tuple items
260-
def_op(loc, "UNPACK_EX", 95, VARYING_STACK_INT, VARYING_STACK_INT)
261-
def_op(loc, "FORMAT_VALUE", 96, VARYING_STACK_INT, VARYING_STACK_INT)
262-
def_op(loc, "POP_EXCEPT", 97)
263-
def_op(loc, "REVERSE", 98)
264-
def_op(loc, "GET_AWAITABLE", 99)
265-
def_op(loc, "GET_AITER", 100)
266-
def_op(loc, "GET_ANEXT", 101)
267-
268-
269-
270-
name_op(loc, "LOAD_NAME", 101) # Index in name list
271-
name_op(loc, "IMPORT_FROM", 109) # Index in name list
272-
def_op(loc, "IS_OP", 117)
273-
def_op(loc, "CONTAINS_OP", 118)
274-
def_op(loc, "RERAISE", 119, 3, 0)
275-
def_op(loc, "BINARY_OP", 122)
276-
jrel_op(loc, "SEND", 123) # Number of bytes to skip
277-
loc["nullaryloadop"].add(124)
278-
def_op(loc , "LOAD_FAST_CHECK" , 127, 0, 1)
279-
local_op(loc, "LOAD_FAST_CHECK", 127) # Local variable number
280-
jrel_op(loc, "POP_JUMP_IF_NOT_NONE", 128)
281-
jrel_op(loc, "POP_JUMP_IF_NONE", 129)
282-
def_op(loc, "RAISE_VARARGS", 130) # Number of raise arguments (1, 2, or 3)
283-
def_op(loc, "BUILD_SLICE", 133) # Number of items
284-
jrel_op(loc, "JUMP_BACKWARD_NO_INTERRUPT", 134) # Number of words to skip (backwards)
285-
free_op(loc, "MAKE_CELL", 135, 0, 0)
286-
free_op(loc, "LOAD_DEREF", 137, 0, 1)
287-
loc["nullaryop"].add(137)
288-
loc["nullaryloadop"].add(137)
289-
jrel_op(loc, "JUMP_BACKWARD", 140) # Number of words to skip (backwards)
290-
291-
def_op(loc, "EXTENDED_ARG", 144)
292-
EXTENDED_ARG = 144
293-
def_op(loc, "SET_ADD", 146)
294-
def_op(loc, "MAP_ADD", 147)
295-
free_op(loc, "LOAD_CLASSDEREF", 148)
296-
def_op(loc, "COPY_FREE_VARS", 149)
297-
def_op(loc, "YIELD_VALUE", 150)
298-
299-
300-
def_op(loc, "MATCH_CLASS", 152)
301-
302-
def_op(loc, "FORMAT_VALUE", 155)
303-
def_op(loc, "BUILD_CONST_KEY_MAP", 156)
304-
def_op(loc, "BUILD_STRING", 157)
305-
306-
def_op(loc, "LIST_EXTEND", 162)
307-
def_op(loc, "SET_UPDATE", 163)
308-
def_op(loc, "DICT_MERGE", 164)
309-
def_op(loc, "DICT_UPDATE", 165)
310-
311-
const_op(loc, "KW_NAMES", 172)
312-
313-
MIN_PSEUDO_OPCODE = 256
314-
315-
hasexc.append(256)
316-
pseudo_op("SETUP_CLEANUP", 257, ["NOP"])
317-
hasexc.append(257)
318-
hasexc.append(258)
319-
320-
# pseudo_op("JUMP", 260, ["JUMP_FORWARD", "JUMP_BACKWARD"])
321-
# pseudo_op("JUMP_NO_INTERRUPT", 261, ["JUMP_FORWARD", "JUMP_BACKWARD_NO_INTERRUPT"])
322-
323-
def_op(loc, "MATCH_SEQUENCE", 232, 0, 1)
324-
def_op(loc, "MATCH_KEYS", 233, 0, 2)
325-
326-
256+
varargs_op(loc, "DICT_UPDATE", 86) # Number of dict entries
257+
def_op(loc, "BUILD_SLICE", 87)
258+
def_op(loc, "LIST_APPEND", 88)
259+
def_op(loc, "SET_ADD", 89)
260+
def_op(loc, "MAP_ADD", 90)
261+
def_op(loc, "PRINT_EXPR", 91)
262+
def_op(loc, "LOAD_BUILD_CLASS", 92)
263+
varargs_op(loc, "UNPACK_SEQUENCE", 93, 1, VARYING_STACK_INT) # Number of tuple items
264+
def_op(loc, "UNPACK_EX", 94, VARYING_STACK_INT, VARYING_STACK_INT)
265+
def_op(loc, "FORMAT_VALUE", 95, VARYING_STACK_INT, VARYING_STACK_INT)
266+
def_op(loc, "POP_EXCEPT", 96)
267+
def_op(loc, "REVERSE", 97)
268+
def_op(loc, "GET_AWAITABLE", 98)
269+
def_op(loc, "END_ASYNC_FOR", 99)
270+
def_op(loc, "MATCH_MAPPING", 100)
271+
def_op(loc, "MATCH_SEQUENCE", 101)
272+
def_op(loc, "MATCH_CLASS", 102)
273+
def_op(loc, "EXTENDED_ARG", 103)
274+
EXTENDED_ARG = 103
327275

328276
# fmt: on
329277

330-
MAX_PSEUDO_OPCODE = MIN_PSEUDO_OPCODE + len(_pseudo_ops) - 1
331-
332-
# extend opcodes to cover pseudo ops
333-
334-
opname = [f"<{op!r}>" for op in range(MAX_PSEUDO_OPCODE + 1)]
335-
opname.extend([f"<{i}>" for i in range(256, 267)])
336-
oppop.extend([0] * 11)
337-
oppush.extend([0] * 11)
338-
339-
for op, i in opmap.items():
340-
opname[i] = op
341-
342-
343278
_specializations = {
344279
"BINARY_OP": [
345280
"BINARY_OP_ADAPTIVE",
@@ -511,6 +446,7 @@ def pseudo_op(name: str, op: int, real_ops: list):
511446
sum(_cache_format.get(opname[opcode], {}).values()) for opcode in range(256)
512447
]
513448

449+
findlinestarts = opcode_311.findlinestarts
514450

515451
def extended_format_BINARY_OP(opc, instructions) -> Tuple[str, Optional[int]]:
516452
opname = _nb_ops[instructions[0].argval][1]
@@ -532,7 +468,6 @@ def extended_format_BINARY_OP(opc, instructions) -> Tuple[str, Optional[int]]:
532468
},
533469
}
534470

535-
from xdis.opcodes.opcode_311 import findlinestarts
536471

537472
update_pj3(globals(), loc, is_rust=True)
538473
finalize_opcodes(loc)

xdis/unmarsh_rust.py

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -163,24 +163,21 @@ def t_code_rust(self, save_ref, bytes_for_s: bool = False) -> Code313Rust:
163163
instr_count = self.read_int32()
164164
co_code = self.read_slice(instr_count * 2)
165165

166-
# instructions = [
167-
# int.from_bytes(co_code[i:i+2], "little") for i in range(0, len(co_code), 2)
168-
# ]
169-
instructions = [int(co_code[i]) for i in range(len(co_code))] # debug
166+
# instructions = [int(co_code[i]) for i in range(len(co_code))] # debug
170167

171168
# read locations
172169
loc_count = self.read_int32()
173170
locations: List[SourceLocation] = []
174171
for _ in range(loc_count):
175-
line = self.read_int32()
176-
if line == 0:
172+
line_number = self.read_int32()
173+
if line_number == 0:
177174
raise MarshalError("invalid source location")
178175
# OneIndexed::new used in Rust requires line != 0
179176
char_off_zero_indexed = self.read_int32()
180177
locations.append(
181178
SourceLocation(
182-
line=line,
183-
character_offset=char_off_zero_indexed + 1 # convert from zero-indexed
179+
line_number=line_number,
180+
column_offset=char_off_zero_indexed + 1 # convert from zero-indexed
184181
)
185182
)
186183

@@ -257,17 +254,19 @@ def read_names():
257254
co_stacksize=max_stackdepth,
258255
co_flags=flags,
259256
co_code=co_code,
260-
co_consts=constants,
257+
co_consts=tuple(constants),
261258
co_names=co_names,
262259
co_varnames=co_varnames,
263260
co_filename=source_path,
264261
co_name=obj_name,
265262
co_qualname=co_qualname,
266263
co_firstlineno=first_line_number,
267-
co_linetable=locations,
264+
co_linetable=co_linetable,
268265
co_freevars=co_freevars,
269266
co_cellvars=co_cellvars,
270267
co_exceptiontable=co_exceptiontable,
268+
version_triple=self.version_triple,
269+
locations=tuple(locations),
271270
)
272271

273272

0 commit comments

Comments
 (0)