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(OUString::Concat(rUNOname.subView(
n + 1,
nPos -
n - 1)) +
"@");
82 return aRet.makeStringAndClear();
90 t_string2PtrMap::const_iterator
const iFind(m_allRTTI.find(rUNOname));
92 if (iFind != m_allRTTI.end())
101 std::pair<t_string2PtrMap::iterator, bool> insertion(
102 m_allRTTI.insert(t_string2PtrMap::value_type(rUNOname, pRTTI)));
103 assert(insertion.second &&
"### rtti insertion failed?!");
114 "### type info structure size differ!");
116 osl::MutexGuard aGuard(s_pRTTIs->
m_aMutex);
131 SAL_INFO(
"bridges",
"> freeing exception infos... <");
135 delete static_cast<RaiseInfo*
>(rEntry.second);
141#if defined _M_AMD64 || defined _M_ARM64
142 SYSTEM_INFO systemInfo;
143 GetSystemInfo(&systemInfo);
144 allocationGranularity = systemInfo.dwAllocationGranularity;
150 && (pTD->eTypeClass == typelib_TypeClass_STRUCT
151 || pTD->eTypeClass == typelib_TypeClass_EXCEPTION));
155 OUString
const& rTypeName = OUString::unacquired(&pTD->pTypeName);
156 std::unique_lock aGuard(s_pInfos->
m_aMutex);
157 t_string2PtrMap::const_iterator
const iFind(s_pInfos->
m_allRaiseInfos.find(rTypeName));
159 pRaiseInfo =
static_cast<RaiseInfo*
>(iFind->second);
164 std::pair<t_string2PtrMap::iterator, bool> insertion(s_pInfos->
m_allRaiseInfos.insert(
165 t_string2PtrMap::value_type(rTypeName,
static_cast<void*
>(pRaiseInfo))));
166 assert(insertion.second &&
"### raise info insertion failed?!");
180 TYPELIB_DANGER_GET(&pTD, pUnoExc->pType);
182 void* pCppExc = alloca(pTD->nSize);
183 ::uno_copyAndConvertData(pCppExc, pUnoExc->pData, pTD, pUno2Cpp);
185 ULONG_PTR arFilterArgs[MSVC_EH_PARAMETERS];
187 arFilterArgs[1] =
reinterpret_cast<ULONG_PTR
>(pCppExc);
189#if MSVC_EH_PARAMETERS == 4
190 arFilterArgs[3] =
reinterpret_cast<RaiseInfo*
>(arFilterArgs[2])->_codeBase;
194 ::uno_any_destruct(pUnoExc,
nullptr);
195 TYPELIB_DANGER_RELEASE(pTD);
198 RaiseException(
MSVC_EH_MAGIC_CODE, EXCEPTION_NONCONTINUABLE, MSVC_EH_PARAMETERS, arFilterArgs);
208 struct EHExceptionRecord
211 DWORD ExceptionFlags;
212 struct _EXCEPTION_RECORD* ExceptionRecord;
213 PVOID ExceptionAddress;
214 DWORD NumberParameters;
215#if MSVC_EH_PARAMETERS == 3
222 PVOID pExceptionObject;
224#if MSVC_EH_PARAMETERS == 4
225 PVOID pThrowImageBase;
230 constexpr auto PER_IS_MSVC_EH = [](EHExceptionRecord*
p) {
237 constexpr auto PER_PTHROW = [](EHExceptionRecord*
p) {
return p->params.pThrowInfo; };
239 EHExceptionRecord* pExcept;
242 pExcept = *
static_cast<EHExceptionRecord**
>(ppExcept);
243 if (PER_IS_MSVC_EH(pExcept) && PER_PTHROW(pExcept) ==
nullptr)
250 if (pPointers ==
nullptr)
251 return EXCEPTION_CONTINUE_SEARCH;
253 EXCEPTION_RECORD* pRecord = pPointers->ExceptionRecord;
257 return EXCEPTION_CONTINUE_SEARCH;
260 assert(pRecord == pPointers->ExceptionRecord);
262 if (rethrow && pRecord == pPointers->ExceptionRecord)
267 return EXCEPTION_CONTINUE_SEARCH;
269 if (pRecord->NumberParameters == MSVC_EH_PARAMETERS
270#
if MSVC_EH_PARAMETERS == 4
273 && pRecord->ExceptionInformation[1] != 0 && pRecord->ExceptionInformation[2] != 0
274#
if MSVC_EH_PARAMETERS == 4
275 && pRecord->ExceptionInformation[3] != 0
286#if MSVC_EH_PARAMETERS == 3
288 DWORD* types =
reinterpret_cast<DWORD*
>(pInfo->
_types);
292 ULONG_PTR
base = pRecord->ExceptionInformation[3];
293 DWORD* types =
reinterpret_cast<DWORD*
>(
base + pInfo->
_types);
295 if (types !=
nullptr && types[0] != 0 && types[1] != 0)
300 OUString aRTTIname(OStringToOUString(
302 RTL_TEXTENCODING_ASCII_US));
307 if (pExcTD ==
nullptr)
309 OUString sMsg =
"[mscx_uno bridge error] UNO type of C++ exception unknown: \""
310 + aUNOname +
"\", RTTI-name=\"" + aRTTIname +
"\"!";
312 uno::RuntimeException exc(sMsg);
314 pUnoExc, &exc,
cppu::UnoType<
decltype(exc)>::get().getTypeLibType(),
321 pUnoExc,
reinterpret_cast<void*
>(pRecord->ExceptionInformation[1]), pExcTD,
326 return EXCEPTION_EXECUTE_HANDLER;
333 uno::RuntimeException exc(
"[mscx_uno bridge error] unexpected C++ exception occurred!");
335 pUnoExc, &exc,
cppu::UnoType<
decltype(exc)>::get().getTypeLibType(), pCpp2Uno);
336 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()