def disassemble(code): i = 0 bc = code.co_code while i < len(bc): typ, sz = upyopcodes.mp_opcode_format(bc, i) if bc[i] in upyopcodes.hascache: sz += 1 print("% 15d " % i, end="") optarg = None opcode_str = opname[bc[i]] if typ == upyopcodes.MP_OPCODE_BYTE: # May have implict value encoded in the opcode implicit = op_implicit_arg[bc[i]] if implicit is not None: optarg = implicit elif typ == upyopcodes.MP_OPCODE_QSTR: optarg = bc[i + 1] + (bc[i + 2] << 8) optarg = "%d (%s)" % (optarg, code.co_names[optarg]) elif typ == upyopcodes.MP_OPCODE_VAR_UINT: next_i, optarg = upyopcodes.decode_uint(bc, i + 1) if opcode_str.startswith("CALL_FUNCTION"): optarg = "n=%d nkw=%d" % (optarg & 0xff, optarg >> 8) elif opcode_str in ("LOAD_CONST_OBJ", "MAKE_FUNCTION", "MAKE_CLOSURE"): optarg = "%d (%r)" % (optarg, code.co_consts[optarg]) if opcode_str == "MAKE_CLOSURE": optarg += " n_closed=%d " % bc[next_i] elif typ == upyopcodes.MP_OPCODE_OFFSET: optarg = bc[i + 1] + (bc[i + 2] << 8) - 0x8000 + (i + sz) else: assert 0 if optarg is not None: print("%-24s %s" % (opcode_str, optarg), end="") else: print("%-24s" % opcode_str, end="") if 0: print(" # t=%d sz=%d" % (typ, sz), end="") print() i += sz
def read_bytecode_qstrs(self, bytecode, ip): cnt = 0 qstrs = [] dprint("before:", bytecode) while ip < len(bytecode): typ, sz = upyopcodes.mp_opcode_format(bytecode, ip) if typ == 1: qstrs.append(self.read_qstr()) # Patch in CodeType-local qstr id, kinda similar to CPython bytecode[ip + 1] = cnt & 0xff bytecode[ip + 2] = cnt >> 8 cnt += 1 ip += sz dprint("after:", bytecode) return qstrs
def disassemble(code, real_qstrs=False, qstr_ids=True): i = 0 bc = code.co_code while i < len(bc): typ, sz = upyopcodes.mp_opcode_format(bc, i) # Handled by mp_opcode_format() above, but # config.MICROPY_OPT_CACHE_MAP_LOOKUP_IN_BYTECODE # must be set correctly! #if bc[i] in upyopcodes.hascache: # sz += 1 print("% 15d " % i, end="") optarg = None opcode_str = opname[bc[i]] if typ == upyopcodes.MP_OPCODE_BYTE: # May have implict value encoded in the opcode implicit = op_implicit_arg[bc[i]] if implicit is not None: optarg = implicit elif typ == upyopcodes.MP_OPCODE_QSTR: optarg = bc[i + 1] + (bc[i + 2] << 8) if real_qstrs: s = qstr_by_id(optarg) else: s = code.co_names[optarg] if qstr_ids: optarg = "%d (%s)" % (optarg, s) else: optarg = s elif typ == upyopcodes.MP_OPCODE_VAR_UINT: signed = False if opcode_str == "LOAD_CONST_SMALL_INT": signed = True next_i, optarg = upyopcodes.decode_varint(bc, i + 1, signed=signed) if opcode_str.startswith("CALL_FUNCTION"): optarg = "n=%d nkw=%d" % (optarg & 0xff, optarg >> 8) elif opcode_str in ("LOAD_CONST_OBJ", "MAKE_FUNCTION", "MAKE_FUNCTION_DEFARGS", "MAKE_CLOSURE"): optarg = "%d (%r)" % (optarg, code.co_consts[optarg]) if opcode_str == "MAKE_CLOSURE": optarg += " n_closed=%d " % bc[next_i] elif typ == upyopcodes.MP_OPCODE_OFFSET: optarg = bc[i + 1] + (bc[i + 2] << 8) - 0x8000 + (i + sz) else: assert 0 if optarg is not None: print("%-24s %s" % (opcode_str, optarg), end="") else: print("%-24s" % opcode_str, end="") if 0: print(" # t=%d sz=%d" % (typ, sz), end="") print() i += sz