You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Replace all_instrs with inst_matches...
which works on 3.6+. Still should write a pytest for this.
This commit is contained in:
@@ -244,17 +244,57 @@ class Scanner(object):
|
|||||||
pass
|
pass
|
||||||
return result_offset
|
return result_offset
|
||||||
|
|
||||||
def all_instr(self, start, end, instr, target=None, include_beyond_target=False):
|
def inst_matches(self, start, end, instr, target=None, include_beyond_target=False):
|
||||||
"""
|
"""
|
||||||
Find all <instr> in the block from start to end.
|
Find all `instr` in the block from start to end.
|
||||||
<instr> is any python bytecode instruction or a list of opcodes
|
`instr` is a Python opcode or a list of opcodes
|
||||||
If <instr> is an opcode with a target (like a jump), a target
|
If `instr` is an opcode with a target (like a jump), a target
|
||||||
destination can be specified which must match precisely.
|
destination can be specified which must match precisely.
|
||||||
|
|
||||||
Return a list with indexes to them or [] if none found.
|
Return a list with indexes to them or [] if none found.
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
|
None in instr
|
||||||
|
except:
|
||||||
|
instr = [instr]
|
||||||
|
|
||||||
# FIXME: this is broken on 3.6+. Revise to use instructions self.insts
|
first = self.offset2inst_index[start]
|
||||||
|
result = []
|
||||||
|
for inst in self.insts[first:]:
|
||||||
|
if inst.opcode in instr:
|
||||||
|
if target is None:
|
||||||
|
result.append(inst.offset)
|
||||||
|
else:
|
||||||
|
t = self.get_target(inst.offset)
|
||||||
|
if include_beyond_target and t >= target:
|
||||||
|
result.append(inst.offset)
|
||||||
|
elif t == target:
|
||||||
|
result.append(inst.offset)
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
if inst.offset >= end:
|
||||||
|
break
|
||||||
|
pass
|
||||||
|
|
||||||
|
# FIXME: put in a test
|
||||||
|
# check = self.all_instr(start, end, instr, target, include_beyond_target)
|
||||||
|
# assert result == check
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
# FIXME: this is broken on 3.6+. Replace remaining (2.x-based) calls
|
||||||
|
# with inst_matches
|
||||||
|
def all_instr(self, start, end, instr, target=None, include_beyond_target=False):
|
||||||
|
"""
|
||||||
|
Find all `instr` in the block from start to end.
|
||||||
|
`instr` is any Python opcode 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
|
code = self.code
|
||||||
assert(start >= 0 and end <= len(code))
|
assert(start >= 0 and end <= len(code))
|
||||||
|
@@ -416,7 +416,7 @@ class Scanner2(Scanner):
|
|||||||
(self.opc.PJIT, self.opc.JUMP_FORWARD),
|
(self.opc.PJIT, self.opc.JUMP_FORWARD),
|
||||||
(self.opc.PJIT, self.opc.JUMP_ABSOLUTE)])
|
(self.opc.PJIT, self.opc.JUMP_ABSOLUTE)])
|
||||||
|
|
||||||
prelim = self.all_instr(start, end, self.stmt_opcodes)
|
prelim = self.all_instr(start, end, self.statement_opcodes)
|
||||||
|
|
||||||
stmts = self.stmts = set(prelim)
|
stmts = self.stmts = set(prelim)
|
||||||
pass_stmts = set()
|
pass_stmts = set()
|
||||||
|
@@ -40,7 +40,7 @@ JUMP_OPS = opcode_26.JUMP_OPS
|
|||||||
class Scanner26(scan.Scanner2):
|
class Scanner26(scan.Scanner2):
|
||||||
def __init__(self, show_asm=False):
|
def __init__(self, show_asm=False):
|
||||||
super(Scanner26, self).__init__(2.6, show_asm)
|
super(Scanner26, self).__init__(2.6, show_asm)
|
||||||
self.stmt_opcodes = frozenset([
|
self.statement_opcodes = frozenset([
|
||||||
self.opc.SETUP_LOOP, self.opc.BREAK_LOOP,
|
self.opc.SETUP_LOOP, self.opc.BREAK_LOOP,
|
||||||
self.opc.SETUP_FINALLY, self.opc.END_FINALLY,
|
self.opc.SETUP_FINALLY, self.opc.END_FINALLY,
|
||||||
self.opc.SETUP_EXCEPT, self.opc.POP_BLOCK,
|
self.opc.SETUP_EXCEPT, self.opc.POP_BLOCK,
|
||||||
|
@@ -25,7 +25,7 @@ class Scanner27(Scanner2):
|
|||||||
super(Scanner27, self).__init__(2.7, show_asm, is_pypy)
|
super(Scanner27, self).__init__(2.7, show_asm, is_pypy)
|
||||||
|
|
||||||
# opcodes that start statements
|
# opcodes that start statements
|
||||||
self.stmt_opcodes = frozenset([
|
self.statement_opcodes = frozenset([
|
||||||
self.opc.SETUP_LOOP, self.opc.BREAK_LOOP,
|
self.opc.SETUP_LOOP, self.opc.BREAK_LOOP,
|
||||||
self.opc.SETUP_FINALLY, self.opc.END_FINALLY,
|
self.opc.SETUP_FINALLY, self.opc.END_FINALLY,
|
||||||
self.opc.SETUP_EXCEPT,
|
self.opc.SETUP_EXCEPT,
|
||||||
|
@@ -428,6 +428,7 @@ class Scanner3(Scanner):
|
|||||||
.opname == 'FOR_ITER'
|
.opname == 'FOR_ITER'
|
||||||
and self.insts[i+1].opname == 'JUMP_FORWARD')
|
and self.insts[i+1].opname == 'JUMP_FORWARD')
|
||||||
|
|
||||||
|
|
||||||
if (is_continue or
|
if (is_continue or
|
||||||
(inst.offset in self.stmts and
|
(inst.offset in self.stmts and
|
||||||
(self.version != 3.0 or (hasattr(inst, 'linestart'))) and
|
(self.version != 3.0 or (hasattr(inst, 'linestart'))) and
|
||||||
@@ -610,7 +611,7 @@ class Scanner3(Scanner):
|
|||||||
|
|
||||||
# Compose preliminary list of indices with statements,
|
# Compose preliminary list of indices with statements,
|
||||||
# using plain statement opcodes
|
# using plain statement opcodes
|
||||||
prelim = self.all_instr(start, end, self.statement_opcodes)
|
prelim = self.inst_matches(start, end, self.statement_opcodes)
|
||||||
|
|
||||||
# Initialize final container with statements with
|
# Initialize final container with statements with
|
||||||
# preliminary data
|
# preliminary data
|
||||||
@@ -873,11 +874,12 @@ class Scanner3(Scanner):
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
fix = None
|
fix = None
|
||||||
jump_ifs = self.all_instr(start, self.next_stmt[offset],
|
jump_ifs = self.inst_matches(start, self.next_stmt[offset],
|
||||||
self.opc.POP_JUMP_IF_FALSE)
|
self.opc.POP_JUMP_IF_FALSE)
|
||||||
last_jump_good = True
|
last_jump_good = True
|
||||||
for j in jump_ifs:
|
for j in jump_ifs:
|
||||||
if target == self.get_target(j):
|
if target == self.get_target(j):
|
||||||
|
# FIXME: remove magic number
|
||||||
if self.lines[j].next == j + 3 and last_jump_good:
|
if self.lines[j].next == j + 3 and last_jump_good:
|
||||||
fix = j
|
fix = j
|
||||||
break
|
break
|
||||||
@@ -1139,13 +1141,14 @@ class Scanner3(Scanner):
|
|||||||
assert(start>=0 and end<=len(self.code) and start <= end)
|
assert(start>=0 and end<=len(self.code) and start <= end)
|
||||||
|
|
||||||
# Find all offsets of requested instructions
|
# Find all offsets of requested instructions
|
||||||
instr_offsets = self.all_instr(start, end, instr, target, include_beyond_target)
|
instr_offsets = self.inst_matches(start, end, instr, target,
|
||||||
|
include_beyond_target)
|
||||||
# Get all POP_JUMP_IF_TRUE (or) offsets
|
# Get all POP_JUMP_IF_TRUE (or) offsets
|
||||||
if self.version == 3.0:
|
if self.version == 3.0:
|
||||||
jump_true_op = self.opc.JUMP_IF_TRUE
|
jump_true_op = self.opc.JUMP_IF_TRUE
|
||||||
else:
|
else:
|
||||||
jump_true_op = self.opc.POP_JUMP_IF_TRUE
|
jump_true_op = self.opc.POP_JUMP_IF_TRUE
|
||||||
pjit_offsets = self.all_instr(start, end, jump_true_op)
|
pjit_offsets = self.inst_matches(start, end, jump_true_op)
|
||||||
filtered = []
|
filtered = []
|
||||||
for pjit_offset in pjit_offsets:
|
for pjit_offset in pjit_offsets:
|
||||||
pjit_tgt = self.get_target(pjit_offset) - 3
|
pjit_tgt = self.get_target(pjit_offset) - 3
|
||||||
|
@@ -195,11 +195,12 @@ class Scanner30(Scanner3):
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
fix = None
|
fix = None
|
||||||
jump_ifs = self.all_instr(start, self.next_stmt[offset],
|
jump_ifs = self.inst_matches(start, self.next_stmt[offset],
|
||||||
opc.JUMP_IF_FALSE)
|
opc.JUMP_IF_FALSE)
|
||||||
last_jump_good = True
|
last_jump_good = True
|
||||||
for j in jump_ifs:
|
for j in jump_ifs:
|
||||||
if target == self.get_target(j):
|
if target == self.get_target(j):
|
||||||
|
# FIXME: remove magic number
|
||||||
if self.lines[j].next == j + 3 and last_jump_good:
|
if self.lines[j].next == j + 3 and last_jump_good:
|
||||||
fix = j
|
fix = j
|
||||||
break
|
break
|
||||||
|
Reference in New Issue
Block a user