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
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

View File

@@ -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,

View File

@@ -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

View File

@@ -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

View File

@@ -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