You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Use xdis' instruction offset calculation fns..
next_offset, op_size, has_argument
This commit is contained in:
@@ -40,7 +40,7 @@ entry_points = {
|
|||||||
]}
|
]}
|
||||||
ftp_url = None
|
ftp_url = None
|
||||||
install_requires = ['spark-parser >= 1.6.1, < 1.7.0',
|
install_requires = ['spark-parser >= 1.6.1, < 1.7.0',
|
||||||
'xdis >= 3.3.1, < 3.4.0', 'six']
|
'xdis >= 3.4.0, < 3.5.0', 'six']
|
||||||
license = 'MIT'
|
license = 'MIT'
|
||||||
mailing_list = 'python-debugger@googlegroups.com'
|
mailing_list = 'python-debugger@googlegroups.com'
|
||||||
modname = 'uncompyle6'
|
modname = 'uncompyle6'
|
||||||
|
@@ -16,6 +16,7 @@ import sys
|
|||||||
|
|
||||||
from uncompyle6 import PYTHON3, IS_PYPY
|
from uncompyle6 import PYTHON3, IS_PYPY
|
||||||
from uncompyle6.scanners.tok import Token
|
from uncompyle6.scanners.tok import Token
|
||||||
|
from xdis.bytecode import op_size
|
||||||
|
|
||||||
# The byte code versions we support
|
# The byte code versions we support
|
||||||
PYTHON_VERSIONS = (1.5,
|
PYTHON_VERSIONS = (1.5,
|
||||||
@@ -214,9 +215,6 @@ class Scanner(object):
|
|||||||
result.append(offset)
|
result.append(offset)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def op_hasArgument(self, op):
|
|
||||||
return self.op_size(op) > 1
|
|
||||||
|
|
||||||
def op_range(self, start, end):
|
def op_range(self, start, end):
|
||||||
"""
|
"""
|
||||||
Iterate through positions of opcodes, skipping
|
Iterate through positions of opcodes, skipping
|
||||||
@@ -224,20 +222,7 @@ class Scanner(object):
|
|||||||
"""
|
"""
|
||||||
while start < end:
|
while start < end:
|
||||||
yield start
|
yield start
|
||||||
start += self.op_size(self.code[start])
|
start += op_size(self.code[start], self.opc)
|
||||||
|
|
||||||
def next_offset(self, op, offset):
|
|
||||||
return offset + self.op_size(op)
|
|
||||||
|
|
||||||
def op_size(self, op):
|
|
||||||
"""
|
|
||||||
Return size of operator with its arguments
|
|
||||||
for given opcode <op>.
|
|
||||||
"""
|
|
||||||
if op < self.opc.HAVE_ARGUMENT:
|
|
||||||
return 2 if self.version >= 3.6 else 1
|
|
||||||
else:
|
|
||||||
return 2 if self.version >= 3.6 else 3
|
|
||||||
|
|
||||||
def remove_mid_line_ifs(self, ifs):
|
def remove_mid_line_ifs(self, ifs):
|
||||||
"""
|
"""
|
||||||
@@ -269,9 +254,6 @@ class Scanner(object):
|
|||||||
self.Token = tokenClass
|
self.Token = tokenClass
|
||||||
return self.Token
|
return self.Token
|
||||||
|
|
||||||
def op_has_argument(op, opc):
|
|
||||||
return op >= opc.HAVE_ARGUMENT
|
|
||||||
|
|
||||||
def parse_fn_counts(argc):
|
def parse_fn_counts(argc):
|
||||||
return ((argc & 0xFF), (argc >> 8) & 0xFF, (argc >> 16) & 0x7FFF)
|
return ((argc & 0xFF), (argc >> 8) & 0xFF, (argc >> 16) & 0x7FFF)
|
||||||
|
|
||||||
|
@@ -25,8 +25,9 @@ from __future__ import print_function
|
|||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from array import array
|
from array import array
|
||||||
|
|
||||||
from uncompyle6.scanner import op_has_argument, L65536
|
from uncompyle6.scanner import L65536
|
||||||
from xdis.code import iscode
|
from xdis.code import iscode
|
||||||
|
from xdis.bytecode import op_has_argument, op_size
|
||||||
|
|
||||||
from uncompyle6.scanner import Scanner
|
from uncompyle6.scanner import Scanner
|
||||||
|
|
||||||
@@ -327,7 +328,7 @@ class Scanner2(Scanner):
|
|||||||
for i in self.op_range(0, n):
|
for i in self.op_range(0, n):
|
||||||
op = self.code[i]
|
op = self.code[i]
|
||||||
self.prev.append(i)
|
self.prev.append(i)
|
||||||
if self.op_hasArgument(op):
|
if op_has_argument(op, self.opc):
|
||||||
self.prev.append(i)
|
self.prev.append(i)
|
||||||
self.prev.append(i)
|
self.prev.append(i)
|
||||||
pass
|
pass
|
||||||
@@ -380,7 +381,7 @@ class Scanner2(Scanner):
|
|||||||
if elem != code[i]:
|
if elem != code[i]:
|
||||||
match = False
|
match = False
|
||||||
break
|
break
|
||||||
i += self.op_size(code[i])
|
i += op_size(code[i], self.opc)
|
||||||
|
|
||||||
if match:
|
if match:
|
||||||
i = self.prev[i]
|
i = self.prev[i]
|
||||||
@@ -617,7 +618,7 @@ class Scanner2(Scanner):
|
|||||||
'start': jump_back+3,
|
'start': jump_back+3,
|
||||||
'end': end})
|
'end': end})
|
||||||
elif op == self.opc.SETUP_EXCEPT:
|
elif op == self.opc.SETUP_EXCEPT:
|
||||||
start = offset + self.op_size(op)
|
start = offset + op_size(op, self.opc)
|
||||||
target = self.get_target(offset, op)
|
target = self.get_target(offset, op)
|
||||||
end = self.restrict_to_parent(target, parent)
|
end = self.restrict_to_parent(target, parent)
|
||||||
if target != end:
|
if target != end:
|
||||||
@@ -641,7 +642,7 @@ class Scanner2(Scanner):
|
|||||||
setup_except_nest -= 1
|
setup_except_nest -= 1
|
||||||
elif self.code[end_finally_offset] == self.opc.SETUP_EXCEPT:
|
elif self.code[end_finally_offset] == self.opc.SETUP_EXCEPT:
|
||||||
setup_except_nest += 1
|
setup_except_nest += 1
|
||||||
end_finally_offset += self.op_size(code[end_finally_offset])
|
end_finally_offset += op_size(code[end_finally_offset], self.opc)
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Add the except blocks
|
# Add the except blocks
|
||||||
@@ -842,7 +843,7 @@ class Scanner2(Scanner):
|
|||||||
else:
|
else:
|
||||||
# We still have the case in 2.7 that the next instruction
|
# We still have the case in 2.7 that the next instruction
|
||||||
# is a jump to a SETUP_LOOP target.
|
# is a jump to a SETUP_LOOP target.
|
||||||
next_offset = target + self.op_size(self.code[target])
|
next_offset = target + op_size(self.code[target], self.opc)
|
||||||
next_op = self.code[next_offset]
|
next_op = self.code[next_offset]
|
||||||
if self.op_name(next_op) == 'JUMP_FORWARD':
|
if self.op_name(next_op) == 'JUMP_FORWARD':
|
||||||
jump_target = self.get_target(next_offset, next_op)
|
jump_target = self.get_target(next_offset, next_op)
|
||||||
|
@@ -25,10 +25,11 @@ from __future__ import print_function
|
|||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
from array import array
|
from array import array
|
||||||
|
|
||||||
from uncompyle6.scanner import Scanner, op_has_argument
|
from uncompyle6.scanner import Scanner
|
||||||
from xdis.code import iscode
|
from xdis.code import iscode
|
||||||
from xdis.bytecode import Bytecode
|
from xdis.bytecode import Bytecode, op_has_argument, op_size
|
||||||
from uncompyle6.scanner import Token, parse_fn_counts
|
from uncompyle6.scanner import Token, parse_fn_counts
|
||||||
|
import xdis
|
||||||
|
|
||||||
# Get all the opcodes into globals
|
# Get all the opcodes into globals
|
||||||
import xdis.opcodes.opcode_33 as op3
|
import xdis.opcodes.opcode_33 as op3
|
||||||
@@ -468,7 +469,7 @@ class Scanner3(Scanner):
|
|||||||
self.prev = self.prev_op = [0]
|
self.prev = self.prev_op = [0]
|
||||||
for offset in self.op_range(0, codelen):
|
for offset in self.op_range(0, codelen):
|
||||||
op = code[offset]
|
op = code[offset]
|
||||||
for _ in range(self.op_size(op)):
|
for _ in range(op_size(op, self.opc)):
|
||||||
self.prev_op.append(offset)
|
self.prev_op.append(offset)
|
||||||
|
|
||||||
def find_jump_targets(self, debug):
|
def find_jump_targets(self, debug):
|
||||||
@@ -518,7 +519,7 @@ class Scanner3(Scanner):
|
|||||||
oparg = code[offset+1]
|
oparg = code[offset+1]
|
||||||
else:
|
else:
|
||||||
oparg = code[offset+1] + code[offset+2] * 256
|
oparg = code[offset+1] + code[offset+2] * 256
|
||||||
next_offset = self.next_offset(op, offset)
|
next_offset = xdis.next_offset(op, self.opc, offset)
|
||||||
|
|
||||||
if label is None:
|
if label is None:
|
||||||
if op in op3.hasjrel and op != self.opc.FOR_ITER:
|
if op in op3.hasjrel and op != self.opc.FOR_ITER:
|
||||||
@@ -564,7 +565,7 @@ class Scanner3(Scanner):
|
|||||||
if elem != code[i]:
|
if elem != code[i]:
|
||||||
match = False
|
match = False
|
||||||
break
|
break
|
||||||
i += self.op_size(code[i])
|
i += op_size(code[i], self.opc)
|
||||||
|
|
||||||
if match is True:
|
if match is True:
|
||||||
i = self.prev_op[i]
|
i = self.prev_op[i]
|
||||||
@@ -757,7 +758,7 @@ class Scanner3(Scanner):
|
|||||||
'start': jump_back+3,
|
'start': jump_back+3,
|
||||||
'end': end})
|
'end': end})
|
||||||
elif op in self.pop_jump_tf:
|
elif op in self.pop_jump_tf:
|
||||||
start = offset + self.op_size(op)
|
start = offset + op_size(op, self.opc)
|
||||||
target = self.get_target(offset)
|
target = self.get_target(offset)
|
||||||
rtarget = self.restrict_to_parent(target, parent)
|
rtarget = self.restrict_to_parent(target, parent)
|
||||||
prev_op = self.prev_op
|
prev_op = self.prev_op
|
||||||
@@ -932,9 +933,9 @@ class Scanner3(Scanner):
|
|||||||
# not from SETUP_EXCEPT
|
# not from SETUP_EXCEPT
|
||||||
next_op = rtarget
|
next_op = rtarget
|
||||||
if code[next_op] == self.opc.POP_BLOCK:
|
if code[next_op] == self.opc.POP_BLOCK:
|
||||||
next_op += self.op_size(self.code[next_op])
|
next_op += op_size(self.code[next_op], self.opc)
|
||||||
if code[next_op] == self.opc.JUMP_ABSOLUTE:
|
if code[next_op] == self.opc.JUMP_ABSOLUTE:
|
||||||
next_op += self.op_size(self.code[next_op])
|
next_op += op_size(self.code[next_op], self.opc)
|
||||||
if next_op in targets:
|
if next_op in targets:
|
||||||
for try_op in targets[next_op]:
|
for try_op in targets[next_op]:
|
||||||
come_from_op = code[try_op]
|
come_from_op = code[try_op]
|
||||||
@@ -957,12 +958,12 @@ class Scanner3(Scanner):
|
|||||||
end = self.restrict_to_parent(target, parent)
|
end = self.restrict_to_parent(target, parent)
|
||||||
self.fixed_jumps[offset] = end
|
self.fixed_jumps[offset] = end
|
||||||
elif op == self.opc.POP_EXCEPT:
|
elif op == self.opc.POP_EXCEPT:
|
||||||
next_offset = self.next_offset(op, offset)
|
next_offset = xdis.next_offset(op, self.opc, offset)
|
||||||
target = self.get_target(next_offset)
|
target = self.get_target(next_offset)
|
||||||
if target > next_offset:
|
if target > next_offset:
|
||||||
next_op = code[next_offset]
|
next_op = code[next_offset]
|
||||||
if (self.opc.JUMP_ABSOLUTE == next_op and
|
if (self.opc.JUMP_ABSOLUTE == next_op and
|
||||||
END_FINALLY != code[self.next_offset(next_op, next_offset)]):
|
END_FINALLY != code[xdis.next_offset(next_op, self.opc, next_offset)]):
|
||||||
self.fixed_jumps[next_offset] = target
|
self.fixed_jumps[next_offset] = target
|
||||||
self.except_targets[target] = next_offset
|
self.except_targets[target] = next_offset
|
||||||
|
|
||||||
|
@@ -10,6 +10,8 @@ from __future__ import print_function
|
|||||||
|
|
||||||
# bytecode verification, verify(), uses JUMP_OPs from here
|
# bytecode verification, verify(), uses JUMP_OPs from here
|
||||||
from xdis.opcodes import opcode_30 as opc
|
from xdis.opcodes import opcode_30 as opc
|
||||||
|
from xdis.bytecode import op_size
|
||||||
|
|
||||||
JUMP_OPs = map(lambda op: opc.opname[op], opc.hasjrel + opc.hasjabs)
|
JUMP_OPs = map(lambda op: opc.opname[op], opc.hasjrel + opc.hasjabs)
|
||||||
|
|
||||||
JUMP_TF = frozenset([opc.JUMP_IF_FALSE, opc.JUMP_IF_TRUE])
|
JUMP_TF = frozenset([opc.JUMP_IF_FALSE, opc.JUMP_IF_TRUE])
|
||||||
@@ -133,7 +135,7 @@ class Scanner30(Scanner3):
|
|||||||
'start': jump_back+3,
|
'start': jump_back+3,
|
||||||
'end': end})
|
'end': end})
|
||||||
elif op in JUMP_TF:
|
elif op in JUMP_TF:
|
||||||
start = offset + self.op_size(op)
|
start = offset + op_size(op, self.opc)
|
||||||
target = self.get_target(offset)
|
target = self.get_target(offset)
|
||||||
rtarget = self.restrict_to_parent(target, parent)
|
rtarget = self.restrict_to_parent(target, parent)
|
||||||
prev_op = self.prev_op
|
prev_op = self.prev_op
|
||||||
@@ -305,9 +307,9 @@ class Scanner30(Scanner3):
|
|||||||
# not from SETUP_EXCEPT
|
# not from SETUP_EXCEPT
|
||||||
next_op = rtarget
|
next_op = rtarget
|
||||||
if code[next_op] == self.opc.POP_BLOCK:
|
if code[next_op] == self.opc.POP_BLOCK:
|
||||||
next_op += self.op_size(self.code[next_op])
|
next_op += op_size(self.code[next_op], self.opc)
|
||||||
if code[next_op] == self.opc.JUMP_ABSOLUTE:
|
if code[next_op] == self.opc.JUMP_ABSOLUTE:
|
||||||
next_op += self.op_size(self.code[next_op])
|
next_op += op_size(self.code[next_op], self.opc)
|
||||||
if next_op in targets:
|
if next_op in targets:
|
||||||
for try_op in targets[next_op]:
|
for try_op in targets[next_op]:
|
||||||
come_from_op = code[try_op]
|
come_from_op = code[try_op]
|
||||||
|
@@ -573,33 +573,6 @@ class SourceWalker(GenericASTTraversal, object):
|
|||||||
node == AST('return_stmt',
|
node == AST('return_stmt',
|
||||||
[AST('ret_expr', [NONE]), Token('RETURN_VALUE')]))
|
[AST('ret_expr', [NONE]), Token('RETURN_VALUE')]))
|
||||||
|
|
||||||
## The below doesn't work because continue may be the only thing inside an 'else'. For example
|
|
||||||
# for ...
|
|
||||||
# if ...
|
|
||||||
# else:
|
|
||||||
# continue
|
|
||||||
#
|
|
||||||
# def n_continue_stmt(self, node):
|
|
||||||
# if self.version >= 3.0 and node[0] == 'CONTINUE':
|
|
||||||
# t = node[0]
|
|
||||||
# if not t.linestart:
|
|
||||||
# # Artificially-added "continue" statements derived from JUMP_ABSOLUTE
|
|
||||||
# # don't have line numbers associated with them.
|
|
||||||
# # If this is a CONTINUE is to the same target as a JUMP_ABSOLUTE following it,
|
|
||||||
# # then the "continue" can be suppressed.
|
|
||||||
# op, offset = t.op, t.offset
|
|
||||||
# next_offset = self.scanner.next_offset(op, offset)
|
|
||||||
# scanner = self.scanner
|
|
||||||
# code = scanner.code
|
|
||||||
# if next_offset < len(code):
|
|
||||||
# next_inst = code[next_offset]
|
|
||||||
# if (scanner.opc.opname[next_inst] == 'JUMP_ABSOLUTE'
|
|
||||||
# and t.pattr == code[next_offset+1]):
|
|
||||||
# # Suppress "continue"
|
|
||||||
# import pdb; pdb.set_trace()
|
|
||||||
# self.prune()
|
|
||||||
# self.default(node)
|
|
||||||
|
|
||||||
def n_return_stmt(self, node):
|
def n_return_stmt(self, node):
|
||||||
if self.params['isLambda']:
|
if self.params['isLambda']:
|
||||||
self.preorder(node[0])
|
self.preorder(node[0])
|
||||||
|
Reference in New Issue
Block a user