summaryrefslogtreecommitdiff
path: root/bridges/source/cpp_uno/gcc3_linux_aarch64
diff options
context:
space:
mode:
Diffstat (limited to 'bridges/source/cpp_uno/gcc3_linux_aarch64')
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx107
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx21
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.cxx2
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.hxx5
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx329
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx202
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_aarch64/vtablecall.hxx33
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s83
8 files changed, 615 insertions, 167 deletions
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx
index 4a5a1d1b662d..dcd27e95ae30 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.cxx
@@ -1,4 +1,4 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This file is part of the LibreOffice project.
*
@@ -21,6 +21,7 @@
#include <cassert>
#include <cstddef>
+#include <cstdint>
#include <cstring>
#include <typeinfo>
@@ -28,6 +29,7 @@
#include <com/sun/star/uno/RuntimeException.hpp>
#include <com/sun/star/uno/genfunc.h>
+#include <o3tl/string_view.hxx>
#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/ustring.hxx>
@@ -44,7 +46,7 @@
namespace {
OUString toUnoName(char const * name) {
- assert(name != 0);
+ assert(name != nullptr);
OUStringBuffer b;
bool scoped = *name == 'N';
if (scoped) {
@@ -73,7 +75,7 @@ OUString toUnoName(char const * name) {
class Rtti {
public:
- Rtti(): app_(dlopen(0, RTLD_LAZY)) {}
+ Rtti(): app_(dlopen(nullptr, RTLD_LAZY)) {}
~Rtti() { dlclose(app_); }
@@ -93,32 +95,40 @@ std::type_info * Rtti::getRtti(typelib_TypeDescription const & type) {
osl::MutexGuard g(mutex_);
Map::iterator i(map_.find(unoName));
if (i == map_.end()) {
- OStringBuffer b;
- b.append("_ZTIN");
+ OStringBuffer b("_ZTIN");
for (sal_Int32 j = 0; j != -1;) {
OString t(
OUStringToOString(
- unoName.getToken(0, '.', j), RTL_TEXTENCODING_ASCII_US));
- b.append(t.getLength());
- b.append(t);
+ o3tl::getToken(unoName, 0, '.', j), RTL_TEXTENCODING_ASCII_US));
+ b.append(OString::number(t.getLength()) + t);
}
b.append('E');
OString sym(b.makeStringAndClear());
std::type_info * rtti = static_cast<std::type_info *>(
dlsym(app_, sym.getStr()));
- if (rtti == 0) {
- char const * rttiName = sym.getStr() + std::strlen("_ZTI");
+ if (rtti == nullptr) {
+ char const * rttiName = strdup(sym.getStr() + std::strlen("_ZTI"));
+ if (rttiName == nullptr) {
+ throw std::bad_alloc();
+ }
+#if defined MACOSX
+ // For the Apple ARM64 ABI, if the most significant ("non-unique RTTI") bit is set, it
+ // means that the instance of the name is not unique (and thus RTTI equality needs to be
+ // determined by string comparison rather than by pointer comparison):
+ rttiName = reinterpret_cast<char const *>(
+ reinterpret_cast<std::uintptr_t>(rttiName) | 0x8000'0000'0000'0000);
+#endif
assert(type.eTypeClass == typelib_TypeClass_EXCEPTION);
typelib_CompoundTypeDescription const & ctd
= reinterpret_cast<typelib_CompoundTypeDescription const &>(
type);
- if (ctd.pBaseTypeDescription == 0) {
- rtti = new __cxxabiv1::__class_type_info(strdup(rttiName));
+ if (ctd.pBaseTypeDescription == nullptr) {
+ rtti = new __cxxabiv1::__class_type_info(rttiName);
} else {
std::type_info * base = getRtti(
ctd.pBaseTypeDescription->aBase);
rtti = new __cxxabiv1::__si_class_type_info(
- strdup(rttiName),
+ rttiName,
static_cast<__cxxabiv1::__class_type_info *>(base));
}
}
@@ -136,8 +146,8 @@ std::type_info * getRtti(typelib_TypeDescription const & type) {
extern "C" void _GLIBCXX_CDTOR_CALLABI deleteException(void * exception) {
__cxxabiv1::__cxa_exception * header =
static_cast<__cxxabiv1::__cxa_exception *>(exception) - 1;
-#if defined _LIBCPPABI_VERSION // detect libc++abi
- // The libcxxabi commit
+#if !defined MACOSX && defined _LIBCPPABI_VERSION // detect libc++abi
+ // First, the libcxxabi commit
// <http://llvm.org/viewvc/llvm-project?view=revision&revision=303175>
// "[libcxxabi] Align unwindHeader on a double-word boundary" towards
// LLVM 5.0 changed the size of __cxa_exception by adding
@@ -147,21 +157,52 @@ extern "C" void _GLIBCXX_CDTOR_CALLABI deleteException(void * exception) {
// to the final member unwindHeader, on x86-64 effectively adding a hole of
// size 8 in front of that member (changing its offset from 88 to 96,
// sizeof(__cxa_exception) from 120 to 128, and alignof(__cxa_exception)
- // from 8 to 16); a hack to dynamically determine whether we run against a
- // new libcxxabi is to look at the exceptionDestructor member, which must
- // point to this function (the use of __cxa_exception in fillUnoException is
+ // from 8 to 16); the "header1" hack below to dynamically determine whether we run against a
+ // LLVM 5 libcxxabi is to look at the exceptionDestructor member, which must
+ // point to this function (the use of __cxa_exception in mapException is
// unaffected, as it only accesses members towards the start of the struct,
- // through a pointer known to actually point at the start):
+ // through a pointer known to actually point at the start). The libcxxabi commit
+ // <https://github.com/llvm/llvm-project/commit/9ef1daa46edb80c47d0486148c0afc4e0d83ddcf>
+ // "Insert padding before the __cxa_exception header to ensure the thrown" in LLVM 6
+ // removes the need for this hack, so the "header1" hack can be removed again once we can be
+ // sure that we only run against libcxxabi from LLVM >= 6.
+ //
+ // Second, the libcxxabi commit
+ // <https://github.com/llvm/llvm-project/commit/674ec1eb16678b8addc02a4b0534ab383d22fa77>
+ // "[libcxxabi] Insert padding in __cxa_exception struct for compatibility" in LLVM 10 changed
+ // the layout of the start of __cxa_exception to
+ //
+ // [8 byte void *reserve]
+ // 8 byte size_t referenceCount
+ //
+ // so the "header2" hack below to dynamically determine whether we run against a LLVM >= 10
+ // libcxxabi is to look whether the exceptionDestructor (with its known value) has increased its
+ // offset by 8. As described in the definition of __cxa_exception
+ // (bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx), the "header2" hack (together with the
+ // "#ifdef MACOSX" in the definition of __cxa_exception and the corresponding hack in call in
+ // bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx) can be dropped once we can be sure
+ // that we only run against new libcxxabi that has the reserve member.
if (header->exceptionDestructor != &deleteException) {
- header = reinterpret_cast<__cxxabiv1::__cxa_exception *>(
+ auto const header1 = reinterpret_cast<__cxxabiv1::__cxa_exception *>(
reinterpret_cast<char *>(header) - 8);
- assert(header->exceptionDestructor == &deleteException);
+ if (header1->exceptionDestructor == &deleteException) {
+ header = header1;
+ } else {
+ auto const header2 = reinterpret_cast<__cxxabiv1::__cxa_exception *>(
+ reinterpret_cast<char *>(header) + 8);
+ if (header2->exceptionDestructor == &deleteException) {
+ header = header2;
+ } else {
+ assert(false);
+ }
+ }
}
#endif
+ assert(header->exceptionDestructor == &deleteException);
OUString unoName(toUnoName(header->exceptionType->name()));
- typelib_TypeDescription * td = 0;
+ typelib_TypeDescription * td = nullptr;
typelib_typedescription_getByName(&td, unoName.pData);
- assert(td != 0);
+ assert(td != nullptr);
uno_destructData(exception, td, &css::uno::cpp_release);
typelib_typedescription_release(td);
}
@@ -172,7 +213,7 @@ enum StructKind {
};
StructKind getStructKind(typelib_CompoundTypeDescription const * type) {
- StructKind k = type->pBaseTypeDescription == 0
+ StructKind k = type->pBaseTypeDescription == nullptr
? STRUCT_KIND_EMPTY : getStructKind(type->pBaseTypeDescription);
for (sal_Int32 i = 0; i != type->nMembers; ++i) {
StructKind k2 = StructKind();
@@ -204,7 +245,7 @@ StructKind getStructKind(typelib_CompoundTypeDescription const * type) {
break;
case typelib_TypeClass_STRUCT:
{
- typelib_TypeDescription * td = 0;
+ typelib_TypeDescription * td = nullptr;
TYPELIB_DANGER_GET(&td, type->ppTypeRefs[i]);
k2 = getStructKind(
reinterpret_cast<typelib_CompoundTypeDescription const *>(
@@ -247,12 +288,12 @@ namespace abi_aarch64 {
void mapException(
__cxxabiv1::__cxa_exception * exception, std::type_info const * type, uno_Any * any, uno_Mapping * mapping)
{
- assert(exception != 0);
+ assert(exception != nullptr);
assert(type != nullptr);
OUString unoName(toUnoName(type->name()));
- typelib_TypeDescription * td = 0;
+ typelib_TypeDescription * td = nullptr;
typelib_typedescription_getByName(&td, unoName.pData);
- if (td == 0) {
+ if (td == nullptr) {
css::uno::RuntimeException e("exception type not found: " + unoName);
uno_type_any_constructAndConvert(
any, &e,
@@ -265,15 +306,15 @@ void mapException(
}
void raiseException(uno_Any * any, uno_Mapping * mapping) {
- typelib_TypeDescription * td = 0;
+ typelib_TypeDescription * td = nullptr;
TYPELIB_DANGER_GET(&td, any->pType);
- if (td == 0) {
+ if (td == nullptr) {
throw css::uno::RuntimeException(
- "no typedescription for " + OUString(any->pType->pTypeName));
+ "no typedescription for " + OUString::unacquired(&any->pType->pTypeName));
}
void * exc = __cxxabiv1::__cxa_allocate_exception(td->nSize);
uno_copyAndConvertData(exc, any->pData, td, mapping);
- uno_any_destruct(any, 0);
+ uno_any_destruct(any, nullptr);
std::type_info * rtti = getRtti(*td);
TYPELIB_DANGER_RELEASE(td);
__cxxabiv1::__cxa_throw(exc, rtti, deleteException);
@@ -283,7 +324,9 @@ ReturnKind getReturnKind(typelib_TypeDescription const * type) {
switch (type->eTypeClass) {
default:
assert(false);
+#ifdef NDEBUG
[[fallthrough]];
+#endif
case typelib_TypeClass_VOID:
case typelib_TypeClass_BOOLEAN:
case typelib_TypeClass_BYTE:
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx
index e3dc9b5872a7..10495582dcc0 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx
@@ -17,8 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_GCC3_LINUX_AARCH64_ABI_HXX
-#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_GCC3_LINUX_AARCH64_ABI_HXX
+#pragma once
#include <sal/config.h>
@@ -71,6 +70,20 @@ namespace __cxxabiv1 {
struct __cxa_exception {
#if defined _LIBCPPABI_VERSION // detect libc++abi
#if defined __LP64__ || LIBCXXABI_ARM_EHABI
+#ifdef MACOSX // on arm64
+ // This is a new field added with LLVM 10
+ // <https://github.com/llvm/llvm-project/commit/674ec1eb16678b8addc02a4b0534ab383d22fa77>
+ // "[libcxxabi] Insert padding in __cxa_exception struct for compatibility". For non-MACOSX,
+ // the HACK in call (bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx) tries to find out at
+ // runtime whether a __cxa_exception has this member. Once we can be sure that we only run
+ // against new libcxxabi that has this member, we can drop the "#ifdef MACOSX" here and drop the
+ // hack in call.
+
+ // Now _Unwind_Exception is marked with __attribute__((aligned)),
+ // which implies __cxa_exception is also aligned. Insert padding
+ // in the beginning of the struct, rather than before unwindHeader.
+ void *reserve;
+#endif
std::size_t referenceCount;
#endif
#endif
@@ -102,7 +115,7 @@ struct __cxa_eh_globals {
#if !HAVE_CXXABI_H_CXA_GET_GLOBALS
namespace __cxxabiv1 {
-extern "C" __cxa_eh_globals * __cxa_get_globals() throw();
+extern "C" __cxa_eh_globals * __cxa_get_globals() noexcept;
}
#endif
@@ -141,6 +154,4 @@ ReturnKind getReturnKind(typelib_TypeDescription const * type);
}
-#endif
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.cxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.cxx
index ba5194d6f8c8..b944f31cfd2a 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.cxx
@@ -55,7 +55,7 @@ void callVirtualFunction(
"m" (stackargs) // dummy input to prevent optimizing the alloca away
: "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10",
"r11", "r12", "r13", "r14", "r15", "r16", "r17",
-#if !defined ANDROID
+#if !defined ANDROID && !defined MACOSX
"r18"/*TODO?*/,
#endif
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9", "v10", "v11",
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.hxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.hxx
index b1b003f413b9..a8b92785f479 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.hxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/callvirtualfunction.hxx
@@ -17,8 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
-#ifndef INCLUDED_BRIDGES_SOURCE_CPP_UNO_GCC3_LINUX_AARCH64_CALLVIRTUALFUNCTION_HXX
-#define INCLUDED_BRIDGES_SOURCE_CPP_UNO_GCC3_LINUX_AARCH64_CALLVIRTUALFUNCTION_HXX
+#pragma once
#include <sal/config.h>
@@ -28,6 +27,4 @@ void callVirtualFunction(
unsigned long function, unsigned long * gpr, unsigned long * fpr,
unsigned long * stack, sal_Int32 sp, void * ret);
-#endif
-
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx
index f9396321cb14..669c4443c5f0 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx
@@ -24,6 +24,7 @@
#include <cstddef>
#include <cstdlib>
#include <cstring>
+#include <typeinfo>
#include <dlfcn.h>
@@ -41,8 +42,7 @@
#include <vtablefactory.hxx>
#include "abi.hxx"
-
-extern "C" void vtableSlotCall_();
+#include "vtablecall.hxx"
namespace {
@@ -53,16 +53,16 @@ void call(
typelib_MethodParameter * parameters, unsigned long * gpr,
unsigned long * fpr, unsigned long * stack, void * indirectRet)
{
- typelib_TypeDescription * rtd = 0;
- if (returnType != 0) {
+ typelib_TypeDescription * rtd = nullptr;
+ if (returnType != nullptr) {
TYPELIB_DANGER_GET(&rtd, returnType);
}
- abi_aarch64::ReturnKind retKind = rtd == 0
+ abi_aarch64::ReturnKind retKind = rtd == nullptr
? abi_aarch64::RETURN_KIND_REG : abi_aarch64::getReturnKind(rtd);
- bool retConv = rtd != 0
+ bool retConv = rtd != nullptr
&& bridges::cpp_uno::shared::relatesToInterfaceType(rtd);
void * retin = retKind == abi_aarch64::RETURN_KIND_INDIRECT && !retConv
- ? indirectRet : rtd == 0 ? 0 : alloca(rtd->nSize);
+ ? indirectRet : rtd == nullptr ? nullptr : alloca(rtd->nSize);
void ** args = static_cast< void ** >(alloca(count * sizeof (void *)));
void ** cppArgs = static_cast< void ** >(alloca(count * sizeof (void *)));
typelib_TypeDescription ** argtds = static_cast<typelib_TypeDescription **>(
@@ -70,11 +70,142 @@ void call(
sal_Int32 ngpr = 1;
sal_Int32 nfpr = 0;
sal_Int32 sp = 0;
+#ifdef MACOSX
+ sal_Int32 subsp = 0;
+#endif
for (sal_Int32 i = 0; i != count; ++i) {
if (!parameters[i].bOut
&& bridges::cpp_uno::shared::isSimpleType(parameters[i].pTypeRef))
{
switch (parameters[i].pTypeRef->eTypeClass) {
+#ifdef MACOSX
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ if (ngpr < 8)
+ {
+ args[i] = gpr + ngpr;
+ ngpr++;
+ }
+ else
+ {
+ args[i] = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(stack + sp) + subsp);
+ subsp += 1;
+ if (subsp == 8)
+ {
+ sp++;
+ subsp = 0;
+ }
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_CHAR:
+ if (ngpr < 8)
+ {
+ args[i] = gpr + ngpr;
+ ngpr++;
+ }
+ else
+ {
+ subsp = (subsp + 1) & ~0x1;
+ if (subsp == 8)
+ {
+ sp++;
+ subsp = 0;
+ }
+ args[i] = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(stack + sp) + subsp);
+ subsp += 2;
+ if (subsp == 8)
+ {
+ sp++;
+ subsp = 0;
+ }
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ if (ngpr < 8)
+ {
+ args[i] = gpr + ngpr;
+ ngpr++;
+ }
+ else
+ {
+ subsp = (subsp + 3) & ~0x3;
+ if (subsp == 8)
+ {
+ sp++;
+ subsp = 0;
+ }
+ args[i] = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(stack + sp) + subsp);
+ subsp += 4;
+ if (subsp == 8)
+ {
+ sp++;
+ subsp = 0;
+ }
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ if (ngpr < 8)
+ {
+ args[i] = gpr + ngpr;
+ ngpr++;
+ }
+ else
+ {
+ if (subsp > 0)
+ {
+ sp++;
+ subsp = 0;
+ }
+ args[i] = stack + sp;
+ sp++;
+ }
+ break;
+ case typelib_TypeClass_FLOAT:
+ if (nfpr < 8)
+ {
+ args[i] = fpr + nfpr;
+ nfpr++;
+ }
+ else
+ {
+ subsp = (subsp + 3) & ~0x3;
+ if (subsp == 8)
+ {
+ sp++;
+ subsp = 0;
+ }
+ args[i] = reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(stack + sp) + subsp);
+ subsp += 4;
+ if (subsp == 8)
+ {
+ sp++;
+ subsp = 0;
+ }
+ }
+ break;
+ case typelib_TypeClass_DOUBLE:
+ if (nfpr < 8)
+ {
+ args[i] = fpr + nfpr;
+ nfpr++;
+ }
+ else
+ {
+ if (subsp > 0)
+ {
+ sp++;
+ subsp = 0;
+ }
+ args[i] = stack + sp;
+ sp++;
+ }
+ break;
+#else
case typelib_TypeClass_BOOLEAN:
case typelib_TypeClass_BYTE:
case typelib_TypeClass_SHORT:
@@ -91,14 +222,22 @@ void call(
case typelib_TypeClass_DOUBLE:
args[i] = nfpr == 8 ? stack + sp++ : fpr + nfpr++;
break;
+#endif
default:
assert(false);
}
- argtds[i] = 0;
+ argtds[i] = nullptr;
} else {
+#ifdef MACOSX
+ if (subsp > 0)
+ {
+ sp++;
+ subsp = 0;
+ }
+#endif
cppArgs[i] = reinterpret_cast<void *>(
ngpr == 8 ? stack[sp++] : gpr[ngpr++]);
- typelib_TypeDescription * ptd = 0;
+ typelib_TypeDescription * ptd = nullptr;
TYPELIB_DANGER_GET(&ptd, parameters[i].pTypeRef);
if (!parameters[i].bIn) {
args[i] = alloca(ptd->nSize);
@@ -110,7 +249,7 @@ void call(
argtds[i] = ptd;
} else {
args[i] = cppArgs[i];
- argtds[i] = 0;
+ argtds[i] = nullptr;
TYPELIB_DANGER_RELEASE(ptd);
}
}
@@ -119,22 +258,22 @@ void call(
uno_Any * pexc = &exc;
proxy->getUnoI()->pDispatcher(
proxy->getUnoI(), description.get(), retin, args, &pexc);
- if (pexc != 0) {
+ if (pexc != nullptr) {
for (sal_Int32 i = 0; i != count; ++i) {
- if (argtds[i] != 0) {
+ if (argtds[i] != nullptr) {
if (parameters[i].bIn) {
- uno_destructData(args[i], argtds[i], 0);
+ uno_destructData(args[i], argtds[i], nullptr);
}
TYPELIB_DANGER_RELEASE(argtds[i]);
}
}
- if (rtd != 0) {
+ if (rtd != nullptr) {
TYPELIB_DANGER_RELEASE(rtd);
}
abi_aarch64::raiseException(&exc, proxy->getBridge()->getUno2Cpp());
}
for (sal_Int32 i = 0; i != count; ++i) {
- if (argtds[i] != 0) {
+ if (argtds[i] != nullptr) {
if (parameters[i].bOut) {
uno_destructData(
cppArgs[i], argtds[i],
@@ -143,25 +282,53 @@ void call(
cppArgs[i], args[i], argtds[i],
proxy->getBridge()->getUno2Cpp());
}
- uno_destructData(args[i], argtds[i], 0);
+ uno_destructData(args[i], argtds[i], nullptr);
TYPELIB_DANGER_RELEASE(argtds[i]);
}
}
- void * retout = 0; // avoid false -Werror=maybe-uninitialized
+ void * retout = nullptr; // avoid false -Werror=maybe-uninitialized
switch (retKind) {
case abi_aarch64::RETURN_KIND_REG:
- switch (rtd == 0 ? typelib_TypeClass_VOID : rtd->eTypeClass) {
+ switch (rtd == nullptr ? typelib_TypeClass_VOID : rtd->eTypeClass) {
case typelib_TypeClass_VOID:
break;
+#if defined MACOSX
+ case typelib_TypeClass_BOOLEAN:
+ assert(rtd->nSize == sizeof (bool));
+ *gpr = static_cast<unsigned long>(*static_cast<bool *>(retin));
+ assert(!retConv);
+ break;
+ case typelib_TypeClass_BYTE:
+ assert(rtd->nSize == sizeof (sal_Int8));
+ *gpr = *static_cast<sal_Int8 *>(retin);
+ assert(!retConv);
+ break;
+ case typelib_TypeClass_SHORT:
+ assert(rtd->nSize == sizeof (sal_Int16));
+ *gpr = *static_cast<sal_Int16 *>(retin);
+ assert(!retConv);
+ break;
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ assert(rtd->nSize == sizeof (sal_uInt16));
+ *gpr = *static_cast<sal_uInt16 *>(retin);
+ assert(!retConv);
+ break;
+ case typelib_TypeClass_CHAR:
+ assert(rtd->nSize == sizeof (sal_Unicode));
+ *gpr = *static_cast<sal_Unicode *>(retin);
+ assert(!retConv);
+ break;
+#else
case typelib_TypeClass_BOOLEAN:
case typelib_TypeClass_BYTE:
case typelib_TypeClass_SHORT:
case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_CHAR:
+#endif
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
- case typelib_TypeClass_CHAR:
case typelib_TypeClass_ENUM:
std::memcpy(gpr, retin, rtd->nSize);
assert(!retConv);
@@ -183,7 +350,7 @@ void call(
}
break;
case abi_aarch64::RETURN_KIND_HFA_FLOAT:
- assert(rtd != 0);
+ assert(rtd != nullptr);
switch (rtd->nSize) {
case 16:
std::memcpy(fpr + 3, static_cast<char *>(retin) + 12, 4);
@@ -203,7 +370,7 @@ void call(
assert(!retConv);
break;
case abi_aarch64::RETURN_KIND_HFA_DOUBLE:
- assert(rtd != 0);
+ assert(rtd != nullptr);
std::memcpy(fpr, retin, rtd->nSize);
assert(!retConv);
break;
@@ -214,14 +381,16 @@ void call(
if (retConv) {
uno_copyAndConvertData(
retout, retin, rtd, proxy->getBridge()->getUno2Cpp());
- uno_destructData(retin, rtd, 0);
+ uno_destructData(retin, rtd, nullptr);
}
- if (rtd != 0) {
+ if (rtd != nullptr) {
TYPELIB_DANGER_RELEASE(rtd);
}
}
-extern "C" void vtableCall(
+}
+
+void vtableCall(
sal_Int32 functionIndex, sal_Int32 vtableOffset,
unsigned long * gpr, unsigned long * fpr, unsigned long * stack,
void * indirectRet)
@@ -241,15 +410,15 @@ extern "C" void vtableCall(
proxy, desc,
reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>(
desc.get())->pAttributeTypeRef,
- 0, 0, gpr, fpr, stack, indirectRet);
+ 0, nullptr, gpr, fpr, stack, indirectRet);
} else {
// Setter:
typelib_MethodParameter param = {
- 0,
+ nullptr,
reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>(
desc.get())->pAttributeTypeRef,
true, false };
- call(proxy, desc, 0, 1, &param, gpr, fpr, stack, indirectRet);
+ call(proxy, desc, nullptr, 1, &param, gpr, fpr, stack, indirectRet);
}
break;
case typelib_TypeClass_INTERFACE_METHOD:
@@ -262,21 +431,21 @@ extern "C" void vtableCall(
break;
case 0:
{
- typelib_TypeDescription * td = 0;
+ typelib_TypeDescription * td = nullptr;
TYPELIB_DANGER_GET(
&td,
(reinterpret_cast<css::uno::Type *>(gpr[1])
->getTypeLibType()));
- if (td != 0 && td->eTypeClass == typelib_TypeClass_INTERFACE) {
- css::uno::XInterface * ifc = 0;
+ if (td != nullptr && td->eTypeClass == typelib_TypeClass_INTERFACE) {
+ css::uno::XInterface * ifc = nullptr;
proxy->getBridge()->getCppEnv()->getRegisteredInterface(
proxy->getBridge()->getCppEnv(),
reinterpret_cast<void **>(&ifc), proxy->getOid().pData,
reinterpret_cast<typelib_InterfaceTypeDescription *>(
td));
- if (ifc != 0) {
+ if (ifc != nullptr) {
uno_any_construct(
- reinterpret_cast<uno_Any *>(indirectRet), &ifc, td,
+ static_cast<uno_Any *>(indirectRet), &ifc, td,
reinterpret_cast<uno_AcquireFunc>(
css::uno::cpp_acquire));
ifc->release();
@@ -304,63 +473,7 @@ extern "C" void vtableCall(
}
}
-struct aarch64_va_list {
- void * stack;
- void * gr_top;
- void * vr_top;
- int gr_offs;
- int vr_offs;
-};
-
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wuninitialized"
-#pragma GCC diagnostic ignored "-Wvolatile-register-var"
-extern "C" void vtableSlotCall(
- unsigned long gpr0, unsigned long gpr1, unsigned long gpr2,
- unsigned long gpr3, unsigned long gpr4, unsigned long gpr5,
- unsigned long gpr6, unsigned long gpr7, double fpr0, double fpr1,
- double fpr2, double fpr3, double fpr4, double fpr5, double fpr6,
- double fpr7, ...)
-{
- register void * volatile indirectRet asm ("x8");
- register sal_Int32 volatile functionIndex asm ("x9");
- register sal_Int32 volatile vtableOffset asm ("x10");
- va_list ap;
- va_start(ap, fpr7);
- assert(sizeof (va_list) == sizeof (aarch64_va_list));
- unsigned long gpr[8];
- gpr[0] = gpr0;
- gpr[1] = gpr1;
- gpr[2] = gpr2;
- gpr[3] = gpr3;
- gpr[4] = gpr4;
- gpr[5] = gpr5;
- gpr[6] = gpr6;
- gpr[7] = gpr7;
- double fpr[8];
- fpr[0] = fpr0;
- fpr[1] = fpr1;
- fpr[2] = fpr2;
- fpr[3] = fpr3;
- fpr[4] = fpr4;
- fpr[5] = fpr5;
- fpr[6] = fpr6;
- fpr[7] = fpr7;
- vtableCall(
- functionIndex, vtableOffset, gpr,
- reinterpret_cast<unsigned long *>(fpr),
- static_cast<unsigned long *>(
- reinterpret_cast<aarch64_va_list *>(&ap)->stack),
- indirectRet);
- asm volatile(
- "ldp x0, x1, [%[gpr_]]\n\t"
- "ldp d0, d1, [%[fpr_]]\n\t"
- "ldp d2, d3, [%[fpr_], #16]\n\t"
- :: [gpr_]"r" (gpr), [fpr_]"r" (fpr)
- : "r0", "r1", "v0", "v1", "v2", "v3");
- va_end(ap);
-}
-#pragma GCC diagnostic pop
+namespace {
std::size_t const codeSnippetSize = 8 * 4;
@@ -390,7 +503,7 @@ unsigned char * generateCodeSnippet(
}
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void const * fn; };
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block) {
@@ -403,28 +516,40 @@ std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
}
+namespace {
+// Some dummy type whose RTTI is used in the synthesized proxy vtables to make uses of dynamic_cast
+// on such proxy objects not crash:
+struct ProxyRtti {};
+}
+
bridges::cpp_uno::shared::VtableFactory::Slot *
bridges::cpp_uno::shared::VtableFactory::initializeBlock(
void * block, sal_Int32 slotCount, sal_Int32,
typelib_InterfaceTypeDescription *)
{
Slot * slots = mapBlockToVtable(block);
- slots[-2].fn = 0;
- slots[-1].fn = 0;
+ slots[-2].fn = nullptr;
+ slots[-1].fn = &typeid(ProxyRtti);
return slots + slotCount;
}
unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
- Slot ** slots, unsigned char * code, sal_PtrDiff writetoexecdiff,
+ Slot ** slots, unsigned char * code,
+#ifdef USE_DOUBLE_MMAP
+ sal_PtrDiff writetoexecdiff,
+#endif
typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
sal_Int32 functionCount, sal_Int32 vtableOffset)
{
+#ifndef USE_DOUBLE_MMAP
+ constexpr sal_PtrDiff writetoexecdiff = 0;
+#endif
(*slots) -= functionCount;
Slot * s = *slots;
for (sal_Int32 i = 0; i != type->nMembers; ++i) {
- typelib_TypeDescription * td = 0;
+ typelib_TypeDescription * td = nullptr;
TYPELIB_DANGER_GET(&td, type->ppMembers[i]);
- assert(td != 0);
+ assert(td != nullptr);
switch (td->eTypeClass) {
case typelib_TypeClass_INTERFACE_ATTRIBUTE:
{
@@ -458,13 +583,23 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
void bridges::cpp_uno::shared::VtableFactory::flushCode(
unsigned char const * begin, unsigned char const * end)
{
-#ifndef ANDROID
+#if !defined ANDROID && !defined MACOSX
static void (*clear_cache)(unsigned char const *, unsigned char const *)
= (void (*)(unsigned char const *, unsigned char const *)) dlsym(
RTLD_DEFAULT, "__clear_cache");
(*clear_cache)(begin, end);
#else
- __builtin___clear_cache((char*)begin, (char*)end);
+ // GCC clarified with
+ // <http://gcc.gnu.org/git/?p=gcc.git;a=commit;h=a90b0cdd444f6dde1084a439862cf507f6d3b2ae>
+ // "extend.texi (__clear_cache): Correct signature" that __builtin___clear_cache takes void*
+ // parameters, while Clang uses char* ever since
+ // <https://github.com/llvm/llvm-project/commit/c491a8d4577052bc6b3b4c72a7db6a7cfcbc2ed0> "Add
+ // support for __builtin___clear_cache in Clang" (TODO: see
+ // <https://bugs.llvm.org/show_bug.cgi?id=48489> "__builtin___clear_cache() has a different
+ // prototype than GCC"; once fixed for our Clang baseline, we can drop the reinterpret_casts):
+ __builtin___clear_cache(
+ reinterpret_cast<char *>(const_cast<unsigned char *>(begin)),
+ reinterpret_cast<char *>(const_cast<unsigned char *>(end)));
#endif
}
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx
index d1928942eb06..57beb6dfa106 100644
--- a/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx
@@ -46,10 +46,82 @@
namespace {
void pushArgument(
- unsigned long value, unsigned long * stack, sal_Int32 * sp,
- unsigned long * regs, sal_Int32 * nregs)
+#ifdef MACOSX
+ typelib_TypeClass typeclass,
+ sal_Int32 * const subsp,
+#endif
+ unsigned long value, unsigned long * const stack, sal_Int32 * const sp,
+ unsigned long * const regs, sal_Int32 * const nregs)
{
+#ifdef MACOSX
+ if (*nregs != 8)
+ {
+ regs[(*nregs)++] = value;
+ }
+ else
+ {
+ switch (typeclass) {
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ *reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(stack + *sp) + *subsp) = value;
+ (*subsp) += 1;
+ if (*subsp == 8)
+ {
+ (*sp)++;
+ *subsp = 0;
+ }
+ break;
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_CHAR:
+ *subsp = (*subsp + 1) & ~0x1;
+ if (*subsp == 8)
+ {
+ (*sp)++;
+ *subsp = 0;
+ }
+ *reinterpret_cast<uint16_t*>(reinterpret_cast<uintptr_t>(stack + *sp) + *subsp) = value;
+ (*subsp) += 2;
+ if (*subsp == 8)
+ {
+ (*sp)++;
+ *subsp = 0;
+ }
+ break;
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_ENUM:
+ case typelib_TypeClass_FLOAT:
+ *subsp = (*subsp + 3) & ~0x3;
+ if (*subsp == 8)
+ {
+ (*sp)++;
+ *subsp = 0;
+ }
+ *reinterpret_cast<uint32_t*>(reinterpret_cast<uintptr_t>(stack + *sp) + *subsp) = value;
+ (*subsp) += 4;
+ if (*subsp == 8)
+ {
+ (*sp)++;
+ *subsp = 0;
+ }
+ break;
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ default:
+ if (*subsp > 0)
+ {
+ (*sp)++;
+ *subsp = 0;
+ }
+ stack[*sp] = value;
+ (*sp)++;
+ break;
+ }
+ }
+#else
(*nregs != 8 ? regs[(*nregs)++] : stack[(*sp)++]) = value;
+#endif
}
void call(
@@ -59,7 +131,7 @@ void call(
typelib_MethodParameter * parameters, void * returnValue, void ** arguments,
uno_Any ** exception)
{
- typelib_TypeDescription * rtd = 0;
+ typelib_TypeDescription * rtd = nullptr;
TYPELIB_DANGER_GET(&rtd, returnType);
abi_aarch64::ReturnKind retKind = abi_aarch64::getReturnKind(rtd);
bool retConv = bridges::cpp_uno::shared::relatesToInterfaceType(rtd);
@@ -69,6 +141,9 @@ void call(
unsigned long * stack = static_cast<unsigned long *>(
alloca(count * sizeof (unsigned long)));
sal_Int32 sp = 0;
+#ifdef MACOSX
+ sal_Int32 subsp = 0;
+#endif
unsigned long gpr[8];
sal_Int32 ngpr = 0;
unsigned long fpr[8];
@@ -82,61 +157,94 @@ void call(
if (!parameters[i].bOut &&
bridges::cpp_uno::shared::isSimpleType(parameters[i].pTypeRef))
{
- cppArgs[i] = 0;
+ cppArgs[i] = nullptr;
switch (parameters[i].pTypeRef->eTypeClass) {
case typelib_TypeClass_BOOLEAN:
pushArgument(
- *static_cast<sal_Bool *>(arguments[i]), stack, &sp, gpr,
- &ngpr);
+#ifdef MACOSX
+ parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
+ static_cast<unsigned long>(*static_cast<sal_Bool *>(arguments[i])), stack, &sp,
+ gpr, &ngpr);
break;
case typelib_TypeClass_BYTE:
pushArgument(
+#ifdef MACOSX
+ parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
*static_cast<sal_Int8 *>(arguments[i]), stack, &sp, gpr,
&ngpr);
break;
case typelib_TypeClass_SHORT:
pushArgument(
+#ifdef MACOSX
+ parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
*static_cast<sal_Int16 *>(arguments[i]), stack, &sp, gpr,
&ngpr);
break;
case typelib_TypeClass_UNSIGNED_SHORT:
pushArgument(
+#ifdef MACOSX
+ parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
*static_cast<sal_uInt16 *>(arguments[i]), stack, &sp, gpr,
&ngpr);
break;
case typelib_TypeClass_LONG:
case typelib_TypeClass_ENUM:
pushArgument(
+#ifdef MACOSX
+ parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
*static_cast<sal_Int32 *>(arguments[i]), stack, &sp, gpr,
&ngpr);
break;
case typelib_TypeClass_UNSIGNED_LONG:
pushArgument(
+#ifdef MACOSX
+ parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
*static_cast<sal_uInt32 *>(arguments[i]), stack, &sp, gpr,
&ngpr);
break;
case typelib_TypeClass_HYPER:
pushArgument(
+#ifdef MACOSX
+ parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
*static_cast<sal_Int64 *>(arguments[i]), stack, &sp, gpr,
&ngpr);
break;
case typelib_TypeClass_UNSIGNED_HYPER:
pushArgument(
+#ifdef MACOSX
+ parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
*static_cast<sal_uInt64 *>(arguments[i]), stack, &sp, gpr,
&ngpr);
break;
case typelib_TypeClass_FLOAT:
pushArgument(
+#ifdef MACOSX
+ parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
*static_cast<unsigned int *>(arguments[i]), stack, &sp, fpr,
&nfpr);
break;
case typelib_TypeClass_DOUBLE:
pushArgument(
+#ifdef MACOSX
+ parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
*static_cast<unsigned long *>(arguments[i]), stack, &sp,
fpr, &nfpr);
break;
case typelib_TypeClass_CHAR:
pushArgument(
+#ifdef MACOSX
+ parameters[i].pTypeRef->eTypeClass, &subsp,
+#endif
*static_cast<sal_Unicode *>(arguments[i]), stack, &sp, gpr,
&ngpr);
break;
@@ -144,13 +252,16 @@ void call(
assert(false);
}
} else {
- typelib_TypeDescription * ptd = 0;
+ typelib_TypeDescription * ptd = nullptr;
TYPELIB_DANGER_GET(&ptd, parameters[i].pTypeRef);
if (!parameters[i].bIn) {
cppArgs[i] = alloca(ptd->nSize);
uno_constructData(cppArgs[i], ptd);
ptds[i] = ptd;
pushArgument(
+#ifdef MACOSX
+ typelib_TypeClass_HYPER, &subsp,
+#endif
reinterpret_cast<unsigned long>(cppArgs[i]), stack, &sp,
gpr, &ngpr);
} else if (bridges::cpp_uno::shared::relatesToInterfaceType(ptd)) {
@@ -160,11 +271,17 @@ void call(
proxy->getBridge()->getUno2Cpp());
ptds[i] = ptd;
pushArgument(
+#ifdef MACOSX
+ typelib_TypeClass_HYPER, &subsp,
+#endif
reinterpret_cast<unsigned long>(cppArgs[i]), stack, &sp,
gpr, &ngpr);
} else {
- cppArgs[i] = 0;
+ cppArgs[i] = nullptr;
pushArgument(
+#ifdef MACOSX
+ typelib_TypeClass_HYPER, &subsp,
+#endif
reinterpret_cast<unsigned long>(arguments[i]), stack, &sp,
gpr, &ngpr);
TYPELIB_DANGER_RELEASE(ptd);
@@ -187,13 +304,42 @@ void call(
"C++ code threw unknown exception");
}
} catch (css::uno::Exception &) {
+ __cxxabiv1::__cxa_exception * header = reinterpret_cast<__cxxabiv1::__cxa_eh_globals *>(
+ __cxxabiv1::__cxa_get_globals())->caughtExceptions;
+#if !defined MACOSX && defined _LIBCPPABI_VERSION // detect libc++abi
+ // Very bad HACK to find out whether we run against a libcxxabi that has a new
+ // __cxa_exception::reserved member at the start, introduced with LLVM 10
+ // <https://github.com/llvm/llvm-project/commit/674ec1eb16678b8addc02a4b0534ab383d22fa77>
+ // "[libcxxabi] Insert padding in __cxa_exception struct for compatibility". The layout of
+ // the start of __cxa_exception is
+ //
+ // [8 byte void *reserve]
+ // 8 byte size_t referenceCount
+ //
+ // where the (bad, hacky) assumption is that reserve (if present) is null
+ // (__cxa_allocate_exception in at least LLVM 11 zero-fills the object, and nothing actively
+ // sets reserve) while referenceCount is non-null (__cxa_throw sets it to 1, and
+ // __cxa_decrement_exception_refcount destroys the exception as soon as it drops to 0; for a
+ // __cxa_dependent_exception, the referenceCount member is rather
+ //
+ // 8 byte void* primaryException
+ //
+ // but which also will always be set to a non-null value in
+ // __cxa_rethrow_primary_exception). As described in the definition of __cxa_exception
+ // (bridges/source/cpp_uno/gcc3_linux_aarch64/abi.hxx), this hack (together with the
+ // "#ifdef MACOSX" there) can be dropped once we can be sure that we only run against new
+ // libcxxabi that has the reserve member:
+ if (*reinterpret_cast<void **>(header) == nullptr) {
+ header = reinterpret_cast<__cxxabiv1::__cxa_exception*>(
+ reinterpret_cast<void **>(header) + 1);
+ }
+#endif
abi_aarch64::mapException(
- reinterpret_cast<__cxxabiv1::__cxa_eh_globals *>(
- __cxxabiv1::__cxa_get_globals())->caughtExceptions,
+ header,
__cxxabiv1::__cxa_current_exception_type(), *exception,
proxy->getBridge()->getCpp2Uno());
for (sal_Int32 i = 0; i != count; ++i) {
- if (cppArgs[i] != 0) {
+ if (cppArgs[i] != nullptr) {
uno_destructData(
cppArgs[i], ptds[i],
reinterpret_cast<uno_ReleaseFunc>(css::uno::cpp_release));
@@ -203,12 +349,12 @@ void call(
TYPELIB_DANGER_RELEASE(rtd);
return;
}
- *exception = 0;
+ *exception = nullptr;
for (sal_Int32 i = 0; i != count; ++i) {
- if (cppArgs[i] != 0) {
+ if (cppArgs[i] != nullptr) {
if (parameters[i].bOut) {
if (parameters[i].bIn) {
- uno_destructData(arguments[i], ptds[i], 0);
+ uno_destructData(arguments[i], ptds[i], nullptr);
}
uno_copyAndConvertData(
arguments[i], cppArgs[i], ptds[i],
@@ -296,14 +442,14 @@ void unoInterfaceProxyDispatch(
typelib_InterfaceAttributeTypeDescription const *>(
pMemberDescr);
VtableSlot slot(getVtableSlot(atd));
- if (pReturn != 0) { // getter
+ if (pReturn != nullptr) { // getter
call(
- proxy, slot, atd->pAttributeTypeRef, 0, 0, pReturn, pArgs,
+ proxy, slot, atd->pAttributeTypeRef, 0, nullptr, pReturn, pArgs,
ppException);
} else { // setter
typelib_MethodParameter param = {
- 0, atd->pAttributeTypeRef, true, false };
- typelib_TypeDescriptionReference * rtd = 0;
+ nullptr, atd->pAttributeTypeRef, true, false };
+ typelib_TypeDescriptionReference * rtd = nullptr;
typelib_typedescriptionreference_new(
&rtd, typelib_TypeClass_VOID, OUString("void").pData);
slot.index += 1;
@@ -322,33 +468,33 @@ void unoInterfaceProxyDispatch(
switch (slot.index) {
case 1:
pUnoI->acquire(pUnoI);
- *ppException = 0;
+ *ppException = nullptr;
break;
case 2:
pUnoI->release(pUnoI);
- *ppException = 0;
+ *ppException = nullptr;
break;
case 0:
{
- typelib_TypeDescription * td = 0;
+ typelib_TypeDescription * td = nullptr;
TYPELIB_DANGER_GET(
&td,
- (reinterpret_cast<css::uno::Type *>(pArgs[0])
+ (static_cast<css::uno::Type *>(pArgs[0])
->getTypeLibType()));
- if (td != 0) {
- uno_Interface * ifc = 0;
+ if (td != nullptr) {
+ uno_Interface * ifc = nullptr;
proxy->pBridge->getUnoEnv()->getRegisteredInterface(
proxy->pBridge->getUnoEnv(),
reinterpret_cast<void **>(&ifc), proxy->oid.pData,
reinterpret_cast<
typelib_InterfaceTypeDescription *>(td));
- if (ifc != 0) {
+ if (ifc != nullptr) {
uno_any_construct(
- reinterpret_cast<uno_Any *>(pReturn), &ifc, td,
- 0);
+ static_cast<uno_Any *>(pReturn), &ifc, td,
+ nullptr);
ifc->release(ifc);
TYPELIB_DANGER_RELEASE(td);
- *ppException = 0;
+ *ppException = nullptr;
break;
}
TYPELIB_DANGER_RELEASE(td);
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/vtablecall.hxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/vtablecall.hxx
new file mode 100644
index 000000000000..6ec92687c4ae
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/vtablecall.hxx
@@ -0,0 +1,33 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <sal/types.h>
+
+extern "C" {
+void vtableCall(sal_Int32 functionIndex, sal_Int32 vtableOffset, unsigned long* gpr,
+ unsigned long* fpr, unsigned long* stack, void* indirectRet);
+
+void vtableSlotCall();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s b/bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s
new file mode 100644
index 000000000000..60bdb4c9cf4e
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/vtableslotcall.s
@@ -0,0 +1,83 @@
+/* -*- tab-width: 4; indent-tabs-mode: nil; 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+ .arch armv8-a
+ .text
+ .align 2
+#ifndef __APPLE__
+ .global vtableSlotCall
+ .hidden vtableSlotCall
+ .type vtableSlotCall, %function
+vtableSlotCall:
+#else
+ .global _vtableSlotCall
+_vtableSlotCall:
+#endif
+ .cfi_startproc
+ stp x29, x30, [sp, -192]!
+ .cfi_def_cfa_offset 192
+ .cfi_offset 29, -192
+ .cfi_offset 30, -184
+ add x11, sp, 192
+ mov x29, sp
+ stp x19, x20, [sp, 16]
+ .cfi_offset 19, -176
+ .cfi_offset 20, -168
+ add x20, sp, 128
+ add x19, sp, 64
+ stp x11, x11, [sp, 32]
+ str x11, [sp, 48]
+ stp wzr, wzr, [sp, 56]
+ stp x0, x1, [sp, 64]
+ mov w0, w9
+ mov w1, w10
+ stp x2, x3, [sp, 80]
+ mov x3, x20
+ mov x2, x19
+ stp x4, x5, [sp, 96]
+ mov x5, x8
+ mov x4, x11
+ stp x6, x7, [sp, 112]
+ stp d0, d1, [sp, 128]
+ stp d2, d3, [sp, 144]
+ stp d4, d5, [sp, 160]
+ stp d6, d7, [sp, 176]
+#ifndef __APPLE__
+ bl vtableCall
+#else
+ bl _vtableCall
+#endif
+ ldp x0, x1, [x19]
+ ldp d0, d1, [x20]
+ ldp d2, d3, [x20, #16]
+ ldp x19, x20, [sp, 16]
+ ldp x29, x30, [sp], 192
+ .cfi_restore 30
+ .cfi_restore 29
+ .cfi_restore 19
+ .cfi_restore 20
+ .cfi_def_cfa_offset 0
+ ret
+ .cfi_endproc
+#ifndef __APPLE__
+ .size vtableSlotCall, .-vtableSlotCall
+ .section .note.GNU-stack, "", @progbits
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab */