diff --git a/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec b/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec index 4061485b562..b7b0eecf327 100644 --- a/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec +++ b/dlls/api-ms-win-crt-private-l1-1-0/api-ms-win-crt-private-l1-1-0.spec @@ -4,7 +4,7 @@ @ cdecl _FindAndUnlinkFrame(ptr) ucrtbase._FindAndUnlinkFrame @ stub _GetImageBase @ stub _GetThrowImageBase -@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr) ucrtbase._IsExceptionObjectToBeDestroyed +@ cdecl _IsExceptionObjectToBeDestroyed(ptr) ucrtbase._IsExceptionObjectToBeDestroyed @ stub _NLG_Dispatch2 @ stub _NLG_Return @ stub _NLG_Return2 diff --git a/dlls/msvcr100/msvcr100.spec b/dlls/msvcr100/msvcr100.spec index 390ccfbbddf..6fde8dfe933 100644 --- a/dlls/msvcr100/msvcr100.spec +++ b/dlls/msvcr100/msvcr100.spec @@ -530,7 +530,7 @@ @ cdecl _Getmonths() @ cdecl _Gettnames() @ extern _HUGE MSVCRT__HUGE -@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr) +@ cdecl _IsExceptionObjectToBeDestroyed(ptr) @ stub _NLG_Dispatch2 @ stub _NLG_Return @ stub _NLG_Return2 diff --git a/dlls/msvcr110/msvcr110.spec b/dlls/msvcr110/msvcr110.spec index 67edb5ab724..76cafd9b02c 100644 --- a/dlls/msvcr110/msvcr110.spec +++ b/dlls/msvcr110/msvcr110.spec @@ -853,7 +853,7 @@ @ cdecl _Getmonths() @ cdecl _Gettnames() @ extern _HUGE MSVCRT__HUGE -@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr) +@ cdecl _IsExceptionObjectToBeDestroyed(ptr) @ stub _Lock_shared_ptr_spin_lock @ stub -arch=i386 _NLG_Dispatch2 @ stub -arch=arm,win64 __NLG_Dispatch2 diff --git a/dlls/msvcr120/msvcr120.spec b/dlls/msvcr120/msvcr120.spec index 8417443f0f3..dee7fd594d1 100644 --- a/dlls/msvcr120/msvcr120.spec +++ b/dlls/msvcr120/msvcr120.spec @@ -837,7 +837,7 @@ @ cdecl _Getmonths() @ cdecl _Gettnames() @ extern _HUGE MSVCRT__HUGE -@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr) +@ cdecl _IsExceptionObjectToBeDestroyed(ptr) @ stub _LCbuild @ stub -arch=i386 _NLG_Dispatch2 @ stub -arch=arm,win64 __NLG_Dispatch2 diff --git a/dlls/msvcr120_app/msvcr120_app.spec b/dlls/msvcr120_app/msvcr120_app.spec index c58d8f773a4..f5dba67b5b4 100644 --- a/dlls/msvcr120_app/msvcr120_app.spec +++ b/dlls/msvcr120_app/msvcr120_app.spec @@ -831,7 +831,7 @@ @ cdecl _Getmonths() msvcr120._Getmonths @ cdecl _Gettnames() msvcr120._Gettnames @ extern _HUGE msvcr120._HUGE -@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr) msvcr120._IsExceptionObjectToBeDestroyed +@ cdecl _IsExceptionObjectToBeDestroyed(ptr) msvcr120._IsExceptionObjectToBeDestroyed @ stub _LCbuild @ stub -arch=i386 _NLG_Dispatch2 @ stub -arch=arm,win64 __NLG_Dispatch2 diff --git a/dlls/msvcr80/msvcr80.spec b/dlls/msvcr80/msvcr80.spec index 0fb6f198089..97f50977d52 100644 --- a/dlls/msvcr80/msvcr80.spec +++ b/dlls/msvcr80/msvcr80.spec @@ -162,7 +162,7 @@ @ cdecl _Getmonths() @ cdecl _Gettnames() @ extern _HUGE MSVCRT__HUGE -@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr) +@ cdecl _IsExceptionObjectToBeDestroyed(ptr) @ stub -arch=i386 _NLG_Dispatch2 @ stub -arch=arm,win64 __NLG_Dispatch2 @ stub -arch=i386 _NLG_Return diff --git a/dlls/msvcr90/msvcr90.spec b/dlls/msvcr90/msvcr90.spec index 7f81b741bf7..4a29dedd20d 100644 --- a/dlls/msvcr90/msvcr90.spec +++ b/dlls/msvcr90/msvcr90.spec @@ -157,7 +157,7 @@ @ cdecl _Getmonths() @ cdecl _Gettnames() @ extern _HUGE MSVCRT__HUGE -@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr) +@ cdecl _IsExceptionObjectToBeDestroyed(ptr) @ stub _NLG_Dispatch2 @ stub _NLG_Return @ stub _NLG_Return2 diff --git a/dlls/msvcrt/except.c b/dlls/msvcrt/except.c index 903daa58e05..09f42f0cb05 100644 --- a/dlls/msvcrt/except.c +++ b/dlls/msvcrt/except.c @@ -372,6 +372,24 @@ void CDECL _FindAndUnlinkFrame(frame_info *fi) ERR("frame not found, native crashes in this case\n"); } +/********************************************************************* + * _IsExceptionObjectToBeDestroyed (MSVCR80.@) + */ +BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj) +{ + frame_info *cur; + + TRACE( "%p\n", obj ); + + for (cur = msvcrt_get_thread_data()->frame_info_head; cur; cur = cur->next) + { + if (cur->object == obj) + return FALSE; + } + + return TRUE; +} + /********************************************************************* * __DestructExceptionObject (MSVCRT.@) */ @@ -424,13 +442,14 @@ void CDECL __CxxUnregisterExceptionObject(cxx_frame_info *frame_info, BOOL in_us { thread_data_t *data = msvcrt_get_thread_data(); - FIXME("(%p) semi-stub\n", frame_info); + TRACE("(%p)\n", frame_info); if(frame_info->rec == (void*)-1) return; _FindAndUnlinkFrame(&frame_info->frame_info); - if(data->exc_record->ExceptionCode == CXX_EXCEPTION && !in_use) /* FIXME: use _IsExceptionObjectToBeDestroyed here */ + if(data->exc_record->ExceptionCode == CXX_EXCEPTION && !in_use + && _IsExceptionObjectToBeDestroyed((void*)data->exc_record->ExceptionInformation[1])) __DestructExceptionObject(data->exc_record); data->exc_record = frame_info->rec; } diff --git a/dlls/msvcrt/except_arm.c b/dlls/msvcrt/except_arm.c index 2779841f630..62dadef6284 100644 --- a/dlls/msvcrt/except_arm.c +++ b/dlls/msvcrt/except_arm.c @@ -74,15 +74,6 @@ int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs, return EXCEPTION_CONTINUE_SEARCH; } -/********************************************************************* - * _IsExceptionObjectToBeDestroyed (MSVCR80.@) - */ -BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj) -{ - FIXME("%p not implemented\n", obj); - return FALSE; -} - /********************************************************************* * __CxxFrameHandler (MSVCRT.@) */ diff --git a/dlls/msvcrt/except_i386.c b/dlls/msvcrt/except_i386.c index 4569572b7e4..7d7ec752991 100644 --- a/dlls/msvcrt/except_i386.c +++ b/dlls/msvcrt/except_i386.c @@ -131,7 +131,6 @@ DWORD CDECL cxx_frame_handler( PEXCEPTION_RECORD rec, cxx_exception_frame* frame PCONTEXT context, EXCEPTION_REGISTRATION_RECORD** dispatch, const cxx_function_descr *descr, EXCEPTION_REGISTRATION_RECORD* nested_frame, int nested_trylevel ); -BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void*); /* call a function with a given ebp */ static inline void *call_ebp_func( void *func, void *ebp ) @@ -350,11 +349,10 @@ static void cxx_local_unwind( cxx_exception_frame* frame, const cxx_function_des struct catch_func_nested_frame { EXCEPTION_REGISTRATION_RECORD frame; /* standard exception frame */ - EXCEPTION_RECORD *prev_rec; /* previous record to restore in thread data */ cxx_exception_frame *cxx_frame; /* frame of parent exception */ const cxx_function_descr *descr; /* descriptor of parent exception */ int trylevel; /* current try level */ - EXCEPTION_RECORD *rec; /* rec associated with frame */ + cxx_frame_info frame_info; }; /* handler for exceptions happening while calling a catch function */ @@ -362,19 +360,10 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) { struct catch_func_nested_frame *nested_frame = (struct catch_func_nested_frame *)frame; - PEXCEPTION_RECORD prev_rec = nested_frame->rec; if (rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) { - if (prev_rec->ExceptionCode == CXX_EXCEPTION) - { - void *object = (void*)prev_rec->ExceptionInformation[1]; - cxx_exception_type *info = (cxx_exception_type*) prev_rec->ExceptionInformation[2]; - if (info && info->destructor && _IsExceptionObjectToBeDestroyed(object)) - call_dtor( info->destructor, object); - } - - msvcrt_get_thread_data()->exc_record = nested_frame->prev_rec; + __CxxUnregisterExceptionObject(&nested_frame->frame_info, FALSE); return ExceptionContinueSearch; } @@ -382,6 +371,8 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG if(rec->ExceptionCode == CXX_EXCEPTION) { + PEXCEPTION_RECORD prev_rec = msvcrt_get_thread_data()->exc_record; + if((rec->ExceptionInformation[1] == 0 && rec->ExceptionInformation[2] == 0) || (prev_rec->ExceptionCode == CXX_EXCEPTION && rec->ExceptionInformation[1] == prev_rec->ExceptionInformation[1] && @@ -408,40 +399,6 @@ static DWORD catch_function_nested_handler( EXCEPTION_RECORD *rec, EXCEPTION_REG nested_frame->trylevel ); } -/********************************************************************* - * _IsExceptionObjectToBeDestroyed (MSVCR80.@) - */ -BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj) -{ - EXCEPTION_REGISTRATION_RECORD *reg = NtCurrentTeb()->Tib.ExceptionList; - frame_info *cur; - - TRACE( "%p\n", obj ); - - while (reg != (EXCEPTION_REGISTRATION_RECORD*)-1) - { - if (reg->Handler == catch_function_nested_handler) - { - EXCEPTION_RECORD *rec = ((struct catch_func_nested_frame*)reg)->rec; - - if(!(rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND)) - && rec->ExceptionCode == CXX_EXCEPTION && rec->NumberParameters == 3 - && rec->ExceptionInformation[1] == (LONG_PTR)obj) - return FALSE; - } - - reg = reg->Prev; - } - - for (cur = msvcrt_get_thread_data()->frame_info_head; cur; cur = cur->next) - { - if (cur->object == obj) - return FALSE; - } - - return TRUE; -} - /* find and call the appropriate catch block for an exception */ /* returns the address to continue execution to after the catch block was called */ static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame *frame, @@ -454,7 +411,6 @@ static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame void *addr, *object = (void *)rec->ExceptionInformation[1]; struct catch_func_nested_frame nested_frame; int trylevel = frame->trylevel; - thread_data_t *thread_data = msvcrt_get_thread_data(); DWORD save_esp = ((DWORD*)frame)[-1]; for (i = 0; i < descr->tryblock_count; i++) @@ -502,21 +458,17 @@ static inline void call_catch_block( PEXCEPTION_RECORD rec, cxx_exception_frame /* setup an exception block for nested exceptions */ nested_frame.frame.Handler = catch_function_nested_handler; - nested_frame.prev_rec = thread_data->exc_record; nested_frame.cxx_frame = frame; nested_frame.descr = descr; nested_frame.trylevel = nested_trylevel + 1; - nested_frame.rec = rec; + __CxxRegisterExceptionObject(&rec, &nested_frame.frame_info); __wine_push_frame( &nested_frame.frame ); - thread_data->exc_record = rec; addr = call_ebp_func( catchblock->handler, &frame->ebp ); - thread_data->exc_record = nested_frame.prev_rec; __wine_pop_frame( &nested_frame.frame ); ((DWORD*)frame)[-1] = save_esp; - if (info && info->destructor && _IsExceptionObjectToBeDestroyed(object)) - call_dtor( info->destructor, object ); + __CxxUnregisterExceptionObject(&nested_frame.frame_info, FALSE); TRACE( "done, continuing at %p\n", addr ); continue_after_catch( frame, addr ); diff --git a/dlls/msvcrt/except_x86_64.c b/dlls/msvcrt/except_x86_64.c index 8f0301dc570..27d0a15d889 100644 --- a/dlls/msvcrt/except_x86_64.c +++ b/dlls/msvcrt/except_x86_64.c @@ -71,15 +71,6 @@ int CDECL __CxxExceptionFilter( PEXCEPTION_POINTERS ptrs, return EXCEPTION_CONTINUE_SEARCH; } -/********************************************************************* - * _IsExceptionObjectToBeDestroyed (MSVCR80.@) - */ -BOOL __cdecl _IsExceptionObjectToBeDestroyed(const void *obj) -{ - FIXME ( "%p not implemented\n", obj ); - return FALSE; -} - /********************************************************************* * __CxxFrameHandler (MSVCRT.@) */ diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index d0893fd13c9..fafdc6b22df 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -217,6 +217,9 @@ typedef struct void *unk; } cxx_frame_info; +BOOL __cdecl __CxxRegisterExceptionObject(EXCEPTION_RECORD**, cxx_frame_info*); +void __cdecl __CxxUnregisterExceptionObject(cxx_frame_info*, BOOL); + /* TLS data */ extern DWORD msvcrt_tls_index DECLSPEC_HIDDEN; diff --git a/dlls/ucrtbase/ucrtbase.spec b/dlls/ucrtbase/ucrtbase.spec index d66148cc6ae..eb681784a9f 100644 --- a/dlls/ucrtbase/ucrtbase.spec +++ b/dlls/ucrtbase/ucrtbase.spec @@ -30,7 +30,7 @@ @ cdecl _Getdays() @ cdecl _Getmonths() @ cdecl _Gettnames() -@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr) +@ cdecl _IsExceptionObjectToBeDestroyed(ptr) @ stub _LCbuild @ stub _LCmulcc @ stub _LCmulcr diff --git a/dlls/vcruntime140/vcruntime140.spec b/dlls/vcruntime140/vcruntime140.spec index 574ce15356b..d8c33c477c3 100644 --- a/dlls/vcruntime140/vcruntime140.spec +++ b/dlls/vcruntime140/vcruntime140.spec @@ -2,7 +2,7 @@ @ stdcall _CxxThrowException(long long) ucrtbase._CxxThrowException @ cdecl -arch=i386 -norelay _EH_prolog() ucrtbase._EH_prolog @ cdecl _FindAndUnlinkFrame(ptr) ucrtbase._FindAndUnlinkFrame -@ cdecl -arch=i386,x86_64,arm _IsExceptionObjectToBeDestroyed(ptr) ucrtbase._IsExceptionObjectToBeDestroyed +@ cdecl _IsExceptionObjectToBeDestroyed(ptr) ucrtbase._IsExceptionObjectToBeDestroyed @ stub _NLG_Dispatch2 @ stub _NLG_Return @ stub _NLG_Return2