in main/bridges/source/cpp_uno/cc5_solaris_sparc64/cpp2uno.cxx [125:404]
void call(
bridges::cpp_uno::shared::CppInterfaceProxy * proxy,
css::uno::TypeDescription const & description,
bool directReturn, typelib_TypeDescriptionReference * returnType,
sal_Int32 count, typelib_MethodParameter * parameters,
unsigned long * callStack)
{
typelib_TypeDescription * rtd = NULL;
if (returnType != NULL) {
TYPELIB_DANGER_GET(&rtd, returnType);
}
bool retconv =
rtd != NULL && bridges::cpp_uno::shared::relatesToInterfaceType(rtd);
OSL_ASSERT(!(directReturn && retconv));
void * retin;
void * retout;
char retbuf[32];
if (directReturn) {
retin = returnType == NULL ? NULL : retbuf;
} else {
retout = reinterpret_cast< void * >(callStack[0]);
retin = retconv ? alloca(rtd->nSize) : retout;
}
void ** args = static_cast< void ** >(alloca(count * sizeof (void *)));
void ** cppArgs = static_cast< void ** >(alloca(count * sizeof (void *)));
typelib_TypeDescription ** argtds =
static_cast< typelib_TypeDescription ** >(
alloca(count * sizeof (typelib_TypeDescription *)));
union fp { float f; double d; };
fp copies[15];
sal_Int32 stackPos = directReturn ? 1 : 2; // skip return ptr and this ptr
for (sal_Int32 i = 0; i < count; ++i) {
typelib_TypeDescription * ptd = NULL;
TYPELIB_DANGER_GET(&ptd, parameters[i].pTypeRef);
if (!parameters[i].bOut && bridges::cpp_uno::shared::isSimpleType(ptd))
{
switch (ptd->eTypeClass) {
case typelib_TypeClass_FLOAT:
if (stackPos <= 15) {
switch (stackPos) {
case 1:
fp_storef3(&copies[0].f);
break;
case 2:
fp_storef5(&copies[1].f);
break;
case 3:
fp_storef7(&copies[2].f);
break;
case 4:
fp_storef9(&copies[3].f);
break;
case 5:
fp_storef11(&copies[4].f);
break;
case 6:
fp_storef13(&copies[5].f);
break;
case 7:
fp_storef15(&copies[6].f);
break;
case 8:
fp_storef17(&copies[7].f);
break;
case 9:
fp_storef19(&copies[8].f);
break;
case 10:
fp_storef21(&copies[9].f);
break;
case 11:
fp_storef23(&copies[10].f);
break;
case 12:
fp_storef25(&copies[11].f);
break;
case 13:
fp_storef27(&copies[12].f);
break;
case 14:
fp_storef29(&copies[13].f);
break;
case 15:
fp_storef31(&copies[14].f);
break;
default:
OSL_ASSERT(false);
break;
}
args[i] = &copies[stackPos - 1].f;
} else {
args[i] = reinterpret_cast< char * >(callStack + stackPos) +
(sizeof (unsigned long) - sizeof (float));
}
break;
case typelib_TypeClass_DOUBLE:
if (stackPos <= 15) {
switch (stackPos) {
case 1:
fp_stored2(&copies[0].d);
break;
case 2:
fp_stored4(&copies[1].d);
break;
case 3:
fp_stored6(&copies[2].d);
break;
case 4:
fp_stored8(&copies[3].d);
break;
case 5:
fp_stored10(&copies[4].d);
break;
case 6:
fp_stored12(&copies[5].d);
break;
case 7:
fp_stored14(&copies[6].d);
break;
case 8:
fp_stored16(&copies[7].d);
break;
case 9:
fp_stored18(&copies[8].d);
break;
case 10:
fp_stored20(&copies[9].d);
break;
case 11:
fp_stored22(&copies[10].d);
break;
case 12:
fp_stored24(&copies[11].d);
break;
case 13:
fp_stored26(&copies[12].d);
break;
case 14:
fp_stored28(&copies[13].d);
break;
case 15:
fp_stored30(&copies[14].d);
break;
default:
OSL_ASSERT(false);
break;
}
args[i] = &copies[stackPos - 1].d;
} else {
args[i] = reinterpret_cast< char * >(callStack + stackPos) +
(sizeof (unsigned long) - sizeof (double));
}
break;
default:
OSL_ASSERT(ptd->nSize <= 8);
args[i] = reinterpret_cast< char * >(callStack + stackPos) +
(sizeof (unsigned long) - ptd->nSize);
break;
}
argtds[i] = NULL;
TYPELIB_DANGER_RELEASE(ptd);
} else {
cppArgs[i] = reinterpret_cast< void * >(callStack[stackPos]);
if (!parameters[i].bIn) {
args[i] = alloca(ptd->nSize);
argtds[i] = ptd;
} else if (bridges::cpp_uno::shared::relatesToInterfaceType(ptd)) {
args[i] = alloca(ptd->nSize);
uno_copyAndConvertData(
args[i], reinterpret_cast< void * >(callStack[stackPos]),
ptd, proxy->getBridge()->getCpp2Uno());
argtds[i] = ptd;
} else {
args[i] = reinterpret_cast< void * >(callStack[stackPos]);
argtds[i] = NULL;
TYPELIB_DANGER_RELEASE(ptd);
}
}
++stackPos;
}
uno_Any exc;
uno_Any * pexc = &exc;
proxy->getUnoI()->pDispatcher(
proxy->getUnoI(), description.get(), retin, args, &pexc);
if (pexc != NULL) {
for (sal_Int32 i = 0; i < count; ++i) {
if (argtds[i] != NULL) {
if (parameters[i].bIn) {
uno_destructData(args[i], argtds[i], NULL);
}
TYPELIB_DANGER_RELEASE(argtds[i]);
}
}
if (rtd != NULL) {
TYPELIB_DANGER_RELEASE(rtd);
}
bridges::cpp_uno::cc5_solaris_sparc64::raiseException(
&exc, proxy->getBridge()->getUno2Cpp());
std::abort(); // just in case
}
for (sal_Int32 i = 0; i < count; ++i) {
if (argtds[i] != NULL) {
if (parameters[i].bOut) {
uno_destructData(
cppArgs[i], argtds[i],
reinterpret_cast< uno_ReleaseFunc >(css::uno::cpp_release));
uno_copyAndConvertData(
cppArgs[i], args[i], argtds[i],
proxy->getBridge()->getUno2Cpp());
}
uno_destructData(args[i], argtds[i], NULL);
TYPELIB_DANGER_RELEASE(argtds[i]);
}
}
if (directReturn) {
if (rtd != NULL) {
switch (rtd->eTypeClass) {
case typelib_TypeClass_VOID:
break;
case typelib_TypeClass_BOOLEAN:
callStack[0] = *reinterpret_cast< sal_Bool * >(retbuf);
break;
case typelib_TypeClass_BYTE:
callStack[0] = *reinterpret_cast< sal_Int8 * >(retbuf);
break;
case typelib_TypeClass_SHORT:
callStack[0] = *reinterpret_cast< sal_Int16 * >(retbuf);
break;
case typelib_TypeClass_UNSIGNED_SHORT:
callStack[0] = *reinterpret_cast< sal_uInt16 * >(retbuf);
break;
case typelib_TypeClass_LONG:
case typelib_TypeClass_ENUM:
callStack[0] = *reinterpret_cast< sal_Int32 * >(retbuf);
break;
case typelib_TypeClass_UNSIGNED_LONG:
callStack[0] = *reinterpret_cast< sal_uInt32 * >(retbuf);
break;
case typelib_TypeClass_HYPER:
callStack[0] = *reinterpret_cast< sal_Int64 * >(retbuf);
break;
case typelib_TypeClass_UNSIGNED_HYPER:
callStack[0] = *reinterpret_cast< sal_uInt64 * >(retbuf);
break;
case typelib_TypeClass_FLOAT:
fp_loadf0(reinterpret_cast< float * >(retbuf));
break;
case typelib_TypeClass_DOUBLE:
fp_loadd0(reinterpret_cast< double * >(retbuf));
break;
case typelib_TypeClass_CHAR:
callStack[0] = *reinterpret_cast< sal_Unicode * >(retbuf);
break;
case typelib_TypeClass_STRING:
case typelib_TypeClass_TYPE:
case typelib_TypeClass_SEQUENCE:
case typelib_TypeClass_INTERFACE:
callStack[0] = reinterpret_cast< unsigned long >(
*reinterpret_cast< void ** >(retbuf));
break;
case typelib_TypeClass_STRUCT:
loadFpRegsFromStruct(rtd, retbuf);
// fall through
case typelib_TypeClass_ANY:
std::memcpy(callStack, retbuf, rtd->nSize);
break;
default:
OSL_ASSERT(false);
break;
}
}
} else if (retconv) {
uno_copyAndConvertData(
retout, retin, rtd, proxy->getBridge()->getUno2Cpp());
uno_destructData(retin, rtd, NULL);
}
if (rtd != NULL) {
TYPELIB_DANGER_RELEASE(rtd);
}
}