frompairipcore.contextimportVMfrompairipcore.decompiler.codeimportCodefrompairipcore.decompiler.handlerimportVMOp_Handlerfrompairipcore.insnimportInsnFormatfrompairipcore.opcodeimportVMOpcode_Interpret# -----------------------------------------------------------------------------# main function# -----------------------------------------------------------------------------
[docs]defdecompiler_main(vm:VM,decomp:"Decompiler",callback=None)->Code:""" Main function to decompile the VM bytecode, executing the appropriate handlers for each opcode. Args: vm (VM): The virtual machine instance. decomp (Decompiler): The decompiler instance with opcode handlers. callback (Optional[Callable[[VM, int], None]]): An optional callback function for handling unknown opcodes. Returns: Code: The generated code as a `Code` object. """# 1. setip state and PCvm.state.comment="//"# C-style outputifvm.context.pc<0:vm.context.pc=vm.entry_point()vm.state["code"]=Code(vm)whilenotvm.state.should_exit:# Fetchopcode=vm.current_opcode()vm.context+=2# DecodeHandler=decomp[opcode]# ExecuteifHandlerisnotNoneandopcodeindecomp.format_ids:handler_obj=Handler(vm,opcode,decomp.format_ids)handler_obj.run(vm)handler_obj.finish(vm)ifvm.state.verbose:handler_obj.debug(vm)else:ifcallbackisnotNone:callback(vm,opcode)else:vm.state["code"]+=(f"// Stopped at unknown opcode {opcode:#04x}")vm.state.should_exit=Truereturnvm.state["code"]
[docs]deffrom_opcode_def(opcode_def:dict[int|str,str|dict[str,str]],)->Decompiler:""" Create a `Decompiler` instance from opcode definitions. >>> dec = pairipcore.decompiler.from_opcode_def(...) >>> code = pairipcore.interpret(vm, dec) >>> for line in code: ... print(line) Args: opcode_def (Dict[Union[int, str], Union[str, dict]]): A dictionary where keys are opcodes and values are format IDs or dictionaries containing format IDs. Returns: Decompiler: The initialized `Decompiler` instance. """decomp=Decompiler()foropcode,valueinopcode_def.items():ifisinstance(opcode,str):opcode=int(opcode)ifisinstance(value,str):decomp.format_ids[opcode]=InsnFormat.parse(value)elifvalueandvalue["format_id"]:decomp.format_ids[opcode]=InsnFormat.parse(value["format_id"])returndecomp