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

#include "test/common/wasm/wasm-module-runner.h"

#include "src/execution/isolate.h"
#include "src/handles/handles.h"
#include "src/objects/heap-number-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/property-descriptor.h"
#include "src/wasm/module-decoder.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-js.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects.h"
#include "src/wasm/wasm-opcodes.h"
#include "src/wasm/wasm-result.h"
#include "test/common/wasm/wasm-interpreter.h"

namespace v8 {
namespace internal {
namespace wasm {
namespace testing {

MaybeHandle<WasmModuleObject> CompileForTesting(Isolate* isolate,
                                                ErrorThrower* thrower,
                                                const ModuleWireBytes& bytes) {
  auto enabled_features = WasmFeatures::FromIsolate(isolate);
  MaybeHandle<WasmModuleObject> module = isolate->wasm_engine()->SyncCompile(
      isolate, enabled_features, thrower, bytes);
  DCHECK_EQ(thrower->error(), module.is_null());
  return module;
}

MaybeHandle<WasmInstanceObject> CompileAndInstantiateForTesting(
    Isolate* isolate, ErrorThrower* thrower, const ModuleWireBytes& bytes) {
  MaybeHandle<WasmModuleObject> module =
      CompileForTesting(isolate, thrower, bytes);
  if (module.is_null()) return {};
  return isolate->wasm_engine()->SyncInstantiate(
      isolate, thrower, module.ToHandleChecked(), {}, {});
}

OwnedVector<WasmValue> MakeDefaultInterpreterArguments(Isolate* isolate,
                                                       const FunctionSig* sig) {
  size_t param_count = sig->parameter_count();
  auto arguments = OwnedVector<WasmValue>::New(param_count);

  for (size_t i = 0; i < param_count; ++i) {
    switch (sig->GetParam(i).kind()) {
      case ValueType::kI32:
        arguments[i] = WasmValue(int32_t{0});
        break;
      case ValueType::kI64:
        arguments[i] = WasmValue(int64_t{0});
        break;
      case ValueType::kF32:
        arguments[i] = WasmValue(0.0f);
        break;
      case ValueType::kF64:
        arguments[i] = WasmValue(0.0);
        break;
      case ValueType::kS128:
        arguments[i] = WasmValue(Simd128{});
        break;
      case ValueType::kOptRef:
        arguments[i] =
            WasmValue(Handle<Object>::cast(isolate->factory()->null_value()));
        break;
      case ValueType::kRef:
      case ValueType::kRtt:
      case ValueType::kI8:
      case ValueType::kI16:
      case ValueType::kStmt:
      case ValueType::kBottom:
        UNREACHABLE();
    }
  }

  return arguments;
}

OwnedVector<Handle<Object>> MakeDefaultArguments(Isolate* isolate,
                                                 const FunctionSig* sig) {
  size_t param_count = sig->parameter_count();
  auto arguments = OwnedVector<Handle<Object>>::New(param_count);

  for (size_t i = 0; i < param_count; ++i) {
    switch (sig->GetParam(i).kind()) {
      case ValueType::kI32:
      case ValueType::kF32:
      case ValueType::kF64:
      case ValueType::kS128:
        // Argument here for kS128 does not matter as we should error out before
        // hitting this case.
        arguments[i] = handle(Smi::zero(), isolate);
        break;
      case ValueType::kI64:
        arguments[i] = BigInt::FromInt64(isolate, 0);
        break;
      case ValueType::kOptRef:
        arguments[i] = isolate->factory()->null_value();
        break;
      case ValueType::kRef:
      case ValueType::kRtt:
      case ValueType::kI8:
      case ValueType::kI16:
      case ValueType::kStmt:
      case ValueType::kBottom:
        UNREACHABLE();
    }
  }

  return arguments;
}

int32_t CompileAndRunWasmModule(Isolate* isolate, const byte* module_start,
                                const byte* module_end) {
  HandleScope scope(isolate);
  ErrorThrower thrower(isolate, "CompileAndRunWasmModule");
  MaybeHandle<WasmInstanceObject> instance = CompileAndInstantiateForTesting(
      isolate, &thrower, ModuleWireBytes(module_start, module_end));
  if (instance.is_null()) {
    return -1;
  }
  return CallWasmFunctionForTesting(isolate, instance.ToHandleChecked(), "main",
                                    0, nullptr);
}

WasmInterpretationResult InterpretWasmModule(
    Isolate* isolate, Handle<WasmInstanceObject> instance,
    int32_t function_index, WasmValue* args) {
  // Don't execute more than 16k steps.
  constexpr int kMaxNumSteps = 16 * 1024;

  Zone zone(isolate->allocator(), ZONE_NAME);
  v8::internal::HandleScope scope(isolate);
  const WasmFunction* func = &instance->module()->functions[function_index];

  CHECK(func->exported);
  // This would normally be handled by export wrappers.
  if (!IsJSCompatibleSignature(func->sig, instance->module(),
                               WasmFeatures::FromIsolate(isolate))) {
    return WasmInterpretationResult::Trapped(false);
  }

  WasmInterpreter interpreter{
      isolate, instance->module(),
      ModuleWireBytes{instance->module_object().native_module()->wire_bytes()},
      instance};
  interpreter.InitFrame(func, args);
  WasmInterpreter::State interpreter_result = interpreter.Run(kMaxNumSteps);

  bool stack_overflow = isolate->has_pending_exception();
  isolate->clear_pending_exception();

  if (stack_overflow) return WasmInterpretationResult::Failed();

  if (interpreter.state() == WasmInterpreter::TRAPPED) {
    return WasmInterpretationResult::Trapped(
        interpreter.PossibleNondeterminism());
  }

  if (interpreter_result == WasmInterpreter::FINISHED) {
    // Get the result as an {int32_t}. Keep this in sync with
    // {CallWasmFunctionForTesting}, because fuzzers will compare the results.
    int32_t result = -1;
    if (func->sig->return_count() > 0) {
      WasmValue return_value = interpreter.GetReturnValue();
      switch (func->sig->GetReturn(0).kind()) {
        case ValueType::kI32:
          result = return_value.to<int32_t>();
          break;
        case ValueType::kI64:
          result = static_cast<int32_t>(return_value.to<int64_t>());
          break;
        case ValueType::kF32:
          result = static_cast<int32_t>(return_value.to<float>());
          break;
        case ValueType::kF64:
          result = static_cast<int32_t>(return_value.to<double>());
          break;
        default:
          break;
      }
    }
    return WasmInterpretationResult::Finished(
        result, interpreter.PossibleNondeterminism());
  }

  // The interpreter did not finish within the limited number of steps, so it
  // might execute an infinite loop or infinite recursion. Return "failed"
  // status in that case.
  return WasmInterpretationResult::Failed();
}

MaybeHandle<WasmExportedFunction> GetExportedFunction(
    Isolate* isolate, Handle<WasmInstanceObject> instance, const char* name) {
  Handle<JSObject> exports_object;
  Handle<Name> exports = isolate->factory()->InternalizeUtf8String("exports");
  exports_object = Handle<JSObject>::cast(
      JSObject::GetProperty(isolate, instance, exports).ToHandleChecked());

  Handle<Name> main_name = isolate->factory()->NewStringFromAsciiChecked(name);
  PropertyDescriptor desc;
  Maybe<bool> property_found = JSReceiver::GetOwnPropertyDescriptor(
      isolate, exports_object, main_name, &desc);
  if (!property_found.FromMaybe(false)) return {};
  if (!desc.value()->IsJSFunction()) return {};

  return Handle<WasmExportedFunction>::cast(desc.value());
}

int32_t CallWasmFunctionForTesting(Isolate* isolate,
                                   Handle<WasmInstanceObject> instance,
                                   const char* name, int argc,
                                   Handle<Object> argv[], bool* exception) {
  if (exception) *exception = false;
  MaybeHandle<WasmExportedFunction> maybe_export =
      GetExportedFunction(isolate, instance, name);
  Handle<WasmExportedFunction> main_export;
  if (!maybe_export.ToHandle(&main_export)) {
    return -1;
  }

  // Call the JS function.
  Handle<Object> undefined = isolate->factory()->undefined_value();
  MaybeHandle<Object> retval =
      Execution::Call(isolate, main_export, undefined, argc, argv);

  // The result should be a number.
  if (retval.is_null()) {
    DCHECK(isolate->has_pending_exception());
    isolate->clear_pending_exception();
    if (exception) *exception = true;
    return -1;
  }
  Handle<Object> result = retval.ToHandleChecked();
  if (result->IsSmi()) {
    return Smi::ToInt(*result);
  }
  if (result->IsHeapNumber()) {
    return static_cast<int32_t>(HeapNumber::cast(*result).value());
  }
  if (result->IsBigInt()) {
    return static_cast<int32_t>(BigInt::cast(*result).AsInt64());
  }
  return -1;
}

void SetupIsolateForWasmModule(Isolate* isolate) {
  WasmJs::Install(isolate, true);
}

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