diff --git a/test/Makefile b/test/Makefile index 08c26c93..0fb70067 100644 --- a/test/Makefile +++ b/test/Makefile @@ -51,7 +51,7 @@ check-bytecode-3: #: Check deparsing bytecode that works running Python 2 and Python 3 check-bytecode: check-bytecode-3 - $(PYTHON) test_pythonlib.py --bytecode-2.5 --bytecode-2.6 --bytecode-2.7 + $(PYTHON) test_pythonlib.py --bytecode-2.4 --bytecode-2.5 --bytecode-2.6 --bytecode-2.7 #: Check deparsing Python 2.3 check-bytecode-2.3: diff --git a/uncompyle6/scanner.py b/uncompyle6/scanner.py index bc8aff57..d10ad5d8 100755 --- a/uncompyle6/scanner.py +++ b/uncompyle6/scanner.py @@ -24,7 +24,7 @@ from uncompyle6.scanners.tok import Token # The byte code versions we support if PYTHON3: # Need to work out Python 2.3. ord's in PYTHON3 - PYTHON_VERSIONS = (2.5, 2.6, 2.7, 3.2, 3.3, 3.4, 3.5) + PYTHON_VERSIONS = (2.4, 2.5, 2.6, 2.7, 3.2, 3.3, 3.4, 3.5) else: PYTHON_VERSIONS = (2.3, 2.4, 2.5, 2.6, 2.7, 3.2, 3.3, 3.4, 3.5) diff --git a/uncompyle6/scanners/scanner24.py b/uncompyle6/scanners/scanner24.py index 48253809..f2e86420 100755 --- a/uncompyle6/scanners/scanner24.py +++ b/uncompyle6/scanners/scanner24.py @@ -8,62 +8,20 @@ information for later use in deparsing. """ import uncompyle6.scanners.scanner25 as scan -import uncompyle6.scanners.scanner2 as scan2 # bytecode verification, verify(), uses JUMP_OPs from here from xdis.opcodes import opcode_24 JUMP_OPs = opcode_24.JUMP_OPs -# We base this off of 2.6 instead of the other way around +# We base this off of 2.5 instead of the other way around # because we cleaned things up this way. # The history is that 2.7 support is the cleanest, # then from that we got 2.6 and so on. class Scanner24(scan.Scanner25): def __init__(self, show_asm): - scan2.Scanner2.__init__(self, 2.4, show_asm) - self.stmt_opcodes = frozenset([ - self.opc.SETUP_LOOP, self.opc.BREAK_LOOP, - self.opc.SETUP_FINALLY, self.opc.END_FINALLY, - self.opc.SETUP_EXCEPT, self.opc.POP_BLOCK, - self.opc.STORE_FAST, self.opc.DELETE_FAST, - self.opc.STORE_DEREF, self.opc.STORE_GLOBAL, - self.opc.DELETE_GLOBAL, self.opc.STORE_NAME, - self.opc.DELETE_NAME, self.opc.STORE_ATTR, - self.opc.DELETE_ATTR, self.opc.STORE_SUBSCR, - self.opc.DELETE_SUBSCR, self.opc.RETURN_VALUE, - self.opc.RAISE_VARARGS, self.opc.POP_TOP, - self.opc.PRINT_EXPR, self.opc.PRINT_ITEM, - self.opc.PRINT_NEWLINE, self.opc.PRINT_ITEM_TO, - self.opc.PRINT_NEWLINE_TO, self.opc.CONTINUE_LOOP, - self.opc.JUMP_ABSOLUTE, self.opc.EXEC_STMT, - ]) - - # "setup" opcodes - self.setup_ops = frozenset([ - self.opc.SETUP_EXCEPT, self.opc.SETUP_FINALLY, - ]) - - # opcodes with expect a variable number pushed values whose - # count is in the opcode. For parsing we generally change the - # opcode name to include that number. - self.varargs_ops = frozenset([ - self.opc.BUILD_LIST, self.opc.BUILD_TUPLE, - self.opc.BUILD_SLICE, self.opc.UNPACK_SEQUENCE, - self.opc.MAKE_FUNCTION, self.opc.CALL_FUNCTION, - self.opc.MAKE_CLOSURE, self.opc.CALL_FUNCTION_VAR, - self.opc.CALL_FUNCTION_KW, self.opc.CALL_FUNCTION_VAR_KW, - self.opc.DUP_TOPX, self.opc.RAISE_VARARGS]) - - # opcodes that store values into a variable - self.designator_ops = frozenset([ - self.opc.STORE_FAST, self.opc.STORE_NAME, - self.opc.STORE_GLOBAL, self.opc.STORE_DEREF, self.opc.STORE_ATTR, - self.opc.STORE_SLICE_0, self.opc.STORE_SLICE_1, self.opc.STORE_SLICE_2, - self.opc.STORE_SLICE_3, self.opc.STORE_SUBSCR, self.opc.UNPACK_SEQUENCE, - self.opc.JA - ]) - # Python 2.7 has POP_JUMP_IF_{TRUE,FALSE}_OR_POP but < 2.7 doesn't - # Add an empty set make processing more uniform. - self.pop_jump_if_or_pop = frozenset([]) + scan.Scanner25.__init__(self, show_asm) + # These are the only differences in initialization between + # 2.4, 2.5 and 2.6 + self.version = 2.4 self.genexpr_name = ''; return diff --git a/uncompyle6/scanners/scanner25.py b/uncompyle6/scanners/scanner25.py index dbd3f180..a11015a2 100755 --- a/uncompyle6/scanners/scanner25.py +++ b/uncompyle6/scanners/scanner25.py @@ -8,7 +8,6 @@ information for later use in deparsing. """ import uncompyle6.scanners.scanner26 as scan -import uncompyle6.scanners.scanner2 as scan2 # bytecode verification, verify(), uses JUMP_OPs from here from xdis.opcodes import opcode_25 @@ -20,49 +19,8 @@ JUMP_OPs = opcode_25.JUMP_OPs # then from that we got 2.6 and so on. class Scanner25(scan.Scanner26): def __init__(self, show_asm): - scan2.Scanner2.__init__(self, 2.5, show_asm) - self.stmt_opcodes = frozenset([ - self.opc.SETUP_LOOP, self.opc.BREAK_LOOP, - self.opc.SETUP_FINALLY, self.opc.END_FINALLY, - self.opc.SETUP_EXCEPT, self.opc.POP_BLOCK, - self.opc.STORE_FAST, self.opc.DELETE_FAST, - self.opc.STORE_DEREF, self.opc.STORE_GLOBAL, - self.opc.DELETE_GLOBAL, self.opc.STORE_NAME, - self.opc.DELETE_NAME, self.opc.STORE_ATTR, - self.opc.DELETE_ATTR, self.opc.STORE_SUBSCR, - self.opc.DELETE_SUBSCR, self.opc.RETURN_VALUE, - self.opc.RAISE_VARARGS, self.opc.POP_TOP, - self.opc.PRINT_EXPR, self.opc.PRINT_ITEM, - self.opc.PRINT_NEWLINE, self.opc.PRINT_ITEM_TO, - self.opc.PRINT_NEWLINE_TO, self.opc.CONTINUE_LOOP, - self.opc.JUMP_ABSOLUTE, self.opc.EXEC_STMT, - ]) - - # "setup" opcodes - self.setup_ops = frozenset([ - self.opc.SETUP_EXCEPT, self.opc.SETUP_FINALLY, - ]) - - # opcodes with expect a variable number pushed values whose - # count is in the opcode. For parsing we generally change the - # opcode name to include that number. - self.varargs_ops = frozenset([ - self.opc.BUILD_LIST, self.opc.BUILD_TUPLE, - self.opc.BUILD_SLICE, self.opc.UNPACK_SEQUENCE, - self.opc.MAKE_FUNCTION, self.opc.CALL_FUNCTION, - self.opc.MAKE_CLOSURE, self.opc.CALL_FUNCTION_VAR, - self.opc.CALL_FUNCTION_KW, self.opc.CALL_FUNCTION_VAR_KW, - self.opc.DUP_TOPX, self.opc.RAISE_VARARGS]) - - # opcodes that store values into a variable - self.designator_ops = frozenset([ - self.opc.STORE_FAST, self.opc.STORE_NAME, - self.opc.STORE_GLOBAL, self.opc.STORE_DEREF, self.opc.STORE_ATTR, - self.opc.STORE_SLICE_0, self.opc.STORE_SLICE_1, self.opc.STORE_SLICE_2, - self.opc.STORE_SLICE_3, self.opc.STORE_SUBSCR, self.opc.UNPACK_SEQUENCE, - self.opc.JA - ]) - # Python 2.7 has POP_JUMP_IF_{TRUE,FALSE}_OR_POP but < 2.7 doesn't - # Add an empty set make processing more uniform. - self.pop_jump_if_or_pop = frozenset([]) + # There are no differences in initialization between + # 2.5 and 2.6 + scan.Scanner26.__init__(self, show_asm) + self.version = 2.5 return diff --git a/uncompyle6/scanners/scanner26.py b/uncompyle6/scanners/scanner26.py index b199b980..904cc098 100755 --- a/uncompyle6/scanners/scanner26.py +++ b/uncompyle6/scanners/scanner26.py @@ -1,7 +1,6 @@ # Copyright (c) 2015, 2016 by Rocky Bernstein # Copyright (c) 2005 by Dan Pascu # Copyright (c) 2000-2002 by hartmut Goebel -# Copyright (c) 1999 John Aycock """ Python 2.6 bytecode scanner @@ -100,7 +99,8 @@ class Scanner26(scan.Scanner2): n = self.setup_code(co) - self.build_lines_data(co, n-1) + self.build_lines_data(co, n) + self.build_prev_op(n) # linestarts contains block code adresses (addr,block) self.linestarts = list(findlinestarts(co)) @@ -123,17 +123,10 @@ class Scanner26(scan.Scanner2): varnames = co.co_varnames self.names = names - # list of instruction to remove/add or change to match with bytecode 2.7 - self.toChange = [] - # Rocky: the restructure code isn't adjusting linestarts - # and this causes problems - # self.restructBytecode() codelen = len(self.code) - self.build_prev_op(codelen) - self.load_asserts = set() - for i in self.op_range(0, codelen): + for i in self.op_range(0, n): if (self.code[i] == self.opc.JUMP_IF_TRUE and i + 4 < codelen and self.code[i+3] == self.opc.POP_TOP and @@ -233,11 +226,6 @@ class Scanner26(scan.Scanner2): pattr = self.opc.cmp_op[oparg] elif op in self.opc.hasfree: pattr = free[oparg] - if offset in self.toChange: - if (self.code[offset] == self.opc.JA and - self.code[oparg] == self.opc.WITH_CLEANUP): - op_name = 'SETUP_WITH' - cf[oparg] = cf.get(oparg, []) + [offset] if op in self.varargs_ops: # CE - Hack for >= 2.5 # Now all values loaded via LOAD_CLOSURE are packed into