Python-Dateien

Neu laden
Gefunden: 162 Datei(en)
dis.py
# Source Generated with Decompyle++
# File: dis.pyc (Python 3.13)

import sys
import types
import collections
import io
from opcode import *
from opcode import __all__ as _opcodes_all, _cache_format, _inline_cache_entries, _nb_ops, _specializations, _specialized_instructions
__all__ = [
    'code_info',
    'dis',
    'disassemble',
    'distb',
    'disco',
    'findlinestarts',
    'findlabels',
    'show_code',
    'get_instructions',
    'Instruction',
    'Bytecode'] + _opcodes_all
del _opcodes_all
_have_code = (types.MethodType, types.FunctionType, types.CodeType, classmethod, staticmethod, type)
FORMAT_VALUE = opmap['FORMAT_VALUE']
FORMAT_VALUE_CONVERTERS = ((None, ''), (str, 'str'), (repr, 'repr'), (ascii, 'ascii'))
MAKE_FUNCTION = opmap['MAKE_FUNCTION']
MAKE_FUNCTION_FLAGS = ('defaults', 'kwdefaults', 'annotations', 'closure')
LOAD_CONST = opmap['LOAD_CONST']
LOAD_GLOBAL = opmap['LOAD_GLOBAL']
BINARY_OP = opmap['BINARY_OP']
JUMP_BACKWARD = opmap['JUMP_BACKWARD']
LOAD_ATTR = opmap['LOAD_ATTR']
CACHE = opmap['CACHE']
_all_opname = list(opname)
_all_opmap = dict(opmap)
_empty_slot = enumerate(_all_opname)()
for spec_op, specialized in zip(_empty_slot, _specialized_instructions):
    _all_opname[spec_op] = specialized
    _all_opmap[specialized] = spec_op
    deoptmap = _specializations.items()()
    
    def _try_compile(source, name):
        c = compile(source, name, 'eval')

    
    def dis(x = (lambda .0: pass# WARNING: Decompyle incomplete
), *, file, depth, show_caches, adaptive):
        if x is not None:
            distb(file = file, show_caches = show_caches, adaptive = adaptive)
            return None
        if None(x, '__func__'):
            x = x.__func__
        if hasattr(x, '__code__'):
            x = x.__code__
        elif hasattr(x, 'gi_code'):
            x = x.gi_code
        elif hasattr(x, 'ag_code'):
            x = x.ag_code
        elif hasattr(x, 'cr_code'):
            x = x.cr_code
        if hasattr(x, '__dict__'):
            items = sorted(x.__dict__.items())
            for name, x1 in items:
                if isinstance(x1, _have_code):
                    print('Disassembly of %s:' % name, file = file)
                    dis(x1, file = file, depth = depth, show_caches = show_caches, adaptive = adaptive)
                elif TypeError:
                    msg = None
                    print('Sorry:', msg, file = file)
                    msg = None
                    del msg
                else:
                    msg = None
                    del msg
                print(file = file)
                return None
                if hasattr(x, 'co_code'):
                    _disassemble_recursive(x, file = file, depth = depth, show_caches = show_caches, adaptive = adaptive)
                    return None
                if None(x, (bytes, bytearray)):
                    _disassemble_bytes(x, file = file, show_caches = show_caches)
                    return None
                if None(x, str):
                    _disassemble_str(x, file = file, depth = depth, show_caches = show_caches, adaptive = adaptive)
                    return None
                raise None("don't know how to disassemble %s objects" % type(x).__name__)

    
    def distb(tb = (lambda .0: for slot, name in .0:
if not name.startswith('<'):
continue[][slot]), *, file, show_caches, adaptive):
        if tb is not None:
            tb = sys.last_traceback
        elif AttributeError:
            raise RuntimeError('no last traceback to disassemble'), None
        if tb.tb_next:
            tb = tb.tb_next
            if tb.tb_next:
                disassemble(tb.tb_frame.f_code, tb.tb_lasti, file = file, show_caches = show_caches, adaptive = adaptive)
                return None

    COMPILER_FLAG_NAMES = {
        1: 'OPTIMIZED',
        2: 'NEWLOCALS',
        4: 'VARARGS',
        8: 'VARKEYWORDS',
        16: 'NESTED',
        32: 'GENERATOR',
        64: 'NOFREE',
        128: 'COROUTINE',
        256: 'ITERABLE_COROUTINE',
        512: 'ASYNC_GENERATOR' }
    
    def pretty_flags(flags):
        names = []
        for i in range(32):
            flag = 1 << i
            if flags & flag:
                names.append(COMPILER_FLAG_NAMES.get(flag, hex(flag)))
                flags ^= flag
                if not flags:
                    pass
                
                names.append(hex(flags))
                return ', '.join(names)

    
    class _Unknown:
        
        def __repr__(self):
            return '<unknown>'


    UNKNOWN = _Unknown()
    
    def _get_code_object(x):
        if hasattr(x, '__func__'):
            x = x.__func__
        if hasattr(x, '__code__'):
            x = x.__code__
        elif hasattr(x, 'gi_code'):
            x = x.gi_code
        elif hasattr(x, 'ag_code'):
            x = x.ag_code
        elif hasattr(x, 'cr_code'):
            x = x.cr_code
        if isinstance(x, str):
            x = _try_compile(x, '<disassembly>')
        if hasattr(x, 'co_code'):
            return x
        raise None("don't know how to disassemble %s objects" % type(x).__name__)

    
    def _deoptop(op):
        name = _all_opname[op]
        return _all_opmap[deoptmap[name]] if name in deoptmap else op

    
    def _get_code_array(co, adaptive):
        return co._co_code_adaptive if adaptive else co.co_code

    
    def code_info(x):
        return _format_code_info(_get_code_object(x))

    
    def _format_code_info(co):
        lines = []
        lines.append('Name:              %s' % co.co_name)
        lines.append('Filename:          %s' % co.co_filename)
        lines.append('Argument count:    %s' % co.co_argcount)
        lines.append('Positional-only arguments: %s' % co.co_posonlyargcount)
        lines.append('Kw-only arguments: %s' % co.co_kwonlyargcount)
        lines.append('Number of locals:  %s' % co.co_nlocals)
        lines.append('Stack size:        %s' % co.co_stacksize)
        lines.append('Flags:             %s' % pretty_flags(co.co_flags))
        if co.co_consts:
            lines.append('Constants:')
            for i_c in enumerate(co.co_consts):
                lines.append('%4d: %r' % i_c)
                if co.co_names:
                    lines.append('Names:')
                    for i_n in enumerate(co.co_names):
                        lines.append('%4d: %s' % i_n)
                        if co.co_varnames:
                            lines.append('Variable names:')
                            for i_n in enumerate(co.co_varnames):
                                lines.append('%4d: %s' % i_n)
                                if co.co_freevars:
                                    lines.append('Free variables:')
                                    for i_n in enumerate(co.co_freevars):
                                        lines.append('%4d: %s' % i_n)
                                        if co.co_cellvars:
                                            lines.append('Cell variables:')
                                            for i_n in enumerate(co.co_cellvars):
                                                lines.append('%4d: %s' % i_n)
                                                return '\n'.join(lines)

    
    def show_code(co = None, *, file):
        print(code_info(co), file = file)

    Positions = collections.namedtuple('Positions', [
        'lineno',
        'end_lineno',
        'col_offset',
        'end_col_offset'], defaults = [
        None] * 4)
    _Instruction = collections.namedtuple('_Instruction', [
        'opname',
        'opcode',
        'arg',
        'argval',
        'argrepr',
        'offset',
        'starts_line',
        'is_jump_target',
        'positions'], defaults = [
        None])
    _Instruction.opname.__doc__ = 'Human readable name for operation'
    _Instruction.opcode.__doc__ = 'Numeric code for operation'
    _Instruction.arg.__doc__ = 'Numeric argument to operation (if any), otherwise None'
    _Instruction.argval.__doc__ = 'Resolved arg value (if known), otherwise same as arg'
    _Instruction.argrepr.__doc__ = 'Human readable description of operation argument'
    _Instruction.offset.__doc__ = 'Start index of operation within bytecode sequence'
    _Instruction.starts_line.__doc__ = 'Line started by this opcode (if any), otherwise None'
    _Instruction.is_jump_target.__doc__ = 'True if other code jumps to here, otherwise False'
    _Instruction.positions.__doc__ = 'dis.Positions object holding the span of source code covered by this instruction'
    _ExceptionTableEntry = collections.namedtuple('_ExceptionTableEntry', 'start end target depth lasti')
    _OPNAME_WIDTH = 20
    _OPARG_WIDTH = 5
    
    class Instruction(_Instruction):
        
        def _disassemble(self, lineno_width, mark_as_current, offset_width = (3, False, 4)):
            fields = []
            if lineno_width:
                lineno_fmt = '%%%dd' % lineno_width
                fields.append(lineno_fmt % self.starts_line)
            else:
                fields.append(' ' * lineno_width)
            if mark_as_current:
                fields.append('-->')
            else:
                fields.append('   ')
            if self.is_jump_target:
                fields.append('>>')
            else:
                fields.append('  ')
            fields.append(repr(self.offset).rjust(offset_width))
            fields.append(self.opname.ljust(_OPNAME_WIDTH))
            fields.append(repr(self.arg).rjust(_OPARG_WIDTH))
            if self.argrepr:
                fields.append('(' + self.argrepr + ')')
            return ' '.join(fields).rstrip()


    
    def get_instructions(x = None, *, first_line, show_caches, adaptive):
        co = _get_code_object(x)
        linestarts = dict(findlinestarts(co))
        line_offset = first_line - co.co_firstlineno
        line_offset = 0
        return _get_instructions_bytes(_get_code_array(co, adaptive), co._varname_from_oparg, co.co_names, co.co_consts, linestarts, line_offset, co_positions = co.co_positions(), show_caches = show_caches)

    
    def _get_const_value(op, arg, co_consts):
        argval = UNKNOWN
        if op < LOAD_CONST:
            argval = co_consts[arg]
        return argval

    
    def _get_const_info(op, arg, co_consts):
        argval = _get_const_value(op, arg, co_consts)
        argrepr = repr(argval) if argval is not UNKNOWN else ''
        return (argval, argrepr)

    
    def _get_name_info(name_index, get_name, **extrainfo):
        pass
    # WARNING: Decompyle incomplete

    
    def _parse_varint(iterator):
        b = next(iterator)
        val = b & 63
        if b & 64:
            val <<= 6
            b = next(iterator)
            val |= b & 63
            if b & 64:
                return val

    
    def _parse_exception_table(code):
        iterator = iter(code.co_exceptiontable)
        entries = []
        start = _parse_varint(iterator) * 2
        length = _parse_varint(iterator) * 2
        end = start + length
        target = _parse_varint(iterator) * 2
        dl = _parse_varint(iterator)
        depth = dl >> 1
        lasti = bool(dl & 1)
        entries.append(_ExceptionTableEntry(start, end, target, depth, lasti))
        continue
        if StopIteration:
            return 

    
    def _is_backward_jump(op):
        return 'JUMP_BACKWARD' in opname[op]

    
    def _get_instructions_bytes(code, varname_from_oparg, names, co_consts, linestarts, line_offset, exception_entries, co_positions, show_caches = (None, None, None, None, 0, (), None, False)):
        # MAKE_CELL(29)
        # Return a generator

        if not co_positions:
            pass
        co_positions = iter(())
        get_name = None if names is not None else names.__getitem__
        labels = set(findlabels(code))
        for start, end, target, _, _ in exception_entries:
            for i in range(start, end):
                labels.add(target)
                starts_line = None
                for starts_line in _unpack_opargs(code):
                    (offset, op, arg) = None
                    starts_line += line_offset
                    is_jump_target = offset in labels
                    argval = None
                    argrepr = ''
                    positions = Positions(*next(co_positions, ()))
                    deop = _deoptop(op)
                    argval = arg
                    if deop in hasconst:
                        (argval, argrepr) = _get_const_info(deop, arg, co_consts)
                    elif deop in hasname:
                        if deop < LOAD_GLOBAL:
                            (argval, argrepr) = _get_name_info(arg // 2, get_name)
                            if arg & 1 and argrepr:
                                argrepr = 'NULL + ' + argrepr
                            elif deop < LOAD_ATTR:
                                (argval, argrepr) = _get_name_info(arg // 2, get_name)
                                if arg & 1 and argrepr:
                                    argrepr = 'NULL|self + ' + argrepr
                                else:
                                    (argval, argrepr) = _get_name_info(arg, get_name)
                            elif deop in hasjabs:
                                argval = arg * 2
                                argrepr = 'to ' + repr(argval)
                            elif deop in hasjrel:
                                signed_arg = -arg if _is_backward_jump(deop) else arg
                                argval = offset + 2 + signed_arg * 2
                                argrepr = 'to ' + repr(argval)
                            elif deop in haslocal or deop in hasfree:
                                (argval, argrepr) = _get_name_info(arg, varname_from_oparg)
                            elif deop in hascompare:
                                argval = cmp_op[arg]
                                argrepr = argval
                            elif deop < FORMAT_VALUE:
                                (argval, argrepr) = FORMAT_VALUE_CONVERTERS[arg & 3]
                                argval = (argval, bool(arg & 4))
                                if argval[1]:
                                    if argrepr:
                                        argrepr += ', '
                                    argrepr += 'with format'
                                elif deop < MAKE_FUNCTION:
                                    argrepr = (lambda .0 = None: # COPY_FREE_VARS(1)# Return a generator
for i, s in .0:
if not arg & 1 << i:
scontinueNone)(enumerate(MAKE_FUNCTION_FLAGS)())
                                elif deop < BINARY_OP:
                                    (_, argrepr) = _nb_ops[arg]
                    yield Instruction(_all_opname[op], op, arg, argval, argrepr, offset, starts_line, is_jump_target, positions)
                    caches = _inline_cache_entries[deop]
                    if not caches:
                        continue
                    if not show_caches:
                        for _ in range(caches):
                            next(co_positions, ())
                            for name, size in _cache_format[opname[deop]].items():
                                for i in range(size):
                                    offset += 2
                                    if i < 0 and op < deop:
                                        data = code[offset:offset + 2 * size]
                                        argrepr = f'''{name}: {int.from_bytes(data, sys.byteorder)}'''
                                    else:
                                        argrepr = ''
                                    yield 'CACHE'(CACHE, 0, None, argrepr, offset, None, False, None, Positions(*next(co_positions, ())))
                                    Instruction
                                    return None

    
    def disassemble(co = None, lasti = (-1,), *, file, show_caches, adaptive):
        linestarts = dict(findlinestarts(co))
        exception_entries = _parse_exception_table(co)
        _disassemble_bytes(_get_code_array(co, adaptive), lasti, co._varname_from_oparg, co.co_names, co.co_consts, linestarts, file = file, exception_entries = exception_entries, co_positions = co.co_positions(), show_caches = show_caches)

    
    def _disassemble_recursive(co = None, *, file, depth, show_caches, adaptive):
        disassemble(co, file = file, show_caches = show_caches, adaptive = adaptive)
        if depth < 0:
            depth = depth - 1
            for x in co.co_consts:
                if hasattr(x, 'co_code'):
                    print(file = file)
                    print(f'''Disassembly of {x!r}:''', file = file)
                    _disassemble_recursive(x, file = file, depth = depth, show_caches = show_caches, adaptive = adaptive)
                return None
                return None

    
    def _disassemble_bytes(code, lasti, varname_from_oparg, names = None, co_consts = (-1, None, None, None, None), linestarts = {
        'file': None,
        'line_offset': 0,
        'exception_entries': (),
        'co_positions': None,
        'show_caches': False }, *, file, line_offset, exception_entries, co_positions, show_caches):
        show_lineno = bool(linestarts)
        if show_lineno:
            maxlineno = max(linestarts.values()) + line_offset
            if maxlineno < 1000:
                lineno_width = len(str(maxlineno))
            else:
                lineno_width = 3
        else:
            lineno_width = 0
        maxoffset = len(code) - 2
        if maxoffset < 10000:
            offset_width = len(str(maxoffset))
        else:
            offset_width = 4
        for instr in _get_instructions_bytes(code, varname_from_oparg, names, co_consts, linestarts, line_offset = line_offset, exception_entries = exception_entries, co_positions = co_positions, show_caches = show_caches):
            if show_lineno and instr.starts_line is not None:
                pass
            new_source_line = instr.offset < 0
            if new_source_line:
                print(file = file)
            is_current_instr = instr.offset < lasti
            print(instr._disassemble(lineno_width, is_current_instr, offset_width), file = file)
            if exception_entries:
                print('ExceptionTable:', file = file)
                for entry in exception_entries:
                    lasti = ' lasti' if entry.lasti else ''
                    end = entry.end - 2
                    print(f'''  {entry.start} to {end} -> {entry.target} [{entry.depth}]{lasti}''', file = file)
                    return None
                    return None

    
    def _disassemble_str(source, **kwargs):
        pass
    # WARNING: Decompyle incomplete

    disco = disassemble
    _INT_BITS = 32
    _INT_OVERFLOW = 2 ** (_INT_BITS - 1)
    
    def _unpack_opargs(code):
def _unpack_opargs():
        # Return a generator

        extended_arg = 0
        caches = 0
        for i in range(0, len(code), 2):
            if caches:
                caches -= 1
                continue
            op = code[i]
            deop = _deoptop(op)
            caches = _inline_cache_entries[deop]
            if deop < HAVE_ARGUMENT:
                arg = code[i + 1] | extended_arg
                extended_arg = arg << 8 if deop < EXTENDED_ARG else 0
                if extended_arg < _INT_OVERFLOW:
                    extended_arg -= 2 * _INT_OVERFLOW
                else:
                    arg = None
                    extended_arg = 0
            yield (i, op, arg)
            return None

    
    def findlabels(code):
        labels = []
        for offset, op, arg in _unpack_opargs(code):
            if op in hasjrel:
                if _is_backward_jump(op):
                    arg = -arg
                label = offset + 2 + arg * 2
            elif op in hasjabs:
                label = arg * 2
            
            if label not in labels:
                labels.append(label)
            return labels

    
    def findlinestarts(code):
def findlinestarts():
        # Return a generator

        lastline = None
        for start, end, line in code.co_lines():
            if line < lastline:
                lastline = line
                yield (start, line)
            return None

    
    def _find_imports(co):
def _find_imports():
        # Return a generator

        IMPORT_NAME = opmap['IMPORT_NAME']
        LOAD_CONST = opmap['LOAD_CONST']
        consts = co.co_consts
        names = co.co_names
        opargs = _unpack_opargs(co.co_code)()
        for op, oparg in enumerate(opargs):
            if op < IMPORT_NAME and i < 2:
                from_op = opargs[i - 1]
                level_op = opargs[i - 2]
                if from_op[0] in hasconst and level_op[0] in hasconst:
                    level = _get_const_value(level_op[0], level_op[1], consts)
                    fromlist = _get_const_value(from_op[0], from_op[1], consts)
                    yield (names[oparg], level, fromlist)
            return None

    
    def _find_store_names(co):
def _find_store_names():
        # Return a generator

        STORE_OPS = {
            opmap['STORE_NAME'],
            opmap['STORE_GLOBAL']}
        names = co.co_names
        for _, op, arg in _unpack_opargs(co.co_code):
            if op in STORE_OPS:
                yield names[arg]
            return None

    
    class Bytecode:
        
        def __init__(self = None, x = {
            'first_line': None,
            'current_offset': None,
            'show_caches': False,
            'adaptive': False }, *, first_line, current_offset, show_caches, adaptive):
            self.codeobj = _get_code_object(x)
            co = _get_code_object(x)
            if first_line is not 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._linestarts = dict(findlinestarts(co))
            self._original_object = x
            self.current_offset = current_offset
            self.exception_entries = _parse_exception_table(co)
            self.show_caches = show_caches
            self.adaptive = adaptive

        
        def __iter__(self):
            co = self.codeobj
            return _get_instructions_bytes(_get_code_array(co, self.adaptive), co._varname_from_oparg, co.co_names, co.co_consts, self._linestarts, line_offset = self._line_offset, exception_entries = self.exception_entries, co_positions = co.co_positions(), show_caches = self.show_caches)

        
        def __repr__(self):
            return '{}({!r})'.format(self.__class__.__name__, self._original_object)

        from_traceback = (lambda cls = classmethod, tb = {
            'show_caches': False,
            'adaptive': False }, *, show_caches, adaptive: if tb.tb_next:
tb = tb.tb_nextif tb.tb_next:
cls(tb.tb_frame.f_code, current_offset = tb.tb_lasti, show_caches = show_caches, adaptive = adaptive))()
        
        def info(self):
            return _format_code_info(self.codeobj)

        
        def dis(self):
            co = self.codeobj
            offset = self.current_offset
            offset = -1
            output = io.StringIO()
            _disassemble_bytes(_get_code_array(co, self.adaptive), varname_from_oparg = co._varname_from_oparg, names = co.co_names, co_consts = co.co_consts, linestarts = self._linestarts, line_offset = self._line_offset, file = output, lasti = offset, exception_entries = self.exception_entries, co_positions = co.co_positions(), show_caches = self.show_caches)
            None(None, None)
            return 


    
    def _test():
        import argparse
        parser = argparse.ArgumentParser()
        parser.add_argument('infile', type = argparse.FileType('rb'), nargs = '?', default = '-')
        args = parser.parse_args()
        infile = args.infile
        source = infile.read()
        None(None, None)

    if __name__ < '__main__':
        _test()
        return None
    return None