Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
/* -*- 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>
|
Properly implement cppu::throwException for Emscripten
...by implementing (for now) just enough of the cpp2uno half of the Wasm UNO
bridge to make it work. In general, that half suffers from the same issue as
the already-implemented uno2cpp half, namely that Wasm doesn't allow to generate
code on the fly (which, in this case, would be needed to implement the vtable
slot trampoline functions). So, for now just hard-code the few
vtableSlotFunction_* that are needed by the UNO interfaces for
cppuhelper/source/exc_thrower.cxx. (A proper fix would probably use the same
approach as for the uno2cpp half, and use something like wasmcallgen to generate
at least all the vtableSlotFunction_* needed for udkapi/offapi upfront.)
The RTTI for the exceptions needs to be unique across the executable for
exception catching to actually work (as it compares exception types by RTTI
address rather than by name). We thus need to export all the relevant RTTI
symbols (which I hacked into the existing wasmcallgen for now, even if that
makes that executable's name a slight misnomer now), and access them with a new
jsGetExportedSymbol. (This exporting would also be needed by the "classical"
approach of using dlsym on the main module, cf.
<https://gerrit.libreoffice.org/c/core/+/167187> "WIP: Emscripten: Set up
support for dlsym from main module". And while that dlsym approach would work,
it is much simpler to just use that jsGetExportedSymbol than to use a dlsym
detour, and thereby avoid all the hassle of -sMAIN_MODULE detailed in the commit
message of that Gerrit change.)
It also turned out that including Emscripten's <cxxabi.h> needs
__USING_WASM_EXCEPTIONS__ to be defined, because it uses that in its declaration
of __cxa_throw. (The source for setting that define internally in Emscripten is
get_cflags in the emsdk's upstream/emscripten/tools/system_libs.py, which
defines __USING_EMSCRIPTEN_EXCEPTIONS__ for the non-Wasm, Emscripten JS
exception mode, and defines __USING_WASM_EXCEPTIONS__ for
--enable-wasm-exceptions, which we use. The commit message of
f4ec967599f5dafa1ce477631d7c2e8de005e28f "Fix redefinion of Emscripten
__cxxabiv1::__cxa_exception" documents my prior confusion of when one or the
other would be defined.)
Change-Id: Id08765ab5b4ce1553dc3a61648324526185cb64c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170246
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-07-09 17:28:46 +02:00
|
|
|
#include <vector>
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
|
|
|
|
#include <codemaker/global.hxx>
|
|
|
|
#include <codemaker/typemanager.hxx>
|
|
|
|
#include <codemaker/unotype.hxx>
|
|
|
|
#include <o3tl/safeint.hxx>
|
2024-07-11 12:53:01 +02:00
|
|
|
#include <o3tl/temporary.hxx>
|
|
|
|
#include <o3tl/unreachable.hxx>
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
#include <osl/file.hxx>
|
|
|
|
#include <osl/process.h>
|
|
|
|
#include <osl/thread.h>
|
2024-07-11 12:53:01 +02:00
|
|
|
#include <rtl/character.hxx>
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
#include <rtl/process.h>
|
|
|
|
#include <rtl/ref.hxx>
|
|
|
|
#include <rtl/strbuf.hxx>
|
|
|
|
#include <rtl/string.hxx>
|
|
|
|
#include <rtl/textcvt.h>
|
Properly implement cppu::throwException for Emscripten
...by implementing (for now) just enough of the cpp2uno half of the Wasm UNO
bridge to make it work. In general, that half suffers from the same issue as
the already-implemented uno2cpp half, namely that Wasm doesn't allow to generate
code on the fly (which, in this case, would be needed to implement the vtable
slot trampoline functions). So, for now just hard-code the few
vtableSlotFunction_* that are needed by the UNO interfaces for
cppuhelper/source/exc_thrower.cxx. (A proper fix would probably use the same
approach as for the uno2cpp half, and use something like wasmcallgen to generate
at least all the vtableSlotFunction_* needed for udkapi/offapi upfront.)
The RTTI for the exceptions needs to be unique across the executable for
exception catching to actually work (as it compares exception types by RTTI
address rather than by name). We thus need to export all the relevant RTTI
symbols (which I hacked into the existing wasmcallgen for now, even if that
makes that executable's name a slight misnomer now), and access them with a new
jsGetExportedSymbol. (This exporting would also be needed by the "classical"
approach of using dlsym on the main module, cf.
<https://gerrit.libreoffice.org/c/core/+/167187> "WIP: Emscripten: Set up
support for dlsym from main module". And while that dlsym approach would work,
it is much simpler to just use that jsGetExportedSymbol than to use a dlsym
detour, and thereby avoid all the hassle of -sMAIN_MODULE detailed in the commit
message of that Gerrit change.)
It also turned out that including Emscripten's <cxxabi.h> needs
__USING_WASM_EXCEPTIONS__ to be defined, because it uses that in its declaration
of __cxa_throw. (The source for setting that define internally in Emscripten is
get_cflags in the emsdk's upstream/emscripten/tools/system_libs.py, which
defines __USING_EMSCRIPTEN_EXCEPTIONS__ for the non-Wasm, Emscripten JS
exception mode, and defines __USING_WASM_EXCEPTIONS__ for
--enable-wasm-exceptions, which we use. The commit message of
f4ec967599f5dafa1ce477631d7c2e8de005e28f "Fix redefinion of Emscripten
__cxxabiv1::__cxa_exception" documents my prior confusion of when one or the
other would be defined.)
Change-Id: Id08765ab5b4ce1553dc3a61648324526185cb64c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170246
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-07-09 17:28:46 +02:00
|
|
|
#include <rtl/textenc.h>
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
#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"
|
2024-07-11 16:41:38 +02:00
|
|
|
" wasmbridgegen <cpp-output> <asm-output> <exp-output> <registries>\n\n"
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
"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"
|
2024-07-11 12:53:01 +02:00
|
|
|
".idl file tree. For all primary registries, Wasm UNO bridge code is written to\n"
|
|
|
|
"<cpp-output>/<asm-output>, and to-be-exported exception RTTI symbols are written\n"
|
|
|
|
"to <exp-output>.\n";
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-11 12:53:01 +02:00
|
|
|
void appendCallSignatureReturnType(OStringBuffer& buffer,
|
|
|
|
rtl::Reference<TypeManager> const& manager, OUString const& type)
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
{
|
2024-07-11 12:53:01 +02:00
|
|
|
switch (manager->getSort(resolveAllTypedefs(manager, type)))
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
{
|
|
|
|
case codemaker::UnoType::Sort::Void:
|
2024-07-11 12:53:01 +02:00
|
|
|
buffer.append('v');
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
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:
|
2024-07-11 12:53:01 +02:00
|
|
|
buffer.append('i');
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
|
|
|
case codemaker::UnoType::Sort::Hyper:
|
|
|
|
case codemaker::UnoType::Sort::UnsignedHyper:
|
2024-07-11 12:53:01 +02:00
|
|
|
buffer.append('j');
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
|
|
|
case codemaker::UnoType::Sort::Float:
|
2024-07-11 12:53:01 +02:00
|
|
|
buffer.append('f');
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
|
|
|
case codemaker::UnoType::Sort::Double:
|
2024-07-11 12:53:01 +02:00
|
|
|
buffer.append('d');
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
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:
|
2024-07-11 12:53:01 +02:00
|
|
|
buffer.append("vi");
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
|
|
|
case codemaker::UnoType::Sort::PlainStruct:
|
|
|
|
case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
|
|
|
|
{
|
2024-07-11 12:53:01 +02:00
|
|
|
switch (getKind(manager, type))
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
{
|
|
|
|
case StructKind::Empty:
|
|
|
|
break;
|
|
|
|
case StructKind::I32:
|
2024-07-11 12:53:01 +02:00
|
|
|
buffer.append('i');
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
|
|
|
case StructKind::I64:
|
2024-07-11 12:53:01 +02:00
|
|
|
buffer.append('j');
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
|
|
|
case StructKind::F32:
|
2024-07-11 12:53:01 +02:00
|
|
|
buffer.append('f');
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
|
|
|
case StructKind::F64:
|
2024-07-11 12:53:01 +02:00
|
|
|
buffer.append('d');
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
|
|
|
case StructKind::General:
|
2024-07-11 12:53:01 +02:00
|
|
|
buffer.append("vi");
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
2024-07-11 12:53:01 +02:00
|
|
|
throw CannotDumpException("unexpected entity \"" + type
|
|
|
|
+ "\" in call to appendCallSignatureReturnType");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendCallSignatureParameter(
|
|
|
|
OStringBuffer& buffer, rtl::Reference<TypeManager> const& manager,
|
|
|
|
unoidl::InterfaceTypeEntity::Method::Parameter::Direction direction, OUString const& type)
|
|
|
|
{
|
|
|
|
if (direction == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN)
|
|
|
|
{
|
|
|
|
switch (manager->getSort(resolveAllTypedefs(manager, 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:
|
|
|
|
buffer.append('i');
|
|
|
|
break;
|
|
|
|
case codemaker::UnoType::Sort::Hyper:
|
|
|
|
case codemaker::UnoType::Sort::UnsignedHyper:
|
|
|
|
buffer.append('j');
|
|
|
|
break;
|
|
|
|
case codemaker::UnoType::Sort::Float:
|
|
|
|
buffer.append('f');
|
|
|
|
break;
|
|
|
|
case codemaker::UnoType::Sort::Double:
|
|
|
|
buffer.append('d');
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw CannotDumpException("unexpected entity \"" + type
|
|
|
|
+ "\" in call to appendCallSignatureParameter");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
buffer.append('i');
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
}
|
2024-07-11 12:53:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
OString computeGetterCallSignature(rtl::Reference<TypeManager> const& manager,
|
|
|
|
unoidl::InterfaceTypeEntity::Attribute const& attribute)
|
|
|
|
{
|
|
|
|
OStringBuffer buf;
|
|
|
|
appendCallSignatureReturnType(buf, manager, attribute.type);
|
|
|
|
buf.append('i');
|
|
|
|
return buf.makeStringAndClear();
|
|
|
|
}
|
|
|
|
|
|
|
|
OString computeSetterCallSignature(rtl::Reference<TypeManager> const& manager,
|
|
|
|
unoidl::InterfaceTypeEntity::Attribute const& attribute)
|
|
|
|
{
|
|
|
|
OStringBuffer buf("vi");
|
|
|
|
appendCallSignatureParameter(
|
|
|
|
buf, manager, unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN, attribute.type);
|
|
|
|
return buf.makeStringAndClear();
|
|
|
|
}
|
|
|
|
|
|
|
|
OString computeMethodCallSignature(rtl::Reference<TypeManager> const& manager,
|
|
|
|
unoidl::InterfaceTypeEntity::Method const& method)
|
|
|
|
{
|
|
|
|
OStringBuffer buf;
|
|
|
|
appendCallSignatureReturnType(buf, manager, method.returnType);
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
buf.append('i');
|
|
|
|
for (auto const& param : method.parameters)
|
|
|
|
{
|
2024-07-11 12:53:01 +02:00
|
|
|
appendCallSignatureParameter(buf, manager, param.direction, param.type);
|
|
|
|
}
|
|
|
|
return buf.makeStringAndClear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendSlotSignatureOffsets(OStringBuffer& buffer, sal_Int32 functionOffset,
|
|
|
|
sal_Int32 vtableOffset)
|
|
|
|
{
|
|
|
|
buffer.append(OString::number(functionOffset) + "_" + OString::number(vtableOffset));
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendSlotSignatureReturnType(OStringBuffer& buffer,
|
|
|
|
rtl::Reference<TypeManager> const& manager, OUString const& type)
|
|
|
|
{
|
|
|
|
switch (manager->getSort(resolveAllTypedefs(manager, type)))
|
|
|
|
{
|
|
|
|
case codemaker::UnoType::Sort::Void:
|
|
|
|
buffer.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:
|
|
|
|
buffer.append('i');
|
|
|
|
break;
|
|
|
|
case codemaker::UnoType::Sort::Hyper:
|
|
|
|
case codemaker::UnoType::Sort::UnsignedHyper:
|
|
|
|
buffer.append('j');
|
|
|
|
break;
|
|
|
|
case codemaker::UnoType::Sort::Float:
|
|
|
|
buffer.append('f');
|
|
|
|
break;
|
|
|
|
case codemaker::UnoType::Sort::Double:
|
|
|
|
buffer.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:
|
|
|
|
buffer.append('I');
|
|
|
|
break;
|
|
|
|
case codemaker::UnoType::Sort::PlainStruct:
|
|
|
|
case codemaker::UnoType::Sort::InstantiatedPolymorphicStruct:
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
{
|
2024-07-11 12:53:01 +02:00
|
|
|
switch (getKind(manager, type))
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
{
|
2024-07-11 12:53:01 +02:00
|
|
|
case StructKind::Empty:
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
2024-07-11 12:53:01 +02:00
|
|
|
case StructKind::I32:
|
|
|
|
buffer.append('i');
|
|
|
|
break;
|
|
|
|
case StructKind::I64:
|
|
|
|
buffer.append('j');
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
2024-07-11 12:53:01 +02:00
|
|
|
case StructKind::F32:
|
|
|
|
buffer.append('f');
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
2024-07-11 12:53:01 +02:00
|
|
|
case StructKind::F64:
|
|
|
|
buffer.append('d');
|
|
|
|
break;
|
|
|
|
case StructKind::General:
|
|
|
|
buffer.append('I');
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
|
|
|
}
|
2024-07-11 12:53:01 +02:00
|
|
|
break;
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
}
|
2024-07-11 12:53:01 +02:00
|
|
|
default:
|
|
|
|
throw CannotDumpException("unexpected entity \"" + type
|
|
|
|
+ "\" in call to appendSlotSignatureReturnType");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void appendSlotSignatureParameter(
|
|
|
|
OStringBuffer& buffer, rtl::Reference<TypeManager> const& manager,
|
|
|
|
unoidl::InterfaceTypeEntity::Method::Parameter::Direction direction, OUString const& type)
|
|
|
|
{
|
|
|
|
if (direction == unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN)
|
|
|
|
{
|
|
|
|
switch (manager->getSort(resolveAllTypedefs(manager, type)))
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
{
|
2024-07-11 12:53:01 +02:00
|
|
|
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:
|
|
|
|
buffer.append('i');
|
|
|
|
break;
|
|
|
|
case codemaker::UnoType::Sort::Hyper:
|
|
|
|
case codemaker::UnoType::Sort::UnsignedHyper:
|
|
|
|
buffer.append('j');
|
|
|
|
break;
|
|
|
|
case codemaker::UnoType::Sort::Float:
|
|
|
|
buffer.append('f');
|
|
|
|
break;
|
|
|
|
case codemaker::UnoType::Sort::Double:
|
|
|
|
buffer.append('d');
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
throw CannotDumpException("unexpected entity \"" + type
|
|
|
|
+ "\" in call to appendSlotSignatureParameter");
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
}
|
|
|
|
}
|
2024-07-11 12:53:01 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
buffer.append('i');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
OString computeGetterSlotSignature(rtl::Reference<TypeManager> const& manager,
|
|
|
|
unoidl::InterfaceTypeEntity::Attribute const& attribute,
|
|
|
|
sal_Int32 functionOffset, sal_Int32 vtableOffset)
|
|
|
|
{
|
|
|
|
OStringBuffer buf;
|
|
|
|
appendSlotSignatureOffsets(buf, functionOffset, vtableOffset);
|
|
|
|
appendSlotSignatureReturnType(buf, manager, attribute.type);
|
|
|
|
return buf.makeStringAndClear();
|
|
|
|
}
|
|
|
|
|
|
|
|
OString computeSetterSlotSignature(rtl::Reference<TypeManager> const& manager,
|
|
|
|
unoidl::InterfaceTypeEntity::Attribute const& attribute,
|
|
|
|
sal_Int32 functionOffset, sal_Int32 vtableOffset)
|
|
|
|
{
|
|
|
|
OStringBuffer buf;
|
|
|
|
appendSlotSignatureOffsets(buf, functionOffset, vtableOffset);
|
|
|
|
buf.append('v');
|
|
|
|
appendSlotSignatureParameter(
|
|
|
|
buf, manager, unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN, attribute.type);
|
|
|
|
return buf.makeStringAndClear();
|
|
|
|
}
|
|
|
|
|
|
|
|
OString computeMethodSlotSignature(rtl::Reference<TypeManager> const& manager,
|
|
|
|
unoidl::InterfaceTypeEntity::Method const& method,
|
|
|
|
sal_Int32 functionOffset, sal_Int32 vtableOffset)
|
|
|
|
{
|
|
|
|
OStringBuffer buf;
|
|
|
|
appendSlotSignatureOffsets(buf, functionOffset, vtableOffset);
|
|
|
|
appendSlotSignatureReturnType(buf, manager, method.returnType);
|
|
|
|
for (auto const& param : method.parameters)
|
|
|
|
{
|
|
|
|
appendSlotSignatureParameter(buf, manager, param.direction, param.type);
|
|
|
|
}
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
return buf.makeStringAndClear();
|
|
|
|
}
|
|
|
|
|
2024-07-11 12:53:01 +02:00
|
|
|
void computeSlotSignatures(rtl::Reference<TypeManager> const& manager,
|
|
|
|
unoidl::InterfaceTypeEntity const& interface, sal_Int32& functionOffset,
|
|
|
|
sal_Int32& vtableOffset, std::set<OString>& slotSignatures)
|
|
|
|
{
|
|
|
|
auto const orgVtableOffset = vtableOffset;
|
|
|
|
auto firstBase = true;
|
|
|
|
for (auto const& base : interface.getDirectMandatoryBases())
|
|
|
|
{
|
|
|
|
auto const ent = manager->getManager()->findEntity(base.name);
|
|
|
|
if (!ent.is() || ent->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
|
|
|
|
{
|
|
|
|
throw CannotDumpException("unexpected base type \"" + base.name
|
|
|
|
+ "\" in call to computeSlotSignatures");
|
|
|
|
}
|
|
|
|
sal_Int32 freshFunctionOffset = 0;
|
|
|
|
computeSlotSignatures(manager, *static_cast<unoidl::InterfaceTypeEntity const*>(ent.get()),
|
|
|
|
firstBase ? functionOffset : freshFunctionOffset, vtableOffset,
|
|
|
|
slotSignatures);
|
|
|
|
vtableOffset += 4;
|
|
|
|
firstBase = false;
|
|
|
|
}
|
|
|
|
for (auto const& attr : interface.getDirectAttributes())
|
|
|
|
{
|
|
|
|
slotSignatures.insert(
|
|
|
|
computeGetterSlotSignature(manager, attr, functionOffset, orgVtableOffset));
|
|
|
|
++functionOffset;
|
|
|
|
if (!attr.readOnly)
|
|
|
|
{
|
|
|
|
slotSignatures.insert(
|
|
|
|
computeSetterSlotSignature(manager, attr, functionOffset, orgVtableOffset));
|
|
|
|
++functionOffset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (auto const& meth : interface.getDirectMethods())
|
|
|
|
{
|
|
|
|
slotSignatures.insert(
|
|
|
|
computeMethodSlotSignature(manager, meth, functionOffset, orgVtableOffset));
|
|
|
|
++functionOffset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Properly implement cppu::throwException for Emscripten
...by implementing (for now) just enough of the cpp2uno half of the Wasm UNO
bridge to make it work. In general, that half suffers from the same issue as
the already-implemented uno2cpp half, namely that Wasm doesn't allow to generate
code on the fly (which, in this case, would be needed to implement the vtable
slot trampoline functions). So, for now just hard-code the few
vtableSlotFunction_* that are needed by the UNO interfaces for
cppuhelper/source/exc_thrower.cxx. (A proper fix would probably use the same
approach as for the uno2cpp half, and use something like wasmcallgen to generate
at least all the vtableSlotFunction_* needed for udkapi/offapi upfront.)
The RTTI for the exceptions needs to be unique across the executable for
exception catching to actually work (as it compares exception types by RTTI
address rather than by name). We thus need to export all the relevant RTTI
symbols (which I hacked into the existing wasmcallgen for now, even if that
makes that executable's name a slight misnomer now), and access them with a new
jsGetExportedSymbol. (This exporting would also be needed by the "classical"
approach of using dlsym on the main module, cf.
<https://gerrit.libreoffice.org/c/core/+/167187> "WIP: Emscripten: Set up
support for dlsym from main module". And while that dlsym approach would work,
it is much simpler to just use that jsGetExportedSymbol than to use a dlsym
detour, and thereby avoid all the hassle of -sMAIN_MODULE detailed in the commit
message of that Gerrit change.)
It also turned out that including Emscripten's <cxxabi.h> needs
__USING_WASM_EXCEPTIONS__ to be defined, because it uses that in its declaration
of __cxa_throw. (The source for setting that define internally in Emscripten is
get_cflags in the emsdk's upstream/emscripten/tools/system_libs.py, which
defines __USING_EMSCRIPTEN_EXCEPTIONS__ for the non-Wasm, Emscripten JS
exception mode, and defines __USING_WASM_EXCEPTIONS__ for
--enable-wasm-exceptions, which we use. The commit message of
f4ec967599f5dafa1ce477631d7c2e8de005e28f "Fix redefinion of Emscripten
__cxxabiv1::__cxa_exception" documents my prior confusion of when one or the
other would be defined.)
Change-Id: Id08765ab5b4ce1553dc3a61648324526185cb64c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170246
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-07-09 17:28:46 +02:00
|
|
|
void appendRttiSymbolSegment(OStringBuffer& buffer, OUString const& id)
|
|
|
|
{
|
|
|
|
OString s(OUStringToOString(id, RTL_TEXTENCODING_ASCII_US));
|
|
|
|
buffer.append(OString::number(s.getLength()) + s);
|
|
|
|
}
|
|
|
|
|
|
|
|
OString computeRttiSymbol(std::vector<OUString> const& path, OUString const& id)
|
|
|
|
{
|
|
|
|
OStringBuffer buf("__ZTI");
|
|
|
|
if (!path.empty())
|
|
|
|
{
|
|
|
|
buf.append('N');
|
|
|
|
for (auto const& i : path)
|
|
|
|
{
|
|
|
|
appendRttiSymbolSegment(buf, i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
appendRttiSymbolSegment(buf, id);
|
|
|
|
if (!path.empty())
|
|
|
|
{
|
|
|
|
buf.append('E');
|
|
|
|
}
|
|
|
|
return buf.makeStringAndClear();
|
|
|
|
}
|
|
|
|
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
void scan(rtl::Reference<TypeManager> const& manager,
|
Properly implement cppu::throwException for Emscripten
...by implementing (for now) just enough of the cpp2uno half of the Wasm UNO
bridge to make it work. In general, that half suffers from the same issue as
the already-implemented uno2cpp half, namely that Wasm doesn't allow to generate
code on the fly (which, in this case, would be needed to implement the vtable
slot trampoline functions). So, for now just hard-code the few
vtableSlotFunction_* that are needed by the UNO interfaces for
cppuhelper/source/exc_thrower.cxx. (A proper fix would probably use the same
approach as for the uno2cpp half, and use something like wasmcallgen to generate
at least all the vtableSlotFunction_* needed for udkapi/offapi upfront.)
The RTTI for the exceptions needs to be unique across the executable for
exception catching to actually work (as it compares exception types by RTTI
address rather than by name). We thus need to export all the relevant RTTI
symbols (which I hacked into the existing wasmcallgen for now, even if that
makes that executable's name a slight misnomer now), and access them with a new
jsGetExportedSymbol. (This exporting would also be needed by the "classical"
approach of using dlsym on the main module, cf.
<https://gerrit.libreoffice.org/c/core/+/167187> "WIP: Emscripten: Set up
support for dlsym from main module". And while that dlsym approach would work,
it is much simpler to just use that jsGetExportedSymbol than to use a dlsym
detour, and thereby avoid all the hassle of -sMAIN_MODULE detailed in the commit
message of that Gerrit change.)
It also turned out that including Emscripten's <cxxabi.h> needs
__USING_WASM_EXCEPTIONS__ to be defined, because it uses that in its declaration
of __cxa_throw. (The source for setting that define internally in Emscripten is
get_cflags in the emsdk's upstream/emscripten/tools/system_libs.py, which
defines __USING_EMSCRIPTEN_EXCEPTIONS__ for the non-Wasm, Emscripten JS
exception mode, and defines __USING_WASM_EXCEPTIONS__ for
--enable-wasm-exceptions, which we use. The commit message of
f4ec967599f5dafa1ce477631d7c2e8de005e28f "Fix redefinion of Emscripten
__cxxabiv1::__cxa_exception" documents my prior confusion of when one or the
other would be defined.)
Change-Id: Id08765ab5b4ce1553dc3a61648324526185cb64c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170246
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-07-09 17:28:46 +02:00
|
|
|
rtl::Reference<unoidl::MapCursor> const& cursor, std::vector<OUString>& path,
|
2024-07-11 12:53:01 +02:00
|
|
|
std::set<OString>& callSignatures, std::set<OString>& slotSignatures,
|
|
|
|
std::set<OString>& rttis)
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
{
|
|
|
|
assert(cursor.is());
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
OUString id;
|
|
|
|
auto const ent = cursor->getNext(&id);
|
|
|
|
if (!ent.is())
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
switch (ent->getSort())
|
|
|
|
{
|
|
|
|
case unoidl::Entity::SORT_MODULE:
|
Properly implement cppu::throwException for Emscripten
...by implementing (for now) just enough of the cpp2uno half of the Wasm UNO
bridge to make it work. In general, that half suffers from the same issue as
the already-implemented uno2cpp half, namely that Wasm doesn't allow to generate
code on the fly (which, in this case, would be needed to implement the vtable
slot trampoline functions). So, for now just hard-code the few
vtableSlotFunction_* that are needed by the UNO interfaces for
cppuhelper/source/exc_thrower.cxx. (A proper fix would probably use the same
approach as for the uno2cpp half, and use something like wasmcallgen to generate
at least all the vtableSlotFunction_* needed for udkapi/offapi upfront.)
The RTTI for the exceptions needs to be unique across the executable for
exception catching to actually work (as it compares exception types by RTTI
address rather than by name). We thus need to export all the relevant RTTI
symbols (which I hacked into the existing wasmcallgen for now, even if that
makes that executable's name a slight misnomer now), and access them with a new
jsGetExportedSymbol. (This exporting would also be needed by the "classical"
approach of using dlsym on the main module, cf.
<https://gerrit.libreoffice.org/c/core/+/167187> "WIP: Emscripten: Set up
support for dlsym from main module". And while that dlsym approach would work,
it is much simpler to just use that jsGetExportedSymbol than to use a dlsym
detour, and thereby avoid all the hassle of -sMAIN_MODULE detailed in the commit
message of that Gerrit change.)
It also turned out that including Emscripten's <cxxabi.h> needs
__USING_WASM_EXCEPTIONS__ to be defined, because it uses that in its declaration
of __cxa_throw. (The source for setting that define internally in Emscripten is
get_cflags in the emsdk's upstream/emscripten/tools/system_libs.py, which
defines __USING_EMSCRIPTEN_EXCEPTIONS__ for the non-Wasm, Emscripten JS
exception mode, and defines __USING_WASM_EXCEPTIONS__ for
--enable-wasm-exceptions, which we use. The commit message of
f4ec967599f5dafa1ce477631d7c2e8de005e28f "Fix redefinion of Emscripten
__cxxabiv1::__cxa_exception" documents my prior confusion of when one or the
other would be defined.)
Change-Id: Id08765ab5b4ce1553dc3a61648324526185cb64c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170246
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-07-09 17:28:46 +02:00
|
|
|
path.push_back(id);
|
|
|
|
scan(manager, static_cast<unoidl::ModuleEntity*>(ent.get())->createCursor(), path,
|
2024-07-11 12:53:01 +02:00
|
|
|
callSignatures, slotSignatures, rttis);
|
Properly implement cppu::throwException for Emscripten
...by implementing (for now) just enough of the cpp2uno half of the Wasm UNO
bridge to make it work. In general, that half suffers from the same issue as
the already-implemented uno2cpp half, namely that Wasm doesn't allow to generate
code on the fly (which, in this case, would be needed to implement the vtable
slot trampoline functions). So, for now just hard-code the few
vtableSlotFunction_* that are needed by the UNO interfaces for
cppuhelper/source/exc_thrower.cxx. (A proper fix would probably use the same
approach as for the uno2cpp half, and use something like wasmcallgen to generate
at least all the vtableSlotFunction_* needed for udkapi/offapi upfront.)
The RTTI for the exceptions needs to be unique across the executable for
exception catching to actually work (as it compares exception types by RTTI
address rather than by name). We thus need to export all the relevant RTTI
symbols (which I hacked into the existing wasmcallgen for now, even if that
makes that executable's name a slight misnomer now), and access them with a new
jsGetExportedSymbol. (This exporting would also be needed by the "classical"
approach of using dlsym on the main module, cf.
<https://gerrit.libreoffice.org/c/core/+/167187> "WIP: Emscripten: Set up
support for dlsym from main module". And while that dlsym approach would work,
it is much simpler to just use that jsGetExportedSymbol than to use a dlsym
detour, and thereby avoid all the hassle of -sMAIN_MODULE detailed in the commit
message of that Gerrit change.)
It also turned out that including Emscripten's <cxxabi.h> needs
__USING_WASM_EXCEPTIONS__ to be defined, because it uses that in its declaration
of __cxa_throw. (The source for setting that define internally in Emscripten is
get_cflags in the emsdk's upstream/emscripten/tools/system_libs.py, which
defines __USING_EMSCRIPTEN_EXCEPTIONS__ for the non-Wasm, Emscripten JS
exception mode, and defines __USING_WASM_EXCEPTIONS__ for
--enable-wasm-exceptions, which we use. The commit message of
f4ec967599f5dafa1ce477631d7c2e8de005e28f "Fix redefinion of Emscripten
__cxxabiv1::__cxa_exception" documents my prior confusion of when one or the
other would be defined.)
Change-Id: Id08765ab5b4ce1553dc3a61648324526185cb64c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170246
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-07-09 17:28:46 +02:00
|
|
|
path.pop_back();
|
|
|
|
break;
|
|
|
|
case unoidl::Entity::SORT_EXCEPTION_TYPE:
|
|
|
|
rttis.insert(computeRttiSymbol(path, id));
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
|
|
|
case unoidl::Entity::SORT_INTERFACE_TYPE:
|
2024-07-11 12:53:01 +02:00
|
|
|
{
|
|
|
|
auto const ite = static_cast<unoidl::InterfaceTypeEntity const*>(ent.get());
|
|
|
|
for (auto const& attr : ite->getDirectAttributes())
|
|
|
|
{
|
|
|
|
callSignatures.insert(computeGetterCallSignature(manager, attr));
|
|
|
|
if (!attr.readOnly)
|
|
|
|
{
|
|
|
|
callSignatures.insert(computeSetterCallSignature(manager, attr));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (auto const& meth : ite->getDirectMethods())
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
{
|
2024-07-11 12:53:01 +02:00
|
|
|
callSignatures.insert(computeMethodCallSignature(manager, meth));
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
}
|
2024-07-11 12:53:01 +02:00
|
|
|
computeSlotSignatures(manager, *ite, o3tl::temporary<sal_Int32>(0),
|
|
|
|
o3tl::temporary<sal_Int32>(0), slotSignatures);
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
break;
|
2024-07-11 12:53:01 +02:00
|
|
|
}
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SAL_IMPLEMENT_MAIN()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
auto const args = rtl_getAppCommandArgCount();
|
Properly implement cppu::throwException for Emscripten
...by implementing (for now) just enough of the cpp2uno half of the Wasm UNO
bridge to make it work. In general, that half suffers from the same issue as
the already-implemented uno2cpp half, namely that Wasm doesn't allow to generate
code on the fly (which, in this case, would be needed to implement the vtable
slot trampoline functions). So, for now just hard-code the few
vtableSlotFunction_* that are needed by the UNO interfaces for
cppuhelper/source/exc_thrower.cxx. (A proper fix would probably use the same
approach as for the uno2cpp half, and use something like wasmcallgen to generate
at least all the vtableSlotFunction_* needed for udkapi/offapi upfront.)
The RTTI for the exceptions needs to be unique across the executable for
exception catching to actually work (as it compares exception types by RTTI
address rather than by name). We thus need to export all the relevant RTTI
symbols (which I hacked into the existing wasmcallgen for now, even if that
makes that executable's name a slight misnomer now), and access them with a new
jsGetExportedSymbol. (This exporting would also be needed by the "classical"
approach of using dlsym on the main module, cf.
<https://gerrit.libreoffice.org/c/core/+/167187> "WIP: Emscripten: Set up
support for dlsym from main module". And while that dlsym approach would work,
it is much simpler to just use that jsGetExportedSymbol than to use a dlsym
detour, and thereby avoid all the hassle of -sMAIN_MODULE detailed in the commit
message of that Gerrit change.)
It also turned out that including Emscripten's <cxxabi.h> needs
__USING_WASM_EXCEPTIONS__ to be defined, because it uses that in its declaration
of __cxa_throw. (The source for setting that define internally in Emscripten is
get_cflags in the emsdk's upstream/emscripten/tools/system_libs.py, which
defines __USING_EMSCRIPTEN_EXCEPTIONS__ for the non-Wasm, Emscripten JS
exception mode, and defines __USING_WASM_EXCEPTIONS__ for
--enable-wasm-exceptions, which we use. The commit message of
f4ec967599f5dafa1ce477631d7c2e8de005e28f "Fix redefinion of Emscripten
__cxxabiv1::__cxa_exception" documents my prior confusion of when one or the
other would be defined.)
Change-Id: Id08765ab5b4ce1553dc3a61648324526185cb64c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170246
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-07-09 17:28:46 +02:00
|
|
|
if (args < 3)
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
{
|
|
|
|
badUsage();
|
|
|
|
}
|
|
|
|
auto const cppPathname = getPathnameArgument(0);
|
|
|
|
auto const asmPathname = getPathnameArgument(1);
|
Properly implement cppu::throwException for Emscripten
...by implementing (for now) just enough of the cpp2uno half of the Wasm UNO
bridge to make it work. In general, that half suffers from the same issue as
the already-implemented uno2cpp half, namely that Wasm doesn't allow to generate
code on the fly (which, in this case, would be needed to implement the vtable
slot trampoline functions). So, for now just hard-code the few
vtableSlotFunction_* that are needed by the UNO interfaces for
cppuhelper/source/exc_thrower.cxx. (A proper fix would probably use the same
approach as for the uno2cpp half, and use something like wasmcallgen to generate
at least all the vtableSlotFunction_* needed for udkapi/offapi upfront.)
The RTTI for the exceptions needs to be unique across the executable for
exception catching to actually work (as it compares exception types by RTTI
address rather than by name). We thus need to export all the relevant RTTI
symbols (which I hacked into the existing wasmcallgen for now, even if that
makes that executable's name a slight misnomer now), and access them with a new
jsGetExportedSymbol. (This exporting would also be needed by the "classical"
approach of using dlsym on the main module, cf.
<https://gerrit.libreoffice.org/c/core/+/167187> "WIP: Emscripten: Set up
support for dlsym from main module". And while that dlsym approach would work,
it is much simpler to just use that jsGetExportedSymbol than to use a dlsym
detour, and thereby avoid all the hassle of -sMAIN_MODULE detailed in the commit
message of that Gerrit change.)
It also turned out that including Emscripten's <cxxabi.h> needs
__USING_WASM_EXCEPTIONS__ to be defined, because it uses that in its declaration
of __cxa_throw. (The source for setting that define internally in Emscripten is
get_cflags in the emsdk's upstream/emscripten/tools/system_libs.py, which
defines __USING_EMSCRIPTEN_EXCEPTIONS__ for the non-Wasm, Emscripten JS
exception mode, and defines __USING_WASM_EXCEPTIONS__ for
--enable-wasm-exceptions, which we use. The commit message of
f4ec967599f5dafa1ce477631d7c2e8de005e28f "Fix redefinion of Emscripten
__cxxabiv1::__cxa_exception" documents my prior confusion of when one or the
other would be defined.)
Change-Id: Id08765ab5b4ce1553dc3a61648324526185cb64c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170246
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-07-09 17:28:46 +02:00
|
|
|
auto const expPathname = getPathnameArgument(2);
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
rtl::Reference<TypeManager> mgr(new TypeManager);
|
Properly implement cppu::throwException for Emscripten
...by implementing (for now) just enough of the cpp2uno half of the Wasm UNO
bridge to make it work. In general, that half suffers from the same issue as
the already-implemented uno2cpp half, namely that Wasm doesn't allow to generate
code on the fly (which, in this case, would be needed to implement the vtable
slot trampoline functions). So, for now just hard-code the few
vtableSlotFunction_* that are needed by the UNO interfaces for
cppuhelper/source/exc_thrower.cxx. (A proper fix would probably use the same
approach as for the uno2cpp half, and use something like wasmcallgen to generate
at least all the vtableSlotFunction_* needed for udkapi/offapi upfront.)
The RTTI for the exceptions needs to be unique across the executable for
exception catching to actually work (as it compares exception types by RTTI
address rather than by name). We thus need to export all the relevant RTTI
symbols (which I hacked into the existing wasmcallgen for now, even if that
makes that executable's name a slight misnomer now), and access them with a new
jsGetExportedSymbol. (This exporting would also be needed by the "classical"
approach of using dlsym on the main module, cf.
<https://gerrit.libreoffice.org/c/core/+/167187> "WIP: Emscripten: Set up
support for dlsym from main module". And while that dlsym approach would work,
it is much simpler to just use that jsGetExportedSymbol than to use a dlsym
detour, and thereby avoid all the hassle of -sMAIN_MODULE detailed in the commit
message of that Gerrit change.)
It also turned out that including Emscripten's <cxxabi.h> needs
__USING_WASM_EXCEPTIONS__ to be defined, because it uses that in its declaration
of __cxa_throw. (The source for setting that define internally in Emscripten is
get_cflags in the emsdk's upstream/emscripten/tools/system_libs.py, which
defines __USING_EMSCRIPTEN_EXCEPTIONS__ for the non-Wasm, Emscripten JS
exception mode, and defines __USING_WASM_EXCEPTIONS__ for
--enable-wasm-exceptions, which we use. The commit message of
f4ec967599f5dafa1ce477631d7c2e8de005e28f "Fix redefinion of Emscripten
__cxxabiv1::__cxa_exception" documents my prior confusion of when one or the
other would be defined.)
Change-Id: Id08765ab5b4ce1553dc3a61648324526185cb64c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170246
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-07-09 17:28:46 +02:00
|
|
|
for (sal_uInt32 i = 3; i != args; ++i)
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
Properly implement cppu::throwException for Emscripten
...by implementing (for now) just enough of the cpp2uno half of the Wasm UNO
bridge to make it work. In general, that half suffers from the same issue as
the already-implemented uno2cpp half, namely that Wasm doesn't allow to generate
code on the fly (which, in this case, would be needed to implement the vtable
slot trampoline functions). So, for now just hard-code the few
vtableSlotFunction_* that are needed by the UNO interfaces for
cppuhelper/source/exc_thrower.cxx. (A proper fix would probably use the same
approach as for the uno2cpp half, and use something like wasmcallgen to generate
at least all the vtableSlotFunction_* needed for udkapi/offapi upfront.)
The RTTI for the exceptions needs to be unique across the executable for
exception catching to actually work (as it compares exception types by RTTI
address rather than by name). We thus need to export all the relevant RTTI
symbols (which I hacked into the existing wasmcallgen for now, even if that
makes that executable's name a slight misnomer now), and access them with a new
jsGetExportedSymbol. (This exporting would also be needed by the "classical"
approach of using dlsym on the main module, cf.
<https://gerrit.libreoffice.org/c/core/+/167187> "WIP: Emscripten: Set up
support for dlsym from main module". And while that dlsym approach would work,
it is much simpler to just use that jsGetExportedSymbol than to use a dlsym
detour, and thereby avoid all the hassle of -sMAIN_MODULE detailed in the commit
message of that Gerrit change.)
It also turned out that including Emscripten's <cxxabi.h> needs
__USING_WASM_EXCEPTIONS__ to be defined, because it uses that in its declaration
of __cxa_throw. (The source for setting that define internally in Emscripten is
get_cflags in the emsdk's upstream/emscripten/tools/system_libs.py, which
defines __USING_EMSCRIPTEN_EXCEPTIONS__ for the non-Wasm, Emscripten JS
exception mode, and defines __USING_WASM_EXCEPTIONS__ for
--enable-wasm-exceptions, which we use. The commit message of
f4ec967599f5dafa1ce477631d7c2e8de005e28f "Fix redefinion of Emscripten
__cxxabiv1::__cxa_exception" documents my prior confusion of when one or the
other would be defined.)
Change-Id: Id08765ab5b4ce1553dc3a61648324526185cb64c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170246
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-07-09 17:28:46 +02:00
|
|
|
std::vector<OUString> path;
|
2024-07-11 12:53:01 +02:00
|
|
|
std::set<OString> callSignatures;
|
|
|
|
std::set<OString> slotSignatures;
|
Properly implement cppu::throwException for Emscripten
...by implementing (for now) just enough of the cpp2uno half of the Wasm UNO
bridge to make it work. In general, that half suffers from the same issue as
the already-implemented uno2cpp half, namely that Wasm doesn't allow to generate
code on the fly (which, in this case, would be needed to implement the vtable
slot trampoline functions). So, for now just hard-code the few
vtableSlotFunction_* that are needed by the UNO interfaces for
cppuhelper/source/exc_thrower.cxx. (A proper fix would probably use the same
approach as for the uno2cpp half, and use something like wasmcallgen to generate
at least all the vtableSlotFunction_* needed for udkapi/offapi upfront.)
The RTTI for the exceptions needs to be unique across the executable for
exception catching to actually work (as it compares exception types by RTTI
address rather than by name). We thus need to export all the relevant RTTI
symbols (which I hacked into the existing wasmcallgen for now, even if that
makes that executable's name a slight misnomer now), and access them with a new
jsGetExportedSymbol. (This exporting would also be needed by the "classical"
approach of using dlsym on the main module, cf.
<https://gerrit.libreoffice.org/c/core/+/167187> "WIP: Emscripten: Set up
support for dlsym from main module". And while that dlsym approach would work,
it is much simpler to just use that jsGetExportedSymbol than to use a dlsym
detour, and thereby avoid all the hassle of -sMAIN_MODULE detailed in the commit
message of that Gerrit change.)
It also turned out that including Emscripten's <cxxabi.h> needs
__USING_WASM_EXCEPTIONS__ to be defined, because it uses that in its declaration
of __cxa_throw. (The source for setting that define internally in Emscripten is
get_cflags in the emsdk's upstream/emscripten/tools/system_libs.py, which
defines __USING_EMSCRIPTEN_EXCEPTIONS__ for the non-Wasm, Emscripten JS
exception mode, and defines __USING_WASM_EXCEPTIONS__ for
--enable-wasm-exceptions, which we use. The commit message of
f4ec967599f5dafa1ce477631d7c2e8de005e28f "Fix redefinion of Emscripten
__cxxabiv1::__cxa_exception" documents my prior confusion of when one or the
other would be defined.)
Change-Id: Id08765ab5b4ce1553dc3a61648324526185cb64c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170246
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-07-09 17:28:46 +02:00
|
|
|
std::set<OString> rttis;
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
for (auto const& prov : mgr->getPrimaryProviders())
|
|
|
|
{
|
2024-07-11 12:53:01 +02:00
|
|
|
scan(mgr, prov->createRootCursor(), path, callSignatures, slotSignatures, rttis);
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
}
|
|
|
|
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"
|
2024-07-11 12:53:01 +02:00
|
|
|
"#include <bit>\n"
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
"#include <string_view>\n"
|
|
|
|
"#include <com/sun/star/uno/RuntimeException.hpp>\n"
|
|
|
|
"#include <rtl/ustring.hxx>\n"
|
2024-07-11 12:53:01 +02:00
|
|
|
"#include <sal/types.h>\n"
|
|
|
|
"#include <wasm/generated.hxx>\n";
|
|
|
|
for (auto const& sig : callSignatures)
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
{
|
|
|
|
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";
|
2024-07-11 12:53:01 +02:00
|
|
|
for (auto const& sig : callSignatures)
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
{
|
|
|
|
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";
|
2024-07-11 12:53:01 +02:00
|
|
|
if (!slotSignatures.empty())
|
|
|
|
{
|
|
|
|
cppOut << "namespace {\n";
|
|
|
|
}
|
|
|
|
for (auto const& sig : slotSignatures)
|
|
|
|
{
|
|
|
|
auto const i1 = sig.indexOf('_');
|
|
|
|
assert(i1 != -1);
|
|
|
|
sal_Int32 i2 = i1 + 1;
|
|
|
|
for (;; ++i2)
|
|
|
|
{
|
|
|
|
assert(i2 < sig.getLength());
|
|
|
|
if (!rtl::isAsciiDigit(static_cast<unsigned char>(sig[i2])))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
assert(i2 != i1);
|
|
|
|
cppOut << "extern \"C\" ";
|
|
|
|
switch (sig[i2])
|
|
|
|
{
|
|
|
|
case 'd':
|
|
|
|
cppOut << "double";
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
cppOut << "float";
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
cppOut << "unsigned";
|
|
|
|
break;
|
|
|
|
case 'j':
|
|
|
|
cppOut << "unsigned long long";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
cppOut << "void";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cppOut << " vtableSlotFunction_" << sig << "(";
|
|
|
|
if (sig[i2] == 'I')
|
|
|
|
{
|
|
|
|
cppOut << "unsigned indirectRet, ";
|
|
|
|
}
|
|
|
|
cppOut << "unsigned thisPtr";
|
|
|
|
for (sal_Int32 i = i2 + 1; i != sig.getLength(); ++i)
|
|
|
|
{
|
|
|
|
cppOut << ", ";
|
|
|
|
switch (sig[i])
|
|
|
|
{
|
|
|
|
case 'd':
|
|
|
|
cppOut << "double";
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
cppOut << "float";
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
cppOut << "unsigned";
|
|
|
|
break;
|
|
|
|
case 'j':
|
|
|
|
cppOut << "unsigned long long";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
O3TL_UNREACHABLE;
|
|
|
|
}
|
|
|
|
cppOut << " arg" << (i - i2);
|
|
|
|
}
|
|
|
|
cppOut << ") { ";
|
|
|
|
switch (sig[i2])
|
|
|
|
{
|
|
|
|
case 'd':
|
|
|
|
cppOut << "return std::bit_cast<double>(static_cast<unsigned long long>(";
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
cppOut << "return std::bit_cast<float>(static_cast<unsigned>(";
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
cppOut << "return static_cast<unsigned>(";
|
|
|
|
break;
|
|
|
|
case 'j':
|
|
|
|
cppOut << "return static_cast<unsigned long long>(";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cppOut << "vtableCall(" << sig.subView(0, i1) << ", "
|
|
|
|
<< sig.subView(i1 + 1, i2 - (i1 + 1)) << ", thisPtr, {";
|
|
|
|
for (sal_Int32 i = i2 + 1; i != sig.getLength(); ++i)
|
|
|
|
{
|
|
|
|
if (i != i2 + 1)
|
|
|
|
{
|
|
|
|
cppOut << ", ";
|
|
|
|
}
|
|
|
|
cppOut << "sal_uInt64(";
|
|
|
|
switch (sig[i])
|
|
|
|
{
|
|
|
|
case 'd':
|
|
|
|
cppOut << "std::bit_cast<unsigned long long>(";
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
cppOut << "std::bit_cast<unsigned>(";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cppOut << "arg" << (i - i2) << ")";
|
|
|
|
switch (sig[i])
|
|
|
|
{
|
|
|
|
case 'd':
|
|
|
|
case 'f':
|
|
|
|
cppOut << ")";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cppOut << "}, "
|
|
|
|
<< (sig[i2] == 'I' ? "indirectRet" : "reinterpret_cast<unsigned>(nullptr)")
|
|
|
|
<< ")";
|
|
|
|
switch (sig[i2])
|
|
|
|
{
|
|
|
|
case 'd':
|
|
|
|
case 'f':
|
|
|
|
cppOut << "))";
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
case 'j':
|
|
|
|
cppOut << ")";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
cppOut << "; }\n";
|
|
|
|
}
|
|
|
|
if (!slotSignatures.empty())
|
|
|
|
{
|
|
|
|
cppOut << "}\n";
|
|
|
|
}
|
|
|
|
cppOut << "void const * getVtableSlotFunction(std::string_view signature) {\n";
|
|
|
|
for (auto const& sig : slotSignatures)
|
|
|
|
{
|
|
|
|
cppOut << " if (signature == \"" << sig << "\") {\n"
|
|
|
|
<< " return reinterpret_cast<void const*>(vtableSlotFunction_" << sig
|
|
|
|
<< ");\n"
|
|
|
|
<< " }\n";
|
|
|
|
}
|
|
|
|
cppOut << " throw css::uno::RuntimeException(\"Wasm bridge cannot fill virtual function "
|
|
|
|
"slot with signature \" + OUString::fromUtf8(signature));\n"
|
|
|
|
"}\n";
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
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";
|
2024-07-11 12:53:01 +02:00
|
|
|
for (auto const& sig : callSignatures)
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
{
|
|
|
|
asmOut << "\t.functype callVirtualFunction_" << sig << " (i32, i32, i32) -> ()\n";
|
|
|
|
}
|
2024-07-11 12:53:01 +02:00
|
|
|
for (auto const& sig : callSignatures)
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
Properly implement cppu::throwException for Emscripten
...by implementing (for now) just enough of the cpp2uno half of the Wasm UNO
bridge to make it work. In general, that half suffers from the same issue as
the already-implemented uno2cpp half, namely that Wasm doesn't allow to generate
code on the fly (which, in this case, would be needed to implement the vtable
slot trampoline functions). So, for now just hard-code the few
vtableSlotFunction_* that are needed by the UNO interfaces for
cppuhelper/source/exc_thrower.cxx. (A proper fix would probably use the same
approach as for the uno2cpp half, and use something like wasmcallgen to generate
at least all the vtableSlotFunction_* needed for udkapi/offapi upfront.)
The RTTI for the exceptions needs to be unique across the executable for
exception catching to actually work (as it compares exception types by RTTI
address rather than by name). We thus need to export all the relevant RTTI
symbols (which I hacked into the existing wasmcallgen for now, even if that
makes that executable's name a slight misnomer now), and access them with a new
jsGetExportedSymbol. (This exporting would also be needed by the "classical"
approach of using dlsym on the main module, cf.
<https://gerrit.libreoffice.org/c/core/+/167187> "WIP: Emscripten: Set up
support for dlsym from main module". And while that dlsym approach would work,
it is much simpler to just use that jsGetExportedSymbol than to use a dlsym
detour, and thereby avoid all the hassle of -sMAIN_MODULE detailed in the commit
message of that Gerrit change.)
It also turned out that including Emscripten's <cxxabi.h> needs
__USING_WASM_EXCEPTIONS__ to be defined, because it uses that in its declaration
of __cxa_throw. (The source for setting that define internally in Emscripten is
get_cflags in the emsdk's upstream/emscripten/tools/system_libs.py, which
defines __USING_EMSCRIPTEN_EXCEPTIONS__ for the non-Wasm, Emscripten JS
exception mode, and defines __USING_WASM_EXCEPTIONS__ for
--enable-wasm-exceptions, which we use. The commit message of
f4ec967599f5dafa1ce477631d7c2e8de005e28f "Fix redefinion of Emscripten
__cxxabiv1::__cxa_exception" documents my prior confusion of when one or the
other would be defined.)
Change-Id: Id08765ab5b4ce1553dc3a61648324526185cb64c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170246
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
2024-07-09 17:28:46 +02:00
|
|
|
std::ofstream expOut(expPathname, std::ios_base::out | std::ios_base::trunc);
|
|
|
|
if (!expOut)
|
|
|
|
{
|
|
|
|
std::cerr << "Cannot open \"" << expPathname << "\" for writing\n";
|
|
|
|
std::exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
for (auto const& rtti : rttis)
|
|
|
|
{
|
|
|
|
expOut << rtti.getStr() << "\n";
|
|
|
|
}
|
|
|
|
expOut.close();
|
|
|
|
if (!expOut)
|
|
|
|
{
|
|
|
|
std::cerr << "Failed to write \"" << expPathname << "\"\n";
|
|
|
|
std::exit(EXIT_FAILURE);
|
|
|
|
}
|
Emscripten: Towards a working C++ UNO bridge
...by making the general UNO -> C++ function call case work (modulo handling
exceptions, which I'll look into later).
Wasm call_indirect unfortunately needs to statically know the call target's
signature, so we statically need to know all possible signatures. So introduce
wasmcallgen helper to scan the existing UNOIDL API upfront and generate the
relevant callvirtualfunction-wrapper.cxx and callvirtualfunction-inst.s code.
(The good thing is that the number of different signatures is somewhat limited,
each parameter can only be one of i32, i64, f32, or f64. So even if 3rd-party
extensions bring along new UNOIDL interface methods, chances are relatively high
that the signatures needed for them would already be covered by the existing
ones.)
Testing this can nicely be done in unotest/source/embindtest/embindtest.js via
css.script.Invocation (which internally exercises the relevant code). (Instead
of adding individual org.libreoffice.embindtest.StructLong/String etc., it would
be nicer to introduce some polymorphic StructOne<T>, but the Emind UNO binding
does not support polymorphic structs, so the embindtest.js code would not work.)
Change-Id: If829c9e3772bfd27561f3ad743d38a71d11545b6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167308
Reviewed-by: Stephan Bergmann <stephan.bergmann@allotropia.de>
Tested-by: Jenkins
2024-05-08 09:46:55 +02:00
|
|
|
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: */
|