scanner3: Python 2.6 compatibility: change set initializations. Get rid

of * import
opcode_*: only a little of the much-needed larger cleanup
Makefile: remove 3.x bytecode checking from Python 2.x for now. DRY
Makefile a little bit (but more is needed)
This commit is contained in:
rocky
2015-12-29 08:23:44 -05:00
parent 226f3c7e63
commit 34841abe14
7 changed files with 38 additions and 49 deletions

View File

@@ -86,11 +86,7 @@ Known Bugs/Restrictions
-----------------------
Python 2 deparsing is probably as solid as the various versions of
uncompyle2. Python 3 deparsing is not as solid. Using Python 2 to
deparse Python 3 has severe limitations, due to byte code format
differences and the current inablity to retrieve code object fields across
different Python versions. (I envy the pycdc C++ code which doesn't have such
problems because they live totally outside of Python.)
uncompyle2. Python 3 deparsing is okay but not as solid.
See Also
--------

View File

@@ -19,28 +19,28 @@ check:
@$(PYTHON) -V && PYTHON_VERSION=`$(PYTHON) -V 2>&1 | cut -d ' ' -f 2 | cut -d'.' -f1,2`; \
$(MAKE) check-$$PYTHON_VERSION
#: Run working tests from Python 2.6
check-2.6: check-bytecode-2.7 check-bytecode-2.5
$(PYTHON) test_pythonlib.py --bytecode-2.6 --verify $(COMPILE)
#: Run working tests from Python 2.7
check-2.7: check-bytecode check-2.7-ok
#: Run working tests from Python 2.6 or 2.7
check-2.6 check-2.7: check-bytecode-2 check-2.7-ok
#: Run working tests from Python 3.3
check-3.3: check-bytecode-3.3 check-bytecode-2.7
check-3.3: check-bytecode
$(PYTHON) test_pythonlib.py --bytecode-3.3 --verify $(COMPILE)
#: Run working tests from Python 3.4
check-3.4: check-bytecode-2.7 check-bytecode-3.2
$(PYTHON) test_pythonlib.py --bytecode-3.4 --ok-2.7 --verify $(COMPILE)
check-3.4: check-bytecode check-2.7-ok
#: Check deparsing only, but from a different Python version
check-disasm:
$(PYTHON) dis-compare.py
#: Check deparsing bytecode only
check-bytecode-2:
$(PYTHON) test_pythonlib.py --bytecode-2.5 --bytecode-2.6 --bytecode-2.7
#: Check deparsing bytecode only
check-bytecode:
$(PYTHON) test_pythonlib.py --bytecode-2.5 --bytecode-2.7 --bytecode-3.2
$(PYTHON) test_pythonlib.py --bytecode-2.5 --bytecode-2.6 --bytecode-2.7 \
--bytecode-3.2 --bytecode-3.3 --bytecode-3.4
#: Check deparsing Python 2.5
check-bytecode-2.5:

View File

@@ -7,10 +7,6 @@ This is a superset of Python 3.4's opcode.py with some opcodes that simplify
parsing and semantic interpretation.
"""
__all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs",
"haslocal", "hascompare", "hasfree", "opname", "opmap",
"HAVE_ARGUMENT", "EXTENDED_ARG"]
cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is',
'is not', 'exception match', 'BAD')
@@ -21,6 +17,7 @@ hasjabs = []
haslocal = []
hascompare = []
hasfree = []
hasnargs = []
opmap = {}
opname = [''] * 256
@@ -179,6 +176,7 @@ haslocal.append(126)
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
def_op('CALL_FUNCTION', 131) # #args + (#kwargs << 8)
hasnargs.append(131)
def_op('MAKE_FUNCTION', 132) # Number of args with default values
def_op('BUILD_SLICE', 133) # Number of items
def_op('MAKE_CLOSURE', 134)
@@ -192,8 +190,11 @@ def_op('DELETE_DEREF', 138)
hasfree.append(138)
def_op('CALL_FUNCTION_VAR', 140) # #args + (#kwargs << 8)
hasnargs.append(140)
def_op('CALL_FUNCTION_KW', 141) # #args + (#kwargs << 8)
hasnargs.append(141)
def_op('CALL_FUNCTION_VAR_KW', 142) # #args + (#kwargs << 8)
hasnargs.append(142)
jrel_op('SETUP_WITH', 143)

View File

@@ -7,12 +7,6 @@ This is a superset of Python 3.3's opcode.py with some opcodes that simplify
parsing and semantic interpretation.
"""
# Note: this should look exactly like Python 3.4's opcode.py
__all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs",
"haslocal", "hascompare", "hasfree", "opname", "opmap",
"HAVE_ARGUMENT", "EXTENDED_ARG"]
cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is',
'is not', 'exception match', 'BAD')

View File

@@ -7,10 +7,6 @@ This is a superset of Python 3.4's opcode.py with some opcodes that simplify
parsing and semantic interpretation.
"""
__all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs",
"haslocal", "hascompare", "hasfree", "opname", "opmap",
"HAVE_ARGUMENT", "EXTENDED_ARG", "hasnargs"]
cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is',
'is not', 'exception match', 'BAD')

View File

@@ -18,8 +18,10 @@ from uncompyle6 import PYTHON_VERSION, PYTHON3
# Get all the opcodes into globals
globals().update(dis.opmap)
from uncompyle6.opcodes.opcode_33 import *
import uncompyle6.opcodes.opcode_33 as op3
globals().update(op3.opmap)
import uncompyle6.scanner as scan
class Code3:
@@ -122,23 +124,23 @@ class Scanner3(scan.Scanner):
jump_idx = 0
for jump_offset in jump_targets[offset]:
tokens.append(Token('COME_FROM', None, repr(jump_offset),
offset='{}_{}'.format(offset, jump_idx)))
offset='%s_%s' % (offset, jump_idx)))
jump_idx += 1
pass
pass
op = code[offset]
op_name = opname[op]
op_name = op3.opname[op]
oparg = None; pattr = None
if op >= HAVE_ARGUMENT:
if op >= op3.HAVE_ARGUMENT:
oparg = self.get_argument(offset) + extended_arg
extended_arg = 0
if op == EXTENDED_ARG:
if op == op3.EXTENDED_ARG:
extended_arg = oparg * scan.L65536
continue
if op in hasconst:
if op in op3.hasconst:
const = co.co_consts[oparg]
if not PYTHON3 and isinstance(const, str):
if const in code_objects:
@@ -168,17 +170,17 @@ class Scanner3(scan.Scanner):
pattr = '<code_object ' + const.co_name + '>'
else:
pattr = const
elif op in hasname:
elif op in op3.hasname:
pattr = names[oparg]
elif op in hasjrel:
elif op in op3.hasjrel:
pattr = repr(offset + 3 + oparg)
elif op in hasjabs:
elif op in op3.hasjabs:
pattr = repr(oparg)
elif op in haslocal:
elif op in op3.haslocal:
pattr = varnames[oparg]
elif op in hascompare:
pattr = cmp_op[oparg]
elif op in hasfree:
elif op in op3.hascompare:
pattr = op3.cmp_op[oparg]
elif op in op3.hasfree:
pattr = free[oparg]
if op in (BUILD_LIST, BUILD_TUPLE, BUILD_SET, BUILD_SLICE,
@@ -338,7 +340,7 @@ class Scanner3(scan.Scanner):
start = 0
end = codelen = len(code)
statement_opcodes = {
statement_opcodes = set([
SETUP_LOOP, BREAK_LOOP, CONTINUE_LOOP,
SETUP_FINALLY, END_FINALLY, SETUP_EXCEPT, SETUP_WITH,
POP_BLOCK, STORE_FAST, DELETE_FAST, STORE_DEREF,
@@ -346,15 +348,15 @@ class Scanner3(scan.Scanner):
STORE_ATTR, DELETE_ATTR, STORE_SUBSCR, DELETE_SUBSCR,
RETURN_VALUE, RAISE_VARARGS, POP_TOP, PRINT_EXPR,
JUMP_ABSOLUTE
}
])
statement_opcode_sequences = [(POP_JUMP_IF_FALSE, JUMP_FORWARD), (POP_JUMP_IF_FALSE, JUMP_ABSOLUTE),
(POP_JUMP_IF_TRUE, JUMP_FORWARD), (POP_JUMP_IF_TRUE, JUMP_ABSOLUTE)]
designator_ops = {
designator_ops = set([
STORE_FAST, STORE_NAME, STORE_GLOBAL, STORE_DEREF, STORE_ATTR,
STORE_SUBSCR, UNPACK_SEQUENCE, JUMP_ABSOLUTE
}
])
# Compose preliminary list of indices with statements,
# using plain statement opcodes

View File

@@ -11,9 +11,9 @@ from __future__ import print_function
import uncompyle6.scanners.scanner3 as scan3
import uncompyle6.opcodes.opcode_34
import uncompyle6.opcodes.opcode_32
# verify uses JUMP_OPs from here
JUMP_OPs = uncompyle6.opcodes.opcode_34.JUMP_OPs
JUMP_OPs = uncompyle6.opcodes.opcode_32.JUMP_OPs
class Scanner32(scan3.Scanner3):