- Based on !463 - _RunAndWait and exception handling implemented in later commits
@piotr
-- v3: msvcr100: Implement _StructuredTaskCollection::_Schedule and _Schedule_loc. msvcr100: Make ExternalContextBase reference-counted. msvcr100: Factor out the mapping of a context to a scheduler. msvcr100: Factor out EXCEPTION_RECORD to exception_ptr conversion. msvcr100: Move exception_ptr functions to a separate file. msvcr100: Implement invalid_multiple_scheduling exception. msvcr100: Make all exception ctors with a string parameter trace the string.
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/msvcrt/concurrency.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/dlls/msvcrt/concurrency.c b/dlls/msvcrt/concurrency.c index c982e367749..e57aef34d2b 100644 --- a/dlls/msvcrt/concurrency.c +++ b/dlls/msvcrt/concurrency.c @@ -378,7 +378,7 @@ static void create_default_scheduler(void); DEFINE_THISCALL_WRAPPER(improper_lock_ctor_str, 8) improper_lock* __thiscall improper_lock_ctor_str(improper_lock *this, const char *str) { - TRACE("(%p %p)\n", this, str); + TRACE("(%p %s)\n", this, str); return __exception_ctor(this, str, &improper_lock_vtable); }
@@ -403,7 +403,7 @@ DEFINE_THISCALL_WRAPPER(improper_scheduler_attach_ctor_str, 8) improper_scheduler_attach* __thiscall improper_scheduler_attach_ctor_str( improper_scheduler_attach *this, const char *str) { - TRACE("(%p %p)\n", this, str); + TRACE("(%p %s)\n", this, str); return __exception_ctor(this, str, &improper_scheduler_attach_vtable); }
@@ -430,7 +430,7 @@ DEFINE_THISCALL_WRAPPER(improper_scheduler_detach_ctor_str, 8) improper_scheduler_detach* __thiscall improper_scheduler_detach_ctor_str( improper_scheduler_detach *this, const char *str) { - TRACE("(%p %p)\n", this, str); + TRACE("(%p %s)\n", this, str); return __exception_ctor(this, str, &improper_scheduler_detach_vtable); }
@@ -457,7 +457,7 @@ DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_key_ctor_str, 8) invalid_scheduler_policy_key* __thiscall invalid_scheduler_policy_key_ctor_str( invalid_scheduler_policy_key *this, const char *str) { - TRACE("(%p %p)\n", this, str); + TRACE("(%p %s)\n", this, str); return __exception_ctor(this, str, &invalid_scheduler_policy_key_vtable); }
@@ -484,7 +484,7 @@ DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_thread_specification_ctor_str, invalid_scheduler_policy_thread_specification* __thiscall invalid_scheduler_policy_thread_specification_ctor_str( invalid_scheduler_policy_thread_specification *this, const char *str) { - TRACE("(%p %p)\n", this, str); + TRACE("(%p %s)\n", this, str); return __exception_ctor(this, str, &invalid_scheduler_policy_thread_specification_vtable); }
@@ -511,7 +511,7 @@ DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_value_ctor_str, 8) invalid_scheduler_policy_value* __thiscall invalid_scheduler_policy_value_ctor_str( invalid_scheduler_policy_value *this, const char *str) { - TRACE("(%p %p)\n", this, str); + TRACE("(%p %s)\n", this, str); return __exception_ctor(this, str, &invalid_scheduler_policy_value_vtable); }
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/concrt140/concrt140.spec | 12 ++++----- dlls/msvcr100/msvcr100.spec | 8 +++--- dlls/msvcr110/msvcr110.spec | 12 ++++----- dlls/msvcr120/msvcr120.spec | 12 ++++----- dlls/msvcr120_app/msvcr120_app.spec | 12 ++++----- dlls/msvcrt/concurrency.c | 38 +++++++++++++++++++++++++++++ 6 files changed, 66 insertions(+), 28 deletions(-)
diff --git a/dlls/concrt140/concrt140.spec b/dlls/concrt140/concrt140.spec index 9370566bb2c..64da684f415 100644 --- a/dlls/concrt140/concrt140.spec +++ b/dlls/concrt140/concrt140.spec @@ -144,12 +144,12 @@ @ stub -arch=arm ??0invalid_link_target@Concurrency@@QAA@XZ @ stub -arch=i386 ??0invalid_link_target@Concurrency@@QAE@XZ @ stub -arch=win64 ??0invalid_link_target@Concurrency@@QEAA@XZ -@ stub -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@PBD@Z -@ stub -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@PBD@Z -@ stub -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@PEBD@Z -@ stub -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@XZ -@ stub -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@XZ -@ stub -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@XZ +@ cdecl -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@PBD@Z(ptr ptr) invalid_multiple_scheduling_ctor_str +@ thiscall -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@PBD@Z(ptr ptr) invalid_multiple_scheduling_ctor_str +@ cdecl -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@PEBD@Z(ptr ptr) invalid_multiple_scheduling_ctor_str +@ cdecl -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@XZ(ptr) invalid_multiple_scheduling_ctor +@ thiscall -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@XZ(ptr) invalid_multiple_scheduling_ctor +@ cdecl -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@XZ(ptr) invalid_multiple_scheduling_ctor @ stub -arch=arm ??0invalid_oversubscribe_operation@Concurrency@@QAA@PBD@Z @ stub -arch=i386 ??0invalid_oversubscribe_operation@Concurrency@@QAE@PBD@Z @ stub -arch=win64 ??0invalid_oversubscribe_operation@Concurrency@@QEAA@PEBD@Z diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 0d38005c13a..c0bbbc5b86d 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -94,10 +94,10 @@ @ stub -arch=win64 ??0invalid_link_target@Concurrency@@QEAA@PEBD@Z @ stub -arch=win32 ??0invalid_link_target@Concurrency@@QAE@XZ @ stub -arch=win64 ??0invalid_link_target@Concurrency@@QEAA@XZ -@ stub -arch=win32 ??0invalid_multiple_scheduling@Concurrency@@QAE@PBD@Z -@ stub -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@PEBD@Z -@ stub -arch=win32 ??0invalid_multiple_scheduling@Concurrency@@QAE@XZ -@ stub -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@XZ +@ thiscall -arch=win32 ??0invalid_multiple_scheduling@Concurrency@@QAE@PBD@Z(ptr ptr) invalid_multiple_scheduling_ctor_str +@ cdecl -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@PEBD@Z(ptr ptr) invalid_multiple_scheduling_ctor_str +@ thiscall -arch=win32 ??0invalid_multiple_scheduling@Concurrency@@QAE@XZ(ptr) invalid_multiple_scheduling_ctor +@ cdecl -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@XZ(ptr) invalid_multiple_scheduling_ctor @ stub -arch=win32 ??0invalid_operation@Concurrency@@QAE@PBD@Z @ stub -arch=win64 ??0invalid_operation@Concurrency@@QEAA@PEBD@Z @ stub -arch=win32 ??0invalid_operation@Concurrency@@QAE@XZ diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index 24e7630194c..a272ae98a1c 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -167,12 +167,12 @@ @ stub -arch=arm ??0invalid_link_target@Concurrency@@QAA@XZ @ stub -arch=i386 ??0invalid_link_target@Concurrency@@QAE@XZ @ stub -arch=win64 ??0invalid_link_target@Concurrency@@QEAA@XZ -@ stub -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@PBD@Z -@ stub -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@PBD@Z -@ stub -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@PEBD@Z -@ stub -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@XZ -@ stub -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@XZ -@ stub -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@XZ +@ cdecl -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@PBD@Z(ptr ptr) invalid_multiple_scheduling_ctor_str +@ thiscall -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@PBD@Z(ptr ptr) invalid_multiple_scheduling_ctor_str +@ cdecl -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@PEBD@Z(ptr ptr) invalid_multiple_scheduling_ctor_str +@ cdecl -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@XZ(ptr) invalid_multiple_scheduling_ctor +@ thiscall -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@XZ(ptr) invalid_multiple_scheduling_ctor +@ cdecl -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@XZ(ptr) invalid_multiple_scheduling_ctor @ stub -arch=arm ??0invalid_operation@Concurrency@@QAA@PBD@Z @ stub -arch=i386 ??0invalid_operation@Concurrency@@QAE@PBD@Z @ stub -arch=win64 ??0invalid_operation@Concurrency@@QEAA@PEBD@Z diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index b1258dad5de..d16316e7e05 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -164,12 +164,12 @@ @ stub -arch=arm ??0invalid_link_target@Concurrency@@QAA@XZ @ stub -arch=i386 ??0invalid_link_target@Concurrency@@QAE@XZ @ stub -arch=win64 ??0invalid_link_target@Concurrency@@QEAA@XZ -@ stub -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@PBD@Z -@ stub -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@PBD@Z -@ stub -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@PEBD@Z -@ stub -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@XZ -@ stub -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@XZ -@ stub -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@XZ +@ cdecl -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@PBD@Z(ptr ptr) invalid_multiple_scheduling_ctor_str +@ thiscall -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@PBD@Z(ptr ptr) invalid_multiple_scheduling_ctor_str +@ cdecl -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@PEBD@Z(ptr ptr) invalid_multiple_scheduling_ctor_str +@ cdecl -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@XZ(ptr) invalid_multiple_scheduling_ctor +@ thiscall -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@XZ(ptr) invalid_multiple_scheduling_ctor +@ cdecl -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@XZ(ptr) invalid_multiple_scheduling_ctor @ stub -arch=arm ??0invalid_operation@Concurrency@@QAA@PBD@Z @ stub -arch=i386 ??0invalid_operation@Concurrency@@QAE@PBD@Z @ stub -arch=win64 ??0invalid_operation@Concurrency@@QEAA@PEBD@Z diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec index 93ce779ea69..aa5d8ccf968 100644 --- a/dlls/msvcr120_app/msvcr120_app.spec +++ b/dlls/msvcr120_app/msvcr120_app.spec @@ -162,12 +162,12 @@ @ stub -arch=arm ??0invalid_link_target@Concurrency@@QAA@XZ @ stub -arch=i386 ??0invalid_link_target@Concurrency@@QAE@XZ @ stub -arch=win64 ??0invalid_link_target@Concurrency@@QEAA@XZ -@ stub -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@PBD@Z -@ stub -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@PBD@Z -@ stub -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@PEBD@Z -@ stub -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@XZ -@ stub -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@XZ -@ stub -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@XZ +@ cdecl -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@PBD@Z(ptr ptr) msvcr120.??0invalid_multiple_scheduling@Concurrency@@QAA@PBD@Z +@ thiscall -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@PBD@Z(ptr ptr) msvcr120.??0invalid_multiple_scheduling@Concurrency@@QAE@PBD@Z +@ cdecl -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@PEBD@Z(ptr ptr) msvcr120.??0invalid_multiple_scheduling@Concurrency@@QEAA@PEBD@Z +@ cdecl -arch=arm ??0invalid_multiple_scheduling@Concurrency@@QAA@XZ(ptr) msvcr120.??0invalid_multiple_scheduling@Concurrency@@QAA@XZ +@ thiscall -arch=i386 ??0invalid_multiple_scheduling@Concurrency@@QAE@XZ(ptr) msvcr120.??0invalid_multiple_scheduling@Concurrency@@QAE@XZ +@ cdecl -arch=win64 ??0invalid_multiple_scheduling@Concurrency@@QEAA@XZ(ptr) msvcr120.??0invalid_multiple_scheduling@Concurrency@@QEAA@XZ @ stub -arch=arm ??0invalid_operation@Concurrency@@QAA@PBD@Z @ stub -arch=i386 ??0invalid_operation@Concurrency@@QAE@PBD@Z @ stub -arch=win64 ??0invalid_operation@Concurrency@@QEAA@PEBD@Z diff --git a/dlls/msvcrt/concurrency.c b/dlls/msvcrt/concurrency.c index e57aef34d2b..d0c9924c631 100644 --- a/dlls/msvcrt/concurrency.c +++ b/dlls/msvcrt/concurrency.c @@ -329,6 +329,9 @@ extern const vtable_ptr improper_scheduler_attach_vtable; typedef exception improper_scheduler_detach; extern const vtable_ptr improper_scheduler_detach_vtable;
+typedef exception invalid_multiple_scheduling; +extern const vtable_ptr invalid_multiple_scheduling_vtable; + typedef exception invalid_scheduler_policy_key; extern const vtable_ptr invalid_scheduler_policy_key_vtable;
@@ -451,6 +454,35 @@ improper_scheduler_detach * __thiscall improper_scheduler_detach_copy_ctor( return __exception_copy_ctor(_this, rhs, &improper_scheduler_detach_vtable); }
+/* ??0invalid_multiple_scheduling@Concurrency@@QAA@PBD@Z */ +/* ??0invalid_multiple_scheduling@Concurrency@@QAE@PBD@Z */ +/* ??0invalid_multiple_scheduling@Concurrency@@QEAA@PEBD@Z */ +DEFINE_THISCALL_WRAPPER(invalid_multiple_scheduling_ctor_str, 8) +invalid_multiple_scheduling* __thiscall invalid_multiple_scheduling_ctor_str( + invalid_multiple_scheduling *this, const char *str) +{ + TRACE("(%p %s)\n", this, str); + return __exception_ctor(this, str, &invalid_multiple_scheduling_vtable); +} + +/* ??0invalid_multiple_scheduling@Concurrency@@QAA@XZ */ +/* ??0invalid_multiple_scheduling@Concurrency@@QAE@XZ */ +/* ??0invalid_multiple_scheduling@Concurrency@@QEAA@XZ */ +DEFINE_THISCALL_WRAPPER(invalid_multiple_scheduling_ctor, 4) +invalid_multiple_scheduling* __thiscall invalid_multiple_scheduling_ctor( + invalid_multiple_scheduling *this) +{ + return invalid_multiple_scheduling_ctor_str(this, NULL); +} + +DEFINE_THISCALL_WRAPPER(invalid_multiple_scheduling_copy_ctor,8) +invalid_multiple_scheduling * __thiscall invalid_multiple_scheduling_copy_ctor( + invalid_multiple_scheduling * _this, const invalid_multiple_scheduling * rhs) +{ + TRACE("(%p %p)\n", _this, rhs); + return __exception_copy_ctor(_this, rhs, &invalid_multiple_scheduling_vtable); +} + /* ??0invalid_scheduler_policy_key@Concurrency@@QAE@PBD@Z */ /* ??0invalid_scheduler_policy_key@Concurrency@@QEAA@PEBD@Z */ DEFINE_THISCALL_WRAPPER(invalid_scheduler_policy_key_ctor_str, 8) @@ -583,6 +615,8 @@ DEFINE_RTTI_DATA1(improper_scheduler_attach, 0, &cexception_rtti_base_descriptor ".?AVimproper_scheduler_attach@Concurrency@@") DEFINE_RTTI_DATA1(improper_scheduler_detach, 0, &cexception_rtti_base_descriptor, ".?AVimproper_scheduler_detach@Concurrency@@") +DEFINE_RTTI_DATA1(invalid_multiple_scheduling, 0, &cexception_rtti_base_descriptor, + ".?AVinvalid_multiple_scheduling@Concurrency@@") DEFINE_RTTI_DATA1(invalid_scheduler_policy_key, 0, &cexception_rtti_base_descriptor, ".?AVinvalid_scheduler_policy_key@Concurrency@@") DEFINE_RTTI_DATA1(invalid_scheduler_policy_thread_specification, 0, &cexception_rtti_base_descriptor, @@ -610,6 +644,9 @@ __ASM_BLOCK_BEGIN(concurrency_exception_vtables) __ASM_VTABLE(improper_scheduler_detach, VTABLE_ADD_FUNC(cexception_vector_dtor) VTABLE_ADD_FUNC(cexception_what)); + __ASM_VTABLE(invalid_multiple_scheduling, + VTABLE_ADD_FUNC(cexception_vector_dtor) + VTABLE_ADD_FUNC(cexception_what)); __ASM_VTABLE(invalid_scheduler_policy_key, VTABLE_ADD_FUNC(cexception_vector_dtor) VTABLE_ADD_FUNC(cexception_what)); @@ -3042,6 +3079,7 @@ void msvcrt_init_concurrency(void *base) init_improper_lock_rtti(base); init_improper_scheduler_attach_rtti(base); init_improper_scheduler_detach_rtti(base); + init_invalid_multiple_scheduling_rtti(base); init_invalid_scheduler_policy_key_rtti(base); init_invalid_scheduler_policy_thread_specification_rtti(base); init_invalid_scheduler_policy_value_rtti(base);
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/crtdll/Makefile.in | 1 + dlls/msvcr100/Makefile.in | 1 + dlls/msvcr110/Makefile.in | 1 + dlls/msvcr120/Makefile.in | 1 + dlls/msvcrt/Makefile.in | 1 + dlls/msvcrt/cpp.c | 344 +---------------------------------- dlls/msvcrt/cxx.h | 6 + dlls/msvcrt/exception_ptr.c | 346 ++++++++++++++++++++++++++++++++++++ dlls/msvcrt/main.c | 1 + dlls/msvcrt/msvcrt.h | 1 + dlls/msvcrtd/Makefile.in | 1 + dlls/ucrtbase/Makefile.in | 1 + 12 files changed, 364 insertions(+), 341 deletions(-) create mode 100644 dlls/msvcrt/exception_ptr.c
diff --git a/dlls/crtdll/Makefile.in b/dlls/crtdll/Makefile.in index ffdbb2ab7a1..d54e8d49964 100644 --- a/dlls/crtdll/Makefile.in +++ b/dlls/crtdll/Makefile.in @@ -17,6 +17,7 @@ C_SRCS = \ except_arm64.c \ except_i386.c \ except_x86_64.c \ + exception_ptr.c \ exit.c \ file.c \ heap.c \ diff --git a/dlls/msvcr100/Makefile.in b/dlls/msvcr100/Makefile.in index a48ae314257..d17aa79b3d7 100644 --- a/dlls/msvcr100/Makefile.in +++ b/dlls/msvcr100/Makefile.in @@ -19,6 +19,7 @@ C_SRCS = \ except_arm64.c \ except_i386.c \ except_x86_64.c \ + exception_ptr.c \ exit.c \ file.c \ heap.c \ diff --git a/dlls/msvcr110/Makefile.in b/dlls/msvcr110/Makefile.in index 26db1d46f7a..0bc15e27d94 100644 --- a/dlls/msvcr110/Makefile.in +++ b/dlls/msvcr110/Makefile.in @@ -19,6 +19,7 @@ C_SRCS = \ except_arm64.c \ except_i386.c \ except_x86_64.c \ + exception_ptr.c \ exit.c \ file.c \ heap.c \ diff --git a/dlls/msvcr120/Makefile.in b/dlls/msvcr120/Makefile.in index d2957c2f1d3..cc3d5b2bdff 100644 --- a/dlls/msvcr120/Makefile.in +++ b/dlls/msvcr120/Makefile.in @@ -19,6 +19,7 @@ C_SRCS = \ except_arm64.c \ except_i386.c \ except_x86_64.c \ + exception_ptr.c \ exit.c \ file.c \ heap.c \ diff --git a/dlls/msvcrt/Makefile.in b/dlls/msvcrt/Makefile.in index e8a510d9937..8cd0c4ea7f4 100644 --- a/dlls/msvcrt/Makefile.in +++ b/dlls/msvcrt/Makefile.in @@ -23,6 +23,7 @@ C_SRCS = \ except_arm64.c \ except_i386.c \ except_x86_64.c \ + exception_ptr.c \ exit.c \ file.c \ heap.c \ diff --git a/dlls/msvcrt/cpp.c b/dlls/msvcrt/cpp.c index f3200e046cb..6b2e0dbb20c 100644 --- a/dlls/msvcrt/cpp.c +++ b/dlls/msvcrt/cpp.c @@ -583,7 +583,9 @@ DEFINE_RTTI_DATA1( bad_cast, 0, &exception_rtti_base_descriptor, ".?AVbad_cast@@ DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@@" ) #endif
+#ifdef __x86_64__ DEFINE_CXX_EXCEPTION0( exception, exception_dtor ) +#endif DEFINE_CXX_DATA1( bad_typeid, &exception_cxx_type_info, bad_typeid_dtor ) DEFINE_CXX_DATA1( bad_cast, &exception_cxx_type_info, bad_cast_dtor ) DEFINE_CXX_DATA2( __non_rtti_object, &bad_typeid_cxx_type_info, @@ -1128,351 +1130,11 @@ const char * __thiscall type_info_name_internal_method(type_info * _this, struct return type_info_name(_this); }
-#endif /* _MSVCR_VER >= 80 */ - -/* std::exception_ptr class helpers */ -typedef struct -{ - EXCEPTION_RECORD *rec; - LONG *ref; /* not binary compatible with native msvcr100 */ -} exception_ptr; - -#if _MSVCR_VER >= 100 - -/********************************************************************* - * ?__ExceptionPtrCreate@@YAXPAX@Z - * ?__ExceptionPtrCreate@@YAXPEAX@Z - */ -void __cdecl __ExceptionPtrCreate(exception_ptr *ep) -{ - TRACE("(%p)\n", ep); - - ep->rec = NULL; - ep->ref = NULL; -} - -#ifdef __ASM_USE_THISCALL_WRAPPER -extern void call_dtor(const cxx_exception_type *type, void *func, void *object); - -__ASM_GLOBAL_FUNC( call_dtor, - "movl 12(%esp),%ecx\n\t" - "call *8(%esp)\n\t" - "ret" ); -#elif __x86_64__ -static inline void call_dtor(const cxx_exception_type *type, unsigned int dtor, void *object) -{ - char *base = RtlPcToFileHeader((void*)type, (void**)&base); - void (__cdecl *func)(void*) = (void*)(base + dtor); - func(object); -} -#else -#define call_dtor(type, func, object) ((void (__thiscall*)(void*))(func))(object) -#endif - -/********************************************************************* - * ?__ExceptionPtrDestroy@@YAXPAX@Z - * ?__ExceptionPtrDestroy@@YAXPEAX@Z - */ -void __cdecl __ExceptionPtrDestroy(exception_ptr *ep) -{ - TRACE("(%p)\n", ep); - - if (!ep->rec) - return; - - if (!InterlockedDecrement(ep->ref)) - { - if (ep->rec->ExceptionCode == CXX_EXCEPTION) - { - const cxx_exception_type *type = (void*)ep->rec->ExceptionInformation[2]; - void *obj = (void*)ep->rec->ExceptionInformation[1]; - - if (type && type->destructor) call_dtor(type, type->destructor, obj); - HeapFree(GetProcessHeap(), 0, obj); - } - - HeapFree(GetProcessHeap(), 0, ep->rec); - HeapFree(GetProcessHeap(), 0, ep->ref); - } -} - -/********************************************************************* - * ?__ExceptionPtrCopy@@YAXPAXPBX@Z - * ?__ExceptionPtrCopy@@YAXPEAXPEBX@Z - */ -void __cdecl __ExceptionPtrCopy(exception_ptr *ep, const exception_ptr *copy) -{ - TRACE("(%p %p)\n", ep, copy); - - /* don't destroy object stored in ep */ - *ep = *copy; - if (ep->ref) - InterlockedIncrement(copy->ref); -} - -/********************************************************************* - * ?__ExceptionPtrAssign@@YAXPAXPBX@Z - * ?__ExceptionPtrAssign@@YAXPEAXPEBX@Z - */ -void __cdecl __ExceptionPtrAssign(exception_ptr *ep, const exception_ptr *assign) -{ - TRACE("(%p %p)\n", ep, assign); - - /* don't destroy object stored in ep */ - if (ep->ref) - InterlockedDecrement(ep->ref); - - *ep = *assign; - if (ep->ref) - InterlockedIncrement(ep->ref); -} - -#endif /* _MSVCR_VER >= 100 */ - -/********************************************************************* - * ?__ExceptionPtrRethrow@@YAXPBX@Z - * ?__ExceptionPtrRethrow@@YAXPEBX@Z - */ -void __cdecl __ExceptionPtrRethrow(const exception_ptr *ep) -{ - TRACE("(%p)\n", ep); - - if (!ep->rec) - { - static const char *exception_msg = "bad exception"; - exception e; - - exception_ctor(&e, &exception_msg); - _CxxThrowException(&e, &exception_exception_type); - return; - } - - RaiseException(ep->rec->ExceptionCode, ep->rec->ExceptionFlags & (~EH_UNWINDING), - ep->rec->NumberParameters, ep->rec->ExceptionInformation); -} - -#if _MSVCR_VER >= 100 - -#ifdef __i386__ -extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase ); -#else -static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase ) -{ - TRACE( "calling copy ctor %p object %p src %p\n", func, this, src ); - if (has_vbase) - ((void (__cdecl*)(void*, void*, BOOL))func)(this, src, 1); - else - ((void (__cdecl*)(void*, void*))func)(this, src); -} -#endif - -/********************************************************************* - * ?__ExceptionPtrCurrentException@@YAXPAX@Z - * ?__ExceptionPtrCurrentException@@YAXPEAX@Z - */ -#ifndef __x86_64__ -void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep) -{ - EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record; - - TRACE("(%p)\n", ep); - - if (!rec) - { - ep->rec = NULL; - ep->ref = NULL; - return; - } - - ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); - ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); - - *ep->rec = *rec; - *ep->ref = 1; - - if (ep->rec->ExceptionCode == CXX_EXCEPTION) - { - const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2]; - const cxx_type_info *ti; - void **data, *obj; - - ti = et->type_info_table->info[0]; - data = HeapAlloc(GetProcessHeap(), 0, ti->size); - - obj = (void*)ep->rec->ExceptionInformation[1]; - if (ti->flags & CLASS_IS_SIMPLE_TYPE) - { - memcpy(data, obj, ti->size); - if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); - } - else if (ti->copy_ctor) - { - call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj), - ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); - } - else - memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size); - ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; - } - return; -} -#else -void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep) -{ - EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record; - - TRACE("(%p)\n", ep); - - if (!rec) - { - ep->rec = NULL; - ep->ref = NULL; - return; - } - - ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); - ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); - - *ep->rec = *rec; - *ep->ref = 1; - - if (ep->rec->ExceptionCode == CXX_EXCEPTION) - { - const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2]; - const cxx_type_info *ti; - void **data, *obj; - char *base = RtlPcToFileHeader((void*)et, (void**)&base); - - ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + et->type_info_table))->info[0]); - data = HeapAlloc(GetProcessHeap(), 0, ti->size); - - obj = (void*)ep->rec->ExceptionInformation[1]; - if (ti->flags & CLASS_IS_SIMPLE_TYPE) - { - memcpy(data, obj, ti->size); - if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); - } - else if (ti->copy_ctor) - { - call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj), - ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); - } - else - memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size); - ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; - } - return; -} -#endif - -#endif /* _MSVCR_VER >= 100 */ - -#if _MSVCR_VER >= 110 -/********************************************************************* - * ?__ExceptionPtrToBool@@YA_NPBX@Z - * ?__ExceptionPtrToBool@@YA_NPEBX@Z - */ -bool __cdecl __ExceptionPtrToBool(exception_ptr *ep) -{ - return !!ep->rec; -} -#endif - -#if _MSVCR_VER >= 100 - -/********************************************************************* - * ?__ExceptionPtrCopyException@@YAXPAXPBX1@Z - * ?__ExceptionPtrCopyException@@YAXPEAXPEBX1@Z - */ -#ifndef __x86_64__ -void __cdecl __ExceptionPtrCopyException(exception_ptr *ep, - exception *object, const cxx_exception_type *type) -{ - const cxx_type_info *ti; - void **data; - - __ExceptionPtrDestroy(ep); - - ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); - ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); - *ep->ref = 1; - - memset(ep->rec, 0, sizeof(EXCEPTION_RECORD)); - ep->rec->ExceptionCode = CXX_EXCEPTION; - ep->rec->ExceptionFlags = EH_NONCONTINUABLE; - ep->rec->NumberParameters = 3; - ep->rec->ExceptionInformation[0] = CXX_FRAME_MAGIC_VC6; - ep->rec->ExceptionInformation[2] = (ULONG_PTR)type; - - ti = type->type_info_table->info[0]; - data = HeapAlloc(GetProcessHeap(), 0, ti->size); - if (ti->flags & CLASS_IS_SIMPLE_TYPE) - { - memcpy(data, object, ti->size); - if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); - } - else if (ti->copy_ctor) - { - call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, object), - ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); - } - else - memcpy(data, get_this_pointer(&ti->offsets, object), ti->size); - ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; -} -#else -void __cdecl __ExceptionPtrCopyException(exception_ptr *ep, - exception *object, const cxx_exception_type *type) -{ - const cxx_type_info *ti; - void **data; - char *base; - - RtlPcToFileHeader((void*)type, (void**)&base); - __ExceptionPtrDestroy(ep); - - ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); - ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); - *ep->ref = 1; - - memset(ep->rec, 0, sizeof(EXCEPTION_RECORD)); - ep->rec->ExceptionCode = CXX_EXCEPTION; - ep->rec->ExceptionFlags = EH_NONCONTINUABLE; - ep->rec->NumberParameters = 4; - ep->rec->ExceptionInformation[0] = CXX_FRAME_MAGIC_VC6; - ep->rec->ExceptionInformation[2] = (ULONG_PTR)type; - ep->rec->ExceptionInformation[3] = (ULONG_PTR)base; - - ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + type->type_info_table))->info[0]); - data = HeapAlloc(GetProcessHeap(), 0, ti->size); - if (ti->flags & CLASS_IS_SIMPLE_TYPE) - { - memcpy(data, object, ti->size); - if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); - } - else if (ti->copy_ctor) - { - call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, object), - ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); - } - else - memcpy(data, get_this_pointer(&ti->offsets, object), ti->size); - ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; -} -#endif - -bool __cdecl __ExceptionPtrCompare(const exception_ptr *ep1, const exception_ptr *ep2) -{ - return ep1->rec == ep2->rec; -} - -#endif /* _MSVCR_VER >= 100 */ - -#if _MSVCR_VER >= 80 void* __cdecl __AdjustPointer(void *obj, const this_ptr_offsets *off) { return get_this_pointer(off, obj); } + #endif
#if _MSVCR_VER >= 140 diff --git a/dlls/msvcrt/cxx.h b/dlls/msvcrt/cxx.h index cacbb1524b6..047bd5610a9 100644 --- a/dlls/msvcrt/cxx.h +++ b/dlls/msvcrt/cxx.h @@ -308,3 +308,9 @@ __ASM_BLOCK_BEGIN(type_info_vtables) \ __ASM_VTABLE(type_info, \ VTABLE_ADD_FUNC(type_info_vector_dtor)); \ __ASM_BLOCK_END + +typedef struct +{ + EXCEPTION_RECORD *rec; + LONG *ref; /* not binary compatible with native msvcr100 */ +} exception_ptr; diff --git a/dlls/msvcrt/exception_ptr.c b/dlls/msvcrt/exception_ptr.c new file mode 100644 index 00000000000..7eddfb98341 --- /dev/null +++ b/dlls/msvcrt/exception_ptr.c @@ -0,0 +1,346 @@ +#include <stdarg.h> +#include <stdbool.h> + +#include "windef.h" +#include "winternl.h" +#include "wine/exception.h" +#include "wine/debug.h" +#include "msvcrt.h" +#include "cxx.h" + +WINE_DEFAULT_DEBUG_CHANNEL(msvcrt); + +/* std::exception_ptr class helpers */ + +typedef exception eexception; +CREATE_EXCEPTION_OBJECT(eexception) + +DEFINE_CXX_EXCEPTION0( eexception, eexception_dtor ) + +void msvcrt_init_exception_ptr(void *base) +{ +#ifdef __x86_64__ + init_eexception_rtti(base); + + init_eexception_cxx(base); +#endif +} + +/********************************************************************* + * ?__ExceptionPtrCreate@@YAXPAX@Z + * ?__ExceptionPtrCreate@@YAXPEAX@Z + */ +void __cdecl __ExceptionPtrCreate(exception_ptr *ep) +{ + TRACE("(%p)\n", ep); + + ep->rec = NULL; + ep->ref = NULL; +} + +#ifdef __ASM_USE_THISCALL_WRAPPER +extern void call_dtor(const cxx_exception_type *type, void *func, void *object); + +__ASM_GLOBAL_FUNC( call_dtor, + "movl 12(%esp),%ecx\n\t" + "call *8(%esp)\n\t" + "ret" ); +#elif __x86_64__ +static inline void call_dtor(const cxx_exception_type *type, unsigned int dtor, void *object) +{ + char *base = RtlPcToFileHeader((void*)type, (void**)&base); + void (__cdecl *func)(void*) = (void*)(base + dtor); + func(object); +} +#else +#define call_dtor(type, func, object) ((void (__thiscall*)(void*))(func))(object) +#endif + +/********************************************************************* + * ?__ExceptionPtrDestroy@@YAXPAX@Z + * ?__ExceptionPtrDestroy@@YAXPEAX@Z + */ +void __cdecl __ExceptionPtrDestroy(exception_ptr *ep) +{ + TRACE("(%p)\n", ep); + + if (!ep->rec) + return; + + if (!InterlockedDecrement(ep->ref)) + { + if (ep->rec->ExceptionCode == CXX_EXCEPTION) + { + const cxx_exception_type *type = (void*)ep->rec->ExceptionInformation[2]; + void *obj = (void*)ep->rec->ExceptionInformation[1]; + + if (type && type->destructor) call_dtor(type, type->destructor, obj); + HeapFree(GetProcessHeap(), 0, obj); + } + + HeapFree(GetProcessHeap(), 0, ep->rec); + HeapFree(GetProcessHeap(), 0, ep->ref); + } +} + +/********************************************************************* + * ?__ExceptionPtrCopy@@YAXPAXPBX@Z + * ?__ExceptionPtrCopy@@YAXPEAXPEBX@Z + */ +void __cdecl __ExceptionPtrCopy(exception_ptr *ep, const exception_ptr *copy) +{ + TRACE("(%p %p)\n", ep, copy); + + /* don't destroy object stored in ep */ + *ep = *copy; + if (ep->ref) + InterlockedIncrement(copy->ref); +} + +/********************************************************************* + * ?__ExceptionPtrAssign@@YAXPAXPBX@Z + * ?__ExceptionPtrAssign@@YAXPEAXPEBX@Z + */ +void __cdecl __ExceptionPtrAssign(exception_ptr *ep, const exception_ptr *assign) +{ + TRACE("(%p %p)\n", ep, assign); + + /* don't destroy object stored in ep */ + if (ep->ref) + InterlockedDecrement(ep->ref); + + *ep = *assign; + if (ep->ref) + InterlockedIncrement(ep->ref); +} + +/********************************************************************* + * ?__ExceptionPtrRethrow@@YAXPBX@Z + * ?__ExceptionPtrRethrow@@YAXPEBX@Z + */ +void __cdecl __ExceptionPtrRethrow(const exception_ptr *ep) +{ + TRACE("(%p)\n", ep); + + if (!ep->rec) + { + static const char *exception_msg = "bad exception"; + exception e; + + exception_ctor(&e, &exception_msg); + _CxxThrowException(&e, &eexception_exception_type); + return; + } + + RaiseException(ep->rec->ExceptionCode, ep->rec->ExceptionFlags & (~EH_UNWINDING), + ep->rec->NumberParameters, ep->rec->ExceptionInformation); +} + +#ifdef __i386__ +extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase ); +#else +static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase ) +{ + TRACE( "calling copy ctor %p object %p src %p\n", func, this, src ); + if (has_vbase) + ((void (__cdecl*)(void*, void*, BOOL))func)(this, src, 1); + else + ((void (__cdecl*)(void*, void*))func)(this, src); +} +#endif + +/********************************************************************* + * ?__ExceptionPtrCurrentException@@YAXPAX@Z + * ?__ExceptionPtrCurrentException@@YAXPEAX@Z + */ +#ifndef __x86_64__ +void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep) +{ + EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record; + + TRACE("(%p)\n", ep); + + if (!rec) + { + ep->rec = NULL; + ep->ref = NULL; + return; + } + + ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); + ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); + + *ep->rec = *rec; + *ep->ref = 1; + + if (ep->rec->ExceptionCode == CXX_EXCEPTION) + { + const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2]; + const cxx_type_info *ti; + void **data, *obj; + + ti = et->type_info_table->info[0]; + data = HeapAlloc(GetProcessHeap(), 0, ti->size); + + obj = (void*)ep->rec->ExceptionInformation[1]; + if (ti->flags & CLASS_IS_SIMPLE_TYPE) + { + memcpy(data, obj, ti->size); + if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); + } + else if (ti->copy_ctor) + { + call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj), + ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); + } + else + memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size); + ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; + } + return; +} +#else +void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep) +{ + EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record; + + TRACE("(%p)\n", ep); + + if (!rec) + { + ep->rec = NULL; + ep->ref = NULL; + return; + } + + ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); + ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); + + *ep->rec = *rec; + *ep->ref = 1; + + if (ep->rec->ExceptionCode == CXX_EXCEPTION) + { + const cxx_exception_type *et = (void*)ep->rec->ExceptionInformation[2]; + const cxx_type_info *ti; + void **data, *obj; + char *base = RtlPcToFileHeader((void*)et, (void**)&base); + + ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + et->type_info_table))->info[0]); + data = HeapAlloc(GetProcessHeap(), 0, ti->size); + + obj = (void*)ep->rec->ExceptionInformation[1]; + if (ti->flags & CLASS_IS_SIMPLE_TYPE) + { + memcpy(data, obj, ti->size); + if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); + } + else if (ti->copy_ctor) + { + call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, obj), + ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); + } + else + memcpy(data, get_this_pointer(&ti->offsets, obj), ti->size); + ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; + } + return; +} +#endif + +#if _MSVCR_VER >= 110 +/********************************************************************* + * ?__ExceptionPtrToBool@@YA_NPBX@Z + * ?__ExceptionPtrToBool@@YA_NPEBX@Z + */ +bool __cdecl __ExceptionPtrToBool(exception_ptr *ep) +{ + return !!ep->rec; +} +#endif + +/********************************************************************* + * ?__ExceptionPtrCopyException@@YAXPAXPBX1@Z + * ?__ExceptionPtrCopyException@@YAXPEAXPEBX1@Z + */ +#ifndef __x86_64__ +void __cdecl __ExceptionPtrCopyException(exception_ptr *ep, + exception *object, const cxx_exception_type *type) +{ + const cxx_type_info *ti; + void **data; + + __ExceptionPtrDestroy(ep); + + ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); + ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); + *ep->ref = 1; + + memset(ep->rec, 0, sizeof(EXCEPTION_RECORD)); + ep->rec->ExceptionCode = CXX_EXCEPTION; + ep->rec->ExceptionFlags = EH_NONCONTINUABLE; + ep->rec->NumberParameters = 3; + ep->rec->ExceptionInformation[0] = CXX_FRAME_MAGIC_VC6; + ep->rec->ExceptionInformation[2] = (ULONG_PTR)type; + + ti = type->type_info_table->info[0]; + data = HeapAlloc(GetProcessHeap(), 0, ti->size); + if (ti->flags & CLASS_IS_SIMPLE_TYPE) + { + memcpy(data, object, ti->size); + if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); + } + else if (ti->copy_ctor) + { + call_copy_ctor(ti->copy_ctor, data, get_this_pointer(&ti->offsets, object), + ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); + } + else + memcpy(data, get_this_pointer(&ti->offsets, object), ti->size); + ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; +} +#else +void __cdecl __ExceptionPtrCopyException(exception_ptr *ep, + exception *object, const cxx_exception_type *type) +{ + const cxx_type_info *ti; + void **data; + char *base; + + RtlPcToFileHeader((void*)type, (void**)&base); + __ExceptionPtrDestroy(ep); + + ep->rec = HeapAlloc(GetProcessHeap(), 0, sizeof(EXCEPTION_RECORD)); + ep->ref = HeapAlloc(GetProcessHeap(), 0, sizeof(int)); + *ep->ref = 1; + + memset(ep->rec, 0, sizeof(EXCEPTION_RECORD)); + ep->rec->ExceptionCode = CXX_EXCEPTION; + ep->rec->ExceptionFlags = EH_NONCONTINUABLE; + ep->rec->NumberParameters = 4; + ep->rec->ExceptionInformation[0] = CXX_FRAME_MAGIC_VC6; + ep->rec->ExceptionInformation[2] = (ULONG_PTR)type; + ep->rec->ExceptionInformation[3] = (ULONG_PTR)base; + + ti = (const cxx_type_info*)(base + ((const cxx_type_info_table*)(base + type->type_info_table))->info[0]); + data = HeapAlloc(GetProcessHeap(), 0, ti->size); + if (ti->flags & CLASS_IS_SIMPLE_TYPE) + { + memcpy(data, object, ti->size); + if (ti->size == sizeof(void *)) *data = get_this_pointer(&ti->offsets, *data); + } + else if (ti->copy_ctor) + { + call_copy_ctor(base + ti->copy_ctor, data, get_this_pointer(&ti->offsets, object), + ti->flags & CLASS_HAS_VIRTUAL_BASE_CLASS); + } + else + memcpy(data, get_this_pointer(&ti->offsets, object), ti->size); + ep->rec->ExceptionInformation[1] = (ULONG_PTR)data; +} +#endif + +bool __cdecl __ExceptionPtrCompare(const exception_ptr *ep1, const exception_ptr *ep2) +{ + return ep1->rec == ep2->rec; +} diff --git a/dlls/msvcrt/main.c b/dlls/msvcrt/main.c index db8554668ad..607962807fd 100644 --- a/dlls/msvcrt/main.c +++ b/dlls/msvcrt/main.c @@ -117,6 +117,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) msvcrt_init_signals(); #if _MSVCR_VER >= 100 && _MSVCR_VER <= 120 msvcrt_init_concurrency(hinstDLL); + msvcrt_init_exception_ptr(hinstDLL); #endif #if _MSVCR_VER == 0 /* don't allow unloading msvcrt, we can't setup file handles twice */ diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 1d965ff8ffc..5117b52cd2b 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -235,6 +235,7 @@ extern void msvcrt_init_clock(void) DECLSPEC_HIDDEN; #if _MSVCR_VER >= 100 extern void msvcrt_init_concurrency(void*) DECLSPEC_HIDDEN; extern void msvcrt_free_concurrency(void) DECLSPEC_HIDDEN; +extern void msvcrt_init_exception_ptr(void*) DECLSPEC_HIDDEN; extern void msvcrt_free_scheduler_thread(void) DECLSPEC_HIDDEN; #endif
diff --git a/dlls/msvcrtd/Makefile.in b/dlls/msvcrtd/Makefile.in index bd4f78729d0..045b9092766 100644 --- a/dlls/msvcrtd/Makefile.in +++ b/dlls/msvcrtd/Makefile.in @@ -19,6 +19,7 @@ C_SRCS = \ except_arm64.c \ except_i386.c \ except_x86_64.c \ + exception_ptr.c \ exit.c \ file.c \ heap.c \ diff --git a/dlls/ucrtbase/Makefile.in b/dlls/ucrtbase/Makefile.in index bf7f62ada8a..4e7cfc03b5c 100644 --- a/dlls/ucrtbase/Makefile.in +++ b/dlls/ucrtbase/Makefile.in @@ -23,6 +23,7 @@ C_SRCS = \ except_arm64.c \ except_i386.c \ except_x86_64.c \ + exception_ptr.c \ exit.c \ file.c \ heap.c \
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/msvcrt/exception_ptr.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/dlls/msvcrt/exception_ptr.c b/dlls/msvcrt/exception_ptr.c index 7eddfb98341..74eb49e3618 100644 --- a/dlls/msvcrt/exception_ptr.c +++ b/dlls/msvcrt/exception_ptr.c @@ -149,15 +149,9 @@ static inline void call_copy_ctor( void *func, void *this, void *src, int has_vb } #endif
-/********************************************************************* - * ?__ExceptionPtrCurrentException@@YAXPAX@Z - * ?__ExceptionPtrCurrentException@@YAXPEAX@Z - */ #ifndef __x86_64__ -void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep) +static void exception_ptr_from_record(exception_ptr *ep, EXCEPTION_RECORD *rec) { - EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record; - TRACE("(%p)\n", ep);
if (!rec) @@ -200,10 +194,8 @@ void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep) return; } #else -void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep) +static void exception_ptr_from_record(exception_ptr *ep, EXCEPTION_RECORD *rec) { - EXCEPTION_RECORD *rec = msvcrt_get_thread_data()->exc_record; - TRACE("(%p)\n", ep);
if (!rec) @@ -248,6 +240,16 @@ void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep) } #endif
+/********************************************************************* + * ?__ExceptionPtrCurrentException@@YAXPAX@Z + * ?__ExceptionPtrCurrentException@@YAXPEAX@Z + */ +void __cdecl __ExceptionPtrCurrentException(exception_ptr *ep) +{ + TRACE("(%p)\n", ep); + exception_ptr_from_record(ep, msvcrt_get_thread_data()->exc_record); +} + #if _MSVCR_VER >= 110 /********************************************************************* * ?__ExceptionPtrToBool@@YA_NPBX@Z
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/msvcrt/concurrency.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-)
diff --git a/dlls/msvcrt/concurrency.c b/dlls/msvcrt/concurrency.c index d0c9924c631..f8abdff9f5d 100644 --- a/dlls/msvcrt/concurrency.c +++ b/dlls/msvcrt/concurrency.c @@ -697,29 +697,38 @@ static Context* get_current_context(void) return ret; }
+static Scheduler* get_scheduler_from_context(Context *ctx) +{ + ExternalContextBase *context = (ExternalContextBase*)ctx; + + if (context->context.vtable != &ExternalContextBase_vtable) + return NULL; + return context->scheduler.scheduler; +} + static Scheduler* try_get_current_scheduler(void) { - ExternalContextBase *context = (ExternalContextBase*)try_get_current_context(); + Context *context = try_get_current_context(); + Scheduler *ret;
if (!context) return NULL;
- if (context->context.vtable != &ExternalContextBase_vtable) { + ret = get_scheduler_from_context(context); + if (!ret) ERR("unknown context set\n"); - return NULL; - } - return context->scheduler.scheduler; + return ret; }
static Scheduler* get_current_scheduler(void) { - ExternalContextBase *context = (ExternalContextBase*)get_current_context(); + Context *context = get_current_context(); + Scheduler *ret;
- if (context->context.vtable != &ExternalContextBase_vtable) { + ret = get_scheduler_from_context(context); + if (!ret) ERR("unknown context set\n"); - return NULL; - } - return context->scheduler.scheduler; + return ret; }
/* ?CurrentContext@Context@Concurrency@@SAPAV12@XZ */
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/msvcrt/concurrency.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/msvcrt/concurrency.c b/dlls/msvcrt/concurrency.c index f8abdff9f5d..65caf7a5040 100644 --- a/dlls/msvcrt/concurrency.c +++ b/dlls/msvcrt/concurrency.c @@ -91,6 +91,7 @@ struct scheduler_list {
typedef struct { Context context; + LONG refcount; struct scheduler_list scheduler; unsigned int id; union allocator_cache_entry *allocator_cache[8]; @@ -845,6 +846,11 @@ static void ExternalContextBase_dtor(ExternalContextBase *this) union allocator_cache_entry *next, *cur; int i;
+ if (InterlockedDecrement(&this->refcount)) { + TRACE("skipping dtor: refcount not zero\n"); + return; + } + /* TODO: move the allocator cache to scheduler so it can be reused */ for(i=0; i<ARRAY_SIZE(this->allocator_cache); i++) { for(cur = this->allocator_cache[i]; cur; cur=next) { @@ -890,6 +896,7 @@ static void ExternalContextBase_ctor(ExternalContextBase *this)
memset(this, 0, sizeof(*this)); this->context.vtable = &ExternalContextBase_vtable; + this->refcount = 1; this->id = InterlockedIncrement(&context_id);
create_default_scheduler();
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/concrt140/Makefile.in | 4 +- dlls/msvcr120/tests/msvcr120.c | 6 +- dlls/msvcrt/concurrency.c | 166 +++++++++++++++++++++++++++++++-- dlls/msvcrt/cxx.h | 5 + dlls/msvcrt/exception_ptr.c | 32 ++++++- 5 files changed, 201 insertions(+), 12 deletions(-)
diff --git a/dlls/concrt140/Makefile.in b/dlls/concrt140/Makefile.in index aac1ed7b34a..05258adf7ee 100644 --- a/dlls/concrt140/Makefile.in +++ b/dlls/concrt140/Makefile.in @@ -1,7 +1,9 @@ +EXTRADEFS = -D_CONCRT= MODULE = concrt140.dll PARENTSRC = ../msvcrt
C_SRCS = \ concrt140.c \ concurrency.c \ - details.c + details.c \ + exception_ptr.c diff --git a/dlls/msvcr120/tests/msvcr120.c b/dlls/msvcr120/tests/msvcr120.c index ac35076af03..24e4914d98a 100644 --- a/dlls/msvcr120/tests/msvcr120.c +++ b/dlls/msvcr120/tests/msvcr120.c @@ -170,7 +170,7 @@ typedef struct _StructuredTaskCollection Context *context; volatile LONG count; volatile LONG finished; - void *unk4; + void *exception; void *event; } _StructuredTaskCollection;
@@ -1439,8 +1439,8 @@ static void test_StructuredTaskCollection(void) "_StructuredTaskCollection ctor set wrong count: %ld != 0\n", task_coll.count); ok(task_coll.finished == LONG_MIN, "_StructuredTaskCollection ctor set wrong finished: %ld != %ld\n", task_coll.finished, LONG_MIN); - ok(task_coll.unk4 == NULL, - "_StructuredTaskCollection ctor set wrong unk4: %p != NULL\n", task_coll.unk4); + ok(task_coll.exception == NULL, + "_StructuredTaskCollection ctor set wrong exception: %p != NULL\n", task_coll.exception);
chore_start_evt = CreateEventW(NULL, TRUE, FALSE, NULL); ok(chore_start_evt != NULL, "CreateEvent failed: 0x%lx\n", GetLastError()); diff --git a/dlls/msvcrt/concurrency.c b/dlls/msvcrt/concurrency.c index 65caf7a5040..38c780028d7 100644 --- a/dlls/msvcrt/concurrency.c +++ b/dlls/msvcrt/concurrency.c @@ -20,10 +20,14 @@
#include <stdarg.h> #include <stdbool.h> +#include <malloc.h>
#include "windef.h" +#include "winbase.h" #include "winternl.h" #include "wine/debug.h" +#include "wine/exception.h" +#include "wine/list.h" #include "msvcrt.h" #include "cxx.h"
@@ -89,12 +93,21 @@ struct scheduler_list { struct scheduler_list *next; };
+struct _UnrealizedChore; + +struct scheduled_chore { + struct list entry; + struct _UnrealizedChore *chore; +}; + typedef struct { Context context; LONG refcount; struct scheduler_list scheduler; unsigned int id; union allocator_cache_entry *allocator_cache[8]; + struct list scheduled_chores; + CRITICAL_SECTION scheduled_chores_cs; } ExternalContextBase; extern const vtable_ptr ExternalContextBase_vtable; static void ExternalContextBase_ctor(ExternalContextBase*); @@ -165,14 +178,27 @@ typedef struct yield_func yield_func; } SpinWait;
-typedef struct +struct _StructuredTaskCollection; + +typedef struct _UnrealizedChore { - char dummy; + const vtable_ptr *vtable; + void (__cdecl *chore_proc)(struct _UnrealizedChore*); + struct _StructuredTaskCollection *task_collection; + void (__cdecl *chore_wrapper)(struct _UnrealizedChore*); + void *unk[6]; } _UnrealizedChore;
-typedef struct +typedef struct _StructuredTaskCollection { - char dummy; + void *unk1; + unsigned int unk2; + void *unk3; + Context *context; + volatile LONG count; + volatile LONG finished; + void *exception; + void *event; } _StructuredTaskCollection;
/* keep in sync with msvcp90/msvcp90.h */ @@ -630,6 +656,7 @@ DEFINE_RTTI_DATA1(scheduler_resource_allocation_error, 0, &cexception_rtti_base_ DEFINE_CXX_DATA1(improper_lock, &cexception_cxx_type_info, cexception_dtor) DEFINE_CXX_DATA1(improper_scheduler_attach, &cexception_cxx_type_info, cexception_dtor) DEFINE_CXX_DATA1(improper_scheduler_detach, &cexception_cxx_type_info, cexception_dtor) +DEFINE_CXX_DATA1(invalid_multiple_scheduling, &cexception_cxx_type_info, cexception_dtor) DEFINE_CXX_DATA1(invalid_scheduler_policy_key, &cexception_cxx_type_info, cexception_dtor) DEFINE_CXX_DATA1(invalid_scheduler_policy_thread_specification, &cexception_cxx_type_info, cexception_dtor) DEFINE_CXX_DATA1(invalid_scheduler_policy_value, &cexception_cxx_type_info, cexception_dtor) @@ -840,6 +867,11 @@ bool __thiscall ExternalContextBase_IsSynchronouslyBlocked(const ExternalContext return FALSE; }
+static void ExternalContextBase_addref(ExternalContextBase *this) +{ + InterlockedIncrement(&this->refcount); +} + static void ExternalContextBase_dtor(ExternalContextBase *this) { struct scheduler_list *scheduler_cur, *scheduler_next; @@ -868,6 +900,12 @@ static void ExternalContextBase_dtor(ExternalContextBase *this) operator_delete(scheduler_cur); } } + + EnterCriticalSection(&this->scheduled_chores_cs); + if (!list_empty(&this->scheduled_chores)) + ERR("scheduled chore list is not empty\n"); + LeaveCriticalSection(&this->scheduled_chores_cs); + DeleteCriticalSection(&this->scheduled_chores_cs); }
DEFINE_THISCALL_WRAPPER(ExternalContextBase_vector_dtor, 8) @@ -898,6 +936,8 @@ static void ExternalContextBase_ctor(ExternalContextBase *this) this->context.vtable = &ExternalContextBase_vtable; this->refcount = 1; this->id = InterlockedIncrement(&context_id); + list_init(&this->scheduled_chores); + InitializeCriticalSection(&this->scheduled_chores_cs);
create_default_scheduler(); this->scheduler.scheduler = &default_scheduler->scheduler; @@ -1827,10 +1867,109 @@ DEFINE_THISCALL_WRAPPER(_StructuredTaskCollection_dtor, 4) void __thiscall _StructuredTaskCollection_dtor(_StructuredTaskCollection *this) { FIXME("(%p): stub!\n", this); + if (this->context && this->context->vtable == &ExternalContextBase_vtable) + ExternalContextBase_dtor((ExternalContextBase*)this->context); }
#endif /* _MSVCR_VER >= 120 */
+static void CALLBACK chore_wrapper_finally(BOOL normal, void *data) +{ + _UnrealizedChore *chore = data; + LONG prev_finished, new_finished; + volatile LONG *ptr; + + TRACE("(%u %p)\n", normal, data); + + if (!chore->task_collection) + return; + ptr = &chore->task_collection->finished; + chore->task_collection = NULL; + + do { + prev_finished = *ptr; + if (prev_finished == 0x80000000) + new_finished = 1; + else + new_finished = prev_finished + 1; + } while (InterlockedCompareExchange(ptr, new_finished, prev_finished) + != prev_finished); +} + +static void __cdecl chore_wrapper(_UnrealizedChore *chore) +{ + TRACE("(%p)\n", chore); + + __TRY + { + if (chore->chore_proc) + chore->chore_proc(chore); + } + __FINALLY_CTX(chore_wrapper_finally, chore) +} + +static void __cdecl _StructuredTaskCollection_scheduler_cb(void *data) +{ + ExternalContextBase *context = data; + struct list *entry; + struct scheduled_chore *sc; + _UnrealizedChore *chore; + + TRACE("(%p)\n", context); + + EnterCriticalSection(&context->scheduled_chores_cs); + entry = list_head(&context->scheduled_chores); + if (entry) + list_remove(entry); + LeaveCriticalSection(&context->scheduled_chores_cs); + if (!entry) + return; + ExternalContextBase_dtor(context); + + sc = LIST_ENTRY(entry, struct scheduled_chore, entry); + chore = sc->chore; + operator_delete(sc); + + chore->chore_wrapper(chore); +} + +static bool schedule_chore(_StructuredTaskCollection *this, + _UnrealizedChore *chore, ExternalContextBase **context) +{ + struct scheduled_chore *sc; + + if (chore->task_collection) { + invalid_multiple_scheduling e; + invalid_multiple_scheduling_ctor_str(&e, "Chore scheduled multiple times"); + _CxxThrowException(&e, &invalid_multiple_scheduling_exception_type); + return FALSE; + } + + *context = (ExternalContextBase*)this->context; + if (!*context) { + *context = (ExternalContextBase*)get_current_context(); + if ((*context)->context.vtable != &ExternalContextBase_vtable) { + ERR("unknown context set\n"); + return FALSE; + } + ExternalContextBase_addref(*context); + this->context = (Context*)*context; + } + + sc = operator_new(sizeof(*sc)); + sc->chore = chore; + + chore->task_collection = this; + chore->chore_wrapper = chore_wrapper; + InterlockedIncrement(&this->count); + + ExternalContextBase_addref(*context); + EnterCriticalSection(&(*context)->scheduled_chores_cs); + list_add_head(&(*context)->scheduled_chores, &sc->entry); + LeaveCriticalSection(&(*context)->scheduled_chores_cs); + return TRUE; +} + #if _MSVCR_VER >= 110
/* ?_Schedule@_StructuredTaskCollection@details@Concurrency@@QAAXPAV_UnrealizedChore@23@PAVlocation@3@@Z */ @@ -1841,7 +1980,14 @@ void __thiscall _StructuredTaskCollection__Schedule_loc( _StructuredTaskCollection *this, _UnrealizedChore *chore, /*location*/void *placement) { - FIXME("(%p %p %p): stub!\n", this, chore, placement); + ExternalContextBase *context; + + FIXME("(%p %p %p): semi-stub\n", this, chore, placement); + + if (schedule_chore(this, chore, &context)) + call_Scheduler_ScheduleTask_loc( + get_scheduler_from_context((Context*)context), + _StructuredTaskCollection_scheduler_cb, context, placement); }
#endif /* _MSVCR_VER >= 110 */ @@ -1853,7 +1999,14 @@ DEFINE_THISCALL_WRAPPER(_StructuredTaskCollection__Schedule, 8) void __thiscall _StructuredTaskCollection__Schedule( _StructuredTaskCollection *this, _UnrealizedChore *chore) { - FIXME("(%p %p): stub!\n", this, chore); + ExternalContextBase *context; + + TRACE("(%p %p)\n", this, chore); + + if (schedule_chore(this, chore, &context)) + call_Scheduler_ScheduleTask( + get_scheduler_from_context((Context*)context), + _StructuredTaskCollection_scheduler_cb, context); }
/* ?_RunAndWait@_StructuredTaskCollection@details@Concurrency@@QAA?AW4_TaskCollectionStatus@23@PAV_UnrealizedChore@23@@Z */ @@ -3112,6 +3265,7 @@ void msvcrt_init_concurrency(void *base) init_improper_lock_cxx(base); init_improper_scheduler_attach_cxx(base); init_improper_scheduler_detach_cxx(base); + init_invalid_multiple_scheduling_cxx(base); init_invalid_scheduler_policy_key_cxx(base); init_invalid_scheduler_policy_thread_specification_cxx(base); init_invalid_scheduler_policy_value_cxx(base); diff --git a/dlls/msvcrt/cxx.h b/dlls/msvcrt/cxx.h index 047bd5610a9..7bbdc4a2a77 100644 --- a/dlls/msvcrt/cxx.h +++ b/dlls/msvcrt/cxx.h @@ -314,3 +314,8 @@ typedef struct EXCEPTION_RECORD *rec; LONG *ref; /* not binary compatible with native msvcr100 */ } exception_ptr; + +void exception_ptr_from_record(exception_ptr*,EXCEPTION_RECORD*) DECLSPEC_HIDDEN; + +void __cdecl __ExceptionPtrCreate(exception_ptr*); +void __cdecl __ExceptionPtrDestroy(exception_ptr*); diff --git a/dlls/msvcrt/exception_ptr.c b/dlls/msvcrt/exception_ptr.c index 74eb49e3618..675ea7664f7 100644 --- a/dlls/msvcrt/exception_ptr.c +++ b/dlls/msvcrt/exception_ptr.c @@ -12,6 +12,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
/* std::exception_ptr class helpers */
+#ifndef _CONCRT + typedef exception eexception; CREATE_EXCEPTION_OBJECT(eexception)
@@ -26,6 +28,8 @@ void msvcrt_init_exception_ptr(void *base) #endif }
+#endif + /********************************************************************* * ?__ExceptionPtrCreate@@YAXPAX@Z * ?__ExceptionPtrCreate@@YAXPEAX@Z @@ -83,6 +87,8 @@ void __cdecl __ExceptionPtrDestroy(exception_ptr *ep) } }
+#ifndef _CONCRT + /********************************************************************* * ?__ExceptionPtrCopy@@YAXPAXPBX@Z * ?__ExceptionPtrCopy@@YAXPEAXPEBX@Z @@ -136,8 +142,26 @@ void __cdecl __ExceptionPtrRethrow(const exception_ptr *ep) ep->rec->NumberParameters, ep->rec->ExceptionInformation); }
+#endif + #ifdef __i386__ extern void call_copy_ctor( void *func, void *this, void *src, int has_vbase ); +#ifdef _CONCRT +__ASM_GLOBAL_FUNC( call_copy_ctor, + "pushl %ebp\n\t" + __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t") + __ASM_CFI(".cfi_rel_offset %ebp,0\n\t") + "movl %esp, %ebp\n\t" + __ASM_CFI(".cfi_def_cfa_register %ebp\n\t") + "pushl $1\n\t" + "movl 12(%ebp), %ecx\n\t" + "pushl 16(%ebp)\n\t" + "call *8(%ebp)\n\t" + "leave\n" + __ASM_CFI(".cfi_def_cfa %esp,4\n\t") + __ASM_CFI(".cfi_same_value %ebp\n\t") + "ret" ); +#endif #else static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase ) { @@ -150,7 +174,7 @@ static inline void call_copy_ctor( void *func, void *this, void *src, int has_vb #endif
#ifndef __x86_64__ -static void exception_ptr_from_record(exception_ptr *ep, EXCEPTION_RECORD *rec) +void exception_ptr_from_record(exception_ptr *ep, EXCEPTION_RECORD *rec) { TRACE("(%p)\n", ep);
@@ -194,7 +218,7 @@ static void exception_ptr_from_record(exception_ptr *ep, EXCEPTION_RECORD *rec) return; } #else -static void exception_ptr_from_record(exception_ptr *ep, EXCEPTION_RECORD *rec) +void exception_ptr_from_record(exception_ptr *ep, EXCEPTION_RECORD *rec) { TRACE("(%p)\n", ep);
@@ -240,6 +264,8 @@ static void exception_ptr_from_record(exception_ptr *ep, EXCEPTION_RECORD *rec) } #endif
+#ifndef _CONCRT + /********************************************************************* * ?__ExceptionPtrCurrentException@@YAXPAX@Z * ?__ExceptionPtrCurrentException@@YAXPEAX@Z @@ -346,3 +372,5 @@ bool __cdecl __ExceptionPtrCompare(const exception_ptr *ep1, const exception_ptr { return ep1->rec == ep2->rec; } + +#endif
Piotr Caban (@piotr) commented about dlls/msvcrt/concurrency.c:
union allocator_cache_entry *next, *cur; int i;
- if (InterlockedDecrement(&this->refcount)) {
TRACE("skipping dtor: refcount not zero\n");
return;
- }
C++ classes are not working this way - you can't add refcounting. Most probably context cancels all task collections on destroy but it's hard to say without tests.
Piotr Caban (@piotr) commented about dlls/msvcrt/cpp.c:
DEFINE_RTTI_DATA2( __non_rtti_object, 0, &bad_typeid_rtti_base_descriptor, &exception_rtti_base_descriptor, ".?AV__non_rtti_object@@" ) #endif
+#ifdef __x86_64__ DEFINE_CXX_EXCEPTION0( exception, exception_dtor ) +#endif
This is looking wrong, probably the line needs to be removed instead.
Piotr Caban (@piotr) commented about dlls/msvcrt/exception_ptr.c:
+#include "windef.h" +#include "winternl.h" +#include "wine/exception.h" +#include "wine/debug.h" +#include "msvcrt.h" +#include "cxx.h"
+WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
+/* std::exception_ptr class helpers */
+typedef exception eexception; +CREATE_EXCEPTION_OBJECT(eexception)
+DEFINE_CXX_EXCEPTION0( eexception, eexception_dtor )
It would be good to find a way to use one exception implementation per module. During exception catch the "fast path" compares pointers, and only if there's no match, whole mangled names are compared. Also there might be an application that does pointers comparison in theory.
It's probably best to add small helper to throws the exception that will be duplicated in msvcrt and concrt sources.
Piotr Caban (@piotr) commented about dlls/msvcrt/concurrency.c:
+static void CALLBACK chore_wrapper_finally(BOOL normal, void *data) +{
- _UnrealizedChore *chore = data;
- LONG prev_finished, new_finished;
- volatile LONG *ptr;
- TRACE("(%u %p)\n", normal, data);
- if (!chore->task_collection)
return;
- ptr = &chore->task_collection->finished;
- chore->task_collection = NULL;
- do {
prev_finished = *ptr;
if (prev_finished == 0x80000000)
I guess that native uses some values/bits as flags. Probably 0x80000000 means that something is not initialized. Probably there's no point in trying to behave exactly the same as long as we don't need to do any initialization. I think it's better to initialize it to 0 and use simple InterlockedIncrement.
If 0x80000000 is really needed please add a define with meaningful name instead of using magic constants.
Piotr Caban (@piotr) commented about dlls/msvcrt/exception_ptr.c:
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
"movl %esp, %ebp\n\t"
__ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
"pushl $1\n\t"
"movl 12(%ebp), %ecx\n\t"
"pushl 16(%ebp)\n\t"
"call *8(%ebp)\n\t"
"leave\n"
__ASM_CFI(".cfi_def_cfa %esp,4\n\t")
__ASM_CFI(".cfi_same_value %ebp\n\t")
"ret" );
+#endif #else static inline void call_copy_ctor( void *func, void *this, void *src, int has_vbase ) {
The implementation can be probably moved from except_i386.c file to avoid code duplication.