1 // 2 // matherr.cpp 3 // 4 // Copyright (c) 2024 Timo Kreuzer 5 // 6 // User math error support. 7 // 8 // SPDX-License-Identifier: MIT 9 // 10 11 #include <math.h> 12 #include <corecrt_startup.h> 13 #include <corecrt_internal.h> 14 15 static __crt_state_management::dual_state_global<_UserMathErrorFunctionPointer> __acrt_global_user_matherr; 16 17 // 18 // Declared in corecrt_internal.h 19 // Called from initialize_pointers() 20 // 21 extern "C" __acrt_initialize_user_matherr(void * encoded_null)22void __cdecl __acrt_initialize_user_matherr(void* encoded_null) 23 { 24 __acrt_global_user_matherr.initialize( 25 reinterpret_cast<_UserMathErrorFunctionPointer>(encoded_null)); 26 } 27 28 // 29 // Declared in corecrt_internal.h 30 // 31 extern "C" __acrt_has_user_matherr(void)32bool __cdecl __acrt_has_user_matherr(void) 33 { 34 _UserMathErrorFunctionPointer user_matherr = 35 __crt_fast_decode_pointer(__acrt_global_user_matherr.value()); 36 return user_matherr != nullptr; 37 } 38 39 // 40 // Declared in corecrt_internal.h 41 // 42 extern "C" __acrt_invoke_user_matherr(struct _exception * _Exp)43int __cdecl __acrt_invoke_user_matherr(struct _exception* _Exp) 44 { 45 _UserMathErrorFunctionPointer user_matherr = 46 __crt_fast_decode_pointer(__acrt_global_user_matherr.value()); 47 if (user_matherr != nullptr) 48 { 49 return user_matherr(_Exp); 50 } 51 52 return 0; 53 } 54 55 // 56 // Declared in corecrt_startup.h 57 // 58 extern "C" 59 void 60 __cdecl __setusermatherr(_UserMathErrorFunctionPointer _UserMathErrorFunction)61__setusermatherr( 62 _UserMathErrorFunctionPointer _UserMathErrorFunction) 63 { 64 _UserMathErrorFunctionPointer encodedPtr = 65 __crt_fast_encode_pointer(_UserMathErrorFunction); 66 67 __acrt_global_user_matherr.value() = encodedPtr; 68 } 69 70 // 71 // Used by libm 72 // 73 extern "C" 74 int 75 __cdecl _invoke_matherr(int type,char * name,double arg1,double arg2,double retval)76_invoke_matherr( 77 int type, 78 char* name, 79 double arg1, 80 double arg2, 81 double retval) 82 { 83 struct _exception excpt; 84 excpt.type = type; 85 excpt.name = name; 86 excpt.arg1 = arg1; 87 excpt.arg2 = arg2; 88 excpt.retval = retval; 89 return __acrt_invoke_user_matherr(&excpt); 90 } 91