summaryrefslogtreecommitdiff
path: root/editors/openoffice.org-2-devel/files/patch-i65467
diff options
context:
space:
mode:
authorJung-uk Kim <jkim@FreeBSD.org>2006-05-17 16:04:52 +0000
committerJung-uk Kim <jkim@FreeBSD.org>2006-05-17 16:04:52 +0000
commitfe1e79de28bf08e6c4487b1a67b56f84aab35c0d (patch)
treefc86469f3ad03e8b530346dcd75bec074467fdaa /editors/openoffice.org-2-devel/files/patch-i65467
parentUpdate to 0.10 (diff)
Add few necessary patches to build OOo on amd64. Please note that this
is not complete because few patches are pending and waiting for maintainer's review. Reviewed by: maho (maintainer)
Notes
Notes: svn path=/head/; revision=162668
Diffstat (limited to 'editors/openoffice.org-2-devel/files/patch-i65467')
-rw-r--r--editors/openoffice.org-2-devel/files/patch-i654672718
1 files changed, 2718 insertions, 0 deletions
diff --git a/editors/openoffice.org-2-devel/files/patch-i65467 b/editors/openoffice.org-2-devel/files/patch-i65467
new file mode 100644
index 000000000000..cbaef34381fe
--- /dev/null
+++ b/editors/openoffice.org-2-devel/files/patch-i65467
@@ -0,0 +1,2718 @@
+--- bridges/prj/build.lst 8 Mar 2006 08:49:22 -0000 1.34
++++ bridges/prj/build.lst 8 May 2006 21:26:08 -0000
+@@ -9,6 +9,7 @@
+ br bridges\source\cpp_uno\gcc3_linux_intel nmake - u br_gcc3li br_cppuno_shared br_unotypes NULL
+ br bridges\source\cpp_uno\gcc3_freebsd_intel nmake - u br_gcc3fi br_cppuno_shared br_unotypes NULL
+ br bridges\source\cpp_uno\gcc3_linux_x86-64 nmake - u br_gcc3lx br_cppuno_shared br_unotypes NULL
++br bridges\source\cpp_uno\gcc3_freebsd_x86-64 nmake - u br_gcc3fx br_cppuno_shared br_unotypes NULL
+ br bridges\source\cpp_uno\gcc3_linux_powerpc nmake - u br_gcclp3 br_cppuno_shared br_unotypes NULL
+ br bridges\source\cpp_uno\gcc3_linux_s390 nmake - u br_gccl33 br_unotypes NULL
+ br bridges\source\cpp_uno\gcc3_linux_sparc nmake - u br_gccl3s br_unotypes br_cppuno_shared NULL
+--- /dev/null Wed Dec 31 19:00:00 1969
++++ bridges/source/cpp_uno/gcc3_freebsd_x86-64/abi.cxx Wed Mar 8 03:49:32 2006
+@@ -0,0 +1,808 @@
++/*************************************************************************
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile$
++ *
++ * $Revision$
++ *
++ * last change: $Author$ $Date$
++ *
++ * The Contents of this file are made available subject to
++ * the terms of GNU Lesser General Public License Version 2.1.
++ *
++ *
++ * GNU Lesser General Public License Version 2.1
++ * =============================================
++ * Copyright 2005 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
++ *
++ ************************************************************************/
++
++// This is an implementation of the x86-64 ABI as described in 'System V
++// Application Binary Interface, AMD64 Architecture Processor Supplement'
++// (http://www.x86-64.org/documentation/abi-0.95.pdf)
++//
++// The code in this file is a modification of src/x86/ffi64.c from libffi
++// (http://sources.redhat.com/libffi/) which is under the following license:
++
++/* -----------------------------------------------------------------------
++ ffi.c - Copyright (c) 2002 Bo Thorsen <bo@suse.de>
++
++ x86-64 Foreign Function Interface
++
++ Permission is hereby granted, free of charge, to any person obtaining
++ a copy of this software and associated documentation files (the
++ ``Software''), to deal in the Software without restriction, including
++ without limitation the rights to use, copy, modify, merge, publish,
++ distribute, sublicense, and/or sell copies of the Software, and to
++ permit persons to whom the Software is furnished to do so, subject to
++ the following conditions:
++
++ The above copyright notice and this permission notice shall be included
++ in all copies or substantial portions of the Software.
++
++ THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
++ OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
++ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
++ IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
++ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
++ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ OTHER DEALINGS IN THE SOFTWARE.
++ ----------------------------------------------------------------------- */
++
++#include <abi.hxx>
++
++#include <rtl/ustring.hxx>
++
++using namespace x86_64;
++
++typedef struct
++{
++ /* Registers for argument passing. */
++ long gpr[MAX_GPR_REGS];
++ __int128_t sse[MAX_SSE_REGS];
++
++ /* Stack space for arguments. */
++ char argspace[0];
++} stackLayout;
++
++/* Register class used for passing given 64bit part of the argument.
++ These represent classes as documented by the PS ABI, with the exception
++ of SSESF, SSEDF classes, that are basically SSE class, just gcc will
++ use SF or DFmode move instead of DImode to avoid reformating penalties.
++
++ Similary we play games with INTEGERSI_CLASS to use cheaper SImode moves
++ whenever possible (upper half does contain padding).
++ */
++enum x86_64_reg_class
++{
++ X86_64_NO_CLASS,
++ X86_64_INTEGER_CLASS,
++ X86_64_INTEGERSI_CLASS,
++ X86_64_SSE_CLASS,
++ X86_64_SSESF_CLASS,
++ X86_64_SSEDF_CLASS,
++ X86_64_SSEUP_CLASS,
++ X86_64_X87_CLASS,
++ X86_64_X87UP_CLASS,
++ X86_64_MEMORY_CLASS
++};
++
++#define MAX_CLASSES 4
++
++#define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1)
++
++/* x86-64 register passing implementation. See x86-64 ABI for details. Goal
++ of this code is to classify each 8bytes of incoming argument by the register
++ class and assign registers accordingly. */
++
++/* Return the union class of CLASS1 and CLASS2.
++ See the x86-64 PS ABI for details. */
++
++static enum x86_64_reg_class
++merge_classes (enum x86_64_reg_class class1, enum x86_64_reg_class class2)
++{
++ /* Rule #1: If both classes are equal, this is the resulting class. */
++ if (class1 == class2)
++ return class1;
++
++ /* Rule #2: If one of the classes is NO_CLASS, the resulting class is
++ the other class. */
++ if (class1 == X86_64_NO_CLASS)
++ return class2;
++ if (class2 == X86_64_NO_CLASS)
++ return class1;
++
++ /* Rule #3: If one of the classes is MEMORY, the result is MEMORY. */
++ if (class1 == X86_64_MEMORY_CLASS || class2 == X86_64_MEMORY_CLASS)
++ return X86_64_MEMORY_CLASS;
++
++ /* Rule #4: If one of the classes is INTEGER, the result is INTEGER. */
++ if ((class1 == X86_64_INTEGERSI_CLASS && class2 == X86_64_SSESF_CLASS)
++ || (class2 == X86_64_INTEGERSI_CLASS && class1 == X86_64_SSESF_CLASS))
++ return X86_64_INTEGERSI_CLASS;
++ if (class1 == X86_64_INTEGER_CLASS || class1 == X86_64_INTEGERSI_CLASS
++ || class2 == X86_64_INTEGER_CLASS || class2 == X86_64_INTEGERSI_CLASS)
++ return X86_64_INTEGER_CLASS;
++
++ /* Rule #5: If one of the classes is X87 or X87UP class, MEMORY is used. */
++ if (class1 == X86_64_X87_CLASS || class1 == X86_64_X87UP_CLASS
++ || class2 == X86_64_X87_CLASS || class2 == X86_64_X87UP_CLASS)
++ return X86_64_MEMORY_CLASS;
++
++ /* Rule #6: Otherwise class SSE is used. */
++ return X86_64_SSE_CLASS;
++}
++
++/* Classify the argument of type TYPE and mode MODE.
++ CLASSES will be filled by the register class used to pass each word
++ of the operand. The number of words is returned. In case the parameter
++ should be passed in memory, 0 is returned. As a special case for zero
++ sized containers, classes[0] will be NO_CLASS and 1 is returned.
++
++ See the x86-64 PS ABI for details.
++*/
++static int
++classify_argument( typelib_TypeDescriptionReference *pTypeRef, enum x86_64_reg_class classes[], int &rByteOffset )
++{
++ /* First, align to the right place. */
++ rByteOffset = ALIGN( rByteOffset, pTypeRef->pType->nAlignment );
++
++ switch ( pTypeRef->eTypeClass )
++ {
++ case typelib_TypeClass_VOID:
++ classes[0] = X86_64_NO_CLASS;
++ return 1;
++ case typelib_TypeClass_CHAR:
++ case typelib_TypeClass_BOOLEAN:
++ case typelib_TypeClass_BYTE:
++ case typelib_TypeClass_SHORT:
++ case typelib_TypeClass_UNSIGNED_SHORT:
++ case typelib_TypeClass_LONG:
++ case typelib_TypeClass_UNSIGNED_LONG:
++ case typelib_TypeClass_HYPER:
++ case typelib_TypeClass_UNSIGNED_HYPER:
++ case typelib_TypeClass_ENUM:
++ if ( ( rByteOffset % 8 + pTypeRef->pType->nSize ) <= 4 )
++ classes[0] = X86_64_INTEGERSI_CLASS;
++ else
++ classes[0] = X86_64_INTEGER_CLASS;
++ return 1;
++ case typelib_TypeClass_FLOAT:
++ if ( ( rByteOffset % 8 ) == 0 )
++ classes[0] = X86_64_SSESF_CLASS;
++ else
++ classes[0] = X86_64_SSE_CLASS;
++ return 1;
++ case typelib_TypeClass_DOUBLE:
++ classes[0] = X86_64_SSEDF_CLASS;
++ return 1;
++ /*case LONGDOUBLE:
++ classes[0] = X86_64_X87_CLASS;
++ classes[1] = X86_64_X87UP_CLASS;
++ return 2;*/
++ case typelib_TypeClass_STRING:
++ case typelib_TypeClass_TYPE:
++ case typelib_TypeClass_ANY:
++ case typelib_TypeClass_TYPEDEF:
++ case typelib_TypeClass_UNION:
++ case typelib_TypeClass_SEQUENCE:
++ case typelib_TypeClass_ARRAY:
++ case typelib_TypeClass_INTERFACE:
++ return 0;
++ case typelib_TypeClass_STRUCT:
++ case typelib_TypeClass_EXCEPTION:
++ {
++ typelib_TypeDescription * pTypeDescr = 0;
++ TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
++
++ const int UNITS_PER_WORD = 8;
++ int words = ( pTypeDescr->nSize + UNITS_PER_WORD - 1 ) / UNITS_PER_WORD;
++ enum x86_64_reg_class subclasses[MAX_CLASSES];
++
++ /* If the struct is larger than 16 bytes, pass it on the stack. */
++ if ( pTypeDescr->nSize > 16 )
++ {
++ TYPELIB_DANGER_RELEASE( pTypeDescr );
++ return 0;
++ }
++
++ for ( int i = 0; i < words; i++ )
++ classes[i] = X86_64_NO_CLASS;
++
++ const typelib_CompoundTypeDescription *pStruct = reinterpret_cast<const typelib_CompoundTypeDescription*>( pTypeDescr );
++
++ /* Merge the fields of structure. */
++ for ( sal_Int32 nMember = 0; nMember < pStruct->nMembers; ++nMember )
++ {
++ typelib_TypeDescriptionReference *pTypeInStruct = pStruct->ppTypeRefs[ nMember ];
++
++ int num = classify_argument( pTypeInStruct, subclasses, rByteOffset );
++
++ if ( num == 0 )
++ {
++ TYPELIB_DANGER_RELEASE( pTypeDescr );
++ return 0;
++ }
++
++ for ( int i = 0; i < num; i++ )
++ {
++ int pos = rByteOffset / 8;
++ classes[i + pos] = merge_classes( subclasses[i], classes[i + pos] );
++ }
++
++ if ( pTypeInStruct->eTypeClass != typelib_TypeClass_STRUCT )
++ rByteOffset = pStruct->pMemberOffsets[ nMember ];
++ }
++
++ TYPELIB_DANGER_RELEASE( pTypeDescr );
++
++ /* Final merger cleanup. */
++ for ( int i = 0; i < words; i++ )
++ {
++ /* If one class is MEMORY, everything should be passed in
++ memory. */
++ if ( classes[i] == X86_64_MEMORY_CLASS )
++ return 0;
++
++ /* The X86_64_SSEUP_CLASS should be always preceded by
++ X86_64_SSE_CLASS. */
++ if ( classes[i] == X86_64_SSEUP_CLASS
++ && ( i == 0 || classes[i - 1] != X86_64_SSE_CLASS ) )
++ classes[i] = X86_64_SSE_CLASS;
++
++ /* X86_64_X87UP_CLASS should be preceded by X86_64_X87_CLASS. */
++ if ( classes[i] == X86_64_X87UP_CLASS
++ && ( i == 0 || classes[i - 1] != X86_64_X87_CLASS ) )
++ classes[i] = X86_64_SSE_CLASS;
++ }
++ return words;
++ }
++
++ default:
++#if OSL_DEBUG_LEVEL > 1
++ OSL_TRACE( "Unhandled case: pType->eTypeClass == %d\n", pTypeRef->eTypeClass );
++#endif
++ OSL_ASSERT(0);
++ }
++ return 0; /* Never reached. */
++}
++
++/* Examine the argument and return set number of register required in each
++ class. Return 0 iff parameter should be passed in memory. */
++bool x86_64::examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedSSE )
++{
++ enum x86_64_reg_class classes[MAX_CLASSES];
++ int offset = 0;
++ int n;
++
++ n = classify_argument( pTypeRef, classes, offset );
++
++ if ( n == 0 )
++ return false;
++
++ nUsedGPR = 0;
++ nUsedSSE = 0;
++ for ( n--; n >= 0; n-- )
++ switch ( classes[n] )
++ {
++ case X86_64_INTEGER_CLASS:
++ case X86_64_INTEGERSI_CLASS:
++ nUsedGPR++;
++ break;
++ case X86_64_SSE_CLASS:
++ case X86_64_SSESF_CLASS:
++ case X86_64_SSEDF_CLASS:
++ nUsedSSE++;
++ break;
++ case X86_64_NO_CLASS:
++ case X86_64_SSEUP_CLASS:
++ break;
++ case X86_64_X87_CLASS:
++ case X86_64_X87UP_CLASS:
++ if ( !bInReturn )
++ return false;
++ break;
++ default:
++#if OSL_DEBUG_LEVEL > 1
++ OSL_TRACE( "Unhandled case: classes[n] == %d\n", classes[n] );
++#endif
++ OSL_ASSERT(0);
++ }
++ return true;
++}
++
++bool x86_64::return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
++{
++ int g, s;
++
++ return examine_argument( pTypeRef, true, g, s ) == 0;
++}
++
++void x86_64::fill_struct( typelib_TypeDescriptionReference *pTypeRef, void * const *pGPR, void * const *pSSE, void *pStruct )
++{
++ enum x86_64_reg_class classes[MAX_CLASSES];
++ int offset = 0;
++ int n;
++
++ n = classify_argument( pTypeRef, classes, offset );
++
++ sal_uInt64 *pStructAlign = reinterpret_cast<sal_uInt64 *>( pStruct );
++ for ( n--; n >= 0; n-- )
++ switch ( classes[n] )
++ {
++ case X86_64_INTEGER_CLASS:
++ case X86_64_INTEGERSI_CLASS:
++ *pStructAlign++ = *reinterpret_cast<sal_uInt64 *>( *pGPR++ );
++ break;
++ case X86_64_SSE_CLASS:
++ case X86_64_SSESF_CLASS:
++ case X86_64_SSEDF_CLASS:
++ *pStructAlign++ = *reinterpret_cast<sal_uInt64 *>( *pSSE++ );
++ break;
++ }
++}
++
++#if 0
++
++/* Functions to load floats and double to an SSE register placeholder. */
++extern void float2sse (float, __int128_t *);
++extern void double2sse (double, __int128_t *);
++extern void floatfloat2sse (void *, __int128_t *);
++
++/* Functions to put the floats and doubles back. */
++extern float sse2float (__int128_t *);
++extern double sse2double (__int128_t *);
++extern void sse2floatfloat(__int128_t *, void *);
++
++/*@-exportheader@*/
++void
++ffi_prep_args (stackLayout *stack, extended_cif *ecif)
++/*@=exportheader@*/
++{
++ int gprcount, ssecount, i, g, s;
++ void **p_argv;
++ void *argp = &stack->argspace;
++ ffi_type **p_arg;
++
++ /* First check if the return value should be passed in memory. If so,
++ pass the pointer as the first argument. */
++ gprcount = ssecount = 0;
++ if (ecif->cif->rtype->type != FFI_TYPE_VOID
++ && examine_argument (ecif->cif->rtype, 1, &g, &s) == 0)
++ (void *)stack->gpr[gprcount++] = ecif->rvalue;
++
++ for (i=ecif->cif->nargs, p_arg=ecif->cif->arg_types, p_argv = ecif->avalue;
++ i!=0; i--, p_arg++, p_argv++)
++ {
++ int in_register = 0;
++
++ switch ((*p_arg)->type)
++ {
++ case FFI_TYPE_SINT8:
++ case FFI_TYPE_SINT16:
++ case FFI_TYPE_SINT32:
++ case FFI_TYPE_SINT64:
++ case FFI_TYPE_UINT8:
++ case FFI_TYPE_UINT16:
++ case FFI_TYPE_UINT32:
++ case FFI_TYPE_UINT64:
++ case FFI_TYPE_POINTER:
++ if (gprcount < MAX_GPR_REGS)
++ {
++ stack->gpr[gprcount] = 0;
++ stack->gpr[gprcount++] = *(long long *)(*p_argv);
++ in_register = 1;
++ }
++ break;
++
++ case FFI_TYPE_FLOAT:
++ if (ssecount < MAX_SSE_REGS)
++ {
++ float2sse (*(float *)(*p_argv), &stack->sse[ssecount++]);
++ in_register = 1;
++ }
++ break;
++
++ case FFI_TYPE_DOUBLE:
++ if (ssecount < MAX_SSE_REGS)
++ {
++ double2sse (*(double *)(*p_argv), &stack->sse[ssecount++]);
++ in_register = 1;
++ }
++ break;
++ }
++
++ if (in_register)
++ continue;
++
++ /* Either all places in registers where filled, or this is a
++ type that potentially goes into a memory slot. */
++ if (examine_argument (*p_arg, 0, &g, &s) == 0
++ || gprcount + g > MAX_GPR_REGS || ssecount + s > MAX_SSE_REGS)
++ {
++ /* Pass this argument in memory. */
++ argp = (void *)ALIGN(argp, (*p_arg)->alignment);
++ memcpy (argp, *p_argv, (*p_arg)->size);
++ argp += (*p_arg)->size;
++ }
++ else
++ {
++ /* All easy cases are eliminated. Now fire the big guns. */
++
++ enum x86_64_reg_class classes[MAX_CLASSES];
++ int offset = 0, j, num;
++ void *a;
++
++ num = classify_argument (*p_arg, classes, &offset);
++ for (j=0, a=*p_argv; j<num; j++, a+=8)
++ {
++ switch (classes[j])
++ {
++ case X86_64_INTEGER_CLASS:
++ case X86_64_INTEGERSI_CLASS:
++ stack->gpr[gprcount++] = *(long long *)a;
++ break;
++ case X86_64_SSE_CLASS:
++ floatfloat2sse (a, &stack->sse[ssecount++]);
++ break;
++ case X86_64_SSESF_CLASS:
++ float2sse (*(float *)a, &stack->sse[ssecount++]);
++ break;
++ case X86_64_SSEDF_CLASS:
++ double2sse (*(double *)a, &stack->sse[ssecount++]);
++ break;
++ default:
++ abort();
++ }
++ }
++ }
++ }
++}
++
++/* Perform machine dependent cif processing. */
++ffi_status
++ffi_prep_cif_machdep (ffi_cif *cif)
++{
++ int gprcount, ssecount, i, g, s;
++
++ gprcount = ssecount = 0;
++
++ /* Reset the byte count. We handle this size estimation here. */
++ cif->bytes = 0;
++
++ /* If the return value should be passed in memory, pass the pointer
++ as the first argument. The actual memory isn't allocated here. */
++ if (cif->rtype->type != FFI_TYPE_VOID
++ && examine_argument (cif->rtype, 1, &g, &s) == 0)
++ gprcount = 1;
++
++ /* Go over all arguments and determine the way they should be passed.
++ If it's in a register and there is space for it, let that be so. If
++ not, add it's size to the stack byte count. */
++ for (i=0; i<cif->nargs; i++)
++ {
++ if (examine_argument (cif->arg_types[i], 0, &g, &s) == 0
++ || gprcount + g > MAX_GPR_REGS || ssecount + s > MAX_SSE_REGS)
++ {
++ /* This is passed in memory. First align to the basic type. */
++ cif->bytes = ALIGN(cif->bytes, cif->arg_types[i]->alignment);
++
++ /* Stack arguments are *always* at least 8 byte aligned. */
++ cif->bytes = ALIGN(cif->bytes, 8);
++
++ /* Now add the size of this argument. */
++ cif->bytes += cif->arg_types[i]->size;
++ }
++ else
++ {
++ gprcount += g;
++ ssecount += s;
++ }
++ }
++
++ /* Set the flag for the closures return. */
++ switch (cif->rtype->type)
++ {
++ case FFI_TYPE_VOID:
++ case FFI_TYPE_STRUCT:
++ case FFI_TYPE_SINT64:
++ case FFI_TYPE_FLOAT:
++ case FFI_TYPE_DOUBLE:
++ case FFI_TYPE_LONGDOUBLE:
++ cif->flags = (unsigned) cif->rtype->type;
++ break;
++
++ case FFI_TYPE_UINT64:
++ cif->flags = FFI_TYPE_SINT64;
++ break;
++
++ default:
++ cif->flags = FFI_TYPE_INT;
++ break;
++ }
++
++ return FFI_OK;
++}
++
++typedef struct
++{
++ long gpr[2];
++ __int128_t sse[2];
++ long double st0;
++} return_value;
++
++//#endif
++
++void
++ffi_fill_return_value (return_value *rv, extended_cif *ecif)
++{
++ enum x86_64_reg_class classes[MAX_CLASSES];
++ int i = 0, num;
++ long *gpr = rv->gpr;
++ __int128_t *sse = rv->sse;
++ signed char sc;
++ signed short ss;
++
++ /* This is needed because of the way x86-64 handles signed short
++ integers. */
++ switch (ecif->cif->rtype->type)
++ {
++ case FFI_TYPE_SINT8:
++ sc = *(signed char *)gpr;
++ *(long long *)ecif->rvalue = (long long)sc;
++ return;
++ case FFI_TYPE_SINT16:
++ ss = *(signed short *)gpr;
++ *(long long *)ecif->rvalue = (long long)ss;
++ return;
++ default:
++ /* Just continue. */
++ ;
++ }
++
++ num = classify_argument (ecif->cif->rtype, classes, &i);
++
++ if (num == 0)
++ /* Return in memory. */
++ ecif->rvalue = (void *) rv->gpr[0];
++ else if (num == 2 && classes[0] == X86_64_X87_CLASS &&
++ classes[1] == X86_64_X87UP_CLASS)
++ /* This is a long double (this is easiest to handle this way instead
++ of an eightbyte at a time as in the loop below. */
++ *((long double *)ecif->rvalue) = rv->st0;
++ else
++ {
++ void *a;
++
++ for (i=0, a=ecif->rvalue; i<num; i++, a+=8)
++ {
++ switch (classes[i])
++ {
++ case X86_64_INTEGER_CLASS:
++ case X86_64_INTEGERSI_CLASS:
++ *(long long *)a = *gpr;
++ gpr++;
++ break;
++ case X86_64_SSE_CLASS:
++ sse2floatfloat (sse++, a);
++ break;
++ case X86_64_SSESF_CLASS:
++ *(float *)a = sse2float (sse++);
++ break;
++ case X86_64_SSEDF_CLASS:
++ *(double *)a = sse2double (sse++);
++ break;
++ default:
++ abort();
++ }
++ }
++ }
++}
++
++//#if 0
++
++/*@-declundef@*/
++/*@-exportheader@*/
++extern void ffi_call_UNIX64(void (*)(stackLayout *, extended_cif *),
++ void (*) (return_value *, extended_cif *),
++ /*@out@*/ extended_cif *,
++ unsigned, /*@out@*/ unsigned *, void (*fn)());
++/*@=declundef@*/
++/*@=exportheader@*/
++
++void ffi_call(/*@dependent@*/ ffi_cif *cif,
++ void (*fn)(),
++ /*@out@*/ void *rvalue,
++ /*@dependent@*/ void **avalue)
++{
++ extended_cif ecif;
++ int dummy;
++
++ ecif.cif = cif;
++ ecif.avalue = avalue;
++
++ /* If the return value is a struct and we don't have a return */
++ /* value address then we need to make one */
++
++ if ((rvalue == NULL) &&
++ (examine_argument (cif->rtype, 1, &dummy, &dummy) == 0))
++ {
++ /*@-sysunrecog@*/
++ ecif.rvalue = alloca(cif->rtype->size);
++ /*@=sysunrecog@*/
++ }
++ else
++ ecif.rvalue = rvalue;
++
++ /* Stack must always be 16byte aligned. Make it so. */
++ cif->bytes = ALIGN(cif->bytes, 16);
++
++ switch (cif->abi)
++ {
++ case FFI_SYSV:
++ /* Calling 32bit code from 64bit is not possible */
++ FFI_ASSERT(0);
++ break;
++
++ case FFI_UNIX64:
++ /*@-usedef@*/
++ ffi_call_UNIX64 (ffi_prep_args, ffi_fill_return_value, &ecif,
++ cif->bytes, ecif.rvalue, fn);
++ /*@=usedef@*/
++ break;
++
++ default:
++ FFI_ASSERT(0);
++ break;
++ }
++}
++
++extern void ffi_closure_UNIX64(void);
++
++ffi_status
++ffi_prep_closure (ffi_closure* closure,
++ ffi_cif* cif,
++ void (*fun)(ffi_cif*, void*, void**, void*),
++ void *user_data)
++{
++ volatile unsigned short *tramp;
++
++ /* FFI_ASSERT (cif->abi == FFI_OSF); */
++
++ tramp = (volatile unsigned short *) &closure->tramp[0];
++ tramp[0] = 0xbb49; /* mov <code>, %r11 */
++ tramp[5] = 0xba49; /* mov <data>, %r10 */
++ tramp[10] = 0xff49; /* jmp *%r11 */
++ tramp[11] = 0x00e3;
++ *(void * volatile *) &tramp[1] = ffi_closure_UNIX64;
++ *(void * volatile *) &tramp[6] = closure;
++
++ closure->cif = cif;
++ closure->fun = fun;
++ closure->user_data = user_data;
++
++ return FFI_OK;
++}
++
++int
++ffi_closure_UNIX64_inner(ffi_closure *closure, va_list l, void *rp)
++{
++ ffi_cif *cif;
++ void **avalue;
++ ffi_type **arg_types;
++ long i, avn, argn;
++
++ cif = closure->cif;
++ avalue = alloca(cif->nargs * sizeof(void *));
++
++ argn = 0;
++
++ i = 0;
++ avn = cif->nargs;
++ arg_types = cif->arg_types;
++
++ /* Grab the addresses of the arguments from the stack frame. */
++ while (i < avn)
++ {
++ switch (arg_types[i]->type)
++ {
++ case FFI_TYPE_SINT8:
++ case FFI_TYPE_UINT8:
++ case FFI_TYPE_SINT16:
++ case FFI_TYPE_UINT16:
++ case FFI_TYPE_SINT32:
++ case FFI_TYPE_UINT32:
++ case FFI_TYPE_SINT64:
++ case FFI_TYPE_UINT64:
++ case FFI_TYPE_POINTER:
++ {
++ if (l->gp_offset > 48-8)
++ {
++ avalue[i] = l->overflow_arg_area;
++ l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
++ }
++ else
++ {
++ avalue[i] = (char *)l->reg_save_area + l->gp_offset;
++ l->gp_offset += 8;
++ }
++ }
++ break;
++
++ case FFI_TYPE_STRUCT:
++ /* FIXME */
++ FFI_ASSERT(0);
++ break;
++
++ case FFI_TYPE_DOUBLE:
++ {
++ if (l->fp_offset > 176-16)
++ {
++ avalue[i] = l->overflow_arg_area;
++ l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
++ }
++ else
++ {
++ avalue[i] = (char *)l->reg_save_area + l->fp_offset;
++ l->fp_offset += 16;
++ }
++ }
++#if DEBUG_FFI
++ fprintf (stderr, "double arg %d = %g\n", i, *(double *)avalue[i]);
++#endif
++ break;
++
++ case FFI_TYPE_FLOAT:
++ {
++ if (l->fp_offset > 176-16)
++ {
++ avalue[i] = l->overflow_arg_area;
++ l->overflow_arg_area = (char *)l->overflow_arg_area + 8;
++ }
++ else
++ {
++ avalue[i] = (char *)l->reg_save_area + l->fp_offset;
++ l->fp_offset += 16;
++ }
++ }
++#if DEBUG_FFI
++ fprintf (stderr, "float arg %d = %g\n", i, *(float *)avalue[i]);
++#endif
++ break;
++
++ default:
++ FFI_ASSERT(0);
++ }
++
++ argn += ALIGN(arg_types[i]->size, SIZEOF_ARG) / SIZEOF_ARG;
++ i++;
++ }
++
++ /* Invoke the closure. */
++ (closure->fun) (cif, rp, avalue, closure->user_data);
++
++ /* FIXME: Structs not supported. */
++ FFI_ASSERT(cif->rtype->type != FFI_TYPE_STRUCT);
++
++ /* Tell ffi_closure_UNIX64 how to perform return type promotions. */
++
++ return cif->rtype->type;
++}
++
++#endif
+--- /dev/null Wed Dec 31 19:00:00 1969
++++ bridges/source/cpp_uno/gcc3_freebsd_x86-64/abi.hxx Wed Mar 8 03:49:42 2006
+@@ -0,0 +1,75 @@
++/*************************************************************************
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile$
++ *
++ * $Revision$
++ *
++ * last change: $Author$ $Date$
++ *
++ * The Contents of this file are made available subject to
++ * the terms of GNU Lesser General Public License Version 2.1.
++ *
++ *
++ * GNU Lesser General Public License Version 2.1
++ * =============================================
++ * Copyright 2005 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
++ *
++ ************************************************************************/
++
++#ifndef _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
++#define _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
++
++// This is an implementation of the x86-64 ABI as described in 'System V
++// Application Binary Interface, AMD64 Architecture Processor Supplement'
++// (http://www.x86-64.org/documentation/abi-0.95.pdf)
++
++#include <typelib/typedescription.hxx>
++
++namespace x86_64
++{
++
++/* 6 general purpose registers are used for parameter passing */
++const sal_uInt32 MAX_GPR_REGS = 6;
++
++/* 8 SSE registers are used for parameter passing */
++const sal_uInt32 MAX_SSE_REGS = 8;
++
++/* Count number of required registers.
++
++ Examine the argument and return set number of register required in each
++ class.
++
++ Return false iff parameter should be passed in memory.
++*/
++bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedSSE );
++
++/** Does function that returns this type use a hidden parameter, or registers?
++
++ The value can be returned either in a hidden 1st parameter (which is a
++ pointer to a structure allocated by the caller), or in registers (rax, rdx
++ for the integers, xmm0, xmm1 for the floating point numbers).
++*/
++bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
++
++void fill_struct( typelib_TypeDescriptionReference *pTypeRef, void * const *pGPR, void * const *pSSE, void *pStruct );
++
++} // namespace x86_64
++
++#endif // _BRIDGES_CPP_UNO_X86_64_ABI_HXX_
+--- /dev/null Wed Dec 31 19:00:00 1969
++++ bridges/source/cpp_uno/gcc3_freebsd_x86-64/call.s Mon May 15 13:21:10 2006
+@@ -0,0 +1,93 @@
++ .text
++ .align 2
++.globl privateSnippetExecutor
++ .type privateSnippetExecutor, @function
++privateSnippetExecutor:
++.LFB3:
++ pushq %rbp
++.LCFI0:
++ movq %rsp, %rbp
++.LCFI1:
++ subq $160, %rsp
++.LCFI2:
++ movq %r10, -152(%rbp) # Save (nVtableOffset << 32) + nFunctionIndex
++
++ movq %rdi, -112(%rbp) # Save GP registers
++ movq %rsi, -104(%rbp)
++ movq %rdx, -96(%rbp)
++ movq %rcx, -88(%rbp)
++ movq %r8 , -80(%rbp)
++ movq %r9 , -72(%rbp)
++
++ movsd %xmm0, -64(%rbp) # Save FP registers
++ movsd %xmm1, -56(%rbp)
++ movsd %xmm2, -48(%rbp)
++ movsd %xmm3, -40(%rbp)
++ movsd %xmm4, -32(%rbp)
++ movsd %xmm5, -24(%rbp)
++ movsd %xmm6, -16(%rbp)
++ movsd %xmm7, -8(%rbp)
++
++ leaq -144(%rbp), %r9 # 6th param: sal_uInt64 * pRegisterReturn
++ leaq 16(%rbp), %r8 # 5rd param: void ** ovrflw
++ leaq -64(%rbp), %rcx # 4th param: void ** fpreg
++ leaq -112(%rbp), %rdx # 3rd param: void ** gpreg
++ movl -148(%rbp), %esi # 2nd param: sal_int32 nVtableOffset
++ movl -152(%rbp), %edi # 1st param: sal_int32 nFunctionIndex
++
++ call cpp_vtable_call
++
++ cmp $10, %rax # typelib_TypeClass_FLOAT
++ je .Lfloat
++ cmp $11, %rax # typelib_TypeClass_DOUBLE
++ je .Lfloat
++
++ movq -144(%rbp), %rax # Return value (int case)
++ jmp .Lfinish
++.Lfloat:
++ movlpd -144(%rbp), %xmm0 # Return value (float/double case)
++
++.Lfinish:
++ leave
++ ret
++.LFE3:
++ .size privateSnippetExecutor, .-privateSnippetExecutor
++ .section .eh_frame,"a",@progbits
++.Lframe1:
++ .long .LECIE1-.LSCIE1
++.LSCIE1:
++ .long 0x0
++ .byte 0x1
++ .string "zR"
++ .uleb128 0x1
++ .sleb128 -8
++ .byte 0x10
++ .uleb128 0x1
++ .byte 0x1b
++ .byte 0xc
++ .uleb128 0x7
++ .uleb128 0x8
++ .byte 0x90
++ .uleb128 0x1
++ .align 8
++.LECIE1:
++.LSFDE1:
++ .long .LEFDE1-.LASFDE1
++.LASFDE1:
++ .long .LASFDE1-.Lframe1
++ .long .LFB3-.
++ .long .LFE3-.LFB3
++ .uleb128 0x0
++ .byte 0x4
++ .long .LCFI0-.LFB3
++ .byte 0xe
++ .uleb128 0x10
++ .byte 0x86
++ .uleb128 0x2
++ .byte 0x4
++ .long .LCFI1-.LCFI0
++ .byte 0xd
++ .uleb128 0x6
++ .align 8
++.LEFDE1:
++ .section .note.GNU-stack,"",@progbits
+--- /dev/null Wed Dec 31 19:00:00 1969
++++ bridges/source/cpp_uno/gcc3_freebsd_x86-64/cpp2uno.cxx Tue May 9 12:49:06 2006
+@@ -0,0 +1,539 @@
++/*************************************************************************
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile$
++ *
++ * $Revision$
++ *
++ * last change: $Author$ $Date$
++ *
++ * The Contents of this file are made available subject to
++ * the terms of GNU Lesser General Public License Version 2.1.
++ *
++ *
++ * GNU Lesser General Public License Version 2.1
++ * =============================================
++ * Copyright 2005 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
++ *
++ ************************************************************************/
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <hash_map>
++
++#include <rtl/alloc.h>
++#include <osl/mutex.hxx>
++
++#include <com/sun/star/uno/genfunc.hxx>
++#include "com/sun/star/uno/RuntimeException.hpp"
++#include <uno/data.h>
++#include <typelib/typedescription.hxx>
++
++#include "bridges/cpp_uno/shared/bridge.hxx"
++#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
++#include "bridges/cpp_uno/shared/types.hxx"
++#include "bridges/cpp_uno/shared/vtablefactory.hxx"
++
++#include "abi.hxx"
++#include "share.hxx"
++
++using namespace ::osl;
++using namespace ::rtl;
++using namespace ::com::sun::star::uno;
++
++//==================================================================================================
++
++// Perform the UNO call
++//
++// We must convert the paramaters stored in gpreg, fpreg and ovrflw to UNO
++// arguments and call pThis->getUnoI()->pDispatcher.
++//
++// gpreg: [ret *], this, [gpr params]
++// fpreg: [fpr params]
++// ovrflw: [gpr or fpr params (properly aligned)]
++//
++// [ret *] is present when we are returning a structure bigger than 16 bytes
++// Simple types are returned in rax, rdx (int), or xmm0, xmm1 (fp).
++// Similarly structures <= 16 bytes are in rax, rdx, xmm0, xmm1 as necessary.
++static typelib_TypeClass 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 ** gpreg, void ** fpreg, void ** ovrflw,
++ sal_uInt64 * pRegisterReturn /* space for register return */ )
++{
++ int nr_gpr = 0; //number of gpr registers used
++ int nr_fpr = 0; //number of fpr regsiters used
++
++ // 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 )
++ {
++ if ( x86_64::return_in_hidden_param( pReturnTypeRef ) )
++ {
++ pCppReturn = *gpreg++;
++ nr_gpr++;
++
++ pUnoReturn = ( bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
++ ? alloca( pReturnTypeDescr->nSize )
++ : pCppReturn ); // direct way
++ }
++ else
++ pUnoReturn = pRegisterReturn; // direct way for simple types
++ }
++
++ // pop this
++ gpreg++;
++ nr_gpr++;
++
++ // stack space
++ // parameters
++ void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
++ void ** pCppArgs = pUnoArgs + nParams;
++ // indizes of values this have to be converted (interface conversion cpp<=>uno)
++ sal_Int32 * pTempIndizes = (sal_Int32 *)(pUnoArgs + (2 * nParams));
++ // type descriptions for reconversions
++ typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * 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 );
++
++ int nUsedGPR = 0;
++ int nUsedSSE = 0;
++ bool bFitsRegisters = x86_64::examine_argument( rParam.pTypeRef, false, nUsedGPR, nUsedSSE );
++ if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ) ) // value
++ {
++ // Simple types must fit exactly one register on x86_64
++ OSL_ASSERT( bFitsRegisters && ( ( nUsedSSE == 1 && nUsedGPR == 0 ) || ( nUsedSSE == 0 && nUsedGPR == 1 ) ) );
++
++ if ( nUsedSSE == 1 )
++ {
++ if ( nr_fpr < x86_64::MAX_SSE_REGS )
++ {
++ pCppArgs[nPos] = pUnoArgs[nPos] = fpreg++;
++ nr_fpr++;
++ }
++ else
++ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
++ }
++ else if ( nUsedGPR == 1 )
++ {
++ if ( nr_gpr < x86_64::MAX_GPR_REGS )
++ {
++ pCppArgs[nPos] = pUnoArgs[nPos] = gpreg++;
++ nr_gpr++;
++ }
++ else
++ pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw++;
++ }
++
++ // no longer needed
++ TYPELIB_DANGER_RELEASE( pParamTypeDescr );
++ }
++ else // struct <= 16 bytes || ptr to complex value || ref
++ {
++ void *pCppStack;
++ char pTmpStruct[16];
++
++ if ( bFitsRegisters && !rParam.bOut &&
++ ( pParamTypeDescr->eTypeClass == typelib_TypeClass_STRUCT ||
++ pParamTypeDescr->eTypeClass == typelib_TypeClass_EXCEPTION ) )
++ {
++ if ( ( nr_gpr + nUsedGPR <= x86_64::MAX_GPR_REGS ) && ( nr_fpr + nUsedSSE <= x86_64::MAX_SSE_REGS ) )
++ {
++ x86_64::fill_struct( rParam.pTypeRef, gpreg, fpreg, pTmpStruct );
++#if OSL_DEBUG_LEVEL > 1
++ fprintf( stderr, "nUsedGPR == %d, nUsedSSE == %d, pTmpStruct[0] == 0x%x, pTmpStruct[1] == 0x%x, **gpreg == 0x%lx\n",
++ nUsedGPR, nUsedSSE, pTmpStruct[0], pTmpStruct[1], *(sal_uInt64*)*gpreg );
++#endif
++
++ pCppArgs[nPos] = pCppStack = reinterpret_cast<void *>( pTmpStruct );
++ gpreg += nUsedGPR;
++ fpreg += nUsedSSE;
++ }
++ else
++ pCppArgs[nPos] = pCppStack = *ovrflw++;
++ }
++ else if ( nr_gpr < x86_64::MAX_GPR_REGS )
++ {
++ pCppArgs[nPos] = pCppStack = *gpreg++;
++ nr_gpr++;
++ }
++ else
++ pCppArgs[nPos] = pCppStack = *ovrflw++;
++
++ if (! rParam.bIn) // is pure out
++ {
++ // uno out is unconstructed mem!
++ pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
++ pTempIndizes[nTempIndizes] = nPos;
++ // will be released at reconversion
++ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
++ }
++ else if ( bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ) ) // is in/inout
++ {
++ uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
++ pCppStack, pParamTypeDescr,
++ pThis->getBridge()->getCpp2Uno() );
++ pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
++ // will be released at reconversion
++ ppTempParamTypeDescr[nTempIndizes++] = pParamTypeDescr;
++ }
++ else // direct way
++ {
++ pUnoArgs[nPos] = pCppStack;
++ // 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 occured...
++ if ( pUnoExc )
++ {
++ // destruct temporary in/inout params
++ for ( ; nTempIndizes--; )
++ {
++ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
++
++ if (pParams[nIndex].bIn) // is in/inout => was constructed
++ uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndizes], 0 );
++ TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndizes] );
++ }
++ 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 occured...
++ {
++ // temporary params
++ for ( ; nTempIndizes--; )
++ {
++ sal_Int32 nIndex = pTempIndizes[nTempIndizes];
++ typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndizes];
++
++ 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 );
++ }
++ // complex return ptr is set to return reg
++ *(void **)pRegisterReturn = pCppReturn;
++ }
++ if ( pReturnTypeDescr )
++ {
++ typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
++ TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
++ return eRet;
++ }
++ else
++ return typelib_TypeClass_VOID;
++ }
++}
++
++
++//==================================================================================================
++extern "C" typelib_TypeClass cpp_vtable_call(
++ sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
++ void ** gpreg, void ** fpreg, void ** ovrflw,
++ sal_uInt64 * pRegisterReturn /* space for register return */ )
++{
++ // gpreg: [ret *], this, [other gpr params]
++ // fpreg: [fpr params]
++ // ovrflw: [gpr or fpr params (properly aligned)]
++ void * pThis;
++ if ( nFunctionIndex & 0x80000000 )
++ {
++ nFunctionIndex &= 0x7fffffff;
++ pThis = gpreg[1];
++ }
++ else
++ {
++ pThis = gpreg[0];
++ }
++ pThis = static_cast<char *>( pThis ) - nVtableOffset;
++
++ bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
++ bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis );
++
++ typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
++
++ OSL_ENSURE( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!\n" );
++ if ( nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex )
++ {
++ throw RuntimeException( OUString::createFromAscii("illegal vtable index!"),
++ reinterpret_cast<XInterface *>( pCppI ) );
++ }
++
++ // determine called method
++ sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
++ OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member index!\n" );
++
++ TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
++
++ typelib_TypeClass eRet;
++ switch ( aMemberDescr.get()->eTypeClass )
++ {
++ case typelib_TypeClass_INTERFACE_ATTRIBUTE:
++ {
++ typelib_TypeDescriptionReference *pAttrTypeRef =
++ reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( aMemberDescr.get() )->pAttributeTypeRef;
++
++ if ( pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex )
++ {
++ // is GET method
++ eRet = cpp2uno_call( pCppI, aMemberDescr.get(), pAttrTypeRef,
++ 0, 0, // no params
++ gpreg, fpreg, ovrflw, pRegisterReturn );
++ }
++ else
++ {
++ // is SET method
++ typelib_MethodParameter aParam;
++ aParam.pTypeRef = pAttrTypeRef;
++ aParam.bIn = sal_True;
++ aParam.bOut = sal_False;
++
++ eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
++ 0, // indicates void return
++ 1, &aParam,
++ gpreg, fpreg, ovrflw, 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 *>( gpreg[2] )->getTypeLibType() );
++ if ( pTD )
++ {
++ XInterface * pInterface = 0;
++ (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
++ ( pCppI->getBridge()->getCppEnv(),
++ (void **)&pInterface,
++ pCppI->getOid().pData,
++ reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
++
++ if ( pInterface )
++ {
++ ::uno_any_construct( reinterpret_cast<uno_Any *>( gpreg[0] ),
++ &pInterface, pTD, cpp_acquire );
++
++ pInterface->release();
++ TYPELIB_DANGER_RELEASE( pTD );
++
++ reinterpret_cast<void **>( pRegisterReturn )[0] = gpreg[0];
++ eRet = typelib_TypeClass_ANY;
++ break;
++ }
++ TYPELIB_DANGER_RELEASE( pTD );
++ }
++ } // else perform queryInterface()
++ default:
++ {
++ typelib_InterfaceMethodTypeDescription *pMethodTD =
++ reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( aMemberDescr.get() );
++
++ eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
++ pMethodTD->pReturnTypeRef,
++ pMethodTD->nParams,
++ pMethodTD->pParams,
++ gpreg, fpreg, ovrflw, pRegisterReturn );
++ }
++ }
++ break;
++ }
++ default:
++ {
++ throw RuntimeException( OUString::createFromAscii("no member description found!"),
++ reinterpret_cast<XInterface *>( pCppI ) );
++ // is here for dummy
++ eRet = typelib_TypeClass_VOID;
++ }
++ }
++
++ return eRet;
++}
++
++//==================================================================================================
++extern "C" void privateSnippetExecutor( ... );
++
++const int codeSnippetSize = 24;
++
++// Generate a trampoline that redirects method calls to
++// privateSnippetExecutor().
++//
++// privateSnippetExecutor() saves all the registers that are used for
++// parameter passing on x86_64, and calls the cpp_vtable_call().
++// When it returns, privateSnippetExecutor() sets the return value.
++//
++// Note: The code snippet we build here must not create a stack frame,
++// otherwise the UNO exceptions stop working thanks to non-existing
++// unwinding info.
++unsigned char * codeSnippet( unsigned char * code,
++ sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
++ bool bHasHiddenParam ) SAL_THROW( () )
++{
++ sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
++
++ if ( bHasHiddenParam )
++ nOffsetAndIndex |= 0x80000000;
++
++ // movq $<nOffsetAndIndex>, %r10
++ *reinterpret_cast<sal_uInt16 *>( code ) = 0xba49;
++ *reinterpret_cast<sal_uInt64 *>( code + 2 ) = nOffsetAndIndex;
++
++ // movq $<address of the privateSnippetExecutor>, %r11
++ *reinterpret_cast<sal_uInt16 *>( code + 10 ) = 0xbb49;
++ *reinterpret_cast<sal_uInt64 *>( code + 12 ) = reinterpret_cast<sal_uInt64>( privateSnippetExecutor );
++
++ // jmpq *%r11
++ *reinterpret_cast<sal_uInt32 *>( code + 20 ) = 0x00e3ff49;
++
++ return code + codeSnippetSize;
++}
++
++//==================================================================================================
++void ** bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable( void * block )
++{
++ return static_cast<void **>( block ) + 2;
++}
++
++//==================================================================================================
++sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
++ sal_Int32 slotCount)
++{
++ return ( slotCount + 2 ) * sizeof( void * ) + slotCount * codeSnippetSize;
++}
++
++//==================================================================================================
++void ** bridges::cpp_uno::shared::VtableFactory::initializeBlock( void * block )
++{
++ void ** slots = mapBlockToVtable( block );
++ slots[-2] = 0;
++ slots[-1] = 0;
++
++ return slots;
++}
++
++//==================================================================================================
++
++unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
++ void ** slots, unsigned char * code,
++ typelib_InterfaceTypeDescription const * type, sal_Int32 nFunctionOffset,
++ sal_Int32 functionCount, sal_Int32 nVtableOffset )
++{
++ for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos )
++ {
++ typelib_TypeDescription * pTD = 0;
++
++ TYPELIB_DANGER_GET( &pTD, type->ppMembers[ nPos ] );
++ OSL_ASSERT( pTD );
++
++ if ( typelib_TypeClass_INTERFACE_ATTRIBUTE == pTD->eTypeClass )
++ {
++ typelib_InterfaceAttributeTypeDescription *pAttrTD =
++ reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
++
++ // get method
++ *slots++ = code;
++ code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
++ x86_64::return_in_hidden_param( pAttrTD->pAttributeTypeRef ) );
++
++ if ( ! pAttrTD->bReadOnly )
++ {
++ // set method
++ *slots++ = code;
++ code = codeSnippet( code, nFunctionOffset++, nVtableOffset, false );
++ }
++ }
++ else if ( typelib_TypeClass_INTERFACE_METHOD == pTD->eTypeClass )
++ {
++ typelib_InterfaceMethodTypeDescription *pMethodTD =
++ reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
++
++ *slots++ = code;
++ code = codeSnippet( code, nFunctionOffset++, nVtableOffset,
++ x86_64::return_in_hidden_param( pMethodTD->pReturnTypeRef ) );
++ }
++ else
++ OSL_ASSERT( false );
++
++ TYPELIB_DANGER_RELEASE( pTD );
++ }
++ return code;
++}
++
++//==================================================================================================
++void bridges::cpp_uno::shared::VtableFactory::flushCode(
++ unsigned char const *, unsigned char const * )
++{
++}
+--- /dev/null Wed Dec 31 19:00:00 1969
++++ bridges/source/cpp_uno/gcc3_freebsd_x86-64/except.cxx Mon May 8 17:19:14 2006
+@@ -0,0 +1,334 @@
++/*************************************************************************
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile$
++ *
++ * $Revision$
++ *
++ * last change: $Author$ $Date$
++ *
++ * The Contents of this file are made available subject to
++ * the terms of GNU Lesser General Public License Version 2.1.
++ *
++ *
++ * GNU Lesser General Public License Version 2.1
++ * =============================================
++ * Copyright 2005 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
++ *
++ ************************************************************************/
++
++#include <stdio.h>
++#include <dlfcn.h>
++#include <cxxabi.h>
++#include <hash_map>
++
++#include <rtl/strbuf.hxx>
++#include <rtl/ustrbuf.hxx>
++#include <osl/diagnose.h>
++#include <osl/mutex.hxx>
++
++#include <com/sun/star/uno/genfunc.hxx>
++#include "com/sun/star/uno/RuntimeException.hpp"
++#include <typelib/typedescription.hxx>
++#include <uno/any2.h>
++
++#include "share.hxx"
++
++
++using namespace ::std;
++using namespace ::osl;
++using namespace ::rtl;
++using namespace ::com::sun::star::uno;
++using namespace ::__cxxabiv1;
++
++
++namespace CPPU_CURRENT_NAMESPACE
++{
++
++void dummy_can_throw_anything( char const * )
++{
++}
++
++//==================================================================================================
++static OUString toUNOname( char const * p ) SAL_THROW( () )
++{
++#if OSL_DEBUG_LEVEL > 1
++ char const * start = p;
++#endif
++
++ // example: N3com3sun4star4lang24IllegalArgumentExceptionE
++
++ OUStringBuffer buf( 64 );
++ OSL_ASSERT( 'N' == *p );
++ ++p; // skip N
++
++ while ('E' != *p)
++ {
++ // read chars count
++ long n = (*p++ - '0');
++ while ('0' <= *p && '9' >= *p)
++ {
++ n *= 10;
++ n += (*p++ - '0');
++ }
++ buf.appendAscii( p, n );
++ p += n;
++ if ('E' != *p)
++ buf.append( (sal_Unicode)'.' );
++ }
++
++#if OSL_DEBUG_LEVEL > 1
++ OUString ret( buf.makeStringAndClear() );
++ OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
++ fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
++ return ret;
++#else
++ return buf.makeStringAndClear();
++#endif
++}
++
++//==================================================================================================
++class RTTI
++{
++ typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
++
++ Mutex m_mutex;
++ t_rtti_map m_rttis;
++ t_rtti_map m_generatedRttis;
++
++ void * m_hApp;
++
++public:
++ RTTI() SAL_THROW( () );
++ ~RTTI() SAL_THROW( () );
++
++ type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () );
++};
++//__________________________________________________________________________________________________
++RTTI::RTTI() SAL_THROW( () )
++ : m_hApp( dlopen( 0, RTLD_NOW | RTLD_GLOBAL ) )
++{
++}
++//__________________________________________________________________________________________________
++RTTI::~RTTI() SAL_THROW( () )
++{
++ dlclose( m_hApp );
++}
++
++//__________________________________________________________________________________________________
++type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) SAL_THROW( () )
++{
++ type_info * rtti;
++
++ OUString const & unoName = *(OUString const *)&pTypeDescr->aBase.pTypeName;
++
++ MutexGuard guard( m_mutex );
++ t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
++ if (iFind == m_rttis.end())
++ {
++ // RTTI symbol
++ OStringBuffer buf( 64 );
++ buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
++ sal_Int32 index = 0;
++ do
++ {
++ OUString token( unoName.getToken( 0, '.', index ) );
++ buf.append( token.getLength() );
++ OString c_token( OUStringToOString( token, RTL_TEXTENCODING_ASCII_US ) );
++ buf.append( c_token );
++ }
++ while (index >= 0);
++ buf.append( 'E' );
++
++ OString symName( buf.makeStringAndClear() );
++ rtti = (type_info *)dlsym( RTLD_DEFAULT, symName.getStr() );
++
++ if (rtti)
++ {
++ pair< t_rtti_map::iterator, bool > insertion(
++ m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
++ OSL_ENSURE( insertion.second, "### inserting new rtti failed?!" );
++ }
++ else
++ {
++ // try to lookup the symbol in the generated rtti map
++ t_rtti_map::const_iterator iFind( m_generatedRttis.find( unoName ) );
++ if (iFind == m_generatedRttis.end())
++ {
++ // we must generate it !
++ // symbol and rtti-name is nearly identical,
++ // the symbol is prefixed with _ZTI
++ char const * rttiName = symName.getStr() +4;
++#if OSL_DEBUG_LEVEL > 1
++ fprintf( stderr,"generated rtti for %s\n", rttiName );
++#endif
++ if (pTypeDescr->pBaseTypeDescription)
++ {
++ // ensure availability of base
++ type_info * base_rtti = getRTTI(
++ (typelib_CompoundTypeDescription *)pTypeDescr->pBaseTypeDescription );
++ rtti = new __si_class_type_info(
++ strdup( rttiName ), (__class_type_info *)base_rtti );
++ }
++ else
++ {
++ // this class has no base class
++ rtti = new __class_type_info( strdup( rttiName ) );
++ }
++
++ pair< t_rtti_map::iterator, bool > insertion(
++ m_generatedRttis.insert( t_rtti_map::value_type( unoName, rtti ) ) );
++ OSL_ENSURE( insertion.second, "### inserting new generated rtti failed?!" );
++ }
++ else // taking already generated rtti
++ {
++ rtti = iFind->second;
++ }
++ }
++ }
++ else
++ {
++ rtti = iFind->second;
++ }
++
++ return rtti;
++}
++
++//--------------------------------------------------------------------------------------------------
++static void deleteException( void * pExc )
++{
++ __cxa_exception const * header = ((__cxa_exception const *)pExc - 1);
++ typelib_TypeDescription * pTD = 0;
++ OUString unoName( toUNOname( header->exceptionType->name() ) );
++ ::typelib_typedescription_getByName( &pTD, unoName.pData );
++ OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction => leaking!!!" );
++ if (pTD)
++ {
++ ::uno_destructData( pExc, pTD, cpp_release );
++ ::typelib_typedescription_release( pTD );
++ }
++}
++
++//==================================================================================================
++void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
++{
++#if OSL_DEBUG_LEVEL > 1
++ OString cstr(
++ OUStringToOString(
++ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
++ RTL_TEXTENCODING_ASCII_US ) );
++ fprintf( stderr, "> uno exception occured: %s\n", cstr.getStr() );
++#endif
++ void * pCppExc;
++ type_info * rtti;
++
++ {
++ // construct cpp exception object
++ typelib_TypeDescription * pTypeDescr = 0;
++ TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
++ OSL_ASSERT( pTypeDescr );
++ if (! pTypeDescr)
++ {
++ throw RuntimeException(
++ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get typedescription for type ") ) +
++ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
++ Reference< XInterface >() );
++ }
++
++ pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
++ ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp );
++
++ // destruct uno exception
++ ::uno_any_destruct( pUnoExc, 0 );
++ // avoiding locked counts
++ static RTTI * s_rtti = 0;
++ if (! s_rtti)
++ {
++ MutexGuard guard( Mutex::getGlobalMutex() );
++ if (! s_rtti)
++ {
++#ifdef LEAK_STATIC_DATA
++ s_rtti = new RTTI();
++#else
++ static RTTI rtti_data;
++ s_rtti = &rtti_data;
++#endif
++ }
++ }
++ rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription *) pTypeDescr );
++ TYPELIB_DANGER_RELEASE( pTypeDescr );
++ OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
++ if (! rtti)
++ {
++ throw RuntimeException(
++ OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
++ *reinterpret_cast< OUString const * >( &pUnoExc->pType->pTypeName ),
++ Reference< XInterface >() );
++ }
++ }
++
++ __cxa_throw( pCppExc, rtti, deleteException );
++}
++
++//==================================================================================================
++void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, uno_Mapping * pCpp2Uno )
++{
++ if (! header)
++ {
++ RuntimeException aRE(
++ OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") ),
++ Reference< XInterface >() );
++ Type const & rType = ::getCppuType( &aRE );
++ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
++#if OSL_DEBUG_LEVEL > 0
++ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
++ OSL_ENSURE( 0, cstr.getStr() );
++#endif
++ return;
++ }
++
++ typelib_TypeDescription * pExcTypeDescr = 0;
++ OUString unoName( toUNOname( header->exceptionType->name() ) );
++#if OSL_DEBUG_LEVEL > 1
++ OString cstr_unoName( OUStringToOString( unoName, RTL_TEXTENCODING_ASCII_US ) );
++ fprintf( stderr, "> c++ exception occured: %s\n", cstr_unoName.getStr() );
++#endif
++ typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
++ if (0 == pExcTypeDescr)
++ {
++ RuntimeException aRE(
++ OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not found: ") ) + unoName,
++ Reference< XInterface >() );
++ Type const & rType = ::getCppuType( &aRE );
++ uno_type_any_constructAndConvert( pUnoExc, &aRE, rType.getTypeLibType(), pCpp2Uno );
++#if OSL_DEBUG_LEVEL > 0
++ OString cstr( OUStringToOString( aRE.Message, RTL_TEXTENCODING_ASCII_US ) );
++ OSL_ENSURE( 0, cstr.getStr() );
++#endif
++ }
++ else
++ {
++ // construct uno exception any
++ uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, pExcTypeDescr, pCpp2Uno );
++ typelib_typedescription_release( pExcTypeDescr );
++ }
++}
++
++}
++
+--- /dev/null Wed Dec 31 19:00:00 1969
++++ bridges/source/cpp_uno/gcc3_freebsd_x86-64/makefile.mk Mon May 8 17:17:43 2006
+@@ -0,0 +1,92 @@
++#*************************************************************************
++#
++# OpenOffice.org - a multi-platform office productivity suite
++#
++# $RCSfile$
++#
++# $Revision$
++#
++# last change: $Author$ $Date$
++#
++# The Contents of this file are made available subject to
++# the terms of GNU Lesser General Public License Version 2.1.
++#
++#
++# GNU Lesser General Public License Version 2.1
++# =============================================
++# Copyright 2005 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
++#
++#*************************************************************************
++
++PRJ=..$/..$/..
++
++PRJNAME=bridges
++TARGET=gcc3_uno
++LIBTARGET=no
++ENABLE_EXCEPTIONS=TRUE
++NO_BSYMBOLIC=TRUE
++
++# --- Settings -----------------------------------------------------
++
++.INCLUDE : svpre.mk
++.INCLUDE : settings.mk
++.INCLUDE : sv.mk
++
++# --- Files --------------------------------------------------------
++
++.IF "$(COM)$(OS)$(CPU)$(COMNAME)" == "GCCFREEBSDXgcc3"
++
++.IF "$(cppu_no_leak)" == ""
++CFLAGS += -DLEAK_STATIC_DATA
++.ENDIF
++
++NOOPTFILES= \
++ $(SLO)$/uno2cpp.obj
++
++
++CFLAGSNOOPT=-O0
++
++SLOFILES= \
++ $(SLO)$/abi.obj \
++ $(SLO)$/except.obj \
++ $(SLO)$/cpp2uno.obj \
++ $(SLO)$/uno2cpp.obj \
++ $(SLO)$/call.obj
++
++SHL1TARGET= $(TARGET)
++
++SHL1DEF=$(MISC)$/$(SHL1TARGET).def
++SHL1IMPLIB=i$(TARGET)
++SHL1VERSIONMAP=..$/..$/bridge_exports.map
++
++SHL1OBJS = $(SLOFILES)
++SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
++
++SHL1STDLIBS= \
++ $(CPPULIB) \
++ $(SALLIB)
++
++.ENDIF
++
++# --- Targets ------------------------------------------------------
++
++.INCLUDE : target.mk
++
++$(SLO)$/%.obj: %.s
++ $(CC) -c -o $(SLO)$/$(@:b).o $<
++ touch $@
+--- /dev/null Wed Dec 31 19:00:00 1969
++++ bridges/source/cpp_uno/gcc3_freebsd_x86-64/share.hxx Wed Mar 8 03:51:06 2006
+@@ -0,0 +1,98 @@
++/*************************************************************************
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile$
++ *
++ * $Revision$
++ *
++ * last change: $Author$ $Date$
++ *
++ * The Contents of this file are made available subject to
++ * the terms of GNU Lesser General Public License Version 2.1.
++ *
++ *
++ * GNU Lesser General Public License Version 2.1
++ * =============================================
++ * Copyright 2005 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
++ *
++ ************************************************************************/
++
++#include "uno/mapping.h"
++
++#include <typeinfo>
++#include <exception>
++#include <cstddef>
++
++namespace CPPU_CURRENT_NAMESPACE
++{
++
++void dummy_can_throw_anything( char const * );
++
++// ----- 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 );
++}
+--- /dev/null Wed Dec 31 19:00:00 1969
++++ bridges/source/cpp_uno/gcc3_freebsd_x86-64/uno2cpp.cxx Wed Mar 8 03:51:19 2006
+@@ -0,0 +1,645 @@
++/*************************************************************************
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile$
++ *
++ * $Revision$
++ *
++ * last change: $Author$ $Date$
++ *
++ * The Contents of this file are made available subject to
++ * the terms of GNU Lesser General Public License Version 2.1.
++ *
++ *
++ * GNU Lesser General Public License Version 2.1
++ * =============================================
++ * Copyright 2005 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
++ *
++ ************************************************************************/
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <rtl/alloc.h>
++
++#include <com/sun/star/uno/genfunc.hxx>
++#include "com/sun/star/uno/RuntimeException.hpp"
++#include <uno/data.h>
++
++#include <bridges/cpp_uno/shared/bridge.hxx>
++#include <bridges/cpp_uno/shared/types.hxx>
++#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
++#include "bridges/cpp_uno/shared/vtables.hxx"
++
++#include "share.hxx"
++
++using namespace ::rtl;
++using namespace ::com::sun::star::uno;
++
++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++] = *reinterpret_cast<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++] = *reinterpret_cast<double *>( pSV++ );
++ else
++ *pDS++ = *reinterpret_cast<double *>( 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++] = *reinterpret_cast<sal_uInt32 *>( pSV++ );
++ else
++ *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV++ );
++ break;
++
++ case 'S': // 16-bit Word
++ if (nr_gpr < GPR_COUNT)
++ pGPR[nr_gpr++] = *reinterpret_cast<sal_uInt16 *>( pSV++ );
++ else
++ *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV++ );
++ break;
++
++ case 'B': // Byte
++ if (nr_gpr < GPR_COUNT)
++ pGPR[nr_gpr++] = *reinterpret_cast<sal_uInt8 *>( pSV++ );
++ else
++ *pDS++ = *reinterpret_cast<sal_uInt8 *>( 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;
++
++ bool bReturnsSimpleType = bridges::cpp_uno::shared::isSimpleType( eReturnType );
++
++#if OSL_DEBUG_LEVEL > 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);
++ ARG_GPR(0);
++ case 0:;
++#undef ARG_GPR
++ }
++
++ if ( bReturnsSimpleType )
++ a0 = (sal_uInt64) pThis;
++ else
++ a1 = (sal_uInt64) pThis;
++
++ // 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 rax;
++ sal_uInt64 rdx;
++ } i;
++ struct {
++ double xmm0;
++ double xmm1;
++ } f;
++ };
++
++ typedef ReturnValue (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 );
++
++ // Perform the call
++ ReturnValue aRet = ( ( FunctionCall ) pMethod )( a0, a1, a2, a3, a4, a5 );
++
++ switch (eReturnType)
++ {
++ case typelib_TypeClass_HYPER:
++ case typelib_TypeClass_UNSIGNED_HYPER:
++ *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = aRet.i.rax;
++ break;
++ case typelib_TypeClass_LONG:
++ case typelib_TypeClass_UNSIGNED_LONG:
++ case typelib_TypeClass_ENUM:
++ *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt32*>( &aRet.i.rax );
++ break;
++ case typelib_TypeClass_CHAR:
++ case typelib_TypeClass_SHORT:
++ case typelib_TypeClass_UNSIGNED_SHORT:
++ *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt16*>( &aRet.i.rax );
++ break;
++ case typelib_TypeClass_BOOLEAN:
++ case typelib_TypeClass_BYTE:
++ *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt8*>( &aRet.i.rax );
++ break;
++ case typelib_TypeClass_FLOAT:
++ *reinterpret_cast<float *>( pRegisterReturn ) = *reinterpret_cast<float*>( &aRet.f.xmm0 );
++ break;
++ case typelib_TypeClass_DOUBLE:
++ *reinterpret_cast<double *>( pRegisterReturn ) = *reinterpret_cast<double*>( &aRet.f.xmm0 );
++ break;
++ }
++}
++
++
++//==================================================================================================
++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 )
++{
++ // 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 + 3 );
++ 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 (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
++ {
++ pCppReturn = pUnoReturn; // direct way for simple types
++ }
++ else
++ {
++ // complex return via ptr
++ pCppReturn = *(void **)pCppStack = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
++ ? __builtin_alloca( pReturnTypeDescr->nSize )
++ : pUnoReturn); // direct way
++ *pPT++ = 'H';
++ pCppStack += sizeof(void *);
++ }
++ }
++
++ // Push "this" pointer
++ void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
++ *(void **)pCppStack = pAdjustedThisPtr;
++ *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 && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
++ {
++ uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
++ pThis->getBridge()->getUno2Cpp() );
++
++ 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 (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
++ {
++ uno_copyAndConvertData(
++ *(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
++ pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
++
++ 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(
++ pAdjustedThisPtr, aVtableSlot.index,
++ 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->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
++ fillUnoException( CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
++
++ // 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 bridges::cpp_uno::shared::UnoInterfaceProxy::dispatch(
++ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
++ void * pReturn, void * pArgs[], uno_Any ** ppException ) SAL_THROW(())
++{
++ // is my surrogate
++ bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
++ = static_cast< bridges::cpp_uno::shared::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!" );
++
++ 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( RTL_CONSTASCII_USTRINGPARAM("void") );
++ typelib_typedescriptionreference_new(
++ &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
++
++ // dependent dispatch
++ aVtableSlot.index += 1; // get, then set method
++ cpp_call(
++ pThis, aVtableSlot, // 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!" );
++
++ 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()
++ 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(
++ 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 );
++ }
++ }
++}