return None
+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_temps', noop)
+ setattr(cls, 'release_temp', noop)
+
class NewTempExprNode(ExprNode):
backwards_compatible_result = None
+
+# 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:
else:
self.release_subexpr_temps(env)
+ def allocate_temp_result(self, code):
+ type = self.type
+ if not type.is_void:
+ if type.is_pyobject:
+ type = PyrexTypes.py_object_type
+ if self.backwards_compatible_result:
+ self.temp_code = self.backwards_compatible_result
+ else:
+ self.temp_code = code.funcstate.allocate_temp(
+ type, manage_ref=True)
+ else:
+ self.temp_code = None
+
+ def release_temp_result(self, code):
+ code.funcstate.release_temp(self.temp_code)
+
def generate_evaluation_code(self, code):
code.mark_pos(self.pos)
self.generate_subexpr_evaluation_code(code)
if self.is_temp:
- type = self.type
- if not type.is_void:
- if type.is_pyobject:
- type = PyrexTypes.py_object_type
- if self.backwards_compatible_result:
- self.temp_code = self.backwards_compatible_result
- else:
- self.temp_code = code.funcstate.allocate_temp(
- type, manage_ref=True)
- else:
- self.temp_code = None
+ self.allocate_temp_result(code)
self.generate_result_code(code)
if self.is_temp:
if self.type.is_pyobject:
code.put_decref_clear(self.result(), self.ctype())
if not self.backwards_compatible_result:
- code.funcstate.release_temp(self.temp_code)
+ self.release_temp_result(code)
else:
self.generate_subexpr_disposal_code(code)
else:
self.generate_subexpr_disposal_code(code)
-
-
+# ExprNode = NewTempExprNode
class AtomicExprNode(ExprNode):
# Abstract base class for expression nodes which have
return op
-class PrimaryCmpNode(ExprNode, CmpNode):
+class PrimaryCmpNode(NewTempExprNode, CmpNode):
# Non-cascaded comparison or first comparison of
# a cascaded sequence.
#
self.operand1.result(),
self.c_operator(self.operator),
self.operand2.result())
-
+
def generate_evaluation_code(self, code):
self.operand1.generate_evaluation_code(code)
self.operand2.generate_evaluation_code(code)
if self.is_temp:
+ self.allocate_temp_result(code)
self.generate_operation_code(code, self.result(),
self.operand1, self.operator, self.operand2)
if self.cascade:
from Buffer import IntroduceBufferAuxiliaryVars
from ModuleNode import check_c_declarations
+ # Temporary hack that can be used to ensure that all result_code's
+ # are generated at code generation time.
+ import Visitor
+ class ClearResultCodes(Visitor.CythonTransform):
+ def visit_ExprNode(self, node):
+ self.visitchildren(node)
+ node.result_code = "<cleared>"
+ return node
+
if pxd:
_check_c_declarations = None
_specific_post_parse = PxdPostParse(self)
DictIterTransform(),
SwitchTransform(),
FinalOptimizePhase(self),
+# ClearResultCodes(self),
# SpecialFunctions(self),
# CreateClosureClasses(context),
]