diff options
Diffstat (limited to 'bridges')
-rw-r--r-- | bridges/CustomTarget_gcc3_wasm.mk | 26 | ||||
-rw-r--r-- | bridges/Library_cpp_uno.mk | 6 | ||||
-rw-r--r-- | bridges/Module_bridges.mk | 1 | ||||
-rw-r--r-- | bridges/inc/wasm/callvirtualfunction.hxx | 21 | ||||
-rw-r--r-- | bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx | 226 |
5 files changed, 279 insertions, 1 deletions
diff --git a/bridges/CustomTarget_gcc3_wasm.mk b/bridges/CustomTarget_gcc3_wasm.mk new file mode 100644 index 000000000000..a88da8577282 --- /dev/null +++ b/bridges/CustomTarget_gcc3_wasm.mk @@ -0,0 +1,26 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t; fill-column: 100 -*- +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# + +$(eval $(call gb_CustomTarget_CustomTarget,bridges/gcc3_wasm)) + +$(eval $(call gb_CustomTarget_register_targets,bridges/gcc3_wasm, \ + callvirtualfunction-wrapper.cxx \ + callvirtualfunction-impls.s \ +)) + +$(gb_CustomTarget_workdir)/bridges/gcc3_wasm/callvirtualfunction-impls.s \ +$(gb_CustomTarget_workdir)/bridges/gcc3_wasm/callvirtualfunction-wrapper.cxx: \ + $(call gb_Executable_get_target_for_build,wasmcallgen) $(call gb_UnoApi_get_target,udkapi) \ + $(call gb_UnoApi_get_target,offapi) + $(call gb_Executable_get_command,wasmcallgen) \ + $(gb_CustomTarget_workdir)/bridges/gcc3_wasm/callvirtualfunction-wrapper.cxx \ + $(gb_CustomTarget_workdir)/bridges/gcc3_wasm/callvirtualfunction-impls.s \ + +$(call gb_UnoApi_get_target,udkapi) +$(call gb_UnoApi_get_target,offapi) + +# vim: set noet sw=4 ts=4: diff --git a/bridges/Library_cpp_uno.mk b/bridges/Library_cpp_uno.mk index dcf83cf34e5b..c42778f359c1 100644 --- a/bridges/Library_cpp_uno.mk +++ b/bridges/Library_cpp_uno.mk @@ -84,6 +84,12 @@ bridge_noopt_objects := except else ifeq ($(OS),EMSCRIPTEN) bridges_SELECTED_BRIDGE := gcc3_wasm bridge_noopt_objects := cpp2uno except uno2cpp +$(eval $(call gb_Library_add_generated_asmobjects,$(CPPU_ENV)_uno, \ + CustomTarget/bridges/gcc3_wasm/callvirtualfunction-impls \ +)) +$(eval $(call gb_Library_add_generated_exception_objects,$(CPPU_ENV)_uno, \ + CustomTarget/bridges/gcc3_wasm/callvirtualfunction-wrapper \ +)) endif else ifeq ($(CPUNAME),M68K) diff --git a/bridges/Module_bridges.mk b/bridges/Module_bridges.mk index 3016bf2c404f..def86fea4cb7 100644 --- a/bridges/Module_bridges.mk +++ b/bridges/Module_bridges.mk @@ -20,6 +20,7 @@ $(eval $(call gb_Module_add_targets,bridges,\ $(if $(filter ANDROID LINUX,$(OS)),\ CustomTarget_gcc3_linux_arm) \ ) \ + $(if $(filter EMSCRIPTEN,$(OS)),CustomTarget_gcc3_wasm) \ )) ifeq (,$(filter build,$(gb_Module_SKIPTARGETS))) diff --git a/bridges/inc/wasm/callvirtualfunction.hxx b/bridges/inc/wasm/callvirtualfunction.hxx new file mode 100644 index 000000000000..23b446cd45b3 --- /dev/null +++ b/bridges/inc/wasm/callvirtualfunction.hxx @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#pragma once + +#include <sal/config.h> + +#include <string_view> + +#include <sal/types.h> + +void callVirtualFunction(std::string_view signature, sal_uInt32 target, sal_uInt64 const* arguments, + void* returnValue); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx index ddb51166b51e..41a471bcc9b0 100644 --- a/bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx +++ b/bridges/source/cpp_uno/gcc3_wasm/uno2cpp.cxx @@ -7,15 +7,81 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <sal/config.h> + +#include <vector> + #include <com/sun/star/uno/RuntimeException.hpp> +#include <com/sun/star/uno/Type.hxx> +#include <o3tl/unreachable.hxx> +#include <rtl/strbuf.hxx> +#include <typelib/typeclass.h> +#include <typelib/typedescription.h> #include <bridge.hxx> #include <types.hxx> #include <unointerfaceproxy.hxx> #include <vtables.hxx> +#include <wasm/callvirtualfunction.hxx> + using namespace ::com::sun::star::uno; +namespace +{ +enum class StructKind +{ + Empty, + I32, + I64, + F32, + F64, + General +}; + +StructKind getKind(typelib_CompoundTypeDescription const* type) +{ + if (type->nMembers > 1) + { + return StructKind::General; + } + auto k = StructKind::Empty; + if (type->pBaseTypeDescription != nullptr) + { + k = getKind(type->pBaseTypeDescription); + } + if (type->nMembers == 0) + { + return k; + } + if (k != StructKind::Empty) + { + return StructKind::General; + } + switch (type->ppTypeRefs[0]->eTypeClass) + { + case typelib_TypeClass_BOOLEAN: + case typelib_TypeClass_BYTE: + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_CHAR: + case typelib_TypeClass_ENUM: + return StructKind::I32; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + return StructKind::I64; + case typelib_TypeClass_FLOAT: + return StructKind::F32; + case typelib_TypeClass_DOUBLE: + return StructKind::F64; + default: + return StructKind::General; + } +} +} + namespace bridges::cpp_uno::shared { void unoInterfaceProxyDispatch(uno_Interface* pUnoI, const typelib_TypeDescription* pMemberDescr, @@ -71,7 +137,165 @@ void unoInterfaceProxyDispatch(uno_Interface* pUnoI, const typelib_TypeDescripti } // else perform queryInterface() [[fallthrough]]; default: - std::abort(); + { + auto const mtd + = reinterpret_cast<typelib_InterfaceMethodTypeDescription const*>( + pMemberDescr); + OStringBuffer sig; + std::vector<sal_uInt64> args; + switch (mtd->pReturnTypeRef->eTypeClass) + { + case typelib_TypeClass_VOID: + sig.append('v'); + break; + case typelib_TypeClass_BOOLEAN: + case typelib_TypeClass_BYTE: + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_CHAR: + case typelib_TypeClass_ENUM: + sig.append('i'); + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + sig.append('j'); + break; + case typelib_TypeClass_FLOAT: + sig.append('f'); + break; + case typelib_TypeClass_DOUBLE: + sig.append('d'); + break; + case typelib_TypeClass_STRING: + case typelib_TypeClass_TYPE: + case typelib_TypeClass_ANY: + case typelib_TypeClass_SEQUENCE: + case typelib_TypeClass_INTERFACE: + sig.append("vi"); + args.push_back(reinterpret_cast<sal_uInt32>(pReturn)); + break; + case typelib_TypeClass_STRUCT: + { + typelib_TypeDescription* td = nullptr; + css::uno::Type(mtd->pReturnTypeRef).getDescription(&td); + switch (getKind( + reinterpret_cast<typelib_CompoundTypeDescription const*>(td))) + { + case StructKind::Empty: + break; + case StructKind::I32: + sig.append('i'); + break; + case StructKind::I64: + sig.append('j'); + break; + case StructKind::F32: + sig.append('f'); + break; + case StructKind::F64: + sig.append('d'); + break; + case StructKind::General: + sig.append("vi"); + args.push_back(reinterpret_cast<sal_uInt32>(pReturn)); + break; + } + break; + } + default: + O3TL_UNREACHABLE; + } + sig.append('i'); + args.push_back(reinterpret_cast<sal_uInt32>(pThis->pCppI)); + for (sal_Int32 i = 0; i != mtd->nParams; ++i) + { + if (mtd->pParams[i].bOut) + { + sig.append('i'); + args.push_back(reinterpret_cast<sal_uInt32>(pArgs[i])); + } + else + { + switch (mtd->pParams[i].pTypeRef->eTypeClass) + { + case typelib_TypeClass_BOOLEAN: + sig.append('i'); + args.push_back(*reinterpret_cast<sal_Bool const*>(pArgs[i])); + break; + case typelib_TypeClass_BYTE: + sig.append('i'); + args.push_back(*reinterpret_cast<sal_Int8 const*>(pArgs[i])); + break; + case typelib_TypeClass_SHORT: + sig.append('i'); + args.push_back(*reinterpret_cast<sal_Int16 const*>(pArgs[i])); + break; + case typelib_TypeClass_UNSIGNED_SHORT: + sig.append('i'); + args.push_back(*reinterpret_cast<sal_uInt16 const*>(pArgs[i])); + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_ENUM: + sig.append('i'); + args.push_back(*reinterpret_cast<sal_Int32 const*>(pArgs[i])); + break; + case typelib_TypeClass_UNSIGNED_LONG: + sig.append('i'); + args.push_back(*reinterpret_cast<sal_uInt32 const*>(pArgs[i])); + break; + case typelib_TypeClass_HYPER: + sig.append('j'); + args.push_back(*reinterpret_cast<sal_Int64 const*>(pArgs[i])); + break; + case typelib_TypeClass_UNSIGNED_HYPER: + sig.append('j'); + args.push_back(*reinterpret_cast<sal_uInt64 const*>(pArgs[i])); + break; + case typelib_TypeClass_FLOAT: + sig.append('f'); + args.push_back(*reinterpret_cast<sal_uInt32 const*>(pArgs[i])); + break; + case typelib_TypeClass_DOUBLE: + sig.append('d'); + args.push_back(*reinterpret_cast<sal_uInt64 const*>(pArgs[i])); + break; + case typelib_TypeClass_CHAR: + sig.append('i'); + args.push_back(*reinterpret_cast<sal_Unicode const*>(pArgs[i])); + break; + case typelib_TypeClass_STRING: + case typelib_TypeClass_TYPE: + case typelib_TypeClass_ANY: + case typelib_TypeClass_SEQUENCE: + case typelib_TypeClass_STRUCT: + case typelib_TypeClass_INTERFACE: + sig.append('i'); + args.push_back(reinterpret_cast<sal_uInt32>(pArgs[i])); + break; + default: + O3TL_UNREACHABLE; + } + } + } + try + { + callVirtualFunction(sig, + (*reinterpret_cast<sal_uInt32 const* const*>( + pThis->pCppI))[aVtableSlot.index], + args.data(), pReturn); + *ppException = nullptr; + } + catch (...) + { + css::uno::RuntimeException TODO("Wasm bridge TODO"); + uno_type_any_construct( + *ppException, &TODO, + cppu::UnoType<css::uno::RuntimeException>::get().getTypeLibType(), + nullptr); + } + } } break; } |