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

Added __Pyx_GOTREF calls (probably not everywhere needed)

parent f020a6d2
...@@ -10,6 +10,7 @@ from PyrexTypes import py_object_type, typecast ...@@ -10,6 +10,7 @@ from PyrexTypes import py_object_type, typecast
from TypeSlots import method_coexist from TypeSlots import method_coexist
from Scanning import SourceDescriptor from Scanning import SourceDescriptor
from Cython.StringIOTree import StringIOTree from Cython.StringIOTree import StringIOTree
import DebugFlags
try: try:
set set
except NameError: except NameError:
...@@ -671,6 +672,10 @@ class CCodeWriter(object): ...@@ -671,6 +672,10 @@ class CCodeWriter(object):
def as_pyobject(self, cname, type): def as_pyobject(self, cname, type):
return typecast(py_object_type, type, cname) return typecast(py_object_type, type, cname)
def put_gotref(self, cname):
if DebugFlags.debug_ref_check_code:
self.putln("__Pyx_GOTREF(%s);" % cname)
def put_incref(self, cname, type): def put_incref(self, cname, type):
self.putln("Py_INCREF(%s);" % self.as_pyobject(cname, type)) self.putln("Py_INCREF(%s);" % self.as_pyobject(cname, type))
...@@ -756,7 +761,7 @@ class CCodeWriter(object): ...@@ -756,7 +761,7 @@ class CCodeWriter(object):
"|".join(method_flags), "|".join(method_flags),
doc_code, doc_code,
term)) term))
def put_error_if_neg(self, pos, value): def put_error_if_neg(self, pos, value):
# return self.putln("if (unlikely(%s < 0)) %s" % (value, self.error_goto(pos))) # TODO this path is almost _never_ taken, yet this macro makes is slower! # return self.putln("if (unlikely(%s < 0)) %s" % (value, self.error_goto(pos))) # TODO this path is almost _never_ taken, yet this macro makes is slower!
return self.putln("if (%s < 0) %s" % (value, self.error_goto(pos))) return self.putln("if (%s < 0) %s" % (value, self.error_goto(pos)))
......
...@@ -2,3 +2,4 @@ debug_disposal_code = 0 ...@@ -2,3 +2,4 @@ debug_disposal_code = 0
debug_temp_alloc = 0 debug_temp_alloc = 0
debug_coercion = 0 debug_coercion = 0
debug_ref_check_code = 1
...@@ -903,6 +903,7 @@ class LongNode(AtomicExprNode): ...@@ -903,6 +903,7 @@ class LongNode(AtomicExprNode):
self.result(), self.result(),
self.value, self.value,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
class ImagNode(AtomicExprNode): class ImagNode(AtomicExprNode):
...@@ -926,6 +927,8 @@ class ImagNode(AtomicExprNode): ...@@ -926,6 +927,8 @@ class ImagNode(AtomicExprNode):
self.result(), self.result(),
self.value, self.value,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
class NameNode(AtomicExprNode): class NameNode(AtomicExprNode):
...@@ -1146,13 +1149,16 @@ class NameNode(AtomicExprNode): ...@@ -1146,13 +1149,16 @@ class NameNode(AtomicExprNode):
namespace, namespace,
self.interned_cname, self.interned_cname,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
elif entry.is_local and False: elif entry.is_local and False:
# control flow not good enough yet # control flow not good enough yet
assigned = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos) assigned = entry.scope.control_flow.get_state((entry.name, 'initalized'), self.pos)
if assigned is False: if assigned is False:
error(self.pos, "local variable '%s' referenced before assignment" % entry.name) error(self.pos, "local variable '%s' referenced before assignment" % entry.name)
elif not Options.init_local_none and assigned is None: elif not Options.init_local_none and assigned is None:
code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' % (entry.cname, entry.name, code.error_goto(self.pos))) code.putln('if (%s == 0) { PyErr_SetString(PyExc_UnboundLocalError, "%s"); %s }' %
(entry.cname, entry.name, code.error_goto(self.pos)))
entry.scope.control_flow.set_state(self.pos, (entry.name, 'initalized'), True) entry.scope.control_flow.set_state(self.pos, (entry.name, 'initalized'), True)
def generate_assignment_code(self, rhs, code): def generate_assignment_code(self, rhs, code):
...@@ -1277,6 +1283,8 @@ class BackquoteNode(ExprNode): ...@@ -1277,6 +1283,8 @@ class BackquoteNode(ExprNode):
self.result(), self.result(),
self.arg.py_result(), self.arg.py_result(),
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
class ImportNode(ExprNode): class ImportNode(ExprNode):
...@@ -1313,6 +1321,7 @@ class ImportNode(ExprNode): ...@@ -1313,6 +1321,7 @@ class ImportNode(ExprNode):
self.module_name.py_result(), self.module_name.py_result(),
name_list_code, name_list_code,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
class IteratorNode(ExprNode): class IteratorNode(ExprNode):
...@@ -1356,6 +1365,7 @@ class IteratorNode(ExprNode): ...@@ -1356,6 +1365,7 @@ class IteratorNode(ExprNode):
self.result(), self.result(),
self.sequence.py_result(), self.sequence.py_result(),
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
code.putln("}") code.putln("}")
...@@ -1402,6 +1412,7 @@ class NextNode(AtomicExprNode): ...@@ -1402,6 +1412,7 @@ class NextNode(AtomicExprNode):
code.putln(code.error_goto_if_PyErr(self.pos)) code.putln(code.error_goto_if_PyErr(self.pos))
code.putln("break;") code.putln("break;")
code.putln("}") code.putln("}")
code.put_gotref(self.result())
code.putln("}") code.putln("}")
...@@ -1649,7 +1660,8 @@ class IndexNode(ExprNode): ...@@ -1649,7 +1660,8 @@ class IndexNode(ExprNode):
self.index_unsigned_parameter(), self.index_unsigned_parameter(),
self.result(), self.result(),
code.error_goto(self.pos))) code.error_goto(self.pos)))
code.put_gotref(self.result())
def generate_setitem_code(self, value_code, code): def generate_setitem_code(self, value_code, code):
if self.index.type.is_int: if self.index.type.is_int:
function = "__Pyx_SetItemInt" function = "__Pyx_SetItemInt"
...@@ -1666,6 +1678,7 @@ class IndexNode(ExprNode): ...@@ -1666,6 +1678,7 @@ class IndexNode(ExprNode):
value_code, value_code,
self.index_unsigned_parameter(), self.index_unsigned_parameter(),
code.error_goto(self.pos))) code.error_goto(self.pos)))
code.put_gotref(self.base.py_result())
def generate_buffer_setitem_code(self, rhs, code, op=""): def generate_buffer_setitem_code(self, rhs, code, op=""):
# Used from generate_assignment_code and InPlaceAssignmentNode # Used from generate_assignment_code and InPlaceAssignmentNode
...@@ -1799,6 +1812,7 @@ class SliceIndexNode(ExprNode): ...@@ -1799,6 +1812,7 @@ class SliceIndexNode(ExprNode):
self.start_code(), self.start_code(),
self.stop_code(), self.stop_code(),
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
def generate_assignment_code(self, rhs, code): def generate_assignment_code(self, rhs, code):
self.generate_subexpr_evaluation_code(code) self.generate_subexpr_evaluation_code(code)
...@@ -1882,6 +1896,7 @@ class SliceNode(ExprNode): ...@@ -1882,6 +1896,7 @@ class SliceNode(ExprNode):
self.stop.py_result(), self.stop.py_result(),
self.step.py_result(), self.step.py_result(),
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
class CallNode(ExprNode): class CallNode(ExprNode):
...@@ -2102,6 +2117,7 @@ class SimpleCallNode(CallNode): ...@@ -2102,6 +2117,7 @@ class SimpleCallNode(CallNode):
self.function.py_result(), self.function.py_result(),
arg_code, arg_code,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
elif func_type.is_cfunction: elif func_type.is_cfunction:
if self.has_optional_args: if self.has_optional_args:
actual_nargs = len(self.args) actual_nargs = len(self.args)
...@@ -2156,6 +2172,9 @@ class SimpleCallNode(CallNode): ...@@ -2156,6 +2172,9 @@ class SimpleCallNode(CallNode):
else: else:
goto_error = "" goto_error = ""
code.putln("%s%s; %s" % (lhs, rhs, goto_error)) code.putln("%s%s; %s" % (lhs, rhs, goto_error))
if self.type.is_pyobject and self.result():
code.put_gotref(self.result())
class GeneralCallNode(CallNode): class GeneralCallNode(CallNode):
# General Python function call, including keyword, # General Python function call, including keyword,
...@@ -2231,6 +2250,7 @@ class GeneralCallNode(CallNode): ...@@ -2231,6 +2250,7 @@ class GeneralCallNode(CallNode):
self.result(), self.result(),
call_code, call_code,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
class AsTupleNode(ExprNode): class AsTupleNode(ExprNode):
...@@ -2263,6 +2283,7 @@ class AsTupleNode(ExprNode): ...@@ -2263,6 +2283,7 @@ class AsTupleNode(ExprNode):
self.result(), self.result(),
self.arg.py_result(), self.arg.py_result(),
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
class AttributeNode(ExprNode): class AttributeNode(ExprNode):
...@@ -2526,6 +2547,7 @@ class AttributeNode(ExprNode): ...@@ -2526,6 +2547,7 @@ class AttributeNode(ExprNode):
self.obj.py_result(), self.obj.py_result(),
self.interned_attr_cname, self.interned_attr_cname,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
else: else:
# result_code contains what is needed, but we may need to insert # result_code contains what is needed, but we may need to insert
# a check and raise an exception # a check and raise an exception
...@@ -2683,6 +2705,7 @@ class SequenceNode(ExprNode): ...@@ -2683,6 +2705,7 @@ class SequenceNode(ExprNode):
self.iterator.result(), self.iterator.result(),
rhs.py_result(), rhs.py_result(),
code.error_goto_if_null(self.iterator.result(), self.pos))) code.error_goto_if_null(self.iterator.result(), self.pos)))
code.put_gotref(self.iterator.result())
rhs.generate_disposal_code(code) rhs.generate_disposal_code(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]
...@@ -2693,6 +2716,7 @@ class SequenceNode(ExprNode): ...@@ -2693,6 +2716,7 @@ class SequenceNode(ExprNode):
item.result(), item.result(),
typecast(item.ctype(), py_object_type, unpack_code), typecast(item.ctype(), py_object_type, unpack_code),
code.error_goto_if_null(item.result(), self.pos))) code.error_goto_if_null(item.result(), self.pos)))
code.put_gotref(item.result())
value_node = self.coerced_unpacked_items[i] value_node = self.coerced_unpacked_items[i]
value_node.generate_evaluation_code(code) value_node.generate_evaluation_code(code)
self.args[i].generate_assignment_code(value_node, code) self.args[i].generate_assignment_code(value_node, code)
...@@ -2751,6 +2775,7 @@ class TupleNode(SequenceNode): ...@@ -2751,6 +2775,7 @@ class TupleNode(SequenceNode):
self.result(), self.result(),
len(self.args), len(self.args),
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
for i in range(len(self.args)): for i in range(len(self.args)):
arg = self.args[i] arg = self.args[i]
if not arg.result_in_temp(): if not arg.result_in_temp():
...@@ -2895,6 +2920,7 @@ class ListComprehensionNode(SequenceNode): ...@@ -2895,6 +2920,7 @@ class ListComprehensionNode(SequenceNode):
(self.result(), (self.result(),
0, 0,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
self.loop.generate_execution_code(code) self.loop.generate_execution_code(code)
def annotate(self, code): def annotate(self, code):
...@@ -3006,6 +3032,7 @@ class DictNode(ExprNode): ...@@ -3006,6 +3032,7 @@ class DictNode(ExprNode):
"%s = PyDict_New(); %s" % ( "%s = PyDict_New(); %s" % (
self.result(), self.result(),
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
for item in self.key_value_pairs: for item in self.key_value_pairs:
item.generate_evaluation_code(code) item.generate_evaluation_code(code)
if self.type.is_pyobject: if self.type.is_pyobject:
...@@ -3092,6 +3119,7 @@ class ClassNode(ExprNode): ...@@ -3092,6 +3119,7 @@ class ClassNode(ExprNode):
self.cname, self.cname,
self.module_name, self.module_name,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
class UnboundMethodNode(ExprNode): class UnboundMethodNode(ExprNode):
...@@ -3119,7 +3147,7 @@ class UnboundMethodNode(ExprNode): ...@@ -3119,7 +3147,7 @@ class UnboundMethodNode(ExprNode):
self.function.py_result(), self.function.py_result(),
self.class_cname, self.class_cname,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
class PyCFunctionNode(AtomicExprNode): class PyCFunctionNode(AtomicExprNode):
# Helper class used in the implementation of Python # Helper class used in the implementation of Python
...@@ -3141,6 +3169,7 @@ class PyCFunctionNode(AtomicExprNode): ...@@ -3141,6 +3169,7 @@ class PyCFunctionNode(AtomicExprNode):
self.result(), self.result(),
self.pymethdef_cname, self.pymethdef_cname,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
#------------------------------------------------------------------- #-------------------------------------------------------------------
# #
...@@ -3215,6 +3244,7 @@ class UnopNode(ExprNode): ...@@ -3215,6 +3244,7 @@ class UnopNode(ExprNode):
function, function,
self.operand.py_result(), self.operand.py_result(),
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
def type_error(self): def type_error(self):
if not self.operand.type.is_error: if not self.operand.type.is_error:
...@@ -3609,6 +3639,7 @@ class BinopNode(NewTempExprNode): ...@@ -3609,6 +3639,7 @@ class BinopNode(NewTempExprNode):
self.operand2.py_result(), self.operand2.py_result(),
extra_args, extra_args,
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
else: else:
if self.is_temp: if self.is_temp:
self.generate_c_operation_code(code) self.generate_c_operation_code(code)
...@@ -4068,6 +4099,7 @@ class CmpNode: ...@@ -4068,6 +4099,7 @@ class CmpNode:
operand2.py_result(), operand2.py_result(),
richcmp_constants[op], richcmp_constants[op],
code.error_goto_if_null(result_code, self.pos))) code.error_goto_if_null(result_code, self.pos)))
code.put_gotref(result_code)
else: else:
type1 = operand1.type type1 = operand1.type
type2 = operand2.type type2 = operand2.type
...@@ -4441,6 +4473,7 @@ class CoerceToPyTypeNode(CoercionNode): ...@@ -4441,6 +4473,7 @@ class CoerceToPyTypeNode(CoercionNode):
function, function,
self.arg.result(), self.arg.result(),
code.error_goto_if_null(self.result(), self.pos))) code.error_goto_if_null(self.result(), self.pos)))
code.put_gotref(self.result())
class CoerceFromPyTypeNode(CoercionNode): class CoerceFromPyTypeNode(CoercionNode):
...@@ -4472,6 +4505,8 @@ class CoerceFromPyTypeNode(CoercionNode): ...@@ -4472,6 +4505,8 @@ class CoerceFromPyTypeNode(CoercionNode):
self.result(), self.result(),
rhs, rhs,
code.error_goto_if(self.type.error_condition(self.result()), self.pos))) code.error_goto_if(self.type.error_condition(self.result()), self.pos)))
if self.type.is_pyobject:
code.put_gotref(self.result())
class CoerceToBooleanNode(CoercionNode): class CoerceToBooleanNode(CoercionNode):
......
...@@ -850,6 +850,7 @@ class CEnumDefNode(StatNode): ...@@ -850,6 +850,7 @@ class CEnumDefNode(StatNode):
self.temp, self.temp,
item.cname, item.cname,
code.error_goto_if_null(self.temp, item.pos))) code.error_goto_if_null(self.temp, item.pos)))
code.put_gotref(self.temp) #TODO: Is this right?
code.putln('if (PyObject_SetAttrString(%s, "%s", %s) < 0) %s' % ( code.putln('if (PyObject_SetAttrString(%s, "%s", %s) < 0) %s' % (
Naming.module_cname, Naming.module_cname,
item.name, item.name,
...@@ -2199,6 +2200,7 @@ class DefNode(FuncDefNode): ...@@ -2199,6 +2200,7 @@ class DefNode(FuncDefNode):
func, func,
arg.hdr_cname, arg.hdr_cname,
code.error_goto_if_null(arg.entry.cname, arg.pos))) code.error_goto_if_null(arg.entry.cname, arg.pos)))
code.put_gotref(arg.entry.cname)
else: else:
error(arg.pos, error(arg.pos,
"Cannot convert argument of type '%s' to Python object" "Cannot convert argument of type '%s' to Python object"
...@@ -2278,6 +2280,7 @@ class OverrideCheckNode(StatNode): ...@@ -2278,6 +2280,7 @@ class OverrideCheckNode(StatNode):
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)
err = code.error_goto_if_null(self.func_node.result(), self.pos) err = code.error_goto_if_null(self.func_node.result(), self.pos)
code.put_gotref(self.func_node.result())
# 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" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err)) code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err))
# It appears that this type is not anywhere exposed in the Python/C API # It appears that this type is not anywhere exposed in the Python/C API
...@@ -2327,7 +2330,7 @@ class PyClassDefNode(ClassDefNode): ...@@ -2327,7 +2330,7 @@ class PyClassDefNode(ClassDefNode):
def as_cclass(self): def as_cclass(self):
""" """
Return this node as if it were declared as an extension class" Return this node as if it were declared as an extension class
""" """
bases = self.classobj.bases.args bases = self.classobj.bases.args
if len(bases) == 0: if len(bases) == 0:
...@@ -2968,6 +2971,7 @@ class InPlaceAssignmentNode(AssignmentNode): ...@@ -2968,6 +2971,7 @@ class InPlaceAssignmentNode(AssignmentNode):
self.rhs.py_result(), self.rhs.py_result(),
extra, extra,
code.error_goto_if_null(self.result_value.py_result(), self.pos))) code.error_goto_if_null(self.result_value.py_result(), self.pos)))
code.put_gotref(self.result_value.result())
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.dup.generate_disposal_code(code) self.dup.generate_disposal_code(code)
...@@ -4443,6 +4447,7 @@ class FromImportStatNode(StatNode): ...@@ -4443,6 +4447,7 @@ class FromImportStatNode(StatNode):
self.module.py_result(), self.module.py_result(),
cname, cname,
code.error_goto_if_null(self.item.result(), self.pos))) code.error_goto_if_null(self.item.result(), self.pos)))
code.put_gotref(self.item.result())
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)
......
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