Misc small changes

Go over history yet again
code cleanups.
This commit is contained in:
rocky
2016-05-16 10:15:55 -04:00
parent ebfe5e3ba8
commit 134b67d952
5 changed files with 51 additions and 21 deletions

View File

@@ -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 Python bytecode. In the fall of 1999, he started writing the Python
program, "decompyle", to do this. program, "decompyle", to do this.
This code introduced another clever idea: using table-driven To help with control structure deparsing the instruction sequence was
semantics routines, using format specifiers. 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. 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 I hope people will use the crazy-compilers service. I wish them the
success that his good work deserves. success that his good work deserves.
Dan Pascu did a bit of work around 2005 on the Python get this code to Dan Pascu did a bit of work from late 2004 to early 2006 to get this
handle Python 2.3 and 2.4 bytecodes. Because of jump optimization code to handle first Python 2.3 and then 2.4 bytecodes. Because of
introduced in the CPython bytecode compiler at that time, various JUMP jump optimization introduced in the CPython bytecode compiler at that
instructions were classifed as going forward or backwards, and COME time, various JUMP instructions were classifed as going backwards, and
FROM instructions were introduced. See RELEASE-2.4-CHANGELOG.txt for COME FROM instructions were reintroduced. See
more details here. 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 Next we get to ["uncompyle" and
PyPI](https://pypi.python.org/pypi/uncompyle/1.1) and the era of PyPI](https://pypi.python.org/pypi/uncompyle/1.1) and the era of
public version control. In contrast to decompyle, uncompyle at least public version control. (Dan's code although not public used
in its final versions, runs only on Python 2.7. However it accepts [darcs](http://darcs.net/) for version control.
bytecode back to Python 2.5. Thomas Grainger is the package owner of
this, although Hartmut is still listed as the author. 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 The project exists not only on
[github](https://github.com/gstarnberger/uncompyle) but also on [github](https://github.com/gstarnberger/uncompyle) but also on

View File

@@ -33,9 +33,11 @@ def uncompyle(version, co, out=None, showasm=False, showast=False,
code_objects=code_objects) code_objects=code_objects)
except pysource.SourceWalkerError as e: except pysource.SourceWalkerError as e:
# deparsing failed # deparsing failed
print("\n")
if real_out != out: if real_out != out:
print("\n", file=real_out)
print(e, file=real_out) print(e, file=real_out)
raise
def uncompyle_file(filename, outstream=None, showasm=False, showast=False, def uncompyle_file(filename, outstream=None, showasm=False, showast=False,

View File

@@ -27,13 +27,21 @@ class Scanner27(scan.Scanner):
def disassemble(self, co, classname=None, code_objects={}): 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 The main part of this procedure is modelled after
dis.disassemble(). dis.disassemble().
""" """
# import dis; dis.disassemble(co) # DEBUG # import dis; dis.disassemble(co) # DEBUG
rv = []
# Container for tokens
tokens = []
customize = {} customize = {}
Token = self.Token # shortcut Token = self.Token # shortcut
self.code = array('B', co.co_code) self.code = array('B', co.co_code)
@@ -125,7 +133,7 @@ class Scanner27(scan.Scanner):
if offset in cf: if offset in cf:
k = 0 k = 0
for j in cf[offset]: 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))) offset="%s_%d" % (offset, k)))
k += 1 k += 1
@@ -211,10 +219,10 @@ class Scanner27(scan.Scanner):
linestart = None linestart = None
if offset not in replace: if offset not in replace:
rv.append(Token(op_name, oparg, pattr, offset, linestart)) tokens.append(Token(op_name, oparg, pattr, offset, linestart))
else: else:
rv.append(Token(replace[offset], oparg, pattr, offset, linestart)) tokens.append(Token(replace[offset], oparg, pattr, offset, linestart))
return rv, customize return tokens, customize
def build_stmt_indices(self): def build_stmt_indices(self):
code = self.code code = self.code

View File

@@ -1,4 +1,7 @@
# Copyright (c) 2015, 2016 by Rocky Bernstein # 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 Python 3 Generic bytecode scanner/deparser
@@ -49,6 +52,16 @@ class Scanner3(scan.Scanner):
## FIXME opnames should be moved to init ## FIXME opnames should be moved to init
def disassemble3(self, co, opnames, classname=None, code_objects={}): 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 self.opnames = opnames # will eventually disasppear

View File

@@ -203,8 +203,8 @@ def cmp_code_objects(version, code_obj1, code_obj2, name=''):
JUMP_OPs = list(scan.JUMP_OPs) + ['JUMP_BACK'] JUMP_OPs = list(scan.JUMP_OPs) + ['JUMP_BACK']
# use changed Token class # use changed Token class
# we (re)set this here to save exception handling, # We (re)set this here to save exception handling,
# which would get 'unubersichtlich' # which would get confusing.
scanner.setTokenClass(Token) scanner.setTokenClass(Token)
try: try:
# disassemble both code-objects # disassemble both code-objects