summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens-Heiner Rechtien <hr@openoffice.org>2004-03-09 11:11:38 +0000
committerJens-Heiner Rechtien <hr@openoffice.org>2004-03-09 11:11:38 +0000
commite7bb65abf8c794152b18d44a88ac682412900528 (patch)
treefc230dd939e326f2676dcc87e165eb9b5c24030c
parentc85cdbd9253f760ddff3a4a70e85945ca76c8e09 (diff)
INTEGRATION: CWS ooo20040225 (1.1.2); FILE ADDED
2004/02/16 18:46:55 fa 1.1.2.1: #i25564# Add preliminary bridge code for x86-64
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx120
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx662
2 files changed, 782 insertions, 0 deletions
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx
new file mode 100644
index 000000000..89b220eb8
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/share.hxx
@@ -0,0 +1,120 @@
+/*************************************************************************
+ *
+ * $RCSfile: share.hxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: hr $ $Date: 2004-03-09 12:11:26 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <typeinfo>
+#include <exception>
+#include <cstddef>
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h
+
+struct _Unwind_Exception
+{
+ unsigned exception_class __attribute__((__mode__(__DI__)));
+ void * exception_cleanup;
+ unsigned private_1 __attribute__((__mode__(__word__)));
+ unsigned private_2 __attribute__((__mode__(__word__)));
+} __attribute__((__aligned__));
+
+struct __cxa_exception
+{
+ ::std::type_info *exceptionType;
+ void (*exceptionDestructor)(void *);
+
+ ::std::unexpected_handler unexpectedHandler;
+ ::std::terminate_handler terminateHandler;
+
+ __cxa_exception *nextException;
+
+ int handlerCount;
+
+ int handlerSwitchValue;
+ const unsigned char *actionRecord;
+ const unsigned char *languageSpecificData;
+ void *catchTemp;
+ void *adjustedPtr;
+
+ _Unwind_Exception unwindHeader;
+};
+
+extern "C" void *__cxa_allocate_exception(
+ std::size_t thrown_size ) throw();
+extern "C" void __cxa_throw (
+ void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));
+
+struct __cxa_eh_globals
+{
+ __cxa_exception *caughtExceptions;
+ unsigned int uncaughtExceptions;
+};
+extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
+
+// -----
+
+//==================================================================================================
+void raiseException(
+ uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
+//==================================================================================================
+void fillUnoException(
+ __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
+}
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx
new file mode 100644
index 000000000..5d90d1ea9
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx
@@ -0,0 +1,662 @@
+/*************************************************************************
+ *
+ * $RCSfile: uno2cpp.cxx,v $
+ *
+ * $Revision: 1.2 $
+ *
+ * last change: $Author: hr $ $Date: 2004-03-09 12:11:38 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (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.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <rtl/alloc.h>
+
+#include <uno/data.h>
+#include <bridges/cpp_uno/bridge.hxx>
+#include <bridges/cpp_uno/type_misc.hxx>
+
+#include "share.hxx"
+
+using namespace ::rtl;
+using namespace ::com::sun::star::uno;
+
+namespace CPPU_CURRENT_NAMESPACE
+{
+
+void dummy_can_throw_anything( char const * );
+
+// 6 integral parameters are passed in registers
+const sal_uInt32 GPR_COUNT = 6;
+
+// 8 floating point parameters are passed in SSE registers
+const sal_uInt32 FPR_COUNT = 8;
+
+static inline void
+invoke_count_words(char * pPT, // Parameter Types
+ sal_uInt32 & nr_gpr, // Number of arguments in GPRs
+ sal_uInt32 & nr_fpr, // Number of arguments in FPRs
+ sal_uInt32 & nr_stack) // Number of arguments in stack
+{
+ nr_gpr = 0;
+ nr_fpr = 0;
+ nr_stack = 0;
+ char c;
+
+ while ((c = *pPT++) != 'X')
+ {
+ if (c == 'F' || c == 'D')
+ {
+ if (nr_fpr < FPR_COUNT)
+ nr_fpr++;
+ else
+ nr_stack++;
+ }
+ else
+ {
+ if (nr_gpr < GPR_COUNT)
+ nr_gpr++;
+ else
+ nr_stack++;
+ }
+ }
+}
+
+static void
+invoke_copy_to_stack(sal_uInt64 * pDS, // Stack Storage
+ char * pPT, // Parameter Types
+ sal_uInt64 * pSV, // Source Values
+ sal_uInt64 * pGPR, // General Purpose Registers
+ double * pFPR) // Floating-Point Registers
+{
+ sal_uInt32 nr_gpr = 0;
+ sal_uInt32 nr_fpr = 0;
+ sal_uInt64 value;
+ char c;
+
+ while ((c = *pPT++) != 'X')
+ {
+ switch (c)
+ {
+ case 'D': // Double
+ if (nr_fpr < FPR_COUNT)
+ pFPR[nr_fpr++] = (double)*pSV++;
+ else
+ *pDS++ = *pSV++;
+ break;
+
+ case 'F': // Float
+ if (nr_fpr < FPR_COUNT)
+ // The value in %xmm register is already prepared to
+ // be retrieved as a float. Therefore, we pass the
+ // value verbatim, as a double without conversion.
+ pFPR[nr_fpr++] = *((double *)pSV);
+ else
+ {
+ *((float *)pDS) = *((float *)pSV);
+ pDS++;
+ }
+ pSV++;
+ break;
+
+ case 'H': // 64-bit Word
+ if (nr_gpr < GPR_COUNT)
+ pGPR[nr_gpr++] = *pSV++;
+ else
+ *pDS++ = *pSV++;
+ break;
+
+ case 'I': // 32-bit Word
+ if (nr_gpr < GPR_COUNT)
+ pGPR[nr_gpr++] = *((sal_uInt32 *)pSV);
+ else
+ *pDS++ = *((sal_uInt32 *)pSV);
+ pSV++;
+ break;
+
+ case 'S': // 16-bit Word
+ if (nr_gpr < GPR_COUNT)
+ pGPR[nr_gpr++] = *((sal_uInt16 *)pSV);
+ else
+ *pDS++ = *((sal_uInt16 *)pSV);
+ pSV++;
+ break;
+
+ case 'B': // Byte
+ if (nr_gpr < GPR_COUNT)
+ pGPR[nr_gpr++] = *((sal_uInt8 *)pSV);
+ else
+ *pDS++ = *((sal_uInt8 *)pSV);
+ pSV++;
+ break;
+
+ default: // Default, assume 64-bit values
+ if (nr_gpr < GPR_COUNT)
+ pGPR[nr_gpr++] = *pSV++;
+ else
+ *pDS++ = *pSV++;
+ break;
+ }
+ }
+}
+
+//==================================================================================================
+static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
+ void * pRegisterReturn, typelib_TypeClass eReturnType,
+ char * pPT, sal_uInt64 * pStackLongs, sal_uInt32 nStackLongs)
+{
+ sal_uInt32 nr_gpr, nr_fpr, nr_stack;
+ invoke_count_words(pPT, nr_gpr, nr_fpr, nr_stack);
+
+ // Stack, if used, must be 16-bytes aligned
+ if (nr_stack)
+ nr_stack = (nr_stack + 1) & ~1;
+
+#if 1
+ // Let's figure out what is really going on here
+ fprintf(stderr,"callVirtualMethod() parameters string is %s\n", pPT);
+ {
+ sal_uInt32 k = nStackLongs;
+ sal_uInt64 *q = pStackLongs;
+ while (k > 0)
+ {
+ fprintf(stderr, "uno stack is: %lx\n", *q);
+ k--;
+ q++;
+ }
+ }
+#endif
+
+ // Load parameters to stack, if necessary
+ sal_uInt64 *stack = (sal_uInt64 *) __builtin_alloca(nr_stack * 8);
+ sal_uInt64 gpregs[GPR_COUNT];
+ double fpregs[FPR_COUNT];
+ invoke_copy_to_stack(stack, pPT, pStackLongs, gpregs, fpregs);
+
+ // Load FPR registers from fpregs[]
+ register double d0 asm("xmm0");
+ register double d1 asm("xmm1");
+ register double d2 asm("xmm2");
+ register double d3 asm("xmm3");
+ register double d4 asm("xmm4");
+ register double d5 asm("xmm5");
+ register double d6 asm("xmm6");
+ register double d7 asm("xmm7");
+
+ switch (nr_fpr) {
+#define ARG_FPR(N) \
+ case N+1: d##N = fpregs[N];
+ ARG_FPR(7);
+ ARG_FPR(6);
+ ARG_FPR(5);
+ ARG_FPR(4);
+ ARG_FPR(3);
+ ARG_FPR(2);
+ ARG_FPR(1);
+ ARG_FPR(0);
+ case 0:;
+#undef ARG_FPR
+ }
+
+ // Load GPR registers from gpregs[]
+ register sal_uInt64 a0 asm("rdi");
+ register sal_uInt64 a1 asm("rsi");
+ register sal_uInt64 a2 asm("rdx");
+ register sal_uInt64 a3 asm("rcx");
+ register sal_uInt64 a4 asm("r8");
+ register sal_uInt64 a5 asm("r9");
+
+ switch (nr_gpr) {
+#define ARG_GPR(N) \
+ case N+1: a##N = gpregs[N];
+ ARG_GPR(5);
+ ARG_GPR(4);
+ ARG_GPR(3);
+ ARG_GPR(2);
+ ARG_GPR(1);
+ case 1: a0 = (sal_uInt64) pThis;
+ case 0:;
+#undef ARG_GPR
+ }
+
+ // Ensure that assignments to SSE registers won't be optimized away
+ asm("" ::
+ "x" (d0), "x" (d1), "x" (d2), "x" (d3),
+ "x" (d4), "x" (d5), "x" (d6), "x" (d7));
+
+ // Get pointer to method
+ sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
+ pMethod += 8 * nVtableIndex;
+ pMethod = *((sal_uInt64 *)pMethod);
+
+ union ReturnValue {
+ struct {
+ sal_uInt64 a0;
+ sal_uInt64 a1;
+ } i;
+ struct {
+ double d0;
+ double d1;
+ } f;
+ };
+
+ ReturnValue retval = ((ReturnValue (*)(sal_uInt64, sal_uInt64, sal_uInt64,
+ sal_uInt64, sal_uInt64, sal_uInt64))
+ pMethod)(a0, a1, a2, a3, a4, a5);
+
+ switch (eReturnType)
+ {
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *((sal_uInt64 *)pRegisterReturn) = retval.i.a0;
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *((sal_uInt32 *)pRegisterReturn) = (sal_uInt32)retval.i.a0;
+ break;
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *((sal_uInt16 *)pRegisterReturn) = (sal_uInt16)retval.i.a0;
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *((sal_uInt8 *)pRegisterReturn) = (sal_uInt8)retval.i.a0;
+ break;
+ case typelib_TypeClass_FLOAT:
+ *((float *)pRegisterReturn) = (float)retval.f.d0;
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *((double *)pRegisterReturn) = retval.f.d0;
+ break;
+ }
+}
+
+
+//==================================================================================================
+static void cpp_call(
+ cppu_unoInterfaceProxy * pThis,
+ sal_Int32 nVtableCall,
+ typelib_TypeDescriptionReference * pReturnTypeRef,
+ sal_Int32 nParams, typelib_MethodParameter * pParams,
+ void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+ // Maxium space for [complex ret ptr], values | ptr ...
+ char * pCppStack = (char *)__builtin_alloca( (nParams + 3) * sizeof(sal_uInt64) );
+ char * pCppStackStart = pCppStack;
+
+ // We need to know parameter types for callVirtualMethod() so generate a signature string
+ char * pParamType = (char *)__builtin_alloca( nParams + 2 );
+ char * pPT = pParamType;
+
+ // Return
+ typelib_TypeDescription * pReturnTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+ OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
+
+ void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+ if (pReturnTypeDescr)
+ {
+ if (cppu_isSimpleType( pReturnTypeDescr ))
+ {
+ pCppReturn = pUnoReturn; // direct way for simple types
+ }
+ else
+ {
+ // complex return via ptr
+ pCppReturn = *(void **)pCppStack = (cppu_relatesToInterface( pReturnTypeDescr )
+ ? alloca( pReturnTypeDescr->nSize )
+ : pUnoReturn); // direct way
+ *pPT++ = 'H';
+ pCppStack += sizeof(void *);
+ }
+ }
+
+ // Push "this" pointer
+ *(void **)pCppStack = pThis->pCppI;
+ *pPT++ = 'H';
+ pCppStack += sizeof(void *);
+
+ // stack space
+ // Args
+ void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
+ // Indizes of values this have to be converted (interface conversion cpp<=>uno)
+ sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
+ // Type descriptions for reconversions
+ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+
+ sal_Int32 nTempIndizes = 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 && cppu_isSimpleType( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
+ &pThis->pBridge->aUno2Cpp );
+
+ switch (pParamTypeDescr->eTypeClass)
+ {
+
+ // we need to know type of each param so that we know whether to use
+ // gpr or fpr to pass in parameters:
+ // Key: I - 32-bit value passed in gpr
+ // B - byte value passed in gpr
+ // S - short value passed in gpr
+ // F - float value pass in fpr
+ // D - double value pass in fpr
+ // H - long value passed in gpr
+ // X - indicates end of parameter description string
+
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ *pPT++ = 'I';
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ *pPT++ = 'S';
+ break;
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *pPT++ = 'B';
+ break;
+ case typelib_TypeClass_FLOAT:
+ *pPT++ = 'F';
+ break;
+ case typelib_TypeClass_DOUBLE:
+ *pPT++ = 'D';
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ *pPT++ = 'H';
+ 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(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pParamTypeDescr );
+ pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ // is in/inout
+ else if (cppu_relatesToInterface( pParamTypeDescr ))
+ {
+ uno_copyAndConvertData(
+ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+ pUnoArgs[nPos], pParamTypeDescr, &pThis->pBridge->aUno2Cpp );
+
+ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
+ // will be released at reconversion
+ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
+ }
+ else // direct way
+ {
+ *(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
+ // no longer needed
+ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+ }
+ // FIXME: is this the right way to pass these?
+ *pPT++='H';
+ }
+ pCppStack += sizeof(sal_uInt64); // standard parameter length
+ }
+
+ // terminate the signature string
+ *pPT++ = 'X';
+ *pPT = 0;
+
+ try
+ {
+ OSL_ENSURE( !( (pCppStack - pCppStackStart ) & 7), "UNALIGNED STACK !!! (Please DO panic)" );
+ callVirtualMethod(
+ pThis->pCppI, nVtableCall,
+ pCppReturn, pReturnTypeDescr->eTypeClass, pParamType,
+ (sal_uInt64 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_uInt64) );
+ // NO exception occured...
+ *ppUnoExc = 0;
+
+ // reconvert temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
+
+ 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->pBridge->aCpp2Uno );
+ }
+ }
+ else // pure out
+ {
+ uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+ &pThis->pBridge->aCpp2Uno );
+ }
+ // 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->pBridge->aCpp2Uno );
+ uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+ }
+ }
+ catch (...)
+ {
+ // fill uno exception
+ fillUnoException( __cxa_get_globals()->caughtExceptions, *ppUnoExc, &pThis->pBridge->aCpp2Uno );
+
+ // temporary params
+ for ( ; nTempIndizes--; )
+ {
+ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
+ // destroy temp cpp param => cpp: every param was constructed
+ uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], cpp_release );
+ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
+ }
+ // return type
+ if (pReturnTypeDescr)
+ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+ }
+}
+
+
+//==================================================================================================
+void SAL_CALL cppu_unoInterfaceProxy_dispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+ void * pReturn, void * pArgs[], uno_Any ** ppException ) throw ()
+{
+ // is my surrogate
+ cppu_unoInterfaceProxy * pThis = (cppu_unoInterfaceProxy *)pUnoI;
+ typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+
+ switch (pMemberDescr->eTypeClass)
+ {
+ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos];
+ OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+
+ if (pReturn)
+ {
+ // dependent dispatch
+ cpp_call(
+ pThis, nVtableCall,
+ ((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( RTL_CONSTASCII_USTRINGPARAM("void") );
+ typelib_typedescriptionreference_new(
+ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
+
+ // dependent dispatch
+ cpp_call(
+ pThis, nVtableCall +1, // get, then set method
+ pReturnTypeRef,
+ 1, &aParam,
+ pReturn, pArgs, ppException );
+
+ typelib_typedescriptionreference_release( pReturnTypeRef );
+ }
+
+ break;
+ }
+ case typelib_TypeClass_INTERFACE_METHOD:
+ {
+ // determine vtable call index
+ sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
+ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member pos out of range!" );
+
+ sal_Int32 nVtableCall = pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos];
+ OSL_ENSURE( nVtableCall < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!" );
+
+ switch (nVtableCall)
+ {
+ // 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->pBridge->pUnoEnv->getRegisteredInterface)(
+ pThis->pBridge->pUnoEnv,
+ (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()
+ default:
+ // dependent dispatch
+ cpp_call(
+ pThis, nVtableCall,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
+ ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
+ pReturn, pArgs, ppException );
+ }
+ break;
+ }
+ default:
+ {
+ ::com::sun::star::uno::RuntimeException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member type description!") ),
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
+
+ Type const & rExcType = ::getCppuType( &aExc );
+ // binary identical null reference
+ ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
+ }
+ }
+}
+
+}
+