summaryrefslogtreecommitdiff
path: root/bridges
diff options
context:
space:
mode:
authorjan Iversen <jani@libreoffice.org>2017-09-21 11:17:35 +0200
committerjan Iversen <jani@libreoffice.org>2017-09-21 14:08:16 +0200
commit0dedbd2040a10098c6079443e21d1949ff384c14 (patch)
treeccf983af7c5eaa5a252d878800d519c21a5e5186 /bridges
parent079525b21fa4f55902af86f67a79b5439db1a289 (diff)
iOS, change bridges to 64bit and reduce
Changed __i386 to not __arm64 iOS either compiles for arm64 (production) or x86_64 (simulator) add common parts to cpp2uno and uno2cpp Change-Id: I059f3cc23bb658d6d53dbf2bf4aa6634eeac9662
Diffstat (limited to 'bridges')
-rw-r--r--bridges/Library_cpp_uno.mk2
-rw-r--r--bridges/source/cpp_uno/gcc3_ios/cpp2uno-arm64.cxx560
-rw-r--r--bridges/source/cpp_uno/gcc3_ios/cpp2uno-i386.cxx532
-rw-r--r--bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx529
-rw-r--r--bridges/source/cpp_uno/gcc3_ios/share.hxx8
-rw-r--r--bridges/source/cpp_uno/gcc3_ios/uno2cpp-arm64.cxx557
-rw-r--r--bridges/source/cpp_uno/gcc3_ios/uno2cpp.cxx527
7 files changed, 1055 insertions, 1660 deletions
diff --git a/bridges/Library_cpp_uno.mk b/bridges/Library_cpp_uno.mk
index 993342baea58..7c85b051f27d 100644
--- a/bridges/Library_cpp_uno.mk
+++ b/bridges/Library_cpp_uno.mk
@@ -11,7 +11,7 @@ $(eval $(call gb_Library_Library,$(gb_CPPU_ENV)_uno))
ifeq ($(OS),IOS)
bridges_SELECTED_BRIDGE := gcc3_ios
-bridge_noopt_objects := cpp2uno cpp2uno-arm64 cpp2uno-i386 except uno2cpp uno2cpp-arm64 uno2cpp-i386
+bridge_noopt_objects := cpp2uno except uno2cpp uno2cpp-i386
else ifeq ($(CPUNAME),ARM)
diff --git a/bridges/source/cpp_uno/gcc3_ios/cpp2uno-arm64.cxx b/bridges/source/cpp_uno/gcc3_ios/cpp2uno-arm64.cxx
deleted file mode 100644
index 64ac9ed38b2b..000000000000
--- a/bridges/source/cpp_uno/gcc3_ios/cpp2uno-arm64.cxx
+++ /dev/null
@@ -1,560 +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 .
- */
-
-#ifdef __arm64
-
-// For iOS devices (64-bit ARM). Originally a copy of
-// ../gcc3_linux_arm/cpp2uno.cxx.
-
-// No attempts at factoring out the large amounts of more or less
-// common code in this, cpp2uno-arm.cxx and cpp2uno-i386.cxx have been
-// done. Which is sad. But then the whole bridges/source/cpp_uno is
-// full of copy/paste. So I continue in that tradition...
-
-#include <com/sun/star/uno/RuntimeException.hpp>
-#include <sal/log.hxx>
-#include <uno/data.h>
-#include <typelib/typedescription.hxx>
-
-#include "bridge.hxx"
-#include "cppinterfaceproxy.hxx"
-#include "types.hxx"
-#include "vtablefactory.hxx"
-
-#include "share.hxx"
-
-extern "C" {
- extern int nFunIndexes, nVtableOffsets;
- extern int codeSnippets[];
-}
-
-using namespace ::com::sun::star::uno;
-
-namespace
-{
- static typelib_TypeClass cpp2uno_call(
- bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
- const typelib_TypeDescription * pMemberTypeDescr,
- typelib_TypeDescriptionReference * pReturnTypeRef,
- sal_Int32 nParams,
- typelib_MethodParameter * pParams,
- void ** pCallStack,
- sal_Int64 * pRegisterReturn /* space for register return */ )
- {
- // pCallStack: x8, lr, d0..d7, x0..x7, rest of params originally on stack
- char *pTopStack = (char *)pCallStack;
- char *pFloatRegs = pTopStack + 2;
- char *pGPRegs = pTopStack + (2+8)*8;
- char *pStackedArgs = pTopStack + (2+8+8)*8;
-
- int nGPR = 0;
- int nFPR = 0;
-
- // return
- typelib_TypeDescription * pReturnTypeDescr = 0;
- if (pReturnTypeRef)
- TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
-
- void * pUnoReturn = 0;
- // complex return ptr: if != 0 && != pUnoReturn, reconversion need
- void * pCppReturn = 0;
-
- if (pReturnTypeDescr)
- {
- if (!arm::return_in_x8(pReturnTypeRef))
- pUnoReturn = pRegisterReturn; // direct way for simple types
- else // complex return via x8
- {
- pCppReturn = pCallStack[0];
-
- pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
- pReturnTypeDescr )
- ? alloca( pReturnTypeDescr->nSize )
- : pCppReturn); // direct way
- }
- }
-
- // Skip 'this'
- pGPRegs += 8;
- nGPR++;
-
- // Parameters
- void ** pUnoArgs = (void **)alloca( sizeof(void *) * nParams );
- void ** pCppArgs = (void **)alloca( sizeof(void *) * nParams );
-
- // Indices of values this have to be converted (interface conversion
- // cpp<=>uno)
- int * pTempIndices = (sal_Int32 *)alloca( sizeof(int) * nParams);
-
- // Type descriptions for reconversions
- typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)alloca( sizeof(typelib_TypeDescription *) * nParams);
-
- int nTempIndices = 0;
-
- for ( int nPos = 0; nPos < nParams; ++nPos )
- {
- const typelib_MethodParameter & rParam = pParams[nPos];
- typelib_TypeDescription * pParamTypeDescr = 0;
- TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
-
- if (!rParam.bOut &&
- bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
- {
- if (nFPR < 8 && (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT ||
- pParamTypeDescr->eTypeClass == typelib_TypeClass_DOUBLE))
- {
- pCppArgs[nPos] = pUnoArgs[nPos] = pFloatRegs;
- pFloatRegs += 8;
- nFPR++;
- }
- else if (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT)
- {
- if ((pStackedArgs - pTopStack) % 4)
- pStackedArgs += 4 - ((pStackedArgs - pTopStack) % 4);
- pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
- pStackedArgs += 4;
- }
- else if (pParamTypeDescr->eTypeClass == typelib_TypeClass_DOUBLE)
- {
- if ((pStackedArgs - pTopStack) % 8)
- pStackedArgs += 8 - ((pStackedArgs - pTopStack) % 8);
- pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
- pStackedArgs += 8;
- }
- else if (nGPR < 8)
- {
- pCppArgs[nPos] = pUnoArgs[nPos] = pGPRegs;
- pGPRegs += 8;
- nGPR++;
- }
- else
- switch (pParamTypeDescr->eTypeClass)
- {
- case typelib_TypeClass_HYPER:
- case typelib_TypeClass_UNSIGNED_HYPER:
- if ((pStackedArgs - pTopStack) % 8)
- pStackedArgs += 8 - ((pStackedArgs - pTopStack) % 8);
- pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
- pStackedArgs += 8;
- break;
- case typelib_TypeClass_ENUM:
- case typelib_TypeClass_LONG:
- case typelib_TypeClass_UNSIGNED_LONG:
- if ((pStackedArgs - pTopStack) % 4)
- pStackedArgs += 4 - ((pStackedArgs - pTopStack) % 4);
- pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
- pStackedArgs += 4;
- break;
- case typelib_TypeClass_CHAR:
- case typelib_TypeClass_SHORT:
- case typelib_TypeClass_UNSIGNED_SHORT:
- if ((pStackedArgs - pTopStack) % 2)
- pStackedArgs += 1;
- pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
- pStackedArgs += 2;
- break;
- case typelib_TypeClass_BOOLEAN:
- case typelib_TypeClass_BYTE:
- pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
- pStackedArgs += 1;
- break;
- default:
- assert(!"should not happen");
- break;
- }
- // no longer needed
- TYPELIB_DANGER_RELEASE( pParamTypeDescr );
- }
- else // ptr to complex value | ref
- {
- if (nGPR < 8)
- {
- pCppArgs[nPos] = *(void **)pGPRegs;
- pGPRegs += 8;
- }
- else
- {
- if ((pStackedArgs - pTopStack) % 8)
- pStackedArgs += 8 - ((pStackedArgs - pTopStack) % 8);
- pCppArgs[nPos] = pStackedArgs;
- pStackedArgs += 8;
- }
-
- if (! rParam.bIn) // is pure out
- {
- // uno out is unconstructed mem!
- pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
- pTempIndices[nTempIndices] = nPos;
- // will be released at reconversion
- ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
- }
- // is in/inout
- else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
- {
- uno_copyAndConvertData( pUnoArgs[nPos] =
- alloca( pParamTypeDescr->nSize ),
- pCppArgs[nPos], pParamTypeDescr,
- pThis->getBridge()->getCpp2Uno() );
- pTempIndices[nTempIndices] = nPos; // has to be reconverted
- // will be released at reconversion
- ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
- }
- else // direct way
- {
- pUnoArgs[nPos] = pCppArgs[nPos];
- // no longer needed
- TYPELIB_DANGER_RELEASE( pParamTypeDescr );
- }
- }
- }
-
- // ExceptionHolder
- uno_Any aUnoExc; // Any will be constructed by callee
- uno_Any * pUnoExc = &aUnoExc;
-
- // invoke uno dispatch call
- (*pThis->getUnoI()->pDispatcher)(
- pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
-
- // in case an exception occurred...
- if (pUnoExc)
- {
- // destruct temporary in/inout params
- for ( ; nTempIndices--; )
- {
- int nIndex = pTempIndices[nTempIndices];
-
- if (pParams[nIndex].bIn) // is in/inout => was constructed
- uno_destructData( pUnoArgs[nIndex],
- ppTempParamTypeDescr[nTempIndices], 0 );
- TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
- }
- if (pReturnTypeDescr)
- TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
-
- CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc,
- pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
- // is here for dummy
- return typelib_TypeClass_VOID;
- }
- else // else no exception occurred...
- {
- // temporary params
- for ( ; nTempIndices--; )
- {
- int nIndex = pTempIndices[nTempIndices];
- typelib_TypeDescription * pParamTypeDescr =
- ppTempParamTypeDescr[nTempIndices];
-
- if (pParams[nIndex].bOut) // inout/out
- {
- // convert and assign
- uno_destructData( pCppArgs[nIndex], pParamTypeDescr,
- cpp_release );
- uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex],
- pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
- }
- // destroy temp uno param
- uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
-
- TYPELIB_DANGER_RELEASE( pParamTypeDescr );
- }
- // return
- if (pCppReturn) // has complex return
- {
- if (pUnoReturn != pCppReturn) // needs reconversion
- {
- uno_copyAndConvertData( pCppReturn, pUnoReturn,
- pReturnTypeDescr, pThis->getBridge()->getUno2Cpp() );
- // destroy temp uno return
- uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
- }
- *(void **)pRegisterReturn = pCppReturn;
- }
- if (pReturnTypeDescr)
- {
- typelib_TypeClass eRet =
- (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
- TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
- return eRet;
- }
- else
- return typelib_TypeClass_VOID;
- }
- }
-
-
- static typelib_TypeClass cpp_mediate( sal_Int32 nFunctionIndex,
- sal_Int32 nVtableOffset,
- void ** pCallStack,
- sal_Int64 * pRegisterReturn )
- {
- // pCallStack: x8, lr, d0..d7, x0..x7, rest of params originally on stack
- // _this_ ptr is patched cppu_XInterfaceProxy object
- void *pThis = pCallStack[2 + 8];
-
- pThis = static_cast< char * >(pThis) - nVtableOffset;
- bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
- bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
- pThis);
-
- typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
-
- // determine called method
- assert( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex );
-
- if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
- {
- throw RuntimeException( "illegal vtable index!", (XInterface *)pCppI );
- }
-
- sal_Int32 nMemberPos =
- pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
- assert( nMemberPos < pTypeDescr->nAllMembers );
-
- TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
-
- typelib_TypeClass eRet;
- switch (aMemberDescr.get()->eTypeClass)
- {
- case typelib_TypeClass_INTERFACE_ATTRIBUTE:
- {
- if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
- nFunctionIndex)
- {
- // is GET method
- eRet = cpp2uno_call(
- pCppI, aMemberDescr.get(),
- ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
- 0, 0, // no params
- pCallStack, pRegisterReturn );
- }
- else
- {
- // is SET method
- typelib_MethodParameter aParam;
- aParam.pTypeRef =
- ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
- aParam.bIn = sal_True;
- aParam.bOut = sal_False;
-
- eRet = cpp2uno_call(
- pCppI, aMemberDescr.get(),
- 0, // indicates void return
- 1, &aParam,
- pCallStack, pRegisterReturn );
- }
- break;
- }
- case typelib_TypeClass_INTERFACE_METHOD:
- {
- // is METHOD
- switch (nFunctionIndex)
- {
- case 1: // acquire()
- pCppI->acquireProxy(); // non virtual call!
- eRet = typelib_TypeClass_VOID;
- break;
- case 2: // release()
- pCppI->releaseProxy(); // non virtual call!
- eRet = typelib_TypeClass_VOID;
- break;
- case 0: // queryInterface() opt
- {
- typelib_TypeDescription * pTD = 0;
- TYPELIB_DANGER_GET(&pTD,
- reinterpret_cast<Type *>(pCallStack[2])->getTypeLibType());
- if (pTD)
- {
- XInterface * pInterface = 0;
- (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
- pCppI->getBridge()->getCppEnv(),
- (void **)&pInterface, pCppI->getOid().pData,
- (typelib_InterfaceTypeDescription *)pTD );
-
- if (pInterface)
- {
- ::uno_any_construct(
- reinterpret_cast< uno_Any * >( pCallStack[0] ),
- &pInterface, pTD, cpp_acquire );
- pInterface->release();
- TYPELIB_DANGER_RELEASE( pTD );
- *(void **)pRegisterReturn = pCallStack[0];
- eRet = typelib_TypeClass_ANY;
- break;
- }
- TYPELIB_DANGER_RELEASE( pTD );
- }
- } // else perform queryInterface()
- SAL_FALLTHROUGH;
- default:
- eRet = cpp2uno_call(
- pCppI, aMemberDescr.get(),
- ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
- ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
- ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
- pCallStack, pRegisterReturn );
- }
- break;
- }
- default:
- {
- throw RuntimeException( "no member description found!", (XInterface *)pCppI );
- }
- }
-
- return eRet;
- }
-}
-
-/**
- * is called on incoming vtable calls
- * (called by asm snippets)
- */
-
-extern "C" sal_Int64 cpp_vtable_call( sal_Int32 *pFunctionAndOffset,
- void **pCallStack )
-{
- sal_Int64 nRegReturn;
- typelib_TypeClass aType = cpp_mediate( pFunctionAndOffset[0], pFunctionAndOffset[1], pCallStack, &nRegReturn );
-
- switch( aType )
- {
- case typelib_TypeClass_BOOLEAN:
- case typelib_TypeClass_BYTE:
- nRegReturn = (unsigned long)(*(unsigned char *)&nRegReturn);
- break;
- case typelib_TypeClass_CHAR:
- case typelib_TypeClass_UNSIGNED_SHORT:
- case typelib_TypeClass_SHORT:
- nRegReturn = (unsigned long)(*(unsigned short *)&nRegReturn);
- break;
- case typelib_TypeClass_ENUM:
- case typelib_TypeClass_UNSIGNED_LONG:
- case typelib_TypeClass_LONG:
- nRegReturn = (unsigned long)(*(unsigned int *)&nRegReturn);
- break;
- case typelib_TypeClass_VOID:
- default:
- break;
- }
-
- return nRegReturn;
-}
-
-namespace
-{
- unsigned char *codeSnippet(const typelib_InterfaceTypeDescription *type,
- const typelib_TypeDescription *member,
- sal_Int32 functionIndex,
- sal_Int32 vtableOffset)
- {
- assert(functionIndex < nFunIndexes);
- if (!(functionIndex < nFunIndexes))
- return NULL;
-
- assert(vtableOffset < nVtableOffsets);
- if (!(vtableOffset < nVtableOffsets))
- return NULL;
-
- // The codeSnippets table is indexed by functionIndex and vtableOffset
-
- int index = functionIndex*nVtableOffsets + vtableOffset;
- unsigned char *result = ((unsigned char *) &codeSnippets) + codeSnippets[index];
-
- SAL_INFO( "bridges.ios", "codeSnippet(" << OUString(type->aBase.pTypeName) << "::" << OUString(member->pTypeName) << "): [" << functionIndex << "," << vtableOffset << "]=" << (void *) result << " (" << std::hex << ((int*)result)[0] << "," << ((int*)result)[1] << "," << ((int*)result)[2] << "," << ((int*)result)[3] << ")");
-
- return result;
- }
-}
-
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
-
-bridges::cpp_uno::shared::VtableFactory::Slot *
-bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
-{
- return static_cast< Slot * >(block) + 2;
-}
-
-std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
- sal_Int32 slotCount)
-{
- return (slotCount + 2) * sizeof (Slot);
-}
-
-bridges::cpp_uno::shared::VtableFactory::Slot *
-bridges::cpp_uno::shared::VtableFactory::initializeBlock(
- void * block, sal_Int32 slotCount, sal_Int32,
- typelib_InterfaceTypeDescription *)
-{
- Slot * slots = mapBlockToVtable(block);
- slots[-2].fn = 0;
- slots[-1].fn = 0;
- return slots + slotCount;
-}
-
-unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
- Slot ** slots,
- unsigned char * code,
- typelib_InterfaceTypeDescription const * type,
- sal_Int32 functionOffset,
- sal_Int32 functionCount,
- sal_Int32 vtableOffset)
-{
- (*slots) -= functionCount;
- Slot * s = *slots;
- for (sal_Int32 i = 0; i < type->nMembers; ++i)
- {
- typelib_TypeDescription * member = 0;
- TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
- assert(member != 0);
- switch (member->eTypeClass)
- {
- case typelib_TypeClass_INTERFACE_ATTRIBUTE:
- {
- typelib_InterfaceAttributeTypeDescription *pAttrTD =
- reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( member );
-
- // Getter:
- (s++)->fn = codeSnippet( type, member, functionOffset++, vtableOffset );
-
- // Setter:
- if (!pAttrTD->bReadOnly)
- {
- (s++)->fn = codeSnippet( type, member, functionOffset++, vtableOffset );
- }
- break;
- }
- case typelib_TypeClass_INTERFACE_METHOD:
- {
- (s++)->fn = codeSnippet( type, member, functionOffset++, vtableOffset );
- break;
- }
- default:
- assert(false);
- break;
- }
- TYPELIB_DANGER_RELEASE(member);
- }
- return code;
-}
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_ios/cpp2uno-i386.cxx b/bridges/source/cpp_uno/gcc3_ios/cpp2uno-i386.cxx
deleted file mode 100644
index 6a3689ca6c33..000000000000
--- a/bridges/source/cpp_uno/gcc3_ios/cpp2uno-i386.cxx
+++ /dev/null
@@ -1,532 +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 .
- */
-
-#ifdef __i386
-
-// For the iOS emulator (i386). Basically a copy of
-// ../gcc3_macosx_intel/cpp2uno.cxx with some cleanups and necessary
-// changes: To match what we do on iOS devices, we don't do any
-// dynamic code generation on the emulator either (even if it as such
-// wouldn't be prohibited).
-
-// No attempts at factoring out the large amounts of more or less
-// common code in this and cpp2uno-arm.cxx have been done. Which is
-// sad. But then the whole bridges/source/cpp_uno is full of
-// copy/paste. So I continue in that tradition...
-
-#include <com/sun/star/uno/RuntimeException.hpp>
-#include <sal/log.hxx>
-#include <uno/data.h>
-#include <typelib/typedescription.hxx>
-
-#include "bridge.hxx"
-#include "cppinterfaceproxy.hxx"
-#include "types.hxx"
-#include "vtablefactory.hxx"
-
-#include "share.hxx"
-
-extern "C" {
- extern int nFunIndexes, nVtableOffsets;
- extern int codeSnippets[];
-}
-
-using namespace ::com::sun::star::uno;
-
-namespace
-{
-
-void cpp2uno_call(
- bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
- const typelib_TypeDescription * pMemberTypeDescr,
- typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
- sal_Int32 nParams, typelib_MethodParameter * pParams,
- void ** pCallStack,
- void * pReturnValue )
-{
- // pCallStack: ret, [return ptr], this, params
- char * pCppStack = (char *)(pCallStack +1);
-
- // return
- typelib_TypeDescription * pReturnTypeDescr = 0;
- if (pReturnTypeRef)
- TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
-
- void * pUnoReturn = 0;
- void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
-
- if (pReturnTypeDescr)
- {
- // xxx todo: test PolyStructy<STRUCT<long>> foo()
- if (CPPU_CURRENT_NAMESPACE::isSimpleReturnType( pReturnTypeDescr ))
- {
- pUnoReturn = pReturnValue; // direct way for simple types
- }
- else // complex return via ptr (pCppReturn)
- {
- pCppReturn = *(void **)pCppStack;
- pCppStack += sizeof(void *);
- pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
- pReturnTypeDescr )
- ? alloca( pReturnTypeDescr->nSize )
- : pCppReturn); // direct way
- }
- }
- // pop this
- pCppStack += sizeof( void* );
-
- // stack space
- static_assert(sizeof(void *) == sizeof(sal_Int32), "### unexpected size!");
- // parameters
- void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
- void ** pCppArgs = pUnoArgs + nParams;
- // indices of values this have to be converted (interface conversion cpp<=>uno)
- sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
- // type descriptions for reconversions
- typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
-
- sal_Int32 nTempIndices = 0;
-
- for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
- {
- const typelib_MethodParameter & rParam = pParams[nPos];
- typelib_TypeDescription * pParamTypeDescr = 0;
- TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
-
- if (!rParam.bOut
- && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
- // value
- {
- pCppArgs[nPos] = pCppStack;
- pUnoArgs[nPos] = pCppStack;
- switch (pParamTypeDescr->eTypeClass)
- {
- case typelib_TypeClass_HYPER:
- case typelib_TypeClass_UNSIGNED_HYPER:
- case typelib_TypeClass_DOUBLE:
- pCppStack += sizeof(sal_Int32); // extra long
- SAL_FALLTHROUGH;
- default:
- break;
- }
- // no longer needed
- TYPELIB_DANGER_RELEASE( pParamTypeDescr );
- }
- else // ptr to complex value | ref
- {
- pCppArgs[nPos] = *(void **)pCppStack;
-
- if (! rParam.bIn) // is pure out
- {
- // uno out is unconstructed mem!
- pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
- pTempIndices[nTempIndices] = nPos;
- // will be released at reconversion
- ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
- }
- // is in/inout
- else if (bridges::cpp_uno::shared::relatesToInterfaceType(
- pParamTypeDescr ))
- {
- uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
- *(void **)pCppStack, pParamTypeDescr,
- pThis->getBridge()->getCpp2Uno() );
- pTempIndices[nTempIndices] = nPos; // has to be reconverted
- // will be released at reconversion
- ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
- }
- else // direct way
- {
- pUnoArgs[nPos] = *(void **)pCppStack;
- // no longer needed
- TYPELIB_DANGER_RELEASE( pParamTypeDescr );
- }
- }
- pCppStack += sizeof(sal_Int32); // standard parameter length
- }
-
- // ExceptionHolder
- uno_Any aUnoExc; // Any will be constructed by callee
- uno_Any * pUnoExc = &aUnoExc;
-
- // invoke uno dispatch call
- (*pThis->getUnoI()->pDispatcher)(
- pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
-
- // in case an exception occurred...
- if (pUnoExc)
- {
- // destruct temporary in/inout params
- for ( ; nTempIndices--; )
- {
- sal_Int32 nIndex = pTempIndices[nTempIndices];
-
- if (pParams[nIndex].bIn) // is in/inout => was constructed
- uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
- TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
- }
- if (pReturnTypeDescr)
- TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
-
- CPPU_CURRENT_NAMESPACE::raiseException(
- &aUnoExc, pThis->getBridge()->getUno2Cpp() );
- // has to destruct the any
- }
- else // else no exception occurred...
- {
- // temporary params
- for ( ; nTempIndices--; )
- {
- sal_Int32 nIndex = pTempIndices[nTempIndices];
- typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
-
- if (pParams[nIndex].bOut) // inout/out
- {
- // convert and assign
- uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
- uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
- pThis->getBridge()->getUno2Cpp() );
- }
- // destroy temp uno param
- uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
-
- TYPELIB_DANGER_RELEASE( pParamTypeDescr );
- }
- // return
- if (pCppReturn) // has complex return
- {
- if (pUnoReturn != pCppReturn) // needs reconversion
- {
- uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
- pThis->getBridge()->getUno2Cpp() );
- // destroy temp uno return
- uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
- }
- if (pReturnValue != pCppReturn) {
- // complex return ptr is set to eax if return value
- // is not transferred via eax[/edx]:
- *static_cast< void ** >(pReturnValue) = pCppReturn;
- }
- }
- if (pReturnTypeDescr)
- {
- TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
- }
- }
-}
-
-
-extern "C" void cpp_vtable_call(
- int nFunctionIndex, int nVtableOffset, void** pCallStack,
- void * pReturnValue )
-{
- static_assert(sizeof(sal_Int32)==sizeof(void *), "### unexpected!");
-
- // pCallStack: ret adr, [ret *], this, params
- void * pThis;
- if( nFunctionIndex & 0x80000000 )
- {
- nFunctionIndex &= 0x7fffffff;
- pThis = pCallStack[2];
- }
- else
- {
- pThis = pCallStack[1];
- }
- pThis = static_cast< char * >(pThis) - nVtableOffset;
- bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
- = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
- pThis);
-
- typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
-
- SAL_INFO( "bridges.ios", "cpp_vtable_call: pCallStack=[" <<
- std::hex << pCallStack[0] << "," << pCallStack[1] << "," << pCallStack[2] << ",...]" <<
- ", pThis=" << pThis << ", pCppI=" << pCppI <<
- std::dec << ", nFunctionIndex=" << nFunctionIndex << ", nVtableOffset=" << nVtableOffset );
-
- SAL_INFO( "bridges.ios", "name=" << OUString::unacquired(&pTypeDescr->aBase.pTypeName) );
-
- assert( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex );
-
- if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
- {
- throw RuntimeException( "illegal vtable index!", (XInterface *)pThis );
- }
-
- // determine called method
- sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
-
- assert( nMemberPos < pTypeDescr->nAllMembers );
-
- TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
-
- SAL_INFO( "bridges.ios", "Calling " << OUString::unacquired(&aMemberDescr.get()->pTypeName) );
-
- switch (aMemberDescr.get()->eTypeClass)
- {
- case typelib_TypeClass_INTERFACE_ATTRIBUTE:
- {
- if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
- {
- // is GET method
- cpp2uno_call(
- pCppI, aMemberDescr.get(),
- ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
- 0, 0, // no params
- pCallStack, pReturnValue );
- }
- else
- {
- // is SET method
- typelib_MethodParameter aParam;
- aParam.pTypeRef =
- ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
- aParam.bIn = sal_True;
- aParam.bOut = sal_False;
-
- cpp2uno_call(
- pCppI, aMemberDescr.get(),
- 0, // indicates void return
- 1, &aParam,
- pCallStack, pReturnValue );
- }
- break;
- }
- case typelib_TypeClass_INTERFACE_METHOD:
- {
- // is METHOD
- switch (nFunctionIndex)
- {
- case 1: // acquire()
- pCppI->acquireProxy(); // non virtual call!
- break;
- case 2: // release()
- pCppI->releaseProxy(); // non virtual call!
- break;
- case 0: // queryInterface() opt
- {
- typelib_TypeDescription * pTD = 0;
- TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() );
- if (pTD)
- {
- XInterface * pInterface = 0;
- (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
- pCppI->getBridge()->getCppEnv(),
- (void **)&pInterface, pCppI->getOid().pData,
- (typelib_InterfaceTypeDescription *)pTD );
-
- if (pInterface)
- {
- ::uno_any_construct(
- reinterpret_cast< uno_Any * >( pCallStack[1] ),
- &pInterface, pTD, cpp_acquire );
- pInterface->release();
- TYPELIB_DANGER_RELEASE( pTD );
- *static_cast< void ** >(pReturnValue) = pCallStack[1];
- break;
- }
- TYPELIB_DANGER_RELEASE( pTD );
- }
- } // else perform queryInterface()
- SAL_FALLTHROUGH;
- default:
- cpp2uno_call(
- pCppI, aMemberDescr.get(),
- ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
- ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
- ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
- pCallStack, pReturnValue );
- }
- break;
- }
- default:
- {
- throw RuntimeException( "no member description found!", (XInterface *)pThis );
- }
- }
-}
-
-typedef enum { privateSnippetExecutorGeneral, privateSnippetExecutorVoid, privateSnippetExecutorHyper, privateSnippetExecutorFloat, privateSnippetExecutorDouble, privateSnippetExecutorClass } snippetExecutorKind;
-
-static const char * snippetExecutorClassName(
- snippetExecutorKind exec)
-{
- switch (exec) {
- case privateSnippetExecutorGeneral: return "General";
- case privateSnippetExecutorVoid: return "Void";
- case privateSnippetExecutorHyper: return "Hyper";
- case privateSnippetExecutorFloat: return "Float";
- case privateSnippetExecutorDouble: return "Double";
- case privateSnippetExecutorClass: return "Class";
- default:
- abort();
- }
-}
-
-unsigned char * codeSnippet(
- sal_Int32 functionIndex, sal_Int32 vtableOffset,
- typelib_TypeDescriptionReference * pReturnTypeRef)
-{
- assert(functionIndex < nFunIndexes);
- if (!(functionIndex < nFunIndexes))
- return NULL;
-
- assert(vtableOffset < nVtableOffsets);
- if (!(vtableOffset < nVtableOffsets))
- return NULL;
-
- snippetExecutorKind exec;
- bool bHasHiddenParam = false;
- if (pReturnTypeRef == 0) {
- exec = privateSnippetExecutorVoid;
- }
- else {
- switch (pReturnTypeRef->eTypeClass) {
- case typelib_TypeClass_VOID:
- exec = privateSnippetExecutorVoid;
- break;
- case typelib_TypeClass_HYPER:
- case typelib_TypeClass_UNSIGNED_HYPER:
- exec = privateSnippetExecutorHyper;
- break;
- case typelib_TypeClass_FLOAT:
- exec = privateSnippetExecutorFloat;
- break;
- case typelib_TypeClass_DOUBLE:
- exec = privateSnippetExecutorDouble;
- break;
- case typelib_TypeClass_STRUCT:
- case typelib_TypeClass_EXCEPTION: {
- typelib_TypeDescription * pReturnTypeDescr = 0;
- TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
- bool const bSimpleReturnStruct =
- CPPU_CURRENT_NAMESPACE::isSimpleReturnType(pReturnTypeDescr);
- sal_Int32 const nRetSize = pReturnTypeDescr->nSize;
- TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
- if (bSimpleReturnStruct && nRetSize <= 8) {
- exec = privateSnippetExecutorGeneral; // fills eax
- if (nRetSize > 4)
- exec = privateSnippetExecutorHyper; // fills eax/edx
- break;
- }
- }
- SAL_FALLTHROUGH;
- case typelib_TypeClass_STRING:
- case typelib_TypeClass_TYPE:
- case typelib_TypeClass_SEQUENCE:
- case typelib_TypeClass_INTERFACE:
- case typelib_TypeClass_ANY:
- bHasHiddenParam = 1;
- exec = privateSnippetExecutorClass;
- break;
- default:
- exec = privateSnippetExecutorGeneral;
- break;
- }
- }
-
- // The codeSnippets table is indexed by functionIndex,
- // vtableOffset, exec and the has-hidden-param flag
-
- int index = functionIndex*nVtableOffsets*6*2 + vtableOffset*6*2 + exec*2 + bHasHiddenParam;
- unsigned char *result = ((unsigned char *) &codeSnippets) + codeSnippets[index];
-
- SAL_INFO( "bridges.ios", "codeSnippet: [" <<
- functionIndex << "," << vtableOffset << "," << snippetExecutorClassName(exec) << "," << bHasHiddenParam << "]=" <<
- (void *) result);
-
- return result;
-}
-
-}
-
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
-
-bridges::cpp_uno::shared::VtableFactory::Slot *
-bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
-{
- return static_cast< Slot * >(block) + 2;
-}
-
-std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
- sal_Int32 slotCount)
-{
- return (slotCount + 2) * sizeof (Slot);
-}
-
-bridges::cpp_uno::shared::VtableFactory::Slot *
-bridges::cpp_uno::shared::VtableFactory::initializeBlock(
- void * block, sal_Int32 slotCount, sal_Int32,
- typelib_InterfaceTypeDescription *)
-{
- Slot * slots = mapBlockToVtable(block);
- slots[-2].fn = 0;
- slots[-1].fn = 0;
- return slots + slotCount;
-}
-
-unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
- Slot ** slots, unsigned char * code,
- typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
- sal_Int32 functionCount, sal_Int32 vtableOffset)
-{
- (*slots) -= functionCount;
- Slot * s = *slots;
- for (sal_Int32 i = 0; i < type->nMembers; ++i) {
- typelib_TypeDescription * member = 0;
- TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
- assert(member != 0);
- switch (member->eTypeClass) {
- case typelib_TypeClass_INTERFACE_ATTRIBUTE:
- // Getter:
- (s++)->fn = codeSnippet(
- functionOffset++, vtableOffset,
- reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
- member)->pAttributeTypeRef);
- // Setter:
- if (!reinterpret_cast<
- typelib_InterfaceAttributeTypeDescription * >(
- member)->bReadOnly)
- {
- (s++)->fn = codeSnippet(
- functionOffset++, vtableOffset,
- 0 /* indicates VOID */);
- }
- break;
-
- case typelib_TypeClass_INTERFACE_METHOD:
- (s++)->fn = codeSnippet(
- functionOffset++, vtableOffset,
- reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
- member)->pReturnTypeRef);
- break;
-
- default:
- assert(false);
- break;
- }
- TYPELIB_DANGER_RELEASE(member);
- }
- return code;
-}
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx
index 46726a8b30ba..6773486e9c9c 100644
--- a/bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx
@@ -17,11 +17,536 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-// If we eventually get around to factoring out stuff from
-// cpp2uno-arm.cxx and cpp2uno-i386.cxx here, this is where to put it.
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <sal/log.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
+#include "bridge.hxx"
+#include "cppinterfaceproxy.hxx"
+#include "types.hxx"
#include "vtablefactory.hxx"
+#include "share.hxx"
+
+extern "C" {
+ extern int nFunIndexes, nVtableOffsets;
+ extern int codeSnippets[];
+}
+
+using namespace ::com::sun::star::uno;
+
+namespace
+{
+ static typelib_TypeClass cpp2uno_call(
+ bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
+ const typelib_TypeDescription * pMemberTypeDescr,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams,
+ typelib_MethodParameter * pParams,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn /* space for register return */ )
+ {
+ // pCallStack: x8, lr, d0..d7, x0..x7, rest of params originally on stack
+ char *pTopStack = (char *)pCallStack;
+ char *pFloatRegs = pTopStack + 2;
+ char *pGPRegs = pTopStack + (2+8)*8;
+ char *pStackedArgs = pTopStack + (2+8+8)*8;
+
+ int nGPR = 0;
+ int nFPR = 0;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ if (pReturnTypeRef)
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+ void * pUnoReturn = 0;
+ // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+ void * pCppReturn = 0;
+
+ if (pReturnTypeDescr)
+ {
+ if (!arm::return_in_x8(pReturnTypeRef))
+ pUnoReturn = pRegisterReturn; // direct way for simple types
+ else // complex return via x8
+ {
+ pCppReturn = pCallStack[0];
+
+ pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+ pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pCppReturn); // direct way
+ }
+ }
+
+ // Skip 'this'
+ pGPRegs += 8;
+ nGPR++;
+
+ // Parameters
+ void ** pUnoArgs = (void **)alloca( sizeof(void *) * nParams );
+ void ** pCppArgs = (void **)alloca( sizeof(void *) * nParams );
+
+ // Indices of values this have to be converted (interface conversion
+ // cpp<=>uno)
+ int * pTempIndices = (sal_Int32 *)alloca( sizeof(int) * nParams);
+
+ // Type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)alloca( sizeof(typelib_TypeDescription *) * nParams);
+
+ int nTempIndices = 0;
+
+ for ( int nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut &&
+ bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ if (nFPR < 8 && (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT ||
+ pParamTypeDescr->eTypeClass == typelib_TypeClass_DOUBLE))
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = pFloatRegs;
+ pFloatRegs += 8;
+ nFPR++;
+ }
+ else if (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT)
+ {
+ if ((pStackedArgs - pTopStack) % 4)
+ pStackedArgs += 4 - ((pStackedArgs - pTopStack) % 4);
+ pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
+ pStackedArgs += 4;
+ }
+ else if (pParamTypeDescr->eTypeClass == typelib_TypeClass_DOUBLE)
+ {
+ if ((pStackedArgs - pTopStack) % 8)
+ pStackedArgs += 8 - ((pStackedArgs - pTopStack) % 8);
+ pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
+ pStackedArgs += 8;
+ }
+ else if (nGPR < 8)
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos] = pGPRegs;
+ pGPRegs += 8;
+ nGPR++;
+ }
+ else
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if ((pStackedArgs - pTopStack) % 8)
+ pStackedArgs += 8 - ((pStackedArgs - pTopStack) % 8);
+ pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
+ pStackedArgs += 8;
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ if ((pStackedArgs - pTopStack) % 4)
+ pStackedArgs += 4 - ((pStackedArgs - pTopStack) % 4);
+ pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
+ pStackedArgs += 4;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ if ((pStackedArgs - pTopStack) % 2)
+ pStackedArgs += 1;
+ pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
+ pStackedArgs += 2;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
+ pStackedArgs += 1;
+ break;
+ default:
+ assert(!"should not happen");
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (nGPR < 8)
+ {
+ pCppArgs[nPos] = *(void **)pGPRegs;
+ pGPRegs += 8;
+ }
+ else
+ {
+ if ((pStackedArgs - pTopStack) % 8)
+ pStackedArgs += 8 - ((pStackedArgs - pTopStack) % 8);
+ pCppArgs[nPos] = pStackedArgs;
+ pStackedArgs += 8;
+ }
+
+ if (! rParam.bIn) // is pure out
+ {
+ // uno out is unconstructed mem!
+ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+ pTempIndices[nTempIndices] = nPos;
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pUnoArgs[nPos] =
+ alloca( pParamTypeDescr->nSize ),
+ pCppArgs[nPos], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ pTempIndices[nTempIndices] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pUnoArgs[nPos] = pCppArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ }
+ }
+
+ // ExceptionHolder
+ uno_Any aUnoExc; // Any will be constructed by callee
+ uno_Any * pUnoExc = &aUnoExc;
+
+ // invoke uno dispatch call
+ (*pThis->getUnoI()->pDispatcher)(
+ pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+ // in case an exception occurred...
+ if (pUnoExc)
+ {
+ // destruct temporary in/inout params
+ for ( ; nTempIndices--; )
+ {
+ int nIndex = pTempIndices[nTempIndices];
+
+ if (pParams[nIndex].bIn) // is in/inout => was constructed
+ uno_destructData( pUnoArgs[nIndex],
+ ppTempParamTypeDescr[nTempIndices], 0 );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
+ }
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+ CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc,
+ pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
+ // is here for dummy
+ return typelib_TypeClass_VOID;
+ }
+ else // else no exception occurred...
+ {
+ // temporary params
+ for ( ; nTempIndices--; )
+ {
+ int nIndex = pTempIndices[nTempIndices];
+ typelib_TypeDescription * pParamTypeDescr =
+ ppTempParamTypeDescr[nTempIndices];
+
+ if (pParams[nIndex].bOut) // inout/out
+ {
+ // convert and assign
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr,
+ cpp_release );
+ uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex],
+ pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+ }
+ // destroy temp uno param
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return
+ if (pCppReturn) // has complex return
+ {
+ if (pUnoReturn != pCppReturn) // needs reconversion
+ {
+ uno_copyAndConvertData( pCppReturn, pUnoReturn,
+ pReturnTypeDescr, pThis->getBridge()->getUno2Cpp() );
+ // destroy temp uno return
+ uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+ }
+ *(void **)pRegisterReturn = pCppReturn;
+ }
+ if (pReturnTypeDescr)
+ {
+ typelib_TypeClass eRet =
+ (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ return eRet;
+ }
+ else
+ return typelib_TypeClass_VOID;
+ }
+ }
+
+ static typelib_TypeClass cpp_mediate( sal_Int32 nFunctionIndex,
+ sal_Int32 nVtableOffset,
+ void ** pCallStack,
+ sal_Int64 * pRegisterReturn )
+ {
+ // pCallStack: x8, lr, d0..d7, x0..x7, rest of params originally on stack
+ // _this_ ptr is patched cppu_XInterfaceProxy object
+ void *pThis = pCallStack[2 + 8];
+
+ pThis = static_cast< char * >(pThis) - nVtableOffset;
+ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
+ bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+ pThis);
+
+ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+ // determine called method
+ assert( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex );
+
+ if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+ {
+ throw RuntimeException( "illegal vtable index!", (XInterface *)pCppI );
+ }
+
+ sal_Int32 nMemberPos =
+ pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+ assert( nMemberPos < pTypeDescr->nAllMembers );
+
+ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+ typelib_TypeClass eRet;
+ switch (aMemberDescr.get()->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
+ nFunctionIndex)
+ {
+ // is GET method
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+ 0, 0, // no params
+ pCallStack, pRegisterReturn );
+ }
+ else
+ {
+ // is SET method
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ 0, // indicates void return
+ 1, &aParam,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // is METHOD
+ switch (nFunctionIndex)
+ {
+ case 1: // acquire()
+ pCppI->acquireProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 2: // release()
+ pCppI->releaseProxy(); // non virtual call!
+ eRet = typelib_TypeClass_VOID;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET(&pTD,
+ reinterpret_cast<Type *>(pCallStack[2])->getTypeLibType());
+ if (pTD)
+ {
+ XInterface * pInterface = 0;
+ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+ pCppI->getBridge()->getCppEnv(),
+ (void **)&pInterface, pCppI->getOid().pData,
+ (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pCallStack[0] ),
+ &pInterface, pTD, cpp_acquire );
+ pInterface->release();
+ TYPELIB_DANGER_RELEASE( pTD );
+ *(void **)pRegisterReturn = pCallStack[0];
+ eRet = typelib_TypeClass_ANY;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ SAL_FALLTHROUGH;
+ default:
+ eRet = cpp2uno_call(
+ pCppI, aMemberDescr.get(),
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+ pCallStack, pRegisterReturn );
+ }
+ break;
+ }
+ default:
+ {
+ throw RuntimeException( "no member description found!", (XInterface *)pCppI );
+ }
+ }
+
+ return eRet;
+ }
+}
+
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+
+extern "C" sal_Int64 cpp_vtable_call( sal_Int32 *pFunctionAndOffset,
+ void **pCallStack )
+{
+ sal_Int64 nRegReturn;
+ typelib_TypeClass aType = cpp_mediate( pFunctionAndOffset[0], pFunctionAndOffset[1], pCallStack, &nRegReturn );
+
+ switch( aType )
+ {
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ nRegReturn = (unsigned long)(*(unsigned char *)&nRegReturn);
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_SHORT:
+ nRegReturn = (unsigned long)(*(unsigned short *)&nRegReturn);
+ break;
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_LONG:
+ nRegReturn = (unsigned long)(*(unsigned int *)&nRegReturn);
+ break;
+ case typelib_TypeClass_VOID:
+ default:
+ break;
+ }
+
+ return nRegReturn;
+}
+
+#ifdef __arm64
+namespace
+{
+ unsigned char *codeSnippet(const typelib_InterfaceTypeDescription *type,
+ const typelib_TypeDescription *member,
+ sal_Int32 functionIndex,
+ sal_Int32 vtableOffset)
+ {
+ assert(functionIndex < nFunIndexes);
+ if (!(functionIndex < nFunIndexes))
+ return NULL;
+
+ assert(vtableOffset < nVtableOffsets);
+ if (!(vtableOffset < nVtableOffsets))
+ return NULL;
+
+ // The codeSnippets table is indexed by functionIndex and vtableOffset
+
+ int index = functionIndex*nVtableOffsets + vtableOffset;
+ unsigned char *result = ((unsigned char *) &codeSnippets) + codeSnippets[index];
+
+ SAL_INFO( "bridges.ios", "codeSnippet(" << OUString(type->aBase.pTypeName) << "::" << OUString(member->pTypeName) << "): [" << functionIndex << "," << vtableOffset << "]=" << (void *) result << " (" << std::hex << ((int*)result)[0] << "," << ((int*)result)[1] << "," << ((int*)result)[2] << "," << ((int*)result)[3] << ")");
+
+ return result;
+ }
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+ return static_cast< Slot * >(block) + 2;
+}
+
+std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+ sal_Int32 slotCount)
+{
+ return (slotCount + 2) * sizeof (Slot);
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+ void * block, sal_Int32 slotCount, sal_Int32,
+ typelib_InterfaceTypeDescription *)
+{
+ Slot * slots = mapBlockToVtable(block);
+ slots[-2].fn = 0;
+ slots[-1].fn = 0;
+ return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+ Slot ** slots,
+ unsigned char * code,
+ typelib_InterfaceTypeDescription const * type,
+ sal_Int32 functionOffset,
+ sal_Int32 functionCount,
+ sal_Int32 vtableOffset)
+{
+ (*slots) -= functionCount;
+ Slot * s = *slots;
+ for (sal_Int32 i = 0; i < type->nMembers; ++i)
+ {
+ typelib_TypeDescription * member = 0;
+ TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+ assert(member != 0);
+ switch (member->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ typelib_InterfaceAttributeTypeDescription *pAttrTD =
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( member );
+
+ // Getter:
+ (s++)->fn = codeSnippet( type, member, functionOffset++, vtableOffset );
+
+ // Setter:
+ if (!pAttrTD->bReadOnly)
+ {
+ (s++)->fn = codeSnippet( type, member, functionOffset++, vtableOffset );
+ }
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ (s++)->fn = codeSnippet( type, member, functionOffset++, vtableOffset );
+ break;
+ }
+ default:
+ assert(false);
+ break;
+ }
+ TYPELIB_DANGER_RELEASE(member);
+ }
+ return code;
+}
+#endif
+
+
void bridges::cpp_uno::shared::VtableFactory::flushCode(
unsigned char const *, unsigned char const *)
{
diff --git a/bridges/source/cpp_uno/gcc3_ios/share.hxx b/bridges/source/cpp_uno/gcc3_ios/share.hxx
index 589f4ba7a174..bcddcdb1f807 100644
--- a/bridges/source/cpp_uno/gcc3_ios/share.hxx
+++ b/bridges/source/cpp_uno/gcc3_ios/share.hxx
@@ -49,19 +49,11 @@ namespace CPPU_CURRENT_NAMESPACE
namespace arm
{
-#if defined(__arm)
- enum armlimits {
- MAX_GPR_REGS = 4,
- MAX_FPR_REGS = 8
- };
- bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
-#elif defined(__arm64)
enum armlimits {
MAX_GPR_REGS = 8,
MAX_FPR_REGS = 8
};
bool return_in_x8( typelib_TypeDescriptionReference *pTypeRef );
-#endif
}
#endif
diff --git a/bridges/source/cpp_uno/gcc3_ios/uno2cpp-arm64.cxx b/bridges/source/cpp_uno/gcc3_ios/uno2cpp-arm64.cxx
deleted file mode 100644
index 7915fa7a9513..000000000000
--- a/bridges/source/cpp_uno/gcc3_ios/uno2cpp-arm64.cxx
+++ /dev/null
@@ -1,557 +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 .
- */
-
-#ifdef __arm64
-
-#include <com/sun/star/uno/RuntimeException.hpp>
-
-#include "bridge.hxx"
-#include "types.hxx"
-#include "unointerfaceproxy.hxx"
-#include "vtables.hxx"
-
-#include "share.hxx"
-
-using namespace ::com::sun::star::uno;
-
-namespace arm
-{
- bool is_hfa_struct(const typelib_TypeDescription * type)
- {
- const typelib_CompoundTypeDescription * p
- = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
- if (p->nMembers >= 4)
- return false;
- for (sal_Int32 i = 0; i < p->nMembers; ++i)
- {
- if ((p->ppTypeRefs[i]->eTypeClass != typelib_TypeClass_FLOAT &&
- p->ppTypeRefs[i]->eTypeClass != typelib_TypeClass_DOUBLE) ||
- p->ppTypeRefs[i]->eTypeClass != p->ppTypeRefs[0]->eTypeClass)
- return false;
- }
- return true;
- }
-
- bool return_in_x8( typelib_TypeDescriptionReference *pTypeRef )
- {
- if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
- return false;
- else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
- {
- typelib_TypeDescription * pTypeDescr = 0;
- TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
-
- // A Composite Type not larger than 16 bytes is returned in x0, x1
- bool bRet = pTypeDescr->nSize > 16;
-
- if (is_hfa_struct(pTypeDescr))
- bRet = false;
-
- TYPELIB_DANGER_RELEASE( pTypeDescr );
- return bRet;
- }
- return true;
- }
-}
-
-void MapReturn(sal_uInt64 x0, sal_uInt64 x1, typelib_TypeDescriptionReference *pReturnType, sal_uInt64 *pRegisterReturn)
-{
- switch( pReturnType->eTypeClass )
- {
- case typelib_TypeClass_HYPER:
- case typelib_TypeClass_UNSIGNED_HYPER:
- pRegisterReturn[1] = x1;
- SAL_FALLTHROUGH;
- case typelib_TypeClass_LONG:
- case typelib_TypeClass_UNSIGNED_LONG:
- case typelib_TypeClass_ENUM:
- case typelib_TypeClass_CHAR:
- case typelib_TypeClass_SHORT:
- case typelib_TypeClass_UNSIGNED_SHORT:
- case typelib_TypeClass_BOOLEAN:
- case typelib_TypeClass_BYTE:
- pRegisterReturn[0] = x0;
- break;
- case typelib_TypeClass_FLOAT:
- register float fret asm("s0");
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wuninitialized"
- *(float*)pRegisterReturn = fret;
-#pragma GCC diagnostic pop
- break;
- case typelib_TypeClass_DOUBLE:
- register double dret asm("d0");
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wuninitialized"
- *(double*)pRegisterReturn = dret;
-#pragma GCC diagnostic pop
- break;
- case typelib_TypeClass_STRUCT:
- case typelib_TypeClass_EXCEPTION:
- if (!arm::return_in_x8(pReturnType))
- {
- pRegisterReturn[0] = x0;
- pRegisterReturn[1] = x1;
- }
- break;
- default:
- break;
- }
-}
-
-namespace
-{
-void callVirtualMethod(
- void *pThis,
- sal_Int32 nVtableIndex,
- void *pRegisterReturn,
- typelib_TypeDescriptionReference *pReturnType,
- sal_uInt64 *pStack,
- int nStack,
- sal_uInt64 *pGPR,
- double *pFPR)
-{
- // never called
- if (! pThis)
- CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
-
- if ( nStack )
- {
- // 16-bytes aligned
- sal_uInt32 nStackBytes = ( ( nStack + 3 ) >> 2 ) * 16;
- sal_uInt32 *stack = (sal_uInt32 *) alloca( nStackBytes );
- memcpy( stack, pStack, nStackBytes );
- }
-
- sal_uInt64 pMethod = *((sal_uInt64*)pThis);
- pMethod += 8 * nVtableIndex;
- pMethod = *((sal_uInt64 *)pMethod);
-
- // For value returned in registers
- sal_uInt64 x0;
- sal_uInt64 x1;
-
- __asm__ __volatile__
- (
- " ldp x0, x1, %[pgpr_0]\n"
- " ldp x2, x3, %[pgpr_2]\n"
- " ldp x4, x5, %[pgpr_4]\n"
- " ldp x6, x7, %[pgpr_6]\n"
- " ldr x8, %[pregisterreturn]\n"
- " ldp d0, d1, %[pfpr_0]\n"
- " ldp d2, d3, %[pfpr_2]\n"
- " ldp d4, d5, %[pfpr_4]\n"
- " ldp d6, d7, %[pfpr_6]\n"
- " blr %[pmethod]\n"
- " str x0, %[x0]\n"
- " str x1, %[x1]\n"
- : [x0]"=m" (x0), [x1]"=m" (x1)
- : [pgpr_0]"m" (pGPR[0]),
- [pgpr_2]"m" (pGPR[2]),
- [pgpr_4]"m" (pGPR[4]),
- [pgpr_6]"m" (pGPR[6]),
- [pregisterreturn]"m" (pRegisterReturn),
- [pfpr_0]"m" (pFPR[0]),
- [pfpr_2]"m" (pFPR[2]),
- [pfpr_4]"m" (pFPR[4]),
- [pfpr_6]"m" (pFPR[6]),
- [pmethod]"r" (pMethod)
- : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7"
- );
-
- MapReturn(x0, x1, pReturnType, (sal_uInt64 *) pRegisterReturn);
-}
-}
-
-#define INSERT_INT64( pSV, nr, pGPR, pDS ) \
- if ( nr < arm::MAX_GPR_REGS ) \
- pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
- else \
- *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
-
-#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
- if ( nr < arm::MAX_GPR_REGS ) \
- pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
- else \
- *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
-
-#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
- if ( nr < arm::MAX_GPR_REGS ) \
- pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
- else \
- *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
-
-#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
- if ( nr < arm::MAX_GPR_REGS ) \
- pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
- else \
- *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
-
-#define INSERT_DOUBLE( pSV, nr, pFPR, pDS ) \
- if ( nr < arm::MAX_FPR_REGS ) \
- pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
- else \
- *pDS++ = *reinterpret_cast<double *>( pSV );
-
-#define INSERT_FLOAT( pSV, nr, pFPR, pDS ) \
- INSERT_DOUBLE( pSV, nr, pGPR, pDS )
-
-namespace {
-static void cpp_call(
- bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
- bridges::cpp_uno::shared::VtableSlot aVtableSlot,
- typelib_TypeDescriptionReference * pReturnTypeRef,
- sal_Int32 nParams, typelib_MethodParameter * pParams,
- void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
-{
- // max space for: values|ptr ...
- sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+2) * sizeof(sal_Int64) );
- sal_uInt64 * pStackStart = pStack;
-
- sal_uInt64 pGPR[arm::MAX_GPR_REGS];
- int nGPR = 0;
-
- // storage and counter for SIMD/FP registers
- double pFPR[arm::MAX_FPR_REGS];
- int nFPR = 0;
-
- // return
- typelib_TypeDescription * pReturnTypeDescr = 0;
- TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
- assert( pReturnTypeDescr);
-
- void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
-
- if (pReturnTypeDescr)
- {
- if (!arm::return_in_x8( pReturnTypeRef ) )
- pCppReturn = pUnoReturn; // direct way for simple types
- else
- {
- // complex return via x8
- pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
- ? alloca( pReturnTypeDescr->nSize )
- : pUnoReturn); // direct way
- }
- }
- // push this
- void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
- + aVtableSlot.offset;
- INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
-
- // stack space
- // args
- void ** pCppArgs = (void **)alloca( sizeof(void *) * nParams );
-
- // indices of values this have to be converted (interface conversion cpp<=>uno)
- int * pTempIndices = (int *)alloca( sizeof(int) * nParams );
-
- // type descriptions for reconversions
- typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)alloca( sizeof(void *) * nParams );
-
- sal_Int32 nTempIndices = 0;
-
- for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
- {
- const typelib_MethodParameter & rParam = pParams[nPos];
- typelib_TypeDescription * pParamTypeDescr = 0;
- TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
-
- if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
- {
- uno_copyAndConvertData( pCppArgs[nPos] = alloca(8), pUnoArgs[nPos],
- pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
-
- switch (pParamTypeDescr->eTypeClass)
- {
- case typelib_TypeClass_HYPER:
- case typelib_TypeClass_UNSIGNED_HYPER:
- INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack );
- break;
- case typelib_TypeClass_LONG:
- case typelib_TypeClass_UNSIGNED_LONG:
- case typelib_TypeClass_ENUM:
- INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack );
- break;
- case typelib_TypeClass_SHORT:
- case typelib_TypeClass_CHAR:
- case typelib_TypeClass_UNSIGNED_SHORT:
- INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack );
- break;
- case typelib_TypeClass_BOOLEAN:
- case typelib_TypeClass_BYTE:
- INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack );
- break;
- case typelib_TypeClass_FLOAT:
- INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, pStack );
- break;
- case typelib_TypeClass_DOUBLE:
- INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack );
- break;
- default:
- break;
- }
- // no longer needed
- TYPELIB_DANGER_RELEASE( pParamTypeDescr );
- }
- else // ptr to complex value | ref
- {
- if (! rParam.bIn) // is pure out
- {
- // cpp out is constructed mem, uno out is not!
- uno_constructData(
- pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
- pParamTypeDescr );
- pTempIndices[nTempIndices] = nPos; // default constructed for cpp call
- // will be released at reconversion
- ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
- }
- // is in/inout
- else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
- {
- uno_copyAndConvertData(
- pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
- pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
-
- pTempIndices[nTempIndices] = nPos; // has to be reconverted
- // will be released at reconversion
- ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
- }
- else // direct way
- {
- pCppArgs[nPos] = pUnoArgs[nPos];
- // no longer needed
- TYPELIB_DANGER_RELEASE( pParamTypeDescr );
- }
- INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
- }
- }
-
- assert( nGPR <= arm::MAX_GPR_REGS );
- assert( nFPR <= arm::MAX_FPR_REGS );
-
- try
- {
- callVirtualMethod(
- pAdjustedThisPtr, aVtableSlot.index,
- pCppReturn, pReturnTypeRef,
- pStackStart,
- (pStack - pStackStart),
- pGPR,
- pFPR);
-
- // NO exception occurred...
- *ppUnoExc = 0;
-
- // reconvert temporary params
- for ( ; nTempIndices--; )
- {
- sal_Int32 nIndex = pTempIndices[nTempIndices];
- typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
-
- if (pParams[nIndex].bIn)
- {
- if (pParams[nIndex].bOut) // inout
- {
- uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
- uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
- pThis->getBridge()->getCpp2Uno() );
- }
- }
- else // pure out
- {
- uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
- pThis->getBridge()->getCpp2Uno() );
- }
- // destroy temp cpp param => cpp: every param was constructed
- uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
-
- TYPELIB_DANGER_RELEASE( pParamTypeDescr );
- }
- // return value
- if (pCppReturn && pUnoReturn != pCppReturn)
- {
- uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
- pThis->getBridge()->getCpp2Uno() );
- uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
- }
- }
- catch (...)
- {
- // fill uno exception
- CPPU_CURRENT_NAMESPACE::fillUnoException( abi::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
-
- // temporary params
- for ( ; nTempIndices--; )
- {
- sal_Int32 nIndex = pTempIndices[nTempIndices];
- // destroy temp cpp param => cpp: every param was constructed
- uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndices], cpp_release );
- TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
- }
-
- // return type
- if (pReturnTypeDescr)
- TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
- }
-}
-}
-
-namespace bridges { namespace cpp_uno { namespace shared {
-
-void unoInterfaceProxyDispatch(
- uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
- void * pReturn, void * pArgs[], uno_Any ** ppException )
-{
- // is my surrogate
- bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
- = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
-#if OSL_DEBUG_LEVEL > 0
- typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
-#endif
-
- switch (pMemberDescr->eTypeClass)
- {
- case typelib_TypeClass_INTERFACE_ATTRIBUTE:
- {
-#if OSL_DEBUG_LEVEL > 0
- // determine vtable call index
- sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
- assert( nMemberPos < pTypeDescr->nAllMembers && "### member pos out of range!");
-#endif
-
- VtableSlot aVtableSlot(
- getVtableSlot(
- reinterpret_cast<typelib_InterfaceAttributeTypeDescription const *>
- (pMemberDescr)));
-
- if (pReturn)
- {
- // dependent dispatch
- cpp_call(
- pThis, aVtableSlot,
- ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
- 0, 0, // no params
- pReturn, pArgs, ppException );
- }
- else
- {
- // is SET
- typelib_MethodParameter aParam;
- aParam.pTypeRef =
- ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
- aParam.bIn = sal_True;
- aParam.bOut = sal_False;
-
- typelib_TypeDescriptionReference * pReturnTypeRef = 0;
- OUString aVoidName("void");
- typelib_typedescriptionreference_new(
- &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
-
- // dependent dispatch
- aVtableSlot.index += 1;
- cpp_call(
- pThis, aVtableSlot, // get, then set method
- pReturnTypeRef,
- 1, &aParam,
- pReturn, pArgs, ppException );
-
- typelib_typedescriptionreference_release( pReturnTypeRef );
- }
-
- break;
- }
- case typelib_TypeClass_INTERFACE_METHOD:
- {
-#if OSL_DEBUG_LEVEL > 0
- // determine vtable call index
- sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
- assert(nMemberPos < pTypeDescr->nAllMembers && "### member pos out of range!");
-#endif
-
- VtableSlot aVtableSlot(
- getVtableSlot(
- reinterpret_cast<typelib_InterfaceMethodTypeDescription const *>
- (pMemberDescr)));
-
- switch (aVtableSlot.index)
- {
- // standard calls
- case 1: // acquire uno interface
- (*pUnoI->acquire)( pUnoI );
- *ppException = 0;
- break;
- case 2: // release uno interface
- (*pUnoI->release)( pUnoI );
- *ppException = 0;
- break;
- case 0: // queryInterface() opt
- {
- typelib_TypeDescription * pTD = 0;
- TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
- if (pTD)
- {
- uno_Interface * pInterface = 0;
- (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
- pThis->getBridge()->getUnoEnv(),
- (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
-
- if (pInterface)
- {
- ::uno_any_construct(
- reinterpret_cast< uno_Any * >( pReturn ),
- &pInterface, pTD, 0 );
- (*pInterface->release)( pInterface );
- TYPELIB_DANGER_RELEASE( pTD );
- *ppException = 0;
- break;
- }
- TYPELIB_DANGER_RELEASE( pTD );
- }
- } // else perform queryInterface()
- SAL_FALLTHROUGH;
- default:
- // dependent dispatch
- cpp_call(
- pThis, aVtableSlot,
- ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
- ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
- ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
- pReturn, pArgs, ppException );
- }
- break;
- }
- default:
- {
- ::com::sun::star::uno::RuntimeException aExc(
- "illegal member type description!",
- ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
-
- Type const & rExcType = cppu::UnoType<decltype(aExc)>::get();
- // binary identical null reference
- ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
- }
- }
-}
-
-} } }
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_ios/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_ios/uno2cpp.cxx
index 17bd59583737..6d2c82fbe0d4 100644
--- a/bridges/source/cpp_uno/gcc3_ios/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/gcc3_ios/uno2cpp.cxx
@@ -17,6 +17,8 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include <com/sun/star/uno/RuntimeException.hpp>
+
#include "bridge.hxx"
#include "types.hxx"
#include "unointerfaceproxy.hxx"
@@ -26,4 +28,529 @@
using namespace ::com::sun::star::uno;
+#ifdef __arm64
+namespace arm
+{
+ bool is_hfa_struct(const typelib_TypeDescription * type)
+ {
+ const typelib_CompoundTypeDescription * p
+ = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
+ if (p->nMembers >= 4)
+ return false;
+ for (sal_Int32 i = 0; i < p->nMembers; ++i)
+ {
+ if ((p->ppTypeRefs[i]->eTypeClass != typelib_TypeClass_FLOAT &&
+ p->ppTypeRefs[i]->eTypeClass != typelib_TypeClass_DOUBLE) ||
+ p->ppTypeRefs[i]->eTypeClass != p->ppTypeRefs[0]->eTypeClass)
+ return false;
+ }
+ return true;
+ }
+
+ bool return_in_x8( typelib_TypeDescriptionReference *pTypeRef )
+ {
+ if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
+ return false;
+ else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+ // A Composite Type not larger than 16 bytes is returned in x0, x1
+ bool bRet = pTypeDescr->nSize > 16;
+
+ if (is_hfa_struct(pTypeDescr))
+ bRet = false;
+
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ return bRet;
+ }
+ return true;
+ }
+}
+
+void MapReturn(sal_uInt64 x0, sal_uInt64 x1, typelib_TypeDescriptionReference *pReturnType, sal_uInt64 *pRegisterReturn)
+{
+ switch( pReturnType->eTypeClass )
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ pRegisterReturn[1] = x1;
+ SAL_FALLTHROUGH;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ pRegisterReturn[0] = x0;
+ break;
+ case typelib_TypeClass_FLOAT:
+ register float fret asm("s0");
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wuninitialized"
+ *(float*)pRegisterReturn = fret;
+#pragma GCC diagnostic pop
+ break;
+ case typelib_TypeClass_DOUBLE:
+ register double dret asm("d0");
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wuninitialized"
+ *(double*)pRegisterReturn = dret;
+#pragma GCC diagnostic pop
+ break;
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_EXCEPTION:
+ if (!arm::return_in_x8(pReturnType))
+ {
+ pRegisterReturn[0] = x0;
+ pRegisterReturn[1] = x1;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+namespace
+{
+void callVirtualMethod(
+ void *pThis,
+ sal_Int32 nVtableIndex,
+ void *pRegisterReturn,
+ typelib_TypeDescriptionReference *pReturnType,
+ sal_uInt64 *pStack,
+ int nStack,
+ sal_uInt64 *pGPR,
+ double *pFPR)
+{
+ // never called
+ if (! pThis)
+ CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+ if ( nStack )
+ {
+ // 16-bytes aligned
+ sal_uInt32 nStackBytes = ( ( nStack + 3 ) >> 2 ) * 16;
+ sal_uInt32 *stack = (sal_uInt32 *) alloca( nStackBytes );
+ memcpy( stack, pStack, nStackBytes );
+ }
+
+ sal_uInt64 pMethod = *((sal_uInt64*)pThis);
+ pMethod += 8 * nVtableIndex;
+ pMethod = *((sal_uInt64 *)pMethod);
+
+ // For value returned in registers
+ sal_uInt64 x0;
+ sal_uInt64 x1;
+
+ __asm__ __volatile__
+ (
+ " ldp x0, x1, %[pgpr_0]\n"
+ " ldp x2, x3, %[pgpr_2]\n"
+ " ldp x4, x5, %[pgpr_4]\n"
+ " ldp x6, x7, %[pgpr_6]\n"
+ " ldr x8, %[pregisterreturn]\n"
+ " ldp d0, d1, %[pfpr_0]\n"
+ " ldp d2, d3, %[pfpr_2]\n"
+ " ldp d4, d5, %[pfpr_4]\n"
+ " ldp d6, d7, %[pfpr_6]\n"
+ " blr %[pmethod]\n"
+ " str x0, %[x0]\n"
+ " str x1, %[x1]\n"
+ : [x0]"=m" (x0), [x1]"=m" (x1)
+ : [pgpr_0]"m" (pGPR[0]),
+ [pgpr_2]"m" (pGPR[2]),
+ [pgpr_4]"m" (pGPR[4]),
+ [pgpr_6]"m" (pGPR[6]),
+ [pregisterreturn]"m" (pRegisterReturn),
+ [pfpr_0]"m" (pFPR[0]),
+ [pfpr_2]"m" (pFPR[2]),
+ [pfpr_4]"m" (pFPR[4]),
+ [pfpr_6]"m" (pFPR[6]),
+ [pmethod]"r" (pMethod)
+ : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7"
+ );
+
+ MapReturn(x0, x1, pReturnType, (sal_uInt64 *) pRegisterReturn);
+}
+}
+
+#define INSERT_INT64( pSV, nr, pGPR, pDS ) \
+ if ( nr < arm::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
+ if ( nr < arm::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
+ if ( nr < arm::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
+ if ( nr < arm::MAX_GPR_REGS ) \
+ pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
+
+#define INSERT_DOUBLE( pSV, nr, pFPR, pDS ) \
+ if ( nr < arm::MAX_FPR_REGS ) \
+ pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
+ else \
+ *pDS++ = *reinterpret_cast<double *>( pSV );
+
+#define INSERT_FLOAT( pSV, nr, pFPR, pDS ) \
+ INSERT_DOUBLE( pSV, nr, pGPR, pDS )
+
+namespace {
+static void cpp_call(
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
+ bridges::cpp_uno::shared::VtableSlot aVtableSlot,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // max space for: values|ptr ...
+ sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+2) * sizeof(sal_Int64) );
+ sal_uInt64 * pStackStart = pStack;
+
+ sal_uInt64 pGPR[arm::MAX_GPR_REGS];
+ int nGPR = 0;
+
+ // storage and counter for SIMD/FP registers
+ double pFPR[arm::MAX_FPR_REGS];
+ int nFPR = 0;
+
+ // return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ assert( pReturnTypeDescr);
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (!arm::return_in_x8( pReturnTypeRef ) )
+ pCppReturn = pUnoReturn; // direct way for simple types
+ else
+ {
+ // complex return via x8
+ pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ }
+ }
+ // push this
+ void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+ + aVtableSlot.offset;
+ INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
+
+ // stack space
+ // args
+ void ** pCppArgs = (void **)alloca( sizeof(void *) * nParams );
+
+ // indices of values this have to be converted (interface conversion cpp<=>uno)
+ int * pTempIndices = (int *)alloca( sizeof(int) * nParams );
+
+ // type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)alloca( sizeof(void *) * nParams );
+
+ sal_Int32 nTempIndices = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ const typelib_MethodParameter & rParam = pParams[nPos];
+ typelib_TypeDescription * pParamTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+ if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = alloca(8), pUnoArgs[nPos],
+ pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack );
+ break;
+ case typelib_TypeClass_FLOAT:
+ INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, pStack );
+ break;
+ case typelib_TypeClass_DOUBLE:
+ INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack );
+ break;
+ default:
+ break;
+ }
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ else // ptr to complex value | ref
+ {
+ if (! rParam.bIn) // is pure out
+ {
+ // cpp out is constructed mem, uno out is not!
+ uno_constructData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndices[nTempIndices] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+ pTempIndices[nTempIndices] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
+ }
+ }
+
+ assert( nGPR <= arm::MAX_GPR_REGS );
+ assert( nFPR <= arm::MAX_FPR_REGS );
+
+ try
+ {
+ callVirtualMethod(
+ pAdjustedThisPtr, aVtableSlot.index,
+ pCppReturn, pReturnTypeRef,
+ pStackStart,
+ (pStack - pStackStart),
+ pGPR,
+ pFPR);
+
+ // NO exception occurred...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndices--; )
+ {
+ sal_Int32 nIndex = pTempIndices[nTempIndices];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
+
+ if (pParams[nIndex].bIn)
+ {
+ if (pParams[nIndex].bOut) // inout
+ {
+ uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ }
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // return value
+ if (pCppReturn && pUnoReturn != pCppReturn)
+ {
+ uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+ pThis->getBridge()->getCpp2Uno() );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ CPPU_CURRENT_NAMESPACE::fillUnoException( abi::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+ // temporary params
+ for ( ; nTempIndices--; )
+ {
+ sal_Int32 nIndex = pTempIndices[nTempIndices];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndices], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
+ }
+
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // is my surrogate
+ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+ = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+#if OSL_DEBUG_LEVEL > 0
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+#endif
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ assert( nMemberPos < pTypeDescr->nAllMembers && "### member pos out of range!");
+#endif
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<typelib_InterfaceAttributeTypeDescription const *>
+ (pMemberDescr)));
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
+ 0, 0, // no params
+ pReturn, pArgs, ppException );
+ }
+ else
+ {
+ // is SET
+ typelib_MethodParameter aParam;
+ aParam.pTypeRef =
+ ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
+ aParam.bIn = sal_True;
+ aParam.bOut = sal_False;
+
+ typelib_TypeDescriptionReference * pReturnTypeRef = 0;
+ OUString aVoidName("void");
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ aVtableSlot.index += 1;
+ cpp_call(
+ pThis, aVtableSlot, // get, then set method
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+#if OSL_DEBUG_LEVEL > 0
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ assert(nMemberPos < pTypeDescr->nAllMembers && "### member pos out of range!");
+#endif
+
+ VtableSlot aVtableSlot(
+ getVtableSlot(
+ reinterpret_cast<typelib_InterfaceMethodTypeDescription const *>
+ (pMemberDescr)));
+
+ switch (aVtableSlot.index)
+ {
+ // standard calls
+ case 1: // acquire uno interface
+ (*pUnoI->acquire)( pUnoI );
+ *ppException = 0;
+ break;
+ case 2: // release uno interface
+ (*pUnoI->release)( pUnoI );
+ *ppException = 0;
+ break;
+ case 0: // queryInterface() opt
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
+ if (pTD)
+ {
+ uno_Interface * pInterface = 0;
+ (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
+ pThis->getBridge()->getUnoEnv(),
+ (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
+
+ if (pInterface)
+ {
+ ::uno_any_construct(
+ reinterpret_cast< uno_Any * >( pReturn ),
+ &pInterface, pTD, 0 );
+ (*pInterface->release)( pInterface );
+ TYPELIB_DANGER_RELEASE( pTD );
+ *ppException = 0;
+ break;
+ }
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ } // else perform queryInterface()
+ SAL_FALLTHROUGH;
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, aVtableSlot,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ "illegal member type description!",
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = cppu::UnoType<decltype(aExc)>::get();
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+} } }
+
+#endif
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */