//===------ OrcLazyJIT.cpp - Basic Orc-based JIT for lazy execution -------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "OrcLazyJIT.h"
#include "llvm/ExecutionEngine/Orc/OrcABISupport.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/DynamicLibrary.h"
#include <cstdio>
#include <system_error>

using namespace llvm;

namespace {

  enum class DumpKind { NoDump, DumpFuncsToStdOut, DumpModsToStdOut,
                        DumpModsToDisk };

  cl::opt<DumpKind> OrcDumpKind("orc-lazy-debug",
                                cl::desc("Debug dumping for the orc-lazy JIT."),
                                cl::init(DumpKind::NoDump),
                                cl::values(
                                  clEnumValN(DumpKind::NoDump, "no-dump",
                                             "Don't dump anything."),
                                  clEnumValN(DumpKind::DumpFuncsToStdOut,
                                             "funcs-to-stdout",
                                             "Dump function names to stdout."),
                                  clEnumValN(DumpKind::DumpModsToStdOut,
                                             "mods-to-stdout",
                                             "Dump modules to stdout."),
                                  clEnumValN(DumpKind::DumpModsToDisk,
                                             "mods-to-disk",
                                             "Dump modules to the current "
                                             "working directory. (WARNING: "
                                             "will overwrite existing files).")),
                                cl::Hidden);

  cl::opt<bool> OrcInlineStubs("orc-lazy-inline-stubs",
                               cl::desc("Try to inline stubs"),
                               cl::init(true), cl::Hidden);
}

OrcLazyJIT::TransformFtor OrcLazyJIT::createDebugDumper() {

  switch (OrcDumpKind) {
  case DumpKind::NoDump:
    return [](std::unique_ptr<Module> M) { return M; };

  case DumpKind::DumpFuncsToStdOut:
    return [](std::unique_ptr<Module> M) {
      printf("[ ");

      for (const auto &F : *M) {
        if (F.isDeclaration())
          continue;

        if (F.hasName()) {
          std::string Name(F.getName());
          printf("%s ", Name.c_str());
        } else
          printf("<anon> ");
      }

      printf("]\n");
      return M;
    };

  case DumpKind::DumpModsToStdOut:
    return [](std::unique_ptr<Module> M) {
             outs() << "----- Module Start -----\n" << *M
                    << "----- Module End -----\n";

             return M;
           };

  case DumpKind::DumpModsToDisk:
    return [](std::unique_ptr<Module> M) {
             std::error_code EC;
             raw_fd_ostream Out(M->getModuleIdentifier() + ".ll", EC,
                                sys::fs::F_Text);
             if (EC) {
               errs() << "Couldn't open " << M->getModuleIdentifier()
                      << " for dumping.\nError:" << EC.message() << "\n";
               exit(1);
             }
             Out << *M;
             return M;
           };
  }
  llvm_unreachable("Unknown DumpKind");
}

// Defined in lli.cpp.
CodeGenOpt::Level getOptLevel();


template <typename PtrTy>
static PtrTy fromTargetAddress(JITTargetAddress Addr) {
  return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
}

int llvm::runOrcLazyJIT(std::vector<std::unique_ptr<Module>> Ms,
                        const std::vector<std::string> &Args) {
  // Add the program's symbols into the JIT's search space.
  if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) {
    errs() << "Error loading program symbols.\n";
    return 1;
  }

  // Grab a target machine and try to build a factory function for the
  // target-specific Orc callback manager.
  EngineBuilder EB;
  EB.setOptLevel(getOptLevel());
  auto TM = std::unique_ptr<TargetMachine>(EB.selectTarget());
  Triple T(TM->getTargetTriple());
  auto CompileCallbackMgr = orc::createLocalCompileCallbackManager(T, 0);

  // If we couldn't build the factory function then there must not be a callback
  // manager for this target. Bail out.
  if (!CompileCallbackMgr) {
    errs() << "No callback manager available for target '"
           << TM->getTargetTriple().str() << "'.\n";
    return 1;
  }

  auto IndirectStubsMgrBuilder = orc::createLocalIndirectStubsManagerBuilder(T);

  // If we couldn't build a stubs-manager-builder for this target then bail out.
  if (!IndirectStubsMgrBuilder) {
    errs() << "No indirect stubs manager available for target '"
           << TM->getTargetTriple().str() << "'.\n";
    return 1;
  }

  // Everything looks good. Build the JIT.
  OrcLazyJIT J(std::move(TM), std::move(CompileCallbackMgr),
               std::move(IndirectStubsMgrBuilder),
               OrcInlineStubs);

  // Add the module, look up main and run it.
  J.addModuleSet(std::move(Ms));
  auto MainSym = J.findSymbol("main");

  if (!MainSym) {
    errs() << "Could not find main function.\n";
    return 1;
  }

  typedef int (*MainFnPtr)(int, const char*[]);
  std::vector<const char *> ArgV;
  for (auto &Arg : Args)
    ArgV.push_back(Arg.c_str());
  auto Main = fromTargetAddress<MainFnPtr>(MainSym.getAddress());
  return Main(ArgV.size(), (const char**)ArgV.data());
}

