From a30f92e1006204a94e7d4410b4a4fe53ba9e531e Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Tue, 9 Sep 2025 14:02:56 +1000 Subject: [PATCH] [orc-rt] Add SPS serialization for WrapperFunctionBuffer. Also adds orc_rt_WrapperFunctionBufferConstData to the C API to get a constant pointer to a wrapper function buffer's data. --- orc-rt/include/CMakeLists.txt | 1 + orc-rt/include/orc-rt-c/WrapperFunction.h | 7 +++ .../include/orc-rt/SPSWrapperFunctionBuffer.h | 48 +++++++++++++++++++ orc-rt/include/orc-rt/WrapperFunction.h | 3 ++ orc-rt/unittests/CMakeLists.txt | 1 + .../SPSWrapperFunctionBufferTest.cpp | 42 ++++++++++++++++ .../SimplePackedSerializationTestUtils.h | 7 +-- 7 files changed, 106 insertions(+), 3 deletions(-) create mode 100644 orc-rt/include/orc-rt/SPSWrapperFunctionBuffer.h create mode 100644 orc-rt/unittests/SPSWrapperFunctionBufferTest.cpp diff --git a/orc-rt/include/CMakeLists.txt b/orc-rt/include/CMakeLists.txt index 17a24aa02e2f6..dfe764976d7eb 100644 --- a/orc-rt/include/CMakeLists.txt +++ b/orc-rt/include/CMakeLists.txt @@ -19,6 +19,7 @@ set(ORC_RT_HEADERS orc-rt/SPSAllocAction.h orc-rt/SPSMemoryFlags.h orc-rt/SPSWrapperFunction.h + orc-rt/SPSWrapperFunctionBuffer.h orc-rt/bind.h orc-rt/bit.h orc-rt/move_only_function.h diff --git a/orc-rt/include/orc-rt-c/WrapperFunction.h b/orc-rt/include/orc-rt-c/WrapperFunction.h index 34bcdeffef9ee..280e513c9c0e6 100644 --- a/orc-rt/include/orc-rt-c/WrapperFunction.h +++ b/orc-rt/include/orc-rt-c/WrapperFunction.h @@ -160,6 +160,13 @@ orc_rt_WrapperFunctionBufferData(orc_rt_WrapperFunctionBuffer *B) { return B->Size > sizeof(B->Data.Value) ? B->Data.ValuePtr : B->Data.Value; } +static inline const char * +orc_rt_WrapperFunctionBufferConstData(const orc_rt_WrapperFunctionBuffer *B) { + assert((B->Size != 0 || B->Data.ValuePtr == NULL) && + "Cannot get data for out-of-band error value"); + return B->Size > sizeof(B->Data.Value) ? B->Data.ValuePtr : B->Data.Value; +} + /** * Safely get the size of the given orc_rt_WrapperFunctionBuffer. * diff --git a/orc-rt/include/orc-rt/SPSWrapperFunctionBuffer.h b/orc-rt/include/orc-rt/SPSWrapperFunctionBuffer.h new file mode 100644 index 0000000000000..5799c386fee47 --- /dev/null +++ b/orc-rt/include/orc-rt/SPSWrapperFunctionBuffer.h @@ -0,0 +1,48 @@ +//===-- SPSWrapperFunctionBuffer.h - SPS serialization for WFB --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// SPS serialization for WrapperFunctionBuffer. +// +//===----------------------------------------------------------------------===// + +#ifndef ORC_RT_SPSWRAPPERFUNCTIONBUFFER_H +#define ORC_RT_SPSWRAPPERFUNCTIONBUFFER_H + +#include "orc-rt/SimplePackedSerialization.h" +#include "orc-rt/WrapperFunction.h" + +namespace orc_rt { + +struct SPSWrapperFunctionBuffer; + +template <> +class SPSSerializationTraits { +public: + static size_t size(const WrapperFunctionBuffer &WFB) { + return SPSArgList::size(static_cast(WFB.size())) + + WFB.size(); + } + + static bool serialize(SPSOutputBuffer &OB, const WrapperFunctionBuffer &WFB) { + if (!SPSArgList::serialize(OB, static_cast(WFB.size()))) + return false; + return OB.write(WFB.data(), WFB.size()); + } + + static bool deserialize(SPSInputBuffer &IB, WrapperFunctionBuffer &WFB) { + uint64_t Size; + if (!SPSArgList::deserialize(IB, Size)) + return false; + WFB = WrapperFunctionBuffer::allocate(Size); + return IB.read(WFB.data(), WFB.size()); + } +}; + +} // namespace orc_rt + +#endif // ORC_RT_SPSWRAPPERFUNCTIONBUFFER_H diff --git a/orc-rt/include/orc-rt/WrapperFunction.h b/orc-rt/include/orc-rt/WrapperFunction.h index 24b149cbe15f3..46434834bd5c2 100644 --- a/orc-rt/include/orc-rt/WrapperFunction.h +++ b/orc-rt/include/orc-rt/WrapperFunction.h @@ -62,6 +62,9 @@ class WrapperFunctionBuffer { /// Get a pointer to the data contained in this instance. char *data() { return orc_rt_WrapperFunctionBufferData(&B); } + /// Get a pointer to the data contained is this instance. + const char *data() const { return orc_rt_WrapperFunctionBufferConstData(&B); } + /// Returns the size of the data contained in this instance. size_t size() const { return orc_rt_WrapperFunctionBufferSize(&B); } diff --git a/orc-rt/unittests/CMakeLists.txt b/orc-rt/unittests/CMakeLists.txt index 54430587dd27b..ca501e69034bf 100644 --- a/orc-rt/unittests/CMakeLists.txt +++ b/orc-rt/unittests/CMakeLists.txt @@ -26,6 +26,7 @@ add_orc_rt_unittest(CoreTests SimplePackedSerializationTest.cpp SPSMemoryFlagsTest.cpp SPSWrapperFunctionTest.cpp + SPSWrapperFunctionBufferTest.cpp WrapperFunctionBufferTest.cpp bind-test.cpp bit-test.cpp diff --git a/orc-rt/unittests/SPSWrapperFunctionBufferTest.cpp b/orc-rt/unittests/SPSWrapperFunctionBufferTest.cpp new file mode 100644 index 0000000000000..99b72b84ca796 --- /dev/null +++ b/orc-rt/unittests/SPSWrapperFunctionBufferTest.cpp @@ -0,0 +1,42 @@ +//===-- SPSWrapperFunctionBufferTest.cpp ----------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Test SPS serialization for WrapperFunctionBuffers. +// +//===----------------------------------------------------------------------===// + +#include "orc-rt/SPSWrapperFunctionBuffer.h" + +#include "SimplePackedSerializationTestUtils.h" +#include "gtest/gtest.h" + +using namespace orc_rt; + +static bool WFBEQ(const WrapperFunctionBuffer &LHS, + const WrapperFunctionBuffer &RHS) { + if (LHS.size() != RHS.size()) + return false; + return memcmp(LHS.data(), RHS.data(), LHS.size()) == 0; +} + +TEST(SPSWrapperFunctionBufferTest, EmptyBuffer) { + WrapperFunctionBuffer EB; + blobSerializationRoundTrip(EB, WFBEQ); +} + +TEST(SPSWrapperFunctionBufferTest, SmallBuffer) { + const char *Source = "foo"; + auto EB = WrapperFunctionBuffer::copyFrom(Source); + blobSerializationRoundTrip(EB, WFBEQ); +} + +TEST(SPSWrapperFunctionBufferTest, BigBuffer) { + const char *Source = "The quick brown fox jumps over the lazy dog"; + auto EB = WrapperFunctionBuffer::copyFrom(Source); + blobSerializationRoundTrip(EB, WFBEQ); +} diff --git a/orc-rt/unittests/SimplePackedSerializationTestUtils.h b/orc-rt/unittests/SimplePackedSerializationTestUtils.h index 7bfa37b6d4bda..bf53ec137fe94 100644 --- a/orc-rt/unittests/SimplePackedSerializationTestUtils.h +++ b/orc-rt/unittests/SimplePackedSerializationTestUtils.h @@ -31,8 +31,9 @@ static bool spsDeserialize(orc_rt::WrapperFunctionBuffer &B, ArgTs &...Args) { return SPSTraitsT::deserialize(IB, Args...); } -template -static inline void blobSerializationRoundTrip(const T &Value) { +template > +static inline void blobSerializationRoundTrip(const T &Value, + Comparator &&C = Comparator()) { using BST = orc_rt::SPSSerializationTraits; size_t Size = BST::size(Value); @@ -46,7 +47,7 @@ static inline void blobSerializationRoundTrip(const T &Value) { T DSValue; EXPECT_TRUE(BST::deserialize(IB, DSValue)); - EXPECT_EQ(Value, DSValue) + EXPECT_TRUE(C(Value, DSValue)) << "Incorrect value after serialization/deserialization round-trip"; }