| //===- LookupAndApply.cpp - Compose a lookup from handlers ----------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/ExecutionEngine/Orc/LookupAndApply.h" | |
| #include "llvm/Support/MSVCErrorWorkarounds.h" | |
| #include <future> | |
| namespace llvm::orc { | |
| void lookupAndApply(unique_function<void(Error)> OnApplied, LookupKind K, | |
| const JITDylibSearchOrder &SearchOrder, | |
| ArrayRef<LookupPrepareFn> PrepareFns) { | |
| /// Empty PrepareFns list trivially succeeds. | |
| if (PrepareFns.empty()) | |
| return OnApplied(Error::success()); | |
| /// Otherwise an empty SearchOrder trivially fails: Without it we don't have | |
| /// the ExecutionSession that we need to pass into the prepare functions. | |
| if (SearchOrder.empty()) | |
| return OnApplied( | |
| make_error<StringError>("lookupAndApply failed: search order is empty", | |
| inconvertibleErrorCode())); | |
| auto &ES = SearchOrder.front().first->getExecutionSession(); | |
| // Build one Mangler for the whole group, so name-mangling prepare functions | |
| // don't each construct their own. | |
| Mangler Mangle(ES.getTargetTriple()); | |
| // Collect the symbols to look up. Each prepare function hands back the | |
| // applicator that will act on the result; the prepare functions themselves | |
| // are not needed beyond this point. | |
| SymbolLookupSet Symbols; | |
| std::vector<LookupApplyFn> Applies; | |
| Applies.reserve(PrepareFns.size()); | |
| for (const auto &PF : PrepareFns) | |
| Applies.push_back(PF(Symbols, ES, Mangle)); | |
| // PrepareFns are independent, so two of them may legitimately ask for the | |
| // same symbol. ExecutionSession::lookup requires a duplicate-free set, and | |
| // the applicators read the result by name, so merging here is invisible to | |
| // them. | |
| Symbols.mergeEntries(); | |
| ES.lookup( | |
| K, SearchOrder, std::move(Symbols), SymbolState::Ready, | |
| [Applies = std::move(Applies), | |
| OnApplied = std::move(OnApplied)](Expected<SymbolMap> Result) mutable { | |
| if (!Result) | |
| return OnApplied(Result.takeError()); | |
| for (auto &Apply : Applies) | |
| Apply(*Result); | |
| OnApplied(Error::success()); | |
| }, | |
| NoDependenciesToRegister); | |
| } | |
| Error lookupAndApply(LookupKind K, const JITDylibSearchOrder &SearchOrder, | |
| ArrayRef<LookupPrepareFn> PrepareFns) { | |
| std::promise<MSVCPError> ResultP; | |
| auto ResultF = ResultP.get_future(); | |
| lookupAndApply([&](Error Err) { ResultP.set_value(std::move(Err)); }, K, | |
| SearchOrder, PrepareFns); | |
| return ResultF.get(); | |
| } | |
| void lookupAndApply(unique_function<void(Error)> OnApplied, JITDylib &JD, | |
| ArrayRef<LookupPrepareFn> PrepareFns) { | |
| lookupAndApply(std::move(OnApplied), LookupKind::Static, | |
| makeJITDylibSearchOrder(&JD), PrepareFns); | |
| } | |
| Error lookupAndApply(JITDylib &JD, ArrayRef<LookupPrepareFn> PrepareFns) { | |
| return lookupAndApply(LookupKind::Static, makeJITDylibSearchOrder(&JD), | |
| PrepareFns); | |
| } | |
| } // namespace llvm::orc |