blob: 3f7fc4ac554f89ba8d10d46333548602c0b9e036 [file] [log] [blame] [edit]
"""Exception-related primitive ops."""
from mypyc.ops import (
bool_rprimitive, object_rprimitive, void_rtype, exc_rtuple,
ERR_NEVER, ERR_FALSE
)
from mypyc.ops_primitive import (
simple_emit, custom_op,
)
# TODO: Making this raise conditionally is kind of hokey.
raise_exception_op = custom_op(
arg_types=[object_rprimitive],
result_type=bool_rprimitive,
error_kind=ERR_FALSE,
format_str='raise_exception({args[0]}); {dest} = 0',
emit=simple_emit('CPy_Raise({args[0]}); {dest} = 0;'))
set_stop_iteration_value = custom_op(
arg_types=[object_rprimitive],
result_type=bool_rprimitive,
error_kind=ERR_FALSE,
format_str='set_stop_iteration_value({args[0]}); {dest} = 0',
emit=simple_emit('CPyGen_SetStopIterationValue({args[0]}); {dest} = 0;'))
raise_exception_with_tb_op = custom_op(
arg_types=[object_rprimitive, object_rprimitive, object_rprimitive],
result_type=bool_rprimitive,
error_kind=ERR_FALSE,
format_str='raise_exception_with_tb({args[0]}, {args[1]}, {args[2]}); {dest} = 0',
emit=simple_emit('CPyErr_SetObjectAndTraceback({args[0]}, {args[1]}, {args[2]}); {dest} = 0;'))
reraise_exception_op = custom_op(
arg_types=[],
result_type=bool_rprimitive,
error_kind=ERR_FALSE,
format_str='reraise_exc; {dest} = 0',
emit=simple_emit('CPy_Reraise(); {dest} = 0;'))
no_err_occurred_op = custom_op(
arg_types=[],
result_type=bool_rprimitive,
error_kind=ERR_FALSE,
format_str='{dest} = no_err_occurred',
emit=simple_emit('{dest} = (PyErr_Occurred() == NULL);'))
assert_err_occured_op = custom_op(
arg_types=[],
result_type=void_rtype,
error_kind=ERR_NEVER,
format_str='assert_err_occurred',
emit=simple_emit('assert(PyErr_Occurred() != NULL && "failure w/o err!");'))
keep_propagating_op = custom_op(
arg_types=[],
result_type=bool_rprimitive,
error_kind=ERR_FALSE,
format_str='{dest} = keep_propagating',
emit=simple_emit('{dest} = 0;'))
# Catches a propagating exception and makes it the "currently
# handled exception" (by sticking it into sys.exc_info()). Returns the
# exception that was previously being handled, which must be restored
# later.
error_catch_op = custom_op(
arg_types=[],
result_type=exc_rtuple,
error_kind=ERR_NEVER,
format_str='{dest} = error_catch',
emit=simple_emit('CPy_CatchError(&{dest}.f0, &{dest}.f1, &{dest}.f2);'))
# Restore an old "currently handled exception" returned from
# error_catch (by sticking it into sys.exc_info())
restore_exc_info_op = custom_op(
arg_types=[exc_rtuple],
result_type=void_rtype,
error_kind=ERR_NEVER,
format_str='restore_exc_info {args[0]}',
emit=simple_emit('CPy_RestoreExcInfo({args[0]}.f0, {args[0]}.f1, {args[0]}.f2);'))
# Checks whether the exception currently being handled matches a particular type.
exc_matches_op = custom_op(
arg_types=[object_rprimitive],
result_type=bool_rprimitive,
error_kind=ERR_NEVER,
format_str='{dest} = exc_matches {args[0]}',
emit=simple_emit('{dest} = CPy_ExceptionMatches({args[0]});'))
# Get the value of the exception currently being handled.
get_exc_value_op = custom_op(
arg_types=[],
result_type=object_rprimitive,
error_kind=ERR_NEVER,
format_str='{dest} = get_exc_value',
emit=simple_emit('{dest} = CPy_GetExcValue();'))
get_exc_info_op = custom_op(
arg_types=[],
result_type=exc_rtuple,
error_kind=ERR_NEVER,
format_str='{dest} = get_exc_info',
emit=simple_emit('CPy_GetExcInfo(&{dest}.f0, &{dest}.f1, &{dest}.f2);'))