summaryrefslogtreecommitdiff
path: root/bridges/source
diff options
context:
space:
mode:
authorJan-Marek Glogowski <glogow@fbihome.de>2020-08-02 09:02:30 +0200
committerJan-Marek Glogowski <glogow@fbihome.de>2020-09-17 00:01:21 +0200
commit8c3e6666c5ef612a20575e0ebcd5757ba21c47f8 (patch)
tree8d5e9c9368940c7b06c67f8f1875fc456c4656b6 /bridges/source
parent52ac46d798a1787baca33cdf9e1c2fd768559522 (diff)
WIN bridges: unify exception handling
This is almost just refactoring, but with classes like type_info_ and __type_info, just following the code became tendious. I tried to come up with better names... and in the end included some minor code changes described below. This patch moves the "common" code for MSVC exception handling into msvc_shared/except.cxx. Still it contains a few small ifdefs, so it doesn't feel like clean separation, but a lot of duplicate code is dropped this way. The "major" code change for amd64 is the drop of the duplicate static RTTInfo object originally used by mscx_getRTTI and mscx_getRTTI_len, by merging of both functions into the single, new get() function to use a single std::find call. Change-Id: Ib07d40e2794cde79156be3324c80ccf21a6aa8ed Reviewed-on: https://gerrit.libreoffice.org/c/core/+/102864 Tested-by: Jenkins Reviewed-by: Jan-Marek Glogowski <glogow@fbihome.de>
Diffstat (limited to 'bridges/source')
-rw-r--r--bridges/source/cpp_uno/msvc_shared/except.cxx338
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx7
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/except.cxx442
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/msci.hxx49
-rw-r--r--bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx4
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx26
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx530
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx49
-rw-r--r--bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx4
9 files changed, 407 insertions, 1042 deletions
diff --git a/bridges/source/cpp_uno/msvc_shared/except.cxx b/bridges/source/cpp_uno/msvc_shared/except.cxx
new file mode 100644
index 000000000000..af6ae6934e60
--- /dev/null
+++ b/bridges/source/cpp_uno/msvc_shared/except.cxx
@@ -0,0 +1,338 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <memory>
+
+#include <malloc.h>
+#include <new.h>
+#include <typeinfo>
+#include <signal.h>
+
+#include <rtl/alloc.h>
+#include <rtl/strbuf.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <sal/log.hxx>
+#include <osl/mutex.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <unordered_map>
+#include <except.hxx>
+#include <msvc/except.hxx>
+
+#if defined(_M_IX86)
+#include <msvc/x86.hxx>
+#elif defined(_M_AMD64)
+#include <msvc/amd64.hxx>
+#else
+#error "Unsupported machine type"
+#endif
+
+#pragma pack(push, 8)
+
+using namespace ::com::sun::star;
+
+static OUString toUNOname(OUString const& rRTTIname) throw()
+{
+ OUStringBuffer aRet(64);
+ OUString aStr(rRTTIname.copy(4, rRTTIname.getLength() - 4 - 2)); // filter .?AUzzz@yyy@xxx@@
+ sal_Int32 nPos = aStr.getLength();
+ while (nPos > 0)
+ {
+ sal_Int32 n = aStr.lastIndexOf('@', nPos);
+ aRet.append(aStr.copy(n + 1, nPos - n - 1));
+ if (n >= 0)
+ aRet.append('.');
+ nPos = n;
+ }
+ return aRet.makeStringAndClear();
+}
+
+static OUString toRTTIname(OUString const& rUNOname) throw()
+{
+ OUStringBuffer aRet(64);
+ aRet.appendAscii(".?AV"); // class ".?AV"; struct ".?AU"
+ sal_Int32 nPos = rUNOname.getLength();
+ while (nPos > 0)
+ {
+ sal_Int32 n = rUNOname.lastIndexOf('.', nPos);
+ aRet.append(rUNOname.copy(n + 1, nPos - n - 1));
+ aRet.append('@');
+ nPos = n;
+ }
+ aRet.append('@');
+ return aRet.makeStringAndClear();
+}
+
+ExceptionTypeInfo::~ExceptionTypeInfo() throw() { (void)m_data; }
+
+ExceptionTypeInfoWrapper* RTTInfos::getInfo(OUString const& rUNOname) throw()
+{
+ ExceptionTypeInfoWrapper* pRTTI;
+ t_string2PtrMap::const_iterator const iFind(m_allRTTI.find(rUNOname));
+
+ if (iFind != m_allRTTI.end())
+ pRTTI = static_cast<ExceptionTypeInfoWrapper*>(iFind->second);
+ else
+ {
+ OString aRawName(OUStringToOString(toRTTIname(rUNOname), RTL_TEXTENCODING_ASCII_US));
+ // Wrap new ExceptionTypeInfo in ExceptionTypeInfoWrapper to preserve length info
+ pRTTI = new (std::malloc(sizeof(ExceptionTypeInfoWrapper) + aRawName.getLength()))
+ ExceptionTypeInfoWrapper(nullptr, aRawName.getStr());
+
+ std::pair<t_string2PtrMap::iterator, bool> insertion(
+ m_allRTTI.insert(t_string2PtrMap::value_type(rUNOname, pRTTI)));
+ assert(insertion.second && "### rtti insertion failed?!");
+ }
+
+ return pRTTI;
+}
+
+type_info* RTTInfos::get(OUString const& rUNOname, int* len) throw()
+{
+ static RTTInfos* s_pRTTIs = new RTTInfos();
+
+ static_assert(sizeof(ExceptionTypeInfo) == sizeof(std::type_info),
+ "### type info structure size differ!");
+
+ osl::MutexGuard aGuard(s_pRTTIs->m_aMutex);
+ ExceptionTypeInfoWrapper* pETIW = s_pRTTIs->getInfo(rUNOname);
+ if (len)
+ *len = pETIW->get_type_info_size();
+ return pETIW->get_type_info();
+}
+
+RTTInfos::RTTInfos() throw() {}
+
+DWORD ExceptionInfos::allocationGranularity = 0;
+
+ExceptionInfos::ExceptionInfos() throw() {}
+
+ExceptionInfos::~ExceptionInfos() throw()
+{
+ SAL_INFO("bridges", "> freeing exception infos... <");
+
+ osl::MutexGuard aGuard(m_aMutex);
+ for (auto& rEntry : m_allRaiseInfos)
+ delete reinterpret_cast<RaiseInfo*>(rEntry.second);
+}
+
+RaiseInfo* ExceptionInfos::getRaiseInfo(typelib_TypeDescription* pTD) throw()
+{
+ static ExceptionInfos* s_pInfos = []() {
+#ifdef _M_AMD64
+ SYSTEM_INFO systemInfo;
+ GetSystemInfo(&systemInfo);
+ allocationGranularity = systemInfo.dwAllocationGranularity;
+#endif
+ return new ExceptionInfos();
+ }();
+
+ assert(pTD
+ && (pTD->eTypeClass == typelib_TypeClass_STRUCT
+ || pTD->eTypeClass == typelib_TypeClass_EXCEPTION));
+
+ RaiseInfo* pRaiseInfo;
+
+ OUString const& rTypeName = OUString::unacquired(&pTD->pTypeName);
+ osl::MutexGuard aGuard(s_pInfos->m_aMutex);
+ t_string2PtrMap::const_iterator const iFind(s_pInfos->m_allRaiseInfos.find(rTypeName));
+ if (iFind != s_pInfos->m_allRaiseInfos.end())
+ pRaiseInfo = static_cast<RaiseInfo*>(iFind->second);
+ else
+ {
+ pRaiseInfo = new RaiseInfo(pTD);
+
+ std::pair<t_string2PtrMap::iterator, bool> insertion(s_pInfos->m_allRaiseInfos.insert(
+ t_string2PtrMap::value_type(rTypeName, static_cast<void*>(pRaiseInfo))));
+ assert(insertion.second && "### raise info insertion failed?!");
+ }
+
+ return pRaiseInfo;
+}
+
+void msvc_raiseException(uno_Any* pUnoExc, uno_Mapping* pUno2Cpp)
+{
+ // no ctor/dtor in here: this leads to dtors called twice upon RaiseException()!
+ // thus this obj file will be compiled without opt, so no inlining of
+ // ExceptionInfos::getRaiseInfo()
+
+ // construct cpp exception object
+ typelib_TypeDescription* pTD = nullptr;
+ TYPELIB_DANGER_GET(&pTD, pUnoExc->pType);
+
+ void* pCppExc = alloca(pTD->nSize);
+ ::uno_copyAndConvertData(pCppExc, pUnoExc->pData, pTD, pUno2Cpp);
+
+ ULONG_PTR arFilterArgs[MSVC_EH_PARAMETERS];
+ arFilterArgs[0] = MSVC_EH_MAGIC_PARAM;
+ arFilterArgs[1] = reinterpret_cast<ULONG_PTR>(pCppExc);
+ arFilterArgs[2] = reinterpret_cast<ULONG_PTR>(ExceptionInfos::getRaiseInfo(pTD));
+#if MSVC_EH_PARAMETERS == 4
+ arFilterArgs[3] = reinterpret_cast<RaiseInfo*>(arFilterArgs[2])->_codeBase;
+#endif
+
+ // Destruct uno exception
+ ::uno_any_destruct(pUnoExc, nullptr);
+ TYPELIB_DANGER_RELEASE(pTD);
+
+ // last point to release anything not affected by stack unwinding
+ RaiseException(MSVC_EH_MAGIC_CODE, EXCEPTION_NONCONTINUABLE, MSVC_EH_PARAMETERS, arFilterArgs);
+}
+
+// This function does the same check as __CxxDetectRethrow from msvcrt (see its
+// crt/src/vcruntime/mgdframe.cpp). But it does not alter the global state, i.e. it does not
+// increment __ProcessingThrow, and so does not break following exception handling. We rely on the
+// definition of EHExceptionRecord, PER_IS_MSVC_EH and PER_PTHROW, that are current as of msvcrt
+// 2017 (14.14.26428).
+static bool DetectRethrow(void* ppExcept)
+{
+ struct EHExceptionRecord
+ {
+ DWORD ExceptionCode;
+ DWORD ExceptionFlags;
+ struct _EXCEPTION_RECORD* ExceptionRecord;
+ PVOID ExceptionAddress;
+ DWORD NumberParameters;
+#if MSVC_EH_PARAMETERS == 3
+ struct EHParameters
+#else
+ struct alignas(8)
+#endif
+ {
+ DWORD magicNumber;
+ PVOID pExceptionObject;
+ PVOID pThrowInfo;
+#if MSVC_EH_PARAMETERS == 4
+ PVOID pThrowImageBase;
+#endif
+ } params;
+ };
+
+ constexpr auto PER_IS_MSVC_EH = [](EHExceptionRecord* p) {
+ return p->ExceptionCode == MSVC_EH_MAGIC_CODE && p->NumberParameters == MSVC_EH_PARAMETERS
+ && (p->params.magicNumber == MSVC_EH_MAGIC_PARAM
+ || p->params.magicNumber == MSVC_EH_MAGIC_PARAM + 1
+ || p->params.magicNumber == MSVC_EH_MAGIC_PARAM + 2);
+ };
+
+ constexpr auto PER_PTHROW = [](EHExceptionRecord* p) { return p->params.pThrowInfo; };
+
+ EHExceptionRecord* pExcept;
+ if (!ppExcept)
+ return false;
+ pExcept = *static_cast<EHExceptionRecord**>(ppExcept);
+ if (PER_IS_MSVC_EH(pExcept) && PER_PTHROW(pExcept) == nullptr)
+ return true;
+ return false;
+}
+
+int msvc_filterCppException(EXCEPTION_POINTERS* pPointers, uno_Any* pUnoExc, uno_Mapping* pCpp2Uno)
+{
+ if (pPointers == nullptr)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ EXCEPTION_RECORD* pRecord = pPointers->ExceptionRecord;
+
+ // Handle only C++ exceptions:
+ if (pRecord == nullptr || pRecord->ExceptionCode != MSVC_EH_MAGIC_CODE)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ const bool rethrow = DetectRethrow(&pRecord);
+ assert(pRecord == pPointers->ExceptionRecord);
+
+ if (rethrow && pRecord == pPointers->ExceptionRecord)
+ pRecord = *reinterpret_cast<EXCEPTION_RECORD**>(__current_exception());
+
+ // Rethrow: handle only C++ exceptions:
+ if (pRecord == nullptr || pRecord->ExceptionCode != MSVC_EH_MAGIC_CODE)
+ return EXCEPTION_CONTINUE_SEARCH;
+
+ if (pRecord->NumberParameters == MSVC_EH_PARAMETERS
+#if MSVC_EH_PARAMETERS == 4
+ && pRecord->ExceptionInformation[0] == MSVC_EH_MAGIC_PARAM
+#endif
+ && pRecord->ExceptionInformation[1] != 0 && pRecord->ExceptionInformation[2] != 0
+#if MSVC_EH_PARAMETERS == 4
+ && pRecord->ExceptionInformation[3] != 0
+#endif
+ )
+ {
+ // ExceptionInformation[1] is the address of the thrown object
+ // (or the address of a pointer to it, in most cases when it
+ // is a C++ class, obviously).
+
+ // [2] is the pThrowInfo pointer
+ RaiseInfo* pInfo = reinterpret_cast<RaiseInfo*>(pRecord->ExceptionInformation[2]);
+
+#if MSVC_EH_PARAMETERS == 3
+ ULONG_PTR base = 0;
+ DWORD* types = reinterpret_cast<DWORD*>(pInfo->_types);
+#else
+ // [3] is the image base address which is added the 32-bit
+ // rva_t fields in throwinfo to get actual 64-bit addresses
+ ULONG_PTR base = pRecord->ExceptionInformation[3];
+ DWORD* types = reinterpret_cast<DWORD*>(base + pInfo->_types);
+#endif
+ if (types != nullptr && types[0] != 0 && types[1] != 0)
+ {
+ ExceptionType* et = reinterpret_cast<ExceptionType*>(base + types[1]);
+ if (et->_pTypeInfo != 0)
+ {
+ OUString aRTTIname(OStringToOUString(
+ reinterpret_cast<ExceptionTypeInfo*>(base + et->_pTypeInfo)->m_d_name,
+ RTL_TEXTENCODING_ASCII_US));
+ OUString aUNOname(toUNOname(aRTTIname));
+
+ typelib_TypeDescription* pExcTD = nullptr;
+ typelib_typedescription_getByName(&pExcTD, aUNOname.pData);
+ if (pExcTD == nullptr)
+ {
+ OUString sMsg = "[mscx_uno bridge error] UNO type of C++ exception unknown: \""
+ + aUNOname + "\", RTTI-name=\"" + aRTTIname + "\"!";
+
+ uno::RuntimeException exc(sMsg);
+ uno_type_any_constructAndConvert(
+ pUnoExc, &exc, cppu::UnoType<decltype(exc)>::get().getTypeLibType(),
+ pCpp2Uno);
+ }
+ else
+ {
+ // construct uno exception any
+ uno_any_constructAndConvert(
+ pUnoExc, reinterpret_cast<void*>(pRecord->ExceptionInformation[1]), pExcTD,
+ pCpp2Uno);
+ typelib_typedescription_release(pExcTD);
+ }
+
+ return EXCEPTION_EXECUTE_HANDLER;
+ }
+ }
+ }
+
+ // though this unknown exception leaks now, no user-defined exception
+ // is ever thrown through the binary C-UNO dispatcher call stack.
+ uno::RuntimeException exc("[mscx_uno bridge error] unexpected C++ exception occurred!");
+ uno_type_any_constructAndConvert(
+ pUnoExc, &exc, cppu::UnoType<decltype(exc)>::get().getTypeLibType(), pCpp2Uno);
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+#pragma pack(pop)
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
index 24a0837a6e30..22e91e4ba8d3 100644
--- a/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_intel/cpp2uno.cxx
@@ -30,7 +30,7 @@
#include "types.hxx"
#include "vtablefactory.hxx"
-#include "msci.hxx"
+#include <msvc/x86.hxx>
using namespace ::com::sun::star;
@@ -167,7 +167,7 @@ static inline typelib_TypeClass cpp2uno_call(
if (pReturnTD)
TYPELIB_DANGER_RELEASE(pReturnTD);
- CPPU_CURRENT_NAMESPACE::msci_raiseException(
+ msvc_raiseException(
&aUnoExc, pThis->getBridge()->getUno2Cpp()); // has to destruct the any
// is here for dummy
@@ -451,8 +451,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
type_info * rtti;
Rtti():
n0(0), n1(0), n2(0),
- rtti(CPPU_CURRENT_NAMESPACE::msci_getRTTI(
- "com.sun.star.uno.XInterface"))
+ rtti(RTTInfos::get("com.sun.star.uno.XInterface"))
{}
};
static Rtti rtti;
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/except.cxx b/bridges/source/cpp_uno/msvc_win32_intel/except.cxx
index 360abb038bec..d65152b29dbe 100644
--- a/bridges/source/cpp_uno/msvc_win32_intel/except.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_intel/except.cxx
@@ -31,157 +31,14 @@
#include <com/sun/star/uno/Any.hxx>
#include <unordered_map>
-#include "msci.hxx"
+#include <msvc/x86.hxx>
#include <except.hxx>
-
#pragma pack(push, 8)
-using namespace ::com::sun::star::uno;
-using namespace ::std;
-using namespace ::osl;
-
-namespace CPPU_CURRENT_NAMESPACE
-{
-
-static inline OUString toUNOname( OUString const & rRTTIname ) throw ()
-{
- OUStringBuffer aRet( 64 );
- OUString aStr( rRTTIname.copy( 4, rRTTIname.getLength()-4-2 ) ); // filter .?AUzzz@yyy@xxx@@
- sal_Int32 nPos = aStr.getLength();
- while (nPos > 0)
- {
- sal_Int32 n = aStr.lastIndexOf( '@', nPos );
- aRet.append( aStr.copy( n +1, nPos -n -1 ) );
- if (n >= 0)
- {
- aRet.append( '.' );
- }
- nPos = n;
- }
- return aRet.makeStringAndClear();
-}
-
-static inline OUString toRTTIname( OUString const & rUNOname ) throw ()
-{
- OUStringBuffer aRet( 64 );
- aRet.appendAscii( ".?AV" ); // class ".?AV"; struct ".?AU"
- sal_Int32 nPos = rUNOname.getLength();
- while (nPos > 0)
- {
- sal_Int32 n = rUNOname.lastIndexOf( '.', nPos );
- aRet.append( rUNOname.copy( n +1, nPos -n -1 ) );
- aRet.append( '@' );
- nPos = n;
- }
- aRet.append( '@' );
- return aRet.makeStringAndClear();
-}
-
-
-//#### RTTI simulation #############################################################################
-
-
-typedef std::unordered_map< OUString, void * > t_string2PtrMap;
-
-class RTTInfos
-{
- Mutex _aMutex;
- t_string2PtrMap _allRTTI;
-
- static OUString toRawName( OUString const & rUNOname ) throw ();
-public:
- type_info * getRTTI( OUString const & rUNOname ) throw ();
-
- RTTInfos();
- ~RTTInfos();
-};
-
-class __type_info
-{
- friend type_info * RTTInfos::getRTTI( OUString const & ) throw ();
- friend int msci_filterCppException(
- LPEXCEPTION_POINTERS, uno_Any *, uno_Mapping * );
-
-public:
- virtual ~__type_info() throw ();
-
- inline __type_info( void * m_data, const char * m_d_name ) throw ()
- : _m_data( m_data )
- { ::strcpy( _m_d_name, m_d_name ); } // #100211# - checked
-
-private:
- void * _m_data;
- char _m_d_name[1];
-};
-
-__type_info::~__type_info() throw ()
-{
-}
-
-type_info * RTTInfos::getRTTI( OUString const & rUNOname ) throw ()
-{
- // a must be
- static_assert(sizeof(__type_info) == sizeof(type_info), "### type info structure size differ!");
-
- MutexGuard aGuard( _aMutex );
- t_string2PtrMap::const_iterator const iFind( _allRTTI.find( rUNOname ) );
-
- // check if type is already available
- if (iFind == _allRTTI.end())
- {
- // insert new type_info
- OString aRawName( OUStringToOString( toRTTIname( rUNOname ), RTL_TEXTENCODING_ASCII_US ) );
- __type_info * pRTTI = new( std::malloc( sizeof(__type_info) + aRawName.getLength() ) )
- __type_info( NULL, aRawName.getStr() );
-
- // put into map
- pair< t_string2PtrMap::iterator, bool > insertion(
- _allRTTI.insert( t_string2PtrMap::value_type( rUNOname, pRTTI ) ) );
- assert(insertion.second && "### rtti insertion failed?!");
-
- return reinterpret_cast<type_info*>(pRTTI);
- }
- else
- {
- return reinterpret_cast<type_info*>(iFind->second);
- }
-}
-
-RTTInfos::RTTInfos() throw ()
-{
-}
-
-RTTInfos::~RTTInfos() throw ()
-{
- SAL_INFO("bridges", "> freeing generated RTTI infos... <");
-
- MutexGuard aGuard( _aMutex );
- for ( auto& rEntry : _allRTTI )
- {
- __type_info * pType = reinterpret_cast<__type_info*>(rEntry.second);
- pType->~__type_info(); // obsolete, but good style...
- std::free( pType );
- }
-}
-
+using namespace ::com::sun::star;
-//#### Exception raising ###########################################################################
-
-
-struct ObjectFunction
-{
- char somecode[12];
- typelib_TypeDescription * _pTypeDescr; // type of object
-
- inline static void * operator new ( size_t nSize );
- inline static void operator delete ( void * pMem );
-
- ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpFunc ) throw ();
- ~ObjectFunction() throw ();
-};
-
-inline void * ObjectFunction::operator new ( size_t nSize )
+void * ObjectFunction::operator new ( size_t nSize )
{
void * pMem = std::malloc( nSize );
if (pMem != 0)
@@ -195,12 +52,11 @@ inline void * ObjectFunction::operator new ( size_t nSize )
return pMem;
}
-inline void ObjectFunction::operator delete ( void * pMem )
+void ObjectFunction::operator delete ( void * pMem )
{
std::free( pMem );
}
-
ObjectFunction::ObjectFunction( typelib_TypeDescription * pTypeDescr, void * fpFunc ) throw ()
: _pTypeDescr( pTypeDescr )
{
@@ -227,14 +83,14 @@ ObjectFunction::~ObjectFunction() throw ()
static void * __cdecl __copyConstruct( void * pExcThis, void * pSource, ObjectFunction * pThis )
throw ()
{
- ::uno_copyData( pExcThis, pSource, pThis->_pTypeDescr, cpp_acquire );
+ ::uno_copyData(pExcThis, pSource, pThis->_pTypeDescr, uno::cpp_acquire);
return pExcThis;
}
static void * __cdecl __destruct( void * pExcThis, ObjectFunction * pThis )
throw ()
{
- ::uno_destructData( pExcThis, pThis->_pTypeDescr, cpp_release );
+ ::uno_destructData(pExcThis, pThis->_pTypeDescr, uno::cpp_release);
return pExcThis;
}
@@ -265,47 +121,22 @@ static __declspec(naked) void destruct() throw ()
}
}
-struct ExceptionType
+ExceptionType::ExceptionType( typelib_TypeDescription * pTypeDescr ) throw ()
+ : _n0( 0 )
+ , _n1( 0 )
+ , _n2( -1 )
+ , _n3( 0 )
+ , _n4( pTypeDescr->nSize )
+ , _pCopyCtor( new ObjectFunction( pTypeDescr, copyConstruct ) )
+ , _n5( 0 )
{
- sal_Int32 _n0;
- type_info * _pTypeInfo;
- sal_Int32 _n1, _n2, _n3, _n4;
- ObjectFunction * _pCopyCtor;
- sal_Int32 _n5;
-
- explicit ExceptionType( typelib_TypeDescription * pTypeDescr ) throw ()
- : _n0( 0 )
- , _n1( 0 )
- , _n2( -1 )
- , _n3( 0 )
- , _n4( pTypeDescr->nSize )
- , _pCopyCtor( new ObjectFunction( pTypeDescr, copyConstruct ) )
- , _n5( 0 )
- {
- _pTypeInfo = msci_getRTTI( pTypeDescr->pTypeName );
- }
-
- ~ExceptionType() throw ()
- {
- delete _pCopyCtor;
- }
-
- // Copy assignment is forbidden and not implemented.
- ExceptionType (const ExceptionType &) = delete;
- ExceptionType & operator= (const ExceptionType &) = delete;
-};
+ _pTypeInfo = RTTInfos::get(pTypeDescr->pTypeName);
+}
-struct RaiseInfo
+ExceptionType::~ExceptionType() throw ()
{
- sal_Int32 _n0;
- ObjectFunction * _pDtor;
- sal_Int32 _n2;
- void * _types;
- sal_Int32 _n3, _n4;
-
- explicit RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ();
- ~RaiseInfo() throw ();
-};
+ delete _pCopyCtor;
+}
RaiseInfo::RaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ()
: _n0( 0 )
@@ -353,241 +184,6 @@ RaiseInfo::~RaiseInfo() throw ()
delete _pDtor;
}
-class ExceptionInfos
-{
- Mutex _aMutex;
- t_string2PtrMap _allRaiseInfos;
-
-public:
- static void * getRaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ();
-
- ExceptionInfos() throw ();
- ~ExceptionInfos() throw ();
-};
-
-ExceptionInfos::ExceptionInfos() throw ()
-{
-}
-
-ExceptionInfos::~ExceptionInfos() throw ()
-{
- SAL_INFO("bridges", "> freeing exception infos... <");
-
- MutexGuard aGuard( _aMutex );
- for ( auto& rEntry : _allRaiseInfos )
- {
- delete reinterpret_cast<RaiseInfo*>(rEntry.second);
- }
-}
-
-void * ExceptionInfos::getRaiseInfo( typelib_TypeDescription * pTypeDescr ) throw ()
-{
- static ExceptionInfos* s_pInfos = new ExceptionInfos();
-
- assert( pTypeDescr &&
- (pTypeDescr->eTypeClass == typelib_TypeClass_STRUCT ||
- pTypeDescr->eTypeClass == typelib_TypeClass_EXCEPTION) );
-
- void * pRaiseInfo;
-
- OUString const & rTypeName = OUString::unacquired( &pTypeDescr->pTypeName );
- MutexGuard aGuard( s_pInfos->_aMutex );
- t_string2PtrMap::const_iterator const iFind(
- s_pInfos->_allRaiseInfos.find( rTypeName ) );
- if (iFind == s_pInfos->_allRaiseInfos.end())
- {
- pRaiseInfo = new RaiseInfo( pTypeDescr );
- // put into map
- pair< t_string2PtrMap::iterator, bool > insertion(
- s_pInfos->_allRaiseInfos.insert( t_string2PtrMap::value_type( rTypeName, pRaiseInfo ) ) );
- assert(insertion.second && "### raise info insertion failed?!");
- }
- else
- {
- // reuse existing info
- pRaiseInfo = iFind->second;
- }
-
- return pRaiseInfo;
-}
-
-
-//#### exported ####################################################################################
-
-
-type_info * msci_getRTTI( OUString const & rUNOname )
-{
- static RTTInfos* s_pRTTIs = new RTTInfos();
- return s_pRTTIs->getRTTI( rUNOname );
-}
-
-void msci_raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
-{
- // no ctor/dtor in here: this leads to dtors called twice upon RaiseException()!
- // thus this obj file will be compiled without opt, so no inlining of
- // ExceptionInfos::getRaiseInfo()
-
- // construct cpp exception object
- typelib_TypeDescription * pTypeDescr = 0;
- TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
-
- void * pCppExc = alloca( pTypeDescr->nSize );
- ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
-
- // a must be
- static_assert(sizeof(sal_Int32) == sizeof(void *),
- "### pointer size differs from sal_Int32!" );
- DWORD arFilterArgs[3];
- arFilterArgs[0] = MSVC_magic_number;
- arFilterArgs[1] = (DWORD)pCppExc;
- arFilterArgs[2] = (DWORD)ExceptionInfos::getRaiseInfo( pTypeDescr );
-
- // destruct uno exception
- ::uno_any_destruct( pUnoExc, 0 );
- TYPELIB_DANGER_RELEASE( pTypeDescr );
-
- // last point to release anything not affected by stack unwinding
- RaiseException( MSVC_ExceptionCode, EXCEPTION_NONCONTINUABLE, 3, arFilterArgs );
-}
-
-namespace
-{
-// This function does the same check as __CxxDetectRethrow from msvcrt (see its
-// crt/src/vcruntime/mgdframe.cpp). But it does not alter the global state, i.e. it does not
-// increment __ProcessingThrow, and so does not break following exception handling. We rely on the
-// definition of EHExceptionRecord, PER_IS_MSVC_EH and PER_PTHROW, that are current as of msvcrt
-// 2017 (14.14.26428).
-bool DetectRethrow(void* ppExcept)
-{
- struct EHExceptionRecord
- {
- DWORD ExceptionCode;
- DWORD ExceptionFlags;
- struct _EXCEPTION_RECORD* ExceptionRecord;
- PVOID ExceptionAddress;
- DWORD NumberParameters;
- struct EHParameters
- {
- DWORD magicNumber;
- PVOID pExceptionObject;
- PVOID pThrowInfo;
- } params;
- };
-
- constexpr auto PER_IS_MSVC_EH = [](EHExceptionRecord* p) {
- constexpr DWORD EH_EXCEPTION_NUMBER = 0xE06D7363; // The NT Exception # that msvcrt uses ('msc' | 0xE0000000)
- constexpr DWORD EH_MAGIC_NUMBER1 = 0x19930520; // latest magic # in thrown object
- constexpr DWORD EH_MAGIC_NUMBER2 = 0x19930521; // latest magic # in func info for exception specs
- constexpr DWORD EH_MAGIC_NUMBER3 = 0x19930522; // latest magic #
- constexpr DWORD EH_EXCEPTION_PARAMETERS = 3; // Number of parameters in exception record for x86
-
- return p->ExceptionCode == EH_EXCEPTION_NUMBER
- && p->NumberParameters == EH_EXCEPTION_PARAMETERS
- && (p->params.magicNumber == EH_MAGIC_NUMBER1
- || p->params.magicNumber == EH_MAGIC_NUMBER2
- || p->params.magicNumber == EH_MAGIC_NUMBER3);
- };
-
- constexpr auto PER_PTHROW = [](EHExceptionRecord* p) {
- return p->params.pThrowInfo;
- };
-
- EHExceptionRecord* pExcept;
- if (!ppExcept)
- return false;
- pExcept = *static_cast<EHExceptionRecord**>(ppExcept);
- if (PER_IS_MSVC_EH(pExcept) && PER_PTHROW(pExcept) == nullptr)
- {
- return true;
- }
- return false;
-}
-}
-
-int msci_filterCppException(
- EXCEPTION_POINTERS * pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
-{
- if (pPointers == 0)
- return EXCEPTION_CONTINUE_SEARCH;
- EXCEPTION_RECORD * pRecord = pPointers->ExceptionRecord;
- // handle only C++ exceptions:
- if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
- return EXCEPTION_CONTINUE_SEARCH;
-
- const bool rethrow = DetectRethrow(&pRecord);
- assert(pRecord == pPointers->ExceptionRecord);
-
- if (rethrow && pRecord == pPointers->ExceptionRecord)
- {
- pRecord = *reinterpret_cast< EXCEPTION_RECORD ** >(__current_exception());
- }
- // rethrow: handle only C++ exceptions:
- if (pRecord == 0 || pRecord->ExceptionCode != MSVC_ExceptionCode)
- return EXCEPTION_CONTINUE_SEARCH;
-
- if (pRecord->NumberParameters == 3 &&
-// pRecord->ExceptionInformation[ 0 ] == MSVC_magic_number &&
- pRecord->ExceptionInformation[ 1 ] != 0 &&
- pRecord->ExceptionInformation[ 2 ] != 0)
- {
- void * types = reinterpret_cast< RaiseInfo * >(
- pRecord->ExceptionInformation[ 2 ] )->_types;
- if (types != 0 && *reinterpret_cast< DWORD * >( types ) > 0) // count
- {
- ExceptionType * pType = *reinterpret_cast< ExceptionType ** >(
- reinterpret_cast< DWORD * >( types ) + 1 );
- if (pType != 0 && pType->_pTypeInfo != 0)
- {
- OUString aRTTIname(
- OStringToOUString(
- reinterpret_cast< __type_info * >(
- pType->_pTypeInfo )->_m_d_name,
- RTL_TEXTENCODING_ASCII_US ) );
- OUString aUNOname( toUNOname( aRTTIname ) );
-
- typelib_TypeDescription * pExcTypeDescr = 0;
- typelib_typedescription_getByName(
- &pExcTypeDescr, aUNOname.pData );
- if (pExcTypeDescr == 0)
- {
- OUString sMsg = "[msci_uno bridge error] UNO type of "
- "C++ exception unknown: \""
- + aUNOname + "\", RTTI-name=\""
- + aRTTIname + "\"!";
- RuntimeException exc( sMsg );
- uno_type_any_constructAndConvert(
- pUnoExc, &exc,
- cppu::UnoType<decltype(exc)>::get().getTypeLibType(), pCpp2Uno );
- // msvcr80.dll cleans up, different from former msvcrs
- // if (! rethrow):
- // though this unknown exception leaks now, no user-defined
- // exception is ever thrown through the binary C-UNO dispatcher
- // call stack.
- }
- else
- {
- // construct uno exception any
- uno_any_constructAndConvert(
- pUnoExc, (void *) pRecord->ExceptionInformation[1],
- pExcTypeDescr, pCpp2Uno );
- typelib_typedescription_release( pExcTypeDescr );
- }
-
- return EXCEPTION_EXECUTE_HANDLER;
- }
- }
- }
- // though this unknown exception leaks now, no user-defined exception
- // is ever thrown through the binary C-UNO dispatcher call stack.
- RuntimeException exc( "[msci_uno bridge error] unexpected "
- "C++ exception occurred!" );
- uno_type_any_constructAndConvert(
- pUnoExc, &exc, cppu::UnoType<decltype(exc)>::get().getTypeLibType(), pCpp2Uno );
- return EXCEPTION_EXECUTE_HANDLER;
-}
-
-}
-
#pragma pack(pop)
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx b/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx
deleted file mode 100644
index 9ee63d338656..000000000000
--- a/bridges/source/cpp_uno/msvc_win32_intel/msci.hxx
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-#pragma once
-
-#if !defined WIN32_LEAN_AND_MEAN
-# define WIN32_LEAN_AND_MEAN
-#endif
-#include <windows.h>
-
-#include "rtl/ustring.hxx"
-
-
-class type_info;
-typedef struct _uno_Any uno_Any;
-typedef struct _uno_Mapping uno_Mapping;
-
-namespace CPPU_CURRENT_NAMESPACE
-{
-
-const DWORD MSVC_ExceptionCode = 0xe06d7363;
-const long MSVC_magic_number = 0x19930520L;
-
-type_info * msci_getRTTI( OUString const & rUNOname );
-
-int msci_filterCppException(
- EXCEPTION_POINTERS * pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno );
-
-void msci_raiseException(
- uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
-
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx b/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx
index bd7e5046d209..570495294e36 100644
--- a/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_intel/uno2cpp.cxx
@@ -28,7 +28,7 @@
#include <unointerfaceproxy.hxx>
#include <vtables.hxx>
-#include "msci.hxx"
+#include <msvc/except.hxx>
using namespace ::com::sun::star;
@@ -259,7 +259,7 @@ void cpp_call(
(sal_Int32 *)pCppStackStart,
(pCppStack - pCppStackStart) / sizeof(sal_Int32) );
}
- __except (CPPU_CURRENT_NAMESPACE::msci_filterCppException(
+ __except (msvc_filterCppException(
GetExceptionInformation(),
*ppUnoExc, pThis->getBridge()->getCpp2Uno() ))
{
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
index a229db4c2ffe..6ed58ed4c9e6 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/cpp2uno.cxx
@@ -31,7 +31,7 @@
#include <vtablefactory.hxx>
#include "call.hxx"
-#include "mscx.hxx"
+#include <msvc/amd64.hxx>
using namespace ::com::sun::star;
@@ -154,7 +154,7 @@ static typelib_TypeClass cpp2uno_call(
if (pReturnTD)
TYPELIB_DANGER_RELEASE(pReturnTD);
- CPPU_CURRENT_NAMESPACE::mscx_raiseException(
+ msvc_raiseException(
&aUnoExc, pThis->getBridge()->getUno2Cpp()); // has to destruct the any
// is here for dummy
@@ -341,6 +341,7 @@ extern "C" typelib_TypeClass cpp_vtable_call(
}
int const codeSnippetSize = 48;
+typedef enum { REGPARAM_INT, REGPARAM_FLT } RegParamKind;
extern "C" char privateSnippetExecutor;
@@ -352,7 +353,7 @@ extern "C" char privateSnippetExecutor;
static unsigned char * codeSnippet(
unsigned char * code,
- CPPU_CURRENT_NAMESPACE::RegParamKind param_kind[4],
+ RegParamKind param_kind[4],
sal_Int32 nFunctionIndex,
sal_Int32 nVtableOffset )
{
@@ -360,7 +361,7 @@ static unsigned char * codeSnippet(
unsigned char *p = code;
// Spill parameters
- if ( param_kind[0] == CPPU_CURRENT_NAMESPACE::REGPARAM_INT )
+ if (param_kind[0] == REGPARAM_INT)
{
// mov qword ptr 8[rsp], rcx
*p++ = 0x48; *p++ = 0x89; *p++ = 0x4C; *p++ = 0x24; *p++ = 0x08;
@@ -370,7 +371,7 @@ static unsigned char * codeSnippet(
// movsd qword ptr 8[rsp], xmm0
*p++ = 0xF2; *p++ = 0x0F; *p++ = 0x11; *p++ = 0x44; *p++ = 0x24; *p++ = 0x08;
}
- if ( param_kind[1] == CPPU_CURRENT_NAMESPACE::REGPARAM_INT )
+ if ( param_kind[1] == REGPARAM_INT )
{
// mov qword ptr 16[rsp], rdx
*p++ = 0x48; *p++ = 0x89; *p++ = 0x54; *p++ = 0x24; *p++ = 0x10;
@@ -380,7 +381,7 @@ static unsigned char * codeSnippet(
// movsd qword ptr 16[rsp], xmm1
*p++ = 0xF2; *p++ = 0x0F; *p++ = 0x11; *p++ = 0x4C; *p++ = 0x24; *p++ = 0x10;
}
- if ( param_kind[2] == CPPU_CURRENT_NAMESPACE::REGPARAM_INT )
+ if ( param_kind[2] == REGPARAM_INT )
{
// mov qword ptr 24[rsp], r8
*p++ = 0x4C; *p++ = 0x89; *p++ = 0x44; *p++ = 0x24; *p++ = 0x18;
@@ -390,7 +391,7 @@ static unsigned char * codeSnippet(
// movsd qword ptr 24[rsp], xmm2
*p++ = 0xF2; *p++ = 0x0F; *p++ = 0x11; *p++ = 0x54; *p++ = 0x24; *p++ = 0x18;
}
- if ( param_kind[3] == CPPU_CURRENT_NAMESPACE::REGPARAM_INT )
+ if ( param_kind[3] == REGPARAM_INT )
{
// mov qword ptr 32[rsp], r9
*p++ = 0x4C;*p++ = 0x89; *p++ = 0x4C; *p++ = 0x24; *p++ = 0x20;
@@ -443,8 +444,7 @@ bridges::cpp_uno::shared::VtableFactory::initializeBlock(
type_info * rtti;
Rtti():
n0(0), n1(0), n2(0),
- rtti(CPPU_CURRENT_NAMESPACE::mscx_getRTTI(
- "com.sun.star.uno.XInterface"))
+ rtti(RTTInfos::get("com.sun.star.uno.XInterface"))
{}
};
static Rtti rtti;
@@ -471,11 +471,11 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
TYPELIB_DANGER_GET( &pTD, type->ppMembers[ member ] );
assert(pTD);
- CPPU_CURRENT_NAMESPACE::RegParamKind param_kind[4];
+ RegParamKind param_kind[4];
int nr = 0;
for (int i = 0; i < 4; ++i)
- param_kind[i] = CPPU_CURRENT_NAMESPACE::REGPARAM_INT;
+ param_kind[i] = REGPARAM_INT;
// 'this'
++nr;
@@ -498,7 +498,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
// Setter
if ( pAttrTD->eTypeClass == typelib_TypeClass_FLOAT ||
pAttrTD->eTypeClass == typelib_TypeClass_DOUBLE )
- param_kind[nr++] = CPPU_CURRENT_NAMESPACE::REGPARAM_FLT;
+ param_kind[nr++] = REGPARAM_FLT;
TYPELIB_DANGER_RELEASE( pAttrTD );
@@ -530,7 +530,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
if ( pParamTD->eTypeClass == typelib_TypeClass_FLOAT ||
pParamTD->eTypeClass == typelib_TypeClass_DOUBLE )
- param_kind[nr] = CPPU_CURRENT_NAMESPACE::REGPARAM_FLT;
+ param_kind[nr] = REGPARAM_FLT;
TYPELIB_DANGER_RELEASE( pParamTD );
}
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
index daa0426a2c17..24c3716333aa 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/except.cxx
@@ -247,199 +247,21 @@ void
#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>
#include <sal/log.hxx>
-#include <osl/mutex.hxx>
#include <com/sun/star/uno/Any.hxx>
-#include <unordered_map>
-#include "mscx.hxx"
+#include <msvc/amd64.hxx>
#include <except.hxx>
#pragma pack(push, 8)
-using namespace ::com::sun::star::uno;
-using namespace ::std;
-using namespace ::osl;
-
-namespace CPPU_CURRENT_NAMESPACE
-{
- static int mscx_getRTTI_len(OUString const & rUNOname);
-
-
-static OUString toUNOname(
- OUString const & rRTTIname )
- throw ()
-{
- OUStringBuffer aRet( 64 );
- OUString aStr( rRTTIname.copy( 4, rRTTIname.getLength()-4-2 ) ); // filter .?AUzzz@yyy@xxx@@
- sal_Int32 nPos = aStr.getLength();
- while (nPos > 0)
- {
- sal_Int32 n = aStr.lastIndexOf( '@', nPos );
- aRet.append( aStr.copy( n +1, nPos -n -1 ) );
- if (n >= 0)
- {
- aRet.append( '.' );
- }
- nPos = n;
- }
- return aRet.makeStringAndClear();
-}
-
-static OUString toRTTIname(
- OUString const & rUNOname )
- throw ()
-{
- OUStringBuffer aRet( 64 );
- aRet.append( ".?AV" ); // class ".?AV"; struct ".?AU"
- sal_Int32 nPos = rUNOname.getLength();
- while (nPos > 0)
- {
- sal_Int32 n = rUNOname.lastIndexOf( '.', nPos );
- aRet.append( rUNOname.copy( n +1, nPos -n -1 ) );
- aRet.append( '@' );
- nPos = n;
- }
- aRet.append( '@' );
- return aRet.makeStringAndClear();
-}
-
-//RTTI simulation
-
-typedef std::unordered_map< OUString, void * > t_string2PtrMap;
-
-namespace {
-
-class type_info_descriptor;
-
-class RTTInfos
-{
- Mutex _aMutex;
- t_string2PtrMap _allRTTI;
-
-public:
- type_info * getRTTI( OUString const & rUNOname ) throw ();
- int getRTTI_len(OUString const & rUNOname) throw ();
- type_info_descriptor * insert_new_type_info_descriptor(OUString const & rUNOname);
-
- RTTInfos() throw ();
-};
-class type_info_
-{
- friend type_info * RTTInfos::getRTTI( OUString const & ) throw ();
- friend int mscx::mscx_filterCppException(
- EXCEPTION_POINTERS *, uno_Any *, uno_Mapping * );
-
-public:
- virtual ~type_info_() throw ();
-
- type_info_( void * m_data, const char * m_d_name ) throw ()
- : _m_data( m_data )
- { ::strcpy( _m_d_name, m_d_name ); } // #100211# - checked
-
-private:
- void * _m_data;
- char _m_d_name[1];
-};
-
-}
-
-type_info_::~type_info_() throw ()
-{
- (void)_m_data;
-}
-
-namespace {
-
-class type_info_descriptor
-{
-private:
- int type_info_size;
- type_info_ info;
-
-public:
-
- type_info_descriptor(void * m_data, const char * m_d_name) throw ()
- : info(m_data, m_d_name)
- {
- type_info_size = sizeof(type_info_) + strlen(m_d_name);
- }
-
- type_info * get_type_info()
- {
- return reinterpret_cast<type_info *>(&info);
- }
- int get_type_info_size()
- {
- return type_info_size;
- }
-};
-
-}
-
-type_info_descriptor * RTTInfos::insert_new_type_info_descriptor(OUString const & rUNOname) {
-
- // insert new type_info
- OString aRawName(OUStringToOString(toRTTIname(rUNOname), RTL_TEXTENCODING_ASCII_US));
- type_info_descriptor * pRTTI = new(std::malloc(sizeof(type_info_descriptor) + aRawName.getLength()))
- type_info_descriptor(nullptr, aRawName.getStr());
-
- // put into map
- pair< t_string2PtrMap::iterator, bool > insertion(
- _allRTTI.insert(t_string2PtrMap::value_type(rUNOname, pRTTI)));
- assert(insertion.second && "### rtti insertion failed?!");
-
- return pRTTI;
-}
-type_info * RTTInfos::getRTTI( OUString const & rUNOname ) throw ()
-{
- // a must be
- static_assert(sizeof(type_info_) == sizeof(type_info), "### type info structure size differ!");
-
- MutexGuard aGuard( _aMutex );
- t_string2PtrMap::const_iterator const iFind( _allRTTI.find( rUNOname ) );
-
- // check if type is already available
- if (iFind == _allRTTI.end())
- {
- // Wrap new type_info_ in type_info_descriptor to preserve length info
- type_info_descriptor * pRTTI = insert_new_type_info_descriptor(rUNOname);
- return pRTTI->get_type_info();
- }
- else
- {
- return static_cast<type_info_descriptor *>(iFind->second)->get_type_info();
- }
-}
-
-int RTTInfos::getRTTI_len(OUString const & rUNOname) throw ()
-{
- MutexGuard aGuard(_aMutex);
- t_string2PtrMap::const_iterator const iFind(_allRTTI.find(rUNOname));
-
- // Wrap new type_info_ in type_info_descriptor to preserve length info
- // check if type is already available
- if (iFind == _allRTTI.end())
- {
- // Wrap new type_info_ in type_info_descriptor to preserve length info
- type_info_descriptor * pRTTI = insert_new_type_info_descriptor(rUNOname);
- return pRTTI->get_type_info_size();
- }
- else
- {
- return static_cast<type_info_descriptor *>(iFind->second)->get_type_info_size();
- }
-}
-
-RTTInfos::RTTInfos() throw ()
-{
-}
+using namespace ::com::sun::star;
static void * __cdecl copyConstruct(
void * pExcThis,
void * pSource,
typelib_TypeDescription * pTD ) throw ()
{
- ::uno_copyData( pExcThis, pSource, pTD, cpp_acquire );
+ ::uno_copyData(pExcThis, pSource, pTD, uno::cpp_acquire);
return pExcThis;
}
@@ -447,7 +269,7 @@ static void * __cdecl destruct(
void * pExcThis,
typelib_TypeDescription * pTD ) throw ()
{
- ::uno_destructData( pExcThis, pTD, cpp_release );
+ ::uno_destructData(pExcThis, pTD, uno::cpp_release);
return pExcThis;
}
@@ -493,85 +315,29 @@ static void GenerateDestructorTrampoline(
assert( p < code + codeSnippetSize );
}
-namespace {
-
-// This looks like it is the struct catchabletype above
-
-struct ExceptionType
-{
- sal_Int32 _n0; // flags
- sal_uInt32 _pTypeInfo; // typeinfo
- sal_Int32 _n1, _n2, _n3; // thiscast
- sal_Int32 _n4; // object_size
- sal_uInt32 _pCopyCtor; // copyctor
- type_info_ type_info;
-
-
- ExceptionType(
- unsigned char * pCode,
- sal_uInt64 pCodeBase,
- typelib_TypeDescription * pTD ) throw ()
- : _n0( 0 )
- , _n1( 0 )
- , _n2( -1 )
- , _n3( 0 )
- , _n4( pTD->nSize)
- , type_info(nullptr, "")
- {
- // As _n0 is always initialized to zero, that means the
- // hasvirtbase flag (see the ONTL catchabletype struct) is
- // off, and thus the copyctor is of the ctor_ptr kind.
- memcpy(static_cast<void *>(&type_info), static_cast<void *>(mscx_getRTTI(pTD->pTypeName)), mscx_getRTTI_len(pTD->pTypeName));
- _pTypeInfo = static_cast<sal_uInt32>(
- reinterpret_cast<sal_uInt64>(&type_info) - pCodeBase);
- GenerateConstructorTrampoline( pCode, pTD );
- assert(
- pCodeBase <= reinterpret_cast<sal_uInt64>(pCode)
- && (reinterpret_cast<sal_uInt64>(pCode) - pCodeBase
- < 0x100000000));
- _pCopyCtor = static_cast<sal_uInt32>(
- reinterpret_cast<sal_uInt64>(pCode) - pCodeBase);
- }
-};
-
-struct RaiseInfo;
-
-class ExceptionInfos
-{
- Mutex _aMutex;
- t_string2PtrMap _allRaiseInfos;
-
-public:
- static RaiseInfo * getRaiseInfo( typelib_TypeDescription * pTD ) throw ();
-
- static DWORD allocationGranularity;
-
- ExceptionInfos() throw ();
-};
-
-}
-
-DWORD ExceptionInfos::allocationGranularity = 0;
-
-// This corresponds to the struct throwinfo described above.
-
-namespace {
-
-struct RaiseInfo
-{
- sal_Int32 _n0;
- sal_uInt32 _pDtor;
- sal_Int32 _n2;
- sal_uInt32 _types;
-
- // Additional fields
- typelib_TypeDescription * _pTD;
- unsigned char * _code;
- sal_uInt64 _codeBase;
-
- explicit RaiseInfo(typelib_TypeDescription * pTD) throw ();
-};
-
+ExceptionType::ExceptionType(unsigned char * pCode, sal_uInt64 pCodeBase,
+ typelib_TypeDescription * pTD) throw ()
+ : _n0(0)
+ , _n1(0)
+ , _n2(-1)
+ , _n3(0)
+ , _n4(pTD->nSize)
+ , exc_type_info(nullptr, "")
+{
+ // As _n0 is always initialized to zero, that means the
+ // hasvirtbase flag (see the ONTL catchabletype struct) is
+ // off, and thus the copyctor is of the ctor_ptr kind.
+
+ int len;
+ type_info* pRTTI = RTTInfos::get(pTD->pTypeName, &len);
+
+ memcpy(static_cast<void*>(&exc_type_info), static_cast<void*>(pRTTI), len);
+ _pTypeInfo = static_cast<sal_uInt32>(reinterpret_cast<sal_uInt64>(&exc_type_info) - pCodeBase);
+ GenerateConstructorTrampoline(pCode, pTD);
+
+ assert(pCodeBase <= reinterpret_cast<sal_uInt64>(pCode)
+ && (reinterpret_cast<sal_uInt64>(pCode) - pCodeBase < 0x100000000));
+ _pCopyCtor = static_cast<sal_uInt32>(reinterpret_cast<sal_uInt64>(pCode) - pCodeBase);
}
/* Rewrite of 32-Bit-Code to work under 64 Bit:
@@ -595,6 +361,7 @@ RaiseInfo::RaiseInfo(typelib_TypeDescription * pTD)throw ()
// Count how many trampolines we need
int codeSize = codeSnippetSize;
+
// Info count
int nLen = 0;
for (pCompTD = reinterpret_cast<typelib_CompoundTypeDescription*>(pTD);
@@ -616,7 +383,8 @@ RaiseInfo::RaiseInfo(typelib_TypeDescription * pTD)throw ()
for (pCompTD = reinterpret_cast<typelib_CompoundTypeDescription*>(pTD);
pCompTD; pCompTD = pCompTD->pBaseTypeDescription)
{
- int typeInfoLen = mscx_getRTTI_len(pCompTD->aBase.pTypeName);
+ int typeInfoLen;
+ RTTInfos::get(pCompTD->aBase.pTypeName, &typeInfoLen);
// Mem has to be on 4-byte Boundary
if (typeInfoLen % 4 != 0)
{
@@ -692,244 +460,6 @@ RaiseInfo::RaiseInfo(typelib_TypeDescription * pTD)throw ()
assert(etMem + etMemOffset == pCode + totalSize);
}
-ExceptionInfos::ExceptionInfos() throw ()
-{
-}
-
-RaiseInfo * ExceptionInfos::getRaiseInfo( typelib_TypeDescription * pTD ) throw ()
-{
- static ExceptionInfos* s_pInfos = []() {
- SYSTEM_INFO systemInfo;
- GetSystemInfo(&systemInfo);
- allocationGranularity = systemInfo.dwAllocationGranularity;
-
- return new ExceptionInfos();
- }();
-
- assert( pTD &&
- (pTD->eTypeClass == typelib_TypeClass_STRUCT ||
- pTD->eTypeClass == typelib_TypeClass_EXCEPTION) );
-
- RaiseInfo * pRaiseInfo;
-
- OUString const & rTypeName = OUString::unacquired( &pTD->pTypeName );
- MutexGuard aGuard( s_pInfos->_aMutex );
- t_string2PtrMap::const_iterator const iFind(
- s_pInfos->_allRaiseInfos.find( rTypeName ) );
- if (iFind == s_pInfos->_allRaiseInfos.end())
- {
- pRaiseInfo = new RaiseInfo( pTD );
-
- // Put into map
- pair< t_string2PtrMap::iterator, bool > insertion(
- s_pInfos->_allRaiseInfos.insert( t_string2PtrMap::value_type( rTypeName, static_cast<void *>(pRaiseInfo) ) ) );
- assert(insertion.second && "### raise info insertion failed?!");
- }
- else
- {
- // Reuse existing info
- pRaiseInfo = static_cast<RaiseInfo *>(iFind->second);
- }
-
- return pRaiseInfo;
-}
-
-type_info * mscx_getRTTI(
- OUString const & rUNOname )
-{
- static RTTInfos* s_pRTTIs = new RTTInfos();
- return s_pRTTIs->getRTTI( rUNOname );
-}
-int mscx_getRTTI_len(
- OUString const & rUNOname)
-{
- static RTTInfos* s_pRTTIs = new RTTInfos();
- return s_pRTTIs->getRTTI_len(rUNOname);
-}
-
-
-void mscx_raiseException(
- uno_Any * pUnoExc,
- uno_Mapping * pUno2Cpp )
-{
- // no ctor/dtor in here: this leads to dtors called twice upon RaiseException()!
- // thus this obj file will be compiled without opt, so no inlining of
- // ExceptionInfos::getRaiseInfo()
-
- // construct cpp exception object
- typelib_TypeDescription * pTD = nullptr;
- TYPELIB_DANGER_GET( &pTD, pUnoExc->pType );
-
- void * pCppExc = alloca( pTD->nSize );
- ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTD, pUno2Cpp );
-
- ULONG_PTR arFilterArgs[4];
- arFilterArgs[0] = MSVC_magic_number;
- arFilterArgs[1] = reinterpret_cast<ULONG_PTR>(pCppExc);
- arFilterArgs[2] = reinterpret_cast<ULONG_PTR>(ExceptionInfos::getRaiseInfo( pTD ));
- arFilterArgs[3] = reinterpret_cast<RaiseInfo *>(arFilterArgs[2])->_codeBase;
-
- // Destruct uno exception
- ::uno_any_destruct( pUnoExc, nullptr );
- TYPELIB_DANGER_RELEASE( pTD );
-
- // last point to release anything not affected by stack unwinding
- RaiseException( MSVC_ExceptionCode, EXCEPTION_NONCONTINUABLE, 4, arFilterArgs);
-}
-
-namespace
-{
-// This function does the same check as __CxxDetectRethrow from msvcrt (see its
-// crt/src/vcruntime/mgdframe.cpp). But it does not alter the global state, i.e. it does not
-// increment __ProcessingThrow, and so does not break following exception handling. We rely on the
-// definition of EHExceptionRecord, PER_IS_MSVC_EH and PER_PTHROW, that are current as of msvcrt
-// 2017 (14.14.26428).
-bool DetectRethrow(void* ppExcept)
-{
- struct EHExceptionRecord
- {
- DWORD ExceptionCode;
- DWORD ExceptionFlags;
- struct _EXCEPTION_RECORD* ExceptionRecord;
- PVOID ExceptionAddress;
- DWORD NumberParameters;
- struct alignas(8)
- {
- DWORD magicNumber;
- PVOID pExceptionObject;
- PVOID pThrowInfo;
- PVOID pThrowImageBase;
- } params;
- };
-
- constexpr auto PER_IS_MSVC_EH = [](EHExceptionRecord* p) {
- constexpr DWORD EH_EXCEPTION_NUMBER = 0xE06D7363; // The NT Exception # that msvcrt uses ('msc' | 0xE0000000)
- constexpr DWORD EH_MAGIC_NUMBER1 = 0x19930520; // latest magic # in thrown object
- constexpr DWORD EH_MAGIC_NUMBER2 = 0x19930521; // latest magic # in func info for exception specs
- constexpr DWORD EH_MAGIC_NUMBER3 = 0x19930522; // latest magic #
- constexpr DWORD EH_EXCEPTION_PARAMETERS = 4; // Number of parameters in exception record for AMD64
-
- return p->ExceptionCode == EH_EXCEPTION_NUMBER
- && p->NumberParameters == EH_EXCEPTION_PARAMETERS
- && (p->params.magicNumber == EH_MAGIC_NUMBER1
- || p->params.magicNumber == EH_MAGIC_NUMBER2
- || p->params.magicNumber == EH_MAGIC_NUMBER3);
- };
-
- constexpr auto PER_PTHROW = [](EHExceptionRecord* p) {
- return p->params.pThrowInfo;
- };
-
- EHExceptionRecord* pExcept;
- if (!ppExcept)
- return false;
- pExcept = *static_cast<EHExceptionRecord**>(ppExcept);
- if (PER_IS_MSVC_EH(pExcept) && PER_PTHROW(pExcept) == nullptr)
- {
- return true;
- }
- return false;
-}
-}
-
-int mscx_filterCppException(
- EXCEPTION_POINTERS * pPointers,
- uno_Any * pUnoExc,
- uno_Mapping * pCpp2Uno )
-{
- if (pPointers == nullptr)
- return EXCEPTION_CONTINUE_SEARCH;
-
- EXCEPTION_RECORD * pRecord = pPointers->ExceptionRecord;
-
- // Handle only C++ exceptions:
- if (pRecord == nullptr || pRecord->ExceptionCode != MSVC_ExceptionCode)
- return EXCEPTION_CONTINUE_SEARCH;
-
- const bool rethrow = DetectRethrow(&pRecord);
- assert(pRecord == pPointers->ExceptionRecord);
-
- if (rethrow && pRecord == pPointers->ExceptionRecord)
- {
- pRecord = *reinterpret_cast< EXCEPTION_RECORD ** >(__current_exception());
- }
-
- // Rethrow: handle only C++ exceptions:
- if (pRecord == nullptr || pRecord->ExceptionCode != MSVC_ExceptionCode)
- return EXCEPTION_CONTINUE_SEARCH;
-
- if (pRecord->NumberParameters == 4 &&
- pRecord->ExceptionInformation[0] == MSVC_magic_number &&
- pRecord->ExceptionInformation[1] != 0 &&
- pRecord->ExceptionInformation[2] != 0 &&
- pRecord->ExceptionInformation[3] != 0)
- {
- // ExceptionInformation[1] is the address of the thrown object
- // (or the address of a pointer to it, in most cases when it
- // is a C++ class, obviously).
-
- // [2] is the throwinfo pointer
-
- // [3] is the image base address which is added the 32-bit
- // rva_t fields in throwinfo to get actual 64-bit addresses
- ULONG_PTR base = pRecord->ExceptionInformation[3];
- DWORD * types = reinterpret_cast<DWORD *>(
- base
- + (reinterpret_cast<RaiseInfo *>(pRecord->ExceptionInformation[2])
- ->_types));
- if (types != nullptr && types[0] != 0)
- {
- DWORD pType = types[1];
- ExceptionType * et
- = reinterpret_cast<ExceptionType *>(base + pType);
- if (pType != 0 && et->_pTypeInfo != 0)
- {
- OUString aRTTIname(
- OStringToOUString(
- (reinterpret_cast<type_info_ *>(base + et->_pTypeInfo)
- ->_m_d_name),
- RTL_TEXTENCODING_ASCII_US));
- OUString aUNOname( toUNOname( aRTTIname ) );
-
- typelib_TypeDescription * pExcTD = nullptr;
- typelib_typedescription_getByName(
- &pExcTD, aUNOname.pData );
- if (pExcTD == nullptr)
- {
- OUString sMsg = "[mscx_uno bridge error] UNO type of "
- "C++ exception unknown: \""
- + aUNOname + "\", RTTI-name=\""
- + aRTTIname + "\"!";
-
- RuntimeException exc( sMsg );
- uno_type_any_constructAndConvert(
- pUnoExc, &exc,
- cppu::UnoType<decltype(exc)>::get().getTypeLibType(), pCpp2Uno );
- }
- else
- {
- // construct uno exception any
- uno_any_constructAndConvert(
- pUnoExc, reinterpret_cast<void *>(pRecord->ExceptionInformation[1]),
- pExcTD, pCpp2Uno );
- typelib_typedescription_release( pExcTD );
- }
-
- return EXCEPTION_EXECUTE_HANDLER;
- }
- }
- }
- // though this unknown exception leaks now, no user-defined exception
- // is ever thrown through the binary C-UNO dispatcher call stack.
- RuntimeException exc( "[mscx_uno bridge error] unexpected "
- "C++ exception occurred!" );
- uno_type_any_constructAndConvert(
- pUnoExc, &exc, cppu::UnoType<decltype(exc)>::get().getTypeLibType(), pCpp2Uno );
- return EXCEPTION_EXECUTE_HANDLER;
-}
-
-}
-
#pragma pack(pop)
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx b/bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx
deleted file mode 100644
index 88d3dcd68950..000000000000
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/mscx.hxx
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-#pragma once
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-#include <rtl/ustring.hxx>
-
-
-class type_info;
-typedef struct _uno_Any uno_Any;
-typedef struct _uno_Mapping uno_Mapping;
-
-namespace CPPU_CURRENT_NAMESPACE
-{
-
-const DWORD MSVC_ExceptionCode = 0xe06d7363;
-const long MSVC_magic_number = 0x19930520L;
-
-typedef enum { REGPARAM_INT, REGPARAM_FLT } RegParamKind;
-
-type_info * mscx_getRTTI( OUString const & rUNOname );
-
-int mscx_filterCppException(
- EXCEPTION_POINTERS * pPointers, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno );
-
-void mscx_raiseException(
- uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
-
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx b/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx
index aa0cdda9de3d..938775629c17 100644
--- a/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/msvc_win32_x86-64/uno2cpp.cxx
@@ -31,7 +31,7 @@
#include <unointerfaceproxy.hxx>
#include <vtables.hxx>
-#include "mscx.hxx"
+#include <msvc/except.hxx>
#if OSL_DEBUG_LEVEL > 1
#include <stdio.h>
@@ -221,7 +221,7 @@ bool cpp_call(
aCppArgs[24].i, aCppArgs[25].i, aCppArgs[26].i, aCppArgs[27].i,
aCppArgs[28].i, aCppArgs[29].i, aCppArgs[30].i, aCppArgs[31].i );
}
- __except (CPPU_CURRENT_NAMESPACE::mscx_filterCppException(
+ __except (msvc_filterCppException(
GetExceptionInformation(),
*ppUnoExc, pThis->getBridge()->getCpp2Uno() ))
{