use totally xdis's opcodes

Needs xdis 1.1.0 or greater
This commit is contained in:
rocky
2016-05-31 19:53:17 -04:00
parent 3e5876dd03
commit 20768266b4
13 changed files with 42 additions and 879 deletions

View File

@@ -37,7 +37,7 @@ entry_points={
]}
ftp_url = None
install_requires = ['spark-parser >= 1.2.1',
'xdis >= 1.0.5']
'xdis >= 1.1.0']
license = 'MIT'
mailing_list = 'python-debugger@googlegroups.com'
modname = 'uncompyle6'

View File

@@ -1 +0,0 @@
*.pyc

View File

@@ -1,7 +0,0 @@
# Whatever it is you want to do, it should be forwarded to the
# to top-level irectories
PHONY=check all
all: check
%:
$(MAKE) -C ../.. $@

View File

@@ -1,190 +0,0 @@
"""
CPython 2.3 bytecode opcodes
This is used in scanner (bytecode disassembly) and parser (Python grammar).
This is a superset of Python 2.3's opcode.py with some opcodes that simplify
parsing and semantic interpretation.
"""
# FIXME: DRY this along the lines of opcode_3x.
cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is',
'is not', 'exception match', 'BAD')
hasconst = []
hasname = []
hasjrel = []
hasjabs = []
haslocal = []
hascompare = []
hasfree = []
opmap = {}
opname = [''] * 256
for op in range(256): opname[op] = '<%r>' % (op,)
del op
def def_op(name, op):
opname[op] = name
opmap[name] = op
def name_op(name, op):
def_op(name, op)
hasname.append(op)
def jrel_op(name, op):
def_op(name, op)
hasjrel.append(op)
def jabs_op(name, op):
def_op(name, op)
hasjabs.append(op)
# Instruction opcodes for compiled code
# Blank lines correspond to available opcodes
def_op('STOP_CODE', 0)
def_op('POP_TOP', 1)
def_op('ROT_TWO', 2)
def_op('ROT_THREE', 3)
def_op('DUP_TOP', 4)
def_op('ROT_FOUR', 5)
def_op('UNARY_POSITIVE', 10)
def_op('UNARY_NEGATIVE', 11)
def_op('UNARY_NOT', 12)
def_op('UNARY_CONVERT', 13)
def_op('UNARY_INVERT', 15)
def_op('BINARY_POWER', 19)
def_op('BINARY_MULTIPLY', 20)
def_op('BINARY_DIVIDE', 21)
def_op('BINARY_MODULO', 22)
def_op('BINARY_ADD', 23)
def_op('BINARY_SUBTRACT', 24)
def_op('BINARY_SUBSCR', 25)
def_op('BINARY_FLOOR_DIVIDE', 26)
def_op('BINARY_TRUE_DIVIDE', 27)
def_op('INPLACE_FLOOR_DIVIDE', 28)
def_op('INPLACE_TRUE_DIVIDE', 29)
def_op('SLICE+0', 30)
def_op('SLICE+1', 31)
def_op('SLICE+2', 32)
def_op('SLICE+3', 33)
def_op('STORE_SLICE+0', 40)
def_op('STORE_SLICE+1', 41)
def_op('STORE_SLICE+2', 42)
def_op('STORE_SLICE+3', 43)
def_op('DELETE_SLICE+0', 50)
def_op('DELETE_SLICE+1', 51)
def_op('DELETE_SLICE+2', 52)
def_op('DELETE_SLICE+3', 53)
def_op('INPLACE_ADD', 55)
def_op('INPLACE_SUBTRACT', 56)
def_op('INPLACE_MULTIPLY', 57)
def_op('INPLACE_DIVIDE', 58)
def_op('INPLACE_MODULO', 59)
def_op('STORE_SUBSCR', 60)
def_op('DELETE_SUBSCR', 61)
def_op('BINARY_LSHIFT', 62)
def_op('BINARY_RSHIFT', 63)
def_op('BINARY_AND', 64)
def_op('BINARY_XOR', 65)
def_op('BINARY_OR', 66)
def_op('INPLACE_POWER', 67)
def_op('GET_ITER', 68)
def_op('PRINT_EXPR', 70)
def_op('PRINT_ITEM', 71)
def_op('PRINT_NEWLINE', 72)
def_op('PRINT_ITEM_TO', 73)
def_op('PRINT_NEWLINE_TO', 74)
def_op('INPLACE_LSHIFT', 75)
def_op('INPLACE_RSHIFT', 76)
def_op('INPLACE_AND', 77)
def_op('INPLACE_XOR', 78)
def_op('INPLACE_OR', 79)
def_op('BREAK_LOOP', 80)
def_op('LOAD_LOCALS', 82)
def_op('RETURN_VALUE', 83)
def_op('IMPORT_STAR', 84)
def_op('EXEC_STMT', 85)
def_op('YIELD_VALUE', 86)
def_op('POP_BLOCK', 87)
def_op('END_FINALLY', 88)
def_op('BUILD_CLASS', 89)
HAVE_ARGUMENT = 90 # Opcodes from here have an argument:
name_op('STORE_NAME', 90) # Index in name list
name_op('DELETE_NAME', 91) # ""
def_op('UNPACK_SEQUENCE', 92) # Number of tuple items
jrel_op('FOR_ITER', 93)
name_op('STORE_ATTR', 95) # Index in name list
name_op('DELETE_ATTR', 96) # ""
name_op('STORE_GLOBAL', 97) # ""
name_op('DELETE_GLOBAL', 98) # ""
def_op('DUP_TOPX', 99) # number of items to duplicate
def_op('LOAD_CONST', 100) # Index in const list
hasconst.append(100)
name_op('LOAD_NAME', 101) # Index in name list
def_op('BUILD_TUPLE', 102) # Number of tuple items
def_op('BUILD_LIST', 103) # Number of list items
def_op('BUILD_MAP', 104) # Always zero for now
name_op('LOAD_ATTR', 105) # Index in name list
def_op('COMPARE_OP', 106) # Comparison operator
hascompare.append(106)
name_op('IMPORT_NAME', 107) # Index in name list
name_op('IMPORT_FROM', 108) # Index in name list
jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip
jrel_op('JUMP_IF_FALSE', 111) # ""
jrel_op('JUMP_IF_TRUE', 112) # ""
jabs_op('JUMP_ABSOLUTE', 113) # Target byte offset from beginning of code
name_op('LOAD_GLOBAL', 116) # Index in name list
jabs_op('CONTINUE_LOOP', 119) # Target address
jrel_op('SETUP_LOOP', 120) # Distance to target address
jrel_op('SETUP_EXCEPT', 121) # ""
jrel_op('SETUP_FINALLY', 122) # ""
def_op('LOAD_FAST', 124) # Local variable number
haslocal.append(124)
def_op('STORE_FAST', 125) # Local variable number
haslocal.append(125)
def_op('DELETE_FAST', 126) # Local variable number
haslocal.append(126)
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
def_op('CALL_FUNCTION', 131) # #args + (#kwargs << 8)
def_op('MAKE_FUNCTION', 132) # Number of args with default values
def_op('BUILD_SLICE', 133) # Number of items
def_op('MAKE_CLOSURE', 134)
def_op('LOAD_CLOSURE', 135)
hasfree.append(135)
def_op('LOAD_DEREF', 136)
hasfree.append(136)
def_op('STORE_DEREF', 137)
hasfree.append(137)
def_op('CALL_FUNCTION_VAR', 140) # #args + (#kwargs << 8)
def_op('CALL_FUNCTION_KW', 141) # #args + (#kwargs << 8)
def_op('CALL_FUNCTION_VAR_KW', 142) # #args + (#kwargs << 8)
def_op('EXTENDED_ARG', 143)
EXTENDED_ARG = 143
del def_op, name_op, jrel_op, jabs_op

View File

@@ -1,194 +0,0 @@
"""
CPython 2.4 bytecode opcodes
This is used in scanner (bytecode disassembly) and parser (Python grammar).
This is a superset of Python 2.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')
hasconst = []
hasname = []
hasjrel = []
hasjabs = []
haslocal = []
hascompare = []
hasfree = []
opmap = {}
opname = [''] * 256
for op in range(256): opname[op] = '<%r>' % (op,)
del op
def def_op(name, op):
opname[op] = name
opmap[name] = op
def name_op(name, op):
def_op(name, op)
hasname.append(op)
def jrel_op(name, op):
def_op(name, op)
hasjrel.append(op)
def jabs_op(name, op):
def_op(name, op)
hasjabs.append(op)
# Instruction opcodes for compiled code
# Blank lines correspond to available opcodes
def_op('STOP_CODE', 0)
def_op('POP_TOP', 1)
def_op('ROT_TWO', 2)
def_op('ROT_THREE', 3)
def_op('DUP_TOP', 4)
def_op('ROT_FOUR', 5)
def_op('NOP', 9)
def_op('UNARY_POSITIVE', 10)
def_op('UNARY_NEGATIVE', 11)
def_op('UNARY_NOT', 12)
def_op('UNARY_CONVERT', 13)
def_op('UNARY_INVERT', 15)
def_op('LIST_APPEND', 18)
def_op('BINARY_POWER', 19)
def_op('BINARY_MULTIPLY', 20)
def_op('BINARY_DIVIDE', 21)
def_op('BINARY_MODULO', 22)
def_op('BINARY_ADD', 23)
def_op('BINARY_SUBTRACT', 24)
def_op('BINARY_SUBSCR', 25)
def_op('BINARY_FLOOR_DIVIDE', 26)
def_op('BINARY_TRUE_DIVIDE', 27)
def_op('INPLACE_FLOOR_DIVIDE', 28)
def_op('INPLACE_TRUE_DIVIDE', 29)
def_op('SLICE+0', 30)
def_op('SLICE+1', 31)
def_op('SLICE+2', 32)
def_op('SLICE+3', 33)
def_op('STORE_SLICE+0', 40)
def_op('STORE_SLICE+1', 41)
def_op('STORE_SLICE+2', 42)
def_op('STORE_SLICE+3', 43)
def_op('DELETE_SLICE+0', 50)
def_op('DELETE_SLICE+1', 51)
def_op('DELETE_SLICE+2', 52)
def_op('DELETE_SLICE+3', 53)
def_op('INPLACE_ADD', 55)
def_op('INPLACE_SUBTRACT', 56)
def_op('INPLACE_MULTIPLY', 57)
def_op('INPLACE_DIVIDE', 58)
def_op('INPLACE_MODULO', 59)
def_op('STORE_SUBSCR', 60)
def_op('DELETE_SUBSCR', 61)
def_op('BINARY_LSHIFT', 62)
def_op('BINARY_RSHIFT', 63)
def_op('BINARY_AND', 64)
def_op('BINARY_XOR', 65)
def_op('BINARY_OR', 66)
def_op('INPLACE_POWER', 67)
def_op('GET_ITER', 68)
def_op('PRINT_EXPR', 70)
def_op('PRINT_ITEM', 71)
def_op('PRINT_NEWLINE', 72)
def_op('PRINT_ITEM_TO', 73)
def_op('PRINT_NEWLINE_TO', 74)
def_op('INPLACE_LSHIFT', 75)
def_op('INPLACE_RSHIFT', 76)
def_op('INPLACE_AND', 77)
def_op('INPLACE_XOR', 78)
def_op('INPLACE_OR', 79)
def_op('BREAK_LOOP', 80)
def_op('LOAD_LOCALS', 82)
def_op('RETURN_VALUE', 83)
def_op('IMPORT_STAR', 84)
def_op('EXEC_STMT', 85)
def_op('YIELD_VALUE', 86)
def_op('POP_BLOCK', 87)
def_op('END_FINALLY', 88)
def_op('BUILD_CLASS', 89)
HAVE_ARGUMENT = 90 # Opcodes from here have an argument:
name_op('STORE_NAME', 90) # Index in name list
name_op('DELETE_NAME', 91) # ""
def_op('UNPACK_SEQUENCE', 92) # Number of tuple items
jrel_op('FOR_ITER', 93)
name_op('STORE_ATTR', 95) # Index in name list
name_op('DELETE_ATTR', 96) # ""
name_op('STORE_GLOBAL', 97) # ""
name_op('DELETE_GLOBAL', 98) # ""
def_op('DUP_TOPX', 99) # number of items to duplicate
def_op('LOAD_CONST', 100) # Index in const list
hasconst.append(100)
name_op('LOAD_NAME', 101) # Index in name list
def_op('BUILD_TUPLE', 102) # Number of tuple items
def_op('BUILD_LIST', 103) # Number of list items
def_op('BUILD_MAP', 104) # Always zero for now
name_op('LOAD_ATTR', 105) # Index in name list
def_op('COMPARE_OP', 106) # Comparison operator
hascompare.append(106)
name_op('IMPORT_NAME', 107) # Index in name list
name_op('IMPORT_FROM', 108) # Index in name list
jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip
jrel_op('JUMP_IF_FALSE', 111) # ""
jrel_op('JUMP_IF_TRUE', 112) # ""
jabs_op('JUMP_ABSOLUTE', 113) # Target byte offset from beginning of code
name_op('LOAD_GLOBAL', 116) # Index in name list
jabs_op('CONTINUE_LOOP', 119) # Target address
jrel_op('SETUP_LOOP', 120) # Distance to target address
jrel_op('SETUP_EXCEPT', 121) # ""
jrel_op('SETUP_FINALLY', 122) # ""
def_op('LOAD_FAST', 124) # Local variable number
haslocal.append(124)
def_op('STORE_FAST', 125) # Local variable number
haslocal.append(125)
def_op('DELETE_FAST', 126) # Local variable number
haslocal.append(126)
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
def_op('CALL_FUNCTION', 131) # #args + (#kwargs << 8)
def_op('MAKE_FUNCTION', 132) # Number of args with default values
def_op('BUILD_SLICE', 133) # Number of items
def_op('MAKE_CLOSURE', 134)
def_op('LOAD_CLOSURE', 135)
hasfree.append(135)
def_op('LOAD_DEREF', 136)
hasfree.append(136)
def_op('STORE_DEREF', 137)
hasfree.append(137)
def_op('CALL_FUNCTION_VAR', 140) # #args + (#kwargs << 8)
def_op('CALL_FUNCTION_KW', 141) # #args + (#kwargs << 8)
def_op('CALL_FUNCTION_VAR_KW', 142) # #args + (#kwargs << 8)
def_op('EXTENDED_ARG', 143)
EXTENDED_ARG = 143
del def_op, name_op, jrel_op, jabs_op

View File

@@ -1,202 +0,0 @@
"""
CPython 2.5 bytecode opcodes
This is used in scanner (bytecode disassembly) and parser (Python grammar).
This is a superset of Python 2.5's opcode.py with some opcodes that simplify
parsing and semantic interpretation.
"""
# FIXME: DRY this along the lines of opcode_3x.
cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is',
'is not', 'exception match', 'BAD')
hasconst = []
hasname = []
hasjrel = []
hasjabs = []
haslocal = []
hascompare = []
hasfree = []
hasArgumentExtended = []
PJIF = PJIT = JA = JF = 0
opmap = {}
opname = [''] * 256
for op in range(256): opname[op] = '<%r>' % (op,)
del op
def def_op(name, op):
opname[op] = name
opmap[name] = op
globals().update({name: op})
def name_op(name, op):
def_op(name, op)
hasname.append(op)
def jrel_op(name, op):
def_op(name, op)
hasjrel.append(op)
def jabs_op(name, op):
def_op(name, op)
hasjabs.append(op)
def def_extArg(name, op):
def_op(name, op)
hasArgumentExtended.append(op)
def updateGlobal():
globals().update({'PJIF': opmap['JUMP_IF_FALSE']})
globals().update({'PJIT': opmap['JUMP_IF_TRUE']})
globals().update({'JA': opmap['JUMP_ABSOLUTE']})
globals().update({'JF': opmap['JUMP_FORWARD']})
globals().update(dict([(k.replace('+', '_'), v) for (k, v) in opmap.items()]))
globals().update({'JUMP_OPs': map(lambda op: opname[op], hasjrel + hasjabs)})
# Instruction opcodes for compiled code
# Blank lines correspond to available opcodes
def_op('STOP_CODE', 0) # 0
def_op('POP_TOP', 1) # 15
def_op('ROT_TWO', 2) # 59
def_op('ROT_THREE', 3) # 60
def_op('DUP_TOP', 4) # 13
def_op('ROT_FOUR', 5) # 49
def_op('NOP', 9) # 53
def_op('UNARY_POSITIVE', 10) # 48
def_op('UNARY_NEGATIVE', 11) # 54
def_op('UNARY_NOT', 12) # 38
def_op('UNARY_CONVERT', 13) # 25
def_op('UNARY_INVERT', 15) # 34
def_extArg('LIST_APPEND', 18) # 68
def_op('BINARY_POWER', 19) # 28
def_op('BINARY_MULTIPLY', 20) # 36
def_op('BINARY_DIVIDE', 21) # 12
def_op('BINARY_MODULO', 22) # 41
def_op('BINARY_ADD', 23) # 52
def_op('BINARY_SUBTRACT', 24) # 55
def_op('BINARY_SUBSCR', 25) # 4
def_op('BINARY_FLOOR_DIVIDE', 26) # 43
def_op('BINARY_TRUE_DIVIDE', 27) # 5
def_op('INPLACE_FLOOR_DIVIDE', 28) # 32
def_op('INPLACE_TRUE_DIVIDE', 29) # 30
def_op('SLICE+0', 30) # 16
def_op('SLICE+1', 31) # 17
def_op('SLICE+2', 32) # 18
def_op('SLICE+3', 33) # 19
def_op('STORE_SLICE+0', 40) # 61
def_op('STORE_SLICE+1', 41) # 62
def_op('STORE_SLICE+2', 42) # 63
def_op('STORE_SLICE+3', 43) # 64
def_op('DELETE_SLICE+0', 50) # 44
def_op('DELETE_SLICE+1', 51) # 45
def_op('DELETE_SLICE+2', 52) # 46
def_op('DELETE_SLICE+3', 53) # 47
def_op('INPLACE_ADD', 55) # 6
def_op('INPLACE_SUBTRACT', 56) # 29
def_op('INPLACE_MULTIPLY', 57) # 8
def_op('INPLACE_DIVIDE', 58) # 27
def_op('INPLACE_MODULO', 59) # 3
def_op('STORE_SUBSCR', 60) # 31
def_op('DELETE_SUBSCR', 61) # 69
def_op('BINARY_LSHIFT', 62) # 7
def_op('BINARY_RSHIFT', 63) # 22
def_op('BINARY_AND', 64) # 50
def_op('BINARY_XOR', 65) # 21
def_op('BINARY_OR', 66) # 2
def_op('INPLACE_POWER', 67) # 57
def_op('GET_ITER', 68) # 39
def_op('PRINT_EXPR', 70) # 20
def_op('PRINT_ITEM', 71) # 9
def_op('PRINT_NEWLINE', 72) # 14
def_op('PRINT_ITEM_TO', 73) # 33
def_op('PRINT_NEWLINE_TO', 74) # 35
def_op('INPLACE_LSHIFT', 75) # 11
def_op('INPLACE_RSHIFT', 76) # 58
def_op('INPLACE_AND', 77) # 24
def_op('INPLACE_XOR', 78) # 23
def_op('INPLACE_OR', 79) # 10
def_op('BREAK_LOOP', 80) # 40
def_op('WITH_CLEANUP', 81) # 37
def_op('LOAD_LOCALS', 82) # 51
def_op('RETURN_VALUE', 83) # 66
def_op('IMPORT_STAR', 84) # 56
def_op('EXEC_STMT', 85) # 65
def_op('YIELD_VALUE', 86) # 26
def_op('POP_BLOCK', 87) # 1
def_op('END_FINALLY', 88) # 67
def_op('BUILD_CLASS', 89) # 42
HAVE_ARGUMENT = 90 # 70 # Opcodes from here have an argument:
name_op('STORE_NAME', 90) # 95 # Index in name list
name_op('DELETE_NAME', 91) # 94 # ""
def_op('UNPACK_SEQUENCE', 92) # 93 # Number of tuple items
jrel_op('FOR_ITER', 93) # 81
name_op('STORE_ATTR', 95) # 84 # Index in name list
name_op('DELETE_ATTR', 96) # 87 # ""
name_op('STORE_GLOBAL', 97) # 105 # ""
name_op('DELETE_GLOBAL', 98) # 98 # ""
def_op('DUP_TOPX', 99) # 104 # number of items to duplicate
def_op('LOAD_CONST', 100) # 72 # Index in const list
hasconst.append(100) # 72
name_op('LOAD_NAME', 101) # 79 # Index in name list
def_op('BUILD_TUPLE', 102) # 80 # Number of tuple items
def_op('BUILD_LIST', 103) # 107 # Number of list items
def_op('BUILD_MAP', 104) # 78 # Always zero for now
name_op('LOAD_ATTR', 105) # 86 # Index in name list
def_op('COMPARE_OP', 106) # 101 # Comparison operator
hascompare.append(106) # 101
name_op('IMPORT_NAME', 107) # 88 # Index in name list
name_op('IMPORT_FROM', 108) # 89 # Index in name list
jrel_op('JUMP_FORWARD', 110) # 73 # Number of bytes to skip
jabs_op('JUMP_IF_FALSE', 111) # 83 # ""
jabs_op('JUMP_IF_TRUE', 112) # 90 # ""
jabs_op('JUMP_ABSOLUTE', 113) # 103 # Target byte offset from beginning of code
name_op('LOAD_GLOBAL', 116) # 70 # Index in name list
jabs_op('CONTINUE_LOOP', 119) # 96 # Target address
jrel_op('SETUP_LOOP', 120) # 74 # Distance to target address
jrel_op('SETUP_EXCEPT', 121) # 75 # ""
jrel_op('SETUP_FINALLY', 122) # 106 # ""
def_op('LOAD_FAST', 124) # 92 # Local variable number
haslocal.append(124) # 92
def_op('STORE_FAST', 125) # 82 # Local variable number
haslocal.append(125) # 82
def_op('DELETE_FAST', 126) # 71 # Local variable number
haslocal.append(126) # 71
def_op('RAISE_VARARGS', 130) # 91 # Number of raise arguments (1, 2, or 3)
def_op('CALL_FUNCTION', 131) # 102 # #args + (#kwargs << 8)
def_op('MAKE_FUNCTION', 132) # 76 # Number of args with default values
def_op('BUILD_SLICE', 133) # 77 # Number of items
def_op('MAKE_CLOSURE', 134) # 85
def_op('LOAD_CLOSURE', 135) # 97
hasfree.append(135) # 97
def_op('LOAD_DEREF', 136) # 99
hasfree.append(136) # 99
def_op('STORE_DEREF', 137) # 100
hasfree.append(137) # 100
def_op('CALL_FUNCTION_VAR', 140) # 111 # #args + (#kwargs << 8)
def_op('CALL_FUNCTION_KW', 141) # 112 # #args + (#kwargs << 8)
def_op('CALL_FUNCTION_VAR_KW', 142) # 113 # #args + (#kwargs << 8)
def_op('EXTENDED_ARG', 143) # 114
EXTENDED_ARG = 143 # 114
updateGlobal()
del def_op, name_op, jrel_op, jabs_op

View File

@@ -1,203 +0,0 @@
"""
CPython 2.6 bytecode opcodes
This is used in scanner (bytecode disassembly) and parser (Python grammar).
This is a superset of Python 3.4's opcode.py with some opcodes that simplify
parsing and semantic interpretation.
"""
# FIXME: DRY this along the lines of opcode_3x.
cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is',
'is not', 'exception match', 'BAD')
hasconst = []
hasname = []
hasjrel = []
hasjabs = []
haslocal = []
hascompare = []
hasfree = []
hasArgumentExtended = []
PJIF = PJIT = JA = JF = 0
opmap = {}
opname = [''] * 256
for op in range(256): opname[op] = '<%r>' % (op,)
del op
def def_op(name, op):
opname[op] = name
opmap[name] = op
globals().update({name: op})
def name_op(name, op):
def_op(name, op)
hasname.append(op)
def jrel_op(name, op):
def_op(name, op)
hasjrel.append(op)
def jabs_op(name, op):
def_op(name, op)
hasjabs.append(op)
def def_extArg(name, op):
def_op(name, op)
hasArgumentExtended.append(op)
def updateGlobal():
globals().update({'PJIF': opmap['JUMP_IF_FALSE']})
globals().update({'PJIT': opmap['JUMP_IF_TRUE']})
globals().update({'JA': opmap['JUMP_ABSOLUTE']})
globals().update({'JF': opmap['JUMP_FORWARD']})
globals().update(dict([(k.replace('+', '_'), v) for (k, v) in opmap.items()]))
globals().update({'JUMP_OPs': map(lambda op: opname[op], hasjrel + hasjabs)})
# Instruction opcodes for compiled code
# Blank lines correspond to available opcodes
def_op('STOP_CODE', 0)
def_op('POP_TOP', 1)
def_op('ROT_TWO', 2)
def_op('ROT_THREE', 3)
def_op('DUP_TOP', 4)
def_op('ROT_FOUR', 5)
def_op('NOP', 9)
def_op('UNARY_POSITIVE', 10)
def_op('UNARY_NEGATIVE', 11)
def_op('UNARY_NOT', 12)
def_op('UNARY_CONVERT', 13)
def_op('UNARY_INVERT', 15)
def_extArg('LIST_APPEND', 18)
def_op('BINARY_POWER', 19)
def_op('BINARY_MULTIPLY', 20)
def_op('BINARY_DIVIDE', 21)
def_op('BINARY_MODULO', 22)
def_op('BINARY_ADD', 23)
def_op('BINARY_SUBTRACT', 24)
def_op('BINARY_SUBSCR', 25)
def_op('BINARY_FLOOR_DIVIDE', 26)
def_op('BINARY_TRUE_DIVIDE', 27)
def_op('INPLACE_FLOOR_DIVIDE', 28)
def_op('INPLACE_TRUE_DIVIDE', 29)
def_op('SLICE+0', 30)
def_op('SLICE+1', 31)
def_op('SLICE+2', 32)
def_op('SLICE+3', 33)
def_op('STORE_SLICE+0', 40)
def_op('STORE_SLICE+1', 41)
def_op('STORE_SLICE+2', 42)
def_op('STORE_SLICE+3', 43)
def_op('DELETE_SLICE+0', 50)
def_op('DELETE_SLICE+1', 51)
def_op('DELETE_SLICE+2', 52)
def_op('DELETE_SLICE+3', 53)
def_op('STORE_MAP', 54)
def_op('INPLACE_ADD', 55)
def_op('INPLACE_SUBTRACT', 56)
def_op('INPLACE_MULTIPLY', 57)
def_op('INPLACE_DIVIDE', 58)
def_op('INPLACE_MODULO', 59)
def_op('STORE_SUBSCR', 60)
def_op('DELETE_SUBSCR', 61)
def_op('BINARY_LSHIFT', 62)
def_op('BINARY_RSHIFT', 63)
def_op('BINARY_AND', 64)
def_op('BINARY_XOR', 65)
def_op('BINARY_OR', 66)
def_op('INPLACE_POWER', 67)
def_op('GET_ITER', 68)
def_op('PRINT_EXPR', 70)
def_op('PRINT_ITEM', 71)
def_op('PRINT_NEWLINE', 72)
def_op('PRINT_ITEM_TO', 73)
def_op('PRINT_NEWLINE_TO', 74)
def_op('INPLACE_LSHIFT', 75)
def_op('INPLACE_RSHIFT', 76)
def_op('INPLACE_AND', 77)
def_op('INPLACE_XOR', 78)
def_op('INPLACE_OR', 79)
def_op('BREAK_LOOP', 80)
def_op('WITH_CLEANUP', 81)
def_op('LOAD_LOCALS', 82)
def_op('RETURN_VALUE', 83)
def_op('IMPORT_STAR', 84)
def_op('EXEC_STMT', 85)
def_op('YIELD_VALUE', 86)
def_op('POP_BLOCK', 87)
def_op('END_FINALLY', 88)
def_op('BUILD_CLASS', 89)
HAVE_ARGUMENT = 90 # Opcodes from here have an argument:
name_op('STORE_NAME', 90) # Index in name list
name_op('DELETE_NAME', 91) # ""
def_op('UNPACK_SEQUENCE', 92) # Number of tuple items
jrel_op('FOR_ITER', 93)
name_op('STORE_ATTR', 95) # Index in name list
name_op('DELETE_ATTR', 96) # ""
name_op('STORE_GLOBAL', 97) # ""
name_op('DELETE_GLOBAL', 98) # ""
def_op('DUP_TOPX', 99) # number of items to duplicate
def_op('LOAD_CONST', 100) # Index in const list
hasconst.append(100)
name_op('LOAD_NAME', 101) # Index in name list
def_op('BUILD_TUPLE', 102) # Number of tuple items
def_op('BUILD_LIST', 103) # Number of list items
def_op('BUILD_MAP', 104) # Number of dict entries (upto 255)
name_op('LOAD_ATTR', 105) # Index in name list
def_op('COMPARE_OP', 106) # Comparison operator
hascompare.append(106)
name_op('IMPORT_NAME', 107) # Index in name list
name_op('IMPORT_FROM', 108) # Index in name list
jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip
jabs_op('JUMP_IF_FALSE', 111) # ""
jabs_op('JUMP_IF_TRUE', 112) # ""
jabs_op('JUMP_ABSOLUTE', 113) # Target byte offset from beginning of code
name_op('LOAD_GLOBAL', 116) # Index in name list
jabs_op('CONTINUE_LOOP', 119) # Target address
jrel_op('SETUP_LOOP', 120) # Distance to target address
jrel_op('SETUP_EXCEPT', 121) # ""
jrel_op('SETUP_FINALLY', 122) # ""
def_op('LOAD_FAST', 124) # Local variable number
haslocal.append(124)
def_op('STORE_FAST', 125) # Local variable number
haslocal.append(125)
def_op('DELETE_FAST', 126) # Local variable number
haslocal.append(126)
def_op('RAISE_VARARGS', 130) # Number of raise arguments (1, 2, or 3)
def_op('CALL_FUNCTION', 131) # #args + (#kwargs << 8)
def_op('MAKE_FUNCTION', 132) # Number of args with default values
def_op('BUILD_SLICE', 133) # Number of items
def_op('MAKE_CLOSURE', 134)
def_op('LOAD_CLOSURE', 135)
hasfree.append(135)
def_op('LOAD_DEREF', 136)
hasfree.append(136)
def_op('STORE_DEREF', 137)
hasfree.append(137)
def_op('CALL_FUNCTION_VAR', 140) # #args + (#kwargs << 8)
def_op('CALL_FUNCTION_KW', 141) # #args + (#kwargs << 8)
def_op('CALL_FUNCTION_VAR_KW', 142) # #args + (#kwargs << 8)
def_op('EXTENDED_ARG', 143)
EXTENDED_ARG = 143
updateGlobal()
del def_op, name_op, jrel_op, jabs_op

View File

@@ -30,12 +30,6 @@ if PYTHON3:
else:
L65536 = long(65536) # NOQA
from uncompyle6.opcodes import (opcode_25, opcode_26)
from xdis.opcodes import (opcode_27,
opcode_32, opcode_33, opcode_34, opcode_35)
class Code(object):
'''
Class for representing code-objects.
@@ -55,18 +49,25 @@ class Scanner(object):
self.version = version
# FIXME: DRY
if version == 2.7:
from xdis.opcodes import opcode_27
self.opc = opcode_27
elif version == 2.6:
from xdis.opcodes import opcode_26
self.opc = opcode_26
elif version == 2.5:
from xdis.opcodes import opcode_25
self.opc = opcode_25
elif version == 3.2:
from xdis.opcodes import opcode_32
self.opc = opcode_32
elif version == 3.3:
from xdis.opcodes import opcode_33
self.opc = opcode_33
elif version == 3.4:
from xdis.opcodes import opcode_34
self.opc = opcode_34
elif version == 3.5:
from xdis.opcodes import opcode_35
self.opc = opcode_35
else:
raise TypeError("%s is not a Python version I know about" % version)

View File

@@ -10,8 +10,7 @@ Python 3 and other versions of Python. Also, we save token
information for later use in deparsing.
"""
from uncompyle6.opcodes.opcode_25 import *
from xdis.opcodes.opcode_25 import *
import uncompyle6.scanners.scanner26 as scan
import uncompyle6.scanners.scanner2 as scan2
@@ -99,24 +98,24 @@ class Scanner25(scan.Scanner26):
if listDel:
for jmp in self.op_range(0, len(self.code)):
op = self.code[jmp]
if op in hasjrel+hasjabs:
if op in self.opc.hasjrel + self.opc.hasjabs:
offset = 0
jmpTarget = self.get_target(jmp)
for toDel in listDel:
if toDel < jmpTarget:
if op in hasjabs or jmp < toDel:
if op in self.opc.hasjabs or jmp < toDel:
offset-=self.op_size(self.code[toDel])
self.restructJump(jmp, jmpTarget+offset)
if listExp:
jmp = 0
while jmp < len(self.code): # we can't use op_range for the moment
op = self.code[jmp]
if op in hasjrel+hasjabs:
if op in self.opc.hasjrel + self.opc.hasjabs:
offset = 0
jmpTarget = self.get_target(jmp)
for toExp in listExp:
if toExp < jmpTarget:
if op in hasjabs or jmp < toExp:
if op in self.opc.hasjabs or jmp < toExp:
offset+=2
self.restructJump(jmp, jmpTarget+offset)
if self.op_hasArgument(op) and op not in self.opc.hasArgumentExtended:
@@ -166,46 +165,6 @@ class Scanner25(scan.Scanner26):
self.code.pop(x-delta)
delta += 1
def restructRelativeJump(self):
'''
change relative JUMP_IF_FALSE/TRUE to absolut jump
and remap the target of PJIF/PJIT
'''
i=0
while i < len(self.code): # we can't use op_range for the moment
op = self.code[i]
if(op in (PJIF, PJIT)):
target = self.get_argument(i)
target += i + 3
self.restructJump(i, target)
if self.op_hasArgument(op) and op not in self.opc.hasArgumentExtended:
i += 3
else: i += 1
i=0
while i < len(self.code): # we can't use op_range for the moment
op = self.code[i]
if(op in (PJIF, PJIT)):
target = self.get_target(i)
if self.code[target] == JA:
target = self.get_target(target)
self.restructJump(i, target)
if self.op_hasArgument(op) and op not in self.opc.hasArgumentExtended:
i += 3
else: i += 1
def restructJump(self, pos, newTarget):
if not (self.code[pos] in hasjabs+hasjrel):
raise 'Can t change this argument. Opcode is not a jump'
if newTarget > 0xFFFF:
raise NotImplementedError
offset = newTarget-self.get_target(pos)
target = self.get_argument(pos)+offset
if target < 0 or target > 0xFFFF:
raise NotImplementedError
self.code[pos+2] = (target >> 8) & 0xFF
self.code[pos+1] = target & 0xFF
def detect_structure(self, pos, op=None):
'''
Detect type of block structures and their boundaries to fix optimizied jumps
@@ -230,7 +189,8 @@ class Scanner25(scan.Scanner26):
parent = s
# We need to know how many new structures were added in this run
if op == SETUP_LOOP:
if op == self.opc.SETUP_LOOP:
start = pos+3
target = self.get_target(pos, op)
end = self.restrict_to_parent(target, parent)
@@ -239,8 +199,7 @@ class Scanner25(scan.Scanner26):
self.fixed_jumps[pos] = end
(line_no, next_line_byte) = self.lines[pos]
jump_back = self.last_instr(start, end, JA,
next_line_byte, False)
jump_back = self.last_instr(start, end, self.opc.JA, next_line_byte, False)
if jump_back and jump_back != self.prev[end] and code[jump_back+3] in (JA, JF):
if code[self.prev[end]] == RETURN_VALUE or \
(code[self.prev[end]] == POP_BLOCK and code[self.prev[self.prev[end]]] == RETURN_VALUE):
@@ -250,7 +209,7 @@ class Scanner25(scan.Scanner26):
if not jump_back:
return
jump_back += 1
if code[self.prev[next_line_byte]] not in (PJIF, PJIT):
if code[self.prev[next_line_byte]] not in self.pop_jump_if:
loop_type = 'for'
else:
loop_type = 'while'
@@ -270,16 +229,16 @@ class Scanner25(scan.Scanner26):
self.fixed_jumps[pos] = jump_back+4
end = jump_back+4
target = self.get_target(jump_back, JA)
target = self.get_target(jump_back, self.opc.JA)
if code[target] in (FOR_ITER, GET_ITER):
if code[target] in (self.opc.FOR_ITER, self.opc.GET_ITER):
loop_type = 'for'
else:
loop_type = 'while'
test = self.prev[next_line_byte]
if test == pos:
loop_type = 'while 1'
elif self.code[test] in hasjabs+hasjrel:
elif self.code[test] in self.opc.hasjabs + self.opc.hasjrel:
self.ignore_if.add(test)
test_target = self.get_target(test)
if test_target > (jump_back+3):
@@ -293,7 +252,7 @@ class Scanner25(scan.Scanner26):
self.structs.append({'type': loop_type + '-else',
'start': jump_back+3,
'end': end})
elif op == SETUP_EXCEPT:
elif op == self.opc.SETUP_EXCEPT:
start = pos+3
target = self.get_target(pos, op)
end = self.restrict_to_parent(target, parent)
@@ -308,12 +267,12 @@ class Scanner25(scan.Scanner26):
# Add the except blocks
i = end
while i < len(self.code) and self.code[i] != END_FINALLY:
while i < len(self.code) and self.code[i] != self.opc.END_FINALLY:
jmp = self.next_except_jump(i)
if jmp is None: # check
i = self.next_stmt[i]
continue
if self.code[jmp] == RETURN_VALUE:
if self.code[jmp] == self.opc.RETURN_VALUE:
self.structs.append({'type': 'except',
'start': i,
'end': jmp+1})
@@ -321,7 +280,7 @@ class Scanner25(scan.Scanner26):
else:
if self.get_target(jmp) != start_else:
end_else = self.get_target(jmp)
if self.code[jmp] == JF:
if self.code[jmp] == self.opc.JF:
self.fixed_jumps[jmp] = -1
self.structs.append({'type': 'except',
'start': i,
@@ -338,7 +297,7 @@ class Scanner25(scan.Scanner26):
else:
self.fixed_jumps[i] = i+1
elif op in (PJIF, PJIT):
elif op in self.pop_jump_if:
start = pos+3
target = self.get_target(pos, op)
rtarget = self.restrict_to_parent(target, parent)
@@ -390,7 +349,7 @@ class Scanner25(scan.Scanner26):
last_jump_good = False
self.fixed_jumps[pos] = fix or match[-1]
return
elif pos < rtarget and code[target] == ROT_TWO:
elif pos < rtarget and code[target] == self.opc.ROT_TWO:
self.fixed_jumps[pos] = target
return
else:
@@ -398,7 +357,7 @@ class Scanner25(scan.Scanner26):
return
else: # op == PJIT
if (pos+3) in self.load_asserts:
if code[pre[rtarget]] == RAISE_VARARGS:
if code[pre[rtarget]] == self.opc.RAISE_VARARGS:
return
self.load_asserts.remove(pos+3)
@@ -427,7 +386,7 @@ class Scanner25(scan.Scanner26):
if_end = self.get_target(pre[rtarget])
# is this a loop not an if?
if (if_end < pre[rtarget]) and (code[pre[if_end]] == SETUP_LOOP):
if (if_end < pre[rtarget]) and (code[pre[if_end]] == self.opc.SETUP_LOOP):
if(if_end > start):
return
@@ -442,9 +401,9 @@ class Scanner25(scan.Scanner26):
self.structs.append({'type': 'if-else',
'start': rtarget,
'end': end})
elif code[pre[rtarget]] == RETURN_VALUE:
elif code[pre[rtarget]] == self.opc.RETURN_VALUE:
# if it's an old JUMP_IF_FALSE_OR_POP, JUMP_IF_TRUE_OR_POP (return 1<2<3 case)
if pos < rtarget and code[rtarget] == ROT_TWO:
if pos < rtarget and code[rtarget] == self.opc.ROT_TWO:
return
self.structs.append({'type': 'if-then',
'start': start,

View File

@@ -11,7 +11,7 @@ from __future__ import print_function
import xdis
# bytecode verification, verify(), uses JUMP_OPs from here
JUMP_OPs = xdis.opcodes.opcode_32.JUMP_OPs
# JUMP_OPs = xdis.opcodes.opcode_32.JUMP_OPs
from uncompyle6.scanners.scanner3 import Scanner3
class Scanner32(Scanner3):

View File

@@ -8,10 +8,10 @@ scanner routine for Python 3.
from __future__ import print_function
import xdis
# import xdis
# bytecode verification, verify(), uses JUMP_OPs from here
JUMP_OPs = xdis.opcodes.opcode_34.JUMP_OPs
# JUMP_OPs = xdis.opcodes.opcode_34.JUMP_OPs
from uncompyle6.scanners.scanner3 import Scanner3
class Scanner34(Scanner3):

View File

@@ -8,12 +8,12 @@ scanner routine for Python 3.
from __future__ import print_function
import xdis
# import xdis
from uncompyle6.scanners.scanner3 import Scanner3
# bytecode verification, verify(), uses JUMP_OPs from here
JUMP_OPs = xdis.opcodes.opcode_35.JUMP_OPs
# JUMP_OPs = xdis.opcodes.opcode_35.JUMP_OPs
class Scanner35(Scanner3):