diff --git a/dlls/msvcp90/exception.c b/dlls/msvcp90/exception.c index 4710848be88..69da38ab4d9 100644 --- a/dlls/msvcp90/exception.c +++ b/dlls/msvcp90/exception.c @@ -76,6 +76,9 @@ void CDECL _CxxThrowException(exception*,const cxx_exception_type*); #define __ASM_EXCEPTION_VTABLE(name) \ __ASM_VTABLE(name, "\t.quad " THISCALL_NAME(MSVCP_what_exception) ) +#define __ASM_EXCEPTION_STRING_VTABLE(name) \ + __ASM_VTABLE(name, "\t.quad " THISCALL_NAME(MSVCP_logic_error_what) ) + #else #define __ASM_VTABLE(name,funcs) \ @@ -90,9 +93,13 @@ void CDECL _CxxThrowException(exception*,const cxx_exception_type*); #define __ASM_EXCEPTION_VTABLE(name) \ __ASM_VTABLE(name, "\t.long " THISCALL_NAME(MSVCP_what_exception) ) +#define __ASM_EXCEPTION_STRING_VTABLE(name) \ + __ASM_VTABLE(name, "\t.long " THISCALL_NAME(MSVCP_logic_error_what) ) + #endif /* _WIN64 */ extern const vtable_ptr MSVCP_bad_alloc_vtable; +extern const vtable_ptr MSVCP_logic_error_vtable; /* exception class data */ static type_info exception_type_info = { @@ -295,10 +302,136 @@ static const cxx_exception_type bad_alloc_cxx_type = { &bad_alloc_cxx_type_table }; +/* logic_error class data */ +typedef struct _logic_error { + exception e; + basic_string_char str; +} logic_error; + +DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_ctor, 8) +logic_error* __stdcall MSVCP_logic_error_ctor( + logic_error *this, const char **name) +{ + TRACE("%p %s\n", this, *name); + this->e.vtable = &MSVCP_logic_error_vtable; + this->e.name = NULL; + this->e.do_free = FALSE; + MSVCP_basic_string_char_ctor_cstr(&this->str, *name); + return this; +} + +DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_copy_ctor, 8) +logic_error* __stdcall MSVCP_logic_error_copy_ctor( + logic_error *this, logic_error *rhs) +{ + TRACE("%p %p\n", this, rhs); + MSVCP_exception_copy_ctor(&this->e, &rhs->e); + MSVCP_basic_string_char_copy_ctor(&this->str, &rhs->str); + this->e.vtable = &MSVCP_logic_error_vtable; + return this; +} + +DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_dtor, 4) +void __stdcall MSVCP_logic_error_dtor(logic_error *this) +{ + TRACE("%p\n", this); + MSVCP_exception_dtor(&this->e); + MSVCP_basic_string_char_dtor(&this->str); +} + +DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_vector_dtor, 8) +void* __stdcall MSVCP_logic_error_vector_dtor( + logic_error *this, unsigned int flags) +{ + TRACE("%p %x\n", this, flags); + if(flags & 2) { + /* we have an array, with the number of elements stored before the first object */ + int i, *ptr = (int *)this-1; + + for(i=*ptr-1; i>=0; i--) + MSVCP_logic_error_dtor(this+i); + MSVCRT_operator_delete(ptr); + } else { + MSVCP_logic_error_dtor(this); + if(flags & 1) + MSVCRT_operator_delete(this); + } + + return this; +} + +DEFINE_THISCALL_WRAPPER(MSVCP_logic_error_what, 4) +const char* __stdcall MSVCP_logic_error_what(logic_error *this) +{ + TRACE("%p\n", this); + return MSVCP_basic_string_char_c_str(&this->str); +} + +static const type_info logic_error_type_info = { + &MSVCP_logic_error_vtable, + NULL, + ".?AVlogic_error@std@@" +}; + +static const rtti_base_descriptor logic_error_rtti_base_descriptor = { + &logic_error_type_info, + 1, + { 0, -1, 0 }, + 64 +}; + +static const rtti_base_array logic_error_rtti_base_array = { + { + &logic_error_rtti_base_descriptor, + &exception_rtti_base_descriptor, + NULL + } +}; + +static const rtti_object_hierarchy logic_error_type_hierarchy = { + 0, + 0, + 2, + &logic_error_rtti_base_array +}; + +const rtti_object_locator logic_error_rtti = { + 0, + 0, + 0, + &logic_error_type_info, + &logic_error_type_hierarchy +}; + +static const cxx_type_info logic_error_cxx_type_info = { + 0, + &logic_error_type_info, + { 0, -1, 0 }, + sizeof(logic_error), + (cxx_copy_ctor)THISCALL(MSVCP_logic_error_copy_ctor) +}; + +static const cxx_type_info_table logic_error_cxx_type_table = { + 2, + { + &logic_error_cxx_type_info, + &exception_cxx_type_info, + NULL + } +}; + +static const cxx_exception_type logic_error_cxx_type = { + 0, + (cxx_copy_ctor)THISCALL(MSVCP_logic_error_dtor), + NULL, + &logic_error_cxx_type_table +}; + #ifndef __GNUC__ void __asm_dummy_vtables(void) { #endif __ASM_EXCEPTION_VTABLE(bad_alloc) + __ASM_EXCEPTION_STRING_VTABLE(logic_error) #ifndef __GNUC__ } #endif @@ -319,6 +452,13 @@ void throw_exception(exception_type et, const char *str) bad_alloc e; MSVCP_bad_alloc_ctor(&e, &addr); _CxxThrowException(&e, &bad_alloc_cxx_type); + return; + } + case EXCEPTION_LOGIC_ERROR: { + logic_error e; + MSVCP_logic_error_ctor(&e, &addr); + _CxxThrowException((exception*)&e, &logic_error_cxx_type); + return; } } } diff --git a/dlls/msvcp90/msvcp90.h b/dlls/msvcp90/msvcp90.h index 3470d1b0e48..b2e45bd817a 100644 --- a/dlls/msvcp90/msvcp90.h +++ b/dlls/msvcp90/msvcp90.h @@ -59,7 +59,8 @@ typedef struct __exception /* Internal: throws selected exception */ typedef enum __exception_type { EXCEPTION, - EXCEPTION_BAD_ALLOC + EXCEPTION_BAD_ALLOC, + EXCEPTION_LOGIC_ERROR } exception_type; void throw_exception(exception_type, const char *); void set_exception_vtable(void); @@ -123,5 +124,10 @@ typedef struct _basic_string_char size_t res; } basic_string_char; +basic_string_char* __stdcall MSVCP_basic_string_char_ctor_cstr(basic_string_char*, const char*); +basic_string_char* __stdcall MSVCP_basic_string_char_copy_ctor(basic_string_char*, const basic_string_char*); +void __stdcall MSVCP_basic_string_char_dtor(basic_string_char*); +const char* __stdcall MSVCP_basic_string_char_c_str(basic_string_char*); + char* __stdcall MSVCP_allocator_char_allocate(void*, size_t); void __stdcall MSVCP_allocator_char_deallocate(void*, char*, size_t);