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