//===-- MCJIT.h - Class definition for the MCJIT ----------------*- 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_MCJIT_MCJIT_H
#define LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H

#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/ObjectCache.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/SmallVectorMemoryBuffer.h"

namespace llvm {
class MCJIT;

// This is a helper class that the MCJIT execution engine uses for linking
// functions across modules that it owns.  It aggregates the memory manager
// that is passed in to the MCJIT constructor and defers most functionality
// to that object.
class LinkingSymbolResolver : public LegacyJITSymbolResolver {
public:
  LinkingSymbolResolver(MCJIT &Parent,
                        std::shared_ptr<LegacyJITSymbolResolver> Resolver)
      : ParentEngine(Parent), ClientResolver(std::move(Resolver)) {}

  JITSymbol findSymbol(const std::string &Name) override;

  // MCJIT doesn't support logical dylibs.
  JITSymbol findSymbolInLogicalDylib(const std::string &Name) override {
    return nullptr;
  }

private:
  MCJIT &ParentEngine;
  std::shared_ptr<LegacyJITSymbolResolver> ClientResolver;
  void anchor() override;
};

// About Module states: added->loaded->finalized.
//
// The purpose of the "added" state is having modules in standby. (added=known
// but not compiled). The idea is that you can add a module to provide function
// definitions but if nothing in that module is referenced by a module in which
// a function is executed (note the wording here because it's not exactly the
// ideal case) then the module never gets compiled. This is sort of lazy
// compilation.
//
// The purpose of the "loaded" state (loaded=compiled and required sections
// copied into local memory but not yet ready for execution) is to have an
// intermediate state wherein clients can remap the addresses of sections, using
// MCJIT::mapSectionAddress, (in preparation for later copying to a new location
// or an external process) before relocations and page permissions are applied.
//
// It might not be obvious at first glance, but the "remote-mcjit" case in the
// lli tool does this.  In that case, the intermediate action is taken by the
// RemoteMemoryManager in response to the notifyObjectLoaded function being
// called.

class MCJIT : public ExecutionEngine {
  MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> tm,
        std::shared_ptr<MCJITMemoryManager> MemMgr,
        std::shared_ptr<LegacyJITSymbolResolver> Resolver);

  typedef llvm::SmallPtrSet<Module *, 4> ModulePtrSet;

  class OwningModuleContainer {
  public:
    OwningModuleContainer() {
    }
    ~OwningModuleContainer() {
      freeModulePtrSet(AddedModules);
      freeModulePtrSet(LoadedModules);
      freeModulePtrSet(FinalizedModules);
    }

    ModulePtrSet::iterator begin_added() { return AddedModules.begin(); }
    ModulePtrSet::iterator end_added() { return AddedModules.end(); }
    iterator_range<ModulePtrSet::iterator> added() {
      return make_range(begin_added(), end_added());
    }

    ModulePtrSet::iterator begin_loaded() { return LoadedModules.begin(); }
    ModulePtrSet::iterator end_loaded() { return LoadedModules.end(); }

    ModulePtrSet::iterator begin_finalized() { return FinalizedModules.begin(); }
    ModulePtrSet::iterator end_finalized() { return FinalizedModules.end(); }

    void addModule(std::unique_ptr<Module> M) {
      AddedModules.insert(M.release());
    }

    bool removeModule(Module *M) {
      return AddedModules.erase(M) || LoadedModules.erase(M) ||
             FinalizedModules.erase(M);
    }

    bool hasModuleBeenAddedButNotLoaded(Module *M) {
      return AddedModules.count(M) != 0;
    }

    bool hasModuleBeenLoaded(Module *M) {
      // If the module is in either the "loaded" or "finalized" sections it
      // has been loaded.
      return (LoadedModules.count(M) != 0 ) || (FinalizedModules.count(M) != 0);
    }

    bool hasModuleBeenFinalized(Module *M) {
      return FinalizedModules.count(M) != 0;
    }

    bool ownsModule(Module* M) {
      return (AddedModules.count(M) != 0) || (LoadedModules.count(M) != 0) ||
             (FinalizedModules.count(M) != 0);
    }

    void markModuleAsLoaded(Module *M) {
      // This checks against logic errors in the MCJIT implementation.
      // This function should never be called with either a Module that MCJIT
      // does not own or a Module that has already been loaded and/or finalized.
      assert(AddedModules.count(M) &&
             "markModuleAsLoaded: Module not found in AddedModules");

      // Remove the module from the "Added" set.
      AddedModules.erase(M);

      // Add the Module to the "Loaded" set.
      LoadedModules.insert(M);
    }

    void markModuleAsFinalized(Module *M) {
      // This checks against logic errors in the MCJIT implementation.
      // This function should never be called with either a Module that MCJIT
      // does not own, a Module that has not been loaded or a Module that has
      // already been finalized.
      assert(LoadedModules.count(M) &&
             "markModuleAsFinalized: Module not found in LoadedModules");

      // Remove the module from the "Loaded" section of the list.
      LoadedModules.erase(M);

      // Add the Module to the "Finalized" section of the list by inserting it
      // before the 'end' iterator.
      FinalizedModules.insert(M);
    }

    void markAllLoadedModulesAsFinalized() {
      for (ModulePtrSet::iterator I = LoadedModules.begin(),
                                  E = LoadedModules.end();
           I != E; ++I) {
        Module *M = *I;
        FinalizedModules.insert(M);
      }
      LoadedModules.clear();
    }

  private:
    ModulePtrSet AddedModules;
    ModulePtrSet LoadedModules;
    ModulePtrSet FinalizedModules;

    void freeModulePtrSet(ModulePtrSet& MPS) {
      // Go through the module set and delete everything.
      for (ModulePtrSet::iterator I = MPS.begin(), E = MPS.end(); I != E; ++I) {
        Module *M = *I;
        delete M;
      }
      MPS.clear();
    }
  };

  std::unique_ptr<TargetMachine> TM;
  MCContext *Ctx;
  std::shared_ptr<MCJITMemoryManager> MemMgr;
  LinkingSymbolResolver Resolver;
  RuntimeDyld Dyld;
  std::vector<JITEventListener*> EventListeners;

  OwningModuleContainer OwnedModules;

  SmallVector<object::OwningBinary<object::Archive>, 2> Archives;
  SmallVector<std::unique_ptr<MemoryBuffer>, 2> Buffers;

  SmallVector<std::unique_ptr<object::ObjectFile>, 2> LoadedObjects;

  // An optional ObjectCache to be notified of compiled objects and used to
  // perform lookup of pre-compiled code to avoid re-compilation.
  ObjectCache *ObjCache;

  Function *FindFunctionNamedInModulePtrSet(StringRef FnName,
                                            ModulePtrSet::iterator I,
                                            ModulePtrSet::iterator E);

  GlobalVariable *FindGlobalVariableNamedInModulePtrSet(StringRef Name,
                                                        bool AllowInternal,
                                                        ModulePtrSet::iterator I,
                                                        ModulePtrSet::iterator E);

  void runStaticConstructorsDestructorsInModulePtrSet(bool isDtors,
                                                      ModulePtrSet::iterator I,
                                                      ModulePtrSet::iterator E);

public:
  ~MCJIT() override;

  /// @name ExecutionEngine interface implementation
  /// @{
  void addModule(std::unique_ptr<Module> M) override;
  void addObjectFile(std::unique_ptr<object::ObjectFile> O) override;
  void addObjectFile(object::OwningBinary<object::ObjectFile> O) override;
  void addArchive(object::OwningBinary<object::Archive> O) override;
  bool removeModule(Module *M) override;

  /// FindFunctionNamed - Search all of the active modules to find the function that
  /// defines FnName.  This is very slow operation and shouldn't be used for
  /// general code.
  Function *FindFunctionNamed(StringRef FnName) override;

  /// FindGlobalVariableNamed - Search all of the active modules to find the
  /// global variable that defines Name.  This is very slow operation and
  /// shouldn't be used for general code.
  GlobalVariable *FindGlobalVariableNamed(StringRef Name,
                                          bool AllowInternal = false) override;

  /// Sets the object manager that MCJIT should use to avoid compilation.
  void setObjectCache(ObjectCache *manager) override;

  void setProcessAllSections(bool ProcessAllSections) override {
    Dyld.setProcessAllSections(ProcessAllSections);
  }

  void generateCodeForModule(Module *M) override;

  /// finalizeObject - ensure the module is fully processed and is usable.
  ///
  /// It is the user-level function for completing the process of making the
  /// object usable for execution. It should be called after sections within an
  /// object have been relocated using mapSectionAddress.  When this method is
  /// called the MCJIT execution engine will reapply relocations for a loaded
  /// object.
  /// Is it OK to finalize a set of modules, add modules and finalize again.
  // FIXME: Do we really need both of these?
  void finalizeObject() override;
  virtual void finalizeModule(Module *);
  void finalizeLoadedModules();

  /// runStaticConstructorsDestructors - This method is used to execute all of
  /// the static constructors or destructors for a program.
  ///
  /// \param isDtors - Run the destructors instead of constructors.
  void runStaticConstructorsDestructors(bool isDtors) override;

  void *getPointerToFunction(Function *F) override;

  GenericValue runFunction(Function *F,
                           ArrayRef<GenericValue> ArgValues) override;

  /// getPointerToNamedFunction - This method returns the address of the
  /// specified function by using the dlsym function call.  As such it is only
  /// useful for resolving library symbols, not code generated symbols.
  ///
  /// If AbortOnFailure is false and no function with the given name is
  /// found, this function silently returns a null pointer. Otherwise,
  /// it prints a message to stderr and aborts.
  ///
  void *getPointerToNamedFunction(StringRef Name,
                                  bool AbortOnFailure = true) override;

  /// mapSectionAddress - map a section to its target address space value.
  /// Map the address of a JIT section as returned from the memory manager
  /// to the address in the target process as the running code will see it.
  /// This is the address which will be used for relocation resolution.
  void mapSectionAddress(const void *LocalAddress,
                         uint64_t TargetAddress) override {
    Dyld.mapSectionAddress(LocalAddress, TargetAddress);
  }
  void RegisterJITEventListener(JITEventListener *L) override;
  void UnregisterJITEventListener(JITEventListener *L) override;

  // If successful, these function will implicitly finalize all loaded objects.
  // To get a function address within MCJIT without causing a finalize, use
  // getSymbolAddress.
  uint64_t getGlobalValueAddress(const std::string &Name) override;
  uint64_t getFunctionAddress(const std::string &Name) override;

  TargetMachine *getTargetMachine() override { return TM.get(); }

  /// @}
  /// @name (Private) Registration Interfaces
  /// @{

  static void Register() {
    MCJITCtor = createJIT;
  }

  static ExecutionEngine *
  createJIT(std::unique_ptr<Module> M, std::string *ErrorStr,
            std::shared_ptr<MCJITMemoryManager> MemMgr,
            std::shared_ptr<LegacyJITSymbolResolver> Resolver,
            std::unique_ptr<TargetMachine> TM);

  // @}

  // Takes a mangled name and returns the corresponding JITSymbol (if a
  // definition of that mangled name has been added to the JIT).
  JITSymbol findSymbol(const std::string &Name, bool CheckFunctionsOnly);

  // DEPRECATED - Please use findSymbol instead.
  //
  // This is not directly exposed via the ExecutionEngine API, but it is
  // used by the LinkingMemoryManager.
  //
  // getSymbolAddress takes an unmangled name and returns the corresponding
  // JITSymbol if a definition of the name has been added to the JIT.
  uint64_t getSymbolAddress(const std::string &Name,
                            bool CheckFunctionsOnly);

protected:
  /// emitObject -- Generate a JITed object in memory from the specified module
  /// Currently, MCJIT only supports a single module and the module passed to
  /// this function call is expected to be the contained module.  The module
  /// is passed as a parameter here to prepare for multiple module support in
  /// the future.
  std::unique_ptr<MemoryBuffer> emitObject(Module *M);

  void notifyObjectLoaded(const object::ObjectFile &Obj,
                          const RuntimeDyld::LoadedObjectInfo &L);
  void notifyFreeingObject(const object::ObjectFile &Obj);

  JITSymbol findExistingSymbol(const std::string &Name);
  Module *findModuleForSymbol(const std::string &Name, bool CheckFunctionsOnly);
};

} // end llvm namespace

#endif // LLVM_LIB_EXECUTIONENGINE_MCJIT_MCJIT_H
