Exemplo n.º 1
0
    def decompile(decompiler):
        PY36 = sys.version_info >= (3, 6)
        code = decompiler.code
        co_code = code.co_code
        free = code.co_cellvars + code.co_freevars
        try:
            extended_arg = 0
            while decompiler.pos < decompiler.end:
                i = decompiler.pos
                if i in decompiler.targets:
                    decompiler.process_target(i)
                op = ord(code.co_code[i])
                if PY36:
                    if op >= HAVE_ARGUMENT:
                        oparg = ord(co_code[i + 1]) | extended_arg
                        extended_arg = ((extended_arg << 8)
                                        if op == EXTENDED_ARG else 0)
                    i += 2
                else:
                    i += 1
                    if op >= HAVE_ARGUMENT:
                        oparg = ord(co_code[i]) + ord(co_code[i + 1]) * 256
                        i += 2
                        if op == EXTENDED_ARG:
                            op = ord(code.co_code[i])
                            i += 1
                            oparg = (ord(co_code[i]) +
                                     ord(co_code[i + 1]) * 256 + oparg * 65536)
                            i += 2
                if op >= HAVE_ARGUMENT:
                    if op in hasconst:
                        arg = [code.co_consts[oparg]]
                    elif op in hasname:
                        arg = [code.co_names[oparg]]
                    elif op in hasjrel:
                        arg = [i + oparg]
                    elif op in haslocal:
                        arg = [code.co_varnames[oparg]]
                    elif op in hascompare:
                        arg = [cmp_op[oparg]]
                    elif op in hasfree:
                        arg = [free[oparg]]
                    else:
                        arg = [oparg]
                else:
                    arg = []

                opname = opnames[op].replace('+', '_')
                # print(opname, arg, decompiler.stack)
                method = getattr(decompiler, opname, None)
                if method is None:
                    throw(NotImplementedError,
                          'Unsupported operation: %s' % opname)  # noqa
                decompiler.pos = i
                x = method(*arg)
                if x is not None:
                    decompiler.stack.append(x)
        except AstGenerated:
            pass
Exemplo n.º 2
0
 def STORE_FAST(decompiler, varname):
     if varname.startswith('_['):
         throw(
             InvalidQuery, 'Use generator expression (... for ... in ...) '
             'instead of list comprehension [... for ... in ...] inside query'
         )  # noqa
     decompiler.assnames.add(varname)
     decompiler.store(ast.AssName(varname, 'OP_ASSIGN'))
Exemplo n.º 3
0
 def CALL_FUNCTION_EX(decompiler, argc):
     star2 = None
     if argc:
         if argc != 1:
             throw(NotImplementedError)
         star2 = decompiler.stack.pop()
     star = decompiler.stack.pop()
     return decompiler._call_function([], star, star2)
Exemplo n.º 4
0
    def process_target(decompiler, pos, partial=False):
        if pos is None:
            limit = None
        elif partial:
            limit = decompiler.targets.get(pos, None)
        else:
            limit = decompiler.targets.pop(pos, None)
        top = decompiler.stack.pop()
        while True:
            top = simplify(top)
            if top is limit:
                break
            if isinstance(top, ast.GenExprFor):
                break

            top2 = decompiler.stack[-1]
            if isinstance(top2, ast.GenExprFor):
                break
            if partial and hasattr(top2, 'endpos') and top2.endpos == pos:
                break

            if isinstance(top2, (ast.And, ast.Or)):
                if top2.__class__ == top.__class__:
                    top2.nodes.extend(top.nodes)
                else:
                    top2.nodes.append(top)
            elif isinstance(top2, ast.IfExp):  # Python 2.5
                top2.else_ = top
                if hasattr(top, 'endpos'):
                    top2.endpos = top.endpos
                    if decompiler.targets.get(top.endpos) is top:
                        decompiler.targets[top.endpos] = top2
            else:
                throw(
                    NotImplementedError,
                    'Expression is too complex to decompile, try to pass query as string, e.g. select("x for x in Something")'
                )  # noqa
            top2.endpos = max(top2.endpos, getattr(top, 'endpos', 0))
            top = decompiler.stack.pop()
        decompiler.stack.append(top)
Exemplo n.º 5
0
def decompile(x):
    cells = {}
    if isinstance(x, types.CodeType):
        codeobject = x
    elif isinstance(x, types.GeneratorType):
        codeobject = x.gi_frame.f_code
    elif isinstance(x, types.FunctionType):
        codeobject = x.func_code if PY2 else x.__code__
        if PY2:
            if x.func_closure:
                cells = dict(izip(codeobject.co_freevars, x.func_closure))
        else:
            if x.__closure__:
                cells = dict(izip(codeobject.co_freevars, x.__closure__))
    else:
        throw(TypeError)
    key = get_codeobject_id(codeobject)
    result = ast_cache.get(key)
    if result is None:
        decompiler = Decompiler(codeobject)
        result = decompiler.ast, decompiler.external_names
        ast_cache.set(key, result)
    return result + (cells, )
Exemplo n.º 6
0
 def MAKE_FUNCTION(decompiler, argc):
     if sys.version_info >= (3, 6):
         if argc:
             if argc != 0x08:
                 throw(NotImplementedError, argc)
         decompiler.stack.pop()
         tos = decompiler.stack.pop()
         if (argc & 0x08):
             decompiler.stack.pop()
     else:
         if argc:
             throw(NotImplementedError)
         tos = decompiler.stack.pop()
         if not PY2:
             tos = decompiler.stack.pop()
     codeobject = tos.value
     func_decompiler = Decompiler(codeobject)
     # decompiler.names.update(decompiler.names)  ???
     if codeobject.co_varnames[:1] == ('.0', ):
         return func_decompiler.ast  # generator
     argnames = codeobject.co_varnames[:codeobject.co_argcount]
     defaults = []  # todo
     flags = 0  # todo
     return ast.Lambda(argnames, defaults, flags, func_decompiler.ast)
Exemplo n.º 7
0
 def RETURN_VALUE(decompiler):
     if decompiler.pos != decompiler.end:
         throw(NotImplementedError)
     expr = decompiler.stack.pop()
     decompiler.stack.append(simplify(expr))
     raise AstGenerated()
Exemplo n.º 8
0
 def LIST_APPEND(decompiler, offset=None):
     throw(InvalidQuery, 'Use generator expression (... for ... in ...) '
           'instead of list comprehension [... for ... in ...] inside query'
           )  # noqa
Exemplo n.º 9
0
 def default_post(translator, node):
     throw(NotImplementedError, node)
Exemplo n.º 10
0
 def default_post(self, node):
     throw(NotImplementedError, node)