You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
WIP : Add THEN to disambigute from "and"
This commit is contained in:
@@ -101,10 +101,10 @@ class Scanner2(scan.Scanner):
|
||||
|
||||
Token = self.Token # shortcut
|
||||
|
||||
n = self.setup_code(co)
|
||||
codelen = self.setup_code(co)
|
||||
|
||||
self.build_lines_data(co, n)
|
||||
self.build_prev_op(n)
|
||||
self.build_lines_data(co, codelen)
|
||||
self.build_prev_op(codelen)
|
||||
|
||||
free, names, varnames = self.unmangle_code_names(co, classname)
|
||||
self.names = names
|
||||
@@ -113,7 +113,7 @@ class Scanner2(scan.Scanner):
|
||||
# turn 'LOAD_GLOBAL' to 'LOAD_ASSERT'.
|
||||
# 'LOAD_ASSERT' is used in assert statements.
|
||||
self.load_asserts = set()
|
||||
for i in self.op_range(0, n):
|
||||
for i in self.op_range(0, codelen):
|
||||
# We need to detect the difference between:
|
||||
# raise AssertionError
|
||||
# and
|
||||
@@ -138,7 +138,7 @@ class Scanner2(scan.Scanner):
|
||||
last_stmt = self.next_stmt[0]
|
||||
i = self.next_stmt[last_stmt]
|
||||
replace = {}
|
||||
while i < n-1:
|
||||
while i < codelen - 1:
|
||||
if self.lines[last_stmt].next > i:
|
||||
# Distinguish "print ..." from "print ...,"
|
||||
if self.code[last_stmt] == self.opc.PRINT_ITEM:
|
||||
@@ -150,7 +150,7 @@ class Scanner2(scan.Scanner):
|
||||
i = self.next_stmt[i]
|
||||
|
||||
extended_arg = 0
|
||||
for offset in self.op_range(0, n):
|
||||
for offset in self.op_range(0, codelen):
|
||||
if offset in jump_targets:
|
||||
jump_idx = 0
|
||||
# We want to process COME_FROMs to the same offset to be in *descending*
|
||||
@@ -176,6 +176,7 @@ class Scanner2(scan.Scanner):
|
||||
offset="%s_%d" % (offset, jump_idx),
|
||||
has_arg = True))
|
||||
jump_idx += 1
|
||||
pass
|
||||
|
||||
op = self.code[offset]
|
||||
op_name = self.opc.opname[op]
|
||||
@@ -675,6 +676,8 @@ class Scanner2(scan.Scanner):
|
||||
self.fixed_jumps[offset] = rtarget
|
||||
return
|
||||
|
||||
jump_if_offset = offset
|
||||
|
||||
start = offset+3
|
||||
pre = self.prev
|
||||
|
||||
@@ -827,20 +830,86 @@ class Scanner2(scan.Scanner):
|
||||
jump_target = self.get_target(next_offset, next_op)
|
||||
if jump_target in self.setup_loops:
|
||||
self.structs.append({'type': 'while-loop',
|
||||
'start': start - 3,
|
||||
'start': jump_if_offset,
|
||||
'end': jump_target})
|
||||
self.fixed_jumps[start-3] = jump_target
|
||||
self.fixed_jumps[jump_if_offset] = jump_target
|
||||
return
|
||||
|
||||
end = self.restrict_to_parent(if_end, parent)
|
||||
|
||||
self.structs.append({'type': 'if-then',
|
||||
'start': start-3,
|
||||
'end': pre_rtarget})
|
||||
if_then_maybe = None
|
||||
|
||||
if 2.2 <= self.version <= 2.6:
|
||||
# Take the JUMP_IF target. In an "if/then", it will be
|
||||
# a POP_TOP instruction and the instruction before it
|
||||
# will be a JUMP_FORWARD to just after the POP_TOP.
|
||||
# For example:
|
||||
# Good:
|
||||
# 3 JUMP_IF_FALSE 33 'to 39'
|
||||
# ..
|
||||
# 36 JUMP_FORWARD 1 'to 40'
|
||||
# 39 POP_TOP
|
||||
# 40 ...
|
||||
# example:
|
||||
|
||||
# BAD (is an "and"):
|
||||
# 28 JUMP_IF_FALSE 4 'to 35'
|
||||
# ...
|
||||
# 32 JUMP_ABSOLUTE 40 'to 40' # should be 36 or there should
|
||||
# # be a COME_FROM at the pop top
|
||||
# # before 40 to 35
|
||||
# 35 POP_TOP
|
||||
# 36 ...
|
||||
# 39 POP_TOP
|
||||
# 39_0 COME_FROM 3
|
||||
# 40 ...
|
||||
|
||||
if self.opc.opname[code[jump_if_offset]].startswith('JUMP_IF'):
|
||||
jump_if_target = code[jump_if_offset+1]
|
||||
if self.opc.opname[code[jump_if_target + jump_if_offset + 3]] == 'POP_TOP':
|
||||
jump_inst = jump_if_target + jump_if_offset
|
||||
jump_offset = code[jump_inst+1]
|
||||
jump_op = self.opc.opname[code[jump_inst]]
|
||||
if (jump_op == 'JUMP_FORWARD' and jump_offset == 1):
|
||||
self.structs.append({'type': 'if-then',
|
||||
'start': start-3,
|
||||
'end': pre_rtarget})
|
||||
|
||||
self.thens[start] = end
|
||||
elif jump_op == 'JUMP_ABSOLUTE':
|
||||
if_then_maybe = {'type': 'if-then',
|
||||
'start': start-3,
|
||||
'end': pre_rtarget}
|
||||
|
||||
elif self.version == 2.7:
|
||||
self.structs.append({'type': 'if-then',
|
||||
'start': start-3,
|
||||
'end': pre_rtarget})
|
||||
|
||||
self.not_continue.add(pre_rtarget)
|
||||
|
||||
if rtarget < end:
|
||||
# We have an "else" block of some kind.
|
||||
# Is it associated with "if_then_maybe" seen above?
|
||||
# These will be linked in this funny way:
|
||||
|
||||
# 198 JUMP_IF_FALSE 18 'to 219'
|
||||
# 201 POP_TOP
|
||||
# ...
|
||||
# 216 JUMP_ABSOLUTE 256 'to 256'
|
||||
# 219 POP_TOP
|
||||
# ...
|
||||
# 252 JUMP_FORWARD 1 'to 256'
|
||||
# 255 POP_TOP
|
||||
# 256
|
||||
if if_then_maybe and jump_op == 'JUMP_ABSOLUTE':
|
||||
jump_target = self.get_target(jump_inst, code[jump_inst])
|
||||
if self.opc.opname[code[end]] == 'JUMP_FORWARD':
|
||||
end_target = self.get_target(end, code[end])
|
||||
if jump_target == end_target:
|
||||
self.structs.append(if_then_maybe)
|
||||
self.thens[start] = end
|
||||
|
||||
self.structs.append({'type': 'else',
|
||||
'start': rtarget,
|
||||
'end': end})
|
||||
@@ -849,6 +918,7 @@ class Scanner2(scan.Scanner):
|
||||
self.structs.append({'type': 'if-then',
|
||||
'start': start,
|
||||
'end': rtarget})
|
||||
self.thens[start] = rtarget
|
||||
if self.version == 2.7 or code[pre_rtarget+1] != self.opc.JUMP_FORWARD:
|
||||
self.return_end_ifs.add(pre_rtarget)
|
||||
|
||||
@@ -887,6 +957,7 @@ class Scanner2(scan.Scanner):
|
||||
self.return_end_ifs = set()
|
||||
self.setup_loop_targets = {} # target given setup_loop offset
|
||||
self.setup_loops = {} # setup_loop offset given target
|
||||
self.thens = {} # JUMP_IF's that separate the 'then' part of an 'if'
|
||||
|
||||
targets = {}
|
||||
for offset in self.op_range(0, n):
|
||||
|
Reference in New Issue
Block a user