-
-class RemoveAllocateTemps(type):
- def __init__(cls, name, bases, dct):
- super(RemoveAllocateTemps, cls).__init__(name, bases, dct)
- def noop(self, env): pass
- setattr(cls, 'allocate_temps', noop)
- setattr(cls, 'allocate_temp', noop)
- setattr(cls, 'release_temp', noop)
-
-class NewTempExprNode(ExprNode):
- temp_code = None
- old_temp = None # error checker for multiple frees etc.
-
-# Do not enable this unless you are trying to make all ExprNodes
-# NewTempExprNodes (child nodes reached via recursion may not have
-# transferred).
-# __metaclass__ = RemoveAllocateTemps
-
- def result(self):
- if self.is_temp:
- return self.temp_code
- else:
- return self.calculate_result_code()
-
- def allocate_target_temps(self, env, rhs):
- self.allocate_subexpr_temps(env)
- self.is_target = True
- if rhs:
- rhs.release_temp(env)
- self.release_subexpr_temps(env)
-
- def allocate_temps(self, env, result = None):
- assert result is None, "deprecated, contact dagss if this triggers"
- self.allocate_subexpr_temps(env)
- if self.is_temp:
- self.release_subexpr_temps(env)
-
- def allocate_temp(self, env, result = None):
- assert result is None
-
- def release_temp(self, env):
- if self.is_temp:
- pass
- else:
- self.release_subexpr_temps(env)
-
- def allocate_temp_result(self, code):
- if self.temp_code:
- raise RuntimeError("Temp allocated multiple times")
- type = self.type
- if not type.is_void:
- if type.is_pyobject:
- type = PyrexTypes.py_object_type
- self.temp_code = code.funcstate.allocate_temp(
- type, manage_ref=True)
- else:
- self.temp_code = None
-
- def release_temp_result(self, code):
- if not self.temp_code:
- if self.old_temp:
- raise RuntimeError("temp %s released multiple times in %s" % (
- self.old_temp, self.__class__.__name__))
- else:
- raise RuntimeError("no temp, but release requested in %s" % (
- self.__class__.__name__))
- code.funcstate.release_temp(self.temp_code)
- self.old_temp = self.temp_code
- self.temp_code = None
-
- def generate_evaluation_code(self, code):
- code.mark_pos(self.pos)
-
- # Generate code to evaluate this node and
- # its sub-expressions, and dispose of any
- # temporary results of its sub-expressions.
- self.generate_subexpr_evaluation_code(code)
-
- if self.is_temp:
- self.allocate_temp_result(code)
-
- self.generate_result_code(code)
- if self.is_temp:
- # If we are temp we do not need to wait until this node is disposed
- # before disposing children.
- self.generate_subexpr_disposal_code(code)
- self.free_subexpr_temps(code)
-
- def generate_disposal_code(self, code):
- if self.is_temp:
- if self.type.is_pyobject:
- code.put_decref_clear(self.result(), self.ctype())
- else:
- # Already done if self.is_temp
- self.generate_subexpr_disposal_code(code)
-
- def generate_post_assignment_code(self, code):
- if self.is_temp:
- if self.type.is_pyobject:
- code.putln("%s = 0;" % self.result())
- else:
- self.generate_subexpr_disposal_code(code)
-
- def free_temps(self, code):
- if self.is_temp:
- if not self.type.is_void:
- self.release_temp_result(code)
- else:
- self.free_subexpr_temps(code)
-
-# ExprNode = NewTempExprNode
-