def are_code_objects_equal(co1, co2): """ Determine if two code objects are approximately equal, see are_instructions_equal for more information. :param i1: left code object to compare :param i2: right code object to compare :return: True if the two code objects are approximately equal, otherwise False. """ instructions1 = Bytecode(co1) instructions2 = Bytecode(co2) for opcode1, opcode2 in zip(instructions1, instructions2): if not are_instructions_equal(opcode1, opcode2): return False return True
def build_instructions(self, co): """ Create a list of instructions (a structured object rather than an array of bytes) and store that in self.insts """ # FIXME: remove this when all subsidiary functions have been removed. # We should be able to get everything from the self.insts list. self.code = array("B", co.co_code) bytecode = Bytecode(co, self.opc) self.build_prev_op() self.insts = self.remove_extended_args(list(bytecode)) self.lines = self.build_lines_data(co) self.offset2inst_index = {} for i, inst in enumerate(self.insts): self.offset2inst_index[inst.offset] = i return bytecode
def number_loop(queue, mappings, opc): while len(queue) > 0: code1 = queue.popleft() code2 = queue.popleft() assert code1.co_name == code2.co_name linestarts_orig = findlinestarts(code1) linestarts_uncompiled = list(findlinestarts(code2)) mappings += [ [line, offset2line(offset, linestarts_uncompiled)] for offset, line in linestarts_orig ] bytecode1 = Bytecode(code1, opc) bytecode2 = Bytecode(code2, opc) instr2s = bytecode2.get_instructions(code2) seen = set([code1.co_name]) for instr in bytecode1.get_instructions(code1): next_code1 = None if iscode(instr.argval): next_code1 = instr.argval if next_code1: next_code2 = None while not next_code2: try: instr2 = next(instr2s) if iscode(instr2.argval): next_code2 = instr2.argval pass except StopIteration: break pass if next_code2: assert next_code1.co_name == next_code2.co_name if next_code1.co_name not in seen: seen.add(next_code1.co_name) queue.append(next_code1) queue.append(next_code2) pass pass pass pass
def _dis_to_text(co): return Bytecode(co).dis()
def dis( msg, msg_nocr, section, errmsg, x=None, start_line=-1, end_line=None, relative_pos=False, highlight="light", start_offset=0, end_offset=None, include_header=False, asm_format="extended", ): """Disassemble classes, methods, functions, or code. With no argument, disassemble the last traceback. """ lasti = -1 if x is None: distb() return None, None if start_offset is None: start_offset = 0 mess = "" if start_line > 1: mess += "from line %d " % start_line elif start_offset > 1: mess = "from offset %d " % start_offset if end_line: mess += "to line %d" % end_line elif end_offset: mess += "to offset %d" % end_offset sectioned = False # Try to dogpaddle to the code object for the type setting x if hasattr(types, "InstanceType") and isinstance(x, types.InstanceType): x = x.__class__ if inspect.ismethod(x): section("Disassembly of %s: %s" % (x, mess)) sectioned = True x = x.__func__.__code__ elif inspect.isfunction(x) or inspect.isgeneratorfunction(x): section("Disassembly of %s: %s" % (x, mess)) x = x.__code__ sectioned = True elif inspect.isgenerator(x): section("Disassembly of %s: %s" % (x, mess)) frame = x.gi_frame lasti = frame.f_last_i x = x.gi_code sectioned = True elif inspect.isframe(x): section("Disassembly of %s: %s" % (x, mess)) sectioned = True if hasattr(x, "f_lasti"): lasti = x.f_lasti if lasti == -1: lasti = 0 pass opc = get_opcode(PYTHON_VERSION_TRIPLE, IS_PYPY) x = x.f_code if include_header: header_lines = Bytecode(x, opc).info().split("\n") header = "\n".join([format_token(Comment, h) for h in header_lines]) msg(header) pass elif inspect.iscode(x): pass if hasattr(x, "__dict__"): # Class or module items = sorted(x.__dict__.items()) for name, x1 in items: if isinstance(x1, _have_code): if not sectioned: section("Disassembly of %s: " % x) try: dis( msg, msg_nocr, section, errmsg, x1, start_line=start_line, end_line=end_line, relative_pos=relative_pos, asm_format=asm_format, ) msg("") except TypeError: _, msg, _ = sys.exc_info() errmsg("Sorry:", msg) pass pass pass pass elif hasattr(x, "co_code"): # Code object if not sectioned: section("Disassembly of %s: " % x) return disassemble( msg, msg_nocr, section, x, lasti=lasti, start_line=start_line, end_line=end_line, relative_pos=relative_pos, highlight=highlight, start_offset=start_offset, end_offset=end_offset, asm_format=asm_format, ) elif isinstance(x, str): # Source code return disassemble_string( msg, msg_nocr, x, ) else: errmsg("Don't know how to disassemble %s objects." % type(x).__name__) return None, None