1//===- LookupAndApply.cpp - Compose a lookup from handlers ----------------===//
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#include "llvm/ExecutionEngine/Orc/LookupAndApply.h"
10
11#include "llvm/Support/MSVCErrorWorkarounds.h"
12
13#include <future>
14
15namespace llvm::orc {
16
17void lookupAndApply(unique_function<void(Error)> OnApplied,
18 ExecutionSession &ES, LookupKind K,
19 const JITDylibSearchOrder &SearchOrder,
20 ArrayRef<LookupPrepareFn> PrepareFns) {
21 // Collect the symbols to look up. Each prepare function hands back the
22 // applicator that will act on the result; the prepare functions themselves
23 // are not needed beyond this point.
24 SymbolLookupSet Symbols;
25 std::vector<LookupApplyFn> Applies;
26 Applies.reserve(n: PrepareFns.size());
27 for (const auto &PF : PrepareFns)
28 Applies.push_back(x: PF(Symbols, ES));
29
30 // PrepareFns are independent, so two of them may legitimately ask for the
31 // same symbol. ExecutionSession::lookup requires a duplicate-free set, and
32 // the applicators read the result by name, so merging here is invisible to
33 // them.
34 Symbols.mergeEntries();
35
36 ES.lookup(
37 K, SearchOrder, Symbols: std::move(Symbols), RequiredState: SymbolState::Ready,
38 NotifyComplete: [Applies = std::move(Applies),
39 OnApplied = std::move(OnApplied)](Expected<SymbolMap> Result) mutable {
40 if (!Result)
41 return OnApplied(Result.takeError());
42 for (auto &Apply : Applies)
43 Apply(*Result);
44 OnApplied(Error::success());
45 },
46 RegisterDependencies: NoDependenciesToRegister);
47}
48
49Error lookupAndApply(ExecutionSession &ES, LookupKind K,
50 const JITDylibSearchOrder &SearchOrder,
51 ArrayRef<LookupPrepareFn> PrepareFns) {
52 std::promise<MSVCPError> ResultP;
53 auto ResultF = ResultP.get_future();
54 lookupAndApply(OnApplied: [&](Error Err) { ResultP.set_value(std::move(Err)); }, ES, K,
55 SearchOrder, PrepareFns);
56 return ResultF.get();
57}
58
59void lookupAndApply(unique_function<void(Error)> OnApplied, JITDylib &JD,
60 ArrayRef<LookupPrepareFn> PrepareFns) {
61 lookupAndApply(OnApplied: std::move(OnApplied), ES&: JD.getExecutionSession(),
62 K: LookupKind::Static, SearchOrder: makeJITDylibSearchOrder(JDs: &JD), PrepareFns);
63}
64
65Error lookupAndApply(JITDylib &JD, ArrayRef<LookupPrepareFn> PrepareFns) {
66 return lookupAndApply(ES&: JD.getExecutionSession(), K: LookupKind::Static,
67 SearchOrder: makeJITDylibSearchOrder(JDs: &JD), PrepareFns);
68}
69
70} // namespace llvm::orc
71