Commit 5c1ef360 authored by Stefan Behnel's avatar Stefan Behnel

clean up exc_info handling in 'with' statement implementation

parent 6aaac39d
...@@ -1944,7 +1944,7 @@ class TempNode(ExprNode): ...@@ -1944,7 +1944,7 @@ class TempNode(ExprNode):
subexprs = [] subexprs = []
def __init__(self, pos, type, env): def __init__(self, pos, type, env=None):
ExprNode.__init__(self, pos) ExprNode.__init__(self, pos)
self.type = type self.type = type
if type.is_pyobject: if type.is_pyobject:
...@@ -1954,6 +1954,9 @@ class TempNode(ExprNode): ...@@ -1954,6 +1954,9 @@ class TempNode(ExprNode):
def analyse_types(self, env): def analyse_types(self, env):
return self.type return self.type
def analyse_target_declaration(self, env):
pass
def generate_result_code(self, code): def generate_result_code(self, code):
pass pass
......
...@@ -5008,7 +5008,7 @@ class ExceptClauseNode(Node): ...@@ -5008,7 +5008,7 @@ class ExceptClauseNode(Node):
# pattern [ExprNode] # pattern [ExprNode]
# target ExprNode or None # target ExprNode or None
# body StatNode # body StatNode
# excinfo_target NameNode or None optional target for exception info # excinfo_target ResultRefNode or None optional target for exception info
# match_flag string result of exception match # match_flag string result of exception match
# exc_value ExcValueNode used internally # exc_value ExcValueNode used internally
# function_name string qualified name of enclosing function # function_name string qualified name of enclosing function
...@@ -5026,8 +5026,6 @@ class ExceptClauseNode(Node): ...@@ -5026,8 +5026,6 @@ class ExceptClauseNode(Node):
def analyse_declarations(self, env): def analyse_declarations(self, env):
if self.target: if self.target:
self.target.analyse_target_declaration(env) self.target.analyse_target_declaration(env)
if self.excinfo_target is not None:
self.excinfo_target.analyse_target_declaration(env)
self.body.analyse_declarations(env) self.body.analyse_declarations(env)
def analyse_expressions(self, env): def analyse_expressions(self, env):
...@@ -5048,7 +5046,6 @@ class ExceptClauseNode(Node): ...@@ -5048,7 +5046,6 @@ class ExceptClauseNode(Node):
self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[ self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)]) ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
self.excinfo_tuple.analyse_expressions(env) self.excinfo_tuple.analyse_expressions(env)
self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
self.body.analyse_expressions(env) self.body.analyse_expressions(env)
...@@ -5103,7 +5100,7 @@ class ExceptClauseNode(Node): ...@@ -5103,7 +5100,7 @@ class ExceptClauseNode(Node):
for tempvar, node in zip(exc_vars, self.excinfo_tuple.args): for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
node.set_var(tempvar) node.set_var(tempvar)
self.excinfo_tuple.generate_evaluation_code(code) self.excinfo_tuple.generate_evaluation_code(code)
self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code) self.excinfo_target.result_code = self.excinfo_tuple.result()
old_break_label, old_continue_label = code.break_label, code.continue_label old_break_label, old_continue_label = code.break_label, code.continue_label
code.break_label = code.new_label('except_break') code.break_label = code.new_label('except_break')
...@@ -5113,24 +5110,32 @@ class ExceptClauseNode(Node): ...@@ -5113,24 +5110,32 @@ class ExceptClauseNode(Node):
code.funcstate.exc_vars = exc_vars code.funcstate.exc_vars = exc_vars
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
code.funcstate.exc_vars = old_exc_vars code.funcstate.exc_vars = old_exc_vars
if self.excinfo_target is not None:
self.excinfo_tuple.generate_disposal_code(code)
for var in exc_vars: for var in exc_vars:
code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var)) code.put_decref_clear(var, py_object_type)
code.put_goto(end_label) code.put_goto(end_label)
if code.label_used(code.break_label): if code.label_used(code.break_label):
code.put_label(code.break_label) code.put_label(code.break_label)
if self.excinfo_target is not None:
self.excinfo_tuple.generate_disposal_code(code)
for var in exc_vars: for var in exc_vars:
code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var)) code.put_decref_clear(var, py_object_type)
code.put_goto(old_break_label) code.put_goto(old_break_label)
code.break_label = old_break_label code.break_label = old_break_label
if code.label_used(code.continue_label): if code.label_used(code.continue_label):
code.put_label(code.continue_label) code.put_label(code.continue_label)
if self.excinfo_target is not None:
self.excinfo_tuple.generate_disposal_code(code)
for var in exc_vars: for var in exc_vars:
code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var)) code.put_decref_clear(var, py_object_type)
code.put_goto(old_continue_label) code.put_goto(old_continue_label)
code.continue_label = old_continue_label code.continue_label = old_continue_label
if self.excinfo_target is not None:
self.excinfo_tuple.free_temps(code)
for temp in exc_vars: for temp in exc_vars:
code.funcstate.release_temp(temp) code.funcstate.release_temp(temp)
......
...@@ -11,11 +11,12 @@ import Naming ...@@ -11,11 +11,12 @@ import Naming
import ExprNodes import ExprNodes
import Nodes import Nodes
import Options import Options
import Builtin
from Cython.Compiler.Visitor import VisitorTransform, TreeVisitor from Cython.Compiler.Visitor import VisitorTransform, TreeVisitor
from Cython.Compiler.Visitor import CythonTransform, EnvTransform, ScopeTrackingTransform from Cython.Compiler.Visitor import CythonTransform, EnvTransform, ScopeTrackingTransform
from Cython.Compiler.ModuleNode import ModuleNode from Cython.Compiler.ModuleNode import ModuleNode
from Cython.Compiler.UtilNodes import LetNode, LetRefNode from Cython.Compiler.UtilNodes import LetNode, LetRefNode, ResultRefNode
from Cython.Compiler.TreeFragment import TreeFragment, TemplateTransform from Cython.Compiler.TreeFragment import TreeFragment, TemplateTransform
from Cython.Compiler.StringEncoding import EncodedString from Cython.Compiler.StringEncoding import EncodedString
from Cython.Compiler.Errors import error, warning, CompileError, InternalError from Cython.Compiler.Errors import error, warning, CompileError, InternalError
...@@ -908,7 +909,6 @@ class WithTransform(CythonTransform, SkipDeclarations): ...@@ -908,7 +909,6 @@ class WithTransform(CythonTransform, SkipDeclarations):
EXC = True EXC = True
try: try:
try: try:
EXCINFO = None
BODY BODY
except: except:
EXC = False EXC = False
...@@ -927,7 +927,6 @@ class WithTransform(CythonTransform, SkipDeclarations): ...@@ -927,7 +927,6 @@ class WithTransform(CythonTransform, SkipDeclarations):
EXC = True EXC = True
try: try:
try: try:
EXCINFO = None
TARGET = VALUE TARGET = VALUE
BODY BODY
except: except:
...@@ -937,39 +936,30 @@ class WithTransform(CythonTransform, SkipDeclarations): ...@@ -937,39 +936,30 @@ class WithTransform(CythonTransform, SkipDeclarations):
finally: finally:
if EXC: if EXC:
EXIT(None, None, None) EXIT(None, None, None)
MGR = EXIT = VALUE = EXC = None MGR = EXIT = VALUE = None
""", temps=[u'MGR', u'EXC', u"EXIT", u"VALUE"], """, temps=[u'MGR', u'EXC', u"EXIT", u"VALUE"],
pipeline=[NormalizeTree(None)]) pipeline=[NormalizeTree(None)])
def visit_WithStatNode(self, node): def visit_WithStatNode(self, node):
# TODO: Cleanup badly needed exc_info = ResultRefNode(pos=node.pos, type=Builtin.tuple_type, may_hold_none=False)
TemplateTransform.temp_name_counter += 1
handle = "__tmpvar_%d" % TemplateTransform.temp_name_counter
self.visitchildren(node, ['body']) self.visitchildren(node, ['body'])
excinfo_temp = ExprNodes.NameNode(node.pos, name=handle)#TempHandle(Builtin.tuple_type)
if node.target is not None: if node.target is not None:
result = self.template_with_target.substitute({ result = self.template_with_target.substitute({
u'EXPR' : node.manager, u'EXPR' : node.manager,
u'BODY' : node.body, u'BODY' : node.body,
u'TARGET' : node.target, u'TARGET' : node.target,
u'EXCINFO' : excinfo_temp u'EXCINFO' : exc_info,
}, pos=node.pos) }, pos=node.pos)
else: else:
result = self.template_without_target.substitute({ result = self.template_without_target.substitute({
u'EXPR' : node.manager, u'EXPR' : node.manager,
u'BODY' : node.body, u'BODY' : node.body,
u'EXCINFO' : excinfo_temp u'EXCINFO' : exc_info,
}, pos=node.pos) }, pos=node.pos)
# Set except excinfo target to EXCINFO # Set except excinfo target to EXCINFO
try_except = result.stats[-1].body.stats[-1] try_except = result.stats[-1].body.stats[-1]
try_except.except_clauses[0].excinfo_target = ExprNodes.NameNode(node.pos, name=handle) try_except.except_clauses[0].excinfo_target = exc_info
# excinfo_temp.ref(node.pos))
# result.stats[-1].body.stats[-1] = TempsBlockNode(
# node.pos, temps=[excinfo_temp], body=try_except)
return result return result
......
...@@ -134,6 +134,10 @@ class ResultRefNode(AtomicExprNode): ...@@ -134,6 +134,10 @@ class ResultRefNode(AtomicExprNode):
self.type = type self.type = type
assert self.pos is not None assert self.pos is not None
def clone_node(self):
# nothing to do here
return self
def analyse_types(self, env): def analyse_types(self, env):
if self.expression is not None: if self.expression is not None:
self.type = self.expression.type self.type = self.expression.type
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment