1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 // Interesting info can be found in:
33 // http://www.osronline.com/article.cfm?article=469
35 // ONTL, "Open NT Native Template Library", a C++ STL-like library
36 // that can be used even when writing Windows drivers. This is some
37 // quite badass code. The author has done impressive heavy spelunking
38 // of MSVCR structures. http://code.google.com/p/ontl/
40 // Geoff Chappell's pages:
41 // http://www.geoffchappell.com/studies/msvc/language/index.htm
43 // The below is from ONTL's ntl/nt/exception.hxx, cleaned up to keep just the _M_X64 parts:
47 /* This information until the corresponding '#endif // 0' is covered
48 * by ONTL's license, which is said to be the "zlib/libgng license"
49 * below, which as far as I see is permissive enough to allow this
50 * information to be included here in this source file. Note that no
51 * actual code from ONTL below gets compiled into the object file.
55 * Copyright (c) 2011 <copyright holders> (The ONTL main
56 * developer(s) don't tell their real name(s) on the ONTL site.)
58 * This software is provided 'as-is', without any express or implied
59 * warranty. In no event will the authors be held liable for any damages
60 * arising from the use of this software.
62 * Permission is granted to anyone to use this software for any purpose,
63 * including commercial applications, and to alter it and redistribute it
64 * freely, subject to the following restrictions:
66 * 1. The origin of this software must not be misrepresented; you must not
67 * claim that you wrote the original software. If you use this software
68 * in a product, an acknowledgment in the product documentation would be
69 * appreciated but is not required.
71 * 2. Altered source versions must be plainly marked as such, and must not be
72 * misrepresented as being the original software.
74 * 3. This notice may not be removed or altered from any source
79 typedef uint32_t rva_t
;
81 ///\note the calling convention should not matter since this has no arguments
82 typedef void generic_function_t();
84 struct ptrtomember
// _PMD
86 typedef __w64
int32_t mdiff_t
;
87 mdiff_t member_offset
;
88 mdiff_t vbtable_offset
; // -1 if not a virtual base
89 mdiff_t vdisp_offset
; // offset to the displacement value inside the vbtable
92 T
* operator()(T
* const thisptr
) const
94 uintptr_t tp
= reinterpret_cast<uintptr_t>(thisptr
);
95 uintptr_t ptr
= tp
+ member_offset
;
96 if ( vbtable_offset
!= -1 ) // !(vbtable_offset < 0)
98 ptr
+= *reinterpret_cast<mdiff_t
*>( static_cast<intptr_t>(vdisp_offset
+ *reinterpret_cast<mdiff_t
*>(tp
+ vbtable_offset
)) )
101 return reinterpret_cast<T
*>(ptr
);
107 typedef void (* dtor_ptr
)(eobject
*);
108 typedef void (* ctor_ptr
)(eobject
*, eobject
*);
109 typedef void (* ctor_ptr2
)(eobject
*, eobject
*, int);
114 /** is simple type */
115 uint32_t memmoveable
: 1;
116 /** catchable as reference only */
117 uint32_t refonly
: 1;
118 /** class with virtual base */
119 uint32_t hasvirtbase
: 1;
120 /** offset to the type descriptor */
123 /** catch type instance location within a thrown object */
124 ptrtomember thiscast
;
125 /** size of the simple type or offset into buffer of \c this pointer for catch object */
126 uint32_t object_size
;
135 #pragma pack(push, 4)
136 struct catchabletypearray
143 #pragma pack(push, 4)
146 typedef exception_disposition __cdecl
forwardcompathandler_t(...);
148 /* 0x00 */ uint32_t econst
: 1;
149 /* 0x00 */ uint32_t evolatile
: 1;
150 /* 0x00 */ uint32_t : 1;
151 /* 0x00 */ uint32_t e8
: 1;
152 /* 0x04 */ rva_t exception_dtor
;
153 /* 0x08 */ rva_t forwardcompathandler
;
154 /* 0x0C */ rva_t catchabletypearray
; ///< types able to catch the exception.
158 /// This type represents the catch clause
161 // union { uint32_t adjectives; void * ptr; };
162 uint32_t isconst
: 1;
163 uint32_t isvolatile
: 1;
164 uint32_t isunaligned
: 1;// guess it is not used on x86
165 uint32_t isreference
: 1;
170 /** offset to the type descriptor of this catch object */
171 /*0x04*/ rva_t typeinfo
; // dispType
172 /*0x08*/ int eobject_bpoffset
; // dispCatchObj
173 /** offset to the catch clause funclet */
174 /*0x0C*/ rva_t handler
; // dispOfHandler
175 /*0x10*/ uint32_t frame
; // dispFrame
178 // ___BuildCatchObject
179 /// 15.3/16 When the exception-declaration specifies a class type, a copy
180 /// constructor is used to initialize either the object declared
181 /// in the exception-declaration or,
182 /// if the exception-declaration does not specify a name,
183 /// a temporary object of that type.
184 ///\note This is the question may we optimize out the last case.
185 ///\warning If the copy constructor throws an exception, std::unexpected would be called
187 constructcatchobject(
188 cxxregistration
* cxxreg
,
189 const ehandler
* const catchblock
,
190 catchabletype
* const convertable
,
191 const dispatcher_context
* const dispatch
198 struct typeinfo_t
{ void* vtbl
; void* spare
; char name
[1]; };
199 enum catchable_info
{ cidefault
, cicomplex
, civirtual
} cinfo
= cidefault
;
201 const typeinfo_t
* ti
= catchblock
->typeinfo
? dispatch
->va
<typeinfo_t
*>(catchblock
->typeinfo
) : NULL
;
202 if(ti
&& *ti
->name
&& (catchblock
->eobject_bpoffset
|| catchblock
->ishz
)){
203 eobject
** objplace
= catchblock
->ishz
204 ? reinterpret_cast<eobject
**>(cxxreg
)
205 : reinterpret_cast<eobject
**>(catchblock
->eobject_bpoffset
+ cxxreg
->fp
.FramePointers
);
206 if(catchblock
->isreference
){
208 *objplace
= adjust_pointer(get_object(), convertable
);
209 }else if(convertable
->memmoveable
){
211 std::memcpy(objplace
, get_object(), convertable
->object_size
);
212 if(convertable
->object_size
== sizeof(void*) && *objplace
)
213 *objplace
= adjust_pointer((void*)*objplace
, convertable
);
215 // if copy ctor exists, call it; binary copy otherwise
216 if(convertable
->copyctor
){
217 cinfo
= convertable
->hasvirtbase
? civirtual
: cicomplex
;
219 std::memcpy(objplace
, (const void*)adjust_pointer(get_object(), convertable
), convertable
->object_size
);
223 // end of build helper
224 if(cinfo
!= cidefault
){
225 eobject
* objthis
= catchblock
->ishz
226 ? reinterpret_cast<eobject
*>(cxxreg
)
227 : reinterpret_cast<eobject
*>(catchblock
->eobject_bpoffset
+ cxxreg
->fp
.FramePointers
);
228 void* copyctor
= thrown_va(convertable
->copyctor
);
229 eobject
* copyarg
= adjust_pointer(get_object(), convertable
);
230 if(cinfo
== cicomplex
)
231 (eobject::ctor_ptr (copyctor
))(objthis
, copyarg
);
233 (eobject::ctor_ptr2(copyctor
))(objthis
, copyarg
, 1);
236 __except(cxxregistration::unwindfilter(static_cast<nt::ntstatus
>(_exception_code())))
238 nt::exception::inconsistency();
246 #pragma warning( disable : 4237 )
247 #include <boost/unordered_map.hpp>
248 #include <sal/config.h>
251 #include <typeinfo.h>
254 #include "rtl/alloc.h"
255 #include <rtl/instance.hxx>
256 #include "rtl/strbuf.hxx"
257 #include "rtl/ustrbuf.hxx"
259 #include "com/sun/star/uno/Any.hxx"
263 #pragma pack(push, 8)
265 using namespace ::com::sun::star::uno
;
266 using namespace ::std
;
267 using namespace ::osl
;
268 using namespace ::rtl
;
270 namespace CPPU_CURRENT_NAMESPACE
273 static inline OUString
toUNOname(
274 OUString
const & rRTTIname
)
277 OUStringBuffer
aRet( 64 );
278 OUString
aStr( rRTTIname
.copy( 4, rRTTIname
.getLength()-4-2 ) ); // filter .?AUzzz@yyy@xxx@@
279 sal_Int32 nPos
= aStr
.getLength();
282 sal_Int32 n
= aStr
.lastIndexOf( '@', nPos
);
283 aRet
.append( aStr
.copy( n
+1, nPos
-n
-1 ) );
286 aRet
.append( (sal_Unicode
)'.' );
290 return aRet
.makeStringAndClear();
293 static inline OUString
toRTTIname(
294 OUString
const & rUNOname
)
297 OUStringBuffer
aRet( 64 );
298 aRet
.appendAscii( RTL_CONSTASCII_STRINGPARAM(".?AV") ); // class ".?AV"; struct ".?AU"
299 sal_Int32 nPos
= rUNOname
.getLength();
302 sal_Int32 n
= rUNOname
.lastIndexOf( '.', nPos
);
303 aRet
.append( rUNOname
.copy( n
+1, nPos
-n
-1 ) );
304 aRet
.append( (sal_Unicode
)'@' );
307 aRet
.append( (sal_Unicode
)'@' );
308 return aRet
.makeStringAndClear();
313 typedef boost::unordered_map
< OUString
, void *, OUStringHash
, equal_to
< OUString
> > t_string2PtrMap
;
318 t_string2PtrMap _allRTTI
;
320 static OUString
toRawName( OUString
const & rUNOname
) throw ();
322 type_info
* getRTTI( OUString
const & rUNOname
) throw ();
330 friend type_info
* RTTInfos::getRTTI( OUString
const & ) throw ();
331 friend int mscx_filterCppException(
332 LPEXCEPTION_POINTERS
, uno_Any
*, uno_Mapping
* );
335 virtual ~__type_info() throw ();
337 inline __type_info( void * m_data
, const char * m_d_name
) throw ()
339 { ::strcpy( _m_d_name
, m_d_name
); } // #100211# - checked
346 __type_info::~__type_info() throw ()
350 type_info
* RTTInfos::getRTTI( OUString
const & rUNOname
) throw ()
353 OSL_ENSURE( sizeof(__type_info
) == sizeof(type_info
), "### type info structure size differ!" );
355 MutexGuard
aGuard( _aMutex
);
356 t_string2PtrMap::const_iterator
const iFind( _allRTTI
.find( rUNOname
) );
358 // check if type is already available
359 if (iFind
== _allRTTI
.end())
361 // insert new type_info
362 OString
aRawName( OUStringToOString( toRTTIname( rUNOname
), RTL_TEXTENCODING_ASCII_US
) );
363 __type_info
* pRTTI
= new( ::rtl_allocateMemory( sizeof(__type_info
) + aRawName
.getLength() ) )
364 __type_info( NULL
, aRawName
.getStr() );
367 pair
< t_string2PtrMap::iterator
, bool > insertion(
368 _allRTTI
.insert( t_string2PtrMap::value_type( rUNOname
, pRTTI
) ) );
369 OSL_ENSURE( insertion
.second
, "### rtti insertion failed?!" );
371 return (type_info
*)pRTTI
;
375 return (type_info
*)iFind
->second
;
379 RTTInfos::RTTInfos() throw ()
383 RTTInfos::~RTTInfos() throw ()
385 #if OSL_DEBUG_LEVEL > 1
386 OSL_TRACE( "> freeing generated RTTI infos... <" );
389 MutexGuard
aGuard( _aMutex
);
390 for ( t_string2PtrMap::const_iterator
iPos( _allRTTI
.begin() );
391 iPos
!= _allRTTI
.end(); ++iPos
)
393 __type_info
* pType
= (__type_info
*)iPos
->second
;
394 pType
->~__type_info(); // obsolete, but good style...
395 ::rtl_freeMemory( pType
);
399 void * __cdecl
copyConstruct(
402 typelib_TypeDescription
* pTD
) throw ()
404 ::uno_copyData( pExcThis
, pSource
, pTD
, cpp_acquire
);
408 void * __cdecl
destruct(
410 typelib_TypeDescription
* pTD
) throw ()
412 ::uno_destructData( pExcThis
, pTD
, cpp_release
);
416 const int codeSnippetSize
= 40;
418 void GenerateConstructorTrampoline(
419 unsigned char * code
,
420 typelib_TypeDescription
* pTD
) throw ()
422 unsigned char *p
= code
;
425 *p
++ = 0x49; *p
++ = 0xB8;
426 *((void **)p
) = pTD
; p
+= 8;
428 // mov r11, copyConstruct
429 *p
++ = 0x49; *p
++ = 0xBB;
430 *((void **)p
) = ©Construct
; p
+= 8;
433 *p
++ = 0x41; *p
++ = 0xFF; *p
++ = 0xE3;
435 OSL_ASSERT( p
< code
+ codeSnippetSize
);
438 void GenerateDestructorTrampoline(
439 unsigned char * code
,
440 typelib_TypeDescription
* pTD
) throw ()
442 unsigned char *p
= code
;
445 *p
++ = 0x48; *p
++ = 0xBA;
446 *((void **)p
) = pTD
; p
+= 8;
449 *p
++ = 0x49; *p
++ = 0xBB;
450 *((void **)p
) = &destruct
; p
+= 8;
453 *p
++ = 0x41; *p
++ = 0xFF; *p
++ = 0xE3;
455 OSL_ASSERT( p
< code
+ codeSnippetSize
);
458 // This looks like it is the struct catchabletype above
462 sal_Int32 _n0
; // flags
463 sal_uInt32 _pTypeInfo
; // typeinfo
464 sal_Int32 _n1
, _n2
, _n3
; // thiscast
465 sal_Int32 _n4
; // object_size
466 sal_uInt32 _pCopyCtor
; // copyctor
468 inline ExceptionType(
470 sal_uInt64 pCodeBase
,
471 typelib_TypeDescription
* pTD
) throw ()
478 // As _n0 is always initialized to zero, that means the
479 // hasvirtbase flag (see the ONTL catchabletype struct) is
480 // off, and thus the copyctor is of the ctor_ptr kind.
481 _pTypeInfo
= (sal_uInt32
) ((sal_uInt64
) mscx_getRTTI( pTD
->pTypeName
) - pCodeBase
);
482 GenerateConstructorTrampoline( pCode
, pTD
);
483 _pCopyCtor
= (sal_uInt32
) ((sal_uInt64
) pCode
- pCodeBase
);
485 inline ~ExceptionType() throw ()
495 t_string2PtrMap _allRaiseInfos
;
498 static RaiseInfo
* getRaiseInfo( typelib_TypeDescription
* pTD
) throw ();
500 static DWORD allocationGranularity
;
502 ExceptionInfos() throw ();
503 ~ExceptionInfos() throw ();
506 DWORD
ExceptionInfos::allocationGranularity
= 0;
508 // This corresponds to the struct throwinfo described above.
518 typelib_TypeDescription
* _pTD
;
520 sal_uInt64 _codeBase
;
522 RaiseInfo( typelib_TypeDescription
* pTD
) throw ();
524 ~RaiseInfo() throw ();
527 RaiseInfo::RaiseInfo( typelib_TypeDescription
* pTD
)throw ()
532 typelib_CompoundTypeDescription
* pCompTD
;
534 // Count how many trampolines we need
535 int codeSize
= codeSnippetSize
;
539 for ( pCompTD
= (typelib_CompoundTypeDescription
*)pTD
;
540 pCompTD
; pCompTD
= pCompTD
->pBaseTypeDescription
)
543 codeSize
+= codeSnippetSize
;
546 sal_uChar
* pCode
= _code
= (sal_uChar
*)::rtl_allocateMemory( codeSize
);
548 _codeBase
= (sal_uInt64
)pCode
& ~(ExceptionInfos::allocationGranularity
-1);
551 #if OSL_DEBUG_LEVEL > 0
554 VirtualProtect( pCode
, codeSize
, PAGE_EXECUTE_READWRITE
, &old_protect
);
555 OSL_ENSURE( success
, "VirtualProtect() failed!" );
557 ::typelib_typedescription_acquire( pTD
);
559 GenerateDestructorTrampoline( pCode
, pTD
);
560 _pDtor
= (sal_Int32
)((sal_uInt64
)pCode
- _codeBase
);
561 pCode
+= codeSnippetSize
;
563 // Info count accompanied by type info ptrs: type, base type, base base type, ...
564 _types
= (sal_Int32
)((sal_uInt64
)::rtl_allocateMemory( 4 + 4* nLen
) - _codeBase
);
565 *(sal_Int32
*)_types
= nLen
;
567 ExceptionType
** ppTypes
= (ExceptionType
**)((sal_Int32
*)_types
+ 1);
570 for ( pCompTD
= (typelib_CompoundTypeDescription
*)pTD
;
571 pCompTD
; pCompTD
= pCompTD
->pBaseTypeDescription
)
574 new ExceptionType( pCode
, _codeBase
,
575 (typelib_TypeDescription
*)pCompTD
);
576 pCode
+= codeSnippetSize
;
580 RaiseInfo::~RaiseInfo() throw ()
582 sal_uInt32
* pTypes
=
583 (sal_uInt32
*)(_codeBase
+ _types
) + 1;
585 for ( int nTypes
= *(sal_uInt32
*)(_codeBase
+ _types
); nTypes
--; )
587 delete (ExceptionType
*) (_codeBase
+ pTypes
[nTypes
]);
589 ::rtl_freeMemory( (void*)(_codeBase
+_types
) );
590 ::rtl_freeMemory( _code
);
592 ::typelib_typedescription_release( _pTD
);
595 ExceptionInfos::ExceptionInfos() throw ()
599 ExceptionInfos::~ExceptionInfos() throw ()
601 #if OSL_DEBUG_LEVEL > 1
602 OSL_TRACE( "> freeing exception infos... <" );
605 MutexGuard
aGuard( _aMutex
);
606 for ( t_string2PtrMap::const_iterator
iPos( _allRaiseInfos
.begin() );
607 iPos
!= _allRaiseInfos
.end(); ++iPos
)
609 delete (RaiseInfo
*)iPos
->second
;
613 RaiseInfo
* ExceptionInfos::getRaiseInfo( typelib_TypeDescription
* pTD
) throw ()
615 static ExceptionInfos
* s_pInfos
= 0;
618 MutexGuard
aGuard( Mutex::getGlobalMutex() );
621 SYSTEM_INFO systemInfo
;
622 GetSystemInfo( &systemInfo
);
623 allocationGranularity
= systemInfo
.dwAllocationGranularity
;
625 #ifdef LEAK_STATIC_DATA
626 s_pInfos
= new ExceptionInfos();
628 static ExceptionInfos s_allExceptionInfos
;
629 s_pInfos
= &s_allExceptionInfos
;
635 (pTD
->eTypeClass
== typelib_TypeClass_STRUCT
||
636 pTD
->eTypeClass
== typelib_TypeClass_EXCEPTION
) );
638 RaiseInfo
* pRaiseInfo
;
640 OUString
const & rTypeName
= *reinterpret_cast< OUString
* >( &pTD
->pTypeName
);
641 MutexGuard
aGuard( s_pInfos
->_aMutex
);
642 t_string2PtrMap::const_iterator
const iFind(
643 s_pInfos
->_allRaiseInfos
.find( rTypeName
) );
644 if (iFind
== s_pInfos
->_allRaiseInfos
.end())
646 pRaiseInfo
= new RaiseInfo( pTD
);
649 pair
< t_string2PtrMap::iterator
, bool > insertion(
650 s_pInfos
->_allRaiseInfos
.insert( t_string2PtrMap::value_type( rTypeName
, (void *)pRaiseInfo
) ) );
651 OSL_ENSURE( insertion
.second
, "### raise info insertion failed?!" );
655 // Reuse existing info
656 pRaiseInfo
= (RaiseInfo
*)iFind
->second
;
662 struct RTTISingleton
: public rtl::Static
< RTTInfos
, RTTISingleton
> {};
664 type_info
* mscx_getRTTI(
665 OUString
const & rUNOname
)
667 return RTTISingleton::get().getRTTI( rUNOname
);
670 void mscx_raiseException(
672 uno_Mapping
* pUno2Cpp
)
674 // no ctor/dtor in here: this leads to dtors called twice upon RaiseException()!
675 // thus this obj file will be compiled without opt, so no inlining of
676 // ExceptionInfos::getRaiseInfo()
678 // construct cpp exception object
679 typelib_TypeDescription
* pTD
= NULL
;
680 TYPELIB_DANGER_GET( &pTD
, pUnoExc
->pType
);
682 void * pCppExc
= alloca( pTD
->nSize
);
683 ::uno_copyAndConvertData( pCppExc
, pUnoExc
->pData
, pTD
, pUno2Cpp
);
685 ULONG_PTR arFilterArgs
[4];
686 arFilterArgs
[0] = MSVC_magic_number
;
687 arFilterArgs
[1] = (ULONG_PTR
)pCppExc
;
688 arFilterArgs
[2] = (ULONG_PTR
)ExceptionInfos::getRaiseInfo( pTD
);
689 arFilterArgs
[3] = ((RaiseInfo
*)arFilterArgs
[2])->_codeBase
;
691 // Destruct uno exception
692 ::uno_any_destruct( pUnoExc
, 0 );
693 TYPELIB_DANGER_RELEASE( pTD
);
695 // last point to release anything not affected by stack unwinding
696 RaiseException( MSVC_ExceptionCode
, EXCEPTION_NONCONTINUABLE
, 3, arFilterArgs
);
699 int mscx_filterCppException(
700 EXCEPTION_POINTERS
* pPointers
,
702 uno_Mapping
* pCpp2Uno
)
705 return EXCEPTION_CONTINUE_SEARCH
;
707 EXCEPTION_RECORD
* pRecord
= pPointers
->ExceptionRecord
;
709 // Handle only C++ exceptions:
710 if (pRecord
== 0 || pRecord
->ExceptionCode
!= MSVC_ExceptionCode
)
711 return EXCEPTION_CONTINUE_SEARCH
;
713 bool rethrow
= __CxxDetectRethrow( &pRecord
);
714 OSL_ASSERT( pRecord
== pPointers
->ExceptionRecord
);
716 if (rethrow
&& pRecord
== pPointers
->ExceptionRecord
)
718 // Hack to get msvcrt internal _curexception field:
719 pRecord
= *reinterpret_cast< EXCEPTION_RECORD
** >(
720 reinterpret_cast< char * >( __pxcptinfoptrs() ) +
721 // As long as we don't demand MSVCR source as build prerequisite,
722 // we have to code those offsets here.
724 // MSVS9/crt/src/mtdll.h:
725 // offsetof (_tiddata, _curexception) -
726 // offsetof (_tiddata, _tpxcptinfoptrs):
728 error
, this compiler version is
not supported
729 #elif _MSC_VER < 1600
732 error
, please find value
for this compiler version
737 // Rethrow: handle only C++ exceptions:
738 if (pRecord
== 0 || pRecord
->ExceptionCode
!= MSVC_ExceptionCode
)
739 return EXCEPTION_CONTINUE_SEARCH
;
741 if (pRecord
->NumberParameters
== 4 &&
742 pRecord
->ExceptionInformation
[0] == MSVC_magic_number
&&
743 pRecord
->ExceptionInformation
[1] != 0 &&
744 pRecord
->ExceptionInformation
[2] != 0 &&
745 pRecord
->ExceptionInformation
[3] != 0)
747 // ExceptionInformation[1] is the address of the thrown object
748 // (or the address of a pointer to it, in most cases when it
749 // is a C++ class, obviously).
751 // [2] is the throwinfo pointer
753 // [3] is the image base address which is added the 32-bit
754 // rva_t fields in throwinfo to get actual 64-bit addresses
757 (void *) (pRecord
->ExceptionInformation
[3] +
758 ((RaiseInfo
*)pRecord
->ExceptionInformation
[2])->_types
);
760 if (types
!= 0 && *(DWORD
*)types
> 0)
762 DWORD pType
= *((DWORD
*)types
+ 1);
764 ((ExceptionType
*)(pRecord
->ExceptionInformation
[3]+pType
))->_pTypeInfo
!= 0)
768 reinterpret_cast< __type_info
* >(
769 ((ExceptionType
*)(pRecord
->ExceptionInformation
[3]+pType
))->_pTypeInfo
)->_m_d_name
,
770 RTL_TEXTENCODING_ASCII_US
) );
771 OUString
aUNOname( toUNOname( aRTTIname
) );
773 typelib_TypeDescription
* pExcTD
= 0;
774 typelib_typedescription_getByName(
775 &pExcTD
, aUNOname
.pData
);
780 RTL_CONSTASCII_STRINGPARAM(
781 "[mscx_uno bridge error] UNO type of "
782 "C++ exception unknown: \"") );
783 buf
.append( aUNOname
);
784 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM(
785 "\", RTTI-name=\"") );
786 buf
.append( aRTTIname
);
787 buf
.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
788 RuntimeException
exc(
789 buf
.makeStringAndClear(), Reference
< XInterface
>() );
790 uno_type_any_constructAndConvert(
792 ::getCppuType( &exc
).getTypeLibType(), pCpp2Uno
);
793 #if _MSC_VER < 1400 // msvcr80.dll cleans up, different from former msvcrs
795 // though this unknown exception leaks now, no user-defined
796 // exception is ever thrown thru the binary C-UNO dispatcher
802 // construct uno exception any
803 uno_any_constructAndConvert(
804 pUnoExc
, (void *) pRecord
->ExceptionInformation
[1],
806 #if _MSC_VER < 1400 // msvcr80.dll cleans up, different from former msvcrs
810 (void *) pRecord
->ExceptionInformation
[1],
811 pExcTD
, cpp_release
);
814 typelib_typedescription_release( pExcTD
);
817 return EXCEPTION_EXECUTE_HANDLER
;
821 // though this unknown exception leaks now, no user-defined exception
822 // is ever thrown thru the binary C-UNO dispatcher call stack.
823 RuntimeException
exc(
824 OUString( RTL_CONSTASCII_USTRINGPARAM(
825 "[mscx_uno bridge error] unexpected "
826 "C++ exception occurred!") ),
827 Reference
< XInterface
>() );
828 uno_type_any_constructAndConvert(
829 pUnoExc
, &exc
, ::getCppuType( &exc
).getTypeLibType(), pCpp2Uno
);
830 return EXCEPTION_EXECUTE_HANDLER
;
837 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */