Merge branch 'master' into python-2.4

This commit is contained in:
rocky
2020-07-06 18:47:39 -04:00
9 changed files with 49 additions and 26 deletions

View File

@@ -154,11 +154,7 @@ provide the input command and the output from that, please give:
## But I don't *have* the source code!
Sure, I get it. No problem. There is Python assembly code on parse
errors, so simply by hand decompile that. To get a full disassembly,
use `pydisasm` from the [xdis](https://pypi.python.org/pypi/xdis)
package. Opcodes are described in the documentation for
the [dis](https://docs.python.org/3.6/library/dis.html) module.
There is Python assembly code on parse errors, so simply by hand decompile that. To get a full disassembly, use `pydisasm` from the [xdis](https://pypi.python.org/pypi/xdis) package. Opcodes are described in the documentation for the[dis](https://docs.python.org/3.6/library/dis.html) module.
### But I don't *have* the source code and am incapable of figuring how to do a hand disassembly!

View File

@@ -172,9 +172,9 @@ erroneous decompilation and report that.
Python support is pretty good for Python 2
There is some work to do on the lower end Python versions which is
more difficult for us to handle since we don't have a Python
interpreter for versions 1.6, and 2.0.
On the lower end of Python versions, decompilation seems pretty good although
we don't have any automated testing in place for Python's distributed tests.
Also, we don't have a Python interpreter for versions 1.6, and 2.0.
In the Python 3 series, Python support is is strongest around 3.4 or
3.3 and drops off as you move further away from those versions. Python
@@ -189,7 +189,7 @@ added. So in sum handling control flow by ad hoc means as is currently
done is worse.
Between Python 3.5, 3.6, 3.7 there have been major changes to the
:code:`MAKE_FUNCTION` and :code:`CALL_FUNCTION` instructions. Python
:code:`MAKE_FUNCTION` and :code:`CALL_FUNCTION` instructions.
Python 3.8 removes :code:`SETUP_LOOP`, :code:`SETUP_EXCEPT`,
:code:`BREAK_LOOP`, and :code:`CONTINUE_LOOP`, instructions which may

View File

@@ -5,6 +5,7 @@ import os, sys, py_compile
assert len(sys.argv) >= 2
version = sys.version[0:3]
vers = sys.version_info[:2]
if sys.argv[1] in ("--run", "-r"):
suffix = "_run"
py_source = sys.argv[2:]
@@ -20,6 +21,9 @@ for path in py_source:
cfile = "bytecode_%s%s/%s" % (version, suffix, short) + "c"
print("byte-compiling %s to %s" % (path, cfile))
optimize = 2
py_compile.compile(path, cfile, optimize=optimize)
if isinstance(version, str) or version >= (2, 6, 0):
if vers >= (3, 0):
py_compile.compile(path, cfile, optimize=optimize)
else:
py_compile.compile(path, cfile)
if vers >= (2, 6):
os.system("../bin/uncompyle6 -a -T %s" % cfile)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,17 @@
# Adapted from 1.4 anydbm
"""This program is self-checking!"""
def scan(items):
for i in items:
try:
5 / i
except:
continue
else:
break
else:
return 2
return i
assert scan((0, 1)) == 1
assert scan((0, 0)) == 2
assert scan((3, 2, 1)) == 3

View File

@@ -93,8 +93,8 @@ class Python26Parser(Python2Parser):
cf_jb_cf_pop ::= _come_froms JUMP_BACK come_froms POP_TOP
bp_come_from ::= POP_BLOCK COME_FROM
jb_pb_come_from ::= JUMP_BACK bp_come_from
pb_come_from ::= POP_BLOCK COME_FROM
jb_pb_come_from ::= JUMP_BACK pb_come_from
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD COME_FROM POP_TOP
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD come_froms POP_TOP COME_FROM
@@ -148,7 +148,7 @@ class Python26Parser(Python2Parser):
while1stmt ::= SETUP_LOOP l_stmts_opt CONTINUE _come_froms
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jb_pop POP_BLOCK _come_froms
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jb_cf_pop bp_come_from
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jb_cf_pop pb_come_from
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt jb_cf_pop POP_BLOCK
whilestmt ::= SETUP_LOOP testexpr returns POP_BLOCK COME_FROM
@@ -412,11 +412,21 @@ class Python26Parser(Python2Parser):
# for t in range(first, last):
# print(tokens[t])
# print("=" * 30)
# FIXME: Figure out why this doesn't work on
# bytecode-1.4/anydbm.pyc
if self.version == 1.4:
return False
return tokens[last-1].off2int() > tokens[first].attr
# If the SETUP_LOOP jumps to the tokens[last] then
# this is a "for" not a "for else".
# However, in Python 2.2 and before there is a SET_LINENO
# instruction which might have gotten removed. So we need
# to account for that. bytecode-1.4/anydbm.pyc exhibits
# this behavior.
# Also we need to use the setup_loop instruction (not opcode)
# since the operand can be a relative offset rather than
# an absolute offset.
setup_inst = self.insts[self.offset2inst_index[tokens[first].offset]]
if self.version <= 2.2 and tokens[last] == "COME_FROM":
last += 1
return tokens[last-1].off2int() > setup_inst.argval
elif rule == ("ifstmt", ("testexpr", "_ifstmts_jump")):
for i in range(last-1, last-4, -1):
t = tokens[i]
@@ -434,10 +444,6 @@ class Python26Parser(Python2Parser):
ja_attr = ast[4].attr
return tokens[last].offset != ja_attr
elif lhs == 'try_except':
# FIXME: Figure out why this doesn't work on
# bytecode-1.4/anydbm.pyc
if self.version == 1.4:
return False
# We need to distingush try_except from tryelsestmt and we do that
# by checking the jump before the END_FINALLY
# If we have:

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2016-2019 Rocky Bernstein
# Copyright (c) 2016-2020 Rocky Bernstein
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
# Copyright (c) 2000-2002 by hartmut Goebel <hartmut@goebel.noris.de>
@@ -92,7 +92,7 @@ class Python27Parser(Python2Parser):
iflaststmtl ::= testexpr c_stmts
_ifstmts_jump ::= c_stmts_opt JUMP_FORWARD come_froms
bp_come_from ::= POP_BLOCK COME_FROM
pb_come_from ::= POP_BLOCK COME_FROM
# FIXME: Common with 3.0+
jmp_false ::= POP_JUMP_IF_FALSE
@@ -164,7 +164,7 @@ class Python27Parser(Python2Parser):
while1elsestmt ::= SETUP_LOOP l_stmts JUMP_BACK
else_suitel COME_FROM
while1stmt ::= SETUP_LOOP returns bp_come_from
while1stmt ::= SETUP_LOOP returns pb_come_from
while1stmt ::= SETUP_LOOP l_stmts_opt JUMP_BACK POP_BLOCK COME_FROM
whilestmt ::= SETUP_LOOP testexpr l_stmts_opt JUMP_BACK POP_BLOCK _come_froms