LLVM 24.0.0git
Calls.h
Go to the documentation of this file.
1//===------------- Calls.h - SPS-based Call Wrappers ------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// SPS-based implementations of the RTBridge caller interfaces.
10//
11// These implement the rt::Caller interfaces by invoking executor-side wrapper
12// functions in the runtime's controller interface, using Simple Packed
13// Serialization to encode arguments and decode results.
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_SPS_CALLS_H
18#define LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_SPS_CALLS_H
19
23
25
26/// Implements the rt::Caller interface BaseT by calling an executor-side SPS
27/// wrapper function, using SPSSigT to encode the arguments and decode the
28/// result.
29///
30/// The wrapper is a controller-interface (CI) entry point named CIName: a
31/// wrapper function (byte blob in, byte blob out) that the runtime exposes to
32/// the controller. SPSSigT is the Simple Packed Serialization signature used to
33/// encode the argument blob and decode the result blob; it must be compatible
34/// with BaseT's FnType. CIName must have static storage duration (e.g. an
35/// inline constexpr char[]).
36///
37/// The FnType parameter is deduced from BaseT and should not be supplied
38/// explicitly; the primary template is left undefined so that only the
39/// RetT(ArgTs...) specialization can be instantiated.
40template <typename BaseT, typename SPSSigT, const char *CINameV,
41 typename FnType = typename BaseT::FnType>
42class Caller;
43
44template <typename BaseT, typename SPSSigT, const char *CINameV, typename RetT,
45 typename... ArgTs>
46class Caller<BaseT, SPSSigT, CINameV, RetT(ArgTs...)> : public BaseT {
47 using CalleeRetT = typename BaseT::CalleeRetT;
48 using ErrorRetT = typename BaseT::ErrorRetT;
49
50public:
51 /// Name of the controller-interface wrapper this caller targets.
52 static constexpr const char *CIName = CINameV;
53
55 : ES(ES), CallerFnAddr(CallerFnAddr) {}
56
57 /// Look the wrapper up in the executor's bootstrap JITDylib and build a
58 /// caller for it.
60 const char *Name = CIName) {
61 if (auto CallerSym = ES.lookup({&ES.getBootstrapJITDylib()}, Name))
62 return Caller(ES, CallerSym->getAddress());
63 else
64 return CallerSym.takeError();
65 }
66
67 /// Asynchronously call the SPS wrapper at CallerFnAddr to invoke the
68 /// executor-side function at FnAddr with the given Args, delivering the
69 /// result (or an error) to OnComplete. Serialization failures are reported
70 /// through OnComplete's error channel.
71 static void callAsync(unique_function<void(ErrorRetT)> OnComplete,
72 ExecutionSession &ES, ExecutorAddr CallerFnAddr,
73 ExecutorAddr FnAddr, const ArgTs &...Args) {
74 using namespace llvm::orc::shared;
75 if constexpr (std::is_void_v<CalleeRetT>) {
76 // Void result: the executor-side function produces no value, so the only
77 // thing to report is the dispatch error (success if the call ran).
78 ES.callSPSWrapperAsync<SPSSigT>(
79 CallerFnAddr,
80 [OnComplete = std::move(OnComplete)](Error SerErr) mutable {
81 OnComplete(std::move(SerErr));
82 },
83 FnAddr, Args...);
84 } else {
85 ES.callSPSWrapperAsync<SPSSigT>(
86 CallerFnAddr,
87 [OnComplete = std::move(OnComplete)](Error SerErr,
88 CalleeRetT Result) mutable {
89 if (SerErr)
90 return OnComplete(std::move(SerErr));
91 else
92 return OnComplete(std::move(Result));
93 },
94 FnAddr, Args...);
95 }
96 }
97
98 void operator()(unique_function<void(ErrorRetT)> OnComplete,
99 ExecutorAddr FnAddr, ArgTs... Args) override {
100 callAsync(std::move(OnComplete), ES, CallerFnAddr, FnAddr, Args...);
101 }
102
103 using BaseT::operator();
104
105private:
107 ExecutorAddr CallerFnAddr;
108};
109
112inline constexpr char CallMainCIName[] = "orc_rt_ci_sps_call_main";
113/// SPS caller for rt::MainCaller: runs a main-like function
114/// (int(int argc, char *argv[])) in the executor.
116
118inline constexpr char CallVoidVoidCIName[] = "orc_rt_ci_sps_call_void_void";
119/// SPS caller for rt::VoidVoidCaller: runs a void() function in the executor.
120/// WARNING: This Caller is experimental and may be removed.
123
125inline constexpr char CallInt32VoidCIName[] = "orc_rt_ci_sps_call_int32_void";
126/// SPS caller for rt::Int32VoidCaller: runs an int32_t() function in the
127/// executor.
128/// WARNING: This Caller is experimental and may be removed.
131
133inline constexpr char CallInt32Int32CIName[] = "orc_rt_ci_sps_call_int32_int32";
134/// SPS caller for rt::Int32Int32Caller: runs an int32_t(int32_t) function in
135/// the executor.
136/// WARNING: This Caller is experimental and may be removed.
139
140} // namespace llvm::orc::rt::sps
141
142#endif // LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_SPS_CALLS_H
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Tagged union holding either a T or a Error.
Definition Error.h:485
An ExecutionSession represents a running JIT program.
Definition Core.h:1111
Represents an address in the executor process.
void operator()(unique_function< void(ErrorRetT)> OnComplete, ExecutorAddr FnAddr, ArgTs... Args) override
Definition Calls.h:98
Caller(ExecutionSession &ES, ExecutorAddr CallerFnAddr)
Definition Calls.h:54
static constexpr const char * CIName
Name of the controller-interface wrapper this caller targets.
Definition Calls.h:52
static void callAsync(unique_function< void(ErrorRetT)> OnComplete, ExecutionSession &ES, ExecutorAddr CallerFnAddr, ExecutorAddr FnAddr, const ArgTs &...Args)
Asynchronously call the SPS wrapper at CallerFnAddr to invoke the executor-side function at FnAddr wi...
Definition Calls.h:71
static Expected< Caller > Create(ExecutionSession &ES, const char *Name=CIName)
Look the wrapper up in the executor's bootstrap JITDylib and build a caller for it.
Definition Calls.h:59
Implements the rt::Caller interface BaseT by calling an executor-side SPS wrapper function,...
Definition Calls.h:42
unique_function is a type-erasing functor similar to std::function.
void(shared::SPSExecutorAddr) CallVoidVoidSPSSig
Definition Calls.h:117
int32_t(shared::SPSExecutorAddr, int32_t) CallInt32Int32SPSSig
Definition Calls.h:132
Caller< rt::Int32Int32Caller, CallInt32Int32SPSSig, CallInt32Int32CIName > Int32Int32Caller
SPS caller for rt::Int32Int32Caller: runs an int32_t(int32_t) function in the executor.
Definition Calls.h:137
constexpr char CallInt32VoidCIName[]
Definition Calls.h:125
Caller< rt::Int32VoidCaller, CallInt32VoidSPSSig, CallInt32VoidCIName > Int32VoidCaller
SPS caller for rt::Int32VoidCaller: runs an int32_t() function in the executor.
Definition Calls.h:129
Caller< rt::MainCaller, CallMainSPSSig, CallMainCIName > MainCaller
SPS caller for rt::MainCaller: runs a main-like function (int(int argc, char *argv[])) in the executo...
Definition Calls.h:115
constexpr char CallMainCIName[]
Definition Calls.h:112
constexpr char CallInt32Int32CIName[]
Definition Calls.h:133
Caller< rt::VoidVoidCaller, CallVoidVoidSPSSig, CallVoidVoidCIName > VoidVoidCaller
SPS caller for rt::VoidVoidCaller: runs a void() function in the executor.
Definition Calls.h:121
constexpr char CallVoidVoidCIName[]
Definition Calls.h:118
int64_t(shared::SPSExecutorAddr, shared::SPSSequence< shared::SPSString >) CallMainSPSSig
Definition Calls.h:110
int32_t(shared::SPSExecutorAddr) CallInt32VoidSPSSig
Definition Calls.h:124
RTTIExtends< ObjectTransformLayer, ObjectLayer > BaseT