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 with the given Args,
68 /// delivering the result (or an error) to OnComplete. Serialization failures
69 /// are reported through OnComplete's error channel.
70 static void callAsync(unique_function<void(ErrorRetT)> OnComplete,
71 ExecutionSession &ES, ExecutorAddr CallerFnAddr,
72 const ArgTs &...Args) {
73 using namespace llvm::orc::shared;
74 if constexpr (std::is_void_v<CalleeRetT>) {
75 // Void result: the executor-side function produces no value, so the only
76 // thing to report is the dispatch error (success if the call ran).
77 ES.callSPSWrapperAsync<SPSSigT>(
78 CallerFnAddr,
79 [OnComplete = std::move(OnComplete)](Error SerErr) mutable {
80 OnComplete(std::move(SerErr));
81 },
82 Args...);
83 } else {
84 ES.callSPSWrapperAsync<SPSSigT>(
85 CallerFnAddr,
86 [OnComplete = std::move(OnComplete)](Error SerErr,
87 CalleeRetT Result) mutable {
88 if (SerErr)
89 return OnComplete(std::move(SerErr));
90 else
91 return OnComplete(std::move(Result));
92 },
93 Args...);
94 }
95 }
96
97 void operator()(unique_function<void(ErrorRetT)> OnComplete,
98 ArgTs... Args) override {
99 callAsync(std::move(OnComplete), ES, CallerFnAddr, Args...);
100 }
101
102 using BaseT::operator();
103
104private:
106 ExecutorAddr CallerFnAddr;
107};
108
111inline constexpr char CallMainCIName[] = "orc_rt_ci_sps_call_main";
112/// SPS caller for rt::MainCaller: runs a main-like function
113/// (int(int argc, char *argv[])) in the executor.
115
117inline constexpr char CallVoidVoidCIName[] = "orc_rt_ci_sps_call_void_void";
118/// SPS caller for rt::VoidVoidCaller: runs a void() function in the executor.
119/// WARNING: This Caller is experimental and may be removed.
122
124inline constexpr char CallInt32VoidCIName[] = "orc_rt_ci_sps_call_int32_void";
125/// SPS caller for rt::Int32VoidCaller: runs an int32_t() function in the
126/// executor.
127/// WARNING: This Caller is experimental and may be removed.
130
132inline constexpr char CallInt32Int32CIName[] = "orc_rt_ci_sps_call_int32_int32";
133/// SPS caller for rt::Int32Int32Caller: runs an int32_t(int32_t) function in
134/// the executor.
135/// WARNING: This Caller is experimental and may be removed.
138
139} // namespace llvm::orc::rt::sps
140
141#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, ArgTs... Args) override
Definition Calls.h:97
Caller(ExecutionSession &ES, ExecutorAddr CallerFnAddr)
Definition Calls.h:54
static void callAsync(unique_function< void(ErrorRetT)> OnComplete, ExecutionSession &ES, ExecutorAddr CallerFnAddr, const ArgTs &...Args)
Asynchronously call the SPS wrapper at CallerFnAddr with the given Args, delivering the result (or an...
Definition Calls.h:70
static constexpr const char * CIName
Name of the controller-interface wrapper this caller targets.
Definition Calls.h:52
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:116
int32_t(shared::SPSExecutorAddr, int32_t) CallInt32Int32SPSSig
Definition Calls.h:131
Caller< rt::Int32Int32Caller, CallInt32Int32SPSSig, CallInt32Int32CIName > Int32Int32Caller
SPS caller for rt::Int32Int32Caller: runs an int32_t(int32_t) function in the executor.
Definition Calls.h:136
constexpr char CallInt32VoidCIName[]
Definition Calls.h:124
Caller< rt::Int32VoidCaller, CallInt32VoidSPSSig, CallInt32VoidCIName > Int32VoidCaller
SPS caller for rt::Int32VoidCaller: runs an int32_t() function in the executor.
Definition Calls.h:128
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:114
constexpr char CallMainCIName[]
Definition Calls.h:111
constexpr char CallInt32Int32CIName[]
Definition Calls.h:132
Caller< rt::VoidVoidCaller, CallVoidVoidSPSSig, CallVoidVoidCIName > VoidVoidCaller
SPS caller for rt::VoidVoidCaller: runs a void() function in the executor.
Definition Calls.h:120
constexpr char CallVoidVoidCIName[]
Definition Calls.h:117
int64_t(shared::SPSExecutorAddr, shared::SPSSequence< shared::SPSString >) CallMainSPSSig
Definition Calls.h:109
int32_t(shared::SPSExecutorAddr) CallInt32VoidSPSSig
Definition Calls.h:123
RTTIExtends< ObjectTransformLayer, ObjectLayer > BaseT