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: */

Reply via email to