/* -*- 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 .
*/
namespace
{ // 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):
// now copy longs down to save register window // and local variables ".LcopyDown:\n\t" "ld [%%l1], %%l2\n\t" "st %%l2,[%%l0]\n\t" "add %%l0, 4, %%l0\n\t" "add %%l1, 4, %%l1\n\t" "subcc %%o4, 1, %%o4\n\t" "bne .LcopyDown\n\t"
"mov %%o5, %%sp\n\t"// move new stack ptr (hopefully) atomically // while register window is valid in both spaces // (scheduling might hit in copyDown loop)
".LdoCall:\n\t" "ld [%%i0], %%l0\n\t"// get vtable ptr
"sll %%i1, 2, %%l6\n\t" // "add %%l6, 8, %%l6\n\t" "add %%l6, %%l0, %%l0\n\t" // // vtable has 8byte wide entries, // // upper half contains 2 half words, of which the first // // is the this ptr patch ! // // first entry is (or __tf)
// "ldsh [%%l0], %%l6\n\t" // load this ptr patch // "add %%l6, %%o0, %%o0\n\t" // patch this ptr
// "add %%l0, 4, %%l0\n\t" // get virtual function ptr "ld [%%l0], %%l0\n\t"
".LcallReturned:\n\t" "mov %%l3, %%sp\n\t"// readjust stack so that our locals are where they belong "st %%o0, %0\n\t"// save possible return registers into our locals "st %%o1, %1\n\t" "std %%f0, %2\n\t" "st %%f0, %3\n\t"
// restore registers "ldd [%%l7], %%l0\n\t" "add %%l7, 8, %%l7\n\t" "ldd [%%l7], %%l2\n\t" "add %%l7, 8, %%l7\n\t" "ldd [%%l7], %%l4\n\t" "add %%l7, 8, %%l7\n\t" "ldd [%%l7], %%o0\n\t" "add %%l7, 8, %%l7\n\t" "ldd [%%l7], %%o2\n\t" "add %%l7, 8, %%l7\n\t" "ldd [%%l7], %%o4\n\t" "add %%l7, 8, %%l7\n\t" "ldd [%%l7], %%l6\n\t"
: "=m"(o0), "=m"(o1), "=m"(f0d), "=m"(f0f)
: "r"(&saveReg[0])
: "memory"
); switch( eReturnType )
{ case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER:
((long*)pRegisterReturn)[1] = o1; case typelib_TypeClass_LONG: case typelib_TypeClass_UNSIGNED_LONG: case typelib_TypeClass_ENUM:
((long*)pRegisterReturn)[0] = o0; break; case typelib_TypeClass_CHAR: case typelib_TypeClass_SHORT: case typelib_TypeClass_UNSIGNED_SHORT:
*(unsignedshort*)pRegisterReturn = (unsignedshort)o0; break; case typelib_TypeClass_BOOLEAN: case typelib_TypeClass_BYTE:
*(unsignedchar*)pRegisterReturn = (unsignedchar)o0; break; case typelib_TypeClass_FLOAT:
*(float*)pRegisterReturn = f0f; break; case typelib_TypeClass_DOUBLE:
*(double*)pRegisterReturn = f0d; break; default: break;
}
}
switch (pParamTypeDescr->eTypeClass)
{ case typelib_TypeClass_HYPER: case typelib_TypeClass_UNSIGNED_HYPER: case typelib_TypeClass_DOUBLE:
static_assert(sizeof (double) == sizeof (sal_Int64), "boo");
*reinterpret_cast< sal_Int32 * >(pCppStack) =
*reinterpret_cast< sal_Int32 const * >(pUnoArgs[ nPos ]);
pCppStack += sizeof (sal_Int32);
*reinterpret_cast< sal_Int32 * >(pCppStack) =
*(reinterpret_cast< sal_Int32 const * >(pUnoArgs[ nPos ] ) + 1); break; default:
uno_copyAndConvertData(
pCppArgs[nPos], pUnoArgs[nPos], pParamTypeDescr,
pThis->getBridge()->getUno2Cpp() ); 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 );
pTempIndices[nTempIndices] = nPos; // default constructed for cpp call // will be released at reconversion
ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
} // is in/inout elseif (bridges::cpp_uno::shared::relatesToInterfaceType(
pParamTypeDescr ))
{
uno_copyAndConvertData(
*(void **)pCppStack = pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
pUnoArgs[nPos], pParamTypeDescr,
pThis->getBridge()->getUno2Cpp() );
pTempIndices[nTempIndices] = nPos; // has to be reconverted // will be released at reconversion
ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
} else// direct way
{
*(void **)pCppStack = pCppArgs[nPos] = pUnoArgs[nPos]; // no longer needed
TYPELIB_DANGER_RELEASE( pParamTypeDescr );
}
}
pCppStack += sizeof(sal_Int32); // standard parameter length
}
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 und die Messung sind noch experimentell.