Commit 8911a122 authored by Stefan Behnel's avatar Stefan Behnel

streamline exit code of with-statement

parent 9112fddd
......@@ -2515,6 +2515,7 @@ class WithExitCallNode(ExprNode):
# args TupleNode or ResultStatNode the exception info tuple
subexprs = ['args']
test_if_run = True
def analyse_types(self, env):
self.args = self.args.analyse_types(env)
......@@ -2522,23 +2523,31 @@ class WithExitCallNode(ExprNode):
self.is_temp = True
return self
def generate_result_code(self, code):
if isinstance(self.args, TupleNode):
def generate_evaluation_code(self, code):
if self.test_if_run:
# call only if it was not already called (and decref-cleared)
code.putln("if (%s) {" % self.with_stat.exit_var)
self.args.generate_evaluation_code(code)
result_var = code.funcstate.allocate_temp(py_object_type, manage_ref=False)
code.mark_pos(self.pos)
code.putln("%s = PyObject_Call(%s, %s, NULL);" % (
result_var,
self.with_stat.exit_var,
self.args.result()))
code.put_decref_clear(self.with_stat.exit_var, type=py_object_type)
self.args.generate_disposal_code(code)
self.args.free_temps(code)
code.putln(code.error_goto_if_null(result_var, self.pos))
code.put_gotref(result_var)
self.allocate_temp_result(code)
code.putln("%s = __Pyx_PyObject_IsTrue(%s);" % (self.result(), result_var))
code.put_decref_clear(result_var, type=py_object_type)
code.put_error_if_neg(self.pos, self.result())
code.funcstate.release_temp(result_var)
if isinstance(self.args, TupleNode):
if self.test_if_run:
code.putln("}")
......
......@@ -1230,35 +1230,37 @@ class WithTransform(CythonTransform, SkipDeclarations):
excinfo_target = ExprNodes.TupleNode(pos, slow=True, args=[
ExprNodes.ExcValueNode(pos) for _ in range(3)])
except_clause = Nodes.ExceptClauseNode(
pos, body = Nodes.IfStatNode(
pos, if_clauses = [
pos, body=Nodes.IfStatNode(
pos, if_clauses=[
Nodes.IfClauseNode(
pos, condition = ExprNodes.NotNode(
pos, operand = ExprNodes.WithExitCallNode(
pos, with_stat = node,
args = excinfo_target)),
body = Nodes.ReraiseStatNode(pos),
pos, condition=ExprNodes.NotNode(
pos, operand=ExprNodes.WithExitCallNode(
pos, with_stat=node,
test_if_run=False,
args=excinfo_target)),
body=Nodes.ReraiseStatNode(pos),
),
],
else_clause = None),
pattern = None,
target = None,
excinfo_target = excinfo_target,
else_clause=None),
pattern=None,
target=None,
excinfo_target=excinfo_target,
)
node.body = Nodes.TryFinallyStatNode(
pos, body = Nodes.TryExceptStatNode(
pos, body = body,
except_clauses = [except_clause],
else_clause = None,
pos, body=Nodes.TryExceptStatNode(
pos, body=body,
except_clauses=[except_clause],
else_clause=None,
),
finally_clause = Nodes.ExprStatNode(
pos, expr = ExprNodes.WithExitCallNode(
pos, with_stat = node,
args = ExprNodes.TupleNode(
pos, args = [ExprNodes.NoneNode(pos) for _ in range(3)]
finally_clause=Nodes.ExprStatNode(
pos, expr=ExprNodes.WithExitCallNode(
pos, with_stat=node,
test_if_run=True,
args=ExprNodes.TupleNode(
pos, args=[ExprNodes.NoneNode(pos) for _ in range(3)]
))),
handle_error_case = False,
handle_error_case=False,
)
return node
......
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