//===------ SelfExecutorProcessControl.cpp -- EPC for in-process JITs -----===//
//
// 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/SelfExecutorProcessControl.h"
#include "llvm/ExecutionEngine/Orc/Shared/Mangler.h"

#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/DylibManager.h"
#include "llvm/ExecutionEngine/Orc/InProcessMemoryAccess.h"
#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/DefaultHostBootstrapValues.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/OrcRTBootstrap.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/TargetExecutionUtils.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Process.h"
#include "llvm/TargetParser/Host.h"

#define DEBUG_TYPE "orc"

namespace llvm::orc {

class SelfExecutorProcessControl::InProcessDylibManager : public DylibManager {
public:
  InProcessDylibManager(char GlobalManglingPrefix);
  Expected<tpctypes::DylibHandle> loadDylib(const char *DylibPath) override;
  void
  lookupSymbolsAsync(tpctypes::DylibHandle H, const SymbolLookupSet &Symbols,
                     DylibManager::SymbolLookupCompleteFn Complete) override;

private:
  char GlobalManglingPrefix;
};

SelfExecutorProcessControl::SelfExecutorProcessControl(
    std::shared_ptr<SymbolStringPool> SSP, std::unique_ptr<TaskDispatcher> D,
    Triple TargetTriple, unsigned PageSize)
    : ExecutorProcessControl(std::move(SSP), std::move(D)) {

  this->TargetTriple = std::move(TargetTriple);
  this->PageSize = PageSize;

  addDefaultBootstrapValuesForHostProcess(BootstrapMap, BootstrapSymbols);
  rt_bootstrap::addRunAsFunctionWrappersTo(BootstrapSymbols);

  Mangler Mangle(getTargetTriple());
  BootstrapSymbols[Mangle.mangledCopy(rt::DispatchName)] =
      ExecutorAddr::fromPtr(jitDispatchViaWrapperFunctionManager);
  BootstrapSymbols[Mangle.mangledCopy(rt::DispatchCtxName)] =
      ExecutorAddr::fromPtr(this);

#ifdef __APPLE__
  // FIXME: Don't add an UnwindInfoManager by default -- it's redundant when
  //        the ORC runtime is loaded. We'll need a way to document this and
  //        allow clients to choose.
  if (UnwindInfoManager::TryEnable())
    UnwindInfoManager::addBootstrapSymbols(this->BootstrapSymbols);
#endif // __APPLE__
}

Expected<std::unique_ptr<SelfExecutorProcessControl>>
SelfExecutorProcessControl::Create(std::shared_ptr<SymbolStringPool> SSP,
                                   std::unique_ptr<TaskDispatcher> D) {

  if (!SSP)
    SSP = std::make_shared<SymbolStringPool>();

  if (!D)
    D = std::make_unique<InPlaceTaskDispatcher>();

  auto PageSize = sys::Process::getPageSize();
  if (!PageSize)
    return PageSize.takeError();

  Triple TT(sys::getProcessTriple());

  return std::make_unique<SelfExecutorProcessControl>(
      std::move(SSP), std::move(D), std::move(TT), *PageSize);
}

Expected<int32_t>
SelfExecutorProcessControl::runAsMain(ExecutorAddr MainFnAddr,
                                      ArrayRef<std::string> Args) {
  using MainTy = int (*)(int, char *[]);
  return orc::runAsMain(MainFnAddr.toPtr<MainTy>(), Args);
}

void SelfExecutorProcessControl::callWrapperAsync(ExecutorAddr WrapperFnAddr,
                                                  IncomingWFRHandler SendResult,
                                                  ArrayRef<char> ArgBuffer) {
  using WrapperFnTy =
      shared::CWrapperFunctionBuffer (*)(const char *Data, size_t Size);
  auto *WrapperFn = WrapperFnAddr.toPtr<WrapperFnTy>();
  SendResult(shared::WrapperFunctionBuffer(
      WrapperFn(ArgBuffer.data(), ArgBuffer.size())));
}

Error SelfExecutorProcessControl::disconnect() {
  D->shutdown();
  return Error::success();
}

Expected<std::unique_ptr<jitlink::JITLinkMemoryManager>>
SelfExecutorProcessControl::createDefaultMemoryManager() {
  return std::make_unique<jitlink::InProcessMemoryManager>(
      sys::Process::getPageSizeEstimate());
}

Expected<std::unique_ptr<DylibManager>>
SelfExecutorProcessControl::createDefaultDylibMgr() {
  char Prefix = TargetTriple.isOSBinFormatMachO() ? '_' : '\0';
  return std::make_unique<InProcessDylibManager>(Prefix);
}

Expected<std::unique_ptr<MemoryAccess>>
SelfExecutorProcessControl::createDefaultMemoryAccess() {
  return std::make_unique<InProcessMemoryAccess>(TargetTriple.isArch64Bit());
}

shared::CWrapperFunctionBuffer
SelfExecutorProcessControl::jitDispatchViaWrapperFunctionManager(
    void *Ctx, const void *FnTag, const char *Data, size_t Size) {

  LLVM_DEBUG({
    dbgs() << "jit-dispatch call with tag " << FnTag << " and " << Size
           << " byte payload.\n";
  });

  std::promise<shared::WrapperFunctionBuffer> ResultP;
  auto ResultF = ResultP.get_future();
  static_cast<SelfExecutorProcessControl *>(Ctx)
      ->getExecutionSession()
      .runCallControllerHandler(
          [ResultP = std::move(ResultP)](
              shared::WrapperFunctionBuffer Result) mutable {
            ResultP.set_value(std::move(Result));
          },
          ExecutorAddr::fromPtr(FnTag),
          shared::WrapperFunctionBuffer::copyFrom(Data, Size));

  return ResultF.get().release();
}

SelfExecutorProcessControl::InProcessDylibManager::InProcessDylibManager(
    char GlobalManglingPrefix)
    : GlobalManglingPrefix(GlobalManglingPrefix) {}

Expected<tpctypes::DylibHandle>
SelfExecutorProcessControl::InProcessDylibManager::loadDylib(
    const char *DylibPath) {
  std::string ErrMsg;
  auto Dylib = sys::DynamicLibrary::getPermanentLibrary(DylibPath, &ErrMsg);
  if (!Dylib.isValid())
    return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
  return ExecutorAddr::fromPtr(Dylib.getOSSpecificHandle());
}

void SelfExecutorProcessControl::InProcessDylibManager::lookupSymbolsAsync(
    tpctypes::DylibHandle H, const SymbolLookupSet &Symbols,
    DylibManager::SymbolLookupCompleteFn Complete) {
  tpctypes::LookupResult R;

  sys::DynamicLibrary Dylib(H.toPtr<void *>());
  for (auto &KV : Symbols) {
    auto &Sym = KV.first;
    std::string Tmp((*Sym).data() + !!GlobalManglingPrefix,
                    (*Sym).size() - !!GlobalManglingPrefix);
    void *Addr = Dylib.getAddressOfSymbol(Tmp.c_str());
    if (!Addr && KV.second == SymbolLookupFlags::RequiredSymbol)
      R.emplace_back();
    else
      R.emplace_back(ExecutorAddr::fromPtr(Addr));
  }
  Complete(std::move(R));
}

} // namespace llvm::orc
