From 267c6f2ac71f92999e969232431ba04678e7437e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 07:54:39 +0200 Subject: Adding upstream version 4:24.2.0. Signed-off-by: Daniel Baumann --- .../source/cpp_uno/msvc_win32_arm64/uno2cpp.cxx | 341 +++++++++++++++++++++ 1 file changed, 341 insertions(+) create mode 100644 bridges/source/cpp_uno/msvc_win32_arm64/uno2cpp.cxx (limited to 'bridges/source/cpp_uno/msvc_win32_arm64/uno2cpp.cxx') diff --git a/bridges/source/cpp_uno/msvc_win32_arm64/uno2cpp.cxx b/bridges/source/cpp_uno/msvc_win32_arm64/uno2cpp.cxx new file mode 100644 index 0000000000..a0c2adc6f6 --- /dev/null +++ b/bridges/source/cpp_uno/msvc_win32_arm64/uno2cpp.cxx @@ -0,0 +1,341 @@ +/* -*- 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 . + */ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "abi.hxx" +#include + +namespace +{ +extern "C" void callVirtualFunction(sal_uInt64* stack, sal_uInt64* frame, sal_uInt64 function, + void* ret); + +void pushArgument(sal_uInt64 value, sal_uInt64* stack, sal_Int32& sp, sal_uInt64* regs, + sal_Int32& nregs) +{ + (nregs != 8 ? regs[nregs++] : stack[sp++]) = value; +} + +void call(bridges::cpp_uno::shared::UnoInterfaceProxy* pProxy, + bridges::cpp_uno::shared::VtableSlot slot, typelib_TypeDescriptionReference* returnType, + const sal_Int32 count, typelib_MethodParameter* parameters, void* returnValue, + void** arguments, uno_Any** exception) +{ + static_assert(sizeof(sal_uInt64) == sizeof(void*)); + typelib_TypeDescription* aReturnTD = nullptr; + TYPELIB_DANGER_GET(&aReturnTD, returnType); + const ReturnKind eRetKind = getReturnKind(aReturnTD); + const bool retConv = bridges::cpp_uno::shared::relatesToInterfaceType(aReturnTD); + void* ret = retConv ? alloca(aReturnTD->nSize) : returnValue; + + sal_uInt64** thisPtr = reinterpret_cast(pProxy->getCppI()) + slot.offset; + + sal_uInt64* gpr = static_cast(alloca((count + 16) * sizeof(sal_uInt64) + 32)); + sal_uInt64* fpr = &gpr[8]; + sal_uInt64* stack = &gpr[16]; + sal_uInt64* frame = &gpr[16 + count]; + void** cppArgs = static_cast(alloca(count * sizeof(void*))); + typelib_TypeDescription** ptds + = static_cast(alloca(count * sizeof(typelib_TypeDescription*))); + + sal_Int32 sp = 0; + sal_Int32 nGPR = 0; + sal_Int32 nFPR = 0; + gpr[nGPR++] = reinterpret_cast(thisPtr); + + for (sal_Int32 i = 0; i != count; ++i) + { + if (!parameters[i].bOut && bridges::cpp_uno::shared::isSimpleType(parameters[i].pTypeRef)) + { + cppArgs[i] = 0; + switch (parameters[i].pTypeRef->eTypeClass) + { + case typelib_TypeClass_BOOLEAN: + pushArgument(*static_cast(arguments[i]), stack, sp, gpr, nGPR); + break; + case typelib_TypeClass_BYTE: + pushArgument(*static_cast(arguments[i]), stack, sp, gpr, nGPR); + break; + case typelib_TypeClass_SHORT: + pushArgument(*static_cast(arguments[i]), stack, sp, gpr, nGPR); + break; + case typelib_TypeClass_UNSIGNED_SHORT: + pushArgument(*static_cast(arguments[i]), stack, sp, gpr, nGPR); + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_ENUM: + pushArgument(*static_cast(arguments[i]), stack, sp, gpr, nGPR); + break; + case typelib_TypeClass_UNSIGNED_LONG: + pushArgument(*static_cast(arguments[i]), stack, sp, gpr, nGPR); + break; + case typelib_TypeClass_HYPER: + pushArgument(*static_cast(arguments[i]), stack, sp, gpr, nGPR); + break; + case typelib_TypeClass_UNSIGNED_HYPER: + pushArgument(*static_cast(arguments[i]), stack, sp, gpr, nGPR); + break; + case typelib_TypeClass_FLOAT: + pushArgument(*static_cast(arguments[i]), stack, sp, fpr, nFPR); + break; + case typelib_TypeClass_DOUBLE: + pushArgument(*static_cast(arguments[i]), stack, sp, fpr, nFPR); + break; + case typelib_TypeClass_CHAR: + pushArgument(*static_cast(arguments[i]), stack, sp, gpr, nGPR); + break; + default: + assert(false); + } + } + else + { + typelib_TypeDescription* ptd = 0; + TYPELIB_DANGER_GET(&ptd, parameters[i].pTypeRef); + if (!parameters[i].bIn) + { + cppArgs[i] = alloca(ptd->nSize); + uno_constructData(cppArgs[i], ptd); + ptds[i] = ptd; + pushArgument(reinterpret_cast(cppArgs[i]), stack, sp, gpr, nGPR); + } + else if (bridges::cpp_uno::shared::relatesToInterfaceType(ptd)) + { + cppArgs[i] = alloca(ptd->nSize); + uno_copyAndConvertData(cppArgs[i], arguments[i], ptd, + pProxy->getBridge()->getUno2Cpp()); + ptds[i] = ptd; + pushArgument(reinterpret_cast(cppArgs[i]), stack, sp, gpr, nGPR); + } + else + { + cppArgs[i] = 0; + pushArgument(reinterpret_cast(arguments[i]), stack, sp, gpr, nGPR); + TYPELIB_DANGER_RELEASE(ptd); + } + } + } + + __try + { + callVirtualFunction(stack, frame, (*thisPtr)[slot.index], ret); + } + __except (msvc_filterCppException(GetExceptionInformation(), *exception, + pProxy->getBridge()->getCpp2Uno())) + { + for (sal_Int32 i = 0; i != count; ++i) + { + if (cppArgs[i] != 0) + { + uno_destructData(cppArgs[i], ptds[i], + reinterpret_cast(css::uno::cpp_release)); + TYPELIB_DANGER_RELEASE(ptds[i]); + } + } + TYPELIB_DANGER_RELEASE(aReturnTD); + return; + } + + *exception = 0; + for (sal_Int32 i = 0; i != count; ++i) + { + if (cppArgs[i] != 0) + { + if (parameters[i].bOut) + { + if (parameters[i].bIn) + { + uno_destructData(arguments[i], ptds[i], 0); + } + uno_copyAndConvertData(arguments[i], cppArgs[i], ptds[i], + pProxy->getBridge()->getCpp2Uno()); + } + uno_destructData(cppArgs[i], ptds[i], + reinterpret_cast(css::uno::cpp_release)); + TYPELIB_DANGER_RELEASE(ptds[i]); + } + } + + switch (eRetKind) + { + case RETURN_KIND_REG: + switch (aReturnTD->eTypeClass) + { + case typelib_TypeClass_VOID: + break; + case typelib_TypeClass_BOOLEAN: + case typelib_TypeClass_BYTE: + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + case typelib_TypeClass_CHAR: + case typelib_TypeClass_ENUM: + case typelib_TypeClass_STRUCT: + std::memcpy(ret, gpr, aReturnTD->nSize); + break; + case typelib_TypeClass_FLOAT: + case typelib_TypeClass_DOUBLE: + std::memcpy(ret, fpr, aReturnTD->nSize); + break; + default: + assert(false); + } + break; + case RETURN_KIND_HFA_FLOAT: + switch (aReturnTD->nSize) + { + case 16: + std::memcpy(static_cast(ret) + 12, fpr + 3, 4); + [[fallthrough]]; + case 12: + std::memcpy(static_cast(ret) + 8, fpr + 2, 4); + [[fallthrough]]; + case 8: + std::memcpy(static_cast(ret) + 4, fpr + 1, 4); + [[fallthrough]]; + case 4: + std::memcpy(ret, fpr, 4); + break; + default: + assert(false); + } + break; + case RETURN_KIND_HFA_DOUBLE: + std::memcpy(ret, fpr, aReturnTD->nSize); + break; + case RETURN_KIND_INDIRECT: + break; + } + + if (retConv) + { + uno_copyAndConvertData(returnValue, ret, aReturnTD, pProxy->getBridge()->getCpp2Uno()); + uno_destructData(ret, aReturnTD, reinterpret_cast(css::uno::cpp_release)); + } + TYPELIB_DANGER_RELEASE(aReturnTD); +} +} + +namespace bridges::cpp_uno::shared +{ +void unoInterfaceProxyDispatch(uno_Interface* pUnoI, typelib_TypeDescription const* pMemberDescr, + void* pReturn, void** pArgs, uno_Any** ppException) +{ + UnoInterfaceProxy* pProxy = static_cast(pUnoI); + switch (pMemberDescr->eTypeClass) + { + case typelib_TypeClass_INTERFACE_ATTRIBUTE: + { + typelib_InterfaceAttributeTypeDescription const* atd + = reinterpret_cast(pMemberDescr); + VtableSlot slot(getVtableSlot(atd)); + if (pReturn != 0) + { // getter + call(pProxy, slot, atd->pAttributeTypeRef, 0, 0, pReturn, pArgs, ppException); + } + else + { // setter + typelib_MethodParameter param = { 0, atd->pAttributeTypeRef, true, false }; + typelib_TypeDescriptionReference* pReturnTD = nullptr; + typelib_typedescriptionreference_new(&pReturnTD, typelib_TypeClass_VOID, + OUString("void").pData); + slot.index += 1; + call(pProxy, slot, pReturnTD, 1, ¶m, pReturn, pArgs, ppException); + typelib_typedescriptionreference_release(pReturnTD); + } + break; + } + case typelib_TypeClass_INTERFACE_METHOD: + { + typelib_InterfaceMethodTypeDescription const* mtd + = reinterpret_cast(pMemberDescr); + VtableSlot slot(getVtableSlot(mtd)); + switch (slot.index) + { + case 1: + pUnoI->acquire(pUnoI); + *ppException = 0; + break; + case 2: + pUnoI->release(pUnoI); + *ppException = 0; + break; + case 0: + { + typelib_TypeDescription* td = 0; + TYPELIB_DANGER_GET( + &td, (reinterpret_cast(pArgs[0])->getTypeLibType())); + if (td != 0) + { + uno_Interface* ifc = 0; + pProxy->pBridge->getUnoEnv()->getRegisteredInterface( + pProxy->pBridge->getUnoEnv(), reinterpret_cast(&ifc), + pProxy->oid.pData, + reinterpret_cast(td)); + if (ifc != 0) + { + uno_any_construct(reinterpret_cast(pReturn), &ifc, td, 0); + ifc->release(ifc); + TYPELIB_DANGER_RELEASE(td); + *ppException = 0; + break; + } + TYPELIB_DANGER_RELEASE(td); + } + } + [[fallthrough]]; + default: + call(pProxy, slot, mtd->pReturnTypeRef, mtd->nParams, mtd->pParams, pReturn, + pArgs, ppException); + break; + } + break; + } + default: + assert(false); + } +} +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ -- cgit v1.2.3