// 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/fuzzer/wasm-fuzzer-common.h"

#include <ctime>

#include "include/v8.h"
#include "src/execution/isolate.h"
#include "src/utils/ostreams.h"
#include "src/objects/objects-inl.h"
#include "src/wasm/wasm-engine.h"
#include "src/wasm/wasm-module-builder.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects-inl.h"
#include "src/zone/accounting-allocator.h"
#include "src/zone/zone.h"
#include "test/common/wasm/flag-utils.h"
#include "test/common/wasm/wasm-module-runner.h"
#include "test/fuzzer/fuzzer-support.h"

namespace v8 {
namespace internal {
namespace wasm {
namespace fuzzer {

void InterpretAndExecuteModule(i::Isolate* isolate,
                               Handle<WasmModuleObject> module_object) {
  // We do not instantiate the module if there is a start function, because a
  // start function can contain an infinite loop which we cannot handle.
  if (module_object->module()->start_function_index >= 0) return;

  ErrorThrower thrower(isolate, "WebAssembly Instantiation");
  MaybeHandle<WasmInstanceObject> maybe_instance;
  Handle<WasmInstanceObject> instance;

  // Try to instantiate and interpret the module_object.
  maybe_instance = isolate->wasm_engine()->SyncInstantiate(
      isolate, &thrower, module_object,
      Handle<JSReceiver>::null(),     // imports
      MaybeHandle<JSArrayBuffer>());  // memory
  if (!maybe_instance.ToHandle(&instance)) {
    isolate->clear_pending_exception();
    thrower.Reset();  // Ignore errors.
    return;
  }
  if (!testing::InterpretWasmModuleForTesting(isolate, instance, "main", 0,
                                              nullptr)) {
    isolate->clear_pending_exception();
    return;
  }

  // Try to instantiate and execute the module_object.
  maybe_instance = isolate->wasm_engine()->SyncInstantiate(
      isolate, &thrower, module_object,
      Handle<JSReceiver>::null(),     // imports
      MaybeHandle<JSArrayBuffer>());  // memory
  if (!maybe_instance.ToHandle(&instance)) {
    isolate->clear_pending_exception();
    thrower.Reset();  // Ignore errors.
    return;
  }
  if (testing::RunWasmModuleForTesting(isolate, instance, 0, nullptr) < 0) {
    isolate->clear_pending_exception();
    return;
  }
}

namespace {
struct PrintSig {
  const size_t num;
  const std::function<ValueType(size_t)> getter;
};
PrintSig PrintParameters(const FunctionSig* sig) {
  return {sig->parameter_count(), [=](size_t i) { return sig->GetParam(i); }};
}
PrintSig PrintReturns(const FunctionSig* sig) {
  return {sig->return_count(), [=](size_t i) { return sig->GetReturn(i); }};
}
const char* ValueTypeToConstantName(ValueType type) {
  switch (type) {
    case kWasmI32:
      return "kWasmI32";
    case kWasmI64:
      return "kWasmI64";
    case kWasmF32:
      return "kWasmF32";
    case kWasmF64:
      return "kWasmF64";
    default:
      UNREACHABLE();
  }
}
std::ostream& operator<<(std::ostream& os, const PrintSig& print) {
  os << "[";
  for (size_t i = 0; i < print.num; ++i) {
    os << (i == 0 ? "" : ", ") << ValueTypeToConstantName(print.getter(i));
  }
  return os << "]";
}

struct PrintName {
  WasmName name;
  PrintName(ModuleWireBytes wire_bytes, WireBytesRef ref)
      : name(wire_bytes.GetNameOrNull(ref)) {}
};
std::ostream& operator<<(std::ostream& os, const PrintName& name) {
  return os.write(name.name.begin(), name.name.size());
}
}  // namespace

void GenerateTestCase(Isolate* isolate, ModuleWireBytes wire_bytes,
                      bool compiles) {
  constexpr bool kVerifyFunctions = false;
  auto enabled_features = i::wasm::WasmFeaturesFromIsolate(isolate);
  ModuleResult module_res = DecodeWasmModule(
      enabled_features, wire_bytes.start(), wire_bytes.end(), kVerifyFunctions,
      ModuleOrigin::kWasmOrigin, isolate->counters(),
      isolate->wasm_engine()->allocator());
  CHECK(module_res.ok());
  WasmModule* module = module_res.value().get();
  CHECK_NOT_NULL(module);

  StdoutStream os;

  tzset();
  time_t current_time = time(nullptr);
  struct tm current_localtime;
#ifdef V8_OS_WIN
  localtime_s(&current_localtime, &current_time);
#else
  localtime_r(&current_time, &current_localtime);
#endif
  int year = 1900 + current_localtime.tm_year;

  os << "// Copyright " << year
     << " the V8 project authors. All rights reserved.\n"
        "// Use of this source code is governed by a BSD-style license that "
        "can be\n"
        "// found in the LICENSE file.\n"
        "\n"
        "load('test/mjsunit/wasm/wasm-module-builder.js');\n"
        "\n"
        "(function() {\n"
        "  const builder = new WasmModuleBuilder();\n";

  if (module->has_memory) {
    os << "  builder.addMemory(" << module->initial_pages;
    if (module->has_maximum_pages) {
      os << ", " << module->maximum_pages;
    } else {
      os << ", undefined";
    }
    os << ", " << (module->mem_export ? "true" : "false");
    if (module->has_shared_memory) {
      os << ", true";
    }
    os << ");\n";
  }

  for (WasmGlobal& glob : module->globals) {
    os << "  builder.addGlobal(" << ValueTypeToConstantName(glob.type) << ", "
       << glob.mutability << ");\n";
  }

  for (const FunctionSig* sig : module->signatures) {
    os << "  builder.addType(makeSig(" << PrintParameters(sig) << ", "
       << PrintReturns(sig) << "));\n";
  }

  Zone tmp_zone(isolate->allocator(), ZONE_NAME);

  // There currently cannot be more than one table.
  DCHECK_GE(1, module->tables.size());
  for (const WasmTable& table : module->tables) {
    os << "  builder.setTableBounds(" << table.initial_size << ", ";
    if (table.has_maximum_size) {
      os << table.maximum_size << ");\n";
    } else {
      os << "undefined);\n";
    }
  }
  for (const WasmElemSegment& elem_segment : module->elem_segments) {
    os << "  builder.addElementSegment(";
    switch (elem_segment.offset.kind) {
      case WasmInitExpr::kGlobalIndex:
        os << elem_segment.offset.val.global_index << ", true";
        break;
      case WasmInitExpr::kI32Const:
        os << elem_segment.offset.val.i32_const << ", false";
        break;
      default:
        UNREACHABLE();
    }
    os << ", " << PrintCollection(elem_segment.entries) << ");\n";
  }

  for (const WasmFunction& func : module->functions) {
    Vector<const uint8_t> func_code = wire_bytes.GetFunctionBytes(&func);
    os << "  // Generate function " << (func.func_index + 1) << " (out of "
       << module->functions.size() << ").\n";

    // Add function.
    os << "  builder.addFunction(undefined, " << func.sig_index
       << " /* sig */)\n";

    // Add locals.
    BodyLocalDecls decls(&tmp_zone);
    DecodeLocalDecls(enabled_features, &decls, func_code.begin(),
                     func_code.end());
    if (!decls.type_list.empty()) {
      os << "    ";
      for (size_t pos = 0, count = 1, locals = decls.type_list.size();
           pos < locals; pos += count, count = 1) {
        ValueType type = decls.type_list[pos];
        while (pos + count < locals && decls.type_list[pos + count] == type)
          ++count;
        os << ".addLocals({" << ValueTypes::TypeName(type)
           << "_count: " << count << "})";
      }
      os << "\n";
    }

    // Add body.
    os << "    .addBodyWithEnd([\n";

    FunctionBody func_body(func.sig, func.code.offset(), func_code.begin(),
                           func_code.end());
    PrintRawWasmCode(isolate->allocator(), func_body, module, kOmitLocals);
    os << "            ]);\n";
  }

  for (WasmExport& exp : module->export_table) {
    if (exp.kind != kExternalFunction) continue;
    os << "  builder.addExport('" << PrintName(wire_bytes, exp.name) << "', "
       << exp.index << ");\n";
  }

  if (compiles) {
    os << "  const instance = builder.instantiate();\n"
          "  print(instance.exports.main(1, 2, 3));\n";
  } else {
    os << "  assertThrows(function() { builder.instantiate(); }, "
          "WebAssembly.CompileError);\n";
  }
  os << "})();\n";
}

void WasmExecutionFuzzer::FuzzWasmModule(Vector<const uint8_t> data,
                                         bool require_valid) {
  // Strictly enforce the input size limit. Note that setting "max_len" on the
  // fuzzer target is not enough, since different fuzzers are used and not all
  // respect that limit.
  if (data.size() > max_input_size()) return;

  v8_fuzzer::FuzzerSupport* support = v8_fuzzer::FuzzerSupport::Get();
  v8::Isolate* isolate = support->GetIsolate();
  i::Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);

  // Clear any pending exceptions from a prior run.
  i_isolate->clear_pending_exception();

  v8::Isolate::Scope isolate_scope(isolate);
  v8::HandleScope handle_scope(isolate);
  v8::Context::Scope context_scope(support->GetContext());
  v8::TryCatch try_catch(isolate);
  HandleScope scope(i_isolate);

  AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);

  ZoneBuffer buffer(&zone);
  int32_t num_args = 0;
  std::unique_ptr<WasmValue[]> interpreter_args;
  std::unique_ptr<Handle<Object>[]> compiler_args;
  // The first byte builds the bitmask to control which function will be
  // compiled with Turbofan and which one with Liftoff.
  uint8_t tier_mask = data.empty() ? 0 : data[0];
  if (!data.empty()) data += 1;
  if (!GenerateModule(i_isolate, &zone, data, &buffer, &num_args,
                      &interpreter_args, &compiler_args)) {
    return;
  }

  testing::SetupIsolateForWasmModule(i_isolate);

  ErrorThrower interpreter_thrower(i_isolate, "Interpreter");
  ModuleWireBytes wire_bytes(buffer.begin(), buffer.end());

  // Compile with Turbofan here. Liftoff will be tested later.
  auto enabled_features = i::wasm::WasmFeaturesFromIsolate(i_isolate);
  MaybeHandle<WasmModuleObject> compiled_module;
  {
    // Explicitly enable Liftoff, disable tiering and set the tier_mask. This
    // way, we deterministically test a combination of Liftoff and Turbofan.
    FlagScope<bool> liftoff(&FLAG_liftoff, true);
    FlagScope<bool> no_tier_up(&FLAG_wasm_tier_up, false);
    FlagScope<int> tier_mask_scope(&FLAG_wasm_tier_mask_for_testing, tier_mask);
    compiled_module = i_isolate->wasm_engine()->SyncCompile(
        i_isolate, enabled_features, &interpreter_thrower, wire_bytes);
  }
  bool compiles = !compiled_module.is_null();

  if (FLAG_wasm_fuzzer_gen_test) {
    GenerateTestCase(i_isolate, wire_bytes, compiles);
  }

  bool validates = i_isolate->wasm_engine()->SyncValidate(
      i_isolate, enabled_features, wire_bytes);

  CHECK_EQ(compiles, validates);
  CHECK_IMPLIES(require_valid, validates);

  if (!compiles) return;

  MaybeHandle<WasmInstanceObject> interpreter_instance =
      i_isolate->wasm_engine()->SyncInstantiate(
          i_isolate, &interpreter_thrower, compiled_module.ToHandleChecked(),
          MaybeHandle<JSReceiver>(), MaybeHandle<JSArrayBuffer>());

  // Ignore instantiation failure.
  if (interpreter_thrower.error()) return;

  testing::WasmInterpretationResult interpreter_result =
      testing::InterpretWasmModule(i_isolate,
                                   interpreter_instance.ToHandleChecked(), 0,
                                   interpreter_args.get());

  // Do not execute the generated code if the interpreter did not finished after
  // a bounded number of steps.
  if (interpreter_result.stopped()) return;

  // The WebAssembly spec allows the sign bit of NaN to be non-deterministic.
  // This sign bit can make the difference between an infinite loop and
  // terminating code. With possible non-determinism we cannot guarantee that
  // the generated code will not go into an infinite loop and cause a timeout in
  // Clusterfuzz. Therefore we do not execute the generated code if the result
  // may be non-deterministic.
  if (interpreter_result.possible_nondeterminism()) return;

  int32_t result_compiled;
  {
    ErrorThrower compiler_thrower(i_isolate, "Compile");
    MaybeHandle<WasmInstanceObject> compiled_instance =
        i_isolate->wasm_engine()->SyncInstantiate(
            i_isolate, &compiler_thrower, compiled_module.ToHandleChecked(),
            MaybeHandle<JSReceiver>(), MaybeHandle<JSArrayBuffer>());

    DCHECK(!compiler_thrower.error());
    result_compiled = testing::CallWasmFunctionForTesting(
        i_isolate, compiled_instance.ToHandleChecked(), &compiler_thrower,
        "main", num_args, compiler_args.get());
  }

  if (interpreter_result.trapped() != i_isolate->has_pending_exception()) {
    const char* exception_text[] = {"no exception", "exception"};
    FATAL("interpreter: %s; compiled: %s",
          exception_text[interpreter_result.trapped()],
          exception_text[i_isolate->has_pending_exception()]);
  }

  if (!interpreter_result.trapped()) {
    CHECK_EQ(interpreter_result.result(), result_compiled);
  }

  // Cleanup any pending exception.
  i_isolate->clear_pending_exception();
}

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