You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Misc small changes
Go over history yet again code cleanups.
This commit is contained in:
31
HISTORY.md
31
HISTORY.md
@@ -23,8 +23,10 @@ working on his thesis, John realized SPARK could be used to deparse
|
||||
Python bytecode. In the fall of 1999, he started writing the Python
|
||||
program, "decompyle", to do this.
|
||||
|
||||
This code introduced another clever idea: using table-driven
|
||||
semantics routines, using format specifiers.
|
||||
To help with control structure deparsing the instruction sequence was
|
||||
augmented with pseudo instruction COME_FROM. This code introduced
|
||||
another clever idea: using table-driven semantics routines, using
|
||||
format specifiers.
|
||||
|
||||
The last mention of a release of SPARK from John is around 2002.
|
||||
|
||||
@@ -55,19 +57,24 @@ it doesn't look like he's done anything compiler-wise since SPARK). So
|
||||
I hope people will use the crazy-compilers service. I wish them the
|
||||
success that his good work deserves.
|
||||
|
||||
Dan Pascu did a bit of work around 2005 on the Python get this code to
|
||||
handle Python 2.3 and 2.4 bytecodes. Because of jump optimization
|
||||
introduced in the CPython bytecode compiler at that time, various JUMP
|
||||
instructions were classifed as going forward or backwards, and COME
|
||||
FROM instructions were introduced. See RELEASE-2.4-CHANGELOG.txt for
|
||||
more details here.
|
||||
Dan Pascu did a bit of work from late 2004 to early 2006 to get this
|
||||
code to handle first Python 2.3 and then 2.4 bytecodes. Because of
|
||||
jump optimization introduced in the CPython bytecode compiler at that
|
||||
time, various JUMP instructions were classifed as going backwards, and
|
||||
COME FROM instructions were reintroduced. See
|
||||
RELEASE-2.4-CHANGELOG.txt for more details here. There wasn't a public
|
||||
release of RELEASE-2.4 and bytecodes other than Python 2.4 weren't
|
||||
supported.
|
||||
|
||||
Next we get to ["uncompyle" and
|
||||
PyPI](https://pypi.python.org/pypi/uncompyle/1.1) and the era of
|
||||
public version control. In contrast to decompyle, uncompyle at least
|
||||
in its final versions, runs only on Python 2.7. However it accepts
|
||||
bytecode back to Python 2.5. Thomas Grainger is the package owner of
|
||||
this, although Hartmut is still listed as the author.
|
||||
public version control. (Dan's code although not public used
|
||||
[darcs](http://darcs.net/) for version control.
|
||||
|
||||
In contrast to _decompyle_, _uncompyle_ at least in its final versions,
|
||||
runs only on Python 2.7. However it accepts bytecode back to Python
|
||||
2.5. Thomas Grainger is the package owner of this, although Hartmut is
|
||||
still listed as the author.
|
||||
|
||||
The project exists not only on
|
||||
[github](https://github.com/gstarnberger/uncompyle) but also on
|
||||
|
@@ -33,9 +33,11 @@ def uncompyle(version, co, out=None, showasm=False, showast=False,
|
||||
code_objects=code_objects)
|
||||
except pysource.SourceWalkerError as e:
|
||||
# deparsing failed
|
||||
print("\n")
|
||||
if real_out != out:
|
||||
print("\n", file=real_out)
|
||||
print(e, file=real_out)
|
||||
raise
|
||||
|
||||
|
||||
|
||||
def uncompyle_file(filename, outstream=None, showasm=False, showast=False,
|
||||
|
@@ -27,13 +27,21 @@ class Scanner27(scan.Scanner):
|
||||
|
||||
def disassemble(self, co, classname=None, code_objects={}):
|
||||
"""
|
||||
Disassemble a code object, returning a list of 'Token'.
|
||||
Disassemble a Python 3 ode object, returning a list of 'Token'.
|
||||
Various tranformations are made to assist the deparsing grammar.
|
||||
For example:
|
||||
- various types of LOAD_CONST's are categorized in terms of what they load
|
||||
- COME_FROM instructions are added to assist parsing control structures
|
||||
- MAKE_FUNCTION and FUNCTION_CALLS append the number of positional aruments
|
||||
The main part of this procedure is modelled after
|
||||
dis.disassemble().
|
||||
"""
|
||||
|
||||
# import dis; dis.disassemble(co) # DEBUG
|
||||
rv = []
|
||||
|
||||
# Container for tokens
|
||||
tokens = []
|
||||
|
||||
customize = {}
|
||||
Token = self.Token # shortcut
|
||||
self.code = array('B', co.co_code)
|
||||
@@ -125,7 +133,7 @@ class Scanner27(scan.Scanner):
|
||||
if offset in cf:
|
||||
k = 0
|
||||
for j in cf[offset]:
|
||||
rv.append(Token('COME_FROM', None, repr(j),
|
||||
tokens.append(Token('COME_FROM', None, repr(j),
|
||||
offset="%s_%d" % (offset, k)))
|
||||
k += 1
|
||||
|
||||
@@ -211,10 +219,10 @@ class Scanner27(scan.Scanner):
|
||||
linestart = None
|
||||
|
||||
if offset not in replace:
|
||||
rv.append(Token(op_name, oparg, pattr, offset, linestart))
|
||||
tokens.append(Token(op_name, oparg, pattr, offset, linestart))
|
||||
else:
|
||||
rv.append(Token(replace[offset], oparg, pattr, offset, linestart))
|
||||
return rv, customize
|
||||
tokens.append(Token(replace[offset], oparg, pattr, offset, linestart))
|
||||
return tokens, customize
|
||||
|
||||
def build_stmt_indices(self):
|
||||
code = self.code
|
||||
|
@@ -1,4 +1,7 @@
|
||||
# Copyright (c) 2015, 2016 by Rocky Bernstein
|
||||
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
|
||||
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
|
||||
# Copyright (c) 1999 John Aycock
|
||||
"""
|
||||
Python 3 Generic bytecode scanner/deparser
|
||||
|
||||
@@ -49,6 +52,16 @@ class Scanner3(scan.Scanner):
|
||||
|
||||
## FIXME opnames should be moved to init
|
||||
def disassemble3(self, co, opnames, classname=None, code_objects={}):
|
||||
"""
|
||||
Disassemble a Python 3 ode object, returning a list of 'Token'.
|
||||
Various tranformations are made to assist the deparsing grammar.
|
||||
For example:
|
||||
- various types of LOAD_CONST's are categorized in terms of what they load
|
||||
- COME_FROM instructions are added to assist parsing control structures
|
||||
- MAKE_FUNCTION and FUNCTION_CALLS append the number of positional aruments
|
||||
The main part of this procedure is modelled after
|
||||
dis.disassemble().
|
||||
"""
|
||||
|
||||
self.opnames = opnames # will eventually disasppear
|
||||
|
||||
|
@@ -203,8 +203,8 @@ def cmp_code_objects(version, code_obj1, code_obj2, name=''):
|
||||
JUMP_OPs = list(scan.JUMP_OPs) + ['JUMP_BACK']
|
||||
|
||||
# use changed Token class
|
||||
# we (re)set this here to save exception handling,
|
||||
# which would get 'unubersichtlich'
|
||||
# We (re)set this here to save exception handling,
|
||||
# which would get confusing.
|
||||
scanner.setTokenClass(Token)
|
||||
try:
|
||||
# disassemble both code-objects
|
||||
|
Reference in New Issue
Block a user