[ORC] Hook up the LLVMOrcAddObjectFile function in the Orc C Bindings.

This can be used to add a relocatable object to the JIT session.

llvm-svn: 313474
diff --git a/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp b/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp
index de80cb1..f945aca 100644
--- a/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp
+++ b/llvm/lib/ExecutionEngine/Orc/OrcCBindings.cpp
@@ -20,16 +20,6 @@
   delete unwrap(SharedMod);
 }
 
-LLVMSharedObjectBufferRef
-LLVMOrcMakeSharedObjectBuffer(LLVMMemoryBufferRef ObjBuffer) {
-  return wrap(new std::shared_ptr<MemoryBuffer>(unwrap(ObjBuffer)));
-}
-
-void
-LLVMOrcDisposeSharedObjectBufferRef(LLVMSharedObjectBufferRef SharedObjBuffer) {
-  delete unwrap(SharedObjBuffer);
-}
-
 LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM) {
   TargetMachine *TM2(unwrap(TM));
 
@@ -105,6 +95,18 @@
   return J.addIRModuleLazy(*RetHandle, *M, SymbolResolver, SymbolResolverCtx);
 }
 
+LLVMOrcErrorCode
+LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
+                     LLVMOrcModuleHandle *RetHandle,
+                     LLVMMemoryBufferRef Obj,
+                     LLVMOrcSymbolResolverFn SymbolResolver,
+                     void *SymbolResolverCtx) {
+  OrcCBindingsStack &J = *unwrap(JITStack);
+  std::unique_ptr<MemoryBuffer> O(unwrap(Obj));
+  return J.addObject(*RetHandle, std::move(O), SymbolResolver,
+                     SymbolResolverCtx);
+}
+
 LLVMOrcErrorCode LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack,
                                      LLVMOrcModuleHandle H) {
   OrcCBindingsStack &J = *unwrap(JITStack);
diff --git a/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h b/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
index ecb4c20..405970e 100644
--- a/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
+++ b/llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h
@@ -44,26 +44,12 @@
 
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr<Module>,
                                    LLVMSharedModuleRef)
-DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr<MemoryBuffer>,
-                                   LLVMSharedObjectBufferRef)
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
 
-class OrcCBindingsStack {
-public:
+namespace detail {
 
-  using CompileCallbackMgr = orc::JITCompileCallbackManager;
-  using ObjLayerT = orc::RTDyldObjectLinkingLayer;
-  using CompileLayerT = orc::IRCompileLayer<ObjLayerT, orc::SimpleCompiler>;
-  using CODLayerT =
-        orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>;
 
-  using CallbackManagerBuilder =
-      std::function<std::unique_ptr<CompileCallbackMgr>()>;
-
-  using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT;
-
-private:
   class GenericHandle {
   public:
     virtual ~GenericHandle() = default;
@@ -90,13 +76,56 @@
     typename LayerT::ModuleHandleT Handle;
   };
 
-  template <typename LayerT>
+  template <>
+  class GenericHandleImpl<orc::RTDyldObjectLinkingLayer>
+    : public GenericHandle {
+  private:
+    using LayerT = orc::RTDyldObjectLinkingLayer;
+  public:
+
+    GenericHandleImpl(LayerT &Layer, typename LayerT::ObjHandleT Handle)
+        : Layer(Layer), Handle(std::move(Handle)) {}
+
+    JITSymbol findSymbolIn(const std::string &Name,
+                           bool ExportedSymbolsOnly) override {
+      return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
+    }
+
+    Error removeModule() override { return Layer.removeObject(Handle); }
+
+  private:
+    LayerT &Layer;
+    typename LayerT::ObjHandleT Handle;
+  };
+
+
+  template <typename LayerT, typename HandleT>
   std::unique_ptr<GenericHandleImpl<LayerT>>
-  createGenericHandle(LayerT &Layer, typename LayerT::ModuleHandleT Handle) {
+  createGenericHandle(LayerT &Layer, HandleT Handle) {
     return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer,
                                                         std::move(Handle));
   }
 
+} // end namespace detail
+
+class OrcCBindingsStack {
+public:
+
+  using CompileCallbackMgr = orc::JITCompileCallbackManager;
+  using ObjLayerT = orc::RTDyldObjectLinkingLayer;
+  using CompileLayerT = orc::IRCompileLayer<ObjLayerT, orc::SimpleCompiler>;
+  using CODLayerT =
+        orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>;
+
+  using CallbackManagerBuilder =
+      std::function<std::unique_ptr<CompileCallbackMgr>()>;
+
+  using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT;
+
+private:
+
+  using OwningObject = object::OwningBinary<object::ObjectFile>;
+
 public:
   using ModuleHandleT = unsigned;
 
@@ -266,6 +295,33 @@
     return LLVMOrcErrSuccess;
   }
 
+  LLVMOrcErrorCode addObject(ModuleHandleT &RetHandle,
+                             std::unique_ptr<MemoryBuffer> ObjBuffer,
+                             LLVMOrcSymbolResolverFn ExternalResolver,
+                             void *ExternalResolverCtx) {
+    if (auto ObjOrErr =
+        object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef())) {
+      auto &Obj = *ObjOrErr;
+      auto OwningObj =
+        std::make_shared<OwningObject>(std::move(Obj), std::move(ObjBuffer));
+
+      // Create the resolver.
+      auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
+
+      ModuleHandleT H;
+      if (auto HOrErr = ObjectLayer.addObject(std::move(OwningObj),
+                                              std::move(Resolver)))
+        H = createHandle(ObjectLayer, *HOrErr);
+      else
+        return mapError(HOrErr.takeError());
+
+      RetHandle = H;
+
+      return LLVMOrcErrSuccess;
+    } else
+      return mapError(ObjOrErr.takeError());
+  }
+
   JITSymbol findSymbol(const std::string &Name,
                                  bool ExportedSymbolsOnly) {
     if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
@@ -301,17 +357,19 @@
   const std::string &getErrorMessage() const { return ErrMsg; }
 
 private:
-  template <typename LayerT>
-  unsigned createHandle(LayerT &Layer, typename LayerT::ModuleHandleT Handle) {
+  template <typename LayerT, typename HandleT>
+  unsigned createHandle(LayerT &Layer, HandleT Handle) {
     unsigned NewHandle;
     if (!FreeHandleIndexes.empty()) {
       NewHandle = FreeHandleIndexes.back();
       FreeHandleIndexes.pop_back();
-      GenericHandles[NewHandle] = createGenericHandle(Layer, std::move(Handle));
+      GenericHandles[NewHandle] =
+        detail::createGenericHandle(Layer, std::move(Handle));
       return NewHandle;
     } else {
       NewHandle = GenericHandles.size();
-      GenericHandles.push_back(createGenericHandle(Layer, std::move(Handle)));
+      GenericHandles.push_back(
+        detail::createGenericHandle(Layer, std::move(Handle)));
     }
     return NewHandle;
   }
@@ -338,7 +396,7 @@
   CompileLayerT CompileLayer;
   CODLayerT CODLayer;
 
-  std::vector<std::unique_ptr<GenericHandle>> GenericHandles;
+  std::vector<std::unique_ptr<detail::GenericHandle>> GenericHandles;
   std::vector<unsigned> FreeHandleIndexes;
 
   orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;