File indexing completed on 2026-05-10 08:43:51
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_WRAPPERFUNCTIONUTILS_H
0014 #define LLVM_EXECUTIONENGINE_ORC_SHARED_WRAPPERFUNCTIONUTILS_H
0015
0016 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
0017 #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
0018 #include "llvm/Support/Error.h"
0019
0020 #include <type_traits>
0021
0022 namespace llvm {
0023 namespace orc {
0024 namespace shared {
0025
0026
0027 union CWrapperFunctionResultDataUnion {
0028 char *ValuePtr;
0029 char Value[sizeof(ValuePtr)];
0030 };
0031
0032
0033 typedef struct {
0034 CWrapperFunctionResultDataUnion Data;
0035 size_t Size;
0036 } CWrapperFunctionResult;
0037
0038
0039
0040 class WrapperFunctionResult {
0041 public:
0042
0043 WrapperFunctionResult() { init(R); }
0044
0045
0046
0047
0048
0049
0050 WrapperFunctionResult(CWrapperFunctionResult R) : R(R) {
0051
0052 init(R);
0053 }
0054
0055 WrapperFunctionResult(const WrapperFunctionResult &) = delete;
0056 WrapperFunctionResult &operator=(const WrapperFunctionResult &) = delete;
0057
0058 WrapperFunctionResult(WrapperFunctionResult &&Other) {
0059 init(R);
0060 std::swap(R, Other.R);
0061 }
0062
0063 WrapperFunctionResult &operator=(WrapperFunctionResult &&Other) {
0064 WrapperFunctionResult Tmp(std::move(Other));
0065 std::swap(R, Tmp.R);
0066 return *this;
0067 }
0068
0069 ~WrapperFunctionResult() {
0070 if ((R.Size > sizeof(R.Data.Value)) ||
0071 (R.Size == 0 && R.Data.ValuePtr != nullptr))
0072 free(R.Data.ValuePtr);
0073 }
0074
0075
0076
0077
0078
0079 CWrapperFunctionResult release() {
0080 CWrapperFunctionResult Tmp;
0081 init(Tmp);
0082 std::swap(R, Tmp);
0083 return Tmp;
0084 }
0085
0086
0087 char *data() {
0088 assert((R.Size != 0 || R.Data.ValuePtr == nullptr) &&
0089 "Cannot get data for out-of-band error value");
0090 return R.Size > sizeof(R.Data.Value) ? R.Data.ValuePtr : R.Data.Value;
0091 }
0092
0093
0094 const char *data() const {
0095 assert((R.Size != 0 || R.Data.ValuePtr == nullptr) &&
0096 "Cannot get data for out-of-band error value");
0097 return R.Size > sizeof(R.Data.Value) ? R.Data.ValuePtr : R.Data.Value;
0098 }
0099
0100
0101 size_t size() const {
0102 assert((R.Size != 0 || R.Data.ValuePtr == nullptr) &&
0103 "Cannot get data for out-of-band error value");
0104 return R.Size;
0105 }
0106
0107
0108
0109 bool empty() const { return R.Size == 0 && R.Data.ValuePtr == nullptr; }
0110
0111
0112
0113 static WrapperFunctionResult allocate(size_t Size) {
0114
0115 WrapperFunctionResult WFR;
0116 WFR.R.Size = Size;
0117 if (WFR.R.Size > sizeof(WFR.R.Data.Value))
0118 WFR.R.Data.ValuePtr = (char *)malloc(WFR.R.Size);
0119 return WFR;
0120 }
0121
0122
0123 static WrapperFunctionResult copyFrom(const char *Source, size_t Size) {
0124 auto WFR = allocate(Size);
0125 memcpy(WFR.data(), Source, Size);
0126 return WFR;
0127 }
0128
0129
0130 static WrapperFunctionResult copyFrom(const char *Source) {
0131 return copyFrom(Source, strlen(Source) + 1);
0132 }
0133
0134
0135 static WrapperFunctionResult copyFrom(const std::string &Source) {
0136 return copyFrom(Source.c_str());
0137 }
0138
0139
0140 static WrapperFunctionResult createOutOfBandError(const char *Msg) {
0141
0142 WrapperFunctionResult WFR;
0143 char *Tmp = (char *)malloc(strlen(Msg) + 1);
0144 strcpy(Tmp, Msg);
0145 WFR.R.Data.ValuePtr = Tmp;
0146 return WFR;
0147 }
0148
0149
0150 static WrapperFunctionResult createOutOfBandError(const std::string &Msg) {
0151 return createOutOfBandError(Msg.c_str());
0152 }
0153
0154
0155
0156 const char *getOutOfBandError() const {
0157 return R.Size == 0 ? R.Data.ValuePtr : nullptr;
0158 }
0159
0160 private:
0161 static void init(CWrapperFunctionResult &R) {
0162 R.Data.ValuePtr = nullptr;
0163 R.Size = 0;
0164 }
0165
0166 CWrapperFunctionResult R;
0167 };
0168
0169 namespace detail {
0170
0171 template <typename SPSArgListT, typename... ArgTs>
0172 WrapperFunctionResult
0173 serializeViaSPSToWrapperFunctionResult(const ArgTs &...Args) {
0174 auto Result = WrapperFunctionResult::allocate(SPSArgListT::size(Args...));
0175 SPSOutputBuffer OB(Result.data(), Result.size());
0176 if (!SPSArgListT::serialize(OB, Args...))
0177 return WrapperFunctionResult::createOutOfBandError(
0178 "Error serializing arguments to blob in call");
0179 return Result;
0180 }
0181
0182 template <typename RetT> class WrapperFunctionHandlerCaller {
0183 public:
0184 template <typename HandlerT, typename ArgTupleT, std::size_t... I>
0185 static decltype(auto) call(HandlerT &&H, ArgTupleT &Args,
0186 std::index_sequence<I...>) {
0187 return std::forward<HandlerT>(H)(std::get<I>(Args)...);
0188 }
0189 };
0190
0191 template <> class WrapperFunctionHandlerCaller<void> {
0192 public:
0193 template <typename HandlerT, typename ArgTupleT, std::size_t... I>
0194 static SPSEmpty call(HandlerT &&H, ArgTupleT &Args,
0195 std::index_sequence<I...>) {
0196 std::forward<HandlerT>(H)(std::get<I>(Args)...);
0197 return SPSEmpty();
0198 }
0199 };
0200
0201 template <typename WrapperFunctionImplT,
0202 template <typename> class ResultSerializer, typename... SPSTagTs>
0203 class WrapperFunctionHandlerHelper
0204 : public WrapperFunctionHandlerHelper<
0205 decltype(&std::remove_reference_t<WrapperFunctionImplT>::operator()),
0206 ResultSerializer, SPSTagTs...> {};
0207
0208 template <typename RetT, typename... ArgTs,
0209 template <typename> class ResultSerializer, typename... SPSTagTs>
0210 class WrapperFunctionHandlerHelper<RetT(ArgTs...), ResultSerializer,
0211 SPSTagTs...> {
0212 public:
0213 using ArgTuple = std::tuple<std::decay_t<ArgTs>...>;
0214 using ArgIndices = std::make_index_sequence<std::tuple_size<ArgTuple>::value>;
0215
0216 template <typename HandlerT>
0217 static WrapperFunctionResult apply(HandlerT &&H, const char *ArgData,
0218 size_t ArgSize) {
0219 ArgTuple Args;
0220 if (!deserialize(ArgData, ArgSize, Args, ArgIndices{}))
0221 return WrapperFunctionResult::createOutOfBandError(
0222 "Could not deserialize arguments for wrapper function call");
0223
0224 auto HandlerResult = WrapperFunctionHandlerCaller<RetT>::call(
0225 std::forward<HandlerT>(H), Args, ArgIndices{});
0226
0227 return ResultSerializer<decltype(HandlerResult)>::serialize(
0228 std::move(HandlerResult));
0229 }
0230
0231 private:
0232 template <std::size_t... I>
0233 static bool deserialize(const char *ArgData, size_t ArgSize, ArgTuple &Args,
0234 std::index_sequence<I...>) {
0235 SPSInputBuffer IB(ArgData, ArgSize);
0236 return SPSArgList<SPSTagTs...>::deserialize(IB, std::get<I>(Args)...);
0237 }
0238 };
0239
0240
0241 template <typename RetT, typename... ArgTs,
0242 template <typename> class ResultSerializer, typename... SPSTagTs>
0243 class WrapperFunctionHandlerHelper<RetT (*)(ArgTs...), ResultSerializer,
0244 SPSTagTs...>
0245 : public WrapperFunctionHandlerHelper<RetT(ArgTs...), ResultSerializer,
0246 SPSTagTs...> {};
0247
0248
0249 template <typename ClassT, typename RetT, typename... ArgTs,
0250 template <typename> class ResultSerializer, typename... SPSTagTs>
0251 class WrapperFunctionHandlerHelper<RetT (ClassT::*)(ArgTs...), ResultSerializer,
0252 SPSTagTs...>
0253 : public WrapperFunctionHandlerHelper<RetT(ArgTs...), ResultSerializer,
0254 SPSTagTs...> {};
0255
0256
0257 template <typename ClassT, typename RetT, typename... ArgTs,
0258 template <typename> class ResultSerializer, typename... SPSTagTs>
0259 class WrapperFunctionHandlerHelper<RetT (ClassT::*)(ArgTs...) const,
0260 ResultSerializer, SPSTagTs...>
0261 : public WrapperFunctionHandlerHelper<RetT(ArgTs...), ResultSerializer,
0262 SPSTagTs...> {};
0263
0264 template <typename WrapperFunctionImplT,
0265 template <typename> class ResultSerializer, typename... SPSTagTs>
0266 class WrapperFunctionAsyncHandlerHelper
0267 : public WrapperFunctionAsyncHandlerHelper<
0268 decltype(&std::remove_reference_t<WrapperFunctionImplT>::operator()),
0269 ResultSerializer, SPSTagTs...> {};
0270
0271 template <typename RetT, typename SendResultT, typename... ArgTs,
0272 template <typename> class ResultSerializer, typename... SPSTagTs>
0273 class WrapperFunctionAsyncHandlerHelper<RetT(SendResultT, ArgTs...),
0274 ResultSerializer, SPSTagTs...> {
0275 public:
0276 using ArgTuple = std::tuple<std::decay_t<ArgTs>...>;
0277 using ArgIndices = std::make_index_sequence<std::tuple_size<ArgTuple>::value>;
0278
0279 template <typename HandlerT, typename SendWrapperFunctionResultT>
0280 static void applyAsync(HandlerT &&H,
0281 SendWrapperFunctionResultT &&SendWrapperFunctionResult,
0282 const char *ArgData, size_t ArgSize) {
0283 ArgTuple Args;
0284 if (!deserialize(ArgData, ArgSize, Args, ArgIndices{})) {
0285 SendWrapperFunctionResult(WrapperFunctionResult::createOutOfBandError(
0286 "Could not deserialize arguments for wrapper function call"));
0287 return;
0288 }
0289
0290 auto SendResult =
0291 [SendWFR = std::move(SendWrapperFunctionResult)](auto Result) mutable {
0292 using ResultT = decltype(Result);
0293 SendWFR(ResultSerializer<ResultT>::serialize(std::move(Result)));
0294 };
0295
0296 callAsync(std::forward<HandlerT>(H), std::move(SendResult), std::move(Args),
0297 ArgIndices{});
0298 }
0299
0300 private:
0301 template <std::size_t... I>
0302 static bool deserialize(const char *ArgData, size_t ArgSize, ArgTuple &Args,
0303 std::index_sequence<I...>) {
0304 SPSInputBuffer IB(ArgData, ArgSize);
0305 return SPSArgList<SPSTagTs...>::deserialize(IB, std::get<I>(Args)...);
0306 }
0307
0308 template <typename HandlerT, typename SerializeAndSendResultT,
0309 typename ArgTupleT, std::size_t... I>
0310 static void callAsync(HandlerT &&H,
0311 SerializeAndSendResultT &&SerializeAndSendResult,
0312 ArgTupleT Args, std::index_sequence<I...>) {
0313 (void)Args;
0314 return std::forward<HandlerT>(H)(std::move(SerializeAndSendResult),
0315 std::move(std::get<I>(Args))...);
0316 }
0317 };
0318
0319
0320 template <typename RetT, typename... ArgTs,
0321 template <typename> class ResultSerializer, typename... SPSTagTs>
0322 class WrapperFunctionAsyncHandlerHelper<RetT (*)(ArgTs...), ResultSerializer,
0323 SPSTagTs...>
0324 : public WrapperFunctionAsyncHandlerHelper<RetT(ArgTs...), ResultSerializer,
0325 SPSTagTs...> {};
0326
0327
0328 template <typename ClassT, typename RetT, typename... ArgTs,
0329 template <typename> class ResultSerializer, typename... SPSTagTs>
0330 class WrapperFunctionAsyncHandlerHelper<RetT (ClassT::*)(ArgTs...),
0331 ResultSerializer, SPSTagTs...>
0332 : public WrapperFunctionAsyncHandlerHelper<RetT(ArgTs...), ResultSerializer,
0333 SPSTagTs...> {};
0334
0335
0336 template <typename ClassT, typename RetT, typename... ArgTs,
0337 template <typename> class ResultSerializer, typename... SPSTagTs>
0338 class WrapperFunctionAsyncHandlerHelper<RetT (ClassT::*)(ArgTs...) const,
0339 ResultSerializer, SPSTagTs...>
0340 : public WrapperFunctionAsyncHandlerHelper<RetT(ArgTs...), ResultSerializer,
0341 SPSTagTs...> {};
0342
0343 template <typename SPSRetTagT, typename RetT> class ResultSerializer {
0344 public:
0345 static WrapperFunctionResult serialize(RetT Result) {
0346 return serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSRetTagT>>(
0347 Result);
0348 }
0349 };
0350
0351 template <typename SPSRetTagT> class ResultSerializer<SPSRetTagT, Error> {
0352 public:
0353 static WrapperFunctionResult serialize(Error Err) {
0354 return serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSRetTagT>>(
0355 toSPSSerializable(std::move(Err)));
0356 }
0357 };
0358
0359 template <typename SPSRetTagT>
0360 class ResultSerializer<SPSRetTagT, ErrorSuccess> {
0361 public:
0362 static WrapperFunctionResult serialize(ErrorSuccess Err) {
0363 return serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSRetTagT>>(
0364 toSPSSerializable(std::move(Err)));
0365 }
0366 };
0367
0368 template <typename SPSRetTagT, typename T>
0369 class ResultSerializer<SPSRetTagT, Expected<T>> {
0370 public:
0371 static WrapperFunctionResult serialize(Expected<T> E) {
0372 return serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSRetTagT>>(
0373 toSPSSerializable(std::move(E)));
0374 }
0375 };
0376
0377 template <typename SPSRetTagT, typename RetT> class ResultDeserializer {
0378 public:
0379 static RetT makeValue() { return RetT(); }
0380 static void makeSafe(RetT &Result) {}
0381
0382 static Error deserialize(RetT &Result, const char *ArgData, size_t ArgSize) {
0383 SPSInputBuffer IB(ArgData, ArgSize);
0384 if (!SPSArgList<SPSRetTagT>::deserialize(IB, Result))
0385 return make_error<StringError>(
0386 "Error deserializing return value from blob in call",
0387 inconvertibleErrorCode());
0388 return Error::success();
0389 }
0390 };
0391
0392 template <> class ResultDeserializer<SPSError, Error> {
0393 public:
0394 static Error makeValue() { return Error::success(); }
0395 static void makeSafe(Error &Err) { cantFail(std::move(Err)); }
0396
0397 static Error deserialize(Error &Err, const char *ArgData, size_t ArgSize) {
0398 SPSInputBuffer IB(ArgData, ArgSize);
0399 SPSSerializableError BSE;
0400 if (!SPSArgList<SPSError>::deserialize(IB, BSE))
0401 return make_error<StringError>(
0402 "Error deserializing return value from blob in call",
0403 inconvertibleErrorCode());
0404 Err = fromSPSSerializable(std::move(BSE));
0405 return Error::success();
0406 }
0407 };
0408
0409 template <typename SPSTagT, typename T>
0410 class ResultDeserializer<SPSExpected<SPSTagT>, Expected<T>> {
0411 public:
0412 static Expected<T> makeValue() { return T(); }
0413 static void makeSafe(Expected<T> &E) { cantFail(E.takeError()); }
0414
0415 static Error deserialize(Expected<T> &E, const char *ArgData,
0416 size_t ArgSize) {
0417 SPSInputBuffer IB(ArgData, ArgSize);
0418 SPSSerializableExpected<T> BSE;
0419 if (!SPSArgList<SPSExpected<SPSTagT>>::deserialize(IB, BSE))
0420 return make_error<StringError>(
0421 "Error deserializing return value from blob in call",
0422 inconvertibleErrorCode());
0423 E = fromSPSSerializable(std::move(BSE));
0424 return Error::success();
0425 }
0426 };
0427
0428 template <typename SPSRetTagT, typename RetT> class AsyncCallResultHelper {
0429
0430 };
0431
0432 }
0433
0434 template <typename SPSSignature> class WrapperFunction;
0435
0436 template <typename SPSRetTagT, typename... SPSTagTs>
0437 class WrapperFunction<SPSRetTagT(SPSTagTs...)> {
0438 private:
0439 template <typename RetT>
0440 using ResultSerializer = detail::ResultSerializer<SPSRetTagT, RetT>;
0441
0442 public:
0443
0444
0445 template <typename CallerFn, typename RetT, typename... ArgTs>
0446 static Error call(const CallerFn &Caller, RetT &Result,
0447 const ArgTs &...Args) {
0448
0449
0450
0451
0452 detail::ResultDeserializer<SPSRetTagT, RetT>::makeSafe(Result);
0453
0454 auto ArgBuffer =
0455 detail::serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSTagTs...>>(
0456 Args...);
0457 if (const char *ErrMsg = ArgBuffer.getOutOfBandError())
0458 return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
0459
0460 WrapperFunctionResult ResultBuffer =
0461 Caller(ArgBuffer.data(), ArgBuffer.size());
0462 if (auto ErrMsg = ResultBuffer.getOutOfBandError())
0463 return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
0464
0465 return detail::ResultDeserializer<SPSRetTagT, RetT>::deserialize(
0466 Result, ResultBuffer.data(), ResultBuffer.size());
0467 }
0468
0469
0470
0471
0472
0473 template <typename AsyncCallerFn, typename SendDeserializedResultFn,
0474 typename... ArgTs>
0475 static void callAsync(AsyncCallerFn &&Caller,
0476 SendDeserializedResultFn &&SendDeserializedResult,
0477 const ArgTs &...Args) {
0478 using RetT = typename std::tuple_element<
0479 1, typename detail::WrapperFunctionHandlerHelper<
0480 std::remove_reference_t<SendDeserializedResultFn>,
0481 ResultSerializer, SPSRetTagT>::ArgTuple>::type;
0482
0483 auto ArgBuffer =
0484 detail::serializeViaSPSToWrapperFunctionResult<SPSArgList<SPSTagTs...>>(
0485 Args...);
0486 if (auto *ErrMsg = ArgBuffer.getOutOfBandError()) {
0487 SendDeserializedResult(
0488 make_error<StringError>(ErrMsg, inconvertibleErrorCode()),
0489 detail::ResultDeserializer<SPSRetTagT, RetT>::makeValue());
0490 return;
0491 }
0492
0493 auto SendSerializedResult = [SDR = std::move(SendDeserializedResult)](
0494 WrapperFunctionResult R) mutable {
0495 RetT RetVal = detail::ResultDeserializer<SPSRetTagT, RetT>::makeValue();
0496 detail::ResultDeserializer<SPSRetTagT, RetT>::makeSafe(RetVal);
0497
0498 if (auto *ErrMsg = R.getOutOfBandError()) {
0499 SDR(make_error<StringError>(ErrMsg, inconvertibleErrorCode()),
0500 std::move(RetVal));
0501 return;
0502 }
0503
0504 SPSInputBuffer IB(R.data(), R.size());
0505 if (auto Err = detail::ResultDeserializer<SPSRetTagT, RetT>::deserialize(
0506 RetVal, R.data(), R.size())) {
0507 SDR(std::move(Err), std::move(RetVal));
0508 return;
0509 }
0510
0511 SDR(Error::success(), std::move(RetVal));
0512 };
0513
0514 Caller(std::move(SendSerializedResult), ArgBuffer.data(), ArgBuffer.size());
0515 }
0516
0517
0518 template <typename HandlerT>
0519 static WrapperFunctionResult handle(const char *ArgData, size_t ArgSize,
0520 HandlerT &&Handler) {
0521 using WFHH =
0522 detail::WrapperFunctionHandlerHelper<std::remove_reference_t<HandlerT>,
0523 ResultSerializer, SPSTagTs...>;
0524 return WFHH::apply(std::forward<HandlerT>(Handler), ArgData, ArgSize);
0525 }
0526
0527
0528 template <typename HandlerT, typename SendResultT>
0529 static void handleAsync(const char *ArgData, size_t ArgSize,
0530 HandlerT &&Handler, SendResultT &&SendResult) {
0531 using WFAHH = detail::WrapperFunctionAsyncHandlerHelper<
0532 std::remove_reference_t<HandlerT>, ResultSerializer, SPSTagTs...>;
0533 WFAHH::applyAsync(std::forward<HandlerT>(Handler),
0534 std::forward<SendResultT>(SendResult), ArgData, ArgSize);
0535 }
0536
0537 private:
0538 template <typename T> static const T &makeSerializable(const T &Value) {
0539 return Value;
0540 }
0541
0542 static detail::SPSSerializableError makeSerializable(Error Err) {
0543 return detail::toSPSSerializable(std::move(Err));
0544 }
0545
0546 template <typename T>
0547 static detail::SPSSerializableExpected<T> makeSerializable(Expected<T> E) {
0548 return detail::toSPSSerializable(std::move(E));
0549 }
0550 };
0551
0552 template <typename... SPSTagTs>
0553 class WrapperFunction<void(SPSTagTs...)>
0554 : private WrapperFunction<SPSEmpty(SPSTagTs...)> {
0555
0556 public:
0557 template <typename CallerFn, typename... ArgTs>
0558 static Error call(const CallerFn &Caller, const ArgTs &...Args) {
0559 SPSEmpty BE;
0560 return WrapperFunction<SPSEmpty(SPSTagTs...)>::call(Caller, BE, Args...);
0561 }
0562
0563 template <typename AsyncCallerFn, typename SendDeserializedResultFn,
0564 typename... ArgTs>
0565 static void callAsync(AsyncCallerFn &&Caller,
0566 SendDeserializedResultFn &&SendDeserializedResult,
0567 const ArgTs &...Args) {
0568 WrapperFunction<SPSEmpty(SPSTagTs...)>::callAsync(
0569 std::forward<AsyncCallerFn>(Caller),
0570 [SDR = std::move(SendDeserializedResult)](Error SerializeErr,
0571 SPSEmpty E) mutable {
0572 SDR(std::move(SerializeErr));
0573 },
0574 Args...);
0575 }
0576
0577 using WrapperFunction<SPSEmpty(SPSTagTs...)>::handle;
0578 using WrapperFunction<SPSEmpty(SPSTagTs...)>::handleAsync;
0579 };
0580
0581
0582
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602
0603 template <typename RetT, typename ClassT, typename... ArgTs>
0604 class MethodWrapperHandler {
0605 public:
0606 using MethodT = RetT (ClassT::*)(ArgTs...);
0607 MethodWrapperHandler(MethodT M) : M(M) {}
0608 RetT operator()(ExecutorAddr ObjAddr, ArgTs &...Args) {
0609 return (ObjAddr.toPtr<ClassT*>()->*M)(std::forward<ArgTs>(Args)...);
0610 }
0611
0612 private:
0613 MethodT M;
0614 };
0615
0616
0617 template <typename RetT, typename ClassT, typename... ArgTs>
0618 MethodWrapperHandler<RetT, ClassT, ArgTs...>
0619 makeMethodWrapperHandler(RetT (ClassT::*Method)(ArgTs...)) {
0620 return MethodWrapperHandler<RetT, ClassT, ArgTs...>(Method);
0621 }
0622
0623
0624
0625
0626
0627
0628
0629
0630 class WrapperFunctionCall {
0631 public:
0632 using ArgDataBufferType = SmallVector<char, 24>;
0633
0634
0635
0636 template <typename SPSSerializer, typename... ArgTs>
0637 static Expected<WrapperFunctionCall> Create(ExecutorAddr FnAddr,
0638 const ArgTs &...Args) {
0639 ArgDataBufferType ArgData;
0640 ArgData.resize(SPSSerializer::size(Args...));
0641 SPSOutputBuffer OB(ArgData.empty() ? nullptr : ArgData.data(),
0642 ArgData.size());
0643 if (SPSSerializer::serialize(OB, Args...))
0644 return WrapperFunctionCall(FnAddr, std::move(ArgData));
0645 return make_error<StringError>("Cannot serialize arguments for "
0646 "AllocActionCall",
0647 inconvertibleErrorCode());
0648 }
0649
0650 WrapperFunctionCall() = default;
0651
0652
0653 WrapperFunctionCall(ExecutorAddr FnAddr, ArgDataBufferType ArgData)
0654 : FnAddr(FnAddr), ArgData(std::move(ArgData)) {}
0655
0656
0657 const ExecutorAddr &getCallee() const { return FnAddr; }
0658
0659
0660 const ArgDataBufferType &getArgData() const { return ArgData; }
0661
0662
0663 explicit operator bool() const { return !!FnAddr; }
0664
0665
0666 shared::WrapperFunctionResult run() const {
0667 using FnTy =
0668 shared::CWrapperFunctionResult(const char *ArgData, size_t ArgSize);
0669 return shared::WrapperFunctionResult(
0670 FnAddr.toPtr<FnTy *>()(ArgData.data(), ArgData.size()));
0671 }
0672
0673
0674 template <typename SPSRetT, typename RetT>
0675 std::enable_if_t<!std::is_same<SPSRetT, void>::value, Error>
0676 runWithSPSRet(RetT &RetVal) const {
0677 auto WFR = run();
0678 if (const char *ErrMsg = WFR.getOutOfBandError())
0679 return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
0680 shared::SPSInputBuffer IB(WFR.data(), WFR.size());
0681 if (!shared::SPSSerializationTraits<SPSRetT, RetT>::deserialize(IB, RetVal))
0682 return make_error<StringError>("Could not deserialize result from "
0683 "serialized wrapper function call",
0684 inconvertibleErrorCode());
0685 return Error::success();
0686 }
0687
0688
0689 template <typename SPSRetT>
0690 std::enable_if_t<std::is_same<SPSRetT, void>::value, Error>
0691 runWithSPSRet() const {
0692 shared::SPSEmpty E;
0693 return runWithSPSRet<shared::SPSEmpty>(E);
0694 }
0695
0696
0697
0698 Error runWithSPSRetErrorMerged() const {
0699 detail::SPSSerializableError RetErr;
0700 if (auto Err = runWithSPSRet<SPSError>(RetErr))
0701 return Err;
0702 return detail::fromSPSSerializable(std::move(RetErr));
0703 }
0704
0705 private:
0706 orc::ExecutorAddr FnAddr;
0707 ArgDataBufferType ArgData;
0708 };
0709
0710 using SPSWrapperFunctionCall = SPSTuple<SPSExecutorAddr, SPSSequence<char>>;
0711
0712 template <>
0713 class SPSSerializationTraits<SPSWrapperFunctionCall, WrapperFunctionCall> {
0714 public:
0715 static size_t size(const WrapperFunctionCall &WFC) {
0716 return SPSWrapperFunctionCall::AsArgList::size(WFC.getCallee(),
0717 WFC.getArgData());
0718 }
0719
0720 static bool serialize(SPSOutputBuffer &OB, const WrapperFunctionCall &WFC) {
0721 return SPSWrapperFunctionCall::AsArgList::serialize(OB, WFC.getCallee(),
0722 WFC.getArgData());
0723 }
0724
0725 static bool deserialize(SPSInputBuffer &IB, WrapperFunctionCall &WFC) {
0726 ExecutorAddr FnAddr;
0727 WrapperFunctionCall::ArgDataBufferType ArgData;
0728 if (!SPSWrapperFunctionCall::AsArgList::deserialize(IB, FnAddr, ArgData))
0729 return false;
0730 WFC = WrapperFunctionCall(FnAddr, std::move(ArgData));
0731 return true;
0732 }
0733 };
0734
0735 }
0736 }
0737 }
0738
0739 #endif