/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
// if we don't return via register, the first stack parameter is the return value int nFirstRealParam = 2; if (pReturnAddr == pCallStack)
++nFirstRealParam;
if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType(pParamTD))
{
pCppArgs[nPos] = pCppIncomingParams;
pUnoArgs[nPos] = pCppIncomingParams; if (sizeof(void*) == sizeof(sal_Int32)) // account 64bit types on 32bit arch
{ switch (pParamTD->eTypeClass)
{ case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: case typelib_TypeClass_DOUBLE:
++pCppIncomingParams; break; default: break;
}
}
TYPELIB_DANGER_RELEASE(pParamTD);
} else// ptr to complex value | ref
{
pCppArgs[nPos] = *pCppIncomingParams;
if (!rParam.bIn) // is pure out
{ // UNO out is unconstructed memory
pUnoArgs[nPos] = alloca(pParamTD->nSize); // pParamTD will be released at reconversion
pTempIndexes[nTempIndex] = nPos;
ppTempParamTD[nTempIndex++] = pParamTD;
} // is in/inout elseif (bridges::cpp_uno::shared::relatesToInterfaceType(pParamTD))
{
::uno_copyAndConvertData(pUnoArgs[nPos] = alloca(pParamTD->nSize),
*pCppIncomingParams, pParamTD,
pThis->getBridge()->getCpp2Uno()); // pParamTD will be released at reconversion
pTempIndexes[nTempIndex] = nPos;
ppTempParamTD[nTempIndex++] = pParamTD;
} else// direct way
{
pUnoArgs[nPos] = *pCppIncomingParams;
TYPELIB_DANGER_RELEASE(pParamTD);
}
}
}
// ExceptionHolder
uno_Any aUnoExc; // Any will be constructed by callee
uno_Any* pUnoExc = &aUnoExc;
// invoke UNO dispatch call
pThis->getUnoI()->pDispatcher(pThis->getUnoI(), pMemberTD, pUnoReturn, pUnoArgs, &pUnoExc);
// in case an exception occurred... if (pUnoExc)
{ // destruct temporary in/inout params while (nTempIndex--)
{ const sal_Int32 nIndex = pTempIndexes[nTempIndex]; if (pParams[nIndex].bIn) // is in/inout => was constructed
::uno_destructData(pUnoArgs[nIndex], ppTempParamTD[nTempIndex], nullptr);
TYPELIB_DANGER_RELEASE(ppTempParamTD[nTempIndex]);
} if (pReturnTD)
TYPELIB_DANGER_RELEASE(pReturnTD);
msvc_raiseException(&aUnoExc, pThis->getBridge()->getUno2Cpp()); // has to destruct the any
} else// no exception occurred...
{ // handle temporary params while (nTempIndex--)
{ const sal_Int32 nIndex = pTempIndexes[nTempIndex];
typelib_TypeDescription* pParamTD = ppTempParamTD[nTempIndex];
if (pParams[nIndex].bOut) // inout/out
{ // convert and assign
::uno_destructData(pCppArgs[nIndex], pParamTD, uno::cpp_release);
::uno_copyAndConvertData(pCppArgs[nIndex], pUnoArgs[nIndex], pParamTD,
pThis->getBridge()->getUno2Cpp());
} // destroy temp UNO param
::uno_destructData(pUnoArgs[nIndex], pParamTD, nullptr);
TYPELIB_DANGER_RELEASE(pParamTD);
}
// handle return if (pCppReturn) // has complex return
{ if (pUnoReturn != pCppReturn) // needs reconversion
{
::uno_copyAndConvertData(pCppReturn, pUnoReturn, pReturnTD,
pThis->getBridge()->getUno2Cpp()); // destroy temp UNO return
::uno_destructData(pUnoReturn, pReturnTD, nullptr);
}
*pReturnAddr = pCppReturn;
}
typelib_TypeClass __cdecl cpp_mediate(void** pCallStack, const sal_Int32 nFunctionIndex, const sal_Int32 nVtableOffset,
sal_Int64* const pRegisterReturn)
{ // pCallStack: // x64: ret value, ret adr, this, [complex ret *], cpp params // x86: ret adr, this, [complex ret *], cpp params // // pRegisterReturn is just set on x86 // the return value is either the direct set for simply types, or it is set // to "complex ret *" and the real return value is constructed at that memory.
// if we don't return via register, the first stack parameter is the return value void** const pReturnAddr
= pRegisterReturn ? reinterpret_cast<void**>(pRegisterReturn) : pCallStack;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.