You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
69 lines
3.0 KiB
Python
Executable File
69 lines
3.0 KiB
Python
Executable File
# Copyright (c) 2015-2016 by Rocky Bernstein
|
|
"""
|
|
Python 2.5 bytecode scanner/deparser
|
|
|
|
This overlaps Python's 2.5'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.scanner26 as scan
|
|
import uncompyle6.scanners.scanner2 as scan2
|
|
|
|
# bytecode verification, verify(), uses JUMP_OPs from here
|
|
from xdis.opcodes import opcode_25
|
|
JUMP_OPs = opcode_25.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 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([])
|
|
return
|