Commit a1f3d113 authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

TempNode to new temps (changes its interface was necesarry)

parent 8d9427cb
...@@ -1627,9 +1627,14 @@ class ExcValueNode(AtomicNewTempExprNode): ...@@ -1627,9 +1627,14 @@ class ExcValueNode(AtomicNewTempExprNode):
pass pass
class TempNode(ExprNode): class TempNode(NewTempExprNode):
# Node created during analyse_types phase # Node created during analyse_types phase
# of some nodes to hold a temporary value. # of some nodes to hold a temporary value.
#
# Note: One must call "allocate" and "release" on
# the node during code generation to get/release the temp.
# This is because the temp result is often used outside of
# the regular cycle.
subexprs = [] subexprs = []
...@@ -1646,6 +1651,26 @@ class TempNode(ExprNode): ...@@ -1646,6 +1651,26 @@ class TempNode(ExprNode):
def generate_result_code(self, code): def generate_result_code(self, code):
pass pass
def allocate(self, code):
self.temp_cname = code.funcstate.allocate_temp(self.type, manage_ref=True)
def release(self, code):
code.funcstate.release_temp(self.temp_cname)
self.temp_cname = None
def result(self):
try:
return self.temp_cname
except:
assert False, "Remember to call allocate/release on TempNode"
raise
# Do not participate in normal temp alloc/dealloc:
def allocate_temp_result(self, code):
pass
def release_temp_result(self, code):
pass
class PyTempNode(TempNode): class PyTempNode(TempNode):
# TempNode holding a Python value. # TempNode holding a Python value.
...@@ -3096,6 +3121,8 @@ class SequenceNode(NewTempExprNode): ...@@ -3096,6 +3121,8 @@ class SequenceNode(NewTempExprNode):
rhs.py_result(), rhs.py_result(),
len(self.args))) len(self.args)))
code.putln("PyObject* tuple = %s;" % rhs.py_result()) code.putln("PyObject* tuple = %s;" % rhs.py_result())
for item in self.unpacked_items:
item.allocate(code)
for i in range(len(self.args)): for i in range(len(self.args)):
item = self.unpacked_items[i] item = self.unpacked_items[i]
code.put( code.put(
...@@ -3119,6 +3146,7 @@ class SequenceNode(NewTempExprNode): ...@@ -3119,6 +3146,7 @@ class SequenceNode(NewTempExprNode):
rhs.py_result(), len(self.args))) rhs.py_result(), len(self.args)))
code.putln(code.error_goto(self.pos)) code.putln(code.error_goto(self.pos))
else: else:
self.iterator.allocate(code)
code.putln( code.putln(
"%s = PyObject_GetIter(%s); %s" % ( "%s = PyObject_GetIter(%s); %s" % (
self.iterator.result(), self.iterator.result(),
...@@ -3146,12 +3174,15 @@ class SequenceNode(NewTempExprNode): ...@@ -3146,12 +3174,15 @@ class SequenceNode(NewTempExprNode):
print("...generating disposal code for %s" % self.iterator) print("...generating disposal code for %s" % self.iterator)
self.iterator.generate_disposal_code(code) self.iterator.generate_disposal_code(code)
self.iterator.free_temps(code) self.iterator.free_temps(code)
self.iterator.release(code)
for i in range(len(self.args)): for i in range(len(self.args)):
self.args[i].generate_assignment_code( self.args[i].generate_assignment_code(
self.coerced_unpacked_items[i], code) self.coerced_unpacked_items[i], code)
code.putln("}") code.putln("}")
for item in self.unpacked_items:
item.release(code)
rhs.free_temps(code) rhs.free_temps(code)
def annotate(self, code): def annotate(self, code):
......
...@@ -2429,6 +2429,7 @@ class OverrideCheckNode(StatNode): ...@@ -2429,6 +2429,7 @@ class OverrideCheckNode(StatNode):
code.putln("else {") code.putln("else {")
else: else:
code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg) code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
self.func_node.allocate(code)
err = code.error_goto_if_null(self.func_node.result(), self.pos) err = code.error_goto_if_null(self.func_node.result(), self.pos)
# need to get attribute manually--scope would return cdef method # need to get attribute manually--scope would return cdef method
code.putln("%s = PyObject_GetAttr(%s, %s); %s" % ( code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
...@@ -2442,6 +2443,7 @@ class OverrideCheckNode(StatNode): ...@@ -2442,6 +2443,7 @@ class OverrideCheckNode(StatNode):
code.putln('}') code.putln('}')
code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type) code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
code.putln("}") code.putln("}")
self.func_node.release(code)
class ClassDefNode(StatNode, BlockNode): class ClassDefNode(StatNode, BlockNode):
pass pass
...@@ -3059,7 +3061,8 @@ class InPlaceAssignmentNode(AssignmentNode): ...@@ -3059,7 +3061,8 @@ class InPlaceAssignmentNode(AssignmentNode):
elif self.rhs.type.is_pyobject: elif self.rhs.type.is_pyobject:
self.rhs = self.rhs.coerce_to(self.lhs.type, env) self.rhs = self.rhs.coerce_to(self.lhs.type, env)
if self.lhs.type.is_pyobject: if self.lhs.type.is_pyobject:
self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env) self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
self.result_value.allocate_temps(env) self.result_value.allocate_temps(env)
# if use_temp: # if use_temp:
# self.rhs = self.rhs.coerce_to_temp(env) # self.rhs = self.rhs.coerce_to_temp(env)
...@@ -3094,6 +3097,7 @@ class InPlaceAssignmentNode(AssignmentNode): ...@@ -3094,6 +3097,7 @@ class InPlaceAssignmentNode(AssignmentNode):
if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access: if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
error(self.pos, "In-place operators not allowed on object buffers in this release.") error(self.pos, "In-place operators not allowed on object buffers in this release.")
self.dup.generate_result_code(code) self.dup.generate_result_code(code)
self.result_value_temp.allocate(code)
code.putln( code.putln(
"%s = %s(%s, %s%s); %s" % ( "%s = %s(%s, %s%s); %s" % (
self.result_value.result(), self.result_value.result(),
...@@ -3109,6 +3113,7 @@ class InPlaceAssignmentNode(AssignmentNode): ...@@ -3109,6 +3113,7 @@ class InPlaceAssignmentNode(AssignmentNode):
self.dup.generate_disposal_code(code) self.dup.generate_disposal_code(code)
self.dup.free_temps(code) self.dup.free_temps(code)
self.lhs.generate_assignment_code(self.result_value, code) self.lhs.generate_assignment_code(self.result_value, code)
self.result_value_temp.release(code)
else: else:
c_op = self.operator c_op = self.operator
if c_op == "//": if c_op == "//":
...@@ -3949,6 +3954,11 @@ class ForFromStatNode(LoopNode, StatNode): ...@@ -3949,6 +3954,11 @@ class ForFromStatNode(LoopNode, StatNode):
self.step.generate_evaluation_code(code) self.step.generate_evaluation_code(code)
step = self.step.result() step = self.step.result()
incop = "%s=%s" % (incop[0], step) incop = "%s=%s" % (incop[0], step)
import ExprNodes
if isinstance(self.loopvar_node, ExprNodes.TempNode):
self.loopvar_node.allocate(code)
if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
self.py_loopvar_node.allocate(code)
if from_range: if from_range:
loopvar_name = code.funcstate.allocate_temp(self.target.type, False) loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
else: else:
...@@ -3991,6 +4001,10 @@ class ForFromStatNode(LoopNode, StatNode): ...@@ -3991,6 +4001,10 @@ class ForFromStatNode(LoopNode, StatNode):
self.bound1.free_temps(code) self.bound1.free_temps(code)
self.bound2.generate_disposal_code(code) self.bound2.generate_disposal_code(code)
self.bound2.free_temps(code) self.bound2.free_temps(code)
if isinstance(self.loopvar_node, ExprNodes.TempNode):
self.loopvar_node.release(code)
if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
self.py_loopvar_node.release(code)
if self.step is not None: if self.step is not None:
self.step.generate_disposal_code(code) self.step.generate_disposal_code(code)
self.step.free_temps(code) self.step.free_temps(code)
...@@ -4739,6 +4753,7 @@ class FromImportStatNode(StatNode): ...@@ -4739,6 +4753,7 @@ class FromImportStatNode(StatNode):
Naming.import_star, Naming.import_star,
self.module.py_result(), self.module.py_result(),
code.error_goto(self.pos))) code.error_goto(self.pos)))
self.item.allocate(code)
for name, target, coerced_item in self.interned_items: for name, target, coerced_item in self.interned_items:
cname = code.intern_identifier(name) cname = code.intern_identifier(name)
code.putln( code.putln(
...@@ -4756,6 +4771,7 @@ class FromImportStatNode(StatNode): ...@@ -4756,6 +4771,7 @@ class FromImportStatNode(StatNode):
target.generate_assignment_code(coerced_item, code) target.generate_assignment_code(coerced_item, code)
if self.item.result() != coerced_item.result(): if self.item.result() != coerced_item.result():
code.put_decref_clear(self.item.result(), self.item.type) code.put_decref_clear(self.item.result(), self.item.type)
self.item.release(code)
self.module.generate_disposal_code(code) self.module.generate_disposal_code(code)
self.module.free_temps(code) self.module.free_temps(code)
......
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