Piotr Caban : msvcp90: Added bad_alloc exception.
Alexandre Julliard
julliard at winehq.org
Wed Aug 18 12:09:56 CDT 2010
Module: wine
Branch: master
Commit: b13e3772d464ca9c85cba48177fab908b16663b8
URL: http://source.winehq.org/git/wine.git/?a=commit;h=b13e3772d464ca9c85cba48177fab908b16663b8
Author: Piotr Caban <piotr at 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 at 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;
More information about the wine-cvs
mailing list