/*
 * Copyright 2016 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// Implementation of the shell interpreter execution environment
//

#ifndef wasm_shell_interface_h
#define wasm_shell_interface_h

#include "asmjs/shared-constants.h"
#include "interpreter/exception.h"
#include "ir/module-utils.h"
#include "shared-constants.h"
#include "support/bits.h"
#include "support/name.h"
#include "support/utilities.h"
#include "wasm-interpreter.h"
#include "wasm.h"

namespace wasm {

struct ShellExternalInterface : ModuleRunner::ExternalInterface {
  class Memory {
    // Use char because it doesn't run afoul of aliasing rules.
    std::vector<char> memory;

  public:
    Memory() = default;
    void resize(size_t newSize) {
      // Ensure the smallest allocation is large enough that most allocators
      // will provide page-aligned storage. This hopefully allows the
      // interpreter's memory to be as aligned as the memory being simulated,
      // ensuring that the performance doesn't needlessly degrade.
      //
      // The code is optimistic this will work until WG21's p0035r0 happens.
      const size_t minSize = 1 << 12;
      size_t oldSize = memory.size();
      memory.resize(std::max(minSize, newSize));
      if (newSize < oldSize && newSize < minSize) {
        std::memset(&memory[newSize], 0, minSize - newSize);
      }
    }
    template<typename T> void set(size_t address, T value) {
      Bits::writeLE<T>(value, &memory[address]);
    }
    template<typename T> T get(size_t address) {
      return Bits::readLE<T>(&memory[address]);
    }
  };

  std::map<Name, Memory> memories;
  std::map<Name, std::shared_ptr<ModuleRunner>> linkedInstances;

  ShellExternalInterface(
    std::map<Name, std::shared_ptr<ModuleRunner>> linkedInstances_ = {}) {
    linkedInstances.swap(linkedInstances_);
  }
  virtual ~ShellExternalInterface() = default;

  ModuleRunner* getImportInstanceOrNull(Importable* import) {
    auto it = linkedInstances.find(import->module);
    if (it == linkedInstances.end()) {
      return nullptr;
    }
    return it->second.get();
  }

  ModuleRunner* getImportInstance(Importable* import) {
    auto* ret = getImportInstanceOrNull(import);
    if (!ret) {
      Fatal() << "getImportInstance: unknown import: " << import->module.str
              << "." << import->base.str;
    }
    return ret;
  }

  void init(Module& wasm, ModuleRunner& instance) override {
    ModuleUtils::iterDefinedMemories(wasm, [&](wasm::Memory* memory) {
      // Compute the initial size in bytes carefully: the byte size of a
      // maximal memory64 (2^48 pages of 64KiB) does not fit in 64 bits. If
      // we let it wrap, instantiation would "succeed" with an empty buffer
      // and every later access would spuriously trap as out of bounds.
      uint64_t bytes = uint64_t(memory->initial) << memory->pageSizeLog2;
      if ((bytes >> memory->pageSizeLog2) != uint64_t(memory->initial)) {
        // The byte size is not even representable; we certainly cannot
        // allocate it, just like a real VM could not.
        hostLimit("memory too large");
      }
      auto shellMemory = Memory();
      try {
        shellMemory.resize(bytes);
      } catch (const std::exception&) {
        // bad_alloc or length_error from the underlying vector: the memory
        // is representable but too large to actually allocate.
        hostLimit("memory too large");
      }
      memories[memory->name] = shellMemory;
    });
  }

  Literal getImportedFunction(Function* import) override {
    // TODO: We should perhaps restrict the types with which the well-known
    // functions can be imported.
    if (import->module == SPECTEST && import->base.startsWith(PRINT)) {
      // Use a null instance because these are host functions.
      return Literal(
        std::make_shared<FuncData>(import->name,
                                   nullptr,
                                   [](const Literals& arguments) -> Flow {
                                     for (auto argument : arguments) {
                                       std::cout << argument << " : "
                                                 << argument.type << '\n';
                                     }
                                     return Flow();
                                   }),
        import->type);
    } else if (import->module == ENV && import->base == EXIT) {
      return Literal(std::make_shared<FuncData>(import->name,
                                                nullptr,
                                                [](const Literals&) -> Flow {
                                                  // XXX hack for torture tests
                                                  std::cout << "exit()\n";
                                                  throw ExitException();
                                                }),
                     import->type);
    } else if (auto* inst = getImportInstanceOrNull(import)) {
      return inst->getExportedFunction(import->base);
    }
    // This is not a known import. Create a literal for it, which is good enough
    // if it is never called (see the ref_func.wast spec test, which does that).
    std::cerr << "warning: getImportedFunction: unknown import: "
              << import->module.str << "." << import->name.str << '\n';
    return Literal::makeFunc(import->name, import->type);
  }

  int8_t load8s(Address addr, Name memoryName) override {
    auto it = memories.find(memoryName);
    assert(it != memories.end());
    auto& memory = it->second;
    return memory.get<int8_t>(addr);
  }
  uint8_t load8u(Address addr, Name memoryName) override {
    auto it = memories.find(memoryName);
    assert(it != memories.end());
    auto& memory = it->second;
    return memory.get<uint8_t>(addr);
  }
  int16_t load16s(Address addr, Name memoryName) override {
    auto it = memories.find(memoryName);
    assert(it != memories.end());
    auto& memory = it->second;
    return memory.get<int16_t>(addr);
  }
  uint16_t load16u(Address addr, Name memoryName) override {
    auto it = memories.find(memoryName);
    assert(it != memories.end());
    auto& memory = it->second;
    return memory.get<uint16_t>(addr);
  }
  int32_t load32s(Address addr, Name memoryName) override {
    auto it = memories.find(memoryName);
    assert(it != memories.end());
    auto& memory = it->second;
    return memory.get<int32_t>(addr);
  }
  uint32_t load32u(Address addr, Name memoryName) override {
    auto it = memories.find(memoryName);
    assert(it != memories.end());
    auto& memory = it->second;
    return memory.get<uint32_t>(addr);
  }
  int64_t load64s(Address addr, Name memoryName) override {
    auto it = memories.find(memoryName);
    assert(it != memories.end());
    auto& memory = it->second;
    return memory.get<int64_t>(addr);
  }
  uint64_t load64u(Address addr, Name memoryName) override {
    auto it = memories.find(memoryName);
    assert(it != memories.end());
    auto& memory = it->second;
    return memory.get<uint64_t>(addr);
  }
  std::array<uint8_t, 16> load128(Address addr, Name memoryName) override {
    auto it = memories.find(memoryName);
    assert(it != memories.end());
    auto& memory = it->second;
    return memory.get<std::array<uint8_t, 16>>(addr);
  }

  void store8(Address addr, int8_t value, Name memoryName) override {
    auto it = memories.find(memoryName);
    assert(it != memories.end());
    auto& memory = it->second;
    memory.set<int8_t>(addr, value);
  }
  void store16(Address addr, int16_t value, Name memoryName) override {
    auto it = memories.find(memoryName);
    assert(it != memories.end());
    auto& memory = it->second;
    memory.set<int16_t>(addr, value);
  }
  void store32(Address addr, int32_t value, Name memoryName) override {
    auto it = memories.find(memoryName);
    assert(it != memories.end());
    auto& memory = it->second;
    memory.set<int32_t>(addr, value);
  }
  void store64(Address addr, int64_t value, Name memoryName) override {
    auto it = memories.find(memoryName);
    assert(it != memories.end());
    auto& memory = it->second;
    memory.set<int64_t>(addr, value);
  }
  void store128(Address addr,
                const std::array<uint8_t, 16>& value,
                Name memoryName) override {
    auto it = memories.find(memoryName);
    assert(it != memories.end());
    auto& memory = it->second;
    memory.set<std::array<uint8_t, 16>>(addr, value);
  }
  bool
  growMemory(Name memoryName, Address /*oldSize*/, Address newSize) override {
    // Apply a reasonable limit on memory size, 1GB, to avoid DOS on the
    // interpreter.
    if (newSize > 1024 * 1024 * 1024) {
      return false;
    }
    auto it = memories.find(memoryName);
    if (it == memories.end()) {
      trap("growMemory on non-existing memory");
    }
    auto& memory = it->second;
    memory.resize(newSize);
    return true;
  }
  void trap(std::string_view why) override {
    std::cout << "[trap " << why << "]\n";
    throw TrapException();
  }

  void hostLimit(std::string_view why) override {
    std::cout << "[host limit " << why << "]\n";
    throw HostLimitException();
  }
  void throwException(const WasmException& exn) override { throw exn; }
};

} // namespace wasm

#endif // wasm_shell_interface_h
