diff options
Diffstat (limited to '')
-rw-r--r-- | bridges/inc/bridge.hxx | 116 | ||||
-rw-r--r-- | bridges/inc/cppinterfaceproxy.hxx | 98 | ||||
-rw-r--r-- | bridges/inc/except.hxx | 36 | ||||
-rw-r--r-- | bridges/inc/msvc/amd64.hxx | 59 | ||||
-rw-r--r-- | bridges/inc/msvc/arm64.hxx | 59 | ||||
-rw-r--r-- | bridges/inc/msvc/cpp2uno.hxx | 31 | ||||
-rw-r--r-- | bridges/inc/msvc/except.hxx | 116 | ||||
-rw-r--r-- | bridges/inc/msvc/x86.hxx | 68 | ||||
-rw-r--r-- | bridges/inc/types.hxx | 67 | ||||
-rw-r--r-- | bridges/inc/unointerfaceproxy.hxx | 105 | ||||
-rw-r--r-- | bridges/inc/vtablefactory.hxx | 221 | ||||
-rw-r--r-- | bridges/inc/vtables.hxx | 97 |
12 files changed, 1073 insertions, 0 deletions
diff --git a/bridges/inc/bridge.hxx b/bridges/inc/bridge.hxx new file mode 100644 index 000000000..0a6da7885 --- /dev/null +++ b/bridges/inc/bridge.hxx @@ -0,0 +1,116 @@ +/* -*- 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 + +#include <sal/config.h> + +#include <atomic> +#include <cstddef> + +#include <sal/types.h> +#include <typelib/typedescription.h> +#include <uno/environment.h> +#include <uno/mapping.h> + +namespace bridges::cpp_uno::shared { + +// private: +extern "C" void freeMapping(uno_Mapping *); + +// private: +extern "C" void acquireMapping(uno_Mapping *); + +// private: +extern "C" void releaseMapping(uno_Mapping *); + +// private: +extern "C" void cpp2unoMapping( + uno_Mapping *, void **, void *, typelib_InterfaceTypeDescription *); + +// private: +extern "C" void uno2cppMapping( + uno_Mapping *, void **, void *, typelib_InterfaceTypeDescription *); + +/** + * Holding environments and mappings. + */ +class Bridge { +public: + // Interface for generic/component.cxx: + + static uno_Mapping * createMapping( + uno_ExtEnvironment * pCppEnv, uno_ExtEnvironment * pUnoEnv, + bool bExportCpp2Uno); + + // Interface for Cpp/UnoInterfaceProxy: + + void acquire(); + void release(); + + // Interface for individual CPP--UNO bridges: + + uno_ExtEnvironment * getCppEnv() { return pCppEnv; } + uno_ExtEnvironment * getUnoEnv() { return pUnoEnv; } + + uno_Mapping * getCpp2Uno() { return &aCpp2Uno; } + uno_Mapping * getUno2Cpp() { return &aUno2Cpp; } + +private: + Bridge(Bridge const &) = delete; + Bridge& operator =(const Bridge&) = delete; + + Bridge( + uno_ExtEnvironment * pCppEnv_, uno_ExtEnvironment * pUnoEnv_, + bool bExportCpp2Uno_); + + ~Bridge(); + + struct Mapping: public uno_Mapping { + Bridge * pBridge; + }; + + std::atomic<std::size_t> nRef; + + uno_ExtEnvironment * pCppEnv; + uno_ExtEnvironment * pUnoEnv; + + Mapping aCpp2Uno; + Mapping aUno2Cpp; + + bool bExportCpp2Uno; + + friend void freeMapping(uno_Mapping * pMapping); + + friend void acquireMapping(uno_Mapping * pMapping); + + friend void releaseMapping(uno_Mapping * pMapping); + + friend void cpp2unoMapping( + uno_Mapping * pMapping, void ** ppUnoI, void * pCppI, + typelib_InterfaceTypeDescription * pTypeDescr); + + friend void uno2cppMapping( + uno_Mapping * pMapping, void ** ppCppI, void * pUnoI, + typelib_InterfaceTypeDescription * pTypeDescr); +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/inc/cppinterfaceproxy.hxx b/bridges/inc/cppinterfaceproxy.hxx new file mode 100644 index 000000000..5b5c85dc7 --- /dev/null +++ b/bridges/inc/cppinterfaceproxy.hxx @@ -0,0 +1,98 @@ +/* -*- 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 + +#include <sal/config.h> + +#include <atomic> +#include <cstddef> + +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <typelib/typedescription.h> +#include <uno/dispatcher.h> +#include <uno/environment.h> +#include "vtablefactory.hxx" + +namespace com::sun::star::uno { class XInterface; } + +namespace bridges::cpp_uno::shared { + +class Bridge; + +extern "C" void freeCppInterfaceProxy( + uno_ExtEnvironment * pEnv, void * pInterface); + +/** + * A cpp proxy wrapping a uno interface. + */ +class CppInterfaceProxy { +public: + // Interface for Bridge: + + static com::sun::star::uno::XInterface * create( + Bridge * pBridge, uno_Interface * pUnoI, + typelib_InterfaceTypeDescription * pTypeDescr, + OUString const & rOId); + + // Interface for individual CPP--UNO bridges: + + Bridge * getBridge() { return pBridge; } + uno_Interface * getUnoI() { return pUnoI; } + typelib_InterfaceTypeDescription * getTypeDescr() { return pTypeDescr; } + const OUString& getOid() const { return oid; } + + // non virtual methods called on incoming vtable calls #1, #2 + void acquireProxy(); + void releaseProxy(); + + static CppInterfaceProxy * castInterfaceToProxy(void * pInterface); + +private: + CppInterfaceProxy(CppInterfaceProxy const &) = delete; + CppInterfaceProxy& operator =(const CppInterfaceProxy&) = delete; + + CppInterfaceProxy( + Bridge * pBridge_, uno_Interface * pUnoI_, + typelib_InterfaceTypeDescription * pTypeDescr_, + OUString aOId_); + + ~CppInterfaceProxy(); + + static com::sun::star::uno::XInterface * castProxyToInterface( + CppInterfaceProxy * pProxy); + + std::atomic<std::size_t> nRef; + Bridge * pBridge; + + // mapping information + uno_Interface * pUnoI; // wrapped interface + typelib_InterfaceTypeDescription * pTypeDescr; + OUString oid; + + VtableFactory::Slot * vtables[1] = {}; + + friend void freeCppInterfaceProxy( + uno_ExtEnvironment * pEnv, void * pInterface); +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/inc/except.hxx b/bridges/inc/except.hxx new file mode 100644 index 000000000..7d7db224f --- /dev/null +++ b/bridges/inc/except.hxx @@ -0,0 +1,36 @@ +/* -*- 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 + +// extern "C" void** __cdecl __current_exception() +// is defined in MSVS14.0/VC/crt/src/vcruntime/frame.cpp: +// return &__vcrt_getptd()->_curexception; +// +// __vcrt_getptd is defined in vcruntime_internal.h: +//typedef struct __vcrt_ptd +//{ +// // C++ Exception Handling (EH) state +// unsigned long _NLG_dwCode; // Required by NLG routines +//[...] +//void* _curexception; // current exception +//[...] +extern "C" void** __current_exception(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/inc/msvc/amd64.hxx b/bridges/inc/msvc/amd64.hxx new file mode 100644 index 000000000..eea88ea96 --- /dev/null +++ b/bridges/inc/msvc/amd64.hxx @@ -0,0 +1,59 @@ +/* -*- 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 + +#include <msvc/except.hxx> + +#pragma pack(push, 8) + +struct ExceptionType final +{ + sal_Int32 _n0; // flags + sal_uInt32 _pTypeInfo; // typeinfo + sal_Int32 _n1, _n2, _n3; // thiscast + sal_Int32 _n4; // object_size + sal_uInt32 _pCopyCtor; // copyctor + ExceptionTypeInfo exc_type_info; + + explicit ExceptionType(unsigned char* pCode, sal_uInt64 pCodeBase, + typelib_TypeDescription* pTD) noexcept; + + ExceptionType(const ExceptionType&) = delete; + ExceptionType& operator=(const ExceptionType&) = delete; +}; + +struct RaiseInfo final +{ + 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) noexcept; +}; + +#pragma pack(pop) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/inc/msvc/arm64.hxx b/bridges/inc/msvc/arm64.hxx new file mode 100644 index 000000000..fb095446b --- /dev/null +++ b/bridges/inc/msvc/arm64.hxx @@ -0,0 +1,59 @@ +/* -*- 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 + +#include <msvc/except.hxx> + +#pragma pack(push, 8) + +struct ExceptionType final +{ + sal_Int32 _n0; // flags + sal_uInt32 _pTypeInfo; // typeinfo + sal_Int32 _n1, _n2, _n3; // thiscast + sal_Int32 _n4; // object_size + sal_uInt32 _pCopyCtor; // copyctor + ExceptionTypeInfo exc_type_info; + + explicit ExceptionType(unsigned char* pCode, sal_uInt64 pCodeBase, + typelib_TypeDescription* pTD) throw(); + + ExceptionType(const ExceptionType&) = delete; + ExceptionType& operator=(const ExceptionType&) = delete; +}; + +struct RaiseInfo final +{ + 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(); +}; + +#pragma pack(pop) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/inc/msvc/cpp2uno.hxx b/bridges/inc/msvc/cpp2uno.hxx new file mode 100644 index 000000000..47091ed3b --- /dev/null +++ b/bridges/inc/msvc/cpp2uno.hxx @@ -0,0 +1,31 @@ +/* -*- 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 <sal/config.h> +#include <typelib/typeclass.h> + +typelib_TypeClass __cdecl cpp_mediate(void** pCallStack, sal_Int32 nFunctionIndex, + sal_Int32 nVtableOffset, sal_Int64* const pRegisterReturn); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/inc/msvc/except.hxx b/bridges/inc/msvc/except.hxx new file mode 100644 index 000000000..798fc44f1 --- /dev/null +++ b/bridges/inc/msvc/except.hxx @@ -0,0 +1,116 @@ +/* -*- 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 <sal/config.h> +#include <rtl/ustrbuf.hxx> +#include <osl/mutex.hxx> + +#include <unordered_map> + +typedef struct _uno_Any uno_Any; +typedef struct _uno_Mapping uno_Mapping; + +int msvc_filterCppException(EXCEPTION_POINTERS*, uno_Any*, uno_Mapping*); +void msvc_raiseException(uno_Any*, uno_Mapping*); + +constexpr DWORD MSVC_EH_MAGIC_PARAM = 0x19930520; +// The NT Exception code that msvcrt uses ('msc' | 0xE0000000) +constexpr DWORD MSVC_EH_MAGIC_CODE = 0xE06D7363; + +#if defined(_M_IX86) +#define MSVC_EH_PARAMETERS 3 // Number of parameters in exception record for x86 +#elif defined(_M_AMD64) || defined(_M_ARM64) +#define MSVC_EH_PARAMETERS 4 // Number of parameters in exception record for AMD64 +#else +#error "Unsupported machine type" +#endif + +class type_info; +struct RaiseInfo; +typedef std::unordered_map<OUString, void*> t_string2PtrMap; +typedef struct _typelib_TypeDescription typelib_TypeDescription; + +// fixed class, because sizeof(ExceptionTypeInfo) must be sizeof(type_info) +// this is tested by a static_assert, so can't break. +class ExceptionTypeInfo final +{ + friend int msvc_filterCppException(EXCEPTION_POINTERS*, uno_Any*, uno_Mapping*); + + void* m_data; + char m_d_name[1]; + +public: + explicit ExceptionTypeInfo(void* data, const char* d_name) noexcept + : m_data(data) + { + ::strcpy(m_d_name, d_name); // #100211# - checked + } + virtual ~ExceptionTypeInfo() noexcept; +}; + +class ExceptionTypeInfoWrapper final +{ + int type_info_size; + ExceptionTypeInfo info; + +public: + explicit ExceptionTypeInfoWrapper(void* m_data, const char* m_d_name) noexcept + : info(m_data, m_d_name) + { + type_info_size = sizeof(ExceptionTypeInfo) + strlen(m_d_name); + } + + type_info* get_type_info() { return reinterpret_cast<type_info*>(&info); } + int get_type_info_size() { return type_info_size; } +}; + +class RTTInfos final +{ + osl::Mutex m_aMutex; + t_string2PtrMap m_allRTTI; + + RTTInfos() noexcept; + ExceptionTypeInfoWrapper* getInfo(OUString const& rUNOname) noexcept; + +public: + ~RTTInfos(); + + static type_info* get(OUString const& rUNOname, int* len = nullptr) noexcept; +}; + +class ExceptionInfos final +{ + osl::Mutex m_aMutex; + t_string2PtrMap m_allRaiseInfos; + +public: + static RaiseInfo* getRaiseInfo(typelib_TypeDescription* pTD) noexcept; + + static DWORD allocationGranularity; + + ExceptionInfos() noexcept; + ~ExceptionInfos() noexcept; +}; + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/inc/msvc/x86.hxx b/bridges/inc/msvc/x86.hxx new file mode 100644 index 000000000..24c55499f --- /dev/null +++ b/bridges/inc/msvc/x86.hxx @@ -0,0 +1,68 @@ +/* -*- 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 + +#include <msvc/except.hxx> + +#pragma pack(push, 8) + +struct ObjectFunction final +{ + 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(); +}; + +struct ExceptionType final +{ + sal_Int32 _n0; + type_info* _pTypeInfo; + sal_Int32 _n1, _n2, _n3, _n4; + ObjectFunction* _pCopyCtor; + sal_Int32 _n5; + + explicit ExceptionType(typelib_TypeDescription* pTypeDescr) throw(); + ~ExceptionType() throw(); + + // Copy assignment is forbidden and not implemented. + ExceptionType(const ExceptionType&) = delete; + ExceptionType& operator=(const ExceptionType&) = delete; +}; + +struct RaiseInfo final +{ + sal_Int32 _n0; + ObjectFunction* _pDtor; + sal_Int32 _n2; + void* _types; + sal_Int32 _n3, _n4; + + explicit RaiseInfo(typelib_TypeDescription* pTypeDescr) throw(); + ~RaiseInfo() throw(); +}; + +#pragma pack(pop) + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/inc/types.hxx b/bridges/inc/types.hxx new file mode 100644 index 000000000..597d55909 --- /dev/null +++ b/bridges/inc/types.hxx @@ -0,0 +1,67 @@ +/* -*- 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 + +#include <typelib/typeclass.h> +#include <typelib/typedescription.h> + +namespace bridges::cpp_uno::shared +{ +/** + * Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT, + * UNSIGNED SHORT, LONG, UNSIGNED LONG, HYPER, UNSIGNED HYPER, FLOAT, DOUBLE, + * CHAR, or an enum type). + * + * @param typeClass a type class + * @return true if the given type is "simple" + */ +bool isSimpleType(typelib_TypeClass typeClass); + +/** + * Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT, + * UNSIGNED SHORT, LONG, UNSIGNED LONG, HYPER, UNSIGNED HYPER, FLOAT, DOUBLE, + * CHAR, or an enum type). + * + * @param type a non-null pointer to a type description reference + * @return true if the given type is "simple" + */ +bool isSimpleType(typelib_TypeDescriptionReference const* type); + +/** + * Determines whether a type is a "simple" type (VOID, BOOLEAN, BYTE, SHORT, + * UNSIGNED SHORT, LONG, UNSIGNED LONG, HYPER, UNSIGNED HYPER, FLOAT, DOUBLE, + * CHAR, or an enum type). + * + * @param type a non-null pointer to a type description + * @return true if the given type is "simple" + */ +bool isSimpleType(typelib_TypeDescription const* type); + +/** + * Determines whether a type relates to an interface type (is itself an + * interface type, or might contain entities of interface type). + * + * @param type a non-null pointer to a type description + * @return true if the given type relates to an interface type + */ +bool relatesToInterfaceType(typelib_TypeDescription const* type); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/inc/unointerfaceproxy.hxx b/bridges/inc/unointerfaceproxy.hxx new file mode 100644 index 000000000..d20a7c354 --- /dev/null +++ b/bridges/inc/unointerfaceproxy.hxx @@ -0,0 +1,105 @@ +/* -*- 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 + +#include <sal/config.h> + +#include <atomic> +#include <cstddef> + +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <typelib/typedescription.h> +#include <uno/dispatcher.h> +#include <uno/environment.h> + +namespace com::sun::star::uno { class XInterface; } + +namespace bridges::cpp_uno::shared { + +class Bridge; + +extern "C" void freeUnoInterfaceProxy( + uno_ExtEnvironment * pEnv, void * pProxy); + +// private: +extern "C" void unoInterfaceProxyDispatch( + uno_Interface * pUnoI, typelib_TypeDescription const * pMemberDescr, + void * pReturn, void * pArgs[], uno_Any ** ppException); + // this function is not defined in the generic part, but instead has to be + // defined individually for each CPP--UNO bridge + +// private: +extern "C" void acquireProxy(uno_Interface *); + +// private: +extern "C" void releaseProxy(uno_Interface *); + +/** + * A uno proxy wrapping a cpp interface. + */ +class UnoInterfaceProxy: public uno_Interface { +public: + // Interface for Bridge: + + static UnoInterfaceProxy * create( + Bridge * pBridge, com::sun::star::uno::XInterface * pCppI, + typelib_InterfaceTypeDescription * pTypeDescr, + OUString const & rOId); + + // Interface for individual CPP--UNO bridges: + + Bridge * getBridge() { return pBridge; } + com::sun::star::uno::XInterface * getCppI() { return pCppI; } + +private: + UnoInterfaceProxy(UnoInterfaceProxy const &) = delete; + UnoInterfaceProxy& operator =(const UnoInterfaceProxy&) = delete; + + UnoInterfaceProxy( + Bridge * pBridge_, com::sun::star::uno::XInterface * pCppI_, + typelib_InterfaceTypeDescription * pTypeDescr_, + OUString aOId_); + + ~UnoInterfaceProxy(); + + std::atomic<std::size_t> nRef; + Bridge * pBridge; + + // mapping information + com::sun::star::uno::XInterface * pCppI; // wrapped interface + typelib_InterfaceTypeDescription * pTypeDescr; + OUString oid; + + friend void freeUnoInterfaceProxy( + uno_ExtEnvironment * pEnv, void * pProxy); + + friend void unoInterfaceProxyDispatch( + uno_Interface * pUnoI, typelib_TypeDescription const * pMemberDescr, + void * pReturn, void * pArgs[], uno_Any ** ppException); + + friend void acquireProxy(uno_Interface * pUnoI); + + friend void releaseProxy(uno_Interface * pUnoI); +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/inc/vtablefactory.hxx b/bridges/inc/vtablefactory.hxx new file mode 100644 index 000000000..9afcb8370 --- /dev/null +++ b/bridges/inc/vtablefactory.hxx @@ -0,0 +1,221 @@ +/* -*- 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 + +#include <rtl/alloc.h> +#include <rtl/ustring.hxx> +#include <sal/types.h> +#include <typelib/typedescription.hxx> + +#include <memory> +#include <mutex> +#include <unordered_map> + +/*See: http://people.redhat.com/drepper/selinux-mem.html*/ +#if defined(LINUX) || defined(OPENBSD) || defined(FREEBSD) \ + || defined(NETBSD) || defined(DRAGONFLY) || defined (ANDROID) \ + || defined(HAIKU) +#define USE_DOUBLE_MMAP +#endif + +namespace bridges::cpp_uno::shared { + +/** Hand out vtable structures for interface type descriptions. + */ +class VtableFactory { +public: + // This structure is not defined in the generic part, but instead has to be + // defined individually for each CPP--UNO bridge: + /** A vtable slot. + */ + struct Slot; + + /** A raw vtable block. + */ + struct Block { + /** The start of the raw vtable block. + + It points to the start of the allocated memory block, whereas the + vtable pointer typically points some bytes into the block (e.g., + skipping an RTTI pointer, see mapBlockToVtable). Also, the block + contains any generated code snippets, after the vtable itself. + */ + void * start; + +#ifdef USE_DOUBLE_MMAP + /** When separately mmapping the block for writing and executing + exec points to the same memory as start, except start is used + exclusively for writing and exec for executing + */ + void * exec; + + /** File handle for the underlying anonymous file + */ + int fd; +#endif + + /** The size of the raw vtable block, in bytes. + */ + sal_Size size; + }; + + /** The vtable structure corresponding to an interface type. + */ + struct Vtables { + /** The number of blocks/vtables. + */ + sal_Int32 count; + + /** An array of blocks, representing the multiple vtables of a + (multiple-inheritance) type. + + <p>A block is a raw vtable. It points to the start of the allocated + memory block, whereas the vtable pointer typically points some bytes + into the block (e.g., skipping an RTTI pointer, see + mapBlockToVtable). Also, the block contains any generated code + snippets, after the vtable itself.</p> + */ + std::unique_ptr<Block[]> blocks; + + Vtables() + : count(0) + { + } + }; + + VtableFactory(); + + ~VtableFactory(); + + /** Given an interface type description, return its corresponding vtable + structure. + */ + const Vtables& getVtables(typelib_InterfaceTypeDescription * type); + + // This function is not defined in the generic part, but instead has to be + // defined individually for each CPP--UNO bridge: + /** Given a pointer to a block, turn it into a vtable pointer. + */ + static Slot * mapBlockToVtable(void * block); + +private: + class GuardedBlocks; + friend class GuardedBlocks; + + class BaseOffset; + + VtableFactory(VtableFactory const &) = delete; + VtableFactory& operator =(const VtableFactory&) = delete; + + bool createBlock(Block &block, sal_Int32 slotCount) const; + + void freeBlock(Block const & block) const; + + sal_Int32 createVtables( + GuardedBlocks & blocks, BaseOffset const & baseOffset, + typelib_InterfaceTypeDescription * type, sal_Int32 vtableNumber, + typelib_InterfaceTypeDescription * mostDerived, bool includePrimary) + const; + + // This function is not defined in the generic part, but instead has to be + // defined individually for each CPP--UNO bridge: + /** Calculate the size of a raw vtable block. + + @param slotCount the number of virtual function slots the returned + vtable block shall support (if there are any platform-specific slots, + like an RTTI pointer, or a pointer to a destructor, they are not covered + by slotCount) + @return the size of the raw vtable block, in bytes + */ + static std::size_t getBlockSize(sal_Int32 slotCount); + + // This function is not defined in the generic part, but instead has to be + // defined individually for each CPP--UNO bridge: + /** Initialize a raw vtable block. + + @param block the start address of the raw vtable block + @param slotCount the number of slots + @param vtableNumber zero-based count across all the most derived type's + vtables (for vtable's "offset to top" slot) + @param type non-null most derived type (for vtable's "typeinfo pointer" + slot) + @return a pointer past the last vtable slot + */ + static Slot * initializeBlock( + void * block, sal_Int32 slotCount, sal_Int32 vtableNumber, + typelib_InterfaceTypeDescription * type); + + // This function is not defined in the generic part, but instead has to be + // defined individually for each CPP--UNO bridge: + /** Fill the vtable slots corresponding to all local (i.e., not inherited) + functions of a given interface type (and generate any necessary code + snippets for them). + + @param slots on input, points past the vtable slot to be filled with + the last virtual function local to the given type; on output, points to + the vtable slot filled with the first virtual function local to the + given type + @param code points to the start of the area where code snippets can be + generated + @param writetoexecdiff when the same code area is mapped twice, once for + writing for code-generation, and once for code-execution, then this + records the offset from a writable address to its executable address + @param type the interface type description for which to generate vtable + slots + @param functionOffset the function offset of the first vtable slot + (typically coded into the code snippet for that vtable slot) + @param functionCount the number of vtable slots to fill (the number of + local functions of the given type, passed in so that it doesn't need to + be recomputed) + @param vtableOffset the offset of this vtable (needed to adjust the + this pointer, typically coded into the code snippets for all the filled + vtable slots) + @return a pointer to the remaining code snippet area + */ + static unsigned char * addLocalFunctions( + Slot ** slots, unsigned char * code, +#ifdef USE_DOUBLE_MMAP + sal_PtrDiff writetoexecdiff, +#endif + typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset, + sal_Int32 functionCount, sal_Int32 vtableOffset); + + // This function is not defined in the generic part, but instead has to be + // defined individually for each CPP--UNO bridge: + /** Flush all the generated code snippets of a vtable, on platforms that + require it. + + @param begin points to the start of the code snippet area + @param end points behind the end of the code snippet area + */ + static void flushCode( + unsigned char const * begin, unsigned char const * end); + + typedef std::unordered_map< OUString, Vtables > Map; + + std::mutex m_mutex; + Map m_map; + + rtl_arena_type * m_arena; +}; + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/bridges/inc/vtables.hxx b/bridges/inc/vtables.hxx new file mode 100644 index 000000000..57ee58f53 --- /dev/null +++ b/bridges/inc/vtables.hxx @@ -0,0 +1,97 @@ +/* -*- 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 + +#include <sal/types.h> +#include <typelib/typedescription.h> + +namespace bridges::cpp_uno::shared +{ +/** + * Calculate the number of local functions of an interface type. + * + * <p><em>Local</em> functions are those not inherited from any base types. The + * number of <em>functions</em> is potentially larger than the number of + * <em>members</em>, as each read–write attribute member counts as two + * functions.</p> + * + * @param type a non-null pointer to an interface type description, for which + * <code>typelib_typedescription_complete</code> must already have been + * executed + * @return the number of local functions of the given interface type + */ +sal_Int32 getLocalFunctions(typelib_InterfaceTypeDescription const* type); + +/** + * Calculate the number of primary functions of an interface type. + * + * <p>The number of primary functions of an interface is the number of local + * functions of that interface (see <code>getLocalFunctions</code>), plus the + * number of primary functions of that interface's first base type (if it has at + * least one base type).</p> + * + * @param type a pointer to an interface type description; may be null + * @return the number of primary functions of the given interface type, or zero + * if the given interface type is null + */ +sal_Int32 getPrimaryFunctions(typelib_InterfaceTypeDescription* type); + +/** + * Represents a vtable slot of a C++ class. + */ +struct VtableSlot +{ + /** + * The offset of the vtable. + * + * <p>Multiple-inheritance C++ classes have more than one vtable. The + * offset is logical (<em>not</em> a byte offset), and must be + * non-negative.</p> + */ + sal_Int32 offset; + + /** + * The index within the vtable. + * + * <p>The index is logical (<em>not</em> a byte offset), and must be + * non-negative.</p> + */ + sal_Int32 index; +}; + +/** + * Calculates the vtable slot associated with an interface attribute member. + * + * @param ifcMember a non-null pointer to an interface attribute member + * description + * @return the vtable slot associated with the given interface member + */ +VtableSlot getVtableSlot(typelib_InterfaceAttributeTypeDescription const* ifcMember); + +/** + * Calculates the vtable slot associated with an interface method member. + * + * @param ifcMember a non-null pointer to an interface method member description + * @return the vtable slot associated with the given interface member + */ +VtableSlot getVtableSlot(typelib_InterfaceMethodTypeDescription const* ifcMember); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |