Commit 029c986f authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Move local manual temporaries from env to code

parent 44b2077c
...@@ -1430,9 +1430,11 @@ class ExcValueNode(AtomicExprNode): ...@@ -1430,9 +1430,11 @@ class ExcValueNode(AtomicExprNode):
# of an ExceptClauseNode to fetch the current # of an ExceptClauseNode to fetch the current
# exception value. # exception value.
def __init__(self, pos, env, var): def __init__(self, pos, env):
ExprNode.__init__(self, pos) ExprNode.__init__(self, pos)
self.type = py_object_type self.type = py_object_type
def set_var(self, var):
self.var = var self.var = var
def calculate_result_code(self): def calculate_result_code(self):
...@@ -2232,8 +2234,6 @@ class SimpleCallNode(CallNode): ...@@ -2232,8 +2234,6 @@ class SimpleCallNode(CallNode):
if func_type.optional_arg_count and expected_nargs != actual_nargs: if func_type.optional_arg_count and expected_nargs != actual_nargs:
self.has_optional_args = 1 self.has_optional_args = 1
self.is_temp = 1 self.is_temp = 1
self.opt_arg_struct = env.allocate_temp(func_type.op_arg_struct.base_type)
env.release_temp(self.opt_arg_struct)
# Coerce arguments # Coerce arguments
for i in range(min(max_nargs, actual_nargs)): for i in range(min(max_nargs, actual_nargs)):
formal_type = func_type.args[i].type formal_type = func_type.args[i].type
...@@ -2306,6 +2306,8 @@ class SimpleCallNode(CallNode): ...@@ -2306,6 +2306,8 @@ class SimpleCallNode(CallNode):
if self.has_optional_args: if self.has_optional_args:
actual_nargs = len(self.args) actual_nargs = len(self.args)
expected_nargs = len(func_type.args) - func_type.optional_arg_count expected_nargs = len(func_type.args) - func_type.optional_arg_count
self.opt_arg_struct = code.funcstate.allocate_temp(
func_type.op_arg_struct.base_type, manage_ref=True)
code.putln("%s.%s = %s;" % ( code.putln("%s.%s = %s;" % (
self.opt_arg_struct, self.opt_arg_struct,
Naming.pyrex_prefix + "n", Naming.pyrex_prefix + "n",
...@@ -2358,6 +2360,8 @@ class SimpleCallNode(CallNode): ...@@ -2358,6 +2360,8 @@ class SimpleCallNode(CallNode):
code.putln("%s%s; %s" % (lhs, rhs, goto_error)) code.putln("%s%s; %s" % (lhs, rhs, goto_error))
if self.type.is_pyobject and self.result(): if self.type.is_pyobject and self.result():
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
if self.has_optional_args:
code.funcstate.release_temp(self.opt_arg_struct)
class PythonCapiFunctionNode(ExprNode): class PythonCapiFunctionNode(ExprNode):
......
...@@ -880,24 +880,21 @@ class CEnumDefNode(StatNode): ...@@ -880,24 +880,21 @@ class CEnumDefNode(StatNode):
for item in self.items: for item in self.items:
item.analyse_declarations(env, self.entry) item.analyse_declarations(env, self.entry)
def analyse_expressions(self, env):
if self.visibility == 'public':
self.temp = env.allocate_temp_pyobject()
env.release_temp(self.temp)
def generate_execution_code(self, code): def generate_execution_code(self, code):
if self.visibility == 'public': if self.visibility == 'public':
temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
for item in self.entry.enum_values: for item in self.entry.enum_values:
code.putln("%s = PyInt_FromLong(%s); %s" % ( code.putln("%s = PyInt_FromLong(%s); %s" % (
self.temp, temp,
item.cname, item.cname,
code.error_goto_if_null(self.temp, item.pos))) code.error_goto_if_null(temp, item.pos)))
code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % ( code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
Naming.module_cname, Naming.module_cname,
item.name, item.name,
self.temp, temp,
code.error_goto(item.pos))) code.error_goto(item.pos)))
code.putln("%s = 0;" % self.temp) code.putln("%s = 0;" % temp)
code.funcstate.release_temp(temp)
class CEnumDefItemNode(StatNode): class CEnumDefItemNode(StatNode):
...@@ -3198,8 +3195,6 @@ class ExecStatNode(StatNode): ...@@ -3198,8 +3195,6 @@ class ExecStatNode(StatNode):
arg.analyse_expressions(env) arg.analyse_expressions(env)
arg = arg.coerce_to_pyobject(env) arg = arg.coerce_to_pyobject(env)
self.args[i] = arg self.args[i] = arg
self.temp_result = env.allocate_temp_pyobject()
env.release_temp(self.temp_result)
env.use_utility_code(Builtin.pyexec_utility_code) env.use_utility_code(Builtin.pyexec_utility_code)
gil_check = StatNode._gil_check gil_check = StatNode._gil_check
...@@ -3211,15 +3206,17 @@ class ExecStatNode(StatNode): ...@@ -3211,15 +3206,17 @@ class ExecStatNode(StatNode):
arg.generate_evaluation_code(code) arg.generate_evaluation_code(code)
args.append( arg.py_result() ) args.append( arg.py_result() )
args = tuple(args + ['0', '0'][:3-len(args)]) args = tuple(args + ['0', '0'][:3-len(args)])
temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % ( code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
(self.temp_result,) + args)) (temp_result,) + args))
for arg in self.args: for arg in self.args:
arg.generate_disposal_code(code) arg.generate_disposal_code(code)
arg.free_temps(code) arg.free_temps(code)
code.putln( code.putln(
code.error_goto_if_null(self.temp_result, self.pos)) code.error_goto_if_null(temp_result, self.pos))
code.put_gotref(self.temp_result) code.put_gotref(temp_result)
code.put_decref_clear(self.temp_result, py_object_type) code.put_decref_clear(temp_result, py_object_type)
code.funcstate.release_temp(temp_result)
def annotate(self, code): def annotate(self, code):
for arg in self.args: for arg in self.args:
...@@ -4140,65 +4137,49 @@ class ExceptClauseNode(Node): ...@@ -4140,65 +4137,49 @@ class ExceptClauseNode(Node):
if self.pattern: if self.pattern:
self.pattern.analyse_expressions(env) self.pattern.analyse_expressions(env)
self.pattern = self.pattern.coerce_to_pyobject(env) self.pattern = self.pattern.coerce_to_pyobject(env)
self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
env.release_temp(self.match_flag)
if self.target or self.excinfo_target:
self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
else:
self.exc_vars = None
if self.target: if self.target:
self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1]) self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
self.target.analyse_target_expression(env, self.exc_value) self.target.analyse_target_expression(env, self.exc_value)
if self.excinfo_target is not None: if self.excinfo_target is not None:
import ExprNodes import ExprNodes
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, var=self.exc_vars[0]), ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
])
self.excinfo_tuple.analyse_expressions(env) self.excinfo_tuple.analyse_expressions(env)
self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple) self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
self.body.analyse_expressions(env) self.body.analyse_expressions(env)
if self.exc_vars:
for var in self.exc_vars:
env.release_temp(var)
def generate_handling_code(self, code, end_label): def generate_handling_code(self, code, end_label):
code.mark_pos(self.pos) code.mark_pos(self.pos)
if self.pattern: if self.pattern:
self.pattern.generate_evaluation_code(code) self.pattern.generate_evaluation_code(code)
match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
code.putln( code.putln(
"%s = PyErr_ExceptionMatches(%s);" % ( "%s = PyErr_ExceptionMatches(%s);" % (
self.match_flag, match_flag,
self.pattern.py_result())) self.pattern.py_result()))
self.pattern.generate_disposal_code(code) self.pattern.generate_disposal_code(code)
self.pattern.free_temps(code) self.pattern.free_temps(code)
code.putln( code.putln(
"if (%s) {" % "if (%s) {" %
self.match_flag) match_flag)
code.funcstate.release_temp(match_flag)
else: else:
code.putln("/*except:*/ {") code.putln("/*except:*/ {")
if self.exc_vars: if not getattr(self.body, 'stats', True):
exc_vars = self.exc_vars
elif not getattr(self.body, 'stats', True):
# most simple case: no exception variable, empty body (pass) # most simple case: no exception variable, empty body (pass)
# => reset the exception state, done # => reset the exception state, done
code.putln("PyErr_Restore(0,0,0);") code.putln("PyErr_Restore(0,0,0);")
code.put_goto(end_label) code.put_goto(end_label)
code.putln("}") code.putln("}")
return return
else:
# during type analysis, we didn't know if we need the
# exception value, but apparently, we do
exc_vars = [code.funcstate.allocate_temp(py_object_type, exc_vars = [code.funcstate.allocate_temp(py_object_type,
manage_ref=True) manage_ref=True)
for i in xrange(3)] for i in xrange(3)]
code.putln('__Pyx_AddTraceback("%s");' % self.function_name) code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
# We always have to fetch the exception value even if # We always have to fetch the exception value even if
# there is no target, because this also normalises the # there is no target, because this also normalises the
...@@ -4210,13 +4191,15 @@ class ExceptClauseNode(Node): ...@@ -4210,13 +4191,15 @@ class ExceptClauseNode(Node):
for x in exc_vars: for x in exc_vars:
code.put_gotref(x) code.put_gotref(x)
if self.target: if self.target:
self.exc_value.set_var(exc_vars[1])
self.exc_value.generate_evaluation_code(code) self.exc_value.generate_evaluation_code(code)
self.target.generate_assignment_code(self.exc_value, code) self.target.generate_assignment_code(self.exc_value, code)
if self.excinfo_target is not None: if self.excinfo_target is not None:
for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
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.generate_assignment_code(self.excinfo_tuple, code)
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')
code.continue_label = code.new_label('except_continue') code.continue_label = code.new_label('except_continue')
...@@ -4243,8 +4226,6 @@ class ExceptClauseNode(Node): ...@@ -4243,8 +4226,6 @@ class ExceptClauseNode(Node):
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 not self.exc_vars:
# clean up locally allocated temps
for temp in exc_vars: for temp in exc_vars:
code.funcstate.release_temp(temp) code.funcstate.release_temp(temp)
......
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