bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx | 97 ++++++++++++++++++++------- unotest/source/embindtest/embindtest.js | 52 ++++++++++++++ 2 files changed, 125 insertions(+), 24 deletions(-)
New commits: commit 3956472eb249e54d5b96af59b33646ee3ceec897 Author: Stephan Bergmann <stephan.bergm...@allotropia.de> AuthorDate: Wed May 8 14:44:41 2024 +0200 Commit: Stephan Bergmann <stephan.bergm...@allotropia.de> CommitDate: Thu May 9 21:04:51 2024 +0200 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.bergm...@allotropia.de> Tested-by: Jenkins 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)); + } } } diff --git a/unotest/source/embindtest/embindtest.js b/unotest/source/embindtest/embindtest.js index 00d9ac68cd3c..f6cc71bbc906 100644 --- a/unotest/source/embindtest/embindtest.js +++ b/unotest/source/embindtest/embindtest.js @@ -1044,6 +1044,58 @@ Module.addOnPostRun(function() { outparamindex.delete(); outparam.delete(); } + { + const params = new Module.uno_Sequence_any(18, Module.uno_Sequence.FromSize); + const outparamindex = new Module.uno_InOutParam_sequence_short; + const outparam = new Module.uno_InOutParam_sequence_any; + const ret = invoke.invoke('getOut', params, outparamindex, outparam); + console.assert(ret.get() === undefined); + ret.delete(); + params.delete(); + console.assert(outparamindex.val.size() == 18); + outparamindex.val.delete(); + outparamindex.delete(); + console.assert(outparam.val.size() == 18); + console.assert(test.isBoolean(outparam.val.get(0).get())); + outparam.val.get(0).delete(); + console.assert(test.isByte(outparam.val.get(1).get())); + outparam.val.get(1).delete(); + console.assert(test.isShort(outparam.val.get(2).get())); + outparam.val.get(2).delete(); + console.assert(test.isUnsignedShort(outparam.val.get(3).get())); + outparam.val.get(3).delete(); + console.assert(test.isLong(outparam.val.get(4).get())); + outparam.val.get(4).delete(); + console.assert(test.isUnsignedLong(outparam.val.get(5).get())); + outparam.val.get(5).delete(); + console.assert(test.isHyper(outparam.val.get(6).get())); + outparam.val.get(6).delete(); + console.assert(test.isUnsignedHyper(outparam.val.get(7).get())); + outparam.val.get(7).delete(); + console.assert(test.isFloat(outparam.val.get(8).get())); + outparam.val.get(8).delete(); + console.assert(test.isDouble(outparam.val.get(9).get())); + outparam.val.get(9).delete(); + console.assert(test.isChar(outparam.val.get(10).get())); + outparam.val.get(10).delete(); + console.assert(test.isString(outparam.val.get(11).get())); + outparam.val.get(11).delete(); + console.assert(test.isType(outparam.val.get(12).get())); + outparam.val.get(12).delete(); + console.assert(test.isAnyLong(outparam.val.get(13))); + outparam.val.get(13).delete(); + console.assert(test.isSequenceString(outparam.val.get(14).get())); + outparam.val.get(14).get().delete(); + outparam.val.get(14).delete(); + console.assert(test.isEnum(outparam.val.get(15).get())); + outparam.val.get(15).delete(); + console.assert(test.isStruct(outparam.val.get(16).get())); + outparam.val.get(16).delete(); + console.assert(Module.sameUnoObject(outparam.val.get(17).get(), test)); + outparam.val.get(17).delete(); + outparam.val.delete(); + outparam.delete(); + } }); /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */