Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Latest commit

 

History

History
History
81 lines (60 loc) · 2.24 KB

File metadata and controls

81 lines (60 loc) · 2.24 KB
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
"""
Generate Lib/_opcode_metadata.py for RustPython bytecode.
This file generates opcode metadata that is compatible with CPython 3.13.
"""
import itertools
import pathlib
import re
import typing
ROOT = pathlib.Path(__file__).parents[1]
BYTECODE_FILE = (
ROOT / "crates" / "compiler-core" / "src" / "bytecode" / "instruction.rs"
)
OPCODE_METADATA_FILE = ROOT / "Lib" / "_opcode_metadata.py"
class Opcode(typing.NamedTuple):
rust_name: str
id: int
@property
def cpython_name(self) -> str:
name = re.sub(r"(?<=[a-z0-9])([A-Z])", r"_\1", self.rust_name)
return re.sub(r"(\D)(\d+)$", r"\1_\2", name).upper()
@classmethod
def from_str(cls, body: str):
raw_variants = re.split(r"(\d+),", body.strip())
raw_variants.remove("")
for raw_name, raw_id in itertools.batched(raw_variants, 2):
name = re.findall(r"\b[A-Z][A-Za-z]*\d*\b(?=\s*[\({=])", raw_name)[0]
yield cls(rust_name=name.strip(), id=int(raw_id))
def __lt__(self, other: typing.Self) -> bool:
return self.id < other.id
def extract_enum_body(contents: str, enum_name: str) -> str:
res = re.search(f"pub enum {enum_name} " + r"\{(.+?)\n\}", contents, re.DOTALL)
if not res:
raise ValueError(f"Could not find {enum_name} enum")
return "\n".join(
line.split("//")[0].strip() # Remove any comment. i.e. "foo // some comment"
for line in res.group(1).splitlines()
if not line.strip().startswith("//") # Ignore comment lines
)
contents = BYTECODE_FILE.read_text(encoding="utf-8")
enum_body = "\n".join(
extract_enum_body(contents, enum_name)
for enum_name in ("Instruction", "PseudoInstruction")
)
opcodes = list(Opcode.from_str(enum_body))
# Generate the output file
output = """# This file is generated by scripts/generate_opcode_metadata.py
# for RustPython bytecode format (CPython 3.13 compatible opcode numbers).
# Do not edit!
_specializations = {}
_specialized_opmap = {}
opmap = {
"""
for opcode in sorted(opcodes):
output += f" '{opcode.cpython_name}': {opcode.id},\n"
output += """}
# CPython 3.13 compatible: opcodes < 44 have no argument
HAVE_ARGUMENT = 44
MIN_INSTRUMENTED_OPCODE = 236
"""
OPCODE_METADATA_FILE.write_text(output, encoding="utf-8")
Morty Proxy This is a proxified and sanitized view of the page, visit original site.