Add 3.6+ grammar for except's ending in RETURN...

Not totally out of the maze in 3.6 control flow...
There are still problems with erroneous RETURN_VALUEs becoming RETURN_END_IF,
This commit is contained in:
rocky
2017-11-08 10:31:38 -05:00
parent f82165aaa7
commit 0bb793239b
3 changed files with 13 additions and 0 deletions

View File

@@ -262,6 +262,10 @@ class PythonParser(GenericASTBuilder):
return_stmt ::= ret_expr RETURN_VALUE
return_stmt_lambda ::= ret_expr RETURN_VALUE_LAMBDA
# return_stmts are a sequence of statements that ends in a RETURN statement.
# In later Python versions with jump optimization, this can cause JUMPs
# that would normally appear to be omitted.
return_stmts ::= return_stmt
return_stmts ::= _stmts return_stmt

View File

@@ -57,6 +57,12 @@ class Python36Parser(Python35Parser):
WITH_CLEANUP_FINISH END_FINALLY
except_suite ::= c_stmts_opt COME_FROM POP_EXCEPT jump_except COME_FROM
# In 3.6+, A sequence of statements ending in a RETURN can cause
# JUMP_FORWARD END_FINALLY to be omitted from try middle
except_return ::= POP_TOP POP_TOP POP_TOP return_stmts
try_middle ::= JUMP_FORWARD COME_FROM_EXCEPT except_return
"""
def add_custom_rules(self, tokens, customize):

View File

@@ -384,9 +384,12 @@ class Scanner3(Scanner):
if last_op_was_break and opname == 'CONTINUE':
last_op_was_break = False
continue
# FIXME: go over for Python 3.6+. This is sometimes wrong
elif op == self.opc.RETURN_VALUE:
if inst.offset in self.return_end_ifs:
opname = 'RETURN_END_IF'
elif inst.offset in self.load_asserts:
opname = 'LOAD_ASSERT'