| //===--- Legacy.h -- Adapters for ExecutionEngine API interop ---*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Contains core ORC APIs. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_EXECUTIONENGINE_ORC_LEGACY_H |
| #define LLVM_EXECUTIONENGINE_ORC_LEGACY_H |
| |
| #include "llvm/ExecutionEngine/JITSymbol.h" |
| #include "llvm/ExecutionEngine/Orc/Core.h" |
| |
| namespace llvm { |
| namespace orc { |
| |
| class JITSymbolResolverAdapter : public JITSymbolResolver { |
| public: |
| JITSymbolResolverAdapter(ExecutionSession &ES, SymbolResolver &R); |
| Expected<LookupFlagsResult> lookupFlags(const LookupSet &Symbols) override; |
| Expected<LookupResult> lookup(const LookupSet &Symbols) override; |
| |
| private: |
| ExecutionSession &ES; |
| std::set<SymbolStringPtr> ResolvedStrings; |
| SymbolResolver &R; |
| }; |
| |
| /// @brief Use the given legacy-style FindSymbol function (i.e. a function that |
| /// takes a const std::string& or StringRef and returns a JITSymbol) to |
| /// find the flags for each symbol in Symbols and store their flags in |
| /// SymbolFlags. If any JITSymbol returned by FindSymbol is in an error |
| /// state the function returns immediately with that error, otherwise it |
| /// returns the set of symbols not found. |
| /// |
| /// Useful for implementing lookupFlags bodies that query legacy resolvers. |
| template <typename FindSymbolFn> |
| Expected<SymbolNameSet> lookupFlagsWithLegacyFn(SymbolFlagsMap &SymbolFlags, |
| const SymbolNameSet &Symbols, |
| FindSymbolFn FindSymbol) { |
| SymbolNameSet SymbolsNotFound; |
| |
| for (auto &S : Symbols) { |
| if (JITSymbol Sym = FindSymbol(*S)) |
| SymbolFlags[S] = Sym.getFlags(); |
| else if (auto Err = Sym.takeError()) |
| return std::move(Err); |
| else |
| SymbolsNotFound.insert(S); |
| } |
| |
| return SymbolsNotFound; |
| } |
| |
| /// @brief Use the given legacy-style FindSymbol function (i.e. a function that |
| /// takes a const std::string& or StringRef and returns a JITSymbol) to |
| /// find the address and flags for each symbol in Symbols and store the |
| /// result in Query. If any JITSymbol returned by FindSymbol is in an |
| /// error then Query.setFailed(...) is called with that error and the |
| /// function returns immediately. On success, returns the set of symbols |
| /// not found. |
| /// |
| /// Useful for implementing lookup bodies that query legacy resolvers. |
| template <typename FindSymbolFn> |
| SymbolNameSet lookupWithLegacyFn(AsynchronousSymbolQuery &Query, |
| const SymbolNameSet &Symbols, |
| FindSymbolFn FindSymbol) { |
| SymbolNameSet SymbolsNotFound; |
| |
| for (auto &S : Symbols) { |
| if (JITSymbol Sym = FindSymbol(*S)) { |
| if (auto Addr = Sym.getAddress()) { |
| Query.setDefinition(S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); |
| Query.notifySymbolFinalized(); |
| } else { |
| Query.setFailed(Addr.takeError()); |
| return SymbolNameSet(); |
| } |
| } else if (auto Err = Sym.takeError()) { |
| Query.setFailed(std::move(Err)); |
| return SymbolNameSet(); |
| } else |
| SymbolsNotFound.insert(S); |
| } |
| |
| return SymbolsNotFound; |
| } |
| |
| /// @brief An ORC SymbolResolver implementation that uses a legacy |
| /// findSymbol-like function to perform lookup; |
| template <typename LegacyLookupFn> |
| class LegacyLookupFnResolver final : public SymbolResolver { |
| public: |
| using ErrorReporter = std::function<void(Error)>; |
| |
| LegacyLookupFnResolver(LegacyLookupFn LegacyLookup, ErrorReporter ReportError) |
| : LegacyLookup(std::move(LegacyLookup)), |
| ReportError(std::move(ReportError)) {} |
| |
| SymbolNameSet lookupFlags(SymbolFlagsMap &Flags, |
| const SymbolNameSet &Symbols) final { |
| if (auto RemainingSymbols = |
| lookupFlagsWithLegacyFn(Flags, Symbols, LegacyLookup)) |
| return std::move(*RemainingSymbols); |
| else { |
| ReportError(RemainingSymbols.takeError()); |
| return Symbols; |
| } |
| } |
| |
| SymbolNameSet lookup(std::shared_ptr<AsynchronousSymbolQuery> Query, |
| SymbolNameSet Symbols) final { |
| return lookupWithLegacyFn(*Query, Symbols, LegacyLookup); |
| } |
| |
| private: |
| LegacyLookupFn LegacyLookup; |
| ErrorReporter ReportError; |
| }; |
| |
| template <typename LegacyLookupFn> |
| std::shared_ptr<LegacyLookupFnResolver<LegacyLookupFn>> |
| createLegacyLookupResolver(LegacyLookupFn LegacyLookup, |
| std::function<void(Error)> ErrorReporter) { |
| return std::make_shared<LegacyLookupFnResolver<LegacyLookupFn>>( |
| std::move(LegacyLookup), std::move(ErrorReporter)); |
| } |
| |
| } // End namespace orc |
| } // End namespace llvm |
| |
| #endif // LLVM_EXECUTIONENGINE_ORC_LEGACY_H |