29 #include <rtl/alloc.h>
30 #include <rtl/strbuf.hxx>
31 #include <rtl/ustrbuf.hxx>
33 #include <osl/mutex.hxx>
35 #include <com/sun/star/uno/Any.hxx>
36 #include <unordered_map>
42 #elif defined(_M_AMD64)
44 #elif defined(_M_ARM64)
47 #error "Unsupported machine type"
54 static OUString
toUNOname(OUString
const& rRTTIname)
throw()
56 OUStringBuffer aRet(64);
57 OUString
aStr(rRTTIname.copy(4, rRTTIname.getLength() - 4 - 2));
58 sal_Int32
nPos = aStr.getLength();
61 sal_Int32
n = aStr.lastIndexOf(
'@', nPos);
62 aRet.append(aStr.subView(n + 1, nPos - n - 1));
67 return aRet.makeStringAndClear();
70 static OUString
toRTTIname(OUString
const& rUNOname)
throw()
72 OUStringBuffer aRet(64);
74 sal_Int32
nPos = rUNOname.getLength();
77 sal_Int32
n = rUNOname.lastIndexOf(
'.', nPos);
78 aRet.append(rUNOname.subView(n + 1, nPos - n - 1));
83 return aRet.makeStringAndClear();
91 t_string2PtrMap::const_iterator
const iFind(m_allRTTI.find(rUNOname));
93 if (iFind != m_allRTTI.end())
94 pRTTI = static_cast<ExceptionTypeInfoWrapper*>(iFind->second);
102 std::pair<t_string2PtrMap::iterator, bool> insertion(
103 m_allRTTI.insert(t_string2PtrMap::value_type(rUNOname, pRTTI)));
104 assert(insertion.second &&
"### rtti insertion failed?!");
115 "### type info structure size differ!");
117 osl::MutexGuard aGuard(s_pRTTIs->
m_aMutex);
132 SAL_INFO(
"bridges",
"> freeing exception infos... <");
136 delete static_cast<RaiseInfo*
>(rEntry.second);
142 #if defined _M_AMD64 || defined _M_ARM64
143 SYSTEM_INFO systemInfo;
144 GetSystemInfo(&systemInfo);
145 allocationGranularity = systemInfo.dwAllocationGranularity;
151 && (pTD->eTypeClass == typelib_TypeClass_STRUCT
152 || pTD->eTypeClass == typelib_TypeClass_EXCEPTION));
156 OUString
const& rTypeName = OUString::unacquired(&pTD->pTypeName);
157 osl::MutexGuard aGuard(s_pInfos->
m_aMutex);
158 t_string2PtrMap::const_iterator
const iFind(s_pInfos->
m_allRaiseInfos.find(rTypeName));
160 pRaiseInfo = static_cast<RaiseInfo*>(iFind->second);
165 std::pair<t_string2PtrMap::iterator, bool> insertion(s_pInfos->
m_allRaiseInfos.insert(
166 t_string2PtrMap::value_type(rTypeName, static_cast<void*>(pRaiseInfo))));
167 assert(insertion.second &&
"### raise info insertion failed?!");
181 TYPELIB_DANGER_GET(&pTD, pUnoExc->pType);
183 void* pCppExc = alloca(pTD->nSize);
184 ::uno_copyAndConvertData(pCppExc, pUnoExc->pData, pTD, pUno2Cpp);
186 ULONG_PTR arFilterArgs[MSVC_EH_PARAMETERS];
188 arFilterArgs[1] =
reinterpret_cast<ULONG_PTR
>(pCppExc);
190 #if MSVC_EH_PARAMETERS == 4
191 arFilterArgs[3] =
reinterpret_cast<RaiseInfo*
>(arFilterArgs[2])->_codeBase;
195 ::uno_any_destruct(pUnoExc,
nullptr);
196 TYPELIB_DANGER_RELEASE(pTD);
199 RaiseException(
MSVC_EH_MAGIC_CODE, EXCEPTION_NONCONTINUABLE, MSVC_EH_PARAMETERS, arFilterArgs);
209 struct EHExceptionRecord
212 DWORD ExceptionFlags;
213 struct _EXCEPTION_RECORD* ExceptionRecord;
214 PVOID ExceptionAddress;
215 DWORD NumberParameters;
216 #if MSVC_EH_PARAMETERS == 3
223 PVOID pExceptionObject;
225 #if MSVC_EH_PARAMETERS == 4
226 PVOID pThrowImageBase;
231 constexpr
auto PER_IS_MSVC_EH = [](EHExceptionRecord*
p) {
238 constexpr
auto PER_PTHROW = [](EHExceptionRecord*
p) {
return p->params.pThrowInfo; };
240 EHExceptionRecord* pExcept;
243 pExcept = *
static_cast<EHExceptionRecord**
>(ppExcept);
244 if (PER_IS_MSVC_EH(pExcept) && PER_PTHROW(pExcept) ==
nullptr)
251 if (pPointers ==
nullptr)
252 return EXCEPTION_CONTINUE_SEARCH;
254 EXCEPTION_RECORD* pRecord = pPointers->ExceptionRecord;
258 return EXCEPTION_CONTINUE_SEARCH;
261 assert(pRecord == pPointers->ExceptionRecord);
263 if (rethrow && pRecord == pPointers->ExceptionRecord)
268 return EXCEPTION_CONTINUE_SEARCH;
270 if (pRecord->NumberParameters == MSVC_EH_PARAMETERS
271 #
if MSVC_EH_PARAMETERS == 4
274 && pRecord->ExceptionInformation[1] != 0 && pRecord->ExceptionInformation[2] != 0
275 #
if MSVC_EH_PARAMETERS == 4
276 && pRecord->ExceptionInformation[3] != 0
287 #if MSVC_EH_PARAMETERS == 3
289 DWORD* types =
reinterpret_cast<DWORD*
>(pInfo->
_types);
293 ULONG_PTR base = pRecord->ExceptionInformation[3];
294 DWORD* types =
reinterpret_cast<DWORD*
>(base + pInfo->
_types);
296 if (types !=
nullptr && types[0] != 0 && types[1] != 0)
301 OUString aRTTIname(OStringToOUString(
302 reinterpret_cast<ExceptionTypeInfo*>(base + et->
_pTypeInfo)->m_d_name,
303 RTL_TEXTENCODING_ASCII_US));
308 if (pExcTD ==
nullptr)
310 OUString sMsg =
"[mscx_uno bridge error] UNO type of C++ exception unknown: \""
311 + aUNOname +
"\", RTTI-name=\"" + aRTTIname +
"\"!";
313 uno::RuntimeException exc(sMsg);
315 pUnoExc, &exc,
cppu::UnoType<decltype(exc)>::
get().getTypeLibType(),
322 pUnoExc, reinterpret_cast<void*>(pRecord->ExceptionInformation[1]), pExcTD,
327 return EXCEPTION_EXECUTE_HANDLER;
334 uno::RuntimeException exc(
"[mscx_uno bridge error] unexpected C++ exception occurred!");
336 pUnoExc, &exc,
cppu::UnoType<decltype(exc)>::
get().getTypeLibType(), pCpp2Uno);
337 return EXCEPTION_EXECUTE_HANDLER;
static DWORD allocationGranularity
type_info * get_type_info()
void ** __current_exception()
struct _uno_Mapping uno_Mapping
int msvc_filterCppException(EXCEPTION_POINTERS *pPointers, uno_Any *pUnoExc, uno_Mapping *pCpp2Uno)
ExceptionTypeInfoWrapper * getInfo(OUString const &rUNOname)
void SAL_CALL uno_type_any_constructAndConvert(uno_Any *pDest, void *pSource, typelib_TypeDescriptionReference *pType, uno_Mapping *mapping) SAL_THROW_EXTERN_C()
void SAL_CALL uno_any_constructAndConvert(uno_Any *pDest, void *pSource, typelib_TypeDescription *pTypeDescr, uno_Mapping *mapping) SAL_THROW_EXTERN_C()
static RaiseInfo * getRaiseInfo(typelib_TypeDescription *pTD)
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
void msvc_raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
static OUString toUNOname(OUString const &rRTTIname)
constexpr DWORD MSVC_EH_MAGIC_CODE
struct _typelib_TypeDescription typelib_TypeDescription
void SAL_CALL typelib_typedescription_release(typelib_TypeDescription *pTD) SAL_THROW_EXTERN_C()
static OUString toRTTIname(OUString const &rUNOname)
void SAL_CALL typelib_typedescription_getByName(typelib_TypeDescription **ppRet, rtl_uString *pName) SAL_THROW_EXTERN_C()
t_string2PtrMap m_allRaiseInfos
static bool DetectRethrow(void *ppExcept)
#define SAL_INFO(area, stream)
static type_info * get(OUString const &rUNOname, int *len=nullptr)
constexpr DWORD MSVC_EH_MAGIC_PARAM
virtual ~ExceptionTypeInfo()