[UCRT:MATH] Implement math error support functions

This commit is contained in:
Timo Kreuzer 2024-10-28 18:14:55 +02:00
parent 8aab548ecd
commit b09b5584e0
3 changed files with 96 additions and 0 deletions

View file

@ -94,6 +94,7 @@ include(initializers/initializers.cmake)
include(internal/internal.cmake)
include(locale/locale.cmake)
include(lowio/lowio.cmake)
include(math/math.cmake)
include(mbstring/mbstring.cmake)
include(misc/misc.cmake)
include(startup/startup.cmake)
@ -116,6 +117,7 @@ add_library(ucrt OBJECT
${UCRT_INTERNAL_SOURCES}
${UCRT_LOCALE_SOURCES}
${UCRT_LOWIO_SOURCES}
${UCRT_MATH_SOURCES}
${UCRT_MBSTRING_SOURCES}
${UCRT_MISC_SOURCES}
${UCRT_STARTUP_SOURCES}

View file

@ -0,0 +1,4 @@
list(APPEND UCRT_MATH_SOURCES
math/matherr.cpp
)

View file

@ -0,0 +1,90 @@
//
// matherr.cpp
//
// Copyright (c) 2024 Timo Kreuzer
//
// User math error support.
//
// SPDX-License-Identifier: MIT
//
#include <math.h>
#include <corecrt_startup.h>
#include <corecrt_internal.h>
static __crt_state_management::dual_state_global<_UserMathErrorFunctionPointer> __acrt_global_user_matherr;
//
// Declared in corecrt_internal.h
// Called from initialize_pointers()
//
extern "C"
void __cdecl __acrt_initialize_user_matherr(void* encoded_null)
{
__acrt_global_user_matherr.initialize(
reinterpret_cast<_UserMathErrorFunctionPointer>(encoded_null));
}
//
// Declared in corecrt_internal.h
//
extern "C"
bool __cdecl __acrt_has_user_matherr(void)
{
_UserMathErrorFunctionPointer user_matherr =
__crt_fast_decode_pointer(__acrt_global_user_matherr.value());
return user_matherr != nullptr;
}
//
// Declared in corecrt_internal.h
//
extern "C"
int __cdecl __acrt_invoke_user_matherr(struct _exception* _Exp)
{
_UserMathErrorFunctionPointer user_matherr =
__crt_fast_decode_pointer(__acrt_global_user_matherr.value());
if (user_matherr != nullptr)
{
return user_matherr(_Exp);
}
return 0;
}
//
// Declared in corecrt_startup.h
//
extern "C"
void
__cdecl
__setusermatherr(
_UserMathErrorFunctionPointer _UserMathErrorFunction)
{
_UserMathErrorFunctionPointer encodedPtr =
__crt_fast_encode_pointer(_UserMathErrorFunction);
__acrt_global_user_matherr.value() = encodedPtr;
}
//
// Used by libm
//
extern "C"
int
__cdecl
_invoke_matherr(
int type,
char* name,
double arg1,
double arg2,
double retval)
{
struct _exception excpt;
excpt.type = type;
excpt.name = name;
excpt.arg1 = arg1;
excpt.arg2 = arg2;
excpt.retval = retval;
return __acrt_invoke_user_matherr(&excpt);
}