| 108 | return base |
| 109 | |
| 110 | class Printer: |
| 111 | |
| 112 | def __init__(self, file: TextIO) -> None: |
| 113 | self.level = 0 |
| 114 | self.file = file |
| 115 | self.cache: Dict[tuple[type, object, str], str] = {} |
| 116 | self.hits, self.misses = 0, 0 |
| 117 | self.patchups: list[str] = [] |
| 118 | self.deallocs: list[str] = [] |
| 119 | self.interns: list[str] = [] |
| 120 | self.write('#include "Python.h"') |
| 121 | self.write('#include "internal/pycore_gc.h"') |
| 122 | self.write('#include "internal/pycore_code.h"') |
| 123 | self.write('#include "internal/pycore_long.h"') |
| 124 | self.write("") |
| 125 | |
| 126 | @contextlib.contextmanager |
| 127 | def indent(self) -> None: |
| 128 | save_level = self.level |
| 129 | try: |
| 130 | self.level += 1 |
| 131 | yield |
| 132 | finally: |
| 133 | self.level = save_level |
| 134 | |
| 135 | def write(self, arg: str) -> None: |
| 136 | self.file.writelines((" "*self.level, arg, "\n")) |
| 137 | |
| 138 | @contextlib.contextmanager |
| 139 | def block(self, prefix: str, suffix: str = "") -> None: |
| 140 | self.write(prefix + " {") |
| 141 | with self.indent(): |
| 142 | yield |
| 143 | self.write("}" + suffix) |
| 144 | |
| 145 | def object_head(self, typename: str) -> None: |
| 146 | with self.block(".ob_base =", ","): |
| 147 | self.write(f".ob_refcnt = 999999999,") |
| 148 | self.write(f".ob_type = &{typename},") |
| 149 | |
| 150 | def object_var_head(self, typename: str, size: int) -> None: |
| 151 | with self.block(".ob_base =", ","): |
| 152 | self.object_head(typename) |
| 153 | self.write(f".ob_size = {size},") |
| 154 | |
| 155 | def field(self, obj: object, name: str) -> None: |
| 156 | self.write(f".{name} = {getattr(obj, name)},") |
| 157 | |
| 158 | def generate_bytes(self, name: str, b: bytes) -> str: |
| 159 | if b == b"": |
| 160 | return "(PyObject *)&_Py_SINGLETON(bytes_empty)" |
| 161 | if len(b) == 1: |
| 162 | return f"(PyObject *)&_Py_SINGLETON(bytes_characters[{b[0]}])" |
| 163 | self.write("static") |
| 164 | with self.indent(): |
| 165 | with self.block("struct"): |
| 166 | self.write("PyObject_VAR_HEAD") |
| 167 | self.write("Py_hash_t ob_shash;") |