mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2024-11-26 22:50:40 +00:00
Misc refactorings
This commit is contained in:
parent
3bd41b68ec
commit
167f5af5e6
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
*_dis
|
||||
*.pyc
|
||||
*~
|
||||
/.cache
|
||||
/.eggs
|
||||
|
@ -84,9 +84,10 @@ for usage help.
|
||||
Known Bugs/Restrictions
|
||||
-----------------------
|
||||
|
||||
Python 2 deparsing decompiles about the first 140 or so of the Python
|
||||
2.7.10 and 2.7.11 standard library files and all but less that 10%
|
||||
verify. So as such, it is probably a little better than uncompyle2.
|
||||
Python 2 deparsing decompiles each and all the Python 2.7.10 and 2.7.11 installed packages
|
||||
I have on my system. All but less that 10%
|
||||
verify. Some of thse failures may be bugs in the verification process.
|
||||
So as such, it is probably a little better than uncompyle2.
|
||||
Other Python 2 versions do worse.
|
||||
|
||||
Python 3 deparsing before 3.5 is okay, but even there, more work is needed to
|
||||
|
@ -1,9 +1,6 @@
|
||||
# Copyright (c) 1999 John Aycock
|
||||
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
|
||||
# Copyright (c) 2015 Rocky Bernstein
|
||||
#
|
||||
# See LICENSE for license
|
||||
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||
# Copyright (c) 1999 John Aycock
|
||||
"""
|
||||
A spark grammar for Python 2.x.
|
||||
|
||||
@ -20,15 +17,11 @@ from __future__ import print_function
|
||||
from uncompyle6.parser import PythonParser, PythonParserSingle, nop_func
|
||||
from uncompyle6.parsers.astnode import AST
|
||||
from spark_parser import DEFAULT_DEBUG as PARSER_DEFAULT_DEBUG
|
||||
from uncompyle6 import PYTHON3
|
||||
|
||||
class Python2Parser(PythonParser):
|
||||
|
||||
def __init__(self, debug_parser=PARSER_DEFAULT_DEBUG):
|
||||
if PYTHON3:
|
||||
super().__init__(AST, 'stmts', debug=debug_parser)
|
||||
else:
|
||||
super(Python2Parser, self).__init__(AST, 'stmts', debug=debug_parser)
|
||||
super(Python2Parser, self).__init__(AST, 'stmts', debug=debug_parser)
|
||||
self.customized = {}
|
||||
|
||||
def p_list_comprehension2(self, args):
|
||||
|
@ -49,9 +49,11 @@ class Scanner2(scan.Scanner):
|
||||
dis.disassemble().
|
||||
"""
|
||||
|
||||
## FIXME: DRY with disassemble_native
|
||||
|
||||
# import dis; dis.disassemble(co) # DEBUG
|
||||
# DEBUG
|
||||
# from xdis.bytecode import Bytecode
|
||||
# bytecode = Bytecode(co, self.opc)
|
||||
# for instr in bytecode.get_instructions(co):
|
||||
# print(instr._disassemble())
|
||||
|
||||
# Container for tokens
|
||||
tokens = []
|
||||
@ -60,6 +62,7 @@ class Scanner2(scan.Scanner):
|
||||
Token = self.Token # shortcut
|
||||
|
||||
n = self.setup_code(co)
|
||||
|
||||
self.build_lines_data(co, n)
|
||||
self.build_prev_op(n)
|
||||
|
||||
@ -203,75 +206,6 @@ class Scanner2(scan.Scanner):
|
||||
tokens.append(Token(replace[offset], oparg, pattr, offset, linestart))
|
||||
return tokens, customize
|
||||
|
||||
def disassemble_native(self, co, classname=None, code_objects={}):
|
||||
"""
|
||||
Like disassemble3 but doesn't try to adjust any opcodes.
|
||||
"""
|
||||
|
||||
## FIXME: DRY with disassemble
|
||||
|
||||
# Container for tokens
|
||||
tokens = []
|
||||
|
||||
customize = {}
|
||||
Token = self.Token # shortcut
|
||||
|
||||
n = self.setup_code(co)
|
||||
self.build_lines_data(co, n)
|
||||
|
||||
# self.lines contains (block,addrLastInstr)
|
||||
if classname:
|
||||
classname = '_' + classname.lstrip('_') + '__'
|
||||
|
||||
def unmangle(name):
|
||||
if name.startswith(classname) and name[-2:] != '__':
|
||||
return name[len(classname) - 2:]
|
||||
return name
|
||||
|
||||
free = [ unmangle(name) for name in (co.co_cellvars + co.co_freevars) ]
|
||||
names = [ unmangle(name) for name in co.co_names ]
|
||||
varnames = [ unmangle(name) for name in co.co_varnames ]
|
||||
else:
|
||||
free = co.co_cellvars + co.co_freevars
|
||||
names = co.co_names
|
||||
varnames = co.co_varnames
|
||||
|
||||
extended_arg = 0
|
||||
for offset in self.op_range(0, n):
|
||||
op = self.code[offset]
|
||||
op_name = self.opc.opname[op]
|
||||
|
||||
oparg = None; pattr = None
|
||||
if op >= self.opc.HAVE_ARGUMENT:
|
||||
oparg = self.get_argument(offset) + extended_arg
|
||||
extended_arg = 0
|
||||
if op == self.opc.EXTENDED_ARG:
|
||||
extended_arg = oparg * scan.L65536
|
||||
continue
|
||||
if op in self.opc.hasconst:
|
||||
pattr = co.co_consts[oparg]
|
||||
elif op in self.opc.hasname:
|
||||
pattr = names[oparg]
|
||||
elif op in self.opc.hasjrel:
|
||||
pattr = repr(offset + 3 + oparg)
|
||||
elif op in self.opc.hasjabs:
|
||||
pattr = repr(oparg)
|
||||
elif op in self.opc.haslocal:
|
||||
pattr = varnames[oparg]
|
||||
elif op in self.opc.hascompare:
|
||||
pattr = self.opc.cmp_op[oparg]
|
||||
elif op in self.opc.hasfree:
|
||||
pattr = free[oparg]
|
||||
|
||||
if offset in self.linestartoffsets:
|
||||
linestart = self.linestartoffsets[offset]
|
||||
else:
|
||||
linestart = None
|
||||
|
||||
tokens.append(Token(op_name, oparg, pattr, offset, linestart))
|
||||
pass
|
||||
return tokens, customize
|
||||
|
||||
def op_size(self, op):
|
||||
"""
|
||||
Return size of operator with its arguments
|
||||
|
@ -73,7 +73,10 @@ class Scanner26(scan.Scanner2):
|
||||
dis.disassemble().
|
||||
'''
|
||||
|
||||
# import dis; dis.disassemble(co) # DEBUG
|
||||
# from xdis.bytecode import Bytecode
|
||||
# bytecode = Bytecode(co, self.opc)
|
||||
# for instr in bytecode.get_instructions(co):
|
||||
# print(instr._disassemble())
|
||||
|
||||
# Container for tokens
|
||||
tokens = []
|
||||
@ -82,7 +85,8 @@ class Scanner26(scan.Scanner2):
|
||||
Token = self.Token # shortcut
|
||||
|
||||
n = self.setup_code(co)
|
||||
self.build_lines_data(co, n)
|
||||
|
||||
self.build_lines_data(co, n-1)
|
||||
|
||||
# linestarts contains block code adresses (addr,block)
|
||||
self.linestarts = list(findlinestarts(co))
|
||||
|
@ -176,32 +176,6 @@ class Scanner3(scan.Scanner):
|
||||
pass
|
||||
return tokens, {}
|
||||
|
||||
def disassemble_native(self, co, classname=None, code_objects={}):
|
||||
"""
|
||||
Like disassemble3 but doesn't try to adjust any opcodes.
|
||||
"""
|
||||
# Container for tokens
|
||||
tokens = []
|
||||
|
||||
self.code = array('B', co.co_code)
|
||||
|
||||
bytecode = Bytecode(co, self.opc)
|
||||
|
||||
for inst in bytecode:
|
||||
pattr = inst.argrepr
|
||||
opname = inst.opname
|
||||
tokens.append(
|
||||
Token(
|
||||
type_ = opname,
|
||||
attr = inst.argval,
|
||||
pattr = pattr,
|
||||
offset = inst.offset,
|
||||
linestart = inst.starts_line,
|
||||
)
|
||||
)
|
||||
pass
|
||||
return tokens, {}
|
||||
|
||||
def build_lines_data(self, code_obj):
|
||||
"""
|
||||
Generate various line-related helper data.
|
||||
|
Loading…
Reference in New Issue
Block a user