You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-03 00:45:53 +08:00
Python 2.6- bug: RETURN_ENDIF, POP_TOP ..
POP_TOP should be excluded as a potentional statement beginning
This commit is contained in:
@@ -199,9 +199,12 @@ class Python26Parser(Python2Parser):
|
||||
'''
|
||||
ret_and ::= expr jmp_false ret_expr_or_cond COME_FROM
|
||||
ret_or ::= expr jmp_true ret_expr_or_cond COME_FROM
|
||||
ret_cond ::= expr jmp_false expr RETURN_END_IF come_from_pop ret_expr_or_cond
|
||||
ret_cond ::= expr jmp_false expr RETURN_END_IF POP_TOP ret_expr_or_cond
|
||||
ret_cond ::= expr jmp_false expr ret_expr_or_cond
|
||||
ret_cond_not ::= expr jmp_true expr RETURN_END_IF come_from_pop ret_expr_or_cond
|
||||
ret_cond_not ::= expr jmp_true expr RETURN_END_IF POP_TOP ret_expr_or_cond
|
||||
|
||||
return_if_stmt ::= ret_expr RETURN_END_IF POP_TOP
|
||||
return_stmt ::= ret_expr RETURN_VALUE POP_TOP
|
||||
|
||||
# FIXME: split into Python 2.5
|
||||
ret_or ::= expr jmp_true ret_expr_or_cond come_froms
|
||||
|
@@ -393,14 +393,16 @@ class Scanner2(scan.Scanner):
|
||||
continue
|
||||
elif code[s] == self.opc.POP_TOP:
|
||||
# The POP_TOP in:
|
||||
# ROT_TWO, POP_TOP or
|
||||
# JUMP_IF_{FALSE,TRUE}, POP_TOP
|
||||
# ROT_TWO, POP_TOP,
|
||||
# RETURN_xxx, POP_TOP (in 2.6-), or
|
||||
# JUMP_IF_{FALSE,TRUE}, POP_TOP (in 2.6-)
|
||||
# is part of the previous instruction and not the
|
||||
# beginning of a new statement
|
||||
prev = code[self.prev[s]]
|
||||
if (prev == self.opc.ROT_TWO or
|
||||
self.version <= 2.6 and prev in
|
||||
(self.opc.JUMP_IF_FALSE, self.opc.JUMP_IF_TRUE)):
|
||||
(self.opc.JUMP_IF_FALSE, self.opc.JUMP_IF_TRUE,
|
||||
self.opc.RETURN_VALUE)):
|
||||
stmts.remove(s)
|
||||
continue
|
||||
elif code[s] in self.designator_ops:
|
||||
@@ -793,12 +795,11 @@ class Scanner2(scan.Scanner):
|
||||
|
||||
def find_jump_targets(self):
|
||||
'''
|
||||
Detect all offsets in a byte code which are jump targets.
|
||||
Detect all offsets in a byte code which are jump targets
|
||||
where we might insert a COME_FROM instruction.
|
||||
|
||||
Return the list of offsets.
|
||||
|
||||
This procedure is modelled after dis.findlabels(), but here
|
||||
for each target the number of jumps are counted.
|
||||
Return the list of offsets. An instruction can be jumped
|
||||
to in from multiple instructions.
|
||||
'''
|
||||
|
||||
n = len(self.code)
|
||||
@@ -836,7 +837,14 @@ class Scanner2(scan.Scanner):
|
||||
label = oparg
|
||||
|
||||
if label is not None and label != -1:
|
||||
targets[label] = targets.get(label, []) + [offset]
|
||||
# In Python <= 2.6, the POP_TOP in:
|
||||
# RETURN_VALUE, POP_TOP
|
||||
# does now start a new statement
|
||||
# Otherwise, we have want to add a "COME_FROM"
|
||||
if not (self.version <= 2.6 and
|
||||
self.code[label] == self.opc.POP_TOP and
|
||||
self.code[self.prev[label]] == self.opc.RETURN_VALUE):
|
||||
targets[label] = targets.get(label, []) + [offset]
|
||||
elif op == self.opc.END_FINALLY and offset in self.fixed_jumps:
|
||||
label = self.fixed_jumps[offset]
|
||||
targets[label] = targets.get(label, []) + [offset]
|
||||
|
Reference in New Issue
Block a user