Skip to content

Commit 8aefeff

Browse files
lhamesgithub-actions[bot]
authored andcommitted
Automerge: [orc-rt] Enable transparent SPS conversion for ptrs via ExecutorAddr. (#162069)
Allows SPS wrapper function calls and handles to use pointer arguments. These will be converted to ExecutorAddr for serialization / deserialization.
2 parents 0f5aa7b + 9a111ff commit 8aefeff

File tree

2 files changed

+62
-31
lines changed

2 files changed

+62
-31
lines changed

orc-rt/include/orc-rt/SPSWrapperFunction.h

Lines changed: 41 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -33,47 +33,61 @@ template <typename... SPSArgTs> struct WFSPSHelper {
3333
return std::move(R);
3434
}
3535

36-
template <typename T> static const T &toSerializable(const T &Arg) noexcept {
37-
return Arg;
38-
}
36+
template <typename T> struct Serializable {
37+
typedef std::decay_t<T> serializable_type;
38+
static const T &to(const T &Arg) noexcept { return Arg; }
39+
static T &&from(T &&Arg) noexcept { return std::forward<T>(Arg); }
40+
};
3941

40-
static SPSSerializableError toSerializable(Error Err) {
41-
return SPSSerializableError(std::move(Err));
42-
}
42+
template <typename T> struct Serializable<T *> {
43+
typedef ExecutorAddr serializable_type;
44+
static ExecutorAddr to(T *Arg) { return ExecutorAddr::fromPtr(Arg); }
45+
static T *from(ExecutorAddr A) { return A.toPtr<T *>(); }
46+
};
4347

44-
template <typename T>
45-
static SPSSerializableExpected<T> toSerializable(Expected<T> Arg) {
46-
return SPSSerializableExpected<T>(std::move(Arg));
47-
}
48+
template <> struct Serializable<Error> {
49+
typedef SPSSerializableError serializable_type;
50+
static SPSSerializableError to(Error Err) {
51+
return SPSSerializableError(std::move(Err));
52+
}
53+
static Error from(SPSSerializableError Err) { return Err.toError(); }
54+
};
55+
56+
template <typename T> struct Serializable<Expected<T>> {
57+
typedef SPSSerializableExpected<T> serializable_type;
58+
static SPSSerializableExpected<T> to(Expected<T> Val) {
59+
return SPSSerializableExpected<T>(std::move(Val));
60+
}
61+
static Expected<T> from(SPSSerializableExpected<T> Val) {
62+
return Val.toExpected();
63+
}
64+
};
4865

4966
template <typename... Ts> struct DeserializableTuple;
5067

5168
template <typename... Ts> struct DeserializableTuple<std::tuple<Ts...>> {
52-
typedef std::tuple<
53-
std::decay_t<decltype(toSerializable(std::declval<Ts>()))>...>
54-
type;
69+
typedef std::tuple<typename Serializable<Ts>::serializable_type...> type;
5570
};
5671

5772
template <typename... Ts>
5873
using DeserializableTuple_t = typename DeserializableTuple<Ts...>::type;
5974

60-
template <typename T> static T &&fromSerializable(T &&Arg) noexcept {
61-
return std::forward<T>(Arg);
62-
}
63-
64-
static Error fromSerializable(SPSSerializableError Err) {
65-
return Err.toError();
66-
}
67-
68-
template <typename T>
69-
static Expected<T> fromSerializable(SPSSerializableExpected<T> Val) {
70-
return Val.toExpected();
75+
template <typename ArgTuple, typename... SerializableArgs, std::size_t... Is>
76+
std::optional<ArgTuple>
77+
applySerializationConversions(std::tuple<SerializableArgs...> &Inputs,
78+
std::index_sequence<Is...>) {
79+
static_assert(sizeof...(SerializableArgs) ==
80+
std::index_sequence<Is...>::size(),
81+
"Tuple sizes don't match");
82+
return std::optional<ArgTuple>(
83+
std::in_place, Serializable<std::tuple_element_t<Is, ArgTuple>>::from(
84+
std::move(std::get<Is>(Inputs)))...);
7185
}
7286

7387
public:
7488
template <typename... ArgTs>
7589
std::optional<WrapperFunctionBuffer> serialize(ArgTs &&...Args) {
76-
return serializeImpl(toSerializable(std::forward<ArgTs>(Args))...);
90+
return serializeImpl(Serializable<ArgTs>::to(std::forward<ArgTs>(Args))...);
7791
}
7892

7993
template <typename ArgTuple>
@@ -85,12 +99,8 @@ template <typename... SPSArgTs> struct WFSPSHelper {
8599
if (!SPSSerializationTraits<SPSTuple<SPSArgTs...>,
86100
decltype(Args)>::deserialize(IB, Args))
87101
return std::nullopt;
88-
return std::apply(
89-
[](auto &&...A) {
90-
return std::optional<ArgTuple>(std::in_place,
91-
std::move(fromSerializable(A))...);
92-
},
93-
std::move(Args));
102+
return applySerializationConversions<ArgTuple>(
103+
Args, std::make_index_sequence<std::tuple_size_v<ArgTuple>>());
94104
}
95105
};
96106

orc-rt/unittests/SPSWrapperFunctionTest.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,27 @@ TEST(SPSWrapperFunctionUtilsTest, TestFunctionReturningExpectedFailureCase) {
221221
EXPECT_EQ(ErrMsg, "N is not a multiple of 2");
222222
}
223223

224+
static void
225+
round_trip_int_pointer_sps_wrapper(orc_rt_SessionRef Session, void *CallCtx,
226+
orc_rt_WrapperFunctionReturn Return,
227+
orc_rt_WrapperFunctionBuffer ArgBytes) {
228+
SPSWrapperFunction<SPSExecutorAddr(SPSExecutorAddr)>::handle(
229+
Session, CallCtx, Return, ArgBytes,
230+
[](move_only_function<void(int32_t *)> Return, int32_t *P) {
231+
Return(P);
232+
});
233+
}
234+
235+
TEST(SPSWrapperFunctionUtilsTest, TestTransparentSerializationForPointers) {
236+
int X = 42;
237+
int *P = nullptr;
238+
SPSWrapperFunction<SPSExecutorAddr(SPSExecutorAddr)>::call(
239+
DirectCaller(nullptr, round_trip_int_pointer_sps_wrapper),
240+
[&](Expected<int32_t *> R) { P = cantFail(std::move(R)); }, &X);
241+
242+
EXPECT_EQ(P, &X);
243+
}
244+
224245
template <size_t N> struct SPSOpCounter {};
225246

226247
namespace orc_rt {

0 commit comments

Comments
 (0)