# Copyright (c) 2016 by Rocky Bernstein """ Python 2.4 bytecode scanner/deparser This overlaps Python's 2.4's dis module, but it can be run from Python 3 and other versions of Python. Also, we save token 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 # 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([]) return