// Copyright 2019 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.

#include "test/wasm-api-tests/wasm-api-test.h"

namespace v8 {
namespace internal {
namespace wasm {

namespace {

int g_instances_finalized = 0;
int g_functions_finalized = 0;
int g_foreigns_finalized = 0;
int g_modules_finalized = 0;

const int kModuleMagic = 42;

void FinalizeInstance(void* data) {
  int iteration = static_cast<int>(reinterpret_cast<intptr_t>(data));
  g_instances_finalized += iteration;
}

void FinalizeFunction(void* data) {
  int iteration = static_cast<int>(reinterpret_cast<intptr_t>(data));
  g_functions_finalized += iteration;
}

void FinalizeForeign(void* data) {
  int iteration = static_cast<int>(reinterpret_cast<intptr_t>(data));
  g_foreigns_finalized += iteration;
}

void FinalizeModule(void* data) {
  g_modules_finalized += static_cast<int>(reinterpret_cast<intptr_t>(data));
}

void RunInStore(Store* store, ZoneBuffer* wire_bytes, int iterations) {
  size_t size = wire_bytes->end() - wire_bytes->begin();
  vec<byte_t> binary = vec<byte_t>::make(
      size, reinterpret_cast<byte_t*>(const_cast<byte*>(wire_bytes->begin())));
  own<Module> module = Module::make(store, binary);
  module->set_host_info(reinterpret_cast<void*>(kModuleMagic), &FinalizeModule);
  for (int iteration = 0; iteration < iterations; iteration++) {
    void* finalizer_data = reinterpret_cast<void*>(iteration);
    own<Instance> instance = Instance::make(store, module.get(), nullptr);
    EXPECT_NE(nullptr, instance.get());
    instance->set_host_info(finalizer_data, &FinalizeInstance);

    own<Func> func = instance->exports()[0]->func()->copy();
    ASSERT_NE(func, nullptr);
    func->set_host_info(finalizer_data, &FinalizeFunction);
    Val args[] = {Val::i32(iteration)};
    Val results[1];
    func->call(args, results);
    EXPECT_EQ(iteration, results[0].i32());

    own<Foreign> foreign = Foreign::make(store);
    foreign->set_host_info(finalizer_data, &FinalizeForeign);
  }
}

}  // namespace

TEST_F(WasmCapiTest, InstanceFinalization) {
  // Add a dummy function: f(x) { return x; }
  byte code[] = {WASM_RETURN1(WASM_GET_LOCAL(0))};
  AddExportedFunction(CStrVector("f"), code, sizeof(code), wasm_i_i_sig());
  Compile();
  g_instances_finalized = 0;
  g_functions_finalized = 0;
  g_foreigns_finalized = 0;
  g_modules_finalized = 0;
  module()->set_host_info(reinterpret_cast<void*>(kModuleMagic),
                          &FinalizeModule);
  static const int kIterations = 10;
  RunInStore(store(), wire_bytes(), kIterations);
  {
    own<Store> store2 = Store::make(engine());
    RunInStore(store2.get(), wire_bytes(), kIterations);
  }
  RunInStore(store(), wire_bytes(), kIterations);
  Shutdown();
  // Verify that (1) all finalizers were called, and (2) they passed the
  // correct host data: the loop above sets {i} as data, and the finalizer
  // callbacks add them all up, so the expected value after three rounds is
  // 3 * sum([0, 1, ..., kIterations - 1]), which per Gauss's formula is:
  static const int kExpected = 3 * ((kIterations * (kIterations - 1)) / 2);
  EXPECT_EQ(g_instances_finalized, kExpected);
  // There are two functions per iteration.
  EXPECT_EQ(g_functions_finalized, kExpected);
  EXPECT_EQ(g_foreigns_finalized, kExpected);
  EXPECT_EQ(g_modules_finalized, 4 * kModuleMagic);
}

namespace {

own<Trap> CapiFunction(void* env, const Val args[], Val results[]) {
  int offset = static_cast<int>(reinterpret_cast<intptr_t>(env));
  results[0] = Val::i32(offset + args[0].i32());
  return nullptr;
}

int g_host_data_finalized = 0;
int g_capi_function_finalized = 0;

void FinalizeCapiFunction(void* data) {
  int value = static_cast<int>(reinterpret_cast<intptr_t>(data));
  g_capi_function_finalized += value;
}

void FinalizeHostData(void* data) {
  g_host_data_finalized += static_cast<int>(reinterpret_cast<intptr_t>(data));
}

}  // namespace

TEST_F(WasmCapiTest, CapiFunctionLifetimes) {
  uint32_t func_index = builder()->AddImport(CStrVector("f"), wasm_i_i_sig());
  builder()->ExportImportedFunction(CStrVector("f"), func_index);
  Compile();
  own<Instance> instance;
  void* kHostData = reinterpret_cast<void*>(1234);
  int base_summand = 1000;
  {
    // Test that the own<> pointers for Func and FuncType can go out of scope
    // without affecting the ability of the Func to be called later.
    own<FuncType> capi_func_type =
        FuncType::make(ownvec<ValType>::make(ValType::make(::wasm::I32)),
                       ownvec<ValType>::make(ValType::make(::wasm::I32)));
    own<Func> capi_func =
        Func::make(store(), capi_func_type.get(), &CapiFunction,
                   reinterpret_cast<void*>(base_summand));
    Extern* imports[] = {capi_func.get()};
    instance = Instance::make(store(), module(), imports);
    // TODO(jkummerow): It may or may not be desirable to be able to set
    // host data even here and have it survive the import/export dance.
    // We are awaiting resolution of the discussion at:
    // https://github.com/WebAssembly/wasm-c-api/issues/100
  }
  {
    ownvec<Extern> exports = instance->exports();
    Func* exported_func = exports[0]->func();
    constexpr int kArg = 123;
    Val args[] = {Val::i32(kArg)};
    Val results[1];
    exported_func->call(args, results);
    EXPECT_EQ(base_summand + kArg, results[0].i32());
    // Host data should survive destruction of the own<> pointer.
    exported_func->set_host_info(kHostData);
  }
  {
    ownvec<Extern> exports = instance->exports();
    Func* exported_func = exports[0]->func();
    EXPECT_EQ(kHostData, exported_func->get_host_info());
  }
  // Test that a Func can have its own internal metadata, an {env}, and
  // separate {host info}, without any of that interfering with each other.
  g_host_data_finalized = 0;
  g_capi_function_finalized = 0;
  base_summand = 23;
  constexpr int kFinalizerData = 345;
  {
    own<FuncType> capi_func_type =
        FuncType::make(ownvec<ValType>::make(ValType::make(::wasm::I32)),
                       ownvec<ValType>::make(ValType::make(::wasm::I32)));
    own<Func> capi_func = Func::make(
        store(), capi_func_type.get(), &CapiFunction,
        reinterpret_cast<void*>(base_summand), &FinalizeCapiFunction);
    capi_func->set_host_info(reinterpret_cast<void*>(kFinalizerData),
                             &FinalizeHostData);
    constexpr int kArg = 19;
    Val args[] = {Val::i32(kArg)};
    Val results[1];
    capi_func->call(args, results);
    EXPECT_EQ(base_summand + kArg, results[0].i32());
  }
  instance.reset();
  Shutdown();
  EXPECT_EQ(base_summand, g_capi_function_finalized);
  EXPECT_EQ(kFinalizerData, g_host_data_finalized);
}

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