// 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 "src/codegen/assembler-inl.h"
#include "src/debug/debug-interface.h"
#include "src/execution/frames-inl.h"
#include "src/objects/property-descriptor.h"
#include "src/utils/utils.h"
#include "src/wasm/wasm-debug.h"
#include "src/wasm/wasm-objects-inl.h"
#include "test/cctest/cctest.h"
#include "test/cctest/compiler/value-helper.h"
#include "test/cctest/wasm/wasm-run-utils.h"
#include "test/common/wasm/test-signatures.h"
#include "test/common/wasm/wasm-macro-gen.h"

namespace v8 {
namespace internal {
namespace wasm {

namespace {

debug::Location TranslateLocation(WasmRunnerBase* runner,
                                  const debug::Location& loc) {
  // Convert locations from {func_index, offset_in_func} to
  // {0, offset_in_module}.
  int func_index = loc.GetLineNumber();
  int func_offset = runner->builder().GetFunctionAt(func_index)->code.offset();
  int offset = loc.GetColumnNumber() + func_offset;
  return {0, offset};
}

void CheckLocations(
    WasmRunnerBase* runner, NativeModule* native_module, debug::Location start,
    debug::Location end,
    std::initializer_list<debug::Location> expected_locations_init) {
  std::vector<debug::BreakLocation> locations;
  std::vector<debug::Location> expected_locations;
  for (auto loc : expected_locations_init) {
    expected_locations.push_back(TranslateLocation(runner, loc));
  }

  bool success = WasmScript::GetPossibleBreakpoints(
      native_module, TranslateLocation(runner, start),
      TranslateLocation(runner, end), &locations);
  CHECK(success);

  printf("got %d locations: ", static_cast<int>(locations.size()));
  for (size_t i = 0, e = locations.size(); i != e; ++i) {
    printf("%s<%d,%d>", i == 0 ? "" : ", ", locations[i].GetLineNumber(),
           locations[i].GetColumnNumber());
  }
  printf("\n");

  CHECK_EQ(expected_locations.size(), locations.size());
  for (size_t i = 0, e = locations.size(); i != e; ++i) {
    CHECK_EQ(expected_locations[i].GetLineNumber(),
             locations[i].GetLineNumber());
    CHECK_EQ(expected_locations[i].GetColumnNumber(),
             locations[i].GetColumnNumber());
  }
}

void CheckLocationsFail(WasmRunnerBase* runner, NativeModule* native_module,
                        debug::Location start, debug::Location end) {
  std::vector<debug::BreakLocation> locations;
  bool success = WasmScript::GetPossibleBreakpoints(
      native_module, TranslateLocation(runner, start),
      TranslateLocation(runner, end), &locations);
  CHECK(!success);
}

class BreakHandler : public debug::DebugDelegate {
 public:
  enum Action {
    Continue = StepAction::LastStepAction + 1,
    StepNext = StepAction::StepNext,
    StepIn = StepAction::StepIn,
    StepOut = StepAction::StepOut
  };
  struct BreakPoint {
    int position;
    Action action;
    std::function<void(void)> pre_action;
    BreakPoint(int position, Action action)
        : position(position), action(action), pre_action([]() {}) {}
    BreakPoint(int position, Action action,
               std::function<void(void)> pre_action)
        : position(position), action(action), pre_action(pre_action) {}
  };

  explicit BreakHandler(Isolate* isolate,
                        std::initializer_list<BreakPoint> expected_breaks)
      : isolate_(isolate), expected_breaks_(expected_breaks) {
    v8::debug::SetDebugDelegate(reinterpret_cast<v8::Isolate*>(isolate_), this);
  }
  ~BreakHandler() override {
    // Check that all expected breakpoints have been hit.
    CHECK_EQ(count_, expected_breaks_.size());
    v8::debug::SetDebugDelegate(reinterpret_cast<v8::Isolate*>(isolate_),
                                nullptr);
  }

  int count() const { return count_; }

 private:
  Isolate* isolate_;
  int count_ = 0;
  std::vector<BreakPoint> expected_breaks_;

  void BreakProgramRequested(v8::Local<v8::Context> paused_context,
                             const std::vector<int>&) override {
    printf("Break #%d\n", count_);
    CHECK_GT(expected_breaks_.size(), count_);

    // Check the current position.
    StackTraceFrameIterator frame_it(isolate_);
    auto summ = FrameSummary::GetTop(frame_it.frame()).AsWasm();
    CHECK_EQ(expected_breaks_[count_].position, summ.byte_offset());

    expected_breaks_[count_].pre_action();
    Action next_action = expected_breaks_[count_].action;
    switch (next_action) {
      case Continue:
        break;
      case StepNext:
      case StepIn:
      case StepOut:
        isolate_->debug()->PrepareStep(static_cast<StepAction>(next_action));
        break;
      default:
        UNREACHABLE();
    }
    ++count_;
  }
};

Handle<BreakPoint> SetBreakpoint(WasmRunnerBase* runner, int function_index,
                                 int byte_offset,
                                 int expected_set_byte_offset = -1) {
  runner->TierDown();
  int func_offset =
      runner->builder().GetFunctionAt(function_index)->code.offset();
  int code_offset = func_offset + byte_offset;
  if (expected_set_byte_offset == -1) expected_set_byte_offset = byte_offset;
  Handle<WasmInstanceObject> instance = runner->builder().instance_object();
  Handle<Script> script(instance->module_object().script(),
                        runner->main_isolate());
  static int break_index = 0;
  Handle<BreakPoint> break_point =
      runner->main_isolate()->factory()->NewBreakPoint(
          break_index++, runner->main_isolate()->factory()->empty_string());
  CHECK(WasmScript::SetBreakPoint(script, &code_offset, break_point));
  return break_point;
}

void ClearBreakpoint(WasmRunnerBase* runner, int function_index,
                     int byte_offset, Handle<BreakPoint> break_point) {
  int func_offset =
      runner->builder().GetFunctionAt(function_index)->code.offset();
  int code_offset = func_offset + byte_offset;
  Handle<WasmInstanceObject> instance = runner->builder().instance_object();
  Handle<Script> script(instance->module_object().script(),
                        runner->main_isolate());
  CHECK(WasmScript::ClearBreakPoint(script, code_offset, break_point));
}

// Wrapper with operator<<.
struct WasmValWrapper {
  WasmValue val;

  bool operator==(const WasmValWrapper& other) const {
    return val == other.val;
  }
};

// Only needed in debug builds. Avoid unused warning otherwise.
#ifdef DEBUG
std::ostream& operator<<(std::ostream& out, const WasmValWrapper& wrapper) {
  switch (wrapper.val.type().kind()) {
    case ValueType::kI32:
      out << "i32: " << wrapper.val.to<int32_t>();
      break;
    case ValueType::kI64:
      out << "i64: " << wrapper.val.to<int64_t>();
      break;
    case ValueType::kF32:
      out << "f32: " << wrapper.val.to<float>();
      break;
    case ValueType::kF64:
      out << "f64: " << wrapper.val.to<double>();
      break;
    default:
      UNIMPLEMENTED();
  }
  return out;
}
#endif

class CollectValuesBreakHandler : public debug::DebugDelegate {
 public:
  struct BreakpointValues {
    std::vector<WasmValue> locals;
    std::vector<WasmValue> stack;
  };

  explicit CollectValuesBreakHandler(
      Isolate* isolate, std::initializer_list<BreakpointValues> expected_values)
      : isolate_(isolate), expected_values_(expected_values) {
    v8::debug::SetDebugDelegate(reinterpret_cast<v8::Isolate*>(isolate_), this);
  }
  ~CollectValuesBreakHandler() override {
    v8::debug::SetDebugDelegate(reinterpret_cast<v8::Isolate*>(isolate_),
                                nullptr);
  }

 private:
  Isolate* isolate_;
  int count_ = 0;
  std::vector<BreakpointValues> expected_values_;

  void BreakProgramRequested(v8::Local<v8::Context> paused_context,
                             const std::vector<int>&) override {
    printf("Break #%d\n", count_);
    CHECK_GT(expected_values_.size(), count_);
    auto& expected = expected_values_[count_];
    ++count_;

    HandleScope handles(isolate_);

    StackTraceFrameIterator frame_it(isolate_);
    WasmFrame* frame = WasmFrame::cast(frame_it.frame());
    DebugInfo* debug_info = frame->native_module()->GetDebugInfo();

    int num_locals = debug_info->GetNumLocals(frame->pc());
    CHECK_EQ(expected.locals.size(), num_locals);
    for (int i = 0; i < num_locals; ++i) {
      WasmValue local_value = debug_info->GetLocalValue(
          i, frame->pc(), frame->fp(), frame->callee_fp());
      CHECK_EQ(WasmValWrapper{expected.locals[i]}, WasmValWrapper{local_value});
    }

    int stack_depth = debug_info->GetStackDepth(frame->pc());
    CHECK_EQ(expected.stack.size(), stack_depth);
    for (int i = 0; i < stack_depth; ++i) {
      WasmValue stack_value = debug_info->GetStackValue(
          i, frame->pc(), frame->fp(), frame->callee_fp());
      CHECK_EQ(WasmValWrapper{expected.stack[i]}, WasmValWrapper{stack_value});
    }

    isolate_->debug()->PrepareStep(StepAction::StepIn);
  }
};

// Special template to explicitly cast to WasmValue.
template <typename Arg>
WasmValue MakeWasmVal(Arg arg) {
  return WasmValue(arg);
}
// Translate long to i64 (ambiguous otherwise).
template <>
WasmValue MakeWasmVal(long arg) {  // NOLINT: allow long parameter
  return WasmValue(static_cast<int64_t>(arg));
}

template <typename... Args>
std::vector<WasmValue> wasmVec(Args... args) {
  std::array<WasmValue, sizeof...(args)> arr{{MakeWasmVal(args)...}};
  return std::vector<WasmValue>{arr.begin(), arr.end()};
}

int GetIntReturnValue(MaybeHandle<Object> retval) {
  CHECK(!retval.is_null());
  int result;
  CHECK(retval.ToHandleChecked()->ToInt32(&result));
  return result;
}

}  // namespace

WASM_COMPILED_EXEC_TEST(WasmCollectPossibleBreakpoints) {
  WasmRunner<int> runner(execution_tier);

  BUILD(runner, WASM_NOP, WASM_I32_ADD(WASM_ZERO, WASM_ONE));

  WasmInstanceObject instance = *runner.builder().instance_object();
  NativeModule* native_module = instance.module_object().native_module();

  std::vector<debug::Location> locations;
  // Check all locations for function 0.
  CheckLocations(&runner, native_module, {0, 0}, {0, 10},
                 {{0, 1}, {0, 2}, {0, 4}, {0, 6}, {0, 7}});
  // Check a range ending at an instruction.
  CheckLocations(&runner, native_module, {0, 2}, {0, 4}, {{0, 2}});
  // Check a range ending one behind an instruction.
  CheckLocations(&runner, native_module, {0, 2}, {0, 5}, {{0, 2}, {0, 4}});
  // Check a range starting at an instruction.
  CheckLocations(&runner, native_module, {0, 7}, {0, 8}, {{0, 7}});
  // Check from an instruction to beginning of next function.
  CheckLocations(&runner, native_module, {0, 7}, {0, 10}, {{0, 7}});
  // Check from end of one function (no valid instruction position) to beginning
  // of next function. Must be empty, but not fail.
  CheckLocations(&runner, native_module, {0, 8}, {0, 10}, {});
  // Check from one after the end of the function. Must fail.
  CheckLocationsFail(&runner, native_module, {0, 9}, {0, 10});
}

WASM_COMPILED_EXEC_TEST(WasmSimpleBreak) {
  WasmRunner<int> runner(execution_tier);
  Isolate* isolate = runner.main_isolate();

  BUILD(runner, WASM_NOP, WASM_I32_ADD(WASM_I32V_1(11), WASM_I32V_1(3)));

  Handle<JSFunction> main_fun_wrapper =
      runner.builder().WrapCode(runner.function_index());
  SetBreakpoint(&runner, runner.function_index(), 4, 4);

  BreakHandler count_breaks(isolate, {{4, BreakHandler::Continue}});

  Handle<Object> global(isolate->context().global_object(), isolate);
  MaybeHandle<Object> retval =
      Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr);
  CHECK_EQ(14, GetIntReturnValue(retval));
}

WASM_COMPILED_EXEC_TEST(WasmNonBreakablePosition) {
  WasmRunner<int> runner(execution_tier);
  Isolate* isolate = runner.main_isolate();

  BUILD(runner, WASM_RETURN1(WASM_I32V_2(1024)));

  Handle<JSFunction> main_fun_wrapper =
      runner.builder().WrapCode(runner.function_index());
  SetBreakpoint(&runner, runner.function_index(), 2, 4);

  BreakHandler count_breaks(isolate, {{4, BreakHandler::Continue}});

  Handle<Object> global(isolate->context().global_object(), isolate);
  MaybeHandle<Object> retval =
      Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr);
  CHECK_EQ(1024, GetIntReturnValue(retval));
}

WASM_COMPILED_EXEC_TEST(WasmSimpleStepping) {
  WasmRunner<int> runner(execution_tier);
  BUILD(runner, WASM_I32_ADD(WASM_I32V_1(11), WASM_I32V_1(3)));

  Isolate* isolate = runner.main_isolate();
  Handle<JSFunction> main_fun_wrapper =
      runner.builder().WrapCode(runner.function_index());

  // Set breakpoint at the first I32Const.
  SetBreakpoint(&runner, runner.function_index(), 1, 1);

  BreakHandler count_breaks(isolate,
                            {
                                {1, BreakHandler::StepNext},  // I32Const
                                {3, BreakHandler::StepNext},  // I32Const
                                {5, BreakHandler::Continue}   // I32Add
                            });

  Handle<Object> global(isolate->context().global_object(), isolate);
  MaybeHandle<Object> retval =
      Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr);
  CHECK_EQ(14, GetIntReturnValue(retval));
}

WASM_COMPILED_EXEC_TEST(WasmStepInAndOut) {
  WasmRunner<int, int> runner(execution_tier);
  runner.TierDown();
  WasmFunctionCompiler& f2 = runner.NewFunction<void>();
  f2.AllocateLocal(kWasmI32);

  // Call f2 via indirect call, because a direct call requires f2 to exist when
  // we compile main, but we need to compile main first so that the order of
  // functions in the code section matches the function indexes.

  // return arg0
  BUILD(runner, WASM_RETURN1(WASM_GET_LOCAL(0)));
  // for (int i = 0; i < 10; ++i) { f2(i); }
  BUILD(f2, WASM_LOOP(
                WASM_BR_IF(0, WASM_BINOP(kExprI32GeU, WASM_GET_LOCAL(0),
                                         WASM_I32V_1(10))),
                WASM_SET_LOCAL(
                    0, WASM_BINOP(kExprI32Sub, WASM_GET_LOCAL(0), WASM_ONE)),
                WASM_CALL_FUNCTION(runner.function_index(), WASM_GET_LOCAL(0)),
                WASM_DROP, WASM_BR(1)));

  Isolate* isolate = runner.main_isolate();
  Handle<JSFunction> main_fun_wrapper =
      runner.builder().WrapCode(f2.function_index());

  // Set first breakpoint on the LocalGet (offset 19) before the Call.
  SetBreakpoint(&runner, f2.function_index(), 19, 19);

  BreakHandler count_breaks(isolate,
                            {
                                {19, BreakHandler::StepIn},   // LocalGet
                                {21, BreakHandler::StepIn},   // Call
                                {1, BreakHandler::StepOut},   // in f2
                                {23, BreakHandler::Continue}  // After Call
                            });

  Handle<Object> global(isolate->context().global_object(), isolate);
  CHECK(!Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr)
             .is_null());
}

WASM_COMPILED_EXEC_TEST(WasmGetLocalsAndStack) {
  WasmRunner<void, int> runner(execution_tier);
  runner.AllocateLocal(kWasmI64);
  runner.AllocateLocal(kWasmF32);
  runner.AllocateLocal(kWasmF64);

  BUILD(runner,
        // set [1] to 17
        WASM_SET_LOCAL(1, WASM_I64V_1(17)),
        // set [2] to <arg0> = 7
        WASM_SET_LOCAL(2, WASM_F32_SCONVERT_I32(WASM_GET_LOCAL(0))),
        // set [3] to <arg1>/2 = 8.5
        WASM_SET_LOCAL(3, WASM_F64_DIV(WASM_F64_SCONVERT_I64(WASM_GET_LOCAL(1)),
                                       WASM_F64(2))));

  Isolate* isolate = runner.main_isolate();
  Handle<JSFunction> main_fun_wrapper =
      runner.builder().WrapCode(runner.function_index());

  // Set breakpoint at the first instruction (7 bytes for local decls: num
  // entries + 3x<count, type>).
  SetBreakpoint(&runner, runner.function_index(), 7, 7);

  CollectValuesBreakHandler break_handler(
      isolate,
      {
          // params + locals          stack
          {wasmVec(7, 0L, 0.f, 0.), wasmVec()},          // 0: i64.const[17]
          {wasmVec(7, 0L, 0.f, 0.), wasmVec(17L)},       // 1: set_local[1]
          {wasmVec(7, 17L, 0.f, 0.), wasmVec()},         // 2: get_local[0]
          {wasmVec(7, 17L, 0.f, 0.), wasmVec(7)},        // 3: f32.convert_s
          {wasmVec(7, 17L, 0.f, 0.), wasmVec(7.f)},      // 4: set_local[2]
          {wasmVec(7, 17L, 7.f, 0.), wasmVec()},         // 5: get_local[1]
          {wasmVec(7, 17L, 7.f, 0.), wasmVec(17L)},      // 6: f64.convert_s
          {wasmVec(7, 17L, 7.f, 0.), wasmVec(17.)},      // 7: f64.const[2]
          {wasmVec(7, 17L, 7.f, 0.), wasmVec(17., 2.)},  // 8: f64.div
          {wasmVec(7, 17L, 7.f, 0.), wasmVec(8.5)},      // 9: set_local[3]
          {wasmVec(7, 17L, 7.f, 8.5), wasmVec()},        // 10: end
      });

  Handle<Object> global(isolate->context().global_object(), isolate);
  Handle<Object> args[]{handle(Smi::FromInt(7), isolate)};
  CHECK(!Execution::Call(isolate, main_fun_wrapper, global, 1, args).is_null());
}

WASM_COMPILED_EXEC_TEST(WasmRemoveBreakPoint) {
  WasmRunner<int> runner(execution_tier);
  Isolate* isolate = runner.main_isolate();

  BUILD(runner, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP,
        WASM_I32V_1(14));

  Handle<JSFunction> main_fun_wrapper =
      runner.builder().WrapCode(runner.function_index());

  SetBreakpoint(&runner, runner.function_index(), 1, 1);
  SetBreakpoint(&runner, runner.function_index(), 2, 2);
  Handle<BreakPoint> to_delete =
      SetBreakpoint(&runner, runner.function_index(), 3, 3);
  SetBreakpoint(&runner, runner.function_index(), 4, 4);

  BreakHandler count_breaks(isolate, {{1, BreakHandler::Continue},
                                      {2, BreakHandler::Continue,
                                       [&runner, &to_delete]() {
                                         ClearBreakpoint(
                                             &runner, runner.function_index(),
                                             3, to_delete);
                                       }},
                                      {4, BreakHandler::Continue}});

  Handle<Object> global(isolate->context().global_object(), isolate);
  MaybeHandle<Object> retval =
      Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr);
  CHECK_EQ(14, GetIntReturnValue(retval));
}

WASM_COMPILED_EXEC_TEST(WasmRemoveLastBreakPoint) {
  WasmRunner<int> runner(execution_tier);
  Isolate* isolate = runner.main_isolate();

  BUILD(runner, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP,
        WASM_I32V_1(14));

  Handle<JSFunction> main_fun_wrapper =
      runner.builder().WrapCode(runner.function_index());

  SetBreakpoint(&runner, runner.function_index(), 1, 1);
  SetBreakpoint(&runner, runner.function_index(), 2, 2);
  Handle<BreakPoint> to_delete =
      SetBreakpoint(&runner, runner.function_index(), 3, 3);

  BreakHandler count_breaks(
      isolate, {{1, BreakHandler::Continue},
                {2, BreakHandler::Continue, [&runner, &to_delete]() {
                   ClearBreakpoint(&runner, runner.function_index(), 3,
                                   to_delete);
                 }}});

  Handle<Object> global(isolate->context().global_object(), isolate);
  MaybeHandle<Object> retval =
      Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr);
  CHECK_EQ(14, GetIntReturnValue(retval));
}

WASM_COMPILED_EXEC_TEST(WasmRemoveAllBreakPoint) {
  WasmRunner<int> runner(execution_tier);
  Isolate* isolate = runner.main_isolate();

  BUILD(runner, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP, WASM_NOP,
        WASM_I32V_1(14));

  Handle<JSFunction> main_fun_wrapper =
      runner.builder().WrapCode(runner.function_index());

  Handle<BreakPoint> bp1 =
      SetBreakpoint(&runner, runner.function_index(), 1, 1);
  Handle<BreakPoint> bp2 =
      SetBreakpoint(&runner, runner.function_index(), 2, 2);
  Handle<BreakPoint> bp3 =
      SetBreakpoint(&runner, runner.function_index(), 3, 3);

  BreakHandler count_breaks(
      isolate, {{1, BreakHandler::Continue, [&runner, &bp1, &bp2, &bp3]() {
                   ClearBreakpoint(&runner, runner.function_index(), 1, bp1);
                   ClearBreakpoint(&runner, runner.function_index(), 3, bp3);
                   ClearBreakpoint(&runner, runner.function_index(), 2, bp2);
                 }}});

  Handle<Object> global(isolate->context().global_object(), isolate);
  MaybeHandle<Object> retval =
      Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr);
  CHECK_EQ(14, GetIntReturnValue(retval));
}

WASM_COMPILED_EXEC_TEST(WasmBreakInPostMVP) {
  // This test checks that we don't fail if experimental / post-MVP opcodes are
  // being used. There was a bug where we were trying to update the "detected"
  // features set, but we were passing a nullptr when compiling with
  // breakpoints.
  EXPERIMENTAL_FLAG_SCOPE(mv);
  WasmRunner<int> runner(execution_tier);
  Isolate* isolate = runner.main_isolate();

  // [] -> [i32, i32]
  ValueType sig_types[] = {kWasmI32, kWasmI32};
  FunctionSig sig{2, 0, sig_types};
  uint8_t sig_idx = runner.builder().AddSignature(&sig);

  constexpr int kReturn = 13;
  constexpr int kIgnored = 23;
  BUILD(runner,
        WASM_BLOCK_X(sig_idx, WASM_I32V_1(kReturn), WASM_I32V_1(kIgnored)),
        WASM_DROP);

  Handle<JSFunction> main_fun_wrapper =
      runner.builder().WrapCode(runner.function_index());

  SetBreakpoint(&runner, runner.function_index(), 3, 3);

  BreakHandler count_breaks(isolate, {{3, BreakHandler::Continue}});

  Handle<Object> global(isolate->context().global_object(), isolate);
  MaybeHandle<Object> retval =
      Execution::Call(isolate, main_fun_wrapper, global, 0, nullptr);
  CHECK_EQ(kReturn, GetIntReturnValue(retval));
}

WASM_COMPILED_EXEC_TEST(Regress10889) {
  FLAG_SCOPE(print_wasm_code);
  WasmRunner<int> runner(execution_tier);
  BUILD(runner, WASM_I32V_1(0));
  SetBreakpoint(&runner, runner.function_index(), 1, 1);
}

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