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

More fixes for new temps

parent 98d56995
...@@ -150,8 +150,9 @@ class FunctionState(object): ...@@ -150,8 +150,9 @@ class FunctionState(object):
freelist = self.temps_free.get((type, manage_ref)) freelist = self.temps_free.get((type, manage_ref))
if freelist is None: if freelist is None:
freelist = [] freelist = []
self.temps_free[(type, manage_ref)] = freelist self.temps_free[(type, manage_ref)] = freelist
if name in freelist:
raise RuntimeError("Temp %s freed twice!" % name)
freelist.append(name) freelist.append(name)
if DebugFlags.debug_temp_code_comments: if DebugFlags.debug_temp_code_comments:
self.owner.putln("/* %s released */" % name) self.owner.putln("/* %s released */" % name)
......
...@@ -439,6 +439,7 @@ class ExprNode(Node): ...@@ -439,6 +439,7 @@ class ExprNode(Node):
self.generate_result_code(code) self.generate_result_code(code)
if self.is_temp: if self.is_temp:
self.generate_subexpr_disposal_code(code) self.generate_subexpr_disposal_code(code)
self.free_subexpr_temps(code)
def generate_subexpr_evaluation_code(self, code): def generate_subexpr_evaluation_code(self, code):
for node in self.subexpr_nodes(): for node in self.subexpr_nodes():
...@@ -487,6 +488,10 @@ class ExprNode(Node): ...@@ -487,6 +488,10 @@ class ExprNode(Node):
def free_temps(self, code): def free_temps(self, code):
pass pass
def free_subexpr_temps(self, code):
for sub in self.subexpr_nodes():
sub.free_temps(code)
# ---------------- Annotation --------------------- # ---------------- Annotation ---------------------
def annotate(self, code): def annotate(self, code):
...@@ -582,6 +587,7 @@ class RemoveAllocateTemps(type): ...@@ -582,6 +587,7 @@ class RemoveAllocateTemps(type):
class NewTempExprNode(ExprNode): class NewTempExprNode(ExprNode):
backwards_compatible_result = None backwards_compatible_result = None
temp_code = None
# Do not enable this unless you are trying to make all ExprNodes # Do not enable this unless you are trying to make all ExprNodes
# NewTempExprNodes (child nodes reached via recursion may not have # NewTempExprNodes (child nodes reached via recursion may not have
...@@ -617,6 +623,8 @@ class NewTempExprNode(ExprNode): ...@@ -617,6 +623,8 @@ class NewTempExprNode(ExprNode):
self.release_subexpr_temps(env) self.release_subexpr_temps(env)
def allocate_temp_result(self, code): def allocate_temp_result(self, code):
if self.temp_code:
raise RuntimeError("Temp allocated multiple times")
type = self.type type = self.type
if not type.is_void: if not type.is_void:
if type.is_pyobject: if type.is_pyobject:
...@@ -630,7 +638,11 @@ class NewTempExprNode(ExprNode): ...@@ -630,7 +638,11 @@ class NewTempExprNode(ExprNode):
self.temp_code = None self.temp_code = None
def release_temp_result(self, code): def release_temp_result(self, code):
if not self.temp_code:
raise RuntimeError("No temp (perhaps released multiple times? See self.old_temp)")
code.funcstate.release_temp(self.temp_code) code.funcstate.release_temp(self.temp_code)
self.old_temp = self.temp_code
self.temp_code = None
def generate_evaluation_code(self, code): def generate_evaluation_code(self, code):
code.mark_pos(self.pos) code.mark_pos(self.pos)
...@@ -648,6 +660,7 @@ class NewTempExprNode(ExprNode): ...@@ -648,6 +660,7 @@ class NewTempExprNode(ExprNode):
# If we are temp we do not need to wait until this node is disposed # If we are temp we do not need to wait until this node is disposed
# before disposing children. # before disposing children.
self.generate_subexpr_disposal_code(code) self.generate_subexpr_disposal_code(code)
self.free_subexpr_temps(code)
def generate_disposal_code(self, code): def generate_disposal_code(self, code):
if self.is_temp: if self.is_temp:
...@@ -658,15 +671,17 @@ class NewTempExprNode(ExprNode): ...@@ -658,15 +671,17 @@ class NewTempExprNode(ExprNode):
self.generate_subexpr_disposal_code(code) self.generate_subexpr_disposal_code(code)
def generate_post_assignment_code(self, code): def generate_post_assignment_code(self, code):
if self.is_temp and self.type.is_pyobject: if self.is_temp:
if self.type.is_pyobject:
code.putln("%s = 0;" % self.result()) code.putln("%s = 0;" % self.result())
else:
self.generate_subexpr_disposal_code(code) self.generate_subexpr_disposal_code(code)
def free_temps(self, code): def free_temps(self, code):
if self.is_temp: if self.is_temp:
self.release_temp_result() self.release_temp_result(code)
for sub in self.subexpr_nodes(): else:
sub.free_temps(code) self.free_subexpr_temps(code)
# ExprNode = NewTempExprNode # ExprNode = NewTempExprNode
...@@ -1238,7 +1253,7 @@ class NameNode(AtomicExprNode): ...@@ -1238,7 +1253,7 @@ class NameNode(AtomicExprNode):
print("NameNode.generate_assignment_code:") print("NameNode.generate_assignment_code:")
print("...generating disposal code for %s" % rhs) print("...generating disposal code for %s" % rhs)
rhs.generate_disposal_code(code) rhs.generate_disposal_code(code)
rhs.free_temps(code)
else: else:
if self.type.is_buffer: if self.type.is_buffer:
# Generate code for doing the buffer release/acquisition. # Generate code for doing the buffer release/acquisition.
...@@ -1270,6 +1285,7 @@ class NameNode(AtomicExprNode): ...@@ -1270,6 +1285,7 @@ class NameNode(AtomicExprNode):
print("NameNode.generate_assignment_code:") print("NameNode.generate_assignment_code:")
print("...generating post-assignment code for %s" % rhs) print("...generating post-assignment code for %s" % rhs)
rhs.generate_post_assignment_code(code) rhs.generate_post_assignment_code(code)
rhs.free_temps(code)
def generate_acquire_buffer(self, rhs, code): def generate_acquire_buffer(self, rhs, code):
# rhstmp is only used in case the rhs is a complicated expression leading to # rhstmp is only used in case the rhs is a complicated expression leading to
...@@ -1708,6 +1724,14 @@ class IndexNode(ExprNode): ...@@ -1708,6 +1724,14 @@ class IndexNode(ExprNode):
for i in self.indices: for i in self.indices:
i.generate_disposal_code(code) i.generate_disposal_code(code)
def free_subexpr_temps(self, code):
self.base.free_temps(code)
if not self.indices:
self.index.free_temps(code)
else:
for i in self.indices:
i.free_temps(code)
def generate_result_code(self, code): def generate_result_code(self, code):
if self.is_buffer_access: if self.is_buffer_access:
if code.globalstate.directives['nonecheck']: if code.globalstate.directives['nonecheck']:
...@@ -1795,7 +1819,9 @@ class IndexNode(ExprNode): ...@@ -1795,7 +1819,9 @@ class IndexNode(ExprNode):
"%s = %s;" % ( "%s = %s;" % (
self.result(), rhs.result())) self.result(), rhs.result()))
self.generate_subexpr_disposal_code(code) self.generate_subexpr_disposal_code(code)
self.free_subexpr_temps(code)
rhs.generate_disposal_code(code) rhs.generate_disposal_code(code)
rhs.free_temps(code)
def generate_deletion_code(self, code): def generate_deletion_code(self, code):
self.generate_subexpr_evaluation_code(code) self.generate_subexpr_evaluation_code(code)
...@@ -1935,6 +1961,7 @@ class SliceIndexNode(ExprNode): ...@@ -1935,6 +1961,7 @@ class SliceIndexNode(ExprNode):
rhs.result(), i)) rhs.result(), i))
self.generate_subexpr_disposal_code(code) self.generate_subexpr_disposal_code(code)
rhs.generate_disposal_code(code) rhs.generate_disposal_code(code)
rhs.free_temps(code)
def generate_deletion_code(self, code): def generate_deletion_code(self, code):
if not self.type.is_pyobject: if not self.type.is_pyobject:
...@@ -2722,6 +2749,7 @@ class AttributeNode(ExprNode): ...@@ -2722,6 +2749,7 @@ class AttributeNode(ExprNode):
self.interned_attr_cname, self.interned_attr_cname,
rhs.py_result())) rhs.py_result()))
rhs.generate_disposal_code(code) rhs.generate_disposal_code(code)
rhs.free_temps(code)
else: else:
if (self.obj.type.is_extension_type if (self.obj.type.is_extension_type
and self.needs_none_check and self.needs_none_check
...@@ -2738,7 +2766,9 @@ class AttributeNode(ExprNode): ...@@ -2738,7 +2766,9 @@ class AttributeNode(ExprNode):
rhs.result_as(self.ctype()))) rhs.result_as(self.ctype())))
#rhs.result())) #rhs.result()))
rhs.generate_post_assignment_code(code) rhs.generate_post_assignment_code(code)
rhs.free_temps(code)
self.obj.generate_disposal_code(code) self.obj.generate_disposal_code(code)
self.obj.free_temps(code)
def generate_deletion_code(self, code): def generate_deletion_code(self, code):
self.obj.generate_evaluation_code(code) self.obj.generate_evaluation_code(code)
...@@ -2750,6 +2780,7 @@ class AttributeNode(ExprNode): ...@@ -2750,6 +2780,7 @@ class AttributeNode(ExprNode):
else: else:
error(self.pos, "Cannot delete C attribute of extension type") error(self.pos, "Cannot delete C attribute of extension type")
self.obj.generate_disposal_code(code) self.obj.generate_disposal_code(code)
self.obj.free_temps(code)
def annotate(self, code): def annotate(self, code):
if self.is_py_attr: if self.is_py_attr:
...@@ -2838,6 +2869,10 @@ class SequenceNode(NewTempExprNode): ...@@ -2838,6 +2869,10 @@ class SequenceNode(NewTempExprNode):
self.generate_operation_code(code) self.generate_operation_code(code)
def generate_assignment_code(self, rhs, code): def generate_assignment_code(self, rhs, code):
# Need to work around the fact that generate_evaluation_code
# allocates the temps in a rather hacky way -- the assignment
# is evaluated twice, within each if-block.
code.putln( code.putln(
"if (PyTuple_CheckExact(%s) && PyTuple_GET_SIZE(%s) == %s) {" % ( "if (PyTuple_CheckExact(%s) && PyTuple_GET_SIZE(%s) == %s) {" % (
rhs.py_result(), rhs.py_result(),
...@@ -2855,6 +2890,10 @@ class SequenceNode(NewTempExprNode): ...@@ -2855,6 +2890,10 @@ class SequenceNode(NewTempExprNode):
value_node.generate_evaluation_code(code) value_node.generate_evaluation_code(code)
rhs.generate_disposal_code(code) rhs.generate_disposal_code(code)
for i in range(len(self.args)):
self.args[i].generate_assignment_code(
self.coerced_unpacked_items[i], code)
code.putln("} else {") code.putln("} else {")
code.putln( code.putln(
...@@ -2881,12 +2920,13 @@ class SequenceNode(NewTempExprNode): ...@@ -2881,12 +2920,13 @@ class SequenceNode(NewTempExprNode):
print("UnpackNode.generate_assignment_code:") print("UnpackNode.generate_assignment_code:")
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)
code.putln("}")
rhs.free_temps()
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("}")
rhs.free_temps(code)
def annotate(self, code): def annotate(self, code):
for arg in self.args: for arg in self.args:
...@@ -2949,6 +2989,8 @@ class TupleNode(SequenceNode): ...@@ -2949,6 +2989,8 @@ class TupleNode(SequenceNode):
# in the tuple using a reference-stealing operation. # in the tuple using a reference-stealing operation.
for arg in self.args: for arg in self.args:
arg.generate_post_assignment_code(code) arg.generate_post_assignment_code(code)
# Should NOT call free_temps -- this is invoked by the default
# generate_evaluation_code which will do that.
class ListNode(SequenceNode): class ListNode(SequenceNode):
...@@ -3051,6 +3093,8 @@ class ListNode(SequenceNode): ...@@ -3051,6 +3093,8 @@ class ListNode(SequenceNode):
# in the list using a reference-stealing operation. # in the list using a reference-stealing operation.
for arg in self.args: for arg in self.args:
arg.generate_post_assignment_code(code) arg.generate_post_assignment_code(code)
# Should NOT call free_temps -- this is invoked by the default
# generate_evaluation_code which will do that.
class ListComprehensionNode(SequenceNode): class ListComprehensionNode(SequenceNode):
...@@ -3202,6 +3246,7 @@ class DictNode(ExprNode): ...@@ -3202,6 +3246,7 @@ class DictNode(ExprNode):
item.key.value, item.key.value,
item.value.result())) item.value.result()))
item.generate_disposal_code(code) item.generate_disposal_code(code)
item.free_temps(code)
def annotate(self, code): def annotate(self, code):
for item in self.key_value_pairs: for item in self.key_value_pairs:
...@@ -3228,6 +3273,10 @@ class DictItemNode(ExprNode): ...@@ -3228,6 +3273,10 @@ class DictItemNode(ExprNode):
self.key.generate_disposal_code(code) self.key.generate_disposal_code(code)
self.value.generate_disposal_code(code) self.value.generate_disposal_code(code)
def free_temps(self, code):
self.key.free_temps(code)
self.value.free_temps(code)
def __iter__(self): def __iter__(self):
return iter([self.key, self.value]) return iter([self.key, self.value])
...@@ -4068,10 +4117,12 @@ class BoolBinopNode(NewTempExprNode): ...@@ -4068,10 +4117,12 @@ class BoolBinopNode(NewTempExprNode):
self.operand2.generate_evaluation_code(code) self.operand2.generate_evaluation_code(code)
self.allocate_temp_result(code) self.allocate_temp_result(code)
code.putln("%s = %s;" % (self.result(), self.operand2.result())) code.putln("%s = %s;" % (self.result(), self.operand2.result()))
self.operand2.free_temps() self.operand2.generate_post_assignment_code(code)
self.operand2.free_temps(code)
code.putln("} else {") code.putln("} else {")
code.putln("%s = %s;" % (self.result(), self.operand1.result())) code.putln("%s = %s;" % (self.result(), self.operand1.result()))
self.operand1.free_temps() self.operand1.generate_post_assignment_code(code)
self.operand1.free_temps(code)
code.putln("}") code.putln("}")
def generate_operand1_test(self, code): def generate_operand1_test(self, code):
...@@ -4174,6 +4225,7 @@ class CondExprNode(ExprNode): ...@@ -4174,6 +4225,7 @@ class CondExprNode(ExprNode):
self.false_val.generate_evaluation_code(code) self.false_val.generate_evaluation_code(code)
code.putln("}") code.putln("}")
self.test.generate_disposal_code(code) self.test.generate_disposal_code(code)
self.test.free_temps(code)
richcmp_constants = { richcmp_constants = {
"<" : "Py_LT", "<" : "Py_LT",
...@@ -4401,6 +4453,8 @@ class PrimaryCmpNode(NewTempExprNode, CmpNode): ...@@ -4401,6 +4453,8 @@ class PrimaryCmpNode(NewTempExprNode, CmpNode):
self.result(), self.operand2) self.result(), self.operand2)
self.operand1.generate_disposal_code(code) self.operand1.generate_disposal_code(code)
self.operand2.generate_disposal_code(code) self.operand2.generate_disposal_code(code)
self.operand1.free_temps(code)
self.operand2.free_temps(code)
def generate_subexpr_disposal_code(self, code): def generate_subexpr_disposal_code(self, code):
# If this is called, it is a non-cascaded cmp, # If this is called, it is a non-cascaded cmp,
...@@ -4408,6 +4462,12 @@ class PrimaryCmpNode(NewTempExprNode, CmpNode): ...@@ -4408,6 +4462,12 @@ class PrimaryCmpNode(NewTempExprNode, CmpNode):
self.operand1.generate_disposal_code(code) self.operand1.generate_disposal_code(code)
self.operand2.generate_disposal_code(code) self.operand2.generate_disposal_code(code)
def free_subexpr_temps(self, code):
# If this is called, it is a non-cascaded cmp,
# so only need to dispose of the two main operands.
self.operand1.free_temps(code)
self.operand2.free_temps(code)
def annotate(self, code): def annotate(self, code):
self.operand1.annotate(code) self.operand1.annotate(code)
self.operand2.annotate(code) self.operand2.annotate(code)
...@@ -4484,6 +4544,7 @@ class CascadedCmpNode(Node, CmpNode): ...@@ -4484,6 +4544,7 @@ class CascadedCmpNode(Node, CmpNode):
code, result, self.operand2) code, result, self.operand2)
# Cascaded cmp result is always temp # Cascaded cmp result is always temp
self.operand2.generate_disposal_code(code) self.operand2.generate_disposal_code(code)
self.operand2.free_temps(code)
code.putln("}") code.putln("}")
def annotate(self, code): def annotate(self, code):
...@@ -4605,6 +4666,9 @@ class PyTypeTestNode(CoercionNode): ...@@ -4605,6 +4666,9 @@ class PyTypeTestNode(CoercionNode):
def generate_post_assignment_code(self, code): def generate_post_assignment_code(self, code):
self.arg.generate_post_assignment_code(code) self.arg.generate_post_assignment_code(code)
def free_temps(self, code):
self.arg.free_temps(code)
class CoerceToPyTypeNode(CoercionNode): class CoerceToPyTypeNode(CoercionNode):
# This node is used to convert a C data type # This node is used to convert a C data type
...@@ -4776,7 +4840,11 @@ class CloneNode(CoercionNode): ...@@ -4776,7 +4840,11 @@ class CloneNode(CoercionNode):
def release_temp(self, env): def release_temp(self, env):
pass pass
class PersistentNode(ExprNode): def free_temps(self, code):
pass
class DISABLED_PersistentNode(ExprNode):
# A PersistentNode is like a CloneNode except it handles the temporary # A PersistentNode is like a CloneNode except it handles the temporary
# allocation itself by keeping track of the number of times it has been # allocation itself by keeping track of the number of times it has been
# used. # used.
......
...@@ -2444,6 +2444,7 @@ class PyClassDefNode(ClassDefNode): ...@@ -2444,6 +2444,7 @@ class PyClassDefNode(ClassDefNode):
self.body.generate_execution_code(code) self.body.generate_execution_code(code)
self.target.generate_assignment_code(self.classobj, code) self.target.generate_assignment_code(self.classobj, code)
self.dict.generate_disposal_code(code) self.dict.generate_disposal_code(code)
self.dict.free_temps(code)
class CClassDefNode(ClassDefNode): class CClassDefNode(ClassDefNode):
...@@ -2659,6 +2660,7 @@ class ExprStatNode(StatNode): ...@@ -2659,6 +2660,7 @@ class ExprStatNode(StatNode):
if not self.expr.is_temp and self.expr.result(): if not self.expr.is_temp and self.expr.result():
code.putln("%s;" % self.expr.result()) code.putln("%s;" % self.expr.result())
self.expr.generate_disposal_code(code) self.expr.generate_disposal_code(code)
self.expr.free_temps(code)
def annotate(self, code): def annotate(self, code):
self.expr.annotate(code) self.expr.annotate(code)
...@@ -2884,6 +2886,7 @@ class CascadedAssignmentNode(AssignmentNode): ...@@ -2884,6 +2886,7 @@ class CascadedAssignmentNode(AssignmentNode):
lhs.generate_assignment_code(rhs, code) lhs.generate_assignment_code(rhs, code)
# Assignment has disposed of the cloned RHS # Assignment has disposed of the cloned RHS
self.rhs.generate_disposal_code(code) self.rhs.generate_disposal_code(code)
self.rhs.free_temps(code)
def annotate(self, code): def annotate(self, code):
for i in range(len(self.lhs_list)): for i in range(len(self.lhs_list)):
...@@ -3016,7 +3019,9 @@ class InPlaceAssignmentNode(AssignmentNode): ...@@ -3016,7 +3019,9 @@ class InPlaceAssignmentNode(AssignmentNode):
code.error_goto_if_null(self.result_value.py_result(), self.pos))) code.error_goto_if_null(self.result_value.py_result(), self.pos)))
self.result_value.generate_evaluation_code(code) # May be a type check... self.result_value.generate_evaluation_code(code) # May be a type check...
self.rhs.generate_disposal_code(code) self.rhs.generate_disposal_code(code)
self.rhs.free_temps(code)
self.dup.generate_disposal_code(code) self.dup.generate_disposal_code(code)
self.dup.free_temps(code)
self.lhs.generate_assignment_code(self.result_value, code) self.lhs.generate_assignment_code(self.result_value, code)
else: else:
c_op = self.operator c_op = self.operator
...@@ -3034,8 +3039,10 @@ class InPlaceAssignmentNode(AssignmentNode): ...@@ -3034,8 +3039,10 @@ class InPlaceAssignmentNode(AssignmentNode):
self.dup.generate_result_code(code) self.dup.generate_result_code(code)
code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) ) code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
self.rhs.generate_disposal_code(code) self.rhs.generate_disposal_code(code)
self.rhs.free_temps(code)
if self.dup.is_temp: if self.dup.is_temp:
self.dup.generate_subexpr_disposal_code(code) self.dup.generate_subexpr_disposal_code(code)
self.dup.free_subexpr_temps(code)
def create_dup_node(self, env): def create_dup_node(self, env):
import ExprNodes import ExprNodes
...@@ -3065,6 +3072,8 @@ class InPlaceAssignmentNode(AssignmentNode): ...@@ -3065,6 +3072,8 @@ class InPlaceAssignmentNode(AssignmentNode):
index = index, index = index,
indices = indices, indices = indices,
is_temp = self.dup.is_temp) is_temp = self.dup.is_temp)
else:
assert False
self.lhs = target_lhs self.lhs = target_lhs
return self.dup return self.dup
...@@ -3117,6 +3126,7 @@ class PrintStatNode(StatNode): ...@@ -3117,6 +3126,7 @@ class PrintStatNode(StatNode):
self.append_newline, self.append_newline,
code.error_goto(self.pos))) code.error_goto(self.pos)))
self.arg_tuple.generate_disposal_code(code) self.arg_tuple.generate_disposal_code(code)
self.arg_tuple.free_temps(code)
def annotate(self, code): def annotate(self, code):
self.arg_tuple.annotate(code) self.arg_tuple.annotate(code)
...@@ -3152,6 +3162,7 @@ class ExecStatNode(StatNode): ...@@ -3152,6 +3162,7 @@ class ExecStatNode(StatNode):
(self.temp_result,) + args)) (self.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)
code.putln( code.putln(
code.error_goto_if_null(self.temp_result, self.pos)) code.error_goto_if_null(self.temp_result, self.pos))
code.put_decref_clear(self.temp_result, py_object_type) code.put_decref_clear(self.temp_result, py_object_type)
...@@ -3287,6 +3298,7 @@ class ReturnStatNode(StatNode): ...@@ -3287,6 +3298,7 @@ class ReturnStatNode(StatNode):
Naming.retval_cname, Naming.retval_cname,
self.value.result_as(self.return_type))) self.value.result_as(self.return_type)))
self.value.generate_post_assignment_code(code) self.value.generate_post_assignment_code(code)
self.value.free_temps(code)
else: else:
if self.return_type.is_pyobject: if self.return_type.is_pyobject:
code.put_init_to_py_none(Naming.retval_cname, self.return_type) code.put_init_to_py_none(Naming.retval_cname, self.return_type)
...@@ -3372,10 +3384,13 @@ class RaiseStatNode(StatNode): ...@@ -3372,10 +3384,13 @@ class RaiseStatNode(StatNode):
"__Pyx_ReRaise();") "__Pyx_ReRaise();")
if self.exc_type: if self.exc_type:
self.exc_type.generate_disposal_code(code) self.exc_type.generate_disposal_code(code)
self.exc_type.free_temps(code)
if self.exc_value: if self.exc_value:
self.exc_value.generate_disposal_code(code) self.exc_value.generate_disposal_code(code)
self.exc_value.free_temps(code)
if self.exc_tb: if self.exc_tb:
self.exc_tb.generate_disposal_code(code) self.exc_tb.generate_disposal_code(code)
self.exc_tb.free_temps(code)
code.putln( code.putln(
code.error_goto(self.pos)) code.error_goto(self.pos))
...@@ -3442,6 +3457,7 @@ class AssertStatNode(StatNode): ...@@ -3442,6 +3457,7 @@ class AssertStatNode(StatNode):
"PyErr_SetObject(PyExc_AssertionError, %s);" % "PyErr_SetObject(PyExc_AssertionError, %s);" %
self.value.py_result()) self.value.py_result())
self.value.generate_disposal_code(code) self.value.generate_disposal_code(code)
self.value.free_temps(code)
else: else:
code.putln( code.putln(
"PyErr_SetNone(PyExc_AssertionError);") "PyErr_SetNone(PyExc_AssertionError);")
...@@ -3450,6 +3466,7 @@ class AssertStatNode(StatNode): ...@@ -3450,6 +3466,7 @@ class AssertStatNode(StatNode):
code.putln( code.putln(
"}") "}")
self.cond.generate_disposal_code(code) self.cond.generate_disposal_code(code)
self.cond.free_temps(code)
code.putln("#endif") code.putln("#endif")
def annotate(self, code): def annotate(self, code):
...@@ -3756,6 +3773,7 @@ class ForInStatNode(LoopNode, StatNode): ...@@ -3756,6 +3773,7 @@ class ForInStatNode(LoopNode, StatNode):
code.put_label(break_label) code.put_label(break_label)
self.iterator.release_counter_temp(code) self.iterator.release_counter_temp(code)
self.iterator.generate_disposal_code(code) self.iterator.generate_disposal_code(code)
self.iterator.free_temps(code)
def annotate(self, code): def annotate(self, code):
self.target.annotate(code) self.target.annotate(code)
...@@ -3878,9 +3896,12 @@ class ForFromStatNode(LoopNode, StatNode): ...@@ -3878,9 +3896,12 @@ class ForFromStatNode(LoopNode, StatNode):
code.putln("}") code.putln("}")
code.put_label(break_label) code.put_label(break_label)
self.bound1.generate_disposal_code(code) self.bound1.generate_disposal_code(code)
self.bound1.free_temps(code)
self.bound2.generate_disposal_code(code) self.bound2.generate_disposal_code(code)
self.bound2.free_temps(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)
relation_table = { relation_table = {
# {relop : (initial offset, increment op)} # {relop : (initial offset, increment op)}
...@@ -4103,6 +4124,7 @@ class ExceptClauseNode(Node): ...@@ -4103,6 +4124,7 @@ class ExceptClauseNode(Node):
self.match_flag, self.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)
code.putln( code.putln(
"if (%s) {" % "if (%s) {" %
self.match_flag) self.match_flag)
...@@ -4539,6 +4561,7 @@ class FromImportStatNode(StatNode): ...@@ -4539,6 +4561,7 @@ class FromImportStatNode(StatNode):
code.error_goto_if_null(self.item.result(), self.pos))) code.error_goto_if_null(self.item.result(), self.pos)))
target.generate_assignment_code(self.item, code) target.generate_assignment_code(self.item, code)
self.module.generate_disposal_code(code) self.module.generate_disposal_code(code)
self.module.free_temps(code)
......
...@@ -8,9 +8,13 @@ import TypeSlots ...@@ -8,9 +8,13 @@ import TypeSlots
import Symtab import Symtab
from StringEncoding import EncodedString from StringEncoding import EncodedString
#def unwrap_node(node):
# while isinstance(node, ExprNodes.PersistentNode):
# node = node.arg
# return node
# Temporary hack while PersistentNode is out of order
def unwrap_node(node): def unwrap_node(node):
while isinstance(node, ExprNodes.PersistentNode):
node = node.arg
return node return node
def is_common_value(a, b): def is_common_value(a, b):
......
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