diff options
author | Stephan Bergmann <stephan.bergmann@allotropia.de> | 2024-05-08 14:44:41 +0200 |
---|---|---|
committer | Stephan Bergmann <stephan.bergmann@allotropia.de> | 2024-05-09 21:04:51 +0200 |
commit | 3956472eb249e54d5b96af59b33646ee3ceec897 (patch) | |
tree | 4fc326848acadc3450e647bb71c3da0f9a9fa2ac /bridges/source/cpp_uno | |
parent | 27e398b88066a4d1e236ce8b298f466754c41de0 (diff) |
Fix missing UNO<->C++ argument/return value conversions
Change-Id: I5ac6013d6c0bd72fe840a592628fd0d5b265b8ab
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167391
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
Diffstat (limited to 'bridges/source/cpp_uno')
-rw-r--r-- | bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx | 97 |
1 files changed, 73 insertions, 24 deletions
diff --git a/bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx index 788d8b2ba99a..537b8f89a872 100644 --- a/bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx +++ b/bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx @@ -11,12 +11,17 @@ #include <vector> +#include <alloca.h> + #include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/uno/genfunc.hxx> #include <o3tl/unreachable.hxx> #include <rtl/strbuf.hxx> #include <typelib/typeclass.h> #include <typelib/typedescription.h> #include <typelib/typedescription.hxx> +#include <uno/any2.h> +#include <uno/data.h> #include <bridge.hxx> #include <types.hxx> @@ -86,9 +91,12 @@ void call(bridges::cpp_uno::shared::UnoInterfaceProxy* proxy, sal_Int32 count, typelib_MethodParameter* parameters, void* returnValue, void** arguments, uno_Any** exception) { + css::uno::TypeDescription rtd(returnType); + auto const retConv = bridges::cpp_uno::shared::relatesToInterfaceType(rtd.get()); + auto const ret = retConv ? alloca(rtd.get()->nSize) : returnValue; OStringBuffer sig; std::vector<sal_uInt64> args; - switch (returnType->eTypeClass) + switch (rtd.get()->eTypeClass) { case typelib_TypeClass_VOID: sig.append('v'); @@ -119,12 +127,11 @@ void call(bridges::cpp_uno::shared::UnoInterfaceProxy* proxy, case typelib_TypeClass_SEQUENCE: case typelib_TypeClass_INTERFACE: sig.append("vi"); - args.push_back(reinterpret_cast<sal_uInt32>(returnValue)); + args.push_back(reinterpret_cast<sal_uInt32>(ret)); break; case typelib_TypeClass_STRUCT: { - css::uno::TypeDescription td(returnType); - switch (getKind(reinterpret_cast<typelib_CompoundTypeDescription const*>(td.get()))) + switch (getKind(reinterpret_cast<typelib_CompoundTypeDescription const*>(rtd.get()))) { case StructKind::Empty: break; @@ -142,7 +149,7 @@ void call(bridges::cpp_uno::shared::UnoInterfaceProxy* proxy, break; case StructKind::General: sig.append("vi"); - args.push_back(reinterpret_cast<sal_uInt32>(returnValue)); + args.push_back(reinterpret_cast<sal_uInt32>(ret)); break; } break; @@ -151,15 +158,14 @@ void call(bridges::cpp_uno::shared::UnoInterfaceProxy* proxy, O3TL_UNREACHABLE; } sig.append('i'); - args.push_back(reinterpret_cast<sal_uInt32>(proxy->getCppI())); + sal_uInt32 const* const* thisPtr + = reinterpret_cast<sal_uInt32 const* const*>(proxy->getCppI()) + slot.offset; + args.push_back(reinterpret_cast<sal_uInt32>(thisPtr)); + std::vector<void*> cppArgs(count); + std::vector<css::uno::TypeDescription> ptds(count); for (sal_Int32 i = 0; i != count; ++i) { - if (parameters[i].bOut) - { - sig.append('i'); - args.push_back(reinterpret_cast<sal_uInt32>(arguments[i])); - } - else + if (!parameters[i].bOut && bridges::cpp_uno::shared::isSimpleType(parameters[i].pTypeRef)) { switch (parameters[i].pTypeRef->eTypeClass) { @@ -208,25 +214,38 @@ void call(bridges::cpp_uno::shared::UnoInterfaceProxy* proxy, sig.append('i'); args.push_back(*reinterpret_cast<sal_Unicode const*>(arguments[i])); break; - case typelib_TypeClass_STRING: - case typelib_TypeClass_TYPE: - case typelib_TypeClass_ANY: - case typelib_TypeClass_SEQUENCE: - case typelib_TypeClass_STRUCT: - case typelib_TypeClass_INTERFACE: - sig.append('i'); - args.push_back(reinterpret_cast<sal_uInt32>(arguments[i])); - break; default: O3TL_UNREACHABLE; } } + else + { + sig.append('i'); + css::uno::TypeDescription ptd(parameters[i].pTypeRef); + if (!parameters[i].bIn) + { + cppArgs[i] = alloca(ptd.get()->nSize); + uno_constructData(cppArgs[i], ptd.get()); + ptds[i] = ptd; + args.push_back(reinterpret_cast<sal_uInt32>(cppArgs[i])); + } + else if (bridges::cpp_uno::shared::relatesToInterfaceType(ptd.get())) + { + cppArgs[i] = alloca(ptd.get()->nSize); + uno_copyAndConvertData(cppArgs[i], arguments[i], ptd.get(), + proxy->getBridge()->getUno2Cpp()); + ptds[i] = ptd; + args.push_back(reinterpret_cast<sal_uInt32>(cppArgs[i])); + } + else + { + args.push_back(reinterpret_cast<sal_uInt32>(arguments[i])); + } + } } try { - callVirtualFunction( - sig, (*reinterpret_cast<sal_uInt32 const* const*>(proxy->getCppI()))[slot.index], - args.data(), returnValue); + callVirtualFunction(sig, (*thisPtr)[slot.index], args.data(), ret); } catch (...) { @@ -234,9 +253,39 @@ void call(bridges::cpp_uno::shared::UnoInterfaceProxy* proxy, uno_type_any_construct(*exception, &TODO, cppu::UnoType<css::uno::RuntimeException>::get().getTypeLibType(), nullptr); + for (sal_Int32 i = 0; i != count; ++i) + { + if (cppArgs[i] != nullptr) + { + uno_destructData(cppArgs[i], ptds[i].get(), + reinterpret_cast<uno_ReleaseFunc>(css::uno::cpp_release)); + } + } return; } *exception = nullptr; + for (sal_Int32 i = 0; i != count; ++i) + { + if (cppArgs[i] != nullptr) + { + if (parameters[i].bOut) + { + if (parameters[i].bIn) + { + uno_destructData(arguments[i], ptds[i].get(), nullptr); + } + uno_copyAndConvertData(arguments[i], cppArgs[i], ptds[i].get(), + proxy->getBridge()->getCpp2Uno()); + } + uno_destructData(cppArgs[i], ptds[i].get(), + reinterpret_cast<uno_ReleaseFunc>(css::uno::cpp_release)); + } + } + if (retConv) + { + uno_copyAndConvertData(returnValue, ret, rtd.get(), proxy->getBridge()->getCpp2Uno()); + uno_destructData(ret, rtd.get(), reinterpret_cast<uno_ReleaseFunc>(css::uno::cpp_release)); + } } } |