| """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);')) |