예제 #1
0
    def test_packing_lines(self):
        from bytecode.tests.long_lines_example import long_lines
        import dis

        line_starts = list(dis.findlinestarts(long_lines.__code__))

        concrete = ConcreteBytecode.from_code(long_lines.__code__)
        as_code = concrete.to_code()
        self.assertEqual(line_starts, list(dis.findlinestarts(as_code)))
예제 #2
0
def trace(aFrame, aEvent, aArg):
    theCode = aFrame.f_code
    if aEvent == 'call':
        print len(dis.findlinestarts(theCode))
        for theTuple in dis.findlinestarts(theCode):
            print theTuple
        print dis.dis(theCode)
        print len(theCode.co_code)
        raw_input()
    elif aEvent == 'line':
        pass
    elif aEvent == 'return':
        pass
    elif aEvent == 'exception':
        pass
예제 #3
0
파일: simpleTrace.py 프로젝트: awhawks/stiq
def trace(aFrame, aEvent, aArg):
    theCode = aFrame.f_code
    if aEvent == 'call':
        print len(dis.findlinestarts(theCode))
        for theTuple in dis.findlinestarts(theCode):
            print theTuple
        print dis.dis(theCode)
        print len(theCode.co_code)
        raw_input()
    elif aEvent == 'line':
        pass
    elif aEvent == 'return':
        pass
    elif aEvent == 'exception':
        pass
예제 #4
0
    def _get_instructions(co):
        code = co.co_code
        linestarts = dict(findlinestarts(co))
        n = len(code)
        i = 0
        extended_arg = 0
        while i < n:
            offset = i
            c = code[i]
            op = ord(c)
            lineno = linestarts.get(i)
            argval = None
            i = i + 1
            if op >= HAVE_ARGUMENT:
                oparg = ord(code[i]) + ord(code[i + 1]) * 256 + extended_arg
                extended_arg = 0
                i = i + 2
                if op == EXTENDED_ARG:
                    extended_arg = oparg * 65536

                if op in hasconst:
                    argval = co.co_consts[oparg]
                elif op in hasname:
                    argval = co.co_names[oparg]
                elif opname[op] == 'LOAD_FAST':
                    argval = co.co_varnames[oparg]
            yield Instruction(offset, argval, opname[op], lineno)
예제 #5
0
def serialize_frames(current_frame, current_tb):
    for frame, lno in iter_stack(current_frame, current_tb):
        code = frame.f_code
        filename = code.co_filename or "<unspecified>"
        if filename == "<frozen importlib._bootstrap>":
            filename = os.path.join(
                os.path.dirname(linecache.__file__),
                "importlib",
                "_bootstrap.py",
            )
        fn = Path(filename)
        if not filename.startswith("<"):
            fn = fn.resolve()

        line = None
        linecache.checkcache(filename)
        line = linecache.getline(filename, lno, frame.f_globals)
        line = line and line.strip()
        startlnos = dis.findlinestarts(code)
        lastlineno = list(startlnos)[-1][1]
        yield {
            "key": id(frame),
            "absoluteFilename": str(fn),
            "filename": fn.name,
            "function": code.co_name,
            "firstFunctionLineNumber": code.co_firstlineno,
            "lastFunctionLineNumber": lastlineno,
            "lineNumber": lno,
            "lineSource": line,
            "active": frame == current_frame,
        }
예제 #6
0
def get_offset_for_line(co, line):
    for (offset, l) in dis.findlinestarts(co):
        if l == line:
            return offset
        while l > line:
            break
    return -1
예제 #7
0
def warnAboutFunction(offender, warningString):
    """
    Issue a warning string, identifying C{offender} as the responsible code.

    This function is used to deprecate some behavior of a function.  It differs
    from L{warnings.warn} in that it is not limited to deprecating the behavior
    of a function currently on the call stack.

    @param function: The function that is being deprecated.

    @param warningString: The string that should be emitted by this warning.
    @type warningString: C{str}

    @since: 11.0
    """
    # inspect.getmodule() is attractive, but somewhat
    # broken in Python < 2.6.  See Python bug 4845.
    offenderModule = sys.modules[offender.__module__]
    filename = inspect.getabsfile(offenderModule)
    lineStarts = list(findlinestarts(offender.func_code))
    lastLineNo = lineStarts[-1][1]
    globals = offender.func_globals

    kwargs = dict(
        category=DeprecationWarning,
        filename=filename,
        lineno=lastLineNo,
        module=offenderModule.__name__,
        registry=globals.setdefault("__warningregistry__", {}),
        module_globals=None)

    if sys.version_info[:2] < (2, 5):
        kwargs.pop('module_globals')

    warn_explicit(warningString, **kwargs)
예제 #8
0
 def __init__(self, py_code):
     import dis
     self.function_name = py_code.co_name
     self.filename = py_code.co_filename
     sorted_offset_lineno = list(dis.findlinestarts(py_code))
     self._sorted_offsets = [ol[0] for ol in sorted_offset_lineno]
     self._sorted_lines = [ol[1] for ol in sorted_offset_lineno]
예제 #9
0
    def build_line_to_contents(self):
        co = self.co
        firstlineno = self.firstlineno

        # print('----')
        # for instruction in self.instructions:
        #     print(instruction)
        # print('----\n\n')

        op_offset_to_line = dict(dis.findlinestarts(co))
        curr_line_index = 0

        line_to_contents = {}

        instructions = self.instructions
        while instructions:
            instruction = instructions[0]
            new_line_index = op_offset_to_line.get(instruction.offset)
            if new_line_index is not None:
                if new_line_index is not None:
                    curr_line_index = new_line_index - firstlineno

            lst = line_to_contents.setdefault(curr_line_index, [])
            lst.append(self._next_instruction_to_str(line_to_contents))
        return line_to_contents
예제 #10
0
def warnAboutFunction(offender, warningString):
    """
    Issue a warning string, identifying C{offender} as the responsible code.

    This function is used to deprecate some behavior of a function.  It differs
    from L{warnings.warn} in that it is not limited to deprecating the behavior
    of a function currently on the call stack.

    @param function: The function that is being deprecated.

    @param warningString: The string that should be emitted by this warning.
    @type warningString: C{str}

    @since: 11.0
    """
    # inspect.getmodule() is attractive, but somewhat
    # broken in Python < 2.6.  See Python bug 4845.
    offenderModule = sys.modules[offender.__module__]
    filename = inspect.getabsfile(offenderModule)
    lineStarts = list(findlinestarts(offender.func_code))
    lastLineNo = lineStarts[-1][1]
    globals = offender.func_globals

    kwargs = dict(
        category=DeprecationWarning,
        filename=filename,
        lineno=lastLineNo,
        module=offenderModule.__name__,
        registry=globals.setdefault("__warningregistry__", {}),
        module_globals=None)

    if sys.version_info[:2] < (2, 5):
        kwargs.pop('module_globals')

    warn_explicit(warningString, **kwargs)
def find_lines_from_code(code, strs):
    linenos = {}
    for _, lineno in dis.findlinestarts(code):
        if lineno not in strs:
            linenos[lineno] = 1

    return linenos
예제 #12
0
def lasti2lineno(code, lasti):
    linestarts = list(dis.findlinestarts(code))
    linestarts.reverse()
    for i, lineno in linestarts:
        if lasti >= i:
            return lineno
    return 0
예제 #13
0
def lasti2lineno(code, lasti):
    linestarts = list(dis.findlinestarts(code))
    linestarts.reverse()
    for (i, lineno) in linestarts:
        while lasti >= i:
            return lineno
    return 0
예제 #14
0
def disassemble(code: str, scope: Scope = None, arg_dict: dict = None):
    """
    Disassembles asynchronous code into dis.dis-style bytecode instructions.
    """

    # Similar to AsyncCodeExecutor.__init__
    arg_names = list(arg_dict.keys()) if arg_dict else []

    scope = scope or Scope()

    wrapped = wrap_code(code, args=', '.join(arg_names))
    exec(compile(wrapped, '<repl>', 'exec'), scope.globals, scope.locals)

    func_def = scope.locals.get(
        '_repl_coroutine') or scope.globals['_repl_coroutine']

    co = func_def.__code__

    for instruction in dis._get_instructions_bytes(
            co.co_code,
            co.co_varnames,
            co.co_names,
            co.co_consts,
            co.co_cellvars + co.co_freevars,
            dict(dis.findlinestarts(co)),
            line_offset=0):
        if instruction.starts_line is not None and instruction.offset > 0:
            yield ''

        yield instruction._disassemble(4, False, 4)
예제 #15
0
파일: __init__.py 프로젝트: arthru/wdb
    def get_trace(self, frame, tb, w_code=None):
        frames = []
        stack, current = self.get_stack(frame, tb)

        for i, (frame, lno) in enumerate(stack):
            code = frame.f_code
            filename = code.co_filename
            if filename == "<wdb>" and w_code:
                line = w_code
            else:
                checkcache(filename)
                line = getline(filename, lno, frame.f_globals)
                line = line and line.strip()

            startlnos = dis.findlinestarts(code)
            lastlineno = list(startlnos)[-1][1]
            frames.append(
                {
                    "file": filename,
                    "function": code.co_name,
                    "flno": code.co_firstlineno,
                    "llno": lastlineno,
                    "lno": lno,
                    "code": escape(line),
                    "level": i,
                }
            )

        return stack, frames, current
예제 #16
0
def disassemble(msg,
                msg_nocr,
                section,
                co,
                lasti=-1,
                start_line=-1,
                end_line=None,
                relative_pos=False,
                highlight='light',
                start_offset=0,
                end_offset=None):
    """Disassemble a code object."""
    disassemble_bytes(msg,
                      msg_nocr,
                      co.co_code,
                      lasti,
                      co.co_firstlineno,
                      start_line,
                      end_line,
                      relative_pos,
                      co.co_varnames,
                      co.co_names,
                      co.co_consts,
                      co.co_cellvars,
                      co.co_freevars,
                      dict(findlinestarts(co)),
                      highlight,
                      start_offset=start_offset,
                      end_offset=end_offset)
    return
예제 #17
0
def get_offset_for_line(co, line):
    for (offset, l) in dis.findlinestarts(co):
        if l == line:
            return offset
        while l > line:
            break
    return -1
예제 #18
0
    def read_code(self):
        extended_arg = 0
        code = self.co_code
        n = len(code)
        i = 0
        label = 0
        lbuffer = []
        line = 0
        linestarts = dict(dis.findlinestarts(self))

        while i < n:
            if i in linestarts:
                line = linestarts[i]

            op = ord(code[i])
            i += 1
            oparg = None
            if op >= HAVE_ARGUMENT:
                oparg = ord(code[i]) + ord(code[i + 1]) * 256 + extended_arg
                extended_arg = 0
                i += 2
                if op == EXTENDED_ARG:
                    extended_arg = oparg * 65536

            if op != EXTENDED_ARG:
                yield (label, op, oparg, line)

            else:
                # Yield a NOP just in case there's a jump to this label
                yield (label, NOP, None, line)

            label += 1
            if op >= HAVE_ARGUMENT:
                label += 2
예제 #19
0
 def run(self, args):
     """Program counter."""
     mainfile = self.core.filename(None)
     if self.core.is_running():
         curframe = self.proc.curframe
         if curframe:
             line_no = inspect.getlineno(curframe)
             offset  = curframe.f_lasti
             self.msg("PC offset is %d." % offset)
             offset = max(offset, 0)
             code = curframe.f_code
             co_code = code.co_code
             disassemble_bytes(self.msg, self.msg_nocr,
                               co_code, offset, line_no, line_no-1, line_no+1,
                               constants=code.co_consts, cells=code.co_cellvars,
                               varnames=code.co_varnames, freevars=code.co_freevars,
                               linestarts=dict(findlinestarts(code)),
                               end_offset=offset+10)
             pass
         pass
     else:
         if mainfile:
             part1 = "Python program '%s'" % mainfile
             msg   = "is not currently running. "
             self.msg(Mmisc.wrapped_lines(part1, msg,
                                          self.settings['width']))
         else:
             self.msg('No Python program is currently running.')
             pass
         self.msg(self.core.execution_status)
         pass
     return False
예제 #20
0
파일: __init__.py 프로젝트: seletz/wdb
    def get_trace(self, frame, tb, w_code=None):
        """Get a dict of the traceback for wdb.js use"""
        frames = []
        stack, current = self.get_stack(frame, tb)

        for i, (frame, lno) in enumerate(stack):
            code = frame.f_code
            filename = code.co_filename
            if filename == '<wdb>' and w_code:
                line = w_code
            else:
                checkcache(filename)
                line = getline(filename, lno, frame.f_globals)
                line = line and line.strip()

            startlnos = dis.findlinestarts(code)
            lastlineno = list(startlnos)[-1][1]
            frames.append({
                'file': filename,
                'function': code.co_name,
                'flno': code.co_firstlineno,
                'llno': lastlineno,
                'lno': lno,
                'code': line,
                'level': i
            })

        return stack, frames, current
예제 #21
0
파일: utils.py 프로젝트: PrVrSs/mephisto
def byte_parser(text: str):
    """Find the offsets in a byte code which are start of lines in the source."""
    return [
        lineno
        for code in code_objects(compile(text, '<str>', 'exec'))
        for _, lineno in findlinestarts(code)
    ]
예제 #22
0
파일: uatu.py 프로젝트: yury-primer/pode
    def cut_asm(self, line, code):
        if line == -1:
            # ignore
            return code

        first = 0
        last = codesize = len(code.co_code)
        lines = list(dis.findlinestarts(code))
        for pos, (asm_line, src_line) in enumerate(lines):
            if line != asm_line:
                continue
            else:
                if asm_line == lines[-1][0]:
                    first, last = (asm_line, codesize)
                else:
                    first, last = (asm_line, lines[pos + 1][0])
                break

        codestr = code.co_code[first:last]

        # Rebuild code object
        new_code = type(code)(code.co_argcount, code.co_nlocals,
                              code.co_stacksize, code.co_flags, codestr,
                              code.co_consts, code.co_names, code.co_varnames,
                              code.co_filename, code.co_name,
                              code.co_firstlineno, code.co_lnotab,
                              code.co_freevars, code.co_cellvars)

        if self.metadebug:
            dis.disassemble(new_code)

        return new_code
예제 #23
0
파일: __init__.py 프로젝트: niziou/wdb
    def get_trace(self, frame, tb):
        """Get a dict of the traceback for wdb.js use"""
        import linecache
        frames = []
        stack, _ = self.get_stack(frame, tb)
        current = 0

        for i, (stack_frame, lno) in enumerate(stack):
            code = stack_frame.f_code
            filename = code.co_filename
            linecache.checkcache(filename)
            line = linecache.getline(filename, lno, stack_frame.f_globals)
            if not line:
                line = self.compile_cache.get(id(code), '')
            line = to_unicode_string(line, filename)
            line = line and line.strip()
            startlnos = dis.findlinestarts(code)
            lastlineno = list(startlnos)[-1][1]
            if frame == stack_frame:
                current = i
            frames.append({
                'file': filename,
                'function': code.co_name,
                'flno': code.co_firstlineno,
                'llno': lastlineno,
                'lno': lno,
                'code': line,
                'level': i,
                'current': frame == stack_frame
            })

        # While in exception always put the context to the top
        return stack, frames, current
예제 #24
0
def warnAboutFunction(offender, warningString):
    """
    Issue a warning string, identifying C{offender} as the responsible code.

    This function is used to deprecate some behavior of a function.  It differs
    from L{warnings.warn} in that it is not limited to deprecating the behavior
    of a function currently on the call stack.

    @param offender: The function that is being deprecated.

    @param warningString: The string that should be emitted by this warning.
    @type warningString: C{str}

    @since: 11.0
    """
    # inspect.getmodule() is attractive, but somewhat
    # broken in Python < 2.6.  See Python bug 4845.
    offenderModule = sys.modules[offender.__module__]
    warn_explicit(
        warningString,
        category=DeprecationWarning,
        filename=inspect.getabsfile(offenderModule),
        lineno=max(lineNumber
                   for _, lineNumber in findlinestarts(offender.__code__)),
        module=offenderModule.__name__,
        registry=offender.__globals__.setdefault("__warningregistry__", {}),
        module_globals=None,
    )
예제 #25
0
 def build_lines_data(self, code_obj):
     """
     Generate various line-related helper data.
     """
     # Offset: lineno pairs, only for offsets which start line.
     # Locally we use list for more convenient iteration using indices
     linestarts = list(dis.findlinestarts(code_obj))
     self.linestarts = dict(linestarts)
     # Plain set with offsets of first ops on line
     self.linestart_offsets = set(a for (a, _) in linestarts)
     # 'List-map' which shows line number of current op and offset of
     # first op on following line, given offset of op as index
     self.lines = lines = []
     LineTuple = namedtuple('LineTuple', ['l_no', 'next'])
     # Iterate through available linestarts, and fill
     # the data for all code offsets encountered until
     # last linestart offset
     _, prev_line_no = linestarts[0]
     offset = 0
     for start_offset, line_no in linestarts[1:]:
         while offset < start_offset:
             lines.append(LineTuple(prev_line_no, start_offset))
             offset += 1
         prev_line_no = line_no
     # Fill remaining offsets with reference to last line number
     # and code length as start offset of following non-existing line
     codelen = len(self.code)
     while offset < codelen:
         lines.append(LineTuple(prev_line_no, codelen))
         offset += 1
예제 #26
0
    def from_code(code, *, extended_arg=False):
        line_starts = dict(dis.findlinestarts(code))

        # find block starts
        instructions = []
        offset = 0
        lineno = code.co_firstlineno
        while offset < len(code.co_code):
            if offset in line_starts:
                lineno = line_starts[offset]

            instr = ConcreteInstr.disassemble(lineno, code.co_code, offset)

            instructions.append(instr)
            offset += instr.size

        # replace jump targets with blocks
        if not extended_arg:
            extended_arg = None
            index = 0
            while index < len(instructions):
                instr = instructions[index]

                if instr.name == 'EXTENDED_ARG' and not extended_arg:
                    if extended_arg is not None:
                        raise ValueError("EXTENDED_ARG followed "
                                         "by EXTENDED_ARG")
                    extended_arg = instr.arg
                    del instructions[index]
                    continue

                if extended_arg is not None:
                    arg = (extended_arg << 16) + instr.arg
                    extended_arg = None

                    instr = ConcreteInstr(instr.name, arg, lineno=instr.lineno)
                    instructions[index] = instr

                index += 1

            if extended_arg is not None:
                raise ValueError("EXTENDED_ARG at the end of the code")

        bytecode = ConcreteBytecode()
        bytecode.name = code.co_name
        bytecode.filename = code.co_filename
        bytecode.flags = code.co_flags
        bytecode.argcount = code.co_argcount
        bytecode.kwonlyargcount = code.co_kwonlyargcount
        bytecode._stacksize = code.co_stacksize
        bytecode.first_lineno = code.co_firstlineno
        bytecode.names = list(code.co_names)
        bytecode.consts = list(code.co_consts)
        bytecode.varnames = list(code.co_varnames)
        bytecode.freevars = list(code.co_freevars)
        bytecode.cellvars = list(code.co_cellvars)
        _set_docstring(bytecode, code.co_consts)

        bytecode[:] = instructions
        return bytecode
예제 #27
0
파일: __init__.py 프로젝트: chiehwen/wdb
    def get_trace(self, frame, tb, w_code=None):
        frames = []
        stack, current = self.get_stack(frame, tb)

        for i, (frame, lno) in enumerate(stack):
            code = frame.f_code
            filename = code.co_filename
            if filename == '<wdb>' and w_code:
                line = w_code
            else:
                checkcache(filename)
                line = getline(filename, lno, frame.f_globals)
                line = line and line.strip()

            startlnos = dis.findlinestarts(code)
            lastlineno = list(startlnos)[-1][1]
            frames.append({
                'file': filename,
                'function': code.co_name,
                'flno': code.co_firstlineno,
                'llno': lastlineno,
                'lno': lno,
                'code': escape(line),
                'level': i
            })

        return stack, frames, current
예제 #28
0
def disassemble(code: str, scope: Scope = None, arg_dict: dict = None):
    """
    Disassembles asynchronous code into dis.dis-style bytecode instructions.
    """

    # Similar to AsyncCodeExecutor.__init__
    arg_names = list(arg_dict.keys()) if arg_dict else []

    scope = scope or Scope()

    wrapped = wrap_code(code, args=", ".join(arg_names))
    exec(
        compile(wrapped, "<repl>", "exec"), scope.globals, scope.locals
    )  # pylint: disable=exec-used

    func_def = scope.locals.get("_repl_coroutine") or scope.globals["_repl_coroutine"]

    # pylint is gonna really hate this part onwards
    # pylint: disable=protected-access, invalid-name
    co = func_def.__code__

    for instruction in dis._get_instructions_bytes(
        co.co_code,
        co.co_varnames,
        co.co_names,
        co.co_consts,
        co.co_cellvars + co.co_freevars,
        dict(dis.findlinestarts(co)),
        line_offset=0,
    ):
        if instruction.starts_line is not None and instruction.offset > 0:
            yield ""

        yield instruction._disassemble(4, False, 4)
예제 #29
0
def demo3():
	def func():
		bug = True
		i = 0
		while i < 3:
			print "a:", i
			i += 1
		i = 0
		while i < 3:
			print "b:", i
			if bug: raise Exception
			i += 1

	try:
		func()
		assert False
	except Exception:
		print "! Exception"
		_,_,tb = sys.exc_info()

	tb = find_traceframe(tb, func.func_code)
	assert tb is not None

	# Start just at where the exception was raised.
	instraddr = max([addr for (addr,_) in dis.findlinestarts(func.func_code) if addr <= tb.tb_lasti])
	# Play around. Avoid that we throw the exception again.
	localdict = dict(tb.tb_frame.f_locals)
	localdict["bug"] = False
	new_func = restart_func(func, instraddr=instraddr, localdict=localdict)

	new_func()
예제 #30
0
    def jsonify_code(code):
        def helper(obj):
            if type(obj) == code_type:
                return jsonify_code(obj)
            else:
                return {
                    "type": "literal",
                    "real_type": str(type(obj)),
                    "value": obj
                }

        # to deeply understand this object
        # https://late.am/post/2012/03/26/exploring-python-code-objects.html
        return { # TODO: consider converting to some binary format instead of JSON
            "type": "code",
            "co_code": base64.encodebytes(code.co_code).decode('ascii').replace("\n", ""), # our C++ base64 decoder does not take kindly to new lines.
            "co_lnotab": base64.encodebytes(code.co_lnotab).decode('ascii').replace("\n", ""), # the line number table
            "co_consts": list(map(helper, code.co_consts)),
            "co_name": code.co_name,
            "co_filename": code.co_filename,
            "co_argcount": code.co_argcount,
            "co_kwonlyargcount": code.co_kwonlyargcount,
            "co_nlocals": code.co_nlocals,
            "co_stacksize": code.co_stacksize,
            "co_names": code.co_names or None,
            "co_varnames": code.co_varnames or None,
            "co_freevars": code.co_freevars or None,
            "co_cellvars": code.co_cellvars or None,
            "lnotab": list([tuple[1], tuple[0]] for tuple in dis.findlinestarts(code)),
        }
예제 #31
0
 def __init__( self, py_code ):
     import dis
     self.function_name = py_code.co_name
     self.filename = py_code.co_filename
     sorted_offset_lineno = list( dis.findlinestarts( py_code ) )
     self._sorted_offsets = [ ol[0] for ol in sorted_offset_lineno ]
     self._sorted_lines = [ ol[1] for ol in sorted_offset_lineno ]
예제 #32
0
파일: __init__.py 프로젝트: s0undt3ch/wdb
    def get_trace(self, frame, tb):
        """Get a dict of the traceback for wdb.js use"""
        import linecache
        frames = []
        stack, _ = self.get_stack(frame, tb)
        current = 0

        for i, (stack_frame, lno) in enumerate(stack):
            code = stack_frame.f_code
            filename = code.co_filename
            linecache.checkcache(filename)
            line = linecache.getline(filename, lno, stack_frame.f_globals)
            if not line:
                line = self.compile_cache.get(id(code), '')
            line = to_unicode_string(line, filename)
            line = line and line.strip()
            startlnos = dis.findlinestarts(code)
            lastlineno = list(startlnos)[-1][1]
            if frame == stack_frame:
                current = i
            frames.append({
                'file': filename,
                'function': code.co_name,
                'flno': code.co_firstlineno,
                'llno': lastlineno,
                'lno': lno,
                'code': line,
                'level': i,
                'current': frame == stack_frame
            })

        # While in exception always put the context to the top
        return stack, frames, current
예제 #33
0
def disassemble(co, lasti=-1):
    """Disassemble a code object."""
    # Taken from dis.disassemble, returns disassembled code instead of printing
    # it (the f**k python ?).
    # Also, unicodified.
    # Also, use % operator instead of string operations.
    # Also, one statement per line.
    out = StringIO()
    code = co.co_code
    labels = dis.findlabels(code)
    linestarts = dict(dis.findlinestarts(co))
    n = len(code)
    i = 0
    extended_arg = 0
    free = None
    while i < n:
        c = code[i]
        op = ord(c)
        if i in linestarts:
            if i > 0:
                print(end=u'\n', file=out)
            print(u'%3d' % linestarts[i], end=u' ', file=out)
        else:
            print(u'   ', end=u' ', file=out)

        if i == lasti:
            print(u'-->', end=u' ', file=out)
        else:
            print(u'   ', end=u' ', file=out)
        if i in labels:
            print(u'>>', end=u' ', file=out)
        else:
            print(u'  ', end=u' ', file=out)
        print(u'%4i' % i, end=u' ', file=out)
        print(u'%-20s' % dis.opname[op], end=u' ', file=out)
        i = i + 1
        if op >= dis.HAVE_ARGUMENT:
            oparg = ord(code[i]) + ord(code[i + 1]) * 256 + extended_arg
            extended_arg = 0
            i = i + 2
            if op == dis.EXTENDED_ARG:
                extended_arg = oparg * 65536
            print(u'%5i' % oparg, end=u' ', file=out)
            if op in dis.hasconst:
                print(u'(%r)' % co.co_consts[oparg], end=u' ', file=out)
            elif op in dis.hasname:
                print(u'(%s)' % co.co_names[oparg], end=u' ', file=out)
            elif op in dis.hasjrel:
                print(u'(to %r)' % (i + oparg), end=u' ', file=out)
            elif op in dis.haslocal:
                print(u'(%s)' % co.co_varnames[oparg], end=u' ', file=out)
            elif op in dis.hascompare:
                print(u'(%s)' % dis.cmp_op[oparg], end=u' ', file=out)
            elif op in dis.hasfree:
                if free is None:
                    free = co.co_cellvars + co.co_freevars
                print(u'(%s)' % free[oparg], end=u' ', file=out)
        print(end=u'\n', file=out)
    return out.getvalue()
예제 #34
0
def insert_code(code_to_modify, code_to_insert, before_line):
    """
    Insert piece of code `code_to_insert` to `code_to_modify` right inside the line `before_line` before the
    instruction on this line by modifying original bytecode

    :param code_to_modify: Code to modify
    :param code_to_insert: Code to insert
    :param before_line: Number of line for code insertion
    :return: boolean flag whether insertion was successful, modified code
    """
    linestarts = dict(dis.findlinestarts(code_to_modify))
    if before_line not in linestarts.values():
        return False, code_to_modify

    offset = None
    for off, line_no in linestarts.items():
        if line_no == before_line:
            offset = off
            break

    code_to_insert_list = add_jump_instruction(offset, code_to_insert)
    try:
        code_to_insert_list, new_names = \
            _add_attr_values_from_insert_to_original(code_to_modify, code_to_insert, code_to_insert_list, 'co_names',
                                                     dis.hasname)
        code_to_insert_list, new_consts = \
            _add_attr_values_from_insert_to_original(code_to_modify, code_to_insert, code_to_insert_list, 'co_consts',
                                                     [opmap['LOAD_CONST']])
        code_to_insert_list, new_vars = \
            _add_attr_values_from_insert_to_original(code_to_modify, code_to_insert, code_to_insert_list, 'co_varnames',
                                                     dis.haslocal)
        new_bytes, all_inserted_code = _update_label_offsets(code_to_modify.co_code, offset, list(code_to_insert_list))

        new_lnotab = _modify_new_lines(code_to_modify, offset, code_to_insert_list)
        if new_lnotab is None:
            return False, code_to_modify

    except ValueError:
        traceback.print_exc()
        return False, code_to_modify

    new_code = CodeType(
        code_to_modify.co_argcount,  # integer
        code_to_modify.co_kwonlyargcount,  # integer
        len(new_vars),  # integer
        code_to_modify.co_stacksize,  # integer
        code_to_modify.co_flags,  # integer
        new_bytes,  # bytes
        new_consts,  # tuple
        new_names,  # tuple
        new_vars,  # tuple
        code_to_modify.co_filename,  # string
        code_to_modify.co_name,  # string
        code_to_modify.co_firstlineno,  # integer
        new_lnotab,  # bytes
        code_to_modify.co_freevars,  # tuple
        code_to_modify.co_cellvars  # tuple
    )
    return True, new_code
예제 #35
0
def lineForInstruction(code, instruction):
	line = 1

	for i, l in dis.findlinestarts(code):
		if i > instruction: break
		line = l

	return line
예제 #36
0
파일: pdb.py 프로젝트: holycrepe/pdbpp
def lasti2lineno(code, lasti):
    import dis
    linestarts = list(dis.findlinestarts(code))
    linestarts.reverse()
    for i, lineno in linestarts:
        if lasti >= i:
            return lineno
    return 0
예제 #37
0
def lineForInstruction(code, instruction):
    line = 1

    for i, l in dis.findlinestarts(code):
        if i > instruction: break
        line = l

    return line
예제 #38
0
 def _find_lineno(self, op):
     linestarts = list(dis.findlinestarts(op.pycode))
     i = bisect.bisect(linestarts, (op.bytecode_no, )) - 1
     if i < 0:
         return -1
     else:
         _, lineno = linestarts[i]
         return lineno
예제 #39
0
def lasti2lineno(code, lasti):
    import dis
    linestarts = list(dis.findlinestarts(code))
    linestarts.reverse()
    for i, lineno in linestarts:
        if lasti >= i:
            return lineno
    assert False, 'Invalid instruction number: %s' % lasti
예제 #40
0
def find_lines_from_code(code, strs):
    """Return dict where keys are lines in the line number table."""
    linenos = {}
    for _, lineno in dis.findlinestarts(code):
        if lineno not in strs:
            linenos[lineno] = 1

    return linenos
예제 #41
0
def find_lines_from_code(code, strs):
    """Return dict where keys are lines in the line number table."""
    linenos = {}
    for _, lineno in dis.findlinestarts(code):
        if lineno not in strs:
            linenos[lineno] = 1

    return linenos
예제 #42
0
def disassemble(msg, msg_nocr, section, co, lasti=-1, start_line=-1, end_line=None,
                relative_pos=False, color='light'):
    """Disassemble a code object."""
    disassemble_bytes(msg, msg_nocr, co.co_code, lasti, co.co_firstlineno,
                      start_line, end_line, relative_pos,
                      co.co_varnames, co.co_names, co.co_consts,
                      co.co_cellvars, co.co_freevars,
                      dict(findlinestarts(co)), color)
    return
예제 #43
0
def disassemble(obj, co, lasti=-1, start_line=-1, end_line=None,
                relative_pos=False):
    """Disassemble a code object."""
    disassemble_string(obj, co.co_code, lasti, co.co_firstlineno,
                       start_line, end_line, relative_pos,
                       co.co_varnames, co.co_names, co.co_consts,
                       co.co_cellvars, co.co_freevars,
                       dict(findlinestarts(co)))
    return
예제 #44
0
 def check_lnotab(self, code):
     "Check that the lnotab byte offsets are sensible."
     code = dis._get_code_object(code)
     lnotab = list(dis.findlinestarts(code))
     # Don't bother checking if the line info is sensible, because
     # most of the line info we can get at comes from lnotab.
     min_bytecode = min(t[0] for t in lnotab)
     max_bytecode = max(t[0] for t in lnotab)
     self.assertGreaterEqual(min_bytecode, 0)
     self.assertLess(max_bytecode, len(code.co_code))
예제 #45
0
def disassemble(msg, msg_nocr, section, co, lasti=-1, start_line=-1,
                end_line=None, relative_pos=False, highlight='light',
                start_offset=0, end_offset=None):
    """Disassemble a code object."""
    return disassemble_bytes(msg, msg_nocr, co.co_code, lasti, co.co_firstlineno,
                             start_line, end_line, relative_pos,
                        co.co_varnames, co.co_names, co.co_consts,
                        co.co_cellvars, co.co_freevars,
                        dict(findlinestarts(co)), highlight,
                        start_offset=start_offset, end_offset=end_offset)
예제 #46
0
파일: dis.py 프로젝트: CrystalMei/ProvBuild
def _instructions(code, lasti=-1):
    """Generator for code instructions"""
    cell_names = code.co_cellvars + code.co_freevars
    linestarts = OrderedDict(_dis.findlinestarts(code))
    insts = _byte_instructions(
        code.co_code, lasti, code.co_varnames, code.co_names,
        code.co_consts, cell_names, linestarts)

    for inst in insts:
        yield inst
예제 #47
0
def _instructions(code, lasti=-1):
    """Generator for code instructions"""
    cell_names = code.co_cellvars + code.co_freevars
    linestarts = OrderedDict(_dis.findlinestarts(code))
    insts = _byte_instructions(
        code.co_code, lasti, code.co_varnames, code.co_names,
        code.co_consts, cell_names, linestarts)

    for inst in insts:
        yield inst
예제 #48
0
 def get_offset_for_line(co, line):
     """
     Return the offset associated with the given line in a code object.
     Return -1 if there is no byte code associated with this line.
     """
     for offset, l in dis.findlinestarts(co):
         if l == line:
             return offset
         elif l > line:
             break
     return -1
예제 #49
0
파일: bytecode.py 프로젝트: filmackay/flypy
 def _mark_lineno(self):
     '''Fill the lineno info for all bytecode inst
     '''
     for offset, lineno in dis.findlinestarts(self.code):
         if offset in self.table:
             self.table[offset].lineno = lineno
     known = -1
     for inst in self:
         if inst.lineno >= 0:
             known = inst.lineno
         else:
             inst.lineno = known
예제 #50
0
def disassemble(co):
    """Disassemble a code object."""
    lines = []
    code = co.co_code
    labels = dis.findlabels(code)
    linestarts = dict(dis.findlinestarts(co))
    n = len(code)
    i = 0
    extended_arg = 0
    free = None
    while i < n:
        c = code[i]
        op = ord(c)
        data = {"raw_op": op}
        if i in linestarts:
            data["line_no"] = linestarts[i]
        else:
            data["line_no"] = None

        if i in labels:
            data["in_labels"] = True
        else:
            data["in_labels"] = False

        data["i"] = i
        data["opname"] = opname[op]
        data["hex"] = "%02X" % op
        i = i + 1
        if op >= HAVE_ARGUMENT:
            oparg = ord(code[i]) + ord(code[i + 1]) * 256 + extended_arg
            extended_arg = 0
            data["hex"] += " %02X %02X" % (ord(code[i]), ord(code[i + 1]))
            i = i + 2
            if op == EXTENDED_ARG:
                extended_arg = oparg * 65536L
            data["raw_arg"] = oparg
            if op in hasconst:
                data['arg'] = {"value": repr(co.co_consts[oparg]), "type": "const"}
            elif op in hasname:
                data['arg'] =  {"value": co.co_names[oparg], "type": "name"}
            elif op in hasjrel:
                data['arg'] =  {"value": repr(i + oparg), "type": "jump_relative"}
            elif op in haslocal:
                data['arg'] =  {"value": co.co_varnames[oparg], "type": "local_name"}
            elif op in hascompare:
                data['arg'] =  {"value": cmp_op[oparg], "type": "compare"}
            elif op in hasfree:
                if free is None:
                    free = co.co_cellvars + co.co_freevars
                data['arg'] =  {"value": cmp_op[oparg], "type": "free_variable"}

        lines.append(data)
    return json.dumps(lines)
예제 #51
0
파일: bytecode.py 프로젝트: ASPP/numba
 def _mark_lineno(cls, table, code):
     '''Fill the lineno info for all bytecode inst
     '''
     for offset, lineno in dis.findlinestarts(code):
         if offset in table:
             table[offset].lineno = lineno
     known = -1
     for inst in table.values():
         if inst.lineno >= 0:
             known = inst.lineno
         else:
             inst.lineno = known
예제 #52
0
 def __init__(self, x, first_line=None, current_offset=None):
     self.codeobj = co = _get_code_object(x)
     if first_line is None:
         self.first_line = co.co_firstlineno
         self._line_offset = 0
     else:
         self.first_line = first_line
         self._line_offset = first_line - co.co_firstlineno
     self._cell_names = co.co_cellvars + co.co_freevars
     self._linestarts = dict(findlinestarts(co))
     self._original_object = x
     self.current_offset = current_offset
예제 #53
0
파일: bytely.py 프로젝트: mahmoud/ipynb-ftw
def dissco(co):
    try:
        code = co.co_code
    except AttributeError:
        raise TypeError("disassembly only works on objects with code components.")

    ret = []
    labels = findlabels(code)
    linestarts = dict(findlinestarts(co))
    print labels, linestarts

    n = len(code)
    i = 0
    cur_line = 0
    oparg = None
    arg = None
    extended_arg = 0
    free = None
    while i < n:
        c = code[i]
        op = ord(c)
        if i in linestarts:
            cur_line = linestarts[i]
        op_name = opname[op]

        i += 1
        if op >= HAVE_ARGUMENT:
            oparg = ord(code[i]) + ord(code[i + 1]) * 256 + extended_arg
            extended_arg = 0
            i += 2
            if op == EXTENDED_ARG:
                extended_arg = oparg * 65536L

            if op in hasconst:
                arg = co.co_consts[oparg]
            elif op in hasname:
                arg = co.co_names[oparg]
            elif op in hasjrel:
                arg = i + oparg
            elif op in haslocal:
                arg = co.co_varnames[oparg]
            elif op in hascompare:
                arg = cmp_op[oparg]
            elif op in hasfree:
                if free is None:
                    free = co.co_cellvars + co.co_freevars
                arg = free[oparg]

        ret.append(Instruction(op, oparg, arg, cur_line))
        oparg = None
        arg = None
    return ret
예제 #54
0
파일: bytecode.py 프로젝트: gsliu/emacs_C
def next_linestart(co, offset, count=1):
    linestarts = dict(dis.findlinestarts(co))
    code = co.co_code
    n = len(code)
    contains_cond_jump = False
    for op, offset in next_opcode(code, offset):
        if offset in linestarts: 
            count -= 1
            if 0 == count:
                return linestarts[offset]
            pass
        pass
    return -1000
예제 #55
0
def get_func_source(obj):
    """Get object's source code. Returns None when source can't be found.
    """
    from inspect import findsource
    from dis import findlinestarts
    try:
        lines, lnum = findsource(obj)
        ls = list(findlinestarts(obj.func_code))
        lstart = ls[0][1]
        lend = ls[-1][1]
    except (IOError, TypeError):
        return None
    return ''.join(lines[lstart-1:lend])
        def iterate():
            # First, get all line starts for this code object. This does not include
            # bodies of nested class and function definitions, as they have their
            # own objects.
            for _, lineno in dis.findlinestarts(code):
                yield lineno

            # For nested class and function definitions, their respective code objects
            # are constants referenced by this object.
            for const in code.co_consts:
                if isinstance(const, types.CodeType) and const.co_filename == code.co_filename:
                    for lineno in _get_code_lines(const):
                        yield lineno