LLVM 24.0.0git
Proxy.h
Go to the documentation of this file.
1//===------- Proxy.h - Runtime-agnostic executor call APIs ------*- 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// Runtime-agnostic interfaces for invoking executor-side operations. These
10// abstract over how a call reaches the executor, so clients can be written
11// once and used whether the operation is provided by a full ORC runtime or by
12// LLVM's own ORC-runtime-lite. Concrete implementations live in subdirectories
13// (e.g. RTBridge/SPS).
14//
15//===----------------------------------------------------------------------===//
16
17#ifndef LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_PROXY_H
18#define LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_PROXY_H
19
20#include "llvm/ADT/ArrayRef.h"
25#include "llvm/Support/Error.h"
27
28#include <cstdint>
29#include <future>
30#include <string>
31#include <type_traits>
32#include <vector>
33
34namespace llvm::orc::rt {
35
36class ProxyBase {
37public:
38 ProxyBase() = default;
39 ProxyBase(ExecutorAddr CalleeAddr) : CalleeAddr(CalleeAddr) {}
40
41 /// Returns the address of the callee in the executor.
42 const ExecutorAddr &calleeAddr() const { return CalleeAddr; }
43
44 /// Evaluates to true if the callee is non-null.
45 explicit operator bool() const { return !!CalleeAddr; }
46
47private:
48 ExecutorAddr CalleeAddr;
49};
50
51template <typename FnT> class Proxy;
52
53namespace detail {
54
55/// Maps a proxy's callee return type to the type delivered to the client, so a
56/// dispatch failure can always be reported alongside the result:
57///
58/// void -> Error
59/// Error -> Error
60/// T -> Expected<T>
61/// Expected<T> -> Expected<T>
62template <typename T> struct ProxyErrorRet {
64};
65template <> struct ProxyErrorRet<void> {
66 using type = Error;
67};
68template <> struct ProxyErrorRet<Error> {
69 using type = Error;
70};
71template <typename T> struct ProxyErrorRet<Expected<T>> {
73};
74
75/// Maps a proxy's client-facing return type to the std::promise value type used
76/// by the blocking call operator (working around MSVC's std::promise).
77template <typename T> struct ProxyRetPromise;
78template <> struct ProxyRetPromise<Error> {
79 using type = std::promise<MSVCPError>;
80};
81template <typename T> struct ProxyRetPromise<Expected<T>> {
82 using type = std::promise<MSVCPExpected<T>>;
83};
84
85} // namespace detail
86
87/// Runtime-agnostic interface for invoking an executor-side operation with the
88/// signature RetT(ArgTs...).
89///
90/// Two call operators are provided: an asynchronous form that delivers the
91/// result to an OnComplete continuation, and a synchronous form that blocks
92/// until the result is available.
93///
94/// A Proxy abstracts over how the operation is dispatched to the executor. Its
95/// dispatch function is supplied by a spec (e.g. rt::sps::ProxySpec).
96template <typename RetT, typename... ArgTs>
97class Proxy<RetT(ArgTs...)> : public ProxyBase {
98public:
99 using FnType = RetT(ArgTs...);
100
101 /// The result type produced by the executor-side function itself.
102 using CalleeRetT = RetT;
103
104 /// The result type delivered to the client: Error when the callee returns
105 /// void or Error, otherwise Expected<T> (with Expected<T> callees flattened
106 /// rather than nested), so that dispatch failures can be reported alongside
107 /// the result.
109
110 using DispatchFn = void (*)(unique_function<void(ErrorRetT)> OnComplete,
111 ExecutionSession &ES, ExecutorAddr Callee,
112 const ArgTs &...Args);
113
114 Proxy() = default;
115 Proxy(DispatchFn Dispatch, ExecutorAddr CalleeAddr)
116 : ProxyBase(CalleeAddr), Dispatch(Dispatch) {}
117
119 StringRef Name, SymbolLookupFlags LF) {
120 auto &ES = JD.getExecutionSession();
121 if (auto CalleeSyms = ES.lookup(makeJITDylibSearchOrder(&JD),
122 SymbolLookupSet{ES.intern(Name), LF})) {
123 if (!CalleeSyms->empty())
124 return Proxy(Dispatch, CalleeSyms->begin()->second.getAddress());
126 return Proxy();
127 } else
128 return CalleeSyms.takeError();
129 }
130
132 StringRef Name, SymbolLookupFlags LF) {
133 return Create(Dispatch, ES.getBootstrapJITDylib(), Name, LF);
134 }
135
136 /// Asynchronously invoke the operation with the given Args, delivering its
137 /// result (or an error) to OnComplete.
138 void operator()(unique_function<void(ErrorRetT)> OnComplete,
139 ExecutionSession &ES, const ArgTs &...Args) const {
140 assert(Dispatch && "Proxy's Dispatch member is not set");
141 Dispatch(std::move(OnComplete), ES, calleeAddr(), Args...);
142 }
143
144 /// Invoke the operation with the given Args, blocking until its result (or an
145 /// error) is available.
146 ErrorRetT operator()(ExecutionSession &ES, const ArgTs &...Args) const {
148 auto F = P.get_future();
149 this->operator()(
150 [P = std::move(P)](ErrorRetT R) mutable { P.set_value(std::move(R)); },
151 ES, Args...);
152 return F.get();
153 }
154
155private:
156 DispatchFn Dispatch = nullptr;
157};
158
165
166template <typename FnT>
169 StringRef Name,
171 return {P, Dispatch, Name, LookupFlags};
172}
173
174template <typename ProxySpecT, typename FnT>
175ProxyInit<FnT>
178 return {P, ProxySpecT::dispatch, ProxySpecT::Name, LookupFlags};
179}
180
181template <typename ProxySpecT, typename FnT>
182ProxyInit<FnT>
185 return {P, ProxySpecT::dispatch, Name, LookupFlags};
186}
187
188/// buildProxies base case.
189inline Error buildProxies(JITDylib &JD) { return Error::success(); }
190
191/// buildProxies: Given an ExecutionSession, use BootstrapJITDylib.
192template <typename... FnTs>
196
197/// Build a sequence of proxies from their respective specs.
198template <typename FnT, typename... FnTs>
200 if (auto POrErr =
202 *PI.P = std::move(*POrErr);
203 else
204 return POrErr.takeError();
205 return buildProxies(JD, PIs...);
206}
207
208/// Runtime-agnostic interface for running a main-like function
209/// (int(int argc, char *argv[])) in the executor.
210///
211/// The function to run is given by its ExecutorAddr, its arguments as an
212/// argument vector, and its int64_t result is returned.
214
215/// Runtime-agnostic interface for running a void() function in the executor.
216///
217/// The function to run is given by its ExecutorAddr.
218///
219/// WARNING: This Proxy is experimental and may be removed.
221
222/// Runtime-agnostic interface for running an int32_t() function in the
223/// executor.
224///
225/// The function to run is given by its ExecutorAddr.
226///
227/// WARNING: This Proxy is experimental and may be removed.
229
230/// Runtime-agnostic interface for running an int32_t(int32_t) function in the
231/// executor.
232///
233/// The function to run is given by its ExecutorAddr.
234///
235/// WARNING: This Proxy is experimental and may be removed.
236using CallInt32Int32Proxy = Proxy<int32_t(ExecutorAddr, int32_t)>;
237
238/// Runtime-agnostic interfaces for the memory-access operations. Unlike the
239/// Call* proxies above, these target wrappers that perform the operation
240/// directly, so they take the operation's data arguments rather than a callee
241/// address.
261
262} // namespace llvm::orc::rt
263
264#endif // LLVM_EXECUTIONENGINE_ORC_RTBRIDGE_PROXY_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file provides a collection of function (or more generally, callable) type erasure utilities supp...
#define F(x, y, z)
Definition MD5.cpp:54
#define T
#define P(N)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
An ExecutionSession represents a running JIT program.
Definition Core.h:1111
JITDylib & getBootstrapJITDylib()
Returns a reference to the bootstrap JITDylib.
Definition Core.h:1177
Represents an address in the executor process.
Represents a JIT'd dynamic library.
Definition Core.h:675
ExecutionSession & getExecutionSession() const
Get a reference to the ExecutionSession for this JITDylib.
Definition Core.h:694
A set of symbols to look up, each associated with a SymbolLookupFlags value.
ProxyBase(ExecutorAddr CalleeAddr)
Definition Proxy.h:39
const ExecutorAddr & calleeAddr() const
Returns the address of the callee in the executor.
Definition Proxy.h:42
static Expected< Proxy > Create(DispatchFn Dispatch, ExecutionSession &ES, StringRef Name, SymbolLookupFlags LF)
Definition Proxy.h:131
void(*)(unique_function< void(ErrorRetT)> OnComplete, ExecutionSession &ES, ExecutorAddr Callee, const ArgTs &...Args) DispatchFn
Definition Proxy.h:110
Proxy(DispatchFn Dispatch, ExecutorAddr CalleeAddr)
Definition Proxy.h:115
ErrorRetT operator()(ExecutionSession &ES, const ArgTs &...Args) const
Invoke the operation with the given Args, blocking until its result (or an error) is available.
Definition Proxy.h:146
static Expected< Proxy > Create(DispatchFn Dispatch, JITDylib &JD, StringRef Name, SymbolLookupFlags LF)
Definition Proxy.h:118
typename detail::ProxyErrorRet< RetT >::type ErrorRetT
The result type delivered to the client: Error when the callee returns void or Error,...
Definition Proxy.h:108
void operator()(unique_function< void(ErrorRetT)> OnComplete, ExecutionSession &ES, const ArgTs &...Args) const
Asynchronously invoke the operation with the given Args, delivering its result (or an error) to OnCom...
Definition Proxy.h:138
RetT CalleeRetT
The result type produced by the executor-side function itself.
Definition Proxy.h:102
unique_function is a type-erasing functor similar to std::function.
Proxy< void(ArrayRef< tpctypes::PointerWrite >)> MemWritePointersProxy
Definition Proxy.h:246
ProxyInit< FnT > proxyInit(Proxy< FnT > *P, typename Proxy< FnT >::DispatchFn Dispatch, StringRef Name, SymbolLookupFlags LookupFlags=SymbolLookupFlags::RequiredSymbol)
Definition Proxy.h:168
Proxy< std::vector< ExecutorAddr >(ArrayRef< ExecutorAddr >)> MemReadPointersProxy
Definition Proxy.h:255
Proxy< std::vector< uint8_t >(ArrayRef< ExecutorAddr >)> MemReadUInt8sProxy
Definition Proxy.h:248
Proxy< std::vector< uint32_t >(ArrayRef< ExecutorAddr >)> MemReadUInt32sProxy
Definition Proxy.h:251
Proxy< void(ExecutorAddr)> CallVoidVoidProxy
Runtime-agnostic interface for running a void() function in the executor.
Definition Proxy.h:220
Proxy< int32_t(ExecutorAddr, int32_t)> CallInt32Int32Proxy
Runtime-agnostic interface for running an int32_t(int32_t) function in the executor.
Definition Proxy.h:236
Proxy< std::vector< uint64_t >(ArrayRef< ExecutorAddr >)> MemReadUInt64sProxy
Definition Proxy.h:253
Proxy< std::vector< std::vector< uint8_t > >(ArrayRef< ExecutorAddrRange >)> MemReadBuffersProxy
Definition Proxy.h:257
Proxy< int32_t(ExecutorAddr)> CallInt32VoidProxy
Runtime-agnostic interface for running an int32_t() function in the executor.
Definition Proxy.h:228
Proxy< std::vector< std::string >(ArrayRef< ExecutorAddr >)> MemReadStringsProxy
Definition Proxy.h:259
Error buildProxies(JITDylib &JD)
buildProxies base case.
Definition Proxy.h:189
Proxy< void(ArrayRef< tpctypes::UInt64Write >)> MemWriteUInt64sProxy
Definition Proxy.h:245
Proxy< int64_t(ExecutorAddr, ArrayRef< std::string >)> CallMainProxy
Runtime-agnostic interface for running a main-like function (int(int argc, char *argv[])) in the exec...
Definition Proxy.h:213
Proxy< void(ArrayRef< tpctypes::UInt8Write >)> MemWriteUInt8sProxy
Runtime-agnostic interfaces for the memory-access operations.
Definition Proxy.h:242
Proxy< void(ArrayRef< tpctypes::UInt16Write >)> MemWriteUInt16sProxy
Definition Proxy.h:243
Proxy< std::vector< uint16_t >(ArrayRef< ExecutorAddr >)> MemReadUInt16sProxy
Definition Proxy.h:249
Proxy< void(ArrayRef< tpctypes::UInt32Write >)> MemWriteUInt32sProxy
Definition Proxy.h:244
Proxy< void(ArrayRef< tpctypes::BufferWrite >)> MemWriteBuffersProxy
Definition Proxy.h:247
JITDylibSearchOrder makeJITDylibSearchOrder(ArrayRef< JITDylib * > JDs, JITDylibLookupFlags Flags=JITDylibLookupFlags::MatchExportedSymbolsOnly)
Convenience function for creating a search order from an ArrayRef of JITDylib*, all with the same fla...
Definition Core.h:153
SymbolLookupFlags
Lookup flags that apply to each symbol in a lookup.
Proxy< FnT > * P
Definition Proxy.h:160
SymbolLookupFlags LookupFlags
Definition Proxy.h:163
Proxy< FnT >::DispatchFn Dispatch
Definition Proxy.h:161
Maps a proxy's callee return type to the type delivered to the client, so a dispatch failure can alwa...
Definition Proxy.h:62
std::promise< MSVCPError > type
Definition Proxy.h:79
std::promise< MSVCPExpected< T > > type
Definition Proxy.h:82
Maps a proxy's client-facing return type to the std::promise value type used by the blocking call ope...
Definition Proxy.h:77