blob: 26ecd8c2ad9ec1bee4f49bf8a5e7f015806decf8 [file] [edit]
//===- 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();
// 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));
// 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