INTEGRATION: CWS sixtyfour11 (1.7.22); FILE MERGED

2007/02/16 11:43:53 kendy 1.7.22.4: #i73974# Cosmetical change.
2007/02/16 11:38:58 kendy 1.7.22.3: #i73974#
Rewrite some deep gcc magic to a simple assembler.
2007/02/13 13:27:29 kendy 1.7.22.2: #i73974# #include <string.h>, remove NOOPT from makefile.mk.
2007/02/13 13:12:39 kendy 1.7.22.1: #i73974#
x86-64 bridge cleanup & float fix.
This commit is contained in:
Rüdiger Timm
2007-04-25 13:57:33 +00:00
parent d7f5d52ccd
commit f424e55b4e

View File

@@ -4,9 +4,9 @@
*
* $RCSfile: uno2cpp.cxx,v $
*
* $Revision: 1.7 $
* $Revision: 1.8 $
*
* last change: $Author: rt $ $Date: 2006-12-01 14:17:59 $
* last change: $Author: rt $ $Date: 2007-04-25 14:57:33 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
@@ -38,6 +38,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rtl/alloc.h>
#include <com/sun/star/uno/genfunc.hxx>
@@ -55,265 +56,188 @@
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++ = *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_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
char * pPT, sal_uInt64 * pStackLongs, sal_uInt32 nStackLongs)
sal_uInt64 *pStack, sal_uInt32 nStack,
sal_uInt64 *pGPR, sal_uInt32 nGPR,
double *pFPR, sal_uInt32 nFPR) __attribute__((noinline));
static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
sal_uInt64 *pStack, sal_uInt32 nStack,
sal_uInt64 *pGPR, sal_uInt32 nGPR,
double *pFPR, sal_uInt32 nFPR)
{
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 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++;
}
fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
for ( int i = 0; i < nGPR; ++i )
fprintf( stderr, "0x%lx, ", pGPR[i] );
fprintf( stderr, "\nFPR's (%d): ", nFPR );
for ( int i = 0; i < nFPR; ++i )
fprintf( stderr, "%f, ", pFPR[i] );
fprintf( stderr, "\nStack (%d): ", nStack );
for ( int i = 0; i < nStack; ++i )
fprintf( stderr, "0x%lx, ", pStack[i] );
fprintf( stderr, "\n" );
}
#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);
// The call instruction within the asm section of callVirtualMethod may throw
// exceptions. So that the compiler handles this correctly, it is important
// that (a) callVirtualMethod might call dummy_can_throw_anything (although this
// never happens at runtime), which in turn can throw exceptions, and (b)
// callVirtualMethod is not inlined at its call site (so that any exceptions are
// caught which are thrown from the instruction calling callVirtualMethod):
if ( !pThis )
CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything( "xxx" ); // address something
// 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 ( bSimpleReturn )
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));
// Should not happen, but...
if ( nFPR > x86_64::MAX_SSE_REGS )
nFPR = x86_64::MAX_SSE_REGS;
if ( nGPR > x86_64::MAX_GPR_REGS )
nGPR = x86_64::MAX_GPR_REGS;
// 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;
};
// Load parameters to stack, if necessary
if ( nStack )
{
// 16-bytes aligned
sal_uInt32 nStackBytes = ( ( nStack + 1 ) >> 1 ) * 16;
sal_uInt64 *pCallStack = (sal_uInt64 *) __builtin_alloca( nStackBytes );
memcpy( pCallStack, pStack, nStackBytes );
}
typedef ReturnValue (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 );
// Return values
sal_uInt64 rax;
sal_uInt64 rdx;
double xmm0;
// Perform the call
ReturnValue aRet = ( ( FunctionCall ) pMethod )( a0, a1, a2, a3, a4, a5 );
asm volatile (
// Fill the xmm registers
"movq %2, %%rax\n\t"
"movsd (%%rax), %%xmm0\n\t"
"movsd 8(%%rax), %%xmm1\n\t"
"movsd 16(%%rax), %%xmm2\n\t"
"movsd 24(%%rax), %%xmm3\n\t"
"movsd 32(%%rax), %%xmm4\n\t"
"movsd 40(%%rax), %%xmm5\n\t"
"movsd 48(%%rax), %%xmm6\n\t"
"movsd 56(%%rax), %%xmm7\n\t"
// Fill the general purpose registers
"movq %1, %%rax\n\t"
"movq (%%rax), %%rdi\n\t"
"movq 8(%%rax), %%rsi\n\t"
"movq 16(%%rax), %%rdx\n\t"
"movq 24(%%rax), %%rcx\n\t"
"movq 32(%%rax), %%r8\n\t"
"movq 40(%%rax), %%r9\n\t"
// Perform the call
"movq %0, %%r11\n\t"
"movq %3, %%rax\n\t"
"call *%%r11\n\t"
// Fill the return values
"movq %%rax, %4\n\t"
"movq %%rdx, %5\n\t"
"movsd %%xmm0, %6\n\t"
:
: "m" ( pMethod ), "m" ( pGPR ), "m" ( pFPR ), "m" ( nFPR ),
"m" ( rax ), "m" ( rdx ), "m" ( xmm0 )
: "rax", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11"
);
switch (pReturnTypeDescr->eTypeClass)
{
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
*reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = aRet.i.rax;
*reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = 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 );
*reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt32*>( &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 );
*reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt16*>( &rax );
break;
case typelib_TypeClass_BOOLEAN:
case typelib_TypeClass_BYTE:
*reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt8*>( &aRet.i.rax );
*reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = *reinterpret_cast<sal_uInt8*>( &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 );
*reinterpret_cast<double *>( pRegisterReturn ) = xmm0;
break;
default: {
sal_Int32 const nRetSize = pReturnTypeDescr->nSize;
if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0) {
if (nRetSize > 8)
static_cast<sal_uInt64 *>(pRegisterReturn)[1] = aRet.i.rdx;
static_cast<sal_uInt64 *>(pRegisterReturn)[0] = aRet.i.rax;
default:
{
sal_Int32 const nRetSize = pReturnTypeDescr->nSize;
if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0)
{
if (nRetSize > 8)
static_cast<sal_uInt64 *>(pRegisterReturn)[1] = rdx;
static_cast<sal_uInt64 *>(pRegisterReturn)[0] = rax;
}
break;
}
break;
}
}
}
//==================================================================================================
// Macros for easier insertion of values to registers or stack
// pSV - pointer to the source
// nr - order of the value [will be increased if stored to register]
// pFPR, pGPR - pointer to the registers
// pDS - pointer to the stack [will be increased if stored here]
// The value in %xmm register is already prepared to be retrieved as a float,
// thus we treat float and double the same
#define INSERT_FLOAT_DOUBLE( pSV, nr, pFPR, pDS ) \
if ( nr < x86_64::MAX_SSE_REGS ) \
pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
else \
*pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
#define INSERT_INT64( pSV, nr, pGPR, pDS ) \
if ( nr < x86_64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
else \
*pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
if ( nr < x86_64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
else \
*pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
if ( nr < x86_64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
else \
*pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
if ( nr < x86_64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
else \
*pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
//==================================================================================================
static void cpp_call(
bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
bridges::cpp_uno::shared::VtableSlot aVtableSlot,
@@ -322,54 +246,52 @@ static void cpp_call(
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;
// (but will be used less - some of the values will be in pGPR and pFPR)
sal_uInt64 *pStack = (sal_uInt64 *)__builtin_alloca( (nParams + 3) * sizeof(sal_uInt64) );
sal_uInt64 *pStackStart = pStack;
// We need to know parameter types for callVirtualMethod() so generate a signature string
char * pParamType = (char *)__builtin_alloca( nParams + 3 );
char * pPT = pParamType;
sal_uInt64 pGPR[x86_64::MAX_GPR_REGS];
sal_uInt32 nGPR = 0;
double pFPR[x86_64::MAX_SSE_REGS];
sal_uInt32 nFPR = 0;
// 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
void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion (see below)
bool bSimpleReturn = true;
if (pReturnTypeDescr)
if ( pReturnTypeDescr )
{
if ( x86_64::return_in_hidden_param( pReturnTypeRef ) )
bSimpleReturn = false;
if (bSimpleReturn)
if ( bSimpleReturn )
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 *);
pCppReturn = bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )?
__builtin_alloca( pReturnTypeDescr->nSize ) : pUnoReturn;
INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack );
}
}
// Push "this" pointer
void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() ) + aVtableSlot.offset;
*(void **)pCppStack = pAdjustedThisPtr;
*pPT++ = 'H';
pCppStack += sizeof(void *);
INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
// stack space
// Args
void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
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;
sal_Int32 nTempIndizes = 0;
for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
{
@@ -379,45 +301,32 @@ static void cpp_call(
if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
{
uno_copyAndConvertData( pCppArgs[nPos] = pCppStack, pUnoArgs[nPos], pParamTypeDescr,
uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), 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_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack );
break;
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_ENUM:
*pPT++ = 'I';
INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack );
break;
case typelib_TypeClass_SHORT:
case typelib_TypeClass_CHAR:
case typelib_TypeClass_UNSIGNED_SHORT:
*pPT++ = 'S';
INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack );
break;
case typelib_TypeClass_BOOLEAN:
case typelib_TypeClass_BYTE:
*pPT++ = 'B';
INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack );
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';
INSERT_FLOAT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack );
break;
}
@@ -430,7 +339,7 @@ static void cpp_call(
{
// cpp out is constructed mem, uno out is not!
uno_constructData(
*(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
pParamTypeDescr );
pTempIndizes[nTempIndizes] = nPos; // default constructed for cpp call
// will be released at reconversion
@@ -440,7 +349,7 @@ static void cpp_call(
else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
{
uno_copyAndConvertData(
*(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
pTempIndizes[nTempIndizes] = nPos; // has to be reconverted
@@ -449,27 +358,22 @@ static void cpp_call(
}
else // direct way
{
*(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos];
pCppArgs[nPos] = pUnoArgs[nPos];
// no longer needed
TYPELIB_DANGER_RELEASE( pParamTypeDescr );
}
// FIXME: is this the right way to pass these?
*pPT++='H';
INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
}
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, bSimpleReturn, pParamType,
(sal_uInt64 *)pCppStackStart, (pCppStack - pCppStackStart) / sizeof(sal_uInt64) );
pCppReturn, pReturnTypeDescr, bSimpleReturn,
pStackStart, ( pStack - pStackStart ),
pGPR, nGPR,
pFPR, nFPR );
// NO exception occured...
*ppUnoExc = 0;
@@ -525,8 +429,8 @@ static void cpp_call(
}
}
//==================================================================================================
namespace bridges { namespace cpp_uno { namespace shared {
void unoInterfaceProxyDispatch(