From e29c3066bc0a1a3716baf9e325fa8855f4113c19 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Tue, 3 Jul 2012 16:53:00 +0200 Subject: [PATCH] msvcp60: Keep class definitions in separate file. --- dlls/msvcp60/cxx.h | 224 +++++++++++++++++++++++++++++++++++++++ dlls/msvcp60/exception.c | 18 ++-- dlls/msvcp60/msvcp.h | 189 +-------------------------------- 3 files changed, 237 insertions(+), 194 deletions(-) create mode 100644 dlls/msvcp60/cxx.h diff --git a/dlls/msvcp60/cxx.h b/dlls/msvcp60/cxx.h new file mode 100644 index 00000000000..cc3915cdfa5 --- /dev/null +++ b/dlls/msvcp60/cxx.h @@ -0,0 +1,224 @@ +/* + * Copyright 2012 Piotr Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Copied from dlls/msvcrt/cpp.c */ +#ifdef __i386__ /* thiscall functions are i386-specific */ + +#define THISCALL(func) __thiscall_ ## func +#define THISCALL_NAME(func) __ASM_NAME("__thiscall_" #func) +#define __thiscall __stdcall +#define DEFINE_THISCALL_WRAPPER(func,args) \ + extern void THISCALL(func)(void); \ + __ASM_GLOBAL_FUNC(__thiscall_ ## func, \ + "popl %eax\n\t" \ + "pushl %ecx\n\t" \ + "pushl %eax\n\t" \ + "jmp " __ASM_NAME(#func) __ASM_STDCALL(args) ) +#else /* __i386__ */ + +#define THISCALL(func) func +#define THISCALL_NAME(func) __ASM_NAME(#func) +#define __thiscall __cdecl +#define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */ + +#endif /* __i386__ */ + +#ifdef _WIN64 + +#define VTABLE_ADD_FUNC(name) "\t.quad " THISCALL_NAME(name) "\n" + +#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") + +#else + +#define VTABLE_ADD_FUNC(name) "\t.long " THISCALL_NAME(name) "\n" + +#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") + +#endif /* _WIN64 */ + +#define DEFINE_RTTI_DATA(name, off, base_classes, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name) \ + static const type_info name ## _type_info = { \ + &MSVCP_type_info_vtable, \ + NULL, \ + mangled_name \ + }; \ +\ +static const rtti_base_descriptor name ## _rtti_base_descriptor = { \ + &name ##_type_info, \ + base_classes, \ + { 0, -1, 0}, \ + 64 \ +}; \ +\ +static const rtti_base_array name ## _rtti_base_array = { \ + { \ + &name ## _rtti_base_descriptor, \ + cl1, \ + cl2, \ + cl3, \ + cl4, \ + cl5, \ + cl6, \ + cl7, \ + cl8, \ + cl9, \ + } \ +}; \ +\ +static const rtti_object_hierarchy name ## _hierarchy = { \ + 0, \ + 0, \ + base_classes+1, \ + &name ## _rtti_base_array \ +}; \ +\ +const rtti_object_locator name ## _rtti = { \ + 0, \ + off, \ + 0, \ + &name ## _type_info, \ + &name ## _hierarchy \ +} + +#define DEFINE_RTTI_DATA0(name, off, mangled_name) \ + DEFINE_RTTI_DATA(name, off, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name) +#define DEFINE_RTTI_DATA1(name, off, cl1, mangled_name) \ + DEFINE_RTTI_DATA(name, off, 1, cl1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name) +#define DEFINE_RTTI_DATA2(name, off, cl1, cl2, mangled_name) \ + DEFINE_RTTI_DATA(name, off, 2, cl1, cl2, NULL, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name) +#define DEFINE_RTTI_DATA3(name, off, cl1, cl2, cl3, mangled_name) \ + DEFINE_RTTI_DATA(name, off, 3, cl1, cl2, cl3, NULL, NULL, NULL, NULL, NULL, NULL, mangled_name) +#define DEFINE_RTTI_DATA4(name, off, cl1, cl2, cl3, cl4, mangled_name) \ + DEFINE_RTTI_DATA(name, off, 4, cl1, cl2, cl3, cl4, NULL, NULL, NULL, NULL, NULL, mangled_name) +#define DEFINE_RTTI_DATA8(name, off, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, mangled_name) \ + DEFINE_RTTI_DATA(name, off, 8, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, NULL, mangled_name) +#define DEFINE_RTTI_DATA9(name, off, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name) \ + DEFINE_RTTI_DATA(name, off, 9, cl1, cl2, cl3, cl4, cl5, cl6, cl7, cl8, cl9, mangled_name) + +#ifdef __i386__ + +#define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (WINAPI*)type)&vtbl_wrapper_##off)args + +extern void *vtbl_wrapper_0; +extern void *vtbl_wrapper_4; +extern void *vtbl_wrapper_8; +extern void *vtbl_wrapper_12; +extern void *vtbl_wrapper_16; +extern void *vtbl_wrapper_20; +extern void *vtbl_wrapper_24; +extern void *vtbl_wrapper_28; +extern void *vtbl_wrapper_32; +extern void *vtbl_wrapper_36; +extern void *vtbl_wrapper_40; +extern void *vtbl_wrapper_44; +extern void *vtbl_wrapper_48; +extern void *vtbl_wrapper_52; +extern void *vtbl_wrapper_56; +extern void *vtbl_wrapper_60; + +#else + +#define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (__cdecl***)type)this)[0][off/4]args + +#endif + +/* exception object */ +typedef void (*vtable_ptr)(void); +typedef struct __exception +{ + const vtable_ptr *vtable; + char *name; /* Name of this exception, always a new copy for each object */ + int do_free; /* Whether to free 'name' in our dtor */ +} exception; + +/* Internal: throws selected exception */ +typedef enum __exception_type { + EXCEPTION_RERAISE, + EXCEPTION, + EXCEPTION_BAD_ALLOC, + EXCEPTION_LOGIC_ERROR, + EXCEPTION_LENGTH_ERROR, + EXCEPTION_OUT_OF_RANGE, + EXCEPTION_INVALID_ARGUMENT, + EXCEPTION_RUNTIME_ERROR, + EXCEPTION_FAILURE, +} exception_type; +void throw_exception(exception_type, const char *); + +/* rtti */ +typedef struct __type_info +{ + const vtable_ptr *vtable; + char *name; /* Unmangled name, allocated lazily */ + char mangled[128]; /* Variable length, but we declare it large enough for static RTTI */ +} type_info; + +extern const vtable_ptr MSVCP_type_info_vtable; + +/* 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[10]; /* 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; diff --git a/dlls/msvcp60/exception.c b/dlls/msvcp60/exception.c index 609cb985090..0b464f8c7dd 100644 --- a/dlls/msvcp60/exception.c +++ b/dlls/msvcp60/exception.c @@ -100,7 +100,7 @@ void * __thiscall MSVCP_type_info_vector_dtor(type_info * _this, unsigned int fl return _this; } -DEFINE_RTTI_DATA( type_info, 0, 0, NULL, NULL, NULL, ".?AVtype_info@@" ); +DEFINE_RTTI_DATA0( type_info, 0, ".?AVtype_info@@" ); DEFINE_THISCALL_WRAPPER(MSVCP_exception_ctor, 8) exception* __thiscall MSVCP_exception_ctor(exception *this, const char *name) @@ -164,7 +164,7 @@ void * __thiscall MSVCP_exception_vector_dtor(exception *this, unsigned int flag return this; } -DEFINE_RTTI_DATA(exception, 0, 0, NULL, NULL, NULL, ".?AVexception@std@@"); +DEFINE_RTTI_DATA0(exception, 0, ".?AVexception@std@@"); /* ?_Doraise@bad_alloc@std@@MBEXXZ */ /* ?_Doraise@bad_alloc@std@@MEBAXXZ */ @@ -284,7 +284,7 @@ bad_alloc* __thiscall MSVCP_bad_alloc_assign(bad_alloc *this, const bad_alloc *a return MSVCP_bad_alloc_copy_ctor(this, assign); } -DEFINE_RTTI_DATA(bad_alloc, 0, 1, &exception_rtti_base_descriptor, NULL, NULL, ".?AVbad_alloc@std@@"); +DEFINE_RTTI_DATA1(bad_alloc, 0, &exception_rtti_base_descriptor, ".?AVbad_alloc@std@@"); static const cxx_type_info bad_alloc_cxx_type_info = { 0, @@ -405,7 +405,7 @@ const char* __thiscall MSVCP_logic_error_what(logic_error *this) return MSVCP_basic_string_char_c_str(&this->str); } -DEFINE_RTTI_DATA(logic_error, 0, 1, &exception_rtti_base_descriptor, NULL, NULL, ".?AVlogic_error@std@@"); +DEFINE_RTTI_DATA1(logic_error, 0, &exception_rtti_base_descriptor, ".?AVlogic_error@std@@"); static const cxx_type_info logic_error_cxx_type_info = { 0, @@ -482,7 +482,7 @@ length_error* __thiscall MSVCP_length_error_assign(length_error *this, const len return MSVCP_length_error_copy_ctor(this, assign); } -DEFINE_RTTI_DATA(length_error, 0, 2, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, NULL, ".?AVlength_error@std@@"); +DEFINE_RTTI_DATA2(length_error, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVlength_error@std@@"); static const cxx_type_info length_error_cxx_type_info = { 0, @@ -559,7 +559,7 @@ out_of_range* __thiscall MSVCP_out_of_range_assign(out_of_range *this, const out return MSVCP_out_of_range_copy_ctor(this, assign); } -DEFINE_RTTI_DATA(out_of_range, 0, 2, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, NULL, ".?AVout_of_range@std@@"); +DEFINE_RTTI_DATA2(out_of_range, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVout_of_range@std@@"); static const cxx_type_info out_of_range_cxx_type_info = { 0, @@ -616,7 +616,7 @@ void* __thiscall MSVCP_invalid_argument_vector_dtor( return MSVCP_logic_error_vector_dtor(this, flags); } -DEFINE_RTTI_DATA(invalid_argument, 0, 2, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, NULL, ".?AVinvalid_argument@std@@"); +DEFINE_RTTI_DATA2(invalid_argument, 0, &logic_error_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AVinvalid_argument@std@@"); static const cxx_type_info invalid_argument_cxx_type_info = { 0, @@ -693,7 +693,7 @@ runtime_error* __thiscall MSVCP_runtime_error_assign(runtime_error *this, const return MSVCP_runtime_error_copy_ctor(this, assign); } -DEFINE_RTTI_DATA(runtime_error, 0, 1, &exception_rtti_base_descriptor, NULL, NULL, ".?AVruntime_error@std@@"); +DEFINE_RTTI_DATA1(runtime_error, 0, &exception_rtti_base_descriptor, ".?AVruntime_error@std@@"); static const cxx_type_info runtime_error_cxx_type_info = { 0, @@ -796,5 +796,7 @@ void throw_exception(exception_type et, const char *str) MSVCP_runtime_error_ctor(&e, str); _CxxThrowException((exception*)&e, &runtime_error_cxx_type); } + default: + ERR("exception type not handled: %d\n", et); } } diff --git a/dlls/msvcp60/msvcp.h b/dlls/msvcp60/msvcp.h index 7a4c041421e..7e1c47a02aa 100644 --- a/dlls/msvcp60/msvcp.h +++ b/dlls/msvcp60/msvcp.h @@ -18,6 +18,7 @@ #include "stdlib.h" #include "windef.h" +#include "cxx.h" typedef unsigned char MSVCP_bool; typedef SIZE_T MSVCP_size_t; @@ -31,191 +32,8 @@ extern void* (__cdecl *MSVCRT_operator_new)(MSVCP_size_t); extern void (__cdecl *MSVCRT_operator_delete)(void*); extern void* (__cdecl *MSVCRT_set_new_handler)(void*); -/* Copied from dlls/msvcrt/cpp.c */ -#ifdef __i386__ /* thiscall functions are i386-specific */ - -#define THISCALL(func) __thiscall_ ## func -#define THISCALL_NAME(func) __ASM_NAME("__thiscall_" #func) -#define __thiscall __stdcall -#define DEFINE_THISCALL_WRAPPER(func,args) \ - extern void THISCALL(func)(void); \ - __ASM_GLOBAL_FUNC(__thiscall_ ## func, \ - "popl %eax\n\t" \ - "pushl %ecx\n\t" \ - "pushl %eax\n\t" \ - "jmp " __ASM_NAME(#func) __ASM_STDCALL(args) ) -#else /* __i386__ */ - -#define THISCALL(func) func -#define THISCALL_NAME(func) __ASM_NAME(#func) -#define __thiscall __cdecl -#define DEFINE_THISCALL_WRAPPER(func,args) /* nothing */ - -#endif /* __i386__ */ - -#ifdef _WIN64 - -#define VTABLE_ADD_FUNC(name) "\t.quad " THISCALL_NAME(name) "\n" - -#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") - -#else - -#define VTABLE_ADD_FUNC(name) "\t.long " THISCALL_NAME(name) "\n" - -#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") - -#endif /* _WIN64 */ - -#define DEFINE_RTTI_DATA(name, off, base_classes, cl1, cl2, cl3, mangled_name) \ -static const type_info name ## _type_info = { \ - &MSVCP_type_info_vtable, \ - NULL, \ - mangled_name \ -}; \ -\ -static const rtti_base_descriptor name ## _rtti_base_descriptor = { \ - &name ##_type_info, \ - base_classes, \ - { 0, -1, 0}, \ - 64 \ -}; \ -\ -static const rtti_base_array name ## _rtti_base_array = { \ - { \ - &name ## _rtti_base_descriptor, \ - cl1, \ - cl2, \ - cl3 \ - } \ -}; \ -\ -static const rtti_object_hierarchy name ## _hierarchy = { \ - 0, \ - 0, \ - base_classes+1, \ - &name ## _rtti_base_array \ -}; \ -\ -const rtti_object_locator name ## _rtti = { \ - 0, \ - off, \ - 0, \ - &name ## _type_info, \ - &name ## _hierarchy \ -} - -#ifdef __i386__ - -#define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (WINAPI*)type)&vtbl_wrapper_##off)args - -extern void *vtbl_wrapper_0; -extern void *vtbl_wrapper_4; -extern void *vtbl_wrapper_8; -extern void *vtbl_wrapper_12; -extern void *vtbl_wrapper_16; -extern void *vtbl_wrapper_20; -extern void *vtbl_wrapper_24; -extern void *vtbl_wrapper_28; -extern void *vtbl_wrapper_32; -extern void *vtbl_wrapper_36; -extern void *vtbl_wrapper_40; -extern void *vtbl_wrapper_44; -extern void *vtbl_wrapper_48; -extern void *vtbl_wrapper_52; -extern void *vtbl_wrapper_56; -extern void *vtbl_wrapper_60; - -#else - -#define CALL_VTBL_FUNC(this, off, ret, type, args) ((ret (__cdecl***)type)this)[0][off/4]args - -#endif - -/* exception object */ -typedef void (*vtable_ptr)(void); -typedef struct __exception -{ - const vtable_ptr *vtable; - char *name; /* Name of this exception, always a new copy for each object */ - int do_free; /* Whether to free 'name' in our dtor */ -} exception; - -/* Internal: throws selected exception */ -typedef enum __exception_type { - EXCEPTION, - EXCEPTION_BAD_ALLOC, - EXCEPTION_LOGIC_ERROR, - EXCEPTION_LENGTH_ERROR, - EXCEPTION_OUT_OF_RANGE, - EXCEPTION_INVALID_ARGUMENT, - EXCEPTION_RUNTIME_ERROR -} exception_type; -void throw_exception(exception_type, const char *); - -/* rtti */ -typedef struct __type_info -{ - const vtable_ptr *vtable; - char *name; /* Unmangled name, allocated lazily */ - char mangled[64]; /* 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[4]; /* 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; - /* basic_string, allocator> */ -#define BUF_SIZE_CHAR 16 -typedef struct _basic_string_char +typedef struct { void *allocator; char *ptr; @@ -228,8 +46,7 @@ basic_string_char* __stdcall MSVCP_basic_string_char_copy_ctor(basic_string_char void __stdcall MSVCP_basic_string_char_dtor(basic_string_char*); const char* __stdcall MSVCP_basic_string_char_c_str(const basic_string_char*); -#define BUF_SIZE_WCHAR 8 -typedef struct _basic_string_wchar +typedef struct { void *allocator; wchar_t *ptr;