You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
4.0 KiB
149 lines
4.0 KiB
"""
|
|
Translate bytecode instructions in frozen_mpy.c to human readable form.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
HERE = Path(__file__).parent
|
|
CORE_DIR = HERE.parent
|
|
|
|
FROZEN_MPY_FILE = CORE_DIR / "build/firmware/frozen_mpy.c"
|
|
NEW_FILE = str(FROZEN_MPY_FILE) + "_translated"
|
|
|
|
# Taken from core/vendor/micropython/py/bc0.h
|
|
OPCODES: dict[str, str] = {
|
|
"0x10": "LOAD QSTR const",
|
|
"0x11": "LOAD QSTR name",
|
|
"0x12": "LOAD QSTR global",
|
|
"0x13": "LOAD QSTR attribute",
|
|
"0x14": "LOAD QSTR method",
|
|
"0x15": "LOAD QSTR super method",
|
|
"0x16": "STORE QSTR name",
|
|
"0x17": "STORE QSTR global",
|
|
"0x18": "STORE QSTR attribute",
|
|
"0x19": "DELETE QSTR name",
|
|
"0x1a": "DELETE QSTR global",
|
|
"0x1b": "IMPORT QSTR name",
|
|
"0x1c": "IMPORT QSTR from",
|
|
"0x20": "MAKE closure",
|
|
"0x21": "MAKE closure defargs",
|
|
"0x22": "LOAD small int",
|
|
"0x23": "LOAD obj ptr",
|
|
"0x24": "LOAD fast N uint",
|
|
"0x25": "LOAD deref uint",
|
|
"0x26": "STORE fast N uint",
|
|
"0x27": "STORE deref uint",
|
|
"0x28": "DELETE fast N uint",
|
|
"0x29": "DELETE deref uint",
|
|
"0x2a": "BUILD tuple",
|
|
"0x2b": "BUILD list",
|
|
"0x2c": "BUILD map",
|
|
"0x2d": "BUILD set",
|
|
"0x2e": "BUILD slice",
|
|
"0x2f": "STORE comp",
|
|
"0x30": "UNPACK sequence",
|
|
"0x31": "UNPACK ex",
|
|
"0x32": "MAKE function",
|
|
"0x33": "MAKE function defargs",
|
|
"0x34": "CALL function",
|
|
"0x35": "CALL function var kw",
|
|
"0x36": "CALL method",
|
|
"0x37": "CALL method var kw",
|
|
"0x40": "JUMP unwind",
|
|
"0x42": "JUMP",
|
|
"0x43": "JUMP pop if true",
|
|
"0x44": "JUMP pop if false",
|
|
"0x45": "JUMP if true or pop",
|
|
"0x46": "JUMP if false or pop",
|
|
"0x47": "SETUP with",
|
|
"0x48": "SETUP except",
|
|
"0x49": "SETUP finally",
|
|
"0x4a": "POP block",
|
|
"0x50": "LOAD False",
|
|
"0x51": "LOAD None",
|
|
"0x52": "LOAD True",
|
|
"0x53": "LOAD null",
|
|
"0x54": "LOAD build class",
|
|
"0x55": "LOAD subscript",
|
|
"0x56": "STORE subscript",
|
|
"0x57": "DUP top",
|
|
"0x58": "DUP top two",
|
|
"0x59": "POP top",
|
|
"0x5a": "ROT two",
|
|
"0x5b": "ROT three",
|
|
"0x5c": "WITH cleanup",
|
|
"0x5d": "END finally",
|
|
"0x5e": "GET iter",
|
|
"0x5f": "GET iter stack",
|
|
"0x62": "STORE map",
|
|
"0x63": "RETURN value",
|
|
"0x64": "RAISE last",
|
|
"0x65": "RAISE obj",
|
|
"0x66": "RAISE from",
|
|
"0x67": "YIELD value",
|
|
"0x68": "YIELD from (AWAIT)",
|
|
"0x69": "IMPORT star",
|
|
"0xd7": "<",
|
|
"0xd8": ">",
|
|
"0xd9": "==",
|
|
"0xda": "<=",
|
|
"0xdb": ">=",
|
|
"0xdc": "!=",
|
|
"0xde": "is",
|
|
"0xef": "&",
|
|
"0xf0": "<<",
|
|
}
|
|
|
|
|
|
def main() -> None:
|
|
with open(FROZEN_MPY_FILE, "r") as f:
|
|
lines = f.readlines()
|
|
|
|
new_lines: list[str] = []
|
|
for line in lines:
|
|
first_byte = line.strip().split(",")[0]
|
|
|
|
# Check if it is a byte, otherwise skip
|
|
try:
|
|
num = int(first_byte, 16)
|
|
except ValueError:
|
|
new_lines.append(line)
|
|
continue
|
|
|
|
# Some OP codes have a value in themselves
|
|
if 0x70 <= num <= 0xAF:
|
|
# Small int
|
|
var = num - 0x10 - 0x70
|
|
val = f"INT {var}"
|
|
line = line.replace(first_byte, val, 1)
|
|
elif 0xB0 <= num <= 0xBF:
|
|
# Local variable loading
|
|
var = num - 0xB0
|
|
val = f"LOAD local {var}"
|
|
line = line.replace(first_byte, val, 1)
|
|
elif 0xC0 <= num <= 0xCF:
|
|
# Local variable storing
|
|
var = num - 0xC0
|
|
val = f"STORE local {var}"
|
|
line = line.replace(first_byte, val, 1)
|
|
else:
|
|
# Hardcoded OPcodes
|
|
if first_byte in OPCODES:
|
|
line = line.replace(first_byte, OPCODES[first_byte], 1)
|
|
else:
|
|
pass
|
|
# print(f"Unknown opcode: {first_byte}")
|
|
|
|
new_lines.append(line)
|
|
|
|
with open(NEW_FILE, "w") as f:
|
|
f.write("".join(new_lines))
|
|
|
|
print(f"Translated file saved as {NEW_FILE}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|