summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Repository.mk2
-rw-r--r--bridges/CustomTarget_gcc3_wasm.mk26
-rw-r--r--bridges/Library_cpp_uno.mk6
-rw-r--r--bridges/Module_bridges.mk1
-rw-r--r--bridges/inc/wasm/callvirtualfunction.hxx21
-rw-r--r--bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx226
-rw-r--r--offapi/UnoApi_offapi.mk2
-rw-r--r--offapi/org/libreoffice/embindtest/StructLong.idl18
-rw-r--r--offapi/org/libreoffice/embindtest/StructString.idl18
-rw-r--r--offapi/org/libreoffice/embindtest/XTest.idl4
-rw-r--r--solenv/gbuild/extensions/pre_BuildTools.mk2
-rw-r--r--static/Executable_wasmcallgen.mk26
-rw-r--r--static/Module_static.mk1
-rw-r--r--static/source/wasmcallgen/wasmcallgen.cxx610
-rw-r--r--unotest/source/embindtest/embindtest.cxx23
-rw-r--r--unotest/source/embindtest/embindtest.js330
16 files changed, 1313 insertions, 3 deletions
diff --git a/Repository.mk b/Repository.mk
index e910b6d572b7..b6ebf64dcf39 100644
--- a/Repository.mk
+++ b/Repository.mk
@@ -33,7 +33,7 @@ $(eval $(call gb_Helper_register_executables,NONE, \
concat-deps \
cpp \
cppunittester \
- $(if $(or $(filter EMSCRIPTEN,$(BUILD_TYPE_FOR_HOST)),$(filter EMSCRIPTEN,$(OS))),embindmaker) \
+ $(if $(or $(filter EMSCRIPTEN,$(BUILD_TYPE_FOR_HOST)),$(filter EMSCRIPTEN,$(OS))),embindmaker wasmcallgen) \
gbuildtojson \
$(if $(filter MSC,$(COM)), \
gcc-wrapper \
diff --git a/bridges/CustomTarget_gcc3_wasm.mk b/bridges/CustomTarget_gcc3_wasm.mk
new file mode 100644
index 000000000000..a88da8577282
--- /dev/null
+++ b/bridges/CustomTarget_gcc3_wasm.mk
@@ -0,0 +1,26 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_CustomTarget_CustomTarget,bridges/gcc3_wasm))
+
+$(eval $(call gb_CustomTarget_register_targets,bridges/gcc3_wasm, \
+ callvirtualfunction-wrapper.cxx \
+ callvirtualfunction-impls.s \
+))
+
+$(gb_CustomTarget_workdir)/bridges/gcc3_wasm/callvirtualfunction-impls.s \
+$(gb_CustomTarget_workdir)/bridges/gcc3_wasm/callvirtualfunction-wrapper.cxx: \
+ $(call gb_Executable_get_target_for_build,wasmcallgen) $(call gb_UnoApi_get_target,udkapi) \
+ $(call gb_UnoApi_get_target,offapi)
+ $(call gb_Executable_get_command,wasmcallgen) \
+ $(gb_CustomTarget_workdir)/bridges/gcc3_wasm/callvirtualfunction-wrapper.cxx \
+ $(gb_CustomTarget_workdir)/bridges/gcc3_wasm/callvirtualfunction-impls.s \
+ +$(call gb_UnoApi_get_target,udkapi) +$(call gb_UnoApi_get_target,offapi)
+
+# vim: set noet sw=4 ts=4:
diff --git a/bridges/Library_cpp_uno.mk b/bridges/Library_cpp_uno.mk
index dcf83cf34e5b..c42778f359c1 100644
--- a/bridges/Library_cpp_uno.mk
+++ b/bridges/Library_cpp_uno.mk
@@ -84,6 +84,12 @@ bridge_noopt_objects := except
else ifeq ($(OS),EMSCRIPTEN)
bridges_SELECTED_BRIDGE := gcc3_wasm
bridge_noopt_objects := cpp2uno except uno2cpp
+$(eval $(call gb_Library_add_generated_asmobjects,$(CPPU_ENV)_uno, \
+ CustomTarget/bridges/gcc3_wasm/callvirtualfunction-impls \
+))
+$(eval $(call gb_Library_add_generated_exception_objects,$(CPPU_ENV)_uno, \
+ CustomTarget/bridges/gcc3_wasm/callvirtualfunction-wrapper \
+))
endif
else ifeq ($(CPUNAME),M68K)
diff --git a/bridges/Module_bridges.mk b/bridges/Module_bridges.mk
index 3016bf2c404f..def86fea4cb7 100644
--- a/bridges/Module_bridges.mk
+++ b/bridges/Module_bridges.mk
@@ -20,6 +20,7 @@ $(eval $(call gb_Module_add_targets,bridges,\
$(if $(filter ANDROID LINUX,$(OS)),\
CustomTarget_gcc3_linux_arm) \
) \
+ $(if $(filter EMSCRIPTEN,$(OS)),CustomTarget_gcc3_wasm) \
))
ifeq (,$(filter build,$(gb_Module_SKIPTARGETS)))
diff --git a/bridges/inc/wasm/callvirtualfunction.hxx b/bridges/inc/wasm/callvirtualfunction.hxx
new file mode 100644
index 000000000000..23b446cd45b3
--- /dev/null
+++ b/bridges/inc/wasm/callvirtualfunction.hxx
@@ -0,0 +1,21 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <sal/types.h>
+
+void callVirtualFunction(std::string_view signature, sal_uInt32 target, sal_uInt64 const* arguments,
+ void* returnValue);
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx
index ddb51166b51e..41a471bcc9b0 100644
--- a/bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx
@@ -7,15 +7,81 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+#include <sal/config.h>
+
+#include <vector>
+
#include <com/sun/star/uno/RuntimeException.hpp>
+#include <com/sun/star/uno/Type.hxx>
+#include <o3tl/unreachable.hxx>
+#include <rtl/strbuf.hxx>
+#include <typelib/typeclass.h>
+#include <typelib/typedescription.h>
#include <bridge.hxx>
#include <types.hxx>
#include <unointerfaceproxy.hxx>
#include <vtables.hxx>
+#include <wasm/callvirtualfunction.hxx>
+
using namespace ::com::sun::star::uno;
+namespace
+{
+enum class StructKind
+{
+ Empty,
+ I32,
+ I64,
+ F32,
+ F64,
+ General
+};
+
+StructKind getKind(typelib_CompoundTypeDescription const* type)
+{
+ if (type->nMembers > 1)
+ {
+ return StructKind::General;
+ }
+ auto k = StructKind::Empty;
+ if (type->pBaseTypeDescription != nullptr)
+ {
+ k = getKind(type->pBaseTypeDescription);
+ }
+ if (type->nMembers == 0)
+ {
+ return k;
+ }
+ if (k != StructKind::Empty)
+ {
+ return StructKind::General;
+ }
+ switch (type->ppTypeRefs[0]->eTypeClass)
+ {
+ 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_CHAR:
+ case typelib_TypeClass_ENUM:
+ return StructKind::I32;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ return StructKind::I64;
+ case typelib_TypeClass_FLOAT:
+ return StructKind::F32;
+ case typelib_TypeClass_DOUBLE:
+ return StructKind::F64;
+ default:
+ return StructKind::General;
+ }
+}
+}
+
namespace bridges::cpp_uno::shared
{
void unoInterfaceProxyDispatch(uno_Interface* pUnoI, const typelib_TypeDescription* pMemberDescr,
@@ -71,7 +137,165 @@ void unoInterfaceProxyDispatch(uno_Interface* pUnoI, const typelib_TypeDescripti
} // else perform queryInterface()
[[fallthrough]];
default:
- std::abort();
+ {
+ auto const mtd
+ = reinterpret_cast<typelib_InterfaceMethodTypeDescription const*>(
+ pMemberDescr);
+ OStringBuffer sig;
+ std::vector<sal_uInt64> args;
+ switch (mtd->pReturnTypeRef->eTypeClass)
+ {
+ case typelib_TypeClass_VOID:
+ sig.append('v');
+ 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_CHAR:
+ case typelib_TypeClass_ENUM:
+ sig.append('i');
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ sig.append('j');
+ break;
+ case typelib_TypeClass_FLOAT:
+ sig.append('f');
+ break;
+ case typelib_TypeClass_DOUBLE:
+ sig.append('d');
+ break;
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_TYPE:
+ case typelib_TypeClass_ANY:
+ case typelib_TypeClass_SEQUENCE:
+ case typelib_TypeClass_INTERFACE:
+ sig.append("vi");
+ args.push_back(reinterpret_cast<sal_uInt32>(pReturn));
+ break;
+ case typelib_TypeClass_STRUCT:
+ {
+ typelib_TypeDescription* td = nullptr;
+ css::uno::Type(mtd->pReturnTypeRef).getDescription(&td);
+ switch (getKind(
+ reinterpret_cast<typelib_CompoundTypeDescription const*>(td)))
+ {
+ case StructKind::Empty:
+ break;
+ case StructKind::I32:
+ sig.append('i');
+ break;
+ case StructKind::I64:
+ sig.append('j');
+ break;
+ case StructKind::F32:
+ sig.append('f');
+ break;
+ case StructKind::F64:
+ sig.append('d');
+ break;
+ case StructKind::General:
+ sig.append("vi");
+ args.push_back(reinterpret_cast<sal_uInt32>(pReturn));
+ break;
+ }
+ break;
+ }
+ default:
+ O3TL_UNREACHABLE;
+ }
+ sig.append('i');
+ args.push_back(reinterpret_cast<sal_uInt32>(pThis->pCppI));
+ for (sal_Int32 i = 0; i != mtd->nParams; ++i)
+ {
+ if (mtd->pParams[i].bOut)
+ {
+ sig.append('i');
+ args.push_back(reinterpret_cast<sal_uInt32>(pArgs[i]));
+ }
+ else
+ {
+ switch (mtd->pParams[i].pTypeRef->eTypeClass)
+ {
+ case typelib_TypeClass_BOOLEAN:
+ sig.append('i');
+ args.push_back(*reinterpret_cast<sal_Bool const*>(pArgs[i]));
+ break;
+ case typelib_TypeClass_BYTE:
+ sig.append('i');
+ args.push_back(*reinterpret_cast<sal_Int8 const*>(pArgs[i]));
+ break;
+ case typelib_TypeClass_SHORT:
+ sig.append('i');
+ args.push_back(*reinterpret_cast<sal_Int16 const*>(pArgs[i]));
+ break;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ sig.append('i');
+ args.push_back(*reinterpret_cast<sal_uInt16 const*>(pArgs[i]));
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_ENUM:
+ sig.append('i');
+ args.push_back(*reinterpret_cast<sal_Int32 const*>(pArgs[i]));
+ break;
+ case typelib_TypeClass_UNSIGNED_LONG:
+ sig.append('i');
+ args.push_back(*reinterpret_cast<sal_uInt32 const*>(pArgs[i]));
+ break;
+ case typelib_TypeClass_HYPER:
+ sig.append('j');
+ args.push_back(*reinterpret_cast<sal_Int64 const*>(pArgs[i]));
+ break;
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ sig.append('j');
+ args.push_back(*reinterpret_cast<sal_uInt64 const*>(pArgs[i]));
+ break;
+ case typelib_TypeClass_FLOAT:
+ sig.append('f');
+ args.push_back(*reinterpret_cast<sal_uInt32 const*>(pArgs[i]));
+ break;
+ case typelib_TypeClass_DOUBLE:
+ sig.append('d');
+ args.push_back(*reinterpret_cast<sal_uInt64 const*>(pArgs[i]));
+ break;
+ case typelib_TypeClass_CHAR:
+ sig.append('i');
+ args.push_back(*reinterpret_cast<sal_Unicode const*>(pArgs[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>(pArgs[i]));
+ break;
+ default:
+ O3TL_UNREACHABLE;
+ }
+ }
+ }
+ try
+ {
+ callVirtualFunction(sig,
+ (*reinterpret_cast<sal_uInt32 const* const*>(
+ pThis->pCppI))[aVtableSlot.index],
+ args.data(), pReturn);
+ *ppException = nullptr;
+ }
+ catch (...)
+ {
+ css::uno::RuntimeException TODO("Wasm bridge TODO");
+ uno_type_any_construct(
+ *ppException, &TODO,
+ cppu::UnoType<css::uno::RuntimeException>::get().getTypeLibType(),
+ nullptr);
+ }
+ }
}
break;
}
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index 8e93cd59389f..fe01fc172776 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -4444,6 +4444,8 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,org/libreoffice/embindtest, \
Enum \
Exception \
Struct \
+ StructLong \
+ StructString \
XTest \
))
$(eval $(call gb_UnoApi_add_idlfiles_nohdl,offapi,org/libreoffice/embindtest, \
diff --git a/offapi/org/libreoffice/embindtest/StructLong.idl b/offapi/org/libreoffice/embindtest/StructLong.idl
new file mode 100644
index 000000000000..22447486b3f3
--- /dev/null
+++ b/offapi/org/libreoffice/embindtest/StructLong.idl
@@ -0,0 +1,18 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+module org { module libreoffice { module embindtest {
+
+struct StructLong {
+ long m;
+};
+
+}; }; };
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/offapi/org/libreoffice/embindtest/StructString.idl b/offapi/org/libreoffice/embindtest/StructString.idl
new file mode 100644
index 000000000000..e0c1464cfc84
--- /dev/null
+++ b/offapi/org/libreoffice/embindtest/StructString.idl
@@ -0,0 +1,18 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+module org { module libreoffice { module embindtest {
+
+struct StructString {
+ string m;
+};
+
+}; }; };
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/offapi/org/libreoffice/embindtest/XTest.idl b/offapi/org/libreoffice/embindtest/XTest.idl
index b84753ebb8c6..ac8549d05397 100644
--- a/offapi/org/libreoffice/embindtest/XTest.idl
+++ b/offapi/org/libreoffice/embindtest/XTest.idl
@@ -40,6 +40,10 @@ interface XTest {
boolean isEnum([in] Enum value);
Struct getStruct();
boolean isStruct([in] Struct value);
+ StructLong getStructLong();
+ boolean isStructLong([in] StructLong value);
+ StructString getStructString();
+ boolean isStructString([in] StructString value);
any getAnyVoid();
boolean isAnyVoid([in] any value);
any getAnyBoolean();
diff --git a/solenv/gbuild/extensions/pre_BuildTools.mk b/solenv/gbuild/extensions/pre_BuildTools.mk
index 2522a4e7680c..63db68dc7b2a 100644
--- a/solenv/gbuild/extensions/pre_BuildTools.mk
+++ b/solenv/gbuild/extensions/pre_BuildTools.mk
@@ -16,7 +16,7 @@ gb_BUILD_TOOLS_executables = \
climaker \
cpp \
cppumaker \
- $(if $(filter EMSCRIPTEN,$(BUILD_TYPE_FOR_HOST)),embindmaker) \
+ $(if $(filter EMSCRIPTEN,$(BUILD_TYPE_FOR_HOST)),embindmaker wasmcallgen) \
gencoll_rule \
genconv_dict \
gendict \
diff --git a/static/Executable_wasmcallgen.mk b/static/Executable_wasmcallgen.mk
new file mode 100644
index 000000000000..77f5d9daf782
--- /dev/null
+++ b/static/Executable_wasmcallgen.mk
@@ -0,0 +1,26 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*-
+#
+# 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/.
+#
+
+$(eval $(call gb_Executable_Executable,wasmcallgen))
+
+$(eval $(call gb_Executable_add_exception_objects,wasmcallgen, \
+ static/source/wasmcallgen/wasmcallgen \
+))
+
+$(eval $(call gb_Executable_use_libraries,wasmcallgen, \
+ sal \
+ salhelper \
+ unoidl \
+))
+
+$(eval $(call gb_Executable_use_static_libraries,wasmcallgen, \
+ codemaker \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/static/Module_static.mk b/static/Module_static.mk
index ff036fac3213..7403da211d27 100644
--- a/static/Module_static.mk
+++ b/static/Module_static.mk
@@ -34,6 +34,7 @@ endif
ifneq ($(filter EMSCRIPTEN,$(BUILD_TYPE_FOR_HOST)),)
$(eval $(call gb_Module_add_targets,static, \
Executable_embindmaker \
+ Executable_wasmcallgen \
))
endif
diff --git a/static/source/wasmcallgen/wasmcallgen.cxx b/static/source/wasmcallgen/wasmcallgen.cxx
new file mode 100644
index 000000000000..0453bdb8aff8
--- /dev/null
+++ b/static/source/wasmcallgen/wasmcallgen.cxx
@@ -0,0 +1,610 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
+/*
+ * 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/.
+ */
+
+#include <sal/config.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstdlib>
+#include <fstream>
+#include <ios>
+#include <iostream>
+#include <set>
+#include <string>
+#include <string_view>
+#include <utility>
+
+#include <codemaker/global.hxx>
+#include <codemaker/typemanager.hxx>
+#include <codemaker/unotype.hxx>
+#include <o3tl/safeint.hxx>
+#include <osl/file.hxx>
+#include <osl/process.h>
+#include <osl/thread.h>
+#include <rtl/process.h>
+#include <rtl/ref.hxx>
+#include <rtl/strbuf.hxx>
+#include <rtl/string.hxx>
+#include <rtl/textcvt.h>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.hxx>
+#include <sal/main.h>
+#include <sal/types.h>
+#include <unoidl/unoidl.hxx>
+
+namespace
+{
+[[noreturn]] void badUsage()
+{
+ std::cerr
+ << "Usage:\n\n"
+ " wasmcallgen <cpp-output> <asm-output> <registries>\n\n"
+ "where each <registry> is '+' (primary) or ':' (secondary), followed by: either a\n"
+ "new- or legacy-format .rdb file, a single .idl file, or a root directory of an\n"
+ ".idl file tree. For all primary registries, Wasm UNO bridge callvirtualfunction\n"
+ "code is written to <cpp-output>/<asm-output>.\n";
+ std::exit(EXIT_FAILURE);
+}
+
+std::string getPathnameArgument(sal_uInt32 argument)
+{
+ OUString arg;
+ rtl_getAppCommandArg(argument, &arg.pData);
+ OString path;
+ auto const enc = osl_getThreadTextEncoding();
+ if (!arg.convertToString(&path, enc,
+ RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
+ | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
+ {
+ std::cerr << "Cannot convert \"" << arg << "\" to system encoding " << enc << "\n";
+ std::exit(EXIT_FAILURE);
+ }
+ return std::string(path);
+}
+
+std::pair<OUString, bool> parseRegistryArgument(sal_uInt32 argument)
+{
+ OUString arg;
+ rtl_getAppCommandArg(argument, &arg.pData);
+ bool primary;
+ if (arg.startsWith(u"+", &arg))
+ {
+ primary = true;
+ }
+ else if (arg.startsWith(u":", &arg))
+ {
+ primary = false;
+ }
+ else
+ {
+ std::cerr << "Bad registry argument \"" << arg << "\"\n";
+ std::exit(EXIT_FAILURE);
+ }
+ OUString url;
+ auto const e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
+ if (e1 != osl::FileBase::E_None)
+ {
+ std::cerr << "Cannot convert \"" << arg << "\" to file URL, error code " << +e1 << "\n";
+ std::exit(EXIT_FAILURE);
+ }
+ OUString cwd;
+ auto const e2 = osl_getProcessWorkingDir(&cwd.pData);
+ if (e2 != osl_Process_E_None)
+ {
+ std::cerr << "Cannot obtain working directory, error code " << +e2 << "\n";
+ std::exit(EXIT_FAILURE);
+ }
+ OUString abs;
+ auto const e3 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs);
+ if (e3 != osl::FileBase::E_None)
+ {
+ std::cerr << "Cannot make \"" << url << "\" into an absolute file URL, error code " << +e3
+ << "\n";
+ std::exit(EXIT_FAILURE);
+ }
+ return { abs, primary };
+}
+
+OUString resolveAllTypedefs(rtl::Reference<TypeManager> const& manager, std::u16string_view name)
+{
+ sal_Int32 k1;
+ OUString n(b2u(codemaker::UnoType::decompose(u2b(name), &k1)));
+ for (;;)
+ {
+ rtl::Reference<unoidl::Entity> ent;
+ if (manager->getSort(n, &ent) != codemaker::UnoType::Sort::Typedef)
+ {
+ break;
+ }
+ sal_Int32 k2;
+ n = b2u(codemaker::UnoType::decompose(
+ u2b(static_cast<unoidl::TypedefEntity*>(ent.get())->getType()), &k2));
+ k1 += k2; //TODO: overflow
+ }
+ OUStringBuffer b;
+ for (sal_Int32 i = 0; i != k1; ++i)
+ {
+ b.append("[]");
+ }
+ b.append(n);
+ return b.makeStringAndClear();
+}
+
+enum class StructKind
+{
+ Empty,
+ I32,
+ I64,
+ F32,
+ F64,
+ General
+};
+
+StructKind getKind(rtl::Reference<TypeManager> const& manager, std::u16string_view type)
+{
+ std::vector<OUString> args;
+ rtl::Reference<unoidl::Entity> ent;
+ OUString singleMemberType;
+ switch (manager->decompose(type, true, nullptr, nullptr, &args, &ent))
+ {
+ case codemaker::UnoType::Sort::PlainStruct:
+ {
+ auto const strct = static_cast<unoidl::PlainStructTypeEntity const*>(ent.get());
+ if (strct->getDirectMembers().size() > 1)
+ {
+ return StructKind::General;
+ }
+ auto k = StructKind::Empty;
+ if (!strct->getDirectBase().isEmpty())
+ {
+ k = getKind(manager, strct->getDirectBase());
+ }
+ if (strct->getDirectMembers().empty())
+ {
+ return k;
+ }
+ if (k != StructKind::Empty)
+ {
+ return StructKind::General;
+ }
+ singleMemberType = strct->getDirectMembers()[0].type;
+ break;
+ }
+ case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
+ {
+ auto const strct
+ = static_cast<unoidl::PolymorphicStructTypeTemplateEntity const*>(ent.get());
+ switch (strct->getMembers().size())
+ {
+ case 0:
+ return StructKind::Empty;
+ case 1:
+ if (strct->getMembers()[0].parameterized)
+ {
+ auto const i = std::find(strct->getTypeParameters().begin(),
+ strct->getTypeParameters().end(),
+ strct->getMembers()[0].type);
+ if (i == strct->getTypeParameters().end())
+ {
+ throw CannotDumpException("bad type parameter \""
+ + strct->getMembers()[0].type
+ + "\" in call to getKind");
+ }
+ auto const n = i - strct->getTypeParameters().begin();
+ if (o3tl::make_unsigned(n) > args.size())
+ {
+ throw CannotDumpException("bad type parameter \""
+ + strct->getMembers()[0].type
+ + "\" in call to getKind");
+ }
+ singleMemberType = args[n];
+ }
+ else
+ {
+ singleMemberType = strct->getMembers()[0].type;
+ }
+ break;
+ default:
+ return StructKind::General;
+ }
+ break;
+ }
+ default:
+ throw CannotDumpException(OUString::Concat("unexpected entity \"") + type
+ + "\" in call to getKind");
+ }
+ switch (manager->getSort(resolveAllTypedefs(manager, singleMemberType)))
+ {
+ case codemaker::UnoType::Sort::Boolean:
+ case codemaker::UnoType::Sort::Byte:
+ case codemaker::UnoType::Sort::Short:
+ case codemaker::UnoType::Sort::UnsignedShort:
+ case codemaker::UnoType::Sort::Long:
+ case codemaker::UnoType::Sort::UnsignedLong:
+ case codemaker::UnoType::Sort::Char:
+ case codemaker::UnoType::Sort::Enum:
+ return StructKind::I32;
+ case codemaker::UnoType::Sort::Hyper:
+ case codemaker::UnoType::Sort::UnsignedHyper:
+ return StructKind::I64;
+ case codemaker::UnoType::Sort::Float:
+ return StructKind::F32;
+ case codemaker::UnoType::Sort::Double:
+ return StructKind::F64;
+ default:
+ return StructKind::General;
+ }
+}
+
+OString computeSignature(rtl::Reference<TypeManager> const& manager,
+ unoidl::InterfaceTypeEntity::Method const& method)
+{
+ OStringBuffer buf;
+ switch (manager->getSort(resolveAllTypedefs(manager, method.returnType)))
+ {
+ case codemaker::UnoType::Sort::Void:
+ buf.append('v');
+ break;
+ case codemaker::UnoType::Sort::Boolean:
+ case codemaker::UnoType::Sort::Byte:
+ case codemaker::UnoType::Sort::Short:
+ case codemaker::UnoType::Sort::UnsignedShort:
+ case codemaker::UnoType::Sort::Long:
+ case codemaker::UnoType::Sort::UnsignedLong:
+ case codemaker::UnoType::Sort::Char:
+ case codemaker::UnoType::Sort::Enum:
+ buf.append('i');
+ break;
+ case codemaker::UnoType::Sort::Hyper:
+ case codemaker::UnoType::Sort::UnsignedHyper:
+ buf.append('j');
+ break;
+ case codemaker::UnoType::Sort::Float:
+ buf.append('f');
+ break;
+ case codemaker::UnoType::Sort::Double:
+ buf.append('d');
+ break;
+ case codemaker::UnoType::Sort::String:
+ case codemaker::UnoType::Sort::Type:
+ case codemaker::UnoType::Sort::Any:
+ case codemaker::UnoType::Sort::Sequence:
+ case codemaker::UnoType::Sort::Interface:
+ buf.append("vi");
+ break;
+ case codemaker::UnoType::Sort::PlainStruct:
+ case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
+ {
+ switch (getKind(manager, method.returnType))
+ {
+ case StructKind::Empty:
+ break;
+ case StructKind::I32:
+ buf.append('i');
+ break;
+ case StructKind::I64:
+ buf.append('j');
+ break;
+ case StructKind::F32:
+ buf.append('f');
+ break;
+ case StructKind::F64:
+ buf.append('d');
+ break;
+ case StructKind::General:
+ buf.append("vi");
+ break;
+ }
+ break;
+ }
+ default:
+ throw CannotDumpException("unexpected entity \"" + method.returnType
+ + "\" in call to computeSignature");
+ }
+ buf.append('i');
+ for (auto const& param : method.parameters)
+ {
+ if (param.direction == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN)
+ {
+ switch (manager->getSort(resolveAllTypedefs(manager, param.type)))
+ {
+ case codemaker::UnoType::Sort::Boolean:
+ case codemaker::UnoType::Sort::Byte:
+ case codemaker::UnoType::Sort::Short:
+ case codemaker::UnoType::Sort::UnsignedShort:
+ case codemaker::UnoType::Sort::Long:
+ case codemaker::UnoType::Sort::UnsignedLong:
+ case codemaker::UnoType::Sort::Char:
+ case codemaker::UnoType::Sort::Enum:
+ case codemaker::UnoType::Sort::String:
+ case codemaker::UnoType::Sort::Type:
+ case codemaker::UnoType::Sort::Any:
+ case codemaker::UnoType::Sort::Sequence:
+ case codemaker::UnoType::Sort::PlainStruct:
+ case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
+ case codemaker::UnoType::Sort::Interface:
+ buf.append('i');
+ break;
+ case codemaker::UnoType::Sort::Hyper:
+ case codemaker::UnoType::Sort::UnsignedHyper:
+ buf.append('j');
+ break;
+ case codemaker::UnoType::Sort::Float:
+ buf.append('f');
+ break;
+ case codemaker::UnoType::Sort::Double:
+ buf.append('d');
+ break;
+ default:
+ throw CannotDumpException("unexpected entity \"" + param.type
+ + "\" in call to computeSignature");
+ }
+ }
+ else
+ {
+ buf.append('i');
+ }
+ }
+ return buf.makeStringAndClear();
+}
+
+void scan(rtl::Reference<TypeManager> const& manager,
+ rtl::Reference<unoidl::MapCursor> const& cursor, std::set<OString>& signatures)
+{
+ assert(cursor.is());
+ for (;;)
+ {
+ OUString id;
+ auto const ent = cursor->getNext(&id);
+ if (!ent.is())
+ {
+ break;
+ }
+ switch (ent->getSort())
+ {
+ case unoidl::Entity::SORT_MODULE:
+ scan(manager, static_cast<unoidl::ModuleEntity*>(ent.get())->createCursor(),
+ signatures);
+ break;
+ case unoidl::Entity::SORT_INTERFACE_TYPE:
+ for (auto const& meth :
+ static_cast<unoidl::InterfaceTypeEntity const*>(ent.get())->getDirectMethods())
+ {
+ signatures.insert(computeSignature(manager, meth));
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+}
+
+SAL_IMPLEMENT_MAIN()
+{
+ try
+ {
+ auto const args = rtl_getAppCommandArgCount();
+ if (args < 2)
+ {
+ badUsage();
+ }
+ auto const cppPathname = getPathnameArgument(0);
+ auto const asmPathname = getPathnameArgument(1);
+ rtl::Reference<TypeManager> mgr(new TypeManager);
+ for (sal_uInt32 i = 2; i != args; ++i)
+ {
+ auto const & [ uri, primary ] = parseRegistryArgument(i);
+ try
+ {
+ mgr->loadProvider(uri, primary);
+ }
+ catch (unoidl::NoSuchFileException&)
+ {
+ std::cerr << "Input <" << uri << "> does not exist\n";
+ std::exit(EXIT_FAILURE);
+ }
+ }
+ std::set<OString> signatures;
+ for (auto const& prov : mgr->getPrimaryProviders())
+ {
+ scan(mgr, prov->createRootCursor(), signatures);
+ }
+ std::ofstream cppOut(cppPathname, std::ios_base::out | std::ios_base::trunc);
+ if (!cppOut)
+ {
+ std::cerr << "Cannot open \"" << cppPathname << "\" for writing\n";
+ std::exit(EXIT_FAILURE);
+ }
+ cppOut << "#include <sal/config.h>\n"
+ "#include <string_view>\n"
+ "#include <com/sun/star/uno/RuntimeException.hpp>\n"
+ "#include <rtl/ustring.hxx>\n"
+ "#include <wasm/callvirtualfunction.hxx>\n";
+ for (auto const& sig : signatures)
+ {
+ cppOut << "extern \"C\" void callVirtualFunction_" << sig
+ << "(sal_uInt32 target, sal_uInt64 const * arguments, void * returnValue);\n";
+ }
+ cppOut << "void callVirtualFunction(std::string_view signature, sal_uInt32 target, "
+ "sal_uInt64 const * arguments, void * returnValue) {\n";
+ for (auto const& sig : signatures)
+ {
+ cppOut << " if (signature == \"" << sig << "\") {\n"
+ << " callVirtualFunction_" << sig << "(target, arguments, returnValue);\n"
+ << " return;\n"
+ << " }\n";
+ }
+ cppOut << " throw css::uno::RuntimeException(\"Wasm bridge cannot call virtual function "
+ "with signature \" + OUString::fromUtf8(signature));\n"
+ "}\n";
+ cppOut.close();
+ if (!cppOut)
+ {
+ std::cerr << "Failed to write \"" << cppPathname << "\"\n";
+ std::exit(EXIT_FAILURE);
+ }
+ std::ofstream asmOut(asmPathname, std::ios_base::out | std::ios_base::trunc);
+ if (!asmOut)
+ {
+ std::cerr << "Cannot open \"" << asmPathname << "\" for writing\n";
+ std::exit(EXIT_FAILURE);
+ }
+ asmOut << "\t.text\n"
+ "\t.tabletype __indirect_function_table, funcref\n";
+ for (auto const& sig : signatures)
+ {
+ asmOut << "\t.functype callVirtualFunction_" << sig << " (i32, i32, i32) -> ()\n";
+ }
+ for (auto const& sig : signatures)
+ {
+ asmOut << "\t.section .text.callVirtualFunction_" << sig
+ << ",\"\",@\n"
+ "\t.globl callVirtualFunction_"
+ << sig
+ << "\n"
+ "\t.type callVirtualFunction_"
+ << sig
+ << ",@function\n"
+ "callVirtualFunction_"
+ << sig
+ << ":\n"
+ "\t.functype callVirtualFunction_"
+ << sig << " (i32, i32, i32) -> ()\n";
+ if (sig[0] != 'v')
+ {
+ asmOut << "\tlocal.get 2\n";
+ }
+ unsigned off = 0;
+ for (auto c : sig.subView(1))
+ {
+ asmOut << "\tlocal.get 1\n"
+ "\t";
+ switch (c)
+ {
+ case 'd':
+ asmOut << "f64";
+ break;
+ case 'f':
+ asmOut << "f32";
+ break;
+ case 'i':
+ asmOut << "i32";
+ break;
+ case 'j':
+ asmOut << "i64";
+ break;
+ default:
+ assert(false);
+ }
+ asmOut << ".load " << off << "\n";
+ off += 8; //TODO: overflow
+ }
+ asmOut << "\tlocal.get 0\n"
+ "\tcall_indirect (";
+ auto first = true;
+ for (auto c : sig.subView(1))
+ {
+ if (first)
+ {
+ first = false;
+ }
+ else
+ {
+ asmOut << ", ";
+ }
+ switch (c)
+ {
+ case 'd':
+ asmOut << "f64";
+ break;
+ case 'f':
+ asmOut << "f32";
+ break;
+ case 'i':
+ asmOut << "i32";
+ break;
+ case 'j':
+ asmOut << "i64";
+ break;
+ default:
+ assert(false);
+ }
+ }
+ asmOut << ") -> (";
+ switch (sig[0])
+ {
+ case 'd':
+ asmOut << "f64";
+ break;
+ case 'f':
+ asmOut << "f32";
+ break;
+ case 'i':
+ asmOut << "i32";
+ break;
+ case 'j':
+ asmOut << "i64";
+ break;
+ case 'v':
+ break;
+ default:
+ assert(false);
+ }
+ asmOut << ")\n";
+ if (sig[0] != 'v')
+ {
+ asmOut << "\t";
+ switch (sig[0])
+ {
+ case 'd':
+ asmOut << "f64";
+ break;
+ case 'f':
+ asmOut << "f32";
+ break;
+ case 'i':
+ asmOut << "i32";
+ break;
+ case 'j':
+ asmOut << "i64";
+ break;
+ default:
+ assert(false);
+ }
+ asmOut << ".store 0\n";
+ }
+ asmOut << "\tend_function\n";
+ }
+ asmOut.close();
+ if (!asmOut)
+ {
+ std::cerr << "Failed to write \"" << asmPathname << "\"\n";
+ std::exit(EXIT_FAILURE);
+ }
+ return EXIT_SUCCESS;
+ }
+ catch (unoidl::FileFormatException const& e)
+ {
+ std::cerr << "Bad input <" << e.getUri() << ">: " << e.getDetail() << "\n";
+ std::exit(EXIT_FAILURE);
+ }
+ catch (CannotDumpException const& e)
+ {
+ std::cerr << "Failure: " << e.getMessage() << "\n";
+ std::exit(EXIT_FAILURE);
+ }
+ catch (std::exception const& e)
+ {
+ std::cerr << "Failure: " << e.what() << "\n";
+ std::exit(EXIT_FAILURE);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/unotest/source/embindtest/embindtest.cxx b/unotest/source/embindtest/embindtest.cxx
index c5fcea1dc42e..7b65ed3ed776 100644
--- a/unotest/source/embindtest/embindtest.cxx
+++ b/unotest/source/embindtest/embindtest.cxx
@@ -24,6 +24,8 @@
#include <org/libreoffice/embindtest/Enum.hpp>
#include <org/libreoffice/embindtest/Exception.hpp>
#include <org/libreoffice/embindtest/Struct.hpp>
+#include <org/libreoffice/embindtest/StructLong.hpp>
+#include <org/libreoffice/embindtest/StructString.hpp>
#include <org/libreoffice/embindtest/XTest.hpp>
#include <rtl/ustring.hxx>
#include <sal/types.h>
@@ -112,6 +114,27 @@ class Test : public cppu::WeakImplHelper<org::libreoffice::embindtest::XTest>
return value == org::libreoffice::embindtest::Struct{ -123456, 100.5, u"hä"_ustr };
}
+ org::libreoffice::embindtest::StructLong SAL_CALL getStructLong() override
+ {
+ return { -123456 };
+ }
+
+ sal_Bool SAL_CALL isStructLong(org::libreoffice::embindtest::StructLong const& value) override
+ {
+ return value.m == -123456;
+ }
+
+ org::libreoffice::embindtest::StructString SAL_CALL getStructString() override
+ {
+ return { u"hä"_ustr };
+ }
+
+ sal_Bool SAL_CALL
+ isStructString(org::libreoffice::embindtest::StructString const& value) override
+ {
+ return value.m == u"hä";
+ }
+
css::uno::Any SAL_CALL getAnyVoid() override { return {}; }
sal_Bool SAL_CALL isAnyVoid(css::uno::Any const& value) override
diff --git a/unotest/source/embindtest/embindtest.js b/unotest/source/embindtest/embindtest.js
index 16efe9acf169..3944f399e3b1 100644
--- a/unotest/source/embindtest/embindtest.js
+++ b/unotest/source/embindtest/embindtest.js
@@ -697,6 +697,336 @@ Module.addOnPostRun(function() {
test.passJobExecutor(css.task.XJobExecutor.reference(obj.implXJobExecutor));
test.passInterface(css.uno.XInterface.reference(obj.implXTypeProvider));
obj.release();
+
+ const args = new Module.uno_Sequence_any(
+ [new Module.uno_Any(Module.uno_Type.Interface('com.sun.star.uno.XInterface'), test)]);
+ const invoke = css.script.XInvocation2.query(css.script.Invocation.create(
+ Module.getUnoComponentContext()).createInstanceWithArguments(args));
+ args.get(0).delete();
+ args.delete();
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getBoolean', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isBoolean', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getByte', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isByte', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getShort', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isShort', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getUnsignedShort', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isUnsignedShort', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getLong', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isLong', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getUnsignedLong', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isUnsignedLong', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getHyper', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isHyper', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getUnsignedHyper', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isUnsignedHyper', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getFloat', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isFloat', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getDouble', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isDouble', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getChar', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isChar', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getString', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isString', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getType', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isType', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getEnum', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isEnum', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getStruct', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isStruct', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getStructLong', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isStructLong', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getStructString', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isStructString', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getAnyLong', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isAnyLong', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
+ {
+ const params1 = new Module.uno_Sequence_any(0, Module.uno_Sequence.FromSize);
+ const outparamindex = new Module.uno_InOutParam_sequence_short;
+ const outparam = new Module.uno_InOutParam_sequence_any;
+ const ret1 = invoke.invoke('getSequenceLong', params1, outparamindex, outparam);
+ console.log(ret1.get());
+ const params2 = new Module.uno_Sequence_any([ret1]);
+ const ret2 = invoke.invoke('isSequenceLong', params2, outparamindex, outparam);
+ console.log(ret2.get());
+ console.assert(ret2.get());
+ ret1.delete();
+ params1.delete();
+ ret2.delete();
+ params2.delete();
+ outparamindex.delete();
+ outparam.delete();
+ }
});
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */