|
6 | 6 | by Python 3.10, and 3.11 features are not available.
|
7 | 7 | """
|
8 | 8 | import argparse
|
9 |
| -import ast |
10 | 9 | import builtins
|
11 | 10 | import collections
|
12 | 11 | import contextlib
|
|
17 | 16 | from typing import Dict, FrozenSet, TextIO, Tuple
|
18 | 17 |
|
19 | 18 | import umarshal
|
20 |
| -from generate_global_objects import get_identifiers_and_strings |
| 19 | + |
| 20 | +ROOT = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) |
21 | 21 |
|
22 | 22 | verbose = False
|
23 |
| -identifiers, strings = get_identifiers_and_strings() |
24 | 23 |
|
25 | 24 | # This must be kept in sync with opcode.py
|
26 | 25 | RESUME = 151
|
@@ -114,13 +113,27 @@ def __init__(self, file: TextIO) -> None:
|
114 | 113 | self.hits, self.misses = 0, 0
|
115 | 114 | self.finis: list[str] = []
|
116 | 115 | self.inits: list[str] = []
|
| 116 | + self.identifiers, self.strings = self.get_identifiers_and_strings() |
117 | 117 | self.write('#include "Python.h"')
|
118 | 118 | self.write('#include "internal/pycore_gc.h"')
|
119 | 119 | self.write('#include "internal/pycore_code.h"')
|
120 | 120 | self.write('#include "internal/pycore_frame.h"')
|
121 | 121 | self.write('#include "internal/pycore_long.h"')
|
122 | 122 | self.write("")
|
123 | 123 |
|
| 124 | + def get_identifiers_and_strings(self) -> tuple[set[str], dict[str, str]]: |
| 125 | + filename = os.path.join(ROOT, "Include", "internal", "pycore_global_strings.h") |
| 126 | + with open(filename) as fp: |
| 127 | + lines = fp.readlines() |
| 128 | + identifiers: set[str] = set() |
| 129 | + strings: dict[str, str] = {} |
| 130 | + for line in lines: |
| 131 | + if m := re.search(r"STRUCT_FOR_ID\((\w+)\)", line): |
| 132 | + identifiers.add(m.group(1)) |
| 133 | + if m := re.search(r'STRUCT_FOR_STR\((\w+), "(.*?)"\)', line): |
| 134 | + strings[m.group(2)] = m.group(1) |
| 135 | + return identifiers, strings |
| 136 | + |
124 | 137 | @contextlib.contextmanager
|
125 | 138 | def indent(self) -> None:
|
126 | 139 | save_level = self.level
|
@@ -171,9 +184,9 @@ def generate_bytes(self, name: str, b: bytes) -> str:
|
171 | 184 | return f"& {name}.ob_base.ob_base"
|
172 | 185 |
|
173 | 186 | def generate_unicode(self, name: str, s: str) -> str:
|
174 |
| - if s in strings: |
175 |
| - return f"&_Py_STR({strings[s]})" |
176 |
| - if s in identifiers: |
| 187 | + if s in self.strings: |
| 188 | + return f"&_Py_STR({self.strings[s]})" |
| 189 | + if s in self.identifiers: |
177 | 190 | return f"&_Py_ID({s})"
|
178 | 191 | if len(s) == 1:
|
179 | 192 | c = ord(s)
|
@@ -441,12 +454,10 @@ def is_frozen_header(source: str) -> bool:
|
441 | 454 |
|
442 | 455 |
|
443 | 456 | def decode_frozen_data(source: str) -> types.CodeType:
|
444 |
| - lines = source.splitlines() |
445 |
| - while lines and re.match(FROZEN_DATA_LINE, lines[0]) is None: |
446 |
| - del lines[0] |
447 |
| - while lines and re.match(FROZEN_DATA_LINE, lines[-1]) is None: |
448 |
| - del lines[-1] |
449 |
| - values: Tuple[int, ...] = ast.literal_eval("".join(lines).strip()) |
| 457 | + values: list[int] = [] |
| 458 | + for line in source.splitlines(): |
| 459 | + if re.match(FROZEN_DATA_LINE, line): |
| 460 | + values.extend([int(x) for x in line.split(",") if x.strip()]) |
450 | 461 | data = bytes(values)
|
451 | 462 | return umarshal.loads(data)
|
452 | 463 |
|
|
0 commit comments