in main/bridges/source/cpp_uno/gcc3_linux_hppa/cpp2uno.cxx [52:370]
static typelib_TypeClass cpp2uno_call(
bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
const typelib_TypeDescription * pMemberTypeDescr,
typelib_TypeDescriptionReference * pReturnTypeRef,
sal_Int32 nParams, typelib_MethodParameter * pParams,
long r8, void ** gpreg, double *fpreg, void ** ovrflw,
sal_Int64 * pRegisterReturn /* space for register return */ )
{
void ** startovrflw = ovrflw;
int nregs = 0; //number of words passed in registers
#ifdef CMC_DEBUG
fprintf(stderr, "cpp2uno_call\n");
#endif
// return
typelib_TypeDescription * pReturnTypeDescr = 0;
if (pReturnTypeRef)
TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
void * pUnoReturn = 0;
// complex return ptr: if != 0 && != pUnoReturn, reconversion need
void * pCppReturn = 0;
if (pReturnTypeDescr)
{
if (hppa::isRegisterReturn(pReturnTypeRef))
{
#ifdef CMC_DEBUG
fprintf(stderr, "simple return\n");
#endif
pUnoReturn = pRegisterReturn; // direct way for simple types
}
else
{
#ifdef CMC_DEBUG
fprintf(stderr, "complex return via r8\n");
#endif
pCppReturn = (void *)r8;
pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
? alloca( pReturnTypeDescr->nSize )
: pCppReturn); // direct way
}
}
// pop this
gpreg++;
fpreg++;
nregs++;
// stack space
OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
// 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;
bool bOverFlowUsed = false;
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 ))
{
switch (pParamTypeDescr->eTypeClass)
{
case typelib_TypeClass_DOUBLE:
if (nregs < hppa::MAX_WORDS_IN_REGS && (nregs & 1))
{
gpreg++;
fpreg++;
nregs++;
}
if (nregs < hppa::MAX_WORDS_IN_REGS-1)
{
fpreg++;
pCppArgs[nPos] = pUnoArgs[nPos] = fpreg;
gpreg+=2;
fpreg+=2;
nregs+=2;
}
else
{
if ((startovrflw-ovrflw) & 1)
ovrflw--;
pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)ovrflw - 4);
bOverFlowUsed = true;
}
if (bOverFlowUsed) ovrflw-=2;
break;
case typelib_TypeClass_FLOAT:
if (nregs < hppa::MAX_WORDS_IN_REGS)
{
pCppArgs[nPos] = pUnoArgs[nPos] = fpreg;
gpreg++;
fpreg++;
nregs++;
}
else
{
pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
bOverFlowUsed = true;
}
if (bOverFlowUsed) ovrflw--;
break;
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
if (nregs < hppa::MAX_WORDS_IN_REGS && (nregs & 1))
{
gpreg++;
fpreg++;
nregs++;
}
if (nregs < hppa::MAX_WORDS_IN_REGS-1)
{
pCppArgs[nPos] = pUnoArgs[nPos] = gpreg;
gpreg+=2;
fpreg+=2;
nregs+=2;
}
else
{
if ((startovrflw-ovrflw) & 1)
ovrflw--;
pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)ovrflw - 4);
bOverFlowUsed = true;
}
if (bOverFlowUsed) ovrflw-=2;
break;
case typelib_TypeClass_BYTE:
case typelib_TypeClass_BOOLEAN:
if (nregs < hppa::MAX_WORDS_IN_REGS)
{
pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)gpreg + 3);
gpreg++;
fpreg++;
nregs++;
}
else
{
pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)ovrflw+3);
bOverFlowUsed = true;
}
if (bOverFlowUsed) ovrflw--;
break;
case typelib_TypeClass_CHAR:
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
if (nregs < hppa::MAX_WORDS_IN_REGS)
{
pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)gpreg+2);
gpreg++;
fpreg++;
nregs++;
}
else
{
pCppArgs[nPos] = pUnoArgs[nPos] = ((char*)ovrflw+2);
bOverFlowUsed = true;
}
if (bOverFlowUsed) ovrflw--;
break;
case typelib_TypeClass_ENUM:
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
default:
if (nregs < hppa::MAX_WORDS_IN_REGS)
{
pCppArgs[nPos] = pUnoArgs[nPos] = gpreg;
gpreg++;
fpreg++;
nregs++;
}
else
{
pCppArgs[nPos] = pUnoArgs[nPos] = ovrflw;
bOverFlowUsed = true;
}
if (bOverFlowUsed) ovrflw--;
break;
}
// no longer needed
TYPELIB_DANGER_RELEASE( pParamTypeDescr );
}
else // ptr to complex value | ref
{
void *pCppStack;
if (nregs < hppa::MAX_WORDS_IN_REGS)
{
pCppArgs[nPos] = pCppStack = *gpreg;
gpreg++;
fpreg++;
nregs++;
}
else
{
pCppArgs[nPos] = pCppStack = *ovrflw;
bOverFlowUsed = true;
}
if (bOverFlowUsed) 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;
}
// is in/inout
else if (bridges::cpp_uno::shared::relatesToInterfaceType(
pParamTypeDescr ))
{
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;
#ifdef CMC_DEBUG
fprintf(stderr, "before dispatch\n");
#endif
// invoke uno dispatch call
(*pThis->getUnoI()->pDispatcher)(
pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
#ifdef CMC_DEBUG
fprintf(stderr, "after dispatch\n");
#endif
// in case an exception occurred...
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 occurred...
{
// 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 eax
*(void **)pRegisterReturn = pCppReturn;
}
if (pReturnTypeDescr)
{
typelib_TypeClass eRet =
(typelib_TypeClass)pReturnTypeDescr->eTypeClass;
TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
return eRet;
}
else
return typelib_TypeClass_VOID;
}
}