// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef WASM_RUN_UTILS_H
#define WASM_RUN_UTILS_H

#include <setjmp.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <array>
#include <memory>

#include "src/base/utils/random-number-generator.h"
#include "src/code-stubs.h"
#include "src/compiler/compiler-source-position-table.h"
#include "src/compiler/graph-visualizer.h"
#include "src/compiler/int64-lowering.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/node.h"
#include "src/compiler/pipeline.h"
#include "src/compiler/wasm-compiler.h"
#include "src/compiler/zone-stats.h"
#include "src/trap-handler/trap-handler.h"
#include "src/wasm/function-body-decoder.h"
#include "src/wasm/local-decl-encoder.h"
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-external-refs.h"
#include "src/wasm/wasm-interpreter.h"
#include "src/wasm/wasm-js.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects-inl.h"
#include "src/wasm/wasm-objects.h"
#include "src/wasm/wasm-opcodes.h"
#include "src/zone/accounting-allocator.h"
#include "src/zone/zone.h"

#include "test/cctest/cctest.h"
#include "test/cctest/compiler/call-tester.h"
#include "test/cctest/compiler/graph-builder-tester.h"
#include "test/common/wasm/flag-utils.h"

namespace v8 {
namespace internal {
namespace wasm {

constexpr uint32_t kMaxFunctions = 10;
constexpr uint32_t kMaxGlobalsSize = 128;

enum WasmExecutionMode {
  kExecuteInterpreter,
  kExecuteTurbofan,
  kExecuteLiftoff
};

enum LowerSimd : bool { kLowerSimd = true, kNoLowerSimd = false };

using compiler::CallDescriptor;
using compiler::MachineTypeForC;
using compiler::Node;

// TODO(titzer): check traps more robustly in tests.
// Currently, in tests, we just return 0xDEADBEEF from the function in which
// the trap occurs if the runtime context is not available to throw a JavaScript
// exception.
#define CHECK_TRAP32(x) \
  CHECK_EQ(0xDEADBEEF, (bit_cast<uint32_t>(x)) & 0xFFFFFFFF)
#define CHECK_TRAP64(x) \
  CHECK_EQ(0xDEADBEEFDEADBEEF, (bit_cast<uint64_t>(x)) & 0xFFFFFFFFFFFFFFFF)
#define CHECK_TRAP(x) CHECK_TRAP32(x)

#define WASM_WRAPPER_RETURN_VALUE 8754

#define BUILD(r, ...)                      \
  do {                                     \
    byte code[] = {__VA_ARGS__};           \
    r.Build(code, code + arraysize(code)); \
  } while (false)

// A  Wasm module builder. Globals are pre-set, however, memory and code may be
// progressively added by a test. In turn, we piecemeal update the runtime
// objects, i.e. {WasmInstanceObject}, {WasmCompiledModule} and, if necessary,
// the interpreter.
class TestingModuleBuilder {
 public:
  TestingModuleBuilder(Zone*, WasmExecutionMode,
                       compiler::RuntimeExceptionSupport, LowerSimd);

  void ChangeOriginToAsmjs() { test_module_.set_origin(kAsmJsOrigin); }

  byte* AddMemory(uint32_t size);

  size_t CodeTableLength() const {
    if (FLAG_wasm_jit_to_native) {
      return native_module_->FunctionCount();
    } else {
      return function_code_.size();
    }
  }

  template <typename T>
  T* AddMemoryElems(uint32_t count) {
    AddMemory(count * sizeof(T));
    return raw_mem_start<T>();
  }

  template <typename T>
  T* AddGlobal(
      ValueType type = WasmOpcodes::ValueTypeFor(MachineTypeForC<T>())) {
    const WasmGlobal* global = AddGlobal(type);
    return reinterpret_cast<T*>(globals_data_ + global->offset);
  }

  byte AddSignature(FunctionSig* sig) {
    DCHECK_EQ(test_module_.signatures.size(),
              test_module_.signature_ids.size());
    test_module_.signatures.push_back(sig);
    auto canonical_sig_num = test_module_.signature_map.FindOrInsert(sig);
    test_module_.signature_ids.push_back(canonical_sig_num);
    size_t size = test_module_.signatures.size();
    CHECK_GT(127, size);
    return static_cast<byte>(size - 1);
  }

  template <typename T>
  T* raw_mem_start() {
    DCHECK(mem_start_);
    return reinterpret_cast<T*>(mem_start_);
  }

  template <typename T>
  T* raw_mem_end() {
    DCHECK(mem_start_);
    return reinterpret_cast<T*>(mem_start_ + mem_size_);
  }

  template <typename T>
  T raw_mem_at(int i) {
    DCHECK(mem_start_);
    return ReadMemory(&(reinterpret_cast<T*>(mem_start_)[i]));
  }

  template <typename T>
  T raw_val_at(int i) {
    return ReadMemory(reinterpret_cast<T*>(mem_start_ + i));
  }

  template <typename T>
  void WriteMemory(T* p, T val) {
    WriteLittleEndianValue<T>(p, val);
  }

  template <typename T>
  T ReadMemory(T* p) {
    return ReadLittleEndianValue<T>(p);
  }

  // Zero-initialize the memory.
  void BlankMemory() {
    byte* raw = raw_mem_start<byte>();
    memset(raw, 0, mem_size_);
  }

  // Pseudo-randomly intialize the memory.
  void RandomizeMemory(unsigned int seed = 88) {
    byte* raw = raw_mem_start<byte>();
    byte* end = raw_mem_end<byte>();
    v8::base::RandomNumberGenerator rng;
    rng.SetSeed(seed);
    rng.NextBytes(raw, end - raw);
  }

  void SetMaxMemPages(uint32_t maximum_pages) {
    test_module_.maximum_pages = maximum_pages;
    if (instance_object()->has_memory_object()) {
      instance_object()->memory_object()->set_maximum_pages(maximum_pages);
    }
  }

  void SetHasSharedMemory() { test_module_.has_shared_memory = true; }

  uint32_t AddFunction(FunctionSig* sig, const char* name);

  uint32_t AddJsFunction(FunctionSig* sig, const char* source,
                         Handle<FixedArray> js_imports_table);

  Handle<JSFunction> WrapCode(uint32_t index);

  void SetFunctionCode(uint32_t index, Handle<Code> code) {
    function_code_[index] = code;
  }

  void AddIndirectFunctionTable(const uint16_t* function_indexes,
                                uint32_t table_size);

  void PopulateIndirectFunctionTable();

  uint32_t AddBytes(Vector<const byte> bytes);

  WasmFunction* GetFunctionAt(int index) {
    return &test_module_.functions[index];
  }

  WasmInterpreter* interpreter() { return interpreter_; }
  bool interpret() { return interpreter_ != nullptr; }
  LowerSimd lower_simd() { return lower_simd_; }
  Isolate* isolate() { return isolate_; }
  Handle<WasmInstanceObject> instance_object() { return instance_object_; }
  WasmCodeWrapper GetFunctionCode(uint32_t index) {
    if (FLAG_wasm_jit_to_native) {
      return WasmCodeWrapper(native_module_->GetCode(index));
    } else {
      return WasmCodeWrapper(function_code_[index]);
    }
  }
  void SetFunctionCode(int index, Handle<Code> code) {
    function_code_[index] = code;
  }
  Address globals_start() { return reinterpret_cast<Address>(globals_data_); }
  void Link() {
    if (!FLAG_wasm_jit_to_native) return;
    if (!linked_) {
      native_module_->LinkAll();
      linked_ = true;
      native_module_->SetExecutable(true);
    }
  }

  compiler::ModuleEnv CreateModuleEnv();

  WasmExecutionMode execution_mode() const { return execution_mode_; }

  compiler::RuntimeExceptionSupport runtime_exception_support() const {
    return runtime_exception_support_;
  }

 private:
  WasmModule test_module_;
  WasmModule* test_module_ptr_;
  Isolate* isolate_;
  uint32_t global_offset;
  byte* mem_start_;
  uint32_t mem_size_;
  std::vector<Handle<Code>> function_code_;
  std::vector<GlobalHandleAddress> function_tables_;
  V8_ALIGNED(16) byte globals_data_[kMaxGlobalsSize];
  WasmInterpreter* interpreter_;
  WasmExecutionMode execution_mode_;
  Handle<WasmInstanceObject> instance_object_;
  NativeModule* native_module_;
  bool linked_ = false;
  compiler::RuntimeExceptionSupport runtime_exception_support_;
  LowerSimd lower_simd_;

  const WasmGlobal* AddGlobal(ValueType type);

  Handle<WasmInstanceObject> InitInstanceObject();
};

void TestBuildingGraph(
    Zone* zone, compiler::JSGraph* jsgraph, compiler::ModuleEnv* module,
    FunctionSig* sig, compiler::SourcePositionTable* source_position_table,
    const byte* start, const byte* end,
    compiler::RuntimeExceptionSupport runtime_exception_support);

class WasmFunctionWrapper : private compiler::GraphAndBuilders {
 public:
  WasmFunctionWrapper(Zone* zone, int num_params);

  void Init(CallDescriptor* descriptor, MachineType return_type,
            Vector<MachineType> param_types);

  template <typename ReturnType, typename... ParamTypes>
  void Init(CallDescriptor* descriptor) {
    std::array<MachineType, sizeof...(ParamTypes)> param_machine_types{
        {MachineTypeForC<ParamTypes>()...}};
    Vector<MachineType> param_vec(param_machine_types.data(),
                                  param_machine_types.size());
    Init(descriptor, MachineTypeForC<ReturnType>(), param_vec);
  }

  void SetInnerCode(WasmCodeWrapper code) {
    if (FLAG_wasm_jit_to_native) {
      intptr_t address = reinterpret_cast<intptr_t>(
          code.GetWasmCode()->instructions().start());
      compiler::NodeProperties::ChangeOp(
          inner_code_node_,
          kPointerSize == 8
              ? common()->RelocatableInt64Constant(address,
                                                   RelocInfo::WASM_CALL)
              : common()->RelocatableInt32Constant(static_cast<int>(address),
                                                   RelocInfo::WASM_CALL));
    } else {
      compiler::NodeProperties::ChangeOp(
          inner_code_node_, common()->HeapConstant(code.GetCode()));
    }
  }

  const compiler::Operator* IntPtrConstant(intptr_t value) {
    return machine()->Is32()
               ? common()->Int32Constant(static_cast<int32_t>(value))
               : common()->Int64Constant(static_cast<int64_t>(value));
  }

  void SetContextAddress(uintptr_t value) {
    auto rmode = RelocInfo::WASM_CONTEXT_REFERENCE;
    auto op = kPointerSize == 8 ? common()->RelocatableInt64Constant(
                                      static_cast<int64_t>(value), rmode)
                                : common()->RelocatableInt32Constant(
                                      static_cast<int32_t>(value), rmode);
    compiler::NodeProperties::ChangeOp(context_address_, op);
  }

  Handle<Code> GetWrapperCode();

  Signature<MachineType>* signature() const { return signature_; }

 private:
  Node* inner_code_node_;
  Node* context_address_;
  Handle<Code> code_;
  Signature<MachineType>* signature_;
};

// A helper for compiling wasm functions for testing.
// It contains the internal state for compilation (i.e. TurboFan graph) and
// interpretation (by adding to the interpreter manually).
class WasmFunctionCompiler : public compiler::GraphAndBuilders {
 public:
  ~WasmFunctionCompiler();

  Isolate* isolate() { return builder_->isolate(); }
  CallDescriptor* descriptor() {
    if (descriptor_ == nullptr) {
      descriptor_ = compiler::GetWasmCallDescriptor(zone(), sig);
    }
    return descriptor_;
  }
  uint32_t function_index() { return function_->func_index; }

  void Build(const byte* start, const byte* end);

  byte AllocateLocal(ValueType type) {
    uint32_t index = local_decls.AddLocals(1, type);
    byte result = static_cast<byte>(index);
    DCHECK_EQ(index, result);
    return result;
  }

  void SetSigIndex(int sig_index) { function_->sig_index = sig_index; }

 private:
  friend class WasmRunnerBase;

  WasmFunctionCompiler(Zone* zone, FunctionSig* sig,
                       TestingModuleBuilder* builder, const char* name);

  compiler::JSGraph jsgraph;
  FunctionSig* sig;
  // The call descriptor is initialized when the function is compiled.
  CallDescriptor* descriptor_;
  TestingModuleBuilder* builder_;
  WasmFunction* function_;
  LocalDeclEncoder local_decls;
  compiler::SourcePositionTable source_position_table_;
  WasmInterpreter* interpreter_;
};

// A helper class to build a module around Wasm bytecode, generate machine
// code, and run that code.
class WasmRunnerBase : public HandleAndZoneScope {
 public:
  WasmRunnerBase(WasmExecutionMode execution_mode, int num_params,
                 compiler::RuntimeExceptionSupport runtime_exception_support,
                 LowerSimd lower_simd)
      : zone_(&allocator_, ZONE_NAME),
        builder_(&zone_, execution_mode, runtime_exception_support, lower_simd),
        wrapper_(&zone_, num_params) {}

  // Builds a graph from the given Wasm code and generates the machine
  // code and call wrapper for that graph. This method must not be called
  // more than once.
  void Build(const byte* start, const byte* end) {
    CHECK(!compiled_);
    compiled_ = true;
    functions_[0]->Build(start, end);
  }

  // Resets the state for building the next function.
  // The main function called will always be the first function.
  template <typename ReturnType, typename... ParamTypes>
  WasmFunctionCompiler& NewFunction(const char* name = nullptr) {
    return NewFunction(CreateSig<ReturnType, ParamTypes...>(), name);
  }

  // Resets the state for building the next function.
  // The main function called will be the last generated function.
  // Returns the index of the previously built function.
  WasmFunctionCompiler& NewFunction(FunctionSig* sig,
                                    const char* name = nullptr) {
    functions_.emplace_back(
        new WasmFunctionCompiler(&zone_, sig, &builder_, name));
    return *functions_.back();
  }

  byte AllocateLocal(ValueType type) {
    return functions_[0]->AllocateLocal(type);
  }

  uint32_t function_index() { return functions_[0]->function_index(); }
  WasmFunction* function() { return functions_[0]->function_; }
  WasmInterpreter* interpreter() {
    DCHECK(interpret());
    return functions_[0]->interpreter_;
  }
  bool possible_nondeterminism() { return possible_nondeterminism_; }
  TestingModuleBuilder& builder() { return builder_; }
  Zone* zone() { return &zone_; }

  bool interpret() { return builder_.interpret(); }

  template <typename ReturnType, typename... ParamTypes>
  FunctionSig* CreateSig() {
    std::array<MachineType, sizeof...(ParamTypes)> param_machine_types{
        {MachineTypeForC<ParamTypes>()...}};
    Vector<MachineType> param_vec(param_machine_types.data(),
                                  param_machine_types.size());
    return CreateSig(MachineTypeForC<ReturnType>(), param_vec);
  }

 private:
  FunctionSig* CreateSig(MachineType return_type,
                         Vector<MachineType> param_types);

 protected:
  v8::internal::AccountingAllocator allocator_;
  Zone zone_;
  TestingModuleBuilder builder_;
  std::vector<std::unique_ptr<WasmFunctionCompiler>> functions_;
  WasmFunctionWrapper wrapper_;
  bool compiled_ = false;
  bool possible_nondeterminism_ = false;

 public:
  // This field has to be static. Otherwise, gcc complains about the use in
  // the lambda context below.
  static bool trap_happened;
};

template <typename ReturnType, typename... ParamTypes>
class WasmRunner : public WasmRunnerBase {
 public:
  WasmRunner(WasmExecutionMode execution_mode,
             const char* main_fn_name = "main",
             compiler::RuntimeExceptionSupport runtime_exception_support =
                 compiler::kNoRuntimeExceptionSupport,
             LowerSimd lower_simd = kNoLowerSimd)
      : WasmRunnerBase(execution_mode, sizeof...(ParamTypes),
                       runtime_exception_support, lower_simd) {
    NewFunction<ReturnType, ParamTypes...>(main_fn_name);
    if (!interpret()) {
      wrapper_.Init<ReturnType, ParamTypes...>(functions_[0]->descriptor());
    }
  }

  WasmRunner(WasmExecutionMode execution_mode, LowerSimd lower_simd)
      : WasmRunner(execution_mode, "main", compiler::kNoRuntimeExceptionSupport,
                   lower_simd) {}

  ReturnType Call(ParamTypes... p) {
    DCHECK(compiled_);
    if (interpret()) return CallInterpreter(p...);

    ReturnType return_value = static_cast<ReturnType>(0xDEADBEEFDEADBEEF);
    WasmRunnerBase::trap_happened = false;
    auto trap_callback = []() -> void {
      WasmRunnerBase::trap_happened = true;
      set_trap_callback_for_testing(nullptr);
    };
    set_trap_callback_for_testing(trap_callback);

    wrapper_.SetInnerCode(builder_.GetFunctionCode(0));
    WasmContext* wasm_context =
        builder().instance_object()->wasm_context()->get();
    wrapper_.SetContextAddress(reinterpret_cast<uintptr_t>(wasm_context));
    builder().Link();
    Handle<Code> wrapper_code = wrapper_.GetWrapperCode();
    compiler::CodeRunner<int32_t> runner(CcTest::InitIsolateOnce(),
                                         wrapper_code, wrapper_.signature());
    int32_t result = runner.Call(static_cast<void*>(&p)...,
                                 static_cast<void*>(&return_value));
    CHECK_EQ(WASM_WRAPPER_RETURN_VALUE, result);
    return WasmRunnerBase::trap_happened
               ? static_cast<ReturnType>(0xDEADBEEFDEADBEEF)
               : return_value;
  }

  ReturnType CallInterpreter(ParamTypes... p) {
    WasmInterpreter::Thread* thread = interpreter()->GetThread(0);
    thread->Reset();
    std::array<WasmValue, sizeof...(p)> args{{WasmValue(p)...}};
    thread->InitFrame(function(), args.data());
    WasmInterpreter::HeapObjectsScope heap_objects_scope(
        interpreter(), builder().instance_object());
    if (thread->Run() == WasmInterpreter::FINISHED) {
      WasmValue val = thread->GetReturnValue();
      possible_nondeterminism_ |= thread->PossibleNondeterminism();
      return val.to<ReturnType>();
    } else if (thread->state() == WasmInterpreter::TRAPPED) {
      // TODO(titzer): return the correct trap code
      int64_t result = 0xDEADBEEFDEADBEEF;
      return static_cast<ReturnType>(result);
    } else {
      // TODO(titzer): falling off end
      return ReturnType{0};
    }
  }

  Handle<Code> GetWrapperCode() { return wrapper_.GetWrapperCode(); }
};

// A macro to define tests that run in different engine configurations.
#define WASM_EXEC_TEST(name)                                               \
  void RunWasm_##name(WasmExecutionMode execution_mode);                   \
  TEST(RunWasmTurbofan_##name) { RunWasm_##name(kExecuteTurbofan); }       \
  TEST(RunWasmLiftoff_##name) { RunWasm_##name(kExecuteLiftoff); }         \
  TEST(RunWasmInterpreter_##name) { RunWasm_##name(kExecuteInterpreter); } \
  void RunWasm_##name(WasmExecutionMode execution_mode)

#define WASM_COMPILED_EXEC_TEST(name)                                \
  void RunWasm_##name(WasmExecutionMode execution_mode);             \
  TEST(RunWasmTurbofan_##name) { RunWasm_##name(kExecuteTurbofan); } \
  TEST(RunWasmLiftoff_##name) { RunWasm_##name(kExecuteLiftoff); }   \
  void RunWasm_##name(WasmExecutionMode execution_mode)

#define WASM_EXEC_TEST_WITH_TRAP(name)                   \
  void RunWasm_##name(WasmExecutionMode execution_mode); \
  TEST(RunWasmTurbofan_##name) {                         \
    if (trap_handler::UseTrapHandler()) return;          \
    RunWasm_##name(kExecuteTurbofan);                    \
  }                                                      \
  TEST(RunWasmLiftoff_##name) {                          \
    if (trap_handler::UseTrapHandler()) return;          \
    RunWasm_##name(kExecuteLiftoff);                     \
  }                                                      \
  TEST(RunWasmInterpreter_##name) {                      \
    if (trap_handler::UseTrapHandler()) return;          \
    RunWasm_##name(kExecuteInterpreter);                 \
  }                                                      \
  void RunWasm_##name(WasmExecutionMode execution_mode)

}  // namespace wasm
}  // namespace internal
}  // namespace v8

#endif
