LLVM 24.0.0git
Proxy.h
Go to the documentation of this file.
1//===------- Proxy.h - Protocol-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// Protocol-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.
13//
14// This header provides only the core Proxy machinery. A Proxy's dispatch
15// function is supplied by a spec for some concrete protocol -- see
16// SPSProxySpec.h for the Simple Packed Serialization implementation. Named
17// proxies for specific operation families live alongside the utilities that use
18// them (e.g. CallProxies.h, EPCGenericMemoryAccess.h).
19//
20//===----------------------------------------------------------------------===//
21
22#ifndef LLVM_EXECUTIONENGINE_ORC_PROXY_H
23#define LLVM_EXECUTIONENGINE_ORC_PROXY_H
24
28#include "llvm/Support/Error.h"
30
31#include <future>
32#include <type_traits>
33
34namespace llvm::orc {
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/// Protocol-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. 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} // namespace llvm::orc
209
210#endif // LLVM_EXECUTIONENGINE_ORC_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)
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
const ExecutorAddr & calleeAddr() const
Returns the address of the callee in the executor.
Definition Proxy.h:42
ProxyBase(ExecutorAddr CalleeAddr)
Definition Proxy.h:39
void(*)(unique_function< void(ErrorRetT)> OnComplete, ExecutionSession &ES, ExecutorAddr Callee, const ArgTs &...Args) DispatchFn
Definition Proxy.h:110
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
Proxy(DispatchFn Dispatch, ExecutorAddr CalleeAddr)
Definition Proxy.h:115
static Expected< Proxy > Create(DispatchFn Dispatch, JITDylib &JD, StringRef Name, SymbolLookupFlags LF)
Definition Proxy.h:118
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
static Expected< Proxy > Create(DispatchFn Dispatch, ExecutionSession &ES, StringRef Name, SymbolLookupFlags LF)
Definition Proxy.h:131
RetT CalleeRetT
The result type produced by the executor-side function itself.
Definition Proxy.h:102
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
A set of symbols to look up, each associated with a SymbolLookupFlags value.
unique_function is a type-erasing functor similar to std::function.
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
ProxyInit< FnT > proxyInit(Proxy< FnT > *P, typename Proxy< FnT >::DispatchFn Dispatch, StringRef Name, SymbolLookupFlags LookupFlags=SymbolLookupFlags::RequiredSymbol)
Definition Proxy.h:168
SymbolLookupFlags
Lookup flags that apply to each symbol in a lookup.
Error buildProxies(JITDylib &JD)
buildProxies base case.
Definition Proxy.h:189
Proxy< FnT >::DispatchFn Dispatch
Definition Proxy.h:161
SymbolLookupFlags LookupFlags
Definition Proxy.h:163
StringRef Name
Definition Proxy.h:162
Proxy< FnT > * P
Definition Proxy.h:160
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