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

All exprnodes over; NewTempExprNode folded into ExprNode

parent a1f3d113
...@@ -46,6 +46,8 @@ class ExprNode(Node): ...@@ -46,6 +46,8 @@ class ExprNode(Node):
result_ctype = None result_ctype = None
type = None type = None
temp_code = None
old_temp = None # error checker for multiple frees etc.
# The Analyse Expressions phase for expressions is split # The Analyse Expressions phase for expressions is split
# into two sub-phases: # into two sub-phases:
...@@ -222,10 +224,10 @@ class ExprNode(Node): ...@@ -222,10 +224,10 @@ class ExprNode(Node):
return nodes return nodes
def result(self): def result(self):
if not self.is_temp or self.is_target: if self.is_temp:
return self.temp_code
else:
return self.calculate_result_code() return self.calculate_result_code()
else: # i.e. self.is_temp:
return self.result_code
def result_as(self, type = None): def result_as(self, type = None):
# Return the result code cast to the specified C type. # Return the result code cast to the specified C type.
...@@ -370,15 +372,18 @@ class ExprNode(Node): ...@@ -370,15 +372,18 @@ class ExprNode(Node):
return self.is_temp return self.is_temp
def allocate_target_temps(self, env, rhs): def allocate_target_temps(self, env, rhs):
# Perform temp allocation for the LHS of an assignment.
if debug_temp_alloc:
print("%s Allocating target temps" % self)
self.allocate_subexpr_temps(env) self.allocate_subexpr_temps(env)
self.is_target = True self.is_target = True
if rhs: if rhs:
rhs.release_temp(env) rhs.release_temp(env)
self.release_subexpr_temps(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_temps(self, env, result = None): def allocate_temps(self, env, result = None):
# Allocate temporary variables for this node and # Allocate temporary variables for this node and
# all its sub-expressions. If a result is specified, # all its sub-expressions. If a result is specified,
...@@ -405,28 +410,7 @@ class ExprNode(Node): ...@@ -405,28 +410,7 @@ class ExprNode(Node):
node.allocate_temps(env) node.allocate_temps(env)
def allocate_temp(self, env, result = None): def allocate_temp(self, env, result = None):
# If this node requires a temporary variable for its assert result is None
# result, allocate one, otherwise set the result to
# a C code fragment. If a result is specified,
# this must be a temp node and the specified variable
# is used as the result instead of allocating a new
# one.
if debug_temp_alloc:
print("%s Allocating temp" % self)
if result:
if not self.is_temp:
raise InternalError("Result forced on non-temp node")
self.result_code = result
elif self.is_temp:
type = self.type
if not type.is_void:
if type.is_pyobject:
type = PyrexTypes.py_object_type
self.result_code = env.allocate_temp(type)
else:
self.result_code = None
if debug_temp_alloc:
print("%s Allocated result %s" % (self, self.result_code))
def target_code(self): def target_code(self):
# Return code fragment for use as LHS of a C assignment. # Return code fragment for use as LHS of a C assignment.
...@@ -439,13 +423,10 @@ class ExprNode(Node): ...@@ -439,13 +423,10 @@ class ExprNode(Node):
# # Release temporaries used by LHS of an assignment. # # Release temporaries used by LHS of an assignment.
# self.release_subexpr_temps(env) # self.release_subexpr_temps(env)
def release_temp(self, env): def release_temp(self, env):
# If this node owns a temporary result, release it,
# otherwise release results of its sub-expressions.
if self.is_temp: if self.is_temp:
if debug_temp_alloc: pass
print("%s Releasing result %s" % (self, self.result_code))
env.release_temp(self.result_code)
else: else:
self.release_subexpr_temps(env) self.release_subexpr_temps(env)
...@@ -456,6 +437,30 @@ class ExprNode(Node): ...@@ -456,6 +437,30 @@ class ExprNode(Node):
if node: if node:
node.release_temp(env) node.release_temp(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
# ---------------- Code Generation ----------------- # ---------------- Code Generation -----------------
def make_owned_reference(self, code): def make_owned_reference(self, code):
...@@ -466,12 +471,19 @@ class ExprNode(Node): ...@@ -466,12 +471,19 @@ class ExprNode(Node):
def generate_evaluation_code(self, code): def generate_evaluation_code(self, code):
code.mark_pos(self.pos) code.mark_pos(self.pos)
# Generate code to evaluate this node and # Generate code to evaluate this node and
# its sub-expressions, and dispose of any # its sub-expressions, and dispose of any
# temporary results of its sub-expressions. # temporary results of its sub-expressions.
self.generate_subexpr_evaluation_code(code) self.generate_subexpr_evaluation_code(code)
if self.is_temp:
self.allocate_temp_result(code)
self.generate_result_code(code) self.generate_result_code(code)
if self.is_temp: 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.generate_subexpr_disposal_code(code)
self.free_subexpr_temps(code) self.free_subexpr_temps(code)
...@@ -483,14 +495,13 @@ class ExprNode(Node): ...@@ -483,14 +495,13 @@ class ExprNode(Node):
self.not_implemented("generate_result_code") self.not_implemented("generate_result_code")
def generate_disposal_code(self, code): def generate_disposal_code(self, code):
# If necessary, generate code to dispose of
# temporary Python reference.
if self.is_temp: if self.is_temp:
if self.type.is_pyobject: if self.type.is_pyobject:
code.put_decref_clear(self.result(), self.ctype()) code.put_decref_clear(self.result(), self.ctype())
else: else:
# Already done if self.is_temp
self.generate_subexpr_disposal_code(code) self.generate_subexpr_disposal_code(code)
def generate_subexpr_disposal_code(self, code): def generate_subexpr_disposal_code(self, code):
# Generate code to dispose of temporary results # Generate code to dispose of temporary results
# of all sub-expressions. # of all sub-expressions.
...@@ -498,15 +509,12 @@ class ExprNode(Node): ...@@ -498,15 +509,12 @@ class ExprNode(Node):
node.generate_disposal_code(code) node.generate_disposal_code(code)
def generate_post_assignment_code(self, code): def generate_post_assignment_code(self, code):
# Same as generate_disposal_code except that
# assignment will have absorbed a reference to
# the result if it is a Python object.
if self.is_temp: if self.is_temp:
if self.type.is_pyobject: if self.type.is_pyobject:
code.putln("%s = 0;" % self.result()) code.putln("%s = 0;" % self.result())
else: else:
self.generate_subexpr_disposal_code(code) self.generate_subexpr_disposal_code(code)
def generate_assignment_code(self, rhs, code): def generate_assignment_code(self, rhs, code):
# Stub method for nodes which are not legal as # Stub method for nodes which are not legal as
# the LHS of an assignment. An error will have # the LHS of an assignment. An error will have
...@@ -520,9 +528,11 @@ class ExprNode(Node): ...@@ -520,9 +528,11 @@ class ExprNode(Node):
pass pass
def free_temps(self, code): def free_temps(self, code):
if not self.is_temp: if self.is_temp:
if not self.type.is_void:
self.release_temp_result(code)
else:
self.free_subexpr_temps(code) self.free_subexpr_temps(code)
# otherwise, already freed in generate_evaluation_code
def free_subexpr_temps(self, code): def free_subexpr_temps(self, code):
for sub in self.subexpr_nodes(): for sub in self.subexpr_nodes():
...@@ -612,125 +622,7 @@ class ExprNode(Node): ...@@ -612,125 +622,7 @@ class ExprNode(Node):
def as_cython_attribute(self): def as_cython_attribute(self):
return None 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_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
class AtomicExprNode(ExprNode): class AtomicExprNode(ExprNode):
# Abstract base class for expression nodes which have
# no sub-expressions.
subexprs = []
class AtomicNewTempExprNode(NewTempExprNode):
# I do not dare to convert NameNode yet. This is now # I do not dare to convert NameNode yet. This is now
# ancestor of all former AtomicExprNode except # ancestor of all former AtomicExprNode except
# NameNode. Should be renamed to AtomicExprNode # NameNode. Should be renamed to AtomicExprNode
...@@ -747,7 +639,7 @@ class AtomicNewTempExprNode(NewTempExprNode): ...@@ -747,7 +639,7 @@ class AtomicNewTempExprNode(NewTempExprNode):
def generate_subexpr_disposal_code(self, code): def generate_subexpr_disposal_code(self, code):
pass pass
class PyConstNode(AtomicNewTempExprNode): class PyConstNode(AtomicExprNode):
# Abstract base class for constant Python values. # Abstract base class for constant Python values.
is_literal = 1 is_literal = 1
...@@ -787,7 +679,7 @@ class EllipsisNode(PyConstNode): ...@@ -787,7 +679,7 @@ class EllipsisNode(PyConstNode):
return Ellipsis return Ellipsis
class ConstNode(AtomicNewTempExprNode): class ConstNode(AtomicExprNode):
# Abstract base type for literal constant nodes. # Abstract base type for literal constant nodes.
# #
# value string C code fragment # value string C code fragment
...@@ -1017,7 +909,7 @@ class IdentifierStringNode(ConstNode): ...@@ -1017,7 +909,7 @@ class IdentifierStringNode(ConstNode):
return self.result_code return self.result_code
class LongNode(AtomicNewTempExprNode): class LongNode(AtomicExprNode):
# Python long integer literal # Python long integer literal
# #
# value string # value string
...@@ -1043,7 +935,7 @@ class LongNode(AtomicNewTempExprNode): ...@@ -1043,7 +935,7 @@ class LongNode(AtomicNewTempExprNode):
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
class ImagNode(AtomicNewTempExprNode): class ImagNode(AtomicExprNode):
# Imaginary number literal # Imaginary number literal
# #
# value float imaginary part # value float imaginary part
...@@ -1070,7 +962,7 @@ class ImagNode(AtomicNewTempExprNode): ...@@ -1070,7 +962,7 @@ class ImagNode(AtomicNewTempExprNode):
class NameNode(AtomicNewTempExprNode): class NameNode(AtomicExprNode):
# Reference to a local or global variable name. # Reference to a local or global variable name.
# #
# name string Python name of the variable # name string Python name of the variable
...@@ -1425,7 +1317,7 @@ class NameNode(AtomicNewTempExprNode): ...@@ -1425,7 +1317,7 @@ class NameNode(AtomicNewTempExprNode):
else: else:
code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name))) code.annotate(pos, AnnotationItem('c_call', 'c function', size=len(self.name)))
class BackquoteNode(NewTempExprNode): class BackquoteNode(ExprNode):
# `expr` # `expr`
# #
# arg ExprNode # arg ExprNode
...@@ -1453,7 +1345,7 @@ class BackquoteNode(NewTempExprNode): ...@@ -1453,7 +1345,7 @@ class BackquoteNode(NewTempExprNode):
class ImportNode(NewTempExprNode): class ImportNode(ExprNode):
# Used as part of import statement implementation. # Used as part of import statement implementation.
# Implements result = # Implements result =
# __import__(module_name, globals(), None, name_list) # __import__(module_name, globals(), None, name_list)
...@@ -1489,7 +1381,7 @@ class ImportNode(NewTempExprNode): ...@@ -1489,7 +1381,7 @@ class ImportNode(NewTempExprNode):
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
class IteratorNode(NewTempExprNode): class IteratorNode(ExprNode):
# Used as part of for statement implementation. # Used as part of for statement implementation.
# #
# allocate_counter_temp/release_counter_temp needs to be called # allocate_counter_temp/release_counter_temp needs to be called
...@@ -1548,7 +1440,7 @@ class IteratorNode(NewTempExprNode): ...@@ -1548,7 +1440,7 @@ class IteratorNode(NewTempExprNode):
code.putln("}") code.putln("}")
class NextNode(AtomicNewTempExprNode): class NextNode(AtomicExprNode):
# Used as part of for statement implementation. # Used as part of for statement implementation.
# Implements result = iterator.next() # Implements result = iterator.next()
# Created during analyse_types phase. # Created during analyse_types phase.
...@@ -1607,7 +1499,7 @@ class NextNode(AtomicNewTempExprNode): ...@@ -1607,7 +1499,7 @@ class NextNode(AtomicNewTempExprNode):
code.putln("}") code.putln("}")
class ExcValueNode(AtomicNewTempExprNode): class ExcValueNode(AtomicExprNode):
# Node created during analyse_types phase # Node created during analyse_types phase
# of an ExceptClauseNode to fetch the current # of an ExceptClauseNode to fetch the current
# exception value. # exception value.
...@@ -1627,7 +1519,7 @@ class ExcValueNode(AtomicNewTempExprNode): ...@@ -1627,7 +1519,7 @@ class ExcValueNode(AtomicNewTempExprNode):
pass pass
class TempNode(NewTempExprNode): class TempNode(ExprNode):
# 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.
# #
...@@ -1685,7 +1577,7 @@ class PyTempNode(TempNode): ...@@ -1685,7 +1577,7 @@ class PyTempNode(TempNode):
# #
#------------------------------------------------------------------- #-------------------------------------------------------------------
class IndexNode(NewTempExprNode): class IndexNode(ExprNode):
# Sequence indexing. # Sequence indexing.
# #
# base ExprNode # base ExprNode
...@@ -2012,7 +1904,7 @@ class IndexNode(NewTempExprNode): ...@@ -2012,7 +1904,7 @@ class IndexNode(NewTempExprNode):
code.putln(code.error_goto(self.pos)) code.putln(code.error_goto(self.pos))
code.putln("}") code.putln("}")
class SliceIndexNode(NewTempExprNode): class SliceIndexNode(ExprNode):
# 2-element slice indexing # 2-element slice indexing
# #
# base ExprNode # base ExprNode
...@@ -2214,7 +2106,7 @@ class SliceIndexNode(NewTempExprNode): ...@@ -2214,7 +2106,7 @@ class SliceIndexNode(NewTempExprNode):
return "<unused>" return "<unused>"
class SliceNode(NewTempExprNode): class SliceNode(ExprNode):
# start:stop:step in subscript list # start:stop:step in subscript list
# #
# start ExprNode # start ExprNode
...@@ -2267,7 +2159,7 @@ class SliceNode(NewTempExprNode): ...@@ -2267,7 +2159,7 @@ class SliceNode(NewTempExprNode):
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
class CallNode(NewTempExprNode): class CallNode(ExprNode):
def analyse_as_type_constructor(self, env): def analyse_as_type_constructor(self, env):
type = self.function.analyse_as_type(env) type = self.function.analyse_as_type(env)
if type and type.is_struct_or_union: if type and type.is_struct_or_union:
...@@ -2661,7 +2553,7 @@ class GeneralCallNode(CallNode): ...@@ -2661,7 +2553,7 @@ class GeneralCallNode(CallNode):
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
class AsTupleNode(NewTempExprNode): class AsTupleNode(ExprNode):
# Convert argument to tuple. Used for normalising # Convert argument to tuple. Used for normalising
# the * argument of a function call. # the * argument of a function call.
# #
...@@ -2697,7 +2589,7 @@ class AsTupleNode(NewTempExprNode): ...@@ -2697,7 +2589,7 @@ class AsTupleNode(NewTempExprNode):
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
class AttributeNode(NewTempExprNode): class AttributeNode(ExprNode):
# obj.attribute # obj.attribute
# #
# obj ExprNode # obj ExprNode
...@@ -3041,7 +2933,7 @@ class AttributeNode(NewTempExprNode): ...@@ -3041,7 +2933,7 @@ class AttributeNode(NewTempExprNode):
# #
#------------------------------------------------------------------- #-------------------------------------------------------------------
class SequenceNode(NewTempExprNode): class SequenceNode(ExprNode):
# Base class for list and tuple constructor nodes. # Base class for list and tuple constructor nodes.
# Contains common code for performing sequence unpacking. # Contains common code for performing sequence unpacking.
# #
...@@ -3366,7 +3258,7 @@ class ListNode(SequenceNode): ...@@ -3366,7 +3258,7 @@ class ListNode(SequenceNode):
# generate_evaluation_code which will do that. # generate_evaluation_code which will do that.
class ComprehensionNode(NewTempExprNode): class ComprehensionNode(ExprNode):
subexprs = ["target"] subexprs = ["target"]
child_attrs = ["loop", "append"] child_attrs = ["loop", "append"]
...@@ -3397,7 +3289,7 @@ class ComprehensionNode(NewTempExprNode): ...@@ -3397,7 +3289,7 @@ class ComprehensionNode(NewTempExprNode):
self.loop.annotate(code) self.loop.annotate(code)
class ComprehensionAppendNode(NewTempExprNode): class ComprehensionAppendNode(ExprNode):
# Need to be careful to avoid infinite recursion: # Need to be careful to avoid infinite recursion:
# target must not be in child_attrs/subexprs # target must not be in child_attrs/subexprs
subexprs = ['expr'] subexprs = ['expr']
...@@ -3447,7 +3339,7 @@ class DictComprehensionAppendNode(ComprehensionAppendNode): ...@@ -3447,7 +3339,7 @@ class DictComprehensionAppendNode(ComprehensionAppendNode):
code.error_goto_if(self.result(), self.pos))) code.error_goto_if(self.result(), self.pos)))
class SetNode(NewTempExprNode): class SetNode(ExprNode):
# Set constructor. # Set constructor.
subexprs = ['args'] subexprs = ['args']
...@@ -3491,7 +3383,7 @@ class SetNode(NewTempExprNode): ...@@ -3491,7 +3383,7 @@ class SetNode(NewTempExprNode):
arg.free_temps(code) arg.free_temps(code)
class DictNode(NewTempExprNode): class DictNode(ExprNode):
# Dictionary constructor. # Dictionary constructor.
# #
# key_value_pairs [DictItemNode] # key_value_pairs [DictItemNode]
...@@ -3591,7 +3483,7 @@ class DictNode(NewTempExprNode): ...@@ -3591,7 +3483,7 @@ class DictNode(NewTempExprNode):
for item in self.key_value_pairs: for item in self.key_value_pairs:
item.annotate(code) item.annotate(code)
class DictItemNode(NewTempExprNode): class DictItemNode(ExprNode):
# Represents a single item in a DictNode # Represents a single item in a DictNode
# #
# key ExprNode # key ExprNode
...@@ -3626,7 +3518,7 @@ class DictItemNode(NewTempExprNode): ...@@ -3626,7 +3518,7 @@ class DictItemNode(NewTempExprNode):
return iter([self.key, self.value]) return iter([self.key, self.value])
class ClassNode(NewTempExprNode): class ClassNode(ExprNode):
# Helper class used in the implementation of Python # Helper class used in the implementation of Python
# class definitions. Constructs a class object given # class definitions. Constructs a class object given
# a name, tuple of bases and class dictionary. # a name, tuple of bases and class dictionary.
...@@ -3669,7 +3561,7 @@ class ClassNode(NewTempExprNode): ...@@ -3669,7 +3561,7 @@ class ClassNode(NewTempExprNode):
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
class UnboundMethodNode(NewTempExprNode): class UnboundMethodNode(ExprNode):
# Helper class used in the implementation of Python # Helper class used in the implementation of Python
# class definitions. Constructs an unbound method # class definitions. Constructs an unbound method
# object from a class and a function. # object from a class and a function.
...@@ -3695,7 +3587,7 @@ class UnboundMethodNode(NewTempExprNode): ...@@ -3695,7 +3587,7 @@ class UnboundMethodNode(NewTempExprNode):
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.py_result()) code.put_gotref(self.py_result())
class PyCFunctionNode(AtomicNewTempExprNode): class PyCFunctionNode(AtomicExprNode):
# Helper class used in the implementation of Python # Helper class used in the implementation of Python
# class definitions. Constructs a PyCFunction object # class definitions. Constructs a PyCFunction object
# from a PyMethodDef struct. # from a PyMethodDef struct.
...@@ -3729,7 +3621,7 @@ compile_time_unary_operators = { ...@@ -3729,7 +3621,7 @@ compile_time_unary_operators = {
'+': operator.pos, '+': operator.pos,
} }
class UnopNode(NewTempExprNode): class UnopNode(ExprNode):
# operator string # operator string
# operand ExprNode # operand ExprNode
# #
...@@ -3805,7 +3697,7 @@ class UnopNode(NewTempExprNode): ...@@ -3805,7 +3697,7 @@ class UnopNode(NewTempExprNode):
self.type = PyrexTypes.error_type self.type = PyrexTypes.error_type
class NotNode(NewTempExprNode): class NotNode(ExprNode):
# 'not' operator # 'not' operator
# #
# operand ExprNode # operand ExprNode
...@@ -3883,7 +3775,7 @@ class TildeNode(UnopNode): ...@@ -3883,7 +3775,7 @@ class TildeNode(UnopNode):
return "(~%s)" % self.operand.result() return "(~%s)" % self.operand.result()
class AmpersandNode(NewTempExprNode): class AmpersandNode(ExprNode):
# The C address-of operator. # The C address-of operator.
# #
# operand ExprNode # operand ExprNode
...@@ -3934,7 +3826,7 @@ def unop_node(pos, operator, operand): ...@@ -3934,7 +3826,7 @@ def unop_node(pos, operator, operand):
operand = operand) operand = operand)
class TypecastNode(NewTempExprNode): class TypecastNode(ExprNode):
# C type cast # C type cast
# #
# operand ExprNode # operand ExprNode
...@@ -4009,7 +3901,7 @@ class TypecastNode(NewTempExprNode): ...@@ -4009,7 +3901,7 @@ class TypecastNode(NewTempExprNode):
code.put_incref(self.result(), self.ctype()) code.put_incref(self.result(), self.ctype())
class SizeofNode(NewTempExprNode): class SizeofNode(ExprNode):
# Abstract base class for sizeof(x) expression nodes. # Abstract base class for sizeof(x) expression nodes.
type = PyrexTypes.c_size_t_type type = PyrexTypes.c_size_t_type
...@@ -4138,7 +4030,7 @@ def get_compile_time_binop(node): ...@@ -4138,7 +4030,7 @@ def get_compile_time_binop(node):
% node.operator) % node.operator)
return func return func
class BinopNode(NewTempExprNode): class BinopNode(ExprNode):
# operator string # operator string
# operand1 ExprNode # operand1 ExprNode
# operand2 ExprNode # operand2 ExprNode
...@@ -4444,7 +4336,7 @@ class PowNode(NumBinopNode): ...@@ -4444,7 +4336,7 @@ class PowNode(NumBinopNode):
# one could have a look at adding this again after /all/ classes # one could have a look at adding this again after /all/ classes
# are converted to the new temp scheme. (The temp juggling cannot work # are converted to the new temp scheme. (The temp juggling cannot work
# otherwise). # otherwise).
class BoolBinopNode(NewTempExprNode): class BoolBinopNode(ExprNode):
# Short-circuiting boolean operation. # Short-circuiting boolean operation.
# #
# operator string # operator string
...@@ -4574,7 +4466,7 @@ class BoolBinopNode(NewTempExprNode): ...@@ -4574,7 +4466,7 @@ class BoolBinopNode(NewTempExprNode):
return (test_result, self.type.is_pyobject) return (test_result, self.type.is_pyobject)
class CondExprNode(NewTempExprNode): class CondExprNode(ExprNode):
# Short-circuiting conditional expression. # Short-circuiting conditional expression.
# #
# test ExprNode # test ExprNode
...@@ -4781,7 +4673,7 @@ class CmpNode(object): ...@@ -4781,7 +4673,7 @@ class CmpNode(object):
return op return op
class PrimaryCmpNode(NewTempExprNode, CmpNode): class PrimaryCmpNode(ExprNode, CmpNode):
# Non-cascaded comparison or first comparison of # Non-cascaded comparison or first comparison of
# a cascaded sequence. # a cascaded sequence.
# #
...@@ -5035,7 +4927,7 @@ def binop_node(pos, operator, operand1, operand2): ...@@ -5035,7 +4927,7 @@ def binop_node(pos, operator, operand1, operand2):
# #
#------------------------------------------------------------------- #-------------------------------------------------------------------
class CoercionNode(NewTempExprNode): class CoercionNode(ExprNode):
# Abstract base class for coercion nodes. # Abstract base class for coercion nodes.
# #
# arg ExprNode node being coerced # arg ExprNode node being coerced
......
...@@ -3084,10 +3084,8 @@ class InPlaceAssignmentNode(AssignmentNode): ...@@ -3084,10 +3084,8 @@ class InPlaceAssignmentNode(AssignmentNode):
import ExprNodes import ExprNodes
self.rhs.generate_evaluation_code(code) self.rhs.generate_evaluation_code(code)
self.dup.generate_subexpr_evaluation_code(code) self.dup.generate_subexpr_evaluation_code(code)
if isinstance(self.dup, ExprNodes.NewTempExprNode): if self.dup.is_temp:
# This is because we're manually messing with subexpr nodes self.dup.allocate_temp_result(code)
if self.dup.is_temp:
self.dup.allocate_temp_result(code)
# self.dup.generate_result_code is run only if it is not buffer access # self.dup.generate_result_code is run only if it is not buffer access
if self.operator == "**": if self.operator == "**":
extra = ", Py_None" extra = ", Py_None"
......
...@@ -142,7 +142,7 @@ class ResultRefNode(AtomicExprNode): ...@@ -142,7 +142,7 @@ class ResultRefNode(AtomicExprNode):
pass pass
class EvalWithTempExprNode(ExprNodes.NewTempExprNode): class EvalWithTempExprNode(ExprNodes.ExprNode):
# A wrapper around a subexpression that moves an expression into a # A wrapper around a subexpression that moves an expression into a
# temp variable and provides it to the subexpression. # temp variable and provides it to the subexpression.
......
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