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- try/except control flow detection
This commit is contained in:
@@ -181,6 +181,11 @@ class Python2Parser(PythonParser):
|
|||||||
trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
trystmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
||||||
try_middle COME_FROM
|
try_middle COME_FROM
|
||||||
|
|
||||||
|
try_middle ::= JUMP_FORWARD COME_FROM except_stmts
|
||||||
|
END_FINALLY COME_FROM
|
||||||
|
try_middle ::= jmp_abs COME_FROM except_stmts
|
||||||
|
END_FINALLY
|
||||||
|
|
||||||
except_stmts ::= except_stmts except_stmt
|
except_stmts ::= except_stmts except_stmt
|
||||||
except_stmts ::= except_stmt
|
except_stmts ::= except_stmt
|
||||||
|
|
||||||
|
@@ -27,11 +27,7 @@ class Python26Parser(Python2Parser):
|
|||||||
POP_TOP END_FINALLY come_froms
|
POP_TOP END_FINALLY come_froms
|
||||||
|
|
||||||
try_middle ::= JUMP_FORWARD COME_FROM except_stmts
|
try_middle ::= JUMP_FORWARD COME_FROM except_stmts
|
||||||
END_FINALLY come_froms
|
come_from_pop END_FINALLY COME_FROM
|
||||||
try_middle ::= JUMP_FORWARD COME_FROM except_stmts
|
|
||||||
come_from_pop END_FINALLY come_froms
|
|
||||||
try_middle ::= JUMP_FORWARD COME_FROM except_stmts
|
|
||||||
END_FINALLY come_froms
|
|
||||||
|
|
||||||
try_middle ::= jmp_abs COME_FROM except_stmts
|
try_middle ::= jmp_abs COME_FROM except_stmts
|
||||||
POP_TOP END_FINALLY
|
POP_TOP END_FINALLY
|
||||||
@@ -39,9 +35,6 @@ class Python26Parser(Python2Parser):
|
|||||||
try_middle ::= jmp_abs COME_FROM except_stmts
|
try_middle ::= jmp_abs COME_FROM except_stmts
|
||||||
come_from_pop END_FINALLY
|
come_from_pop END_FINALLY
|
||||||
|
|
||||||
try_middle ::= jmp_abs COME_FROM except_stmts
|
|
||||||
END_FINALLY
|
|
||||||
|
|
||||||
trystmt ::= SETUP_EXCEPT suite_stmts_opt come_from_pop
|
trystmt ::= SETUP_EXCEPT suite_stmts_opt come_from_pop
|
||||||
try_middle
|
try_middle
|
||||||
|
|
||||||
|
@@ -27,11 +27,6 @@ class Python27Parser(Python2Parser):
|
|||||||
|
|
||||||
def p_try27(self, args):
|
def p_try27(self, args):
|
||||||
"""
|
"""
|
||||||
try_middle ::= JUMP_FORWARD COME_FROM except_stmts
|
|
||||||
END_FINALLY COME_FROM
|
|
||||||
try_middle ::= jmp_abs COME_FROM except_stmts
|
|
||||||
END_FINALLY
|
|
||||||
|
|
||||||
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
tryelsestmt ::= SETUP_EXCEPT suite_stmts_opt POP_BLOCK
|
||||||
try_middle else_suite COME_FROM
|
try_middle else_suite COME_FROM
|
||||||
|
|
||||||
|
@@ -44,7 +44,7 @@ class Scanner2(scan.Scanner):
|
|||||||
Pick out tokens from an uncompyle6 code object, and transform them,
|
Pick out tokens from an uncompyle6 code object, and transform them,
|
||||||
returning a list of uncompyle6 'Token's.
|
returning a list of uncompyle6 'Token's.
|
||||||
|
|
||||||
The tranformations are made to assist the deparsing grammar.
|
The transformations are made to assist the deparsing grammar.
|
||||||
Specificially:
|
Specificially:
|
||||||
- various types of LOAD_CONST's are categorized in terms of what they load
|
- various types of LOAD_CONST's are categorized in terms of what they load
|
||||||
- COME_FROM instructions are added to assist parsing control structures
|
- COME_FROM instructions are added to assist parsing control structures
|
||||||
@@ -56,7 +56,7 @@ class Scanner2(scan.Scanner):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
show_asm = self.show_asm if not show_asm else show_asm
|
show_asm = self.show_asm if not show_asm else show_asm
|
||||||
# show_asm = 'both'
|
# show_asm = 'after'
|
||||||
if show_asm in ('both', 'before'):
|
if show_asm in ('both', 'before'):
|
||||||
from xdis.bytecode import Bytecode
|
from xdis.bytecode import Bytecode
|
||||||
bytecode = Bytecode(co, self.opc)
|
bytecode = Bytecode(co, self.opc)
|
||||||
@@ -846,6 +846,8 @@ class Scanner2(scan.Scanner):
|
|||||||
pass
|
pass
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
# FIXME: All the <2.6 conditions are is horrible. We need a better way.
|
||||||
if label is not None and label != -1:
|
if label is not None and label != -1:
|
||||||
# In Python <= 2.6, the POP_TOP in:
|
# In Python <= 2.6, the POP_TOP in:
|
||||||
# RETURN_VALUE, POP_TOP
|
# RETURN_VALUE, POP_TOP
|
||||||
@@ -854,8 +856,19 @@ class Scanner2(scan.Scanner):
|
|||||||
if not (self.version <= 2.6 and
|
if not (self.version <= 2.6 and
|
||||||
self.code[label] == self.opc.POP_TOP and
|
self.code[label] == self.opc.POP_TOP and
|
||||||
self.code[self.prev[label]] == self.opc.RETURN_VALUE):
|
self.code[self.prev[label]] == self.opc.RETURN_VALUE):
|
||||||
targets[label] = targets.get(label, []) + [offset]
|
# In Python <= 2.6, don't add a COME_FROM, for:
|
||||||
elif op == self.opc.END_FINALLY and offset in self.fixed_jumps:
|
# JUMP_FORWARD, END_FINALLY
|
||||||
|
# or:
|
||||||
|
# JUMP_FORWARD, POP_TOP, END_FINALLY
|
||||||
|
if not (self.version <= 2.6 and op == self.opc.JUMP_FORWARD
|
||||||
|
and ((self.code[offset+3] == self.opc.END_FINALLY)
|
||||||
|
or (self.code[offset+3] == self.opc.POP_TOP
|
||||||
|
and self.code[offset+4] == self.opc.END_FINALLY))):
|
||||||
|
targets[label] = targets.get(label, []) + [offset]
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
pass
|
||||||
|
elif op == self.opc.END_FINALLY and offset in self.fixed_jumps and self.version == 2.7:
|
||||||
label = self.fixed_jumps[offset]
|
label = self.fixed_jumps[offset]
|
||||||
targets[label] = targets.get(label, []) + [offset]
|
targets[label] = targets.get(label, []) + [offset]
|
||||||
return targets
|
return targets
|
||||||
|
@@ -75,7 +75,7 @@ class Scanner26(scan.Scanner2):
|
|||||||
Pick out tokens from an uncompyle6 code object, and transform them,
|
Pick out tokens from an uncompyle6 code object, and transform them,
|
||||||
returning a list of uncompyle6 'Token's.
|
returning a list of uncompyle6 'Token's.
|
||||||
|
|
||||||
The tranformations are made to assist the deparsing grammar.
|
The transformations are made to assist the deparsing grammar.
|
||||||
Specificially:
|
Specificially:
|
||||||
- various types of LOAD_CONST's are categorized in terms of what they load
|
- various types of LOAD_CONST's are categorized in terms of what they load
|
||||||
- COME_FROM instructions are added to assist parsing control structures
|
- COME_FROM instructions are added to assist parsing control structures
|
||||||
@@ -87,7 +87,7 @@ class Scanner26(scan.Scanner2):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
show_asm = self.show_asm if not show_asm else show_asm
|
show_asm = self.show_asm if not show_asm else show_asm
|
||||||
# show_asm = 'both'
|
# show_asm = 'after'
|
||||||
if show_asm in ('both', 'before'):
|
if show_asm in ('both', 'before'):
|
||||||
from xdis.bytecode import Bytecode
|
from xdis.bytecode import Bytecode
|
||||||
bytecode = Bytecode(co, self.opc)
|
bytecode = Bytecode(co, self.opc)
|
||||||
|
@@ -115,7 +115,7 @@ class Scanner3(Scanner):
|
|||||||
Pick out tokens from an uncompyle6 code object, and transform them,
|
Pick out tokens from an uncompyle6 code object, and transform them,
|
||||||
returning a list of uncompyle6 'Token's.
|
returning a list of uncompyle6 'Token's.
|
||||||
|
|
||||||
The tranformations are made to assist the deparsing grammar.
|
The transformations are made to assist the deparsing grammar.
|
||||||
Specificially:
|
Specificially:
|
||||||
- various types of LOAD_CONST's are categorized in terms of what they load
|
- various types of LOAD_CONST's are categorized in terms of what they load
|
||||||
- COME_FROM instructions are added to assist parsing control structures
|
- COME_FROM instructions are added to assist parsing control structures
|
||||||
|
Reference in New Issue
Block a user