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"
54static OUString
toUNOname(OUString
const& rRTTIname)
noexcept
56 OUStringBuffer aRet(64);
57 OUString
aStr(rRTTIname.copy(4, rRTTIname.getLength() - 4 - 2));
61 sal_Int32
n =
aStr.lastIndexOf(
'@',
nPos);
62 aRet.append(
aStr.subView(
n + 1,
nPos -
n - 1));
67 return aRet.makeStringAndClear();
70static OUString
toRTTIname(OUString
const& rUNOname)
noexcept
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())
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 std::unique_lock 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(
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;
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) noexcept
static DWORD allocationGranularity
~ExceptionInfos() noexcept
ExceptionInfos() noexcept
t_string2PtrMap m_allRaiseInfos
type_info * get_type_info()
virtual ~ExceptionTypeInfo() noexcept
ExceptionTypeInfoWrapper * getInfo(OUString const &rUNOname) noexcept
static type_info * get(OUString const &rUNOname, int *len=nullptr) noexcept
void ** __current_exception()
#define SAL_INFO(area, stream)
struct _uno_Mapping uno_Mapping
struct _typelib_TypeDescription typelib_TypeDescription
constexpr DWORD MSVC_EH_MAGIC_PARAM
constexpr DWORD MSVC_EH_MAGIC_CODE
int msvc_filterCppException(EXCEPTION_POINTERS *pPointers, uno_Any *pUnoExc, uno_Mapping *pCpp2Uno)
static OUString toUNOname(OUString const &rRTTIname) noexcept
static OUString toRTTIname(OUString const &rUNOname) noexcept
void msvc_raiseException(uno_Any *pUnoExc, uno_Mapping *pUno2Cpp)
static bool DetectRethrow(void *ppExcept)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
void SAL_CALL typelib_typedescription_release(typelib_TypeDescription *pTD) SAL_THROW_EXTERN_C()
void SAL_CALL typelib_typedescription_getByName(typelib_TypeDescription **ppRet, rtl_uString *pName) SAL_THROW_EXTERN_C()