1 //===------ RemoteObjectLayer.h - Forwards objs to a remote -----*- 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 // Forwards objects to a remote object layer via RPC.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H
14 #define LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H
15
16 #include "llvm/ExecutionEngine/Orc/Core.h"
17 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
18 #include "llvm/ExecutionEngine/Orc/OrcRemoteTargetRPCAPI.h"
19 #include "llvm/Object/ObjectFile.h"
20 #include <map>
21
22 namespace llvm {
23 namespace orc {
24
25 /// RPC API needed by RemoteObjectClientLayer and RemoteObjectServerLayer.
26 class RemoteObjectLayerAPI {
27 public:
28
29 using ObjHandleT = remote::ResourceIdMgr::ResourceId;
30
31 protected:
32
33 using RemoteSymbolId = remote::ResourceIdMgr::ResourceId;
34 using RemoteSymbol = std::pair<RemoteSymbolId, JITSymbolFlags>;
35
36 public:
37
38 using BadSymbolHandleError = remote::ResourceNotFound<RemoteSymbolId>;
39 using BadObjectHandleError = remote::ResourceNotFound<ObjHandleT>;
40
41 protected:
42
43 static const ObjHandleT InvalidObjectHandleId = 0;
44 static const RemoteSymbolId NullSymbolId = 0;
45
46 class AddObject
47 : public rpc::Function<AddObject, Expected<ObjHandleT>(std::string)> {
48 public:
getName()49 static const char *getName() { return "AddObject"; }
50 };
51
52 class RemoveObject
53 : public rpc::Function<RemoveObject, Error(ObjHandleT)> {
54 public:
getName()55 static const char *getName() { return "RemoveObject"; }
56 };
57
58 class FindSymbol
59 : public rpc::Function<FindSymbol, Expected<RemoteSymbol>(std::string,
60 bool)> {
61 public:
getName()62 static const char *getName() { return "FindSymbol"; }
63 };
64
65 class FindSymbolIn
66 : public rpc::Function<FindSymbolIn,
67 Expected<RemoteSymbol>(ObjHandleT, std::string,
68 bool)> {
69 public:
getName()70 static const char *getName() { return "FindSymbolIn"; }
71 };
72
73 class EmitAndFinalize
74 : public rpc::Function<EmitAndFinalize,
75 Error(ObjHandleT)> {
76 public:
getName()77 static const char *getName() { return "EmitAndFinalize"; }
78 };
79
80 class Lookup
81 : public rpc::Function<Lookup,
82 Expected<RemoteSymbol>(ObjHandleT, std::string)> {
83 public:
getName()84 static const char *getName() { return "Lookup"; }
85 };
86
87 class LookupInLogicalDylib
88 : public rpc::Function<LookupInLogicalDylib,
89 Expected<RemoteSymbol>(ObjHandleT, std::string)> {
90 public:
getName()91 static const char *getName() { return "LookupInLogicalDylib"; }
92 };
93
94 class ReleaseRemoteSymbol
95 : public rpc::Function<ReleaseRemoteSymbol, Error(RemoteSymbolId)> {
96 public:
getName()97 static const char *getName() { return "ReleaseRemoteSymbol"; }
98 };
99
100 class MaterializeRemoteSymbol
101 : public rpc::Function<MaterializeRemoteSymbol,
102 Expected<JITTargetAddress>(RemoteSymbolId)> {
103 public:
getName()104 static const char *getName() { return "MaterializeRemoteSymbol"; }
105 };
106 };
107
108 /// Base class containing common utilities for RemoteObjectClientLayer and
109 /// RemoteObjectServerLayer.
110 template <typename RPCEndpoint>
111 class RemoteObjectLayer : public RemoteObjectLayerAPI {
112 public:
113
RemoteObjectLayer(RPCEndpoint & Remote,std::function<void (Error)> ReportError)114 RemoteObjectLayer(RPCEndpoint &Remote,
115 std::function<void(Error)> ReportError)
116 : Remote(Remote), ReportError(std::move(ReportError)),
117 SymbolIdMgr(NullSymbolId + 1) {
118 using ThisT = RemoteObjectLayer<RPCEndpoint>;
119 Remote.template addHandler<ReleaseRemoteSymbol>(
120 *this, &ThisT::handleReleaseRemoteSymbol);
121 Remote.template addHandler<MaterializeRemoteSymbol>(
122 *this, &ThisT::handleMaterializeRemoteSymbol);
123 }
124
125 protected:
126
127 /// This class is used as the symbol materializer for JITSymbols returned by
128 /// RemoteObjectLayerClient/RemoteObjectLayerServer -- the materializer knows
129 /// how to call back to the other RPC endpoint to get the address when
130 /// requested.
131 class RemoteSymbolMaterializer {
132 public:
133
134 /// Construct a RemoteSymbolMaterializer for the given RemoteObjectLayer
135 /// with the given Id.
RemoteSymbolMaterializer(RemoteObjectLayer & C,RemoteSymbolId Id)136 RemoteSymbolMaterializer(RemoteObjectLayer &C,
137 RemoteSymbolId Id)
138 : C(C), Id(Id) {}
139
RemoteSymbolMaterializer(RemoteSymbolMaterializer && Other)140 RemoteSymbolMaterializer(RemoteSymbolMaterializer &&Other)
141 : C(Other.C), Id(Other.Id) {
142 Other.Id = 0;
143 }
144
145 RemoteSymbolMaterializer &operator=(RemoteSymbolMaterializer &&) = delete;
146
147 /// Release the remote symbol.
~RemoteSymbolMaterializer()148 ~RemoteSymbolMaterializer() {
149 if (Id)
150 C.releaseRemoteSymbol(Id);
151 }
152
153 /// Materialize the symbol on the remote and get its address.
materialize()154 Expected<JITTargetAddress> materialize() {
155 auto Addr = C.materializeRemoteSymbol(Id);
156 Id = 0;
157 return Addr;
158 }
159
160 private:
161 RemoteObjectLayer &C;
162 RemoteSymbolId Id;
163 };
164
165 /// Convenience function for getting a null remote symbol value.
nullRemoteSymbol()166 RemoteSymbol nullRemoteSymbol() {
167 return RemoteSymbol(0, JITSymbolFlags());
168 }
169
170 /// Creates a StringError that contains a copy of Err's log message, then
171 /// sends that StringError to ReportError.
172 ///
173 /// This allows us to locally log error messages for errors that will actually
174 /// be delivered to the remote.
teeLog(Error Err)175 Error teeLog(Error Err) {
176 return handleErrors(std::move(Err),
177 [this](std::unique_ptr<ErrorInfoBase> EIB) {
178 ReportError(make_error<StringError>(
179 EIB->message(),
180 EIB->convertToErrorCode()));
181 return Error(std::move(EIB));
182 });
183 }
184
badRemoteSymbolIdError(RemoteSymbolId Id)185 Error badRemoteSymbolIdError(RemoteSymbolId Id) {
186 return make_error<BadSymbolHandleError>(Id, "Remote JIT Symbol");
187 }
188
badObjectHandleError(ObjHandleT H)189 Error badObjectHandleError(ObjHandleT H) {
190 return make_error<RemoteObjectLayerAPI::BadObjectHandleError>(
191 H, "Bad object handle");
192 }
193
194 /// Create a RemoteSymbol wrapping the given JITSymbol.
jitSymbolToRemote(JITSymbol Sym)195 Expected<RemoteSymbol> jitSymbolToRemote(JITSymbol Sym) {
196 if (Sym) {
197 auto Id = SymbolIdMgr.getNext();
198 auto Flags = Sym.getFlags();
199 assert(!InUseSymbols.count(Id) && "Symbol id already in use");
200 InUseSymbols.insert(std::make_pair(Id, std::move(Sym)));
201 return RemoteSymbol(Id, Flags);
202 } else if (auto Err = Sym.takeError())
203 return teeLog(std::move(Err));
204 // else...
205 return nullRemoteSymbol();
206 }
207
208 /// Convert an Expected<RemoteSymbol> to a JITSymbol.
remoteToJITSymbol(Expected<RemoteSymbol> RemoteSymOrErr)209 JITSymbol remoteToJITSymbol(Expected<RemoteSymbol> RemoteSymOrErr) {
210 if (RemoteSymOrErr) {
211 auto &RemoteSym = *RemoteSymOrErr;
212 if (RemoteSym == nullRemoteSymbol())
213 return nullptr;
214 // else...
215 RemoteSymbolMaterializer RSM(*this, RemoteSym.first);
216 auto Sym = JITSymbol(
217 [RSM = std::move(RSM)]() mutable { return RSM.materialize(); },
218 RemoteSym.second);
219 return Sym;
220 } else
221 return RemoteSymOrErr.takeError();
222 }
223
224 RPCEndpoint &Remote;
225 std::function<void(Error)> ReportError;
226
227 private:
228
229 /// Notify the remote to release the given JITSymbol.
releaseRemoteSymbol(RemoteSymbolId Id)230 void releaseRemoteSymbol(RemoteSymbolId Id) {
231 if (auto Err = Remote.template callB<ReleaseRemoteSymbol>(Id))
232 ReportError(std::move(Err));
233 }
234
235 /// Notify the remote to materialize the JITSymbol with the given Id and
236 /// return its address.
materializeRemoteSymbol(RemoteSymbolId Id)237 Expected<JITTargetAddress> materializeRemoteSymbol(RemoteSymbolId Id) {
238 return Remote.template callB<MaterializeRemoteSymbol>(Id);
239 }
240
241 /// Release the JITSymbol with the given Id.
handleReleaseRemoteSymbol(RemoteSymbolId Id)242 Error handleReleaseRemoteSymbol(RemoteSymbolId Id) {
243 auto SI = InUseSymbols.find(Id);
244 if (SI != InUseSymbols.end()) {
245 InUseSymbols.erase(SI);
246 return Error::success();
247 } else
248 return teeLog(badRemoteSymbolIdError(Id));
249 }
250
251 /// Run the materializer for the JITSymbol with the given Id and return its
252 /// address.
handleMaterializeRemoteSymbol(RemoteSymbolId Id)253 Expected<JITTargetAddress> handleMaterializeRemoteSymbol(RemoteSymbolId Id) {
254 auto SI = InUseSymbols.find(Id);
255 if (SI != InUseSymbols.end()) {
256 auto AddrOrErr = SI->second.getAddress();
257 InUseSymbols.erase(SI);
258 SymbolIdMgr.release(Id);
259 if (AddrOrErr)
260 return *AddrOrErr;
261 else
262 return teeLog(AddrOrErr.takeError());
263 } else {
264 return teeLog(badRemoteSymbolIdError(Id));
265 }
266 }
267
268 remote::ResourceIdMgr SymbolIdMgr;
269 std::map<RemoteSymbolId, JITSymbol> InUseSymbols;
270 };
271
272 /// RemoteObjectClientLayer forwards the ORC Object Layer API over an RPC
273 /// connection.
274 ///
275 /// This class can be used as the base layer of a JIT stack on the client and
276 /// will forward operations to a corresponding RemoteObjectServerLayer on the
277 /// server (which can be composed on top of a "real" object layer like
278 /// RTDyldObjectLinkingLayer to actually carry out the operations).
279 ///
280 /// Sending relocatable objects to the server (rather than fully relocated
281 /// bits) allows JIT'd code to be cached on the server side and re-used in
282 /// subsequent JIT sessions.
283 template <typename RPCEndpoint>
284 class RemoteObjectClientLayer : public RemoteObjectLayer<RPCEndpoint> {
285 private:
286
287 using AddObject = RemoteObjectLayerAPI::AddObject;
288 using RemoveObject = RemoteObjectLayerAPI::RemoveObject;
289 using FindSymbol = RemoteObjectLayerAPI::FindSymbol;
290 using FindSymbolIn = RemoteObjectLayerAPI::FindSymbolIn;
291 using EmitAndFinalize = RemoteObjectLayerAPI::EmitAndFinalize;
292 using Lookup = RemoteObjectLayerAPI::Lookup;
293 using LookupInLogicalDylib = RemoteObjectLayerAPI::LookupInLogicalDylib;
294
295 using RemoteObjectLayer<RPCEndpoint>::teeLog;
296 using RemoteObjectLayer<RPCEndpoint>::badObjectHandleError;
297 using RemoteObjectLayer<RPCEndpoint>::remoteToJITSymbol;
298
299 public:
300
301 using ObjHandleT = RemoteObjectLayerAPI::ObjHandleT;
302 using RemoteSymbol = RemoteObjectLayerAPI::RemoteSymbol;
303
304 using ObjectPtr = std::unique_ptr<MemoryBuffer>;
305
306 /// Create a RemoteObjectClientLayer that communicates with a
307 /// RemoteObjectServerLayer instance via the given RPCEndpoint.
308 ///
309 /// The ReportError functor can be used locally log errors that are intended
310 /// to be sent sent
311 LLVM_ATTRIBUTE_DEPRECATED(
312 RemoteObjectClientLayer(RPCEndpoint &Remote,
313 std::function<void(Error)> ReportError),
314 "ORCv1 layers (including RemoteObjectClientLayer) are deprecated. Please "
315 "use "
316 "ORCv2 (see docs/ORCv2.rst)");
317
RemoteObjectClientLayer(ORCv1DeprecationAcknowledgement,RPCEndpoint & Remote,std::function<void (Error)> ReportError)318 RemoteObjectClientLayer(ORCv1DeprecationAcknowledgement, RPCEndpoint &Remote,
319 std::function<void(Error)> ReportError)
320 : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)) {
321 using ThisT = RemoteObjectClientLayer<RPCEndpoint>;
322 Remote.template addHandler<Lookup>(*this, &ThisT::lookup);
323 Remote.template addHandler<LookupInLogicalDylib>(
324 *this, &ThisT::lookupInLogicalDylib);
325 }
326
327 /// Add an object to the JIT.
328 ///
329 /// @return A handle that can be used to refer to the loaded object (for
330 /// symbol searching, finalization, freeing memory, etc.).
331 Expected<ObjHandleT>
addObject(ObjectPtr ObjBuffer,std::shared_ptr<LegacyJITSymbolResolver> Resolver)332 addObject(ObjectPtr ObjBuffer,
333 std::shared_ptr<LegacyJITSymbolResolver> Resolver) {
334 if (auto HandleOrErr =
335 this->Remote.template callB<AddObject>(ObjBuffer->getBuffer())) {
336 auto &Handle = *HandleOrErr;
337 // FIXME: Return an error for this:
338 assert(!Resolvers.count(Handle) && "Handle already in use?");
339 Resolvers[Handle] = std::move(Resolver);
340 return Handle;
341 } else
342 return HandleOrErr.takeError();
343 }
344
345 /// Remove the given object from the JIT.
removeObject(ObjHandleT H)346 Error removeObject(ObjHandleT H) {
347 return this->Remote.template callB<RemoveObject>(H);
348 }
349
350 /// Search for the given named symbol.
findSymbol(StringRef Name,bool ExportedSymbolsOnly)351 JITSymbol findSymbol(StringRef Name, bool ExportedSymbolsOnly) {
352 return remoteToJITSymbol(
353 this->Remote.template callB<FindSymbol>(Name,
354 ExportedSymbolsOnly));
355 }
356
357 /// Search for the given named symbol within the given context.
findSymbolIn(ObjHandleT H,StringRef Name,bool ExportedSymbolsOnly)358 JITSymbol findSymbolIn(ObjHandleT H, StringRef Name, bool ExportedSymbolsOnly) {
359 return remoteToJITSymbol(
360 this->Remote.template callB<FindSymbolIn>(H, Name,
361 ExportedSymbolsOnly));
362 }
363
364 /// Immediately emit and finalize the object with the given handle.
emitAndFinalize(ObjHandleT H)365 Error emitAndFinalize(ObjHandleT H) {
366 return this->Remote.template callB<EmitAndFinalize>(H);
367 }
368
369 private:
370
lookup(ObjHandleT H,const std::string & Name)371 Expected<RemoteSymbol> lookup(ObjHandleT H, const std::string &Name) {
372 auto RI = Resolvers.find(H);
373 if (RI != Resolvers.end()) {
374 return this->jitSymbolToRemote(RI->second->findSymbol(Name));
375 } else
376 return teeLog(badObjectHandleError(H));
377 }
378
lookupInLogicalDylib(ObjHandleT H,const std::string & Name)379 Expected<RemoteSymbol> lookupInLogicalDylib(ObjHandleT H,
380 const std::string &Name) {
381 auto RI = Resolvers.find(H);
382 if (RI != Resolvers.end())
383 return this->jitSymbolToRemote(
384 RI->second->findSymbolInLogicalDylib(Name));
385 else
386 return teeLog(badObjectHandleError(H));
387 }
388
389 std::map<remote::ResourceIdMgr::ResourceId,
390 std::shared_ptr<LegacyJITSymbolResolver>>
391 Resolvers;
392 };
393
394 /// RemoteObjectServerLayer acts as a server and handling RPC calls for the
395 /// object layer API from the given RPC connection.
396 ///
397 /// This class can be composed on top of a 'real' object layer (e.g.
398 /// RTDyldObjectLinkingLayer) to do the actual work of relocating objects
399 /// and making them executable.
400 template <typename BaseLayerT, typename RPCEndpoint>
401 class RemoteObjectServerLayer : public RemoteObjectLayer<RPCEndpoint> {
402 private:
403
404 using ObjHandleT = RemoteObjectLayerAPI::ObjHandleT;
405 using RemoteSymbol = RemoteObjectLayerAPI::RemoteSymbol;
406
407 using AddObject = RemoteObjectLayerAPI::AddObject;
408 using RemoveObject = RemoteObjectLayerAPI::RemoveObject;
409 using FindSymbol = RemoteObjectLayerAPI::FindSymbol;
410 using FindSymbolIn = RemoteObjectLayerAPI::FindSymbolIn;
411 using EmitAndFinalize = RemoteObjectLayerAPI::EmitAndFinalize;
412 using Lookup = RemoteObjectLayerAPI::Lookup;
413 using LookupInLogicalDylib = RemoteObjectLayerAPI::LookupInLogicalDylib;
414
415 using RemoteObjectLayer<RPCEndpoint>::teeLog;
416 using RemoteObjectLayer<RPCEndpoint>::badObjectHandleError;
417 using RemoteObjectLayer<RPCEndpoint>::remoteToJITSymbol;
418
419 public:
420
421 /// Create a RemoteObjectServerLayer with the given base layer (which must be
422 /// an object layer), RPC endpoint, and error reporter function.
423 LLVM_ATTRIBUTE_DEPRECATED(
424 RemoteObjectServerLayer(BaseLayerT &BaseLayer, RPCEndpoint &Remote,
425 std::function<void(Error)> ReportError),
426 "ORCv1 layers (including RemoteObjectServerLayer) are deprecated. Please "
427 "use "
428 "ORCv2 (see docs/ORCv2.rst)");
429
RemoteObjectServerLayer(ORCv1DeprecationAcknowledgement,BaseLayerT & BaseLayer,RPCEndpoint & Remote,std::function<void (Error)> ReportError)430 RemoteObjectServerLayer(ORCv1DeprecationAcknowledgement,
431 BaseLayerT &BaseLayer, RPCEndpoint &Remote,
432 std::function<void(Error)> ReportError)
433 : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)),
434 BaseLayer(BaseLayer), HandleIdMgr(1) {
435 using ThisT = RemoteObjectServerLayer<BaseLayerT, RPCEndpoint>;
436
437 Remote.template addHandler<AddObject>(*this, &ThisT::addObject);
438 Remote.template addHandler<RemoveObject>(*this, &ThisT::removeObject);
439 Remote.template addHandler<FindSymbol>(*this, &ThisT::findSymbol);
440 Remote.template addHandler<FindSymbolIn>(*this, &ThisT::findSymbolIn);
441 Remote.template addHandler<EmitAndFinalize>(*this, &ThisT::emitAndFinalize);
442 }
443
444 private:
445
446 class StringMemoryBuffer : public MemoryBuffer {
447 public:
StringMemoryBuffer(std::string Buffer)448 StringMemoryBuffer(std::string Buffer)
449 : Buffer(std::move(Buffer)) {
450 init(this->Buffer.data(), this->Buffer.data() + this->Buffer.size(),
451 false);
452 }
453
getBufferKind()454 BufferKind getBufferKind() const override { return MemoryBuffer_Malloc; }
455 private:
456 std::string Buffer;
457 };
458
lookup(ObjHandleT Id,const std::string & Name)459 JITSymbol lookup(ObjHandleT Id, const std::string &Name) {
460 return remoteToJITSymbol(
461 this->Remote.template callB<Lookup>(Id, Name));
462 }
463
lookupInLogicalDylib(ObjHandleT Id,const std::string & Name)464 JITSymbol lookupInLogicalDylib(ObjHandleT Id, const std::string &Name) {
465 return remoteToJITSymbol(
466 this->Remote.template callB<LookupInLogicalDylib>(Id, Name));
467 }
468
addObject(std::string ObjBuffer)469 Expected<ObjHandleT> addObject(std::string ObjBuffer) {
470 auto Buffer = std::make_unique<StringMemoryBuffer>(std::move(ObjBuffer));
471 auto Id = HandleIdMgr.getNext();
472 assert(!BaseLayerHandles.count(Id) && "Id already in use?");
473
474 auto Resolver = createLambdaResolver(
475 AcknowledgeORCv1Deprecation,
476 [this, Id](const std::string &Name) { return lookup(Id, Name); },
477 [this, Id](const std::string &Name) {
478 return lookupInLogicalDylib(Id, Name);
479 });
480
481 if (auto HandleOrErr =
482 BaseLayer.addObject(std::move(Buffer), std::move(Resolver))) {
483 BaseLayerHandles[Id] = std::move(*HandleOrErr);
484 return Id;
485 } else
486 return teeLog(HandleOrErr.takeError());
487 }
488
removeObject(ObjHandleT H)489 Error removeObject(ObjHandleT H) {
490 auto HI = BaseLayerHandles.find(H);
491 if (HI != BaseLayerHandles.end()) {
492 if (auto Err = BaseLayer.removeObject(HI->second))
493 return teeLog(std::move(Err));
494 return Error::success();
495 } else
496 return teeLog(badObjectHandleError(H));
497 }
498
findSymbol(const std::string & Name,bool ExportedSymbolsOnly)499 Expected<RemoteSymbol> findSymbol(const std::string &Name,
500 bool ExportedSymbolsOnly) {
501 if (auto Sym = BaseLayer.findSymbol(Name, ExportedSymbolsOnly))
502 return this->jitSymbolToRemote(std::move(Sym));
503 else if (auto Err = Sym.takeError())
504 return teeLog(std::move(Err));
505 return this->nullRemoteSymbol();
506 }
507
findSymbolIn(ObjHandleT H,const std::string & Name,bool ExportedSymbolsOnly)508 Expected<RemoteSymbol> findSymbolIn(ObjHandleT H, const std::string &Name,
509 bool ExportedSymbolsOnly) {
510 auto HI = BaseLayerHandles.find(H);
511 if (HI != BaseLayerHandles.end()) {
512 if (auto Sym = BaseLayer.findSymbolIn(HI->second, Name, ExportedSymbolsOnly))
513 return this->jitSymbolToRemote(std::move(Sym));
514 else if (auto Err = Sym.takeError())
515 return teeLog(std::move(Err));
516 return this->nullRemoteSymbol();
517 } else
518 return teeLog(badObjectHandleError(H));
519 }
520
emitAndFinalize(ObjHandleT H)521 Error emitAndFinalize(ObjHandleT H) {
522 auto HI = BaseLayerHandles.find(H);
523 if (HI != BaseLayerHandles.end()) {
524 if (auto Err = BaseLayer.emitAndFinalize(HI->second))
525 return teeLog(std::move(Err));
526 return Error::success();
527 } else
528 return teeLog(badObjectHandleError(H));
529 }
530
531 BaseLayerT &BaseLayer;
532 remote::ResourceIdMgr HandleIdMgr;
533 std::map<ObjHandleT, typename BaseLayerT::ObjHandleT> BaseLayerHandles;
534 };
535
536 template <typename RPCEndpoint>
RemoteObjectClientLayer(RPCEndpoint & Remote,std::function<void (Error)> ReportError)537 RemoteObjectClientLayer<RPCEndpoint>::RemoteObjectClientLayer(
538 RPCEndpoint &Remote, std::function<void(Error)> ReportError)
539 : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)) {
540 using ThisT = RemoteObjectClientLayer<RPCEndpoint>;
541 Remote.template addHandler<Lookup>(*this, &ThisT::lookup);
542 Remote.template addHandler<LookupInLogicalDylib>(
543 *this, &ThisT::lookupInLogicalDylib);
544 }
545
546 template <typename BaseLayerT, typename RPCEndpoint>
RemoteObjectServerLayer(BaseLayerT & BaseLayer,RPCEndpoint & Remote,std::function<void (Error)> ReportError)547 RemoteObjectServerLayer<BaseLayerT, RPCEndpoint>::RemoteObjectServerLayer(
548 BaseLayerT &BaseLayer, RPCEndpoint &Remote,
549 std::function<void(Error)> ReportError)
550 : RemoteObjectLayer<RPCEndpoint>(Remote, std::move(ReportError)),
551 BaseLayer(BaseLayer), HandleIdMgr(1) {
552 using ThisT = RemoteObjectServerLayer<BaseLayerT, RPCEndpoint>;
553
554 Remote.template addHandler<AddObject>(*this, &ThisT::addObject);
555 Remote.template addHandler<RemoveObject>(*this, &ThisT::removeObject);
556 Remote.template addHandler<FindSymbol>(*this, &ThisT::findSymbol);
557 Remote.template addHandler<FindSymbolIn>(*this, &ThisT::findSymbolIn);
558 Remote.template addHandler<EmitAndFinalize>(*this, &ThisT::emitAndFinalize);
559 }
560
561 } // end namespace orc
562 } // end namespace llvm
563
564 #endif // LLVM_EXECUTIONENGINE_ORC_REMOTEOBJECTLAYER_H
565