Commit d229ad5d authored by Xavier Thompson's avatar Xavier Thompson

Support CheckedResult exception propagation on cypclass subscript operations

parent ea5bd9a2
...@@ -3913,6 +3913,8 @@ class IndexNode(_IndexingBaseNode): ...@@ -3913,6 +3913,8 @@ class IndexNode(_IndexingBaseNode):
self.is_temp = True self.is_temp = True
if self.exception_value is None: if self.exception_value is None:
env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp")) env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
elif self.exception_check == '~':
self.is_temp = True
self.index = self.index.coerce_to(func_type.args[0].type, env) self.index = self.index.coerce_to(func_type.args[0].type, env)
self.type = func_type.return_type self.type = func_type.return_type
if setting and not func_type.return_type.is_reference: if setting and not func_type.return_type.is_reference:
...@@ -3944,6 +3946,8 @@ class IndexNode(_IndexingBaseNode): ...@@ -3944,6 +3946,8 @@ class IndexNode(_IndexingBaseNode):
self.is_temp = True self.is_temp = True
if self.exception_value is None: if self.exception_value is None:
env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp")) env.use_utility_code(UtilityCode.load_cached("CppExceptionConversion", "CppSupport.cpp"))
elif self.exception_check == '~':
self.is_temp = True
self.index = self.index.coerce_to(function.type.args[0].type, env) self.index = self.index.coerce_to(function.type.args[0].type, env)
self.type = func_type.return_type self.type = func_type.return_type
...@@ -4287,7 +4291,7 @@ class IndexNode(_IndexingBaseNode): ...@@ -4287,7 +4291,7 @@ class IndexNode(_IndexingBaseNode):
function = "__Pyx_GetItemInt_ByteArray" function = "__Pyx_GetItemInt_ByteArray"
error_value = '-1' error_value = '-1'
utility_code = UtilityCode.load_cached("GetItemIntByteArray", "StringTools.c") utility_code = UtilityCode.load_cached("GetItemIntByteArray", "StringTools.c")
elif not (self.base.type.is_cpp_class and self.exception_check == '+'): elif not (self.base.type.is_cpp_class and self.exception_check in ('+', '~')):
assert False, "unexpected type %s and base type %s for indexing" % ( assert False, "unexpected type %s and base type %s for indexing" % (
self.type, self.base.type) self.type, self.base.type)
...@@ -4299,15 +4303,20 @@ class IndexNode(_IndexingBaseNode): ...@@ -4299,15 +4303,20 @@ class IndexNode(_IndexingBaseNode):
else: else:
index_code = self.index.py_result() index_code = self.index.py_result()
if self.base.type.is_cpp_class and self.exception_check == '+': if self.base.type.is_cpp_class:
base_result = self.base.result() base_result = self.base.result()
if self.base.type.is_cyp_class: if self.base.type.is_cyp_class:
base_result = "(*%s)" % base_result base_result = "(*%s)" % base_result
evaluation_code = "%s = %s[%s];" % (self.result(), base_result, self.index.result())
if self.exception_check == '+':
translate_cpp_exception(code, self.pos, translate_cpp_exception(code, self.pos,
"%s = %s[%s];" % (self.result(), base_result, evaluation_code,
self.index.result()),
self.result() if self.type.is_pyobject else None, self.result() if self.type.is_pyobject else None,
self.exception_value, self.in_nogil_context) self.exception_value, self.in_nogil_context)
elif self.exception_check == '~':
exc_check_code = self.type.error_condition(self.result())
goto_error = code.error_goto_if(exc_check_code, self.pos)
code.putln("%s %s" % (evaluation_code, goto_error))
else: else:
error_check = '!%s' if error_value == 'NULL' else '%%s == %s' % error_value error_check = '!%s' if error_value == 'NULL' else '%%s == %s' % error_value
code.putln( code.putln(
...@@ -4364,11 +4373,18 @@ class IndexNode(_IndexingBaseNode): ...@@ -4364,11 +4373,18 @@ class IndexNode(_IndexingBaseNode):
function_code, function_code,
self.index.result(), self.index.result(),
value_code) value_code)
if self.exception_check and self.exception_check == "+": if self.exception_check == "+":
translate_cpp_exception(code, self.pos, translate_cpp_exception(code, self.pos,
setitem_code, setitem_code,
None, None,
self.exception_value, self.in_nogil_context) self.exception_value, self.in_nogil_context)
elif self.exception_check == "~":
checked_result_type = function.type.return_type
temp_code = code.funcstate.allocate_temp(checked_result_type, manage_ref=False)
exc_check_code = checked_result_type.error_condition(temp_code)
goto_error = code.error_goto_if(exc_check_code, self.pos)
code.putln("%s = %s %s" % (temp_code, setitem_code, goto_error))
code.funcstate.release_temp(temp_code)
else: else:
code.putln(setitem_code) code.putln(setitem_code)
...@@ -4450,11 +4466,17 @@ class IndexNode(_IndexingBaseNode): ...@@ -4450,11 +4466,17 @@ class IndexNode(_IndexingBaseNode):
self.base.result(), self.base.result(),
function_code, function_code,
self.index.result()) self.index.result())
if self.exception_check and self.exception_check == "+": if self.exception_check == "+":
translate_cpp_exception(code, self.pos, translate_cpp_exception(code, self.pos,
setitem_code, setitem_code,
None, None,
self.exception_value, self.in_nogil_context) self.exception_value, self.in_nogil_context)
elif self.exception_check == "~":
temp_code = code.funcstate.allocate_temp(self.type, manage_ref=False)
exc_check_code = self.type.error_condition(temp_code)
goto_error = code.error_goto_if(exc_check_code, self.pos)
code.putln("%s = %s %s" % (temp_code, setitem_code, goto_error))
code.funcstate.release_temp(temp_code)
else: else:
code.putln(setitem_code) code.putln(setitem_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