Module: wine Branch: master Commit: b13e3772d464ca9c85cba48177fab908b16663b8 URL: http://source.winehq.org/git/wine.git/?a=commit;h=b13e3772d464ca9c85cba48177...
Author: Piotr Caban piotr@codeweavers.com Date: Wed Aug 18 10:36:52 2010 +0200
msvcp90: Added bad_alloc exception.
---
dlls/msvcp90/exception.c | 184 ++++++++++++++++++++++++++++++++++++++++++---- dlls/msvcp90/msvcp90.h | 51 +++++++++++++- 2 files changed, 219 insertions(+), 16 deletions(-)
diff --git a/dlls/msvcp90/exception.c b/dlls/msvcp90/exception.c index 1988be2..4710848 100644 --- a/dlls/msvcp90/exception.c +++ b/dlls/msvcp90/exception.c @@ -28,23 +28,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcp90);
/* dlls/msvcrt/cppexcept.h */ -typedef struct __type_info -{ - const vtable_ptr *vtable; - char *name; /* Unmangled name, allocated lazily */ - char mangled[32]; /* Variable length, but we declare it large enough for static RTTI */ -} type_info; - typedef void (*cxx_copy_ctor)(void);
-/* offsets for computing the this pointer */ -typedef struct -{ - int this_offset; /* offset of base class this pointer from start of object */ - int vbase_descr; /* offset of virtual base class descriptor */ - int vbase_offset; /* offset of this pointer offset in virtual base class descriptor */ -} this_ptr_offsets; - /* complete information about a C++ type */ typedef struct __cxx_type_info { @@ -75,6 +60,40 @@ typedef struct __cxx_exception_type
void CDECL _CxxThrowException(exception*,const cxx_exception_type*);
+/* vtables */ + +#ifdef _WIN64 + +#define __ASM_VTABLE(name,funcs) \ + __asm__(".data\n" \ + "\t.align 8\n" \ + "\t.quad " __ASM_NAME(#name "_rtti") "\n" \ + "\t.globl " __ASM_NAME("MSVCP_" #name "_vtable") "\n" \ + __ASM_NAME("MSVCP_" #name "_vtable") ":\n" \ + "\t.quad " THISCALL_NAME(MSVCP_ ## name ## _vector_dtor) "\n" \ + funcs "\n\t.text"); + +#define __ASM_EXCEPTION_VTABLE(name) \ + __ASM_VTABLE(name, "\t.quad " THISCALL_NAME(MSVCP_what_exception) ) + +#else + +#define __ASM_VTABLE(name,funcs) \ + __asm__(".data\n" \ + "\t.align 4\n" \ + "\t.long " __ASM_NAME(#name "_rtti") "\n" \ + "\t.globl " __ASM_NAME("MSVCP_" #name "_vtable") "\n" \ + __ASM_NAME("MSVCP_" #name "_vtable") ":\n" \ + "\t.long " THISCALL_NAME(MSVCP_ ## name ## _vector_dtor) "\n" \ + funcs "\n\t.text"); + +#define __ASM_EXCEPTION_VTABLE(name) \ + __ASM_VTABLE(name, "\t.long " THISCALL_NAME(MSVCP_what_exception) ) + +#endif /* _WIN64 */ + +extern const vtable_ptr MSVCP_bad_alloc_vtable; + /* exception class data */ static type_info exception_type_info = { NULL, /* set by set_exception_vtable */ @@ -124,6 +143,13 @@ void __stdcall MSVCP_exception_dtor(exception *this) free(this->name); }
+static const rtti_base_descriptor exception_rtti_base_descriptor = { + &exception_type_info, + 0, + { 0, -1, 0 }, + 0 +}; + static const cxx_type_info exception_cxx_type_info = { 0, &exception_type_info, @@ -154,6 +180,129 @@ void set_exception_vtable(void) exception_type_info.vtable = (void*)GetProcAddress(hmod, "??_7exception@@6B@"); }
+/* bad_alloc class data */ +typedef exception bad_alloc; + +DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_ctor, 8) +bad_alloc* __stdcall MSVCP_bad_alloc_ctor(bad_alloc *this, const char **name) +{ + TRACE("%p %s\n", this, *name); + MSVCP_exception_ctor(this, name); + this->vtable = &MSVCP_bad_alloc_vtable; + return this; +} + +DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_copy_ctor, 8) +bad_alloc* __stdcall MSVCP_bad_alloc_copy_ctor(bad_alloc *this, const bad_alloc *rhs) +{ + TRACE("%p %p\n", this, rhs); + MSVCP_exception_copy_ctor(this, rhs); + this->vtable = &MSVCP_bad_alloc_vtable; + return this; +} + +DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_dtor, 4) +void __stdcall MSVCP_bad_alloc_dtor(bad_alloc *this) +{ + TRACE("%p\n", this); + MSVCP_exception_dtor(this); +} + +DEFINE_THISCALL_WRAPPER(MSVCP_bad_alloc_vector_dtor, 8) +void * __stdcall MSVCP_bad_alloc_vector_dtor(bad_alloc *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_bad_alloc_dtor(this+i); + MSVCRT_operator_delete(ptr); + } else { + MSVCP_bad_alloc_dtor(this); + if(flags & 1) + MSVCRT_operator_delete(this); + } + + return this; +} + +DEFINE_THISCALL_WRAPPER(MSVCP_what_exception,4) +const char* __stdcall MSVCP_what_exception(exception * this) +{ + TRACE("(%p) returning %s\n", this, this->name); + return this->name ? this->name : "Unknown exception"; +} + +static const type_info bad_alloc_type_info = { + &MSVCP_bad_alloc_vtable, + NULL, + ".?AVbad_alloc@std@@" +}; + +static const rtti_base_descriptor bad_alloc_rtti_base_descriptor = { + &bad_alloc_type_info, + 1, + { 0, -1, 0 }, + 64 +}; + +static const rtti_base_array bad_alloc_rtti_base_array = { + { + &bad_alloc_rtti_base_descriptor, + &exception_rtti_base_descriptor, + NULL + } +}; + +static const rtti_object_hierarchy bad_alloc_type_hierarchy = { + 0, + 0, + 2, + &bad_alloc_rtti_base_array +}; + +const rtti_object_locator bad_alloc_rtti = { + 0, + 0, + 0, + &bad_alloc_type_info, + &bad_alloc_type_hierarchy +}; + +static const cxx_type_info bad_alloc_cxx_type_info = { + 0, + &bad_alloc_type_info, + { 0, -1, 0 }, + sizeof(bad_alloc), + (cxx_copy_ctor)THISCALL(MSVCP_bad_alloc_copy_ctor) +}; + +static const cxx_type_info_table bad_alloc_cxx_type_table = { + 2, + { + &bad_alloc_cxx_type_info, + &exception_cxx_type_info, + NULL + } +}; + +static const cxx_exception_type bad_alloc_cxx_type = { + 0, + (cxx_copy_ctor)THISCALL(MSVCP_bad_alloc_dtor), + NULL, + &bad_alloc_cxx_type_table +}; + +#ifndef __GNUC__ +void __asm_dummy_vtables(void) { +#endif + __ASM_EXCEPTION_VTABLE(bad_alloc) +#ifndef __GNUC__ +} +#endif + /* Internal: throws selected exception */ void throw_exception(exception_type et, const char *str) { @@ -166,5 +315,10 @@ void throw_exception(exception_type et, const char *str) _CxxThrowException(&e, &exception_cxx_type); return; } + case EXCEPTION_BAD_ALLOC: { + bad_alloc e; + MSVCP_bad_alloc_ctor(&e, &addr); + _CxxThrowException(&e, &bad_alloc_cxx_type); + } } } diff --git a/dlls/msvcp90/msvcp90.h b/dlls/msvcp90/msvcp90.h index f27958b..8d588ef 100644 --- a/dlls/msvcp90/msvcp90.h +++ b/dlls/msvcp90/msvcp90.h @@ -31,6 +31,7 @@ extern void (__cdecl *MSVCRT_operator_delete)(void*); #ifdef __i386__ /* thiscall functions are i386-specific */
#define THISCALL(func) __thiscall_ ## func +#define THISCALL_NAME(func) __ASM_NAME("__thiscall_" #func) #define DEFINE_THISCALL_WRAPPER(func,args) \ extern void THISCALL(func)(void); \ __ASM_GLOBAL_FUNC(__thiscall_ ## func, \ @@ -41,6 +42,7 @@ extern void (__cdecl *MSVCRT_operator_delete)(void*); #else /* __i386__ */
#define THISCALL(func) func +#define THISCALL_NAME(func) __ASM_NAME(#func) #define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */
#endif /* __i386__ */ @@ -56,7 +58,54 @@ typedef struct __exception
/* Internal: throws selected exception */ typedef enum __exception_type { - EXCEPTION + EXCEPTION, + EXCEPTION_BAD_ALLOC } exception_type; void throw_exception(exception_type, const char *); void set_exception_vtable(void); + +/* rtti */ +typedef struct __type_info +{ + const vtable_ptr *vtable; + char *name; /* Unmangled name, allocated lazily */ + char mangled[32]; /* Variable length, but we declare it large enough for static RTTI */ +} type_info; + +/* offsets for computing the this pointer */ +typedef struct +{ + int this_offset; /* offset of base class this pointer from start of object */ + int vbase_descr; /* offset of virtual base class descriptor */ + int vbase_offset; /* offset of this pointer offset in virtual base class descriptor */ +} this_ptr_offsets; + +typedef struct _rtti_base_descriptor +{ + const type_info *type_descriptor; + int num_base_classes; + this_ptr_offsets offsets; /* offsets for computing the this pointer */ + unsigned int attributes; +} rtti_base_descriptor; + +typedef struct _rtti_base_array +{ + const rtti_base_descriptor *bases[3]; /* First element is the class itself */ +} rtti_base_array; + +typedef struct _rtti_object_hierarchy +{ + unsigned int signature; + unsigned int attributes; + int array_len; /* Size of the array pointed to by 'base_classes' */ + const rtti_base_array *base_classes; +} rtti_object_hierarchy; + +typedef struct _rtti_object_locator +{ + unsigned int signature; + int base_class_offset; + unsigned int flags; + const type_info *type_descriptor; + const rtti_object_hierarchy *type_hierarchy; +} rtti_object_locator;