|  | //===- OrcCBindingsStack.h - Orc JIT stack for C bindings -----*- C++ -*---===// | 
|  | // | 
|  | // 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 | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H | 
|  | #define LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H | 
|  |  | 
|  | #include "llvm-c/OrcBindings.h" | 
|  | #include "llvm-c/TargetMachine.h" | 
|  | #include "llvm/ADT/STLExtras.h" | 
|  | #include "llvm/ADT/StringRef.h" | 
|  | #include "llvm/ExecutionEngine/JITSymbol.h" | 
|  | #include "llvm/ExecutionEngine/JITEventListener.h" | 
|  | #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h" | 
|  | #include "llvm/ExecutionEngine/Orc/CompileUtils.h" | 
|  | #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h" | 
|  | #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" | 
|  | #include "llvm/ExecutionEngine/Orc/LambdaResolver.h" | 
|  | #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" | 
|  | #include "llvm/ExecutionEngine/RuntimeDyld.h" | 
|  | #include "llvm/ExecutionEngine/SectionMemoryManager.h" | 
|  | #include "llvm/IR/DataLayout.h" | 
|  | #include "llvm/IR/Mangler.h" | 
|  | #include "llvm/IR/Module.h" | 
|  | #include "llvm/Support/CBindingWrapping.h" | 
|  | #include "llvm/Support/Error.h" | 
|  | #include "llvm/Support/raw_ostream.h" | 
|  | #include "llvm/Target/TargetMachine.h" | 
|  | #include <algorithm> | 
|  | #include <cstdint> | 
|  | #include <functional> | 
|  | #include <map> | 
|  | #include <memory> | 
|  | #include <set> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | namespace llvm { | 
|  |  | 
|  | class OrcCBindingsStack; | 
|  |  | 
|  | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef) | 
|  | DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef) | 
|  |  | 
|  | namespace detail { | 
|  |  | 
|  | // FIXME: Kill this off once the Layer concept becomes an interface. | 
|  | class GenericLayer { | 
|  | public: | 
|  | virtual ~GenericLayer() = default; | 
|  |  | 
|  | virtual JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name, | 
|  | bool ExportedSymbolsOnly) = 0; | 
|  | virtual Error removeModule(orc::VModuleKey K) = 0; | 
|  | }; | 
|  |  | 
|  | template <typename LayerT> class GenericLayerImpl : public GenericLayer { | 
|  | public: | 
|  | GenericLayerImpl(LayerT &Layer) : Layer(Layer) {} | 
|  |  | 
|  | JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name, | 
|  | bool ExportedSymbolsOnly) override { | 
|  | return Layer.findSymbolIn(K, Name, ExportedSymbolsOnly); | 
|  | } | 
|  |  | 
|  | Error removeModule(orc::VModuleKey K) override { | 
|  | return Layer.removeModule(K); | 
|  | } | 
|  |  | 
|  | private: | 
|  | LayerT &Layer; | 
|  | }; | 
|  |  | 
|  | template <> | 
|  | class GenericLayerImpl<orc::LegacyRTDyldObjectLinkingLayer> : public GenericLayer { | 
|  | private: | 
|  | using LayerT = orc::LegacyRTDyldObjectLinkingLayer; | 
|  | public: | 
|  | GenericLayerImpl(LayerT &Layer) : Layer(Layer) {} | 
|  |  | 
|  | JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name, | 
|  | bool ExportedSymbolsOnly) override { | 
|  | return Layer.findSymbolIn(K, Name, ExportedSymbolsOnly); | 
|  | } | 
|  |  | 
|  | Error removeModule(orc::VModuleKey K) override { | 
|  | return Layer.removeObject(K); | 
|  | } | 
|  |  | 
|  | private: | 
|  | LayerT &Layer; | 
|  | }; | 
|  |  | 
|  | template <typename LayerT> | 
|  | std::unique_ptr<GenericLayerImpl<LayerT>> createGenericLayer(LayerT &Layer) { | 
|  | return std::make_unique<GenericLayerImpl<LayerT>>(Layer); | 
|  | } | 
|  |  | 
|  | } // end namespace detail | 
|  |  | 
|  | class OrcCBindingsStack { | 
|  | public: | 
|  |  | 
|  | using CompileCallbackMgr = orc::JITCompileCallbackManager; | 
|  | using ObjLayerT = orc::LegacyRTDyldObjectLinkingLayer; | 
|  | using CompileLayerT = orc::LegacyIRCompileLayer<ObjLayerT, orc::SimpleCompiler>; | 
|  | using CODLayerT = | 
|  | orc::LegacyCompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>; | 
|  |  | 
|  | using CallbackManagerBuilder = | 
|  | std::function<std::unique_ptr<CompileCallbackMgr>()>; | 
|  |  | 
|  | using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT; | 
|  |  | 
|  | private: | 
|  |  | 
|  | using OwningObject = object::OwningBinary<object::ObjectFile>; | 
|  |  | 
|  | class CBindingsResolver : public orc::SymbolResolver { | 
|  | public: | 
|  | CBindingsResolver(OrcCBindingsStack &Stack, | 
|  | LLVMOrcSymbolResolverFn ExternalResolver, | 
|  | void *ExternalResolverCtx) | 
|  | : Stack(Stack), ExternalResolver(std::move(ExternalResolver)), | 
|  | ExternalResolverCtx(std::move(ExternalResolverCtx)) {} | 
|  |  | 
|  | orc::SymbolNameSet | 
|  | getResponsibilitySet(const orc::SymbolNameSet &Symbols) override { | 
|  | orc::SymbolNameSet Result; | 
|  |  | 
|  | for (auto &S : Symbols) { | 
|  | if (auto Sym = findSymbol(*S)) { | 
|  | if (!Sym.getFlags().isStrong()) | 
|  | Result.insert(S); | 
|  | } else if (auto Err = Sym.takeError()) { | 
|  | Stack.reportError(std::move(Err)); | 
|  | return orc::SymbolNameSet(); | 
|  | } | 
|  | } | 
|  |  | 
|  | return Result; | 
|  | } | 
|  |  | 
|  | orc::SymbolNameSet | 
|  | lookup(std::shared_ptr<orc::AsynchronousSymbolQuery> Query, | 
|  | orc::SymbolNameSet Symbols) override { | 
|  | orc::SymbolNameSet UnresolvedSymbols; | 
|  |  | 
|  | for (auto &S : Symbols) { | 
|  | if (auto Sym = findSymbol(*S)) { | 
|  | if (auto Addr = Sym.getAddress()) { | 
|  | Query->notifySymbolMetRequiredState( | 
|  | S, JITEvaluatedSymbol(*Addr, Sym.getFlags())); | 
|  | } else { | 
|  | Stack.ES.legacyFailQuery(*Query, Addr.takeError()); | 
|  | return orc::SymbolNameSet(); | 
|  | } | 
|  | } else if (auto Err = Sym.takeError()) { | 
|  | Stack.ES.legacyFailQuery(*Query, std::move(Err)); | 
|  | return orc::SymbolNameSet(); | 
|  | } else | 
|  | UnresolvedSymbols.insert(S); | 
|  | } | 
|  |  | 
|  | if (Query->isComplete()) | 
|  | Query->handleComplete(); | 
|  |  | 
|  | return UnresolvedSymbols; | 
|  | } | 
|  |  | 
|  | private: | 
|  | JITSymbol findSymbol(const std::string &Name) { | 
|  | // Search order: | 
|  | // 1. JIT'd symbols. | 
|  | // 2. Runtime overrides. | 
|  | // 3. External resolver (if present). | 
|  |  | 
|  | if (Stack.CODLayer) { | 
|  | if (auto Sym = Stack.CODLayer->findSymbol(Name, true)) | 
|  | return Sym; | 
|  | else if (auto Err = Sym.takeError()) | 
|  | return Sym.takeError(); | 
|  | } else { | 
|  | if (auto Sym = Stack.CompileLayer.findSymbol(Name, true)) | 
|  | return Sym; | 
|  | else if (auto Err = Sym.takeError()) | 
|  | return Sym.takeError(); | 
|  | } | 
|  |  | 
|  | if (auto Sym = Stack.CXXRuntimeOverrides.searchOverrides(Name)) | 
|  | return Sym; | 
|  |  | 
|  | if (ExternalResolver) | 
|  | return JITSymbol(ExternalResolver(Name.c_str(), ExternalResolverCtx), | 
|  | JITSymbolFlags::Exported); | 
|  |  | 
|  | return JITSymbol(nullptr); | 
|  | } | 
|  |  | 
|  | OrcCBindingsStack &Stack; | 
|  | LLVMOrcSymbolResolverFn ExternalResolver; | 
|  | void *ExternalResolverCtx = nullptr; | 
|  | }; | 
|  |  | 
|  | public: | 
|  | OrcCBindingsStack(TargetMachine &TM, | 
|  | IndirectStubsManagerBuilder IndirectStubsMgrBuilder) | 
|  | : CCMgr(createCompileCallbackManager(TM, ES)), DL(TM.createDataLayout()), | 
|  | IndirectStubsMgr(IndirectStubsMgrBuilder()), | 
|  | ObjectLayer( | 
|  | AcknowledgeORCv1Deprecation, ES, | 
|  | [this](orc::VModuleKey K) { | 
|  | auto ResolverI = Resolvers.find(K); | 
|  | assert(ResolverI != Resolvers.end() && | 
|  | "No resolver for module K"); | 
|  | auto Resolver = std::move(ResolverI->second); | 
|  | Resolvers.erase(ResolverI); | 
|  | return ObjLayerT::Resources{ | 
|  | std::make_shared<SectionMemoryManager>(), Resolver}; | 
|  | }, | 
|  | nullptr, | 
|  | [this](orc::VModuleKey K, const object::ObjectFile &Obj, | 
|  | const RuntimeDyld::LoadedObjectInfo &LoadedObjInfo) { | 
|  | this->notifyFinalized(K, Obj, LoadedObjInfo); | 
|  | }, | 
|  | [this](orc::VModuleKey K, const object::ObjectFile &Obj) { | 
|  | this->notifyFreed(K, Obj); | 
|  | }), | 
|  | CompileLayer(AcknowledgeORCv1Deprecation, ObjectLayer, | 
|  | orc::SimpleCompiler(TM)), | 
|  | CODLayer(createCODLayer(ES, CompileLayer, CCMgr.get(), | 
|  | std::move(IndirectStubsMgrBuilder), Resolvers)), | 
|  | CXXRuntimeOverrides( | 
|  | AcknowledgeORCv1Deprecation, | 
|  | [this](const std::string &S) { return mangle(S); }) {} | 
|  |  | 
|  | Error shutdown() { | 
|  | // Run any destructors registered with __cxa_atexit. | 
|  | CXXRuntimeOverrides.runDestructors(); | 
|  | // Run any IR destructors. | 
|  | for (auto &DtorRunner : IRStaticDestructorRunners) | 
|  | if (auto Err = DtorRunner.runViaLayer(*this)) | 
|  | return Err; | 
|  | return Error::success(); | 
|  | } | 
|  |  | 
|  | std::string mangle(StringRef Name) { | 
|  | std::string MangledName; | 
|  | { | 
|  | raw_string_ostream MangledNameStream(MangledName); | 
|  | Mangler::getNameWithPrefix(MangledNameStream, Name, DL); | 
|  | } | 
|  | return MangledName; | 
|  | } | 
|  |  | 
|  | template <typename PtrTy> | 
|  | static PtrTy fromTargetAddress(JITTargetAddress Addr) { | 
|  | return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr)); | 
|  | } | 
|  |  | 
|  | Expected<JITTargetAddress> | 
|  | createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback, | 
|  | void *CallbackCtx) { | 
|  | auto WrappedCallback = [=]() -> JITTargetAddress { | 
|  | return Callback(wrap(this), CallbackCtx); | 
|  | }; | 
|  |  | 
|  | return CCMgr->getCompileCallback(std::move(WrappedCallback)); | 
|  | } | 
|  |  | 
|  | Error createIndirectStub(StringRef StubName, JITTargetAddress Addr) { | 
|  | return IndirectStubsMgr->createStub(StubName, Addr, | 
|  | JITSymbolFlags::Exported); | 
|  | } | 
|  |  | 
|  | Error setIndirectStubPointer(StringRef Name, JITTargetAddress Addr) { | 
|  | return IndirectStubsMgr->updatePointer(Name, Addr); | 
|  | } | 
|  |  | 
|  | template <typename LayerT> | 
|  | Expected<orc::VModuleKey> | 
|  | addIRModule(LayerT &Layer, std::unique_ptr<Module> M, | 
|  | std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr, | 
|  | LLVMOrcSymbolResolverFn ExternalResolver, | 
|  | void *ExternalResolverCtx) { | 
|  |  | 
|  | // Attach a data-layout if one isn't already present. | 
|  | if (M->getDataLayout().isDefault()) | 
|  | M->setDataLayout(DL); | 
|  |  | 
|  | // Record the static constructors and destructors. We have to do this before | 
|  | // we hand over ownership of the module to the JIT. | 
|  | std::vector<std::string> CtorNames, DtorNames; | 
|  | for (auto Ctor : orc::getConstructors(*M)) | 
|  | CtorNames.push_back(mangle(Ctor.Func->getName())); | 
|  | for (auto Dtor : orc::getDestructors(*M)) | 
|  | DtorNames.push_back(mangle(Dtor.Func->getName())); | 
|  |  | 
|  | // Add the module to the JIT. | 
|  | auto K = ES.allocateVModule(); | 
|  | Resolvers[K] = std::make_shared<CBindingsResolver>(*this, ExternalResolver, | 
|  | ExternalResolverCtx); | 
|  | if (auto Err = Layer.addModule(K, std::move(M))) | 
|  | return std::move(Err); | 
|  |  | 
|  | KeyLayers[K] = detail::createGenericLayer(Layer); | 
|  |  | 
|  | // Run the static constructors, and save the static destructor runner for | 
|  | // execution when the JIT is torn down. | 
|  | orc::LegacyCtorDtorRunner<OrcCBindingsStack> CtorRunner( | 
|  | AcknowledgeORCv1Deprecation, std::move(CtorNames), K); | 
|  | if (auto Err = CtorRunner.runViaLayer(*this)) | 
|  | return std::move(Err); | 
|  |  | 
|  | IRStaticDestructorRunners.emplace_back(AcknowledgeORCv1Deprecation, | 
|  | std::move(DtorNames), K); | 
|  |  | 
|  | return K; | 
|  | } | 
|  |  | 
|  | Expected<orc::VModuleKey> | 
|  | addIRModuleEager(std::unique_ptr<Module> M, | 
|  | LLVMOrcSymbolResolverFn ExternalResolver, | 
|  | void *ExternalResolverCtx) { | 
|  | return addIRModule(CompileLayer, std::move(M), | 
|  | std::make_unique<SectionMemoryManager>(), | 
|  | std::move(ExternalResolver), ExternalResolverCtx); | 
|  | } | 
|  |  | 
|  | Expected<orc::VModuleKey> | 
|  | addIRModuleLazy(std::unique_ptr<Module> M, | 
|  | LLVMOrcSymbolResolverFn ExternalResolver, | 
|  | void *ExternalResolverCtx) { | 
|  | if (!CODLayer) | 
|  | return make_error<StringError>("Can not add lazy module: No compile " | 
|  | "callback manager available", | 
|  | inconvertibleErrorCode()); | 
|  |  | 
|  | return addIRModule(*CODLayer, std::move(M), | 
|  | std::make_unique<SectionMemoryManager>(), | 
|  | std::move(ExternalResolver), ExternalResolverCtx); | 
|  | } | 
|  |  | 
|  | Error removeModule(orc::VModuleKey K) { | 
|  | // FIXME: Should error release the module key? | 
|  | if (auto Err = KeyLayers[K]->removeModule(K)) | 
|  | return Err; | 
|  | ES.releaseVModule(K); | 
|  | KeyLayers.erase(K); | 
|  | return Error::success(); | 
|  | } | 
|  |  | 
|  | Expected<orc::VModuleKey> addObject(std::unique_ptr<MemoryBuffer> ObjBuffer, | 
|  | LLVMOrcSymbolResolverFn ExternalResolver, | 
|  | void *ExternalResolverCtx) { | 
|  | if (auto Obj = object::ObjectFile::createObjectFile( | 
|  | ObjBuffer->getMemBufferRef())) { | 
|  |  | 
|  | auto K = ES.allocateVModule(); | 
|  | Resolvers[K] = std::make_shared<CBindingsResolver>( | 
|  | *this, ExternalResolver, ExternalResolverCtx); | 
|  |  | 
|  | if (auto Err = ObjectLayer.addObject(K, std::move(ObjBuffer))) | 
|  | return std::move(Err); | 
|  |  | 
|  | KeyLayers[K] = detail::createGenericLayer(ObjectLayer); | 
|  |  | 
|  | return K; | 
|  | } else | 
|  | return Obj.takeError(); | 
|  | } | 
|  |  | 
|  | JITSymbol findSymbol(const std::string &Name, | 
|  | bool ExportedSymbolsOnly) { | 
|  | if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly)) | 
|  | return Sym; | 
|  | if (CODLayer) | 
|  | return CODLayer->findSymbol(mangle(Name), ExportedSymbolsOnly); | 
|  | return CompileLayer.findSymbol(mangle(Name), ExportedSymbolsOnly); | 
|  | } | 
|  |  | 
|  | JITSymbol findSymbolIn(orc::VModuleKey K, const std::string &Name, | 
|  | bool ExportedSymbolsOnly) { | 
|  | assert(KeyLayers.count(K) && "looking up symbol in unknown module"); | 
|  | return KeyLayers[K]->findSymbolIn(K, mangle(Name), ExportedSymbolsOnly); | 
|  | } | 
|  |  | 
|  | Expected<JITTargetAddress> findSymbolAddress(const std::string &Name, | 
|  | bool ExportedSymbolsOnly) { | 
|  | if (auto Sym = findSymbol(Name, ExportedSymbolsOnly)) { | 
|  | // Successful lookup, non-null symbol: | 
|  | if (auto AddrOrErr = Sym.getAddress()) | 
|  | return *AddrOrErr; | 
|  | else | 
|  | return AddrOrErr.takeError(); | 
|  | } else if (auto Err = Sym.takeError()) { | 
|  | // Lookup failure - report error. | 
|  | return std::move(Err); | 
|  | } | 
|  |  | 
|  | // No symbol not found. Return 0. | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | Expected<JITTargetAddress> findSymbolAddressIn(orc::VModuleKey K, | 
|  | const std::string &Name, | 
|  | bool ExportedSymbolsOnly) { | 
|  | if (auto Sym = findSymbolIn(K, Name, ExportedSymbolsOnly)) { | 
|  | // Successful lookup, non-null symbol: | 
|  | if (auto AddrOrErr = Sym.getAddress()) | 
|  | return *AddrOrErr; | 
|  | else | 
|  | return AddrOrErr.takeError(); | 
|  | } else if (auto Err = Sym.takeError()) { | 
|  | // Lookup failure - report error. | 
|  | return std::move(Err); | 
|  | } | 
|  |  | 
|  | // Symbol not found. Return 0. | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | const std::string &getErrorMessage() const { return ErrMsg; } | 
|  |  | 
|  | void RegisterJITEventListener(JITEventListener *L) { | 
|  | if (!L) | 
|  | return; | 
|  | EventListeners.push_back(L); | 
|  | } | 
|  |  | 
|  | void UnregisterJITEventListener(JITEventListener *L) { | 
|  | if (!L) | 
|  | return; | 
|  |  | 
|  | auto I = find(reverse(EventListeners), L); | 
|  | if (I != EventListeners.rend()) { | 
|  | std::swap(*I, EventListeners.back()); | 
|  | EventListeners.pop_back(); | 
|  | } | 
|  | } | 
|  |  | 
|  | private: | 
|  | using ResolverMap = | 
|  | std::map<orc::VModuleKey, std::shared_ptr<orc::SymbolResolver>>; | 
|  |  | 
|  | static std::unique_ptr<CompileCallbackMgr> | 
|  | createCompileCallbackManager(TargetMachine &TM, orc::ExecutionSession &ES) { | 
|  | auto CCMgr = createLocalCompileCallbackManager(TM.getTargetTriple(), ES, 0); | 
|  | if (!CCMgr) { | 
|  | // FIXME: It would be good if we could report this somewhere, but we do | 
|  | //        have an instance yet. | 
|  | logAllUnhandledErrors(CCMgr.takeError(), errs(), "ORC error: "); | 
|  | return nullptr; | 
|  | } | 
|  | return std::move(*CCMgr); | 
|  | } | 
|  |  | 
|  | static std::unique_ptr<CODLayerT> | 
|  | createCODLayer(orc::ExecutionSession &ES, CompileLayerT &CompileLayer, | 
|  | CompileCallbackMgr *CCMgr, | 
|  | IndirectStubsManagerBuilder IndirectStubsMgrBuilder, | 
|  | ResolverMap &Resolvers) { | 
|  | // If there is no compile callback manager available we can not create a | 
|  | // compile on demand layer. | 
|  | if (!CCMgr) | 
|  | return nullptr; | 
|  |  | 
|  | return std::make_unique<CODLayerT>( | 
|  | AcknowledgeORCv1Deprecation, ES, CompileLayer, | 
|  | [&Resolvers](orc::VModuleKey K) { | 
|  | auto ResolverI = Resolvers.find(K); | 
|  | assert(ResolverI != Resolvers.end() && "No resolver for module K"); | 
|  | return ResolverI->second; | 
|  | }, | 
|  | [&Resolvers](orc::VModuleKey K, | 
|  | std::shared_ptr<orc::SymbolResolver> Resolver) { | 
|  | assert(!Resolvers.count(K) && "Resolver already present"); | 
|  | Resolvers[K] = std::move(Resolver); | 
|  | }, | 
|  | [](Function &F) { return std::set<Function *>({&F}); }, *CCMgr, | 
|  | std::move(IndirectStubsMgrBuilder), false); | 
|  | } | 
|  |  | 
|  | void reportError(Error Err) { | 
|  | // FIXME: Report errors on the execution session. | 
|  | logAllUnhandledErrors(std::move(Err), errs(), "ORC error: "); | 
|  | }; | 
|  |  | 
|  | void notifyFinalized(orc::VModuleKey K, | 
|  | const object::ObjectFile &Obj, | 
|  | const RuntimeDyld::LoadedObjectInfo &LoadedObjInfo) { | 
|  | uint64_t Key = static_cast<uint64_t>( | 
|  | reinterpret_cast<uintptr_t>(Obj.getData().data())); | 
|  | for (auto &Listener : EventListeners) | 
|  | Listener->notifyObjectLoaded(Key, Obj, LoadedObjInfo); | 
|  | } | 
|  |  | 
|  | void notifyFreed(orc::VModuleKey K, const object::ObjectFile &Obj) { | 
|  | uint64_t Key = static_cast<uint64_t>( | 
|  | reinterpret_cast<uintptr_t>(Obj.getData().data())); | 
|  | for (auto &Listener : EventListeners) | 
|  | Listener->notifyFreeingObject(Key); | 
|  | } | 
|  |  | 
|  | orc::ExecutionSession ES; | 
|  | std::unique_ptr<CompileCallbackMgr> CCMgr; | 
|  |  | 
|  | std::vector<JITEventListener *> EventListeners; | 
|  |  | 
|  | DataLayout DL; | 
|  | SectionMemoryManager CCMgrMemMgr; | 
|  |  | 
|  | std::unique_ptr<orc::IndirectStubsManager> IndirectStubsMgr; | 
|  |  | 
|  | ObjLayerT ObjectLayer; | 
|  | CompileLayerT CompileLayer; | 
|  | std::unique_ptr<CODLayerT> CODLayer; | 
|  |  | 
|  | std::map<orc::VModuleKey, std::unique_ptr<detail::GenericLayer>> KeyLayers; | 
|  |  | 
|  | orc::LegacyLocalCXXRuntimeOverrides CXXRuntimeOverrides; | 
|  | std::vector<orc::LegacyCtorDtorRunner<OrcCBindingsStack>> IRStaticDestructorRunners; | 
|  | std::string ErrMsg; | 
|  |  | 
|  | ResolverMap Resolvers; | 
|  | }; | 
|  |  | 
|  | } // end namespace llvm | 
|  |  | 
|  | #endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H |