mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 02:38:07 +08:00
[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:
@@ -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...>> {
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user