Commit 771071fd authored by Stefan Behnel's avatar Stefan Behnel

clean up exc_info handling in 'with' statement implementation

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