Bug in for loop with try. Add more of 2.7's COME_FROM statements.

spark.py: add tracing reduce rules. main: reduce cutsines.
Start history
This commit is contained in:
rocky
2015-12-21 21:08:08 -05:00
parent 6b0bb124ea
commit 6a49cd2c69
12 changed files with 225 additions and 27 deletions

View File

@@ -29,7 +29,6 @@ globals().update(dis.opmap)
from uncompyle6.opcodes.opcode_34 import *
import uncompyle6.scanner as scan
@@ -60,21 +59,22 @@ class Scanner34(scan.Scanner):
bytecode = dis.Bytecode(co)
# self.lines contains (block,addrLastInstr)
# if classname:
# classname = '_' + classname.lstrip('_') + '__'
if classname:
classname = '_' + classname.lstrip('_') + '__'
# def unmangle(name):
# if name.startswith(classname) and name[-2:] != '__':
# return name[len(classname) - 2:]
# return name
def unmangle(name):
if name.startswith(classname) and name[-2:] != '__':
return name[len(classname) - 2:]
return name
# free = [ unmangle(name) for name in (co.co_cellvars + co.co_freevars) ]
# names = [ unmangle(name) for name in co.co_names ]
# varnames = [ unmangle(name) for name in co.co_varnames ]
# else:
# free = co.co_cellvars + co.co_freevars
# names = co.co_names
# varnames = co.co_varnames
# free = [ unmangle(name) for name in (co.co_cellvars + co.co_freevars) ]
# names = [ unmangle(name) for name in co.co_names ]
# varnames = [ unmangle(name) for name in co.co_varnames ]
else:
# free = co.co_cellvars + co.co_freevars
# names = co.co_names
# varnames = co.co_varnames
pass
# Scan for assertions. Later we will
# turn 'LOAD_GLOBAL' to 'LOAD_ASSERT' for those
@@ -439,6 +439,33 @@ class Scanner34(scan.Scanner):
target += offset + 3
return target
def next_except_jump(self, start):
"""
Return the next jump that was generated by an except SomeException:
construct in a try...except...else clause or None if not found.
"""
if self.code[start] == DUP_TOP:
except_match = self.first_instr(start, len(self.code), POP_JUMP_IF_FALSE)
if except_match:
jmp = self.prev_op[self.get_target(except_match)]
self.ignore_if.add(except_match)
self.not_continue.add(jmp)
return jmp
count_END_FINALLY = 0
count_SETUP_ = 0
for i in self.op_range(start, len(self.code)):
op = self.code[i]
if op == END_FINALLY:
if count_END_FINALLY == count_SETUP_:
assert self.code[self.prev_op[i]] in (JUMP_ABSOLUTE, JUMP_FORWARD, RETURN_VALUE)
self.not_continue.add(self.prev_op[i])
return self.prev_op[i]
count_END_FINALLY += 1
elif op in (SETUP_EXCEPT, SETUP_WITH, SETUP_FINALLY):
count_SETUP_ += 1
def detect_structure(self, offset):
"""
Detect structures and their boundaries to fix optimizied jumps
@@ -459,8 +486,51 @@ class Scanner34(scan.Scanner):
start = curent_start
end = curent_end
parent = struct
pass
if op in (POP_JUMP_IF_FALSE, POP_JUMP_IF_TRUE):
if op == SETUP_EXCEPT:
start = offset + 3
target = self.get_target(offset)
end = self.restrict_to_parent(target, parent)
if target != end:
self.fixed_jumps[pos] = end
# print target, end, parent
# Add the try block
self.structs.append({'type': 'try',
'start': start,
'end': end-4})
# Now isolate the except and else blocks
end_else = start_else = self.get_target(self.prev_op[end])
# Add the except blocks
i = end
while self.code[i] != END_FINALLY:
jmp = self.next_except_jump(i)
if self.code[jmp] == RETURN_VALUE:
self.structs.append({'type': 'except',
'start': i,
'end': jmp+1})
i = jmp + 1
else:
if self.get_target(jmp) != start_else:
end_else = self.get_target(jmp)
if self.code[jmp] == JUMP_FORWARD:
self.fixed_jumps[jmp] = -1
self.structs.append({'type': 'except',
'start': i,
'end': jmp})
i = jmp + 3
# Add the try-else block
if end_else != start_else:
r_end_else = self.restrict_to_parent(end_else, parent)
self.structs.append({'type': 'try-else',
'start': i+1,
'end': r_end_else})
self.fixed_jumps[i] = r_end_else
else:
self.fixed_jumps[i] = i+1
elif op in (POP_JUMP_IF_FALSE, POP_JUMP_IF_TRUE):
start = offset + self.op_size(op)
target = self.get_target(offset)
rtarget = self.restrict_to_parent(target, parent)