From 43be238331ba8cebd4c8bf93eb2d7be0e1339184 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Tue, 2 Sep 2014 17:06:06 +0200 Subject: [PATCH] msvcr80: Throw bad_alloc exception when operator new fails. --- dlls/msvcrt/cpp.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ dlls/msvcrt/heap.c | 3 +++ dlls/msvcrt/msvcrt.h | 5 ++++- 3 files changed, 52 insertions(+), 1 deletion(-) diff --git a/dlls/msvcrt/cpp.c b/dlls/msvcrt/cpp.c index db48dcbbd25..de9a9b4b436 100644 --- a/dlls/msvcrt/cpp.c +++ b/dlls/msvcrt/cpp.c @@ -696,6 +696,47 @@ DEFINE_EXCEPTION_TYPE_INFO( bad_typeid, 1, &exception_cxx_type_info, NULL ) DEFINE_EXCEPTION_TYPE_INFO( bad_cast, 1, &exception_cxx_type_info, NULL ) DEFINE_EXCEPTION_TYPE_INFO( __non_rtti_object, 2, &bad_typeid_cxx_type_info, &exception_cxx_type_info ) +#if _MSVCR_VER >= 80 +typedef exception bad_alloc; +extern const vtable_ptr MSVCRT_bad_alloc_vtable; + +static void bad_alloc_ctor(bad_alloc *this, const char **name) +{ + MSVCRT_exception_ctor(this, name); + this->vtable = &MSVCRT_bad_alloc_vtable; +} + +/* bad_alloc class implementation */ +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_alloc_copy_ctor,8) +bad_alloc * __thiscall MSVCRT_bad_alloc_copy_ctor(bad_alloc * _this, const bad_alloc * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + MSVCRT_exception_copy_ctor(_this, rhs); + _this->vtable = &MSVCRT_bad_alloc_vtable; + return _this; +} + +DEFINE_THISCALL_WRAPPER(MSVCRT_bad_alloc_dtor,4) +void __thiscall MSVCRT_bad_alloc_dtor(bad_alloc * _this) +{ + TRACE("(%p)\n", _this); + MSVCRT_exception_dtor(_this); +} + +__ASM_VTABLE(bad_alloc, + VTABLE_ADD_FUNC(MSVCRT_exception_vector_dtor) + VTABLE_ADD_FUNC(MSVCRT_what_exception)); +DEFINE_RTTI_DATA1( bad_alloc, 0, &exception_rtti_base_descriptor, ".?AVbad_alloc@std@@" ) +DEFINE_EXCEPTION_TYPE_INFO( bad_alloc, 1, &exception_cxx_type_info, NULL ) + +void throw_bad_alloc(const char *str) +{ + bad_alloc e; + bad_alloc_ctor(&e, &str); + _CxxThrowException(&e, &bad_alloc_exception_type); +} +#endif + void msvcrt_init_exception(void *base) { #ifdef __x86_64__ @@ -703,6 +744,7 @@ void msvcrt_init_exception(void *base) init_exception_rtti(base); #if _MSVCR_VER >= 80 init_exception_old_rtti(base); + init_bad_alloc_rtti(base); #endif init_bad_typeid_rtti(base); init_bad_cast_rtti(base); @@ -712,6 +754,9 @@ void msvcrt_init_exception(void *base) init_bad_typeid_cxx(base); init_bad_cast_cxx(base); init___non_rtti_object_cxx(base); +#if _MSVCR_VER >= 80 + init_bad_alloc_cxx(base); +#endif #endif } diff --git a/dlls/msvcrt/heap.c b/dlls/msvcrt/heap.c index 432df86e1a2..bb265bf33d1 100644 --- a/dlls/msvcrt/heap.c +++ b/dlls/msvcrt/heap.c @@ -150,6 +150,9 @@ void* CDECL MSVCRT_operator_new(MSVCRT_size_t size) } while(freed); TRACE("(%ld) out of memory\n", size); +#if _MSVCR_VER >= 80 + throw_bad_alloc("bad allocation"); +#endif return NULL; } diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 6c4e763dada..54cd11af7f2 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -234,7 +234,10 @@ extern unsigned int MSVCRT___lc_codepage; extern int MSVCRT___lc_collate_cp; extern WORD MSVCRT__ctype [257]; -void msvcrt_set_errno(int) DECLSPEC_HIDDEN; +void msvcrt_set_errno(int) DECLSPEC_HIDDEN; +#if _MSVCR_VER >= 80 +void throw_bad_alloc(const char*) DECLSPEC_HIDDEN; +#endif void __cdecl _purecall(void); void __cdecl _amsg_exit(int errnum);