//===-- RemoteJITUtils.h - Utilities for remote-JITing with LLI -*- 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
//
//===----------------------------------------------------------------------===//
//
// Utilities for remote-JITing with LLI.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TOOLS_LLI_FORWARDINGMEMORYMANAGER_H
#define LLVM_TOOLS_LLI_FORWARDINGMEMORYMANAGER_H

#include "llvm/ExecutionEngine/Orc/EPCGenericDylibManager.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"

namespace llvm {

// ForwardingMM - Adapter to connect MCJIT to Orc's Remote
// memory manager.
class ForwardingMemoryManager : public llvm::RTDyldMemoryManager {
public:
  void setMemMgr(std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr) {
    this->MemMgr = std::move(MemMgr);
  }

  void setResolver(std::shared_ptr<LegacyJITSymbolResolver> Resolver) {
    this->Resolver = std::move(Resolver);
  }

  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
                               unsigned SectionID,
                               StringRef SectionName) override {
    return MemMgr->allocateCodeSection(Size, Alignment, SectionID, SectionName);
  }

  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
                               unsigned SectionID, StringRef SectionName,
                               bool IsReadOnly) override {
    return MemMgr->allocateDataSection(Size, Alignment, SectionID, SectionName,
                                       IsReadOnly);
  }

  void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,
                              uintptr_t RODataSize, uint32_t RODataAlign,
                              uintptr_t RWDataSize,
                              uint32_t RWDataAlign) override {
    MemMgr->reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign,
                                   RWDataSize, RWDataAlign);
  }

  bool needsToReserveAllocationSpace() override {
    return MemMgr->needsToReserveAllocationSpace();
  }

  void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,
                        size_t Size) override {
    MemMgr->registerEHFrames(Addr, LoadAddr, Size);
  }

  void deregisterEHFrames() override { MemMgr->deregisterEHFrames(); }

  bool finalizeMemory(std::string *ErrMsg = nullptr) override {
    return MemMgr->finalizeMemory(ErrMsg);
  }

  void notifyObjectLoaded(RuntimeDyld &RTDyld,
                          const object::ObjectFile &Obj) override {
    MemMgr->notifyObjectLoaded(RTDyld, Obj);
  }

  // Don't hide the sibling notifyObjectLoaded from RTDyldMemoryManager.
  using RTDyldMemoryManager::notifyObjectLoaded;

  JITSymbol findSymbol(const std::string &Name) override {
    return Resolver->findSymbol(Name);
  }

  JITSymbol findSymbolInLogicalDylib(const std::string &Name) override {
    return Resolver->findSymbolInLogicalDylib(Name);
  }

private:
  std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr;
  std::shared_ptr<LegacyJITSymbolResolver> Resolver;
};

class RemoteResolver : public LegacyJITSymbolResolver {
public:
  static Expected<std::unique_ptr<RemoteResolver>>
  Create(orc::ExecutorProcessControl &EPC) {
    auto DylibMgr =
        orc::EPCGenericDylibManager::CreateWithDefaultBootstrapSymbols(EPC);
    if (!DylibMgr)
      return DylibMgr.takeError();
    auto H = DylibMgr->open("", 0);
    if (!H)
      return H.takeError();
    return std::unique_ptr<RemoteResolver>(
        new RemoteResolver(std::move(*DylibMgr), std::move(*H)));
  }

  JITSymbol findSymbol(const std::string &Name) override {
    orc::RemoteSymbolLookupSet R;
    R.push_back({std::move(Name), false});
    if (auto Addrs = DylibMgr.lookup(H, R)) {
      if (Addrs->size() != 1)
        return make_error<StringError>("Unexpected remote lookup result",
                                       inconvertibleErrorCode());
      return JITSymbol(Addrs->front().getValue(), JITSymbolFlags::Exported);
    } else
      return Addrs.takeError();
  }

  JITSymbol findSymbolInLogicalDylib(const std::string &Name) override {
    return nullptr;
  }

public:
  RemoteResolver(orc::EPCGenericDylibManager DylibMgr,
                 orc::tpctypes::DylibHandle H)
      : DylibMgr(std::move(DylibMgr)), H(std::move(H)) {}

  orc::EPCGenericDylibManager DylibMgr;
  orc::tpctypes::DylibHandle H;
};
} // namespace llvm

#endif // LLVM_TOOLS_LLI_FORWARDINGMEMORYMANAGER_H
