Python 3.x else clause detection and..

- Strengthen verify check.
- weak verification on Python 3.5 for now
This commit is contained in:
rocky
2016-12-09 21:10:10 -05:00
parent 9cc2700160
commit a5d2237435
6 changed files with 66 additions and 16 deletions

View File

@@ -226,6 +226,14 @@ class Scanner3(Scanner):
jump_idx += 1
pass
pass
elif inst.offset in self.else_start:
end_offset = self.else_start[inst.offset]
tokens.append(Token('ELSE',
None, repr(end_offset),
offset='%s' % (inst.offset),
has_arg = True, opc=self.opc))
pass
pattr = inst.argrepr
opname = inst.opname
@@ -425,6 +433,7 @@ class Scanner3(Scanner):
self.fixed_jumps = {}
self.ignore_if = set()
self.build_statement_indices()
self.else_start = {}
# Containers filled by detect_structure()
self.not_continue = set()
@@ -759,15 +768,28 @@ class Scanner3(Scanner):
code[prev_op[prev_op[rtarget]]] != self.opc.JUMP_ABSOLUTE)):
rtarget = prev_op[rtarget]
# Does the "if" jump just beyond a jump op, then this can be
# a block inside an "if" statement
# Does the "jump if" jump beyond a jump op?
# That is, we have something like:
# POP_JUMP_IF_FALSE HERE
# ...
# JUMP_FORWARD
# HERE:
#
# If so, this can be block inside an "if" statement
# or a conditional assignment like:
# x = 1 if x else 2
#
# There are other contexts we may need to consider
# like whether the target is "END_FINALLY"
# or if the condition jump is to a forward location
if self.is_jump_forward(prev_op[rtarget]):
if_end = self.get_target(prev_op[rtarget])
rrtarget = prev_op[rtarget]
if_end = self.get_target(rrtarget)
# Is this a loop and not an "if" statement?
if ((if_end < prev_op[rtarget]) and
# If the jump target is back, we are looping
if (if_end < rrtarget and
(code[prev_op[if_end]] == self.opc.SETUP_LOOP)):
if(if_end > start):
if (if_end > start):
return
end = self.restrict_to_parent(if_end, parent)
@@ -777,10 +799,13 @@ class Scanner3(Scanner):
'end': prev_op[rtarget]})
self.not_continue.add(prev_op[rtarget])
if rtarget < end:
self.structs.append({'type': 'if-else',
if rtarget < end and (
code[rtarget] != self.opc.END_FINALLY
and code[prev_op[rrtarget]] != self.opc.POP_EXCEPT):
self.structs.append({'type': 'else',
'start': rtarget,
'end': end})
self.else_start[rtarget] = end
elif code[prev_op[rtarget]] == self.opc.RETURN_VALUE:
self.structs.append({'type': 'if-then',
'start': start,
@@ -870,7 +895,9 @@ class Scanner3(Scanner):
op = self.code[i]
if op == self.opc.END_FINALLY:
if count_END_FINALLY == count_SETUP_:
assert self.code[self.prev_op[i]] in (JUMP_ABSOLUTE, JUMP_FORWARD, RETURN_VALUE)
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