Assigns opcodes, then returns the opmap, have_arg and min_instrumented values
(
instructions: dict[str, Instruction],
families: dict[str, Family],
pseudos: dict[str, PseudoInstruction],
)
| 1198 | |
| 1199 | |
| 1200 | def assign_opcodes( |
| 1201 | instructions: dict[str, Instruction], |
| 1202 | families: dict[str, Family], |
| 1203 | pseudos: dict[str, PseudoInstruction], |
| 1204 | ) -> tuple[dict[str, int], int, int]: |
| 1205 | """Assigns opcodes, then returns the opmap, |
| 1206 | have_arg and min_instrumented values""" |
| 1207 | instmap: dict[str, int] = {} |
| 1208 | |
| 1209 | # 0 is reserved for cache entries. This helps debugging. |
| 1210 | instmap["CACHE"] = 0 |
| 1211 | |
| 1212 | # 17 is reserved as it is the initial value for the specializing counter. |
| 1213 | # This helps catch cases where we attempt to execute a cache. |
| 1214 | instmap["RESERVED"] = 17 |
| 1215 | |
| 1216 | # 128 is RESUME - it is hard coded as such in Tools/build/deepfreeze.py |
| 1217 | instmap["RESUME"] = 128 |
| 1218 | |
| 1219 | # This is an historical oddity. |
| 1220 | instmap["BINARY_OP_INPLACE_ADD_UNICODE"] = 3 |
| 1221 | |
| 1222 | instmap["INSTRUMENTED_LINE"] = 253 |
| 1223 | instmap["ENTER_EXECUTOR"] = 254 |
| 1224 | instmap["TRACE_RECORD"] = 255 |
| 1225 | |
| 1226 | instrumented = [name for name in instructions if name.startswith("INSTRUMENTED")] |
| 1227 | |
| 1228 | specialized: set[str] = set() |
| 1229 | no_arg: list[str] = [] |
| 1230 | has_arg: list[str] = [] |
| 1231 | |
| 1232 | for family in families.values(): |
| 1233 | specialized.update(inst.name for inst in family.members) |
| 1234 | |
| 1235 | for inst in instructions.values(): |
| 1236 | name = inst.name |
| 1237 | if name in specialized: |
| 1238 | continue |
| 1239 | if name in instrumented: |
| 1240 | continue |
| 1241 | if inst.properties.oparg: |
| 1242 | has_arg.append(name) |
| 1243 | else: |
| 1244 | no_arg.append(name) |
| 1245 | |
| 1246 | # Specialized ops appear in their own section |
| 1247 | # Instrumented opcodes are at the end of the valid range |
| 1248 | min_internal = instmap["RESUME"] + 1 |
| 1249 | min_instrumented = 254 - len(instrumented) |
| 1250 | assert min_internal + len(specialized) < min_instrumented |
| 1251 | |
| 1252 | next_opcode = 1 |
| 1253 | |
| 1254 | def add_instruction(name: str) -> None: |
| 1255 | nonlocal next_opcode |
| 1256 | if name in instmap: |
| 1257 | return # Pre-defined name |
no test coverage detected
searching dependent graphs…