You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-02 16:44:46 +08:00
DRY and clean up code a little
This commit is contained in:
@@ -63,13 +63,17 @@ class Scanner(object):
|
||||
# FIXME: This weird Python2 behavior is not Python3
|
||||
self.resetTokenClass()
|
||||
|
||||
def setTokenClass(self, tokenClass):
|
||||
# assert isinstance(tokenClass, types.ClassType)
|
||||
self.Token = tokenClass
|
||||
return self.Token
|
||||
|
||||
def resetTokenClass(self):
|
||||
return self.setTokenClass(Token)
|
||||
def is_jump_forward(self, offset):
|
||||
"""
|
||||
Return True if the code at offset is some sort of jump forward.
|
||||
That is, it is ether "JUMP_FORWARD" or an absolute jump that
|
||||
goes forward.
|
||||
"""
|
||||
if self.code[offset] == self.opc.JUMP_FORWARD:
|
||||
return True
|
||||
if self.code[offset] != self.opc.JUMP_ABSOLUTE:
|
||||
return False
|
||||
return offset < self.get_target(offset)
|
||||
|
||||
def get_target(self, pos, op=None):
|
||||
if op is None:
|
||||
@@ -214,53 +218,23 @@ class Scanner(object):
|
||||
start += self.op_size(self.code[start])
|
||||
|
||||
def remove_mid_line_ifs(self, ifs):
|
||||
"""
|
||||
Go through passed offsets, filtering ifs
|
||||
located somewhere mid-line.
|
||||
"""
|
||||
filtered = []
|
||||
for i in ifs:
|
||||
# For each offset, if line number of current and next op
|
||||
# is the same
|
||||
if self.lines[i].l_no == self.lines[i+3].l_no:
|
||||
# Skip last op on line if it is some sort of POP_JUMP.
|
||||
if self.code[self.prev[self.lines[i].next]] in (self.opc.PJIT, self.opc.PJIF):
|
||||
continue
|
||||
filtered.append(i)
|
||||
return filtered
|
||||
|
||||
def rem_or(self, start, end, instr, target=None, include_beyond_target=False):
|
||||
"""
|
||||
Find all <instr> in the block from start to end.
|
||||
<instr> is any python bytecode instruction or a list of opcodes
|
||||
If <instr> is an opcode with a target (like a jump), a target
|
||||
destination can be specified which must match precisely.
|
||||
|
||||
Return a list with indexes to them or [] if none found.
|
||||
"""
|
||||
|
||||
code = self.code
|
||||
assert(start>=0 and end<=len(code))
|
||||
|
||||
try: None in instr
|
||||
except: instr = [instr]
|
||||
|
||||
result = []
|
||||
for i in self.op_range(start, end):
|
||||
op = code[i]
|
||||
if op in instr:
|
||||
if target is None:
|
||||
result.append(i)
|
||||
else:
|
||||
t = self.get_target(i, op)
|
||||
if include_beyond_target and t >= target:
|
||||
result.append(i)
|
||||
elif t == target:
|
||||
result.append(i)
|
||||
|
||||
pjits = self.all_instr(start, end, self.opc.PJIT)
|
||||
filtered = []
|
||||
for pjit in pjits:
|
||||
tgt = self.get_target(pjit)-3
|
||||
for i in result:
|
||||
if i <= pjit or i >= tgt:
|
||||
filtered.append(i)
|
||||
result = filtered
|
||||
filtered = []
|
||||
return result
|
||||
def resetTokenClass(self):
|
||||
return self.setTokenClass(Token)
|
||||
|
||||
def restrict_to_parent(self, target, parent):
|
||||
"""Restrict target to parent structure boundaries."""
|
||||
@@ -268,6 +242,12 @@ class Scanner(object):
|
||||
target = parent['end']
|
||||
return target
|
||||
|
||||
def setTokenClass(self, tokenClass):
|
||||
# assert isinstance(tokenClass, types.ClassType)
|
||||
self.Token = tokenClass
|
||||
return self.Token
|
||||
|
||||
|
||||
def parse_fn_counts(argc):
|
||||
return ((argc & 0xFF), (argc >> 8) & 0xFF, (argc >> 16) & 0x7FFF)
|
||||
|
||||
|
@@ -35,7 +35,7 @@ class Scanner2(scan.Scanner):
|
||||
def __init__(self, version, show_asm=None):
|
||||
scan.Scanner.__init__(self, version, show_asm)
|
||||
self.pop_jump_if = frozenset([self.opc.PJIF, self.opc.PJIT])
|
||||
self.jump_forward = frozenset([self.opc.JUMP_ABSOLUTE, self.opc.JF])
|
||||
self.jump_forward = frozenset([self.opc.JUMP_ABSOLUTE, self.opc.JUMP_FORWARD])
|
||||
# This is the 2.5+ default
|
||||
# For <2.5 it is <generator expression>
|
||||
self.genexpr_name = '<genexpr>';
|
||||
@@ -300,9 +300,9 @@ class Scanner2(scan.Scanner):
|
||||
start = 0
|
||||
end = len(code)
|
||||
|
||||
stmt_opcode_seqs = frozenset([(self.opc.PJIF, self.opc.JF),
|
||||
stmt_opcode_seqs = frozenset([(self.opc.PJIF, self.opc.JUMP_FORWARD),
|
||||
(self.opc.PJIF, self.opc.JUMP_ABSOLUTE),
|
||||
(self.opc.PJIT, self.opc.JF),
|
||||
(self.opc.PJIT, self.opc.JUMP_FORWARD),
|
||||
(self.opc.PJIT, self.opc.JUMP_ABSOLUTE)])
|
||||
|
||||
prelim = self.all_instr(start, end, self.stmt_opcodes)
|
||||
@@ -567,7 +567,7 @@ class Scanner2(scan.Scanner):
|
||||
target = self.get_target(jmp)
|
||||
if target != start_else:
|
||||
end_else = self.get_target(jmp)
|
||||
if self.code[jmp] == self.opc.JF:
|
||||
if self.code[jmp] == self.opc.JUMP_FORWARD:
|
||||
if self.version <= 2.6:
|
||||
self.fixed_jumps[jmp] = target
|
||||
else:
|
||||
@@ -679,7 +679,7 @@ class Scanner2(scan.Scanner):
|
||||
pass
|
||||
elif code[next] in self.jump_forward and target == self.get_target(next):
|
||||
if code[pre[next]] == self.opc.PJIF:
|
||||
if code[next] == self.opc.JF or target != rtarget or code[pre[pre[rtarget]]] not in (self.opc.JUMP_ABSOLUTE, self.opc.RETURN_VALUE):
|
||||
if code[next] == self.opc.JUMP_FORWARD or target != rtarget or code[pre[pre[rtarget]]] not in (self.opc.JUMP_ABSOLUTE, self.opc.RETURN_VALUE):
|
||||
self.fixed_jumps[pos] = pre[next]
|
||||
return
|
||||
elif code[next] == self.opc.JUMP_ABSOLUTE and code[target] in self.jump_forward:
|
||||
@@ -791,6 +791,47 @@ class Scanner2(scan.Scanner):
|
||||
targets[label] = targets.get(label, []) + [i]
|
||||
return targets
|
||||
|
||||
# FIXME: combine with scanner3.py code and put into scanner.py
|
||||
def rem_or(self, start, end, instr, target=None, include_beyond_target=False):
|
||||
"""
|
||||
Find all <instr> in the block from start to end.
|
||||
<instr> is any python bytecode instruction or a list of opcodes
|
||||
If <instr> is an opcode with a target (like a jump), a target
|
||||
destination can be specified which must match precisely.
|
||||
|
||||
Return a list with indexes to them or [] if none found.
|
||||
"""
|
||||
|
||||
assert(start>=0 and end<=len(self.code) and start <= end)
|
||||
|
||||
try: None in instr
|
||||
except: instr = [instr]
|
||||
|
||||
instr_offsets = []
|
||||
for i in self.op_range(start, end):
|
||||
op = self.code[i]
|
||||
if op in instr:
|
||||
if target is None:
|
||||
instr_offsets.append(i)
|
||||
else:
|
||||
t = self.get_target(i, op)
|
||||
if include_beyond_target and t >= target:
|
||||
instr_offsets.append(i)
|
||||
elif t == target:
|
||||
instr_offsets.append(i)
|
||||
|
||||
pjits = self.all_instr(start, end, self.opc.PJIT)
|
||||
filtered = []
|
||||
for pjit in pjits:
|
||||
tgt = self.get_target(pjit)-3
|
||||
for i in instr_offsets:
|
||||
if i <= pjit or i >= tgt:
|
||||
filtered.append(i)
|
||||
instr_offsets = filtered
|
||||
filtered = []
|
||||
return instr_offsets
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
from uncompyle6 import PYTHON_VERSION
|
||||
if PYTHON_VERSION >= 2.3:
|
||||
|
@@ -694,18 +694,6 @@ class Scanner3(scan.Scanner):
|
||||
else:
|
||||
self.fixed_jumps[offset] = self.restrict_to_parent(target, parent)
|
||||
|
||||
def is_jump_forward(self, offset):
|
||||
"""
|
||||
Return True if the code at offset is some sort of jump forward.
|
||||
That is, it is ether "JUMP_FORWARD" or an absolute jump that
|
||||
goes forward.
|
||||
"""
|
||||
if self.code[offset] == self.opc.JUMP_FORWARD:
|
||||
return True
|
||||
if self.code[offset] != self.opc.JUMP_ABSOLUTE:
|
||||
return False
|
||||
return offset < self.get_target(offset)
|
||||
|
||||
|
||||
def next_except_jump(self, start):
|
||||
"""
|
||||
@@ -740,6 +728,8 @@ class Scanner3(scan.Scanner):
|
||||
optionally <target>ing specified offset, and return list found
|
||||
<instr> offsets which are not within any POP_JUMP_IF_TRUE jumps.
|
||||
"""
|
||||
assert(start>=0 and end<=len(self.code) and start <= end)
|
||||
|
||||
# Find all offsets of requested instructions
|
||||
instr_offsets = self.all_instr(start, end, instr, target, include_beyond_target)
|
||||
# Get all POP_JUMP_IF_TRUE (or) offsets
|
||||
@@ -754,22 +744,6 @@ class Scanner3(scan.Scanner):
|
||||
filtered = []
|
||||
return instr_offsets
|
||||
|
||||
def remove_mid_line_ifs(self, ifs):
|
||||
"""
|
||||
Go through passed offsets, filtering ifs
|
||||
located somewhere mid-line.
|
||||
"""
|
||||
filtered = []
|
||||
for if_ in ifs:
|
||||
# For each offset, if line number of current and next op
|
||||
# is the same
|
||||
if self.lines[if_].l_no == self.lines[if_+3].l_no:
|
||||
# Skip last op on line if it is some sort of POP_JUMP.
|
||||
if self.code[self.prev_op[self.lines[if_].next]] in POP_JUMP_TF:
|
||||
continue
|
||||
filtered.append(if_)
|
||||
return filtered
|
||||
|
||||
if __name__ == "__main__":
|
||||
from uncompyle6 import PYTHON_VERSION
|
||||
if PYTHON_VERSION >= 3.2:
|
||||
|
Reference in New Issue
Block a user