[orc-rt] Add SPSExecutorAddr <-> T* serialization. (#162992)

This replaces SPS transparent conversion for pointers. Transparent
conversion only applies to argument/return types, not nested types. We
want to be able to serialize / deserialize structs containing pointers.

We may need to replace this in the near future with a new SPSPointer tag
type, since SPSExecutorAddr is meant to be serialization for pure
addresses, and pointers may carry other information (e.g. tag bits), but
we can do that in a follow-up commit.
This commit is contained in:
Lang Hames
2025-10-11 22:24:03 +11:00
committed by GitHub
parent 24ac5066dd
commit 28b3f2f04b
4 changed files with 26 additions and 77 deletions

View File

@@ -42,12 +42,6 @@ private:
static T &&from(T &&Arg) noexcept { return std::forward<T>(Arg); }
};
template <typename T> struct Serializable<T *> {
typedef ExecutorAddr serializable_type;
static ExecutorAddr to(T *Arg) { return ExecutorAddr::fromPtr(Arg); }
static T *from(ExecutorAddr A) { return A.toPtr<T *>(); }
};
template <> struct Serializable<Error> {
typedef SPSSerializableError serializable_type;
static SPSSerializableError to(Error Err) {
@@ -66,21 +60,6 @@ private:
}
};
template <typename T> struct Serializable<Expected<T *>> {
typedef SPSSerializableExpected<ExecutorAddr> serializable_type;
static SPSSerializableExpected<ExecutorAddr> to(Expected<T *> Val) {
return SPSSerializableExpected<ExecutorAddr>(
Val ? Expected<ExecutorAddr>(ExecutorAddr::fromPtr(*Val))
: Expected<ExecutorAddr>(Val.takeError()));
}
static Expected<T *> from(SPSSerializableExpected<ExecutorAddr> Val) {
if (auto Tmp = Val.toExpected())
return Tmp->toPtr<T *>();
else
return Tmp.takeError();
}
};
template <typename... Ts> struct DeserializableTuple;
template <typename... Ts> struct DeserializableTuple<std::tuple<Ts...>> {

View File

@@ -556,6 +556,26 @@ public:
}
};
/// Allow SPSExectorAddr serialization to/from T*.
template <typename T> class SPSSerializationTraits<SPSExecutorAddr, T *> {
public:
static size_t size(T *const &P) {
return SPSArgList<SPSExecutorAddr>::size(ExecutorAddr::fromPtr(P));
}
static bool serialize(SPSOutputBuffer &OB, T *const &P) {
return SPSArgList<SPSExecutorAddr>::serialize(OB, ExecutorAddr::fromPtr(P));
}
static bool deserialize(SPSInputBuffer &IB, T *&P) {
ExecutorAddr Value;
if (!SPSArgList<SPSExecutorAddr>::deserialize(IB, Value))
return false;
P = Value.toPtr<T *>();
return true;
}
};
/// Helper type for serializing Errors.
///
/// llvm::Errors are move-only, and not inspectable except by consuming them.

View File

@@ -192,62 +192,6 @@ TEST(SPSWrapperFunctionUtilsTest, TransparentConversionExpectedFailureCase) {
EXPECT_EQ(ErrMsg, "N is not a multiple of 2");
}
static void
round_trip_int_pointer_sps_wrapper(orc_rt_SessionRef Session, void *CallCtx,
orc_rt_WrapperFunctionReturn Return,
orc_rt_WrapperFunctionBuffer ArgBytes) {
SPSWrapperFunction<SPSExecutorAddr(SPSExecutorAddr)>::handle(
Session, CallCtx, Return, ArgBytes,
[](move_only_function<void(int32_t *)> Return, int32_t *P) {
Return(P);
});
}
TEST(SPSWrapperFunctionUtilsTest, TransparentConversionPointers) {
int X = 42;
int *P = nullptr;
SPSWrapperFunction<SPSExecutorAddr(SPSExecutorAddr)>::call(
DirectCaller(nullptr, round_trip_int_pointer_sps_wrapper),
[&](Expected<int32_t *> R) { P = cantFail(std::move(R)); }, &X);
EXPECT_EQ(P, &X);
}
TEST(SPSWrapperFunctionUtilsTest, TransparentConversionReferenceArguments) {
int X = 42;
int *P = nullptr;
SPSWrapperFunction<SPSExecutorAddr(SPSExecutorAddr)>::call(
DirectCaller(nullptr, round_trip_int_pointer_sps_wrapper),
[&](Expected<int32_t *> R) { P = cantFail(std::move(R)); },
static_cast<int *const &>(&X));
EXPECT_EQ(P, &X);
}
static void
expected_int_pointer_sps_wrapper(orc_rt_SessionRef Session, void *CallCtx,
orc_rt_WrapperFunctionReturn Return,
orc_rt_WrapperFunctionBuffer ArgBytes) {
SPSWrapperFunction<SPSExpected<SPSExecutorAddr>(SPSExecutorAddr)>::handle(
Session, CallCtx, Return, ArgBytes,
[](move_only_function<void(Expected<int32_t *>)> Return, int32_t *P) {
Return(P);
});
}
TEST(SPSWrapperFunctionUtilsTest, TransparentConversionExpectedPointers) {
int X = 42;
int *P = nullptr;
SPSWrapperFunction<SPSExpected<SPSExecutorAddr>(SPSExecutorAddr)>::call(
DirectCaller(nullptr, expected_int_pointer_sps_wrapper),
[&](Expected<Expected<int32_t *>> R) {
P = cantFail(cantFail(std::move(R)));
},
&X);
EXPECT_EQ(P, &X);
}
template <size_t N> struct SPSOpCounter {};
namespace orc_rt {

View File

@@ -169,6 +169,12 @@ TEST(SimplePackedSerializationTest, StdOptionalValueSerialization) {
blobSerializationRoundTrip<SPSOptional<int64_t>>(Value);
}
TEST(SimplePackedSerializationTest, Pointers) {
int X = 42;
int *P = &X;
blobSerializationRoundTrip<SPSExecutorAddr>(P);
}
TEST(SimplePackedSerializationTest, ArgListSerialization) {
using BAL = SPSArgList<bool, int32_t, SPSString>;