// 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 "src/base/win32-headers.h"
#include "src/init/v8.h"
#include "test/cctest/cctest.h"

#if defined(V8_OS_WIN_X64)
#define CONTEXT_PC(context) (context.Rip)
#elif defined(V8_OS_WIN_ARM64)
#define CONTEXT_PC(context) (context.Pc)
#endif

class UnwindingWin64Callbacks {
 public:
  UnwindingWin64Callbacks() = default;

  static void Getter(v8::Local<v8::String> name,
                     const v8::PropertyCallbackInfo<v8::Value>& info) {
    // Expects to find at least 15 stack frames in the call stack.
    // The stack walking should fail on stack frames for builtin functions if
    // stack unwinding data has not been correctly registered.
    int stack_frames = CountCallStackFrames(15);
    CHECK_GE(stack_frames, 15);
  }
  static void Setter(v8::Local<v8::String> name, v8::Local<v8::Value> value,
                     const v8::PropertyCallbackInfo<void>& info) {}

 private:
  // Windows-specific code to walk the stack starting from the current
  // instruction pointer.
  static int CountCallStackFrames(int max_frames) {
    CONTEXT context_record;
    ::RtlCaptureContext(&context_record);

    int iframe = 0;
    while (++iframe < max_frames) {
      uint64_t image_base;
      PRUNTIME_FUNCTION function_entry = ::RtlLookupFunctionEntry(
          CONTEXT_PC(context_record), &image_base, nullptr);
      if (!function_entry) break;

      void* handler_data;
      uint64_t establisher_frame;
      ::RtlVirtualUnwind(UNW_FLAG_NHANDLER, image_base,
                         CONTEXT_PC(context_record), function_entry,
                         &context_record, &handler_data, &establisher_frame,
                         NULL);
    }
    return iframe;
  }
};

// Verifies that stack unwinding data has been correctly registered on Win64.
UNINITIALIZED_TEST(StackUnwindingWin64) {
#ifdef V8_WIN64_UNWINDING_INFO

  static const char* unwinding_win64_test_source =
      "function start(count) {\n"
      "  for (var i = 0; i < count; i++) {\n"
      "    var o = instance.foo;\n"
      "    instance.foo = o + 1;\n"
      "  }\n"
      "};\n"
      "%PrepareFunctionForOptimization(start);\n";

  // This test may fail on Windows 7
  if (!::IsWindows8OrGreater()) {
    return;
  }

  i::FLAG_allow_natives_syntax = true;
  i::FLAG_win64_unwinding_info = true;

  v8::Isolate::CreateParams create_params;
  create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
  v8::Isolate* isolate = v8::Isolate::New(create_params);
  isolate->Enter();
  {
    v8::HandleScope scope(isolate);
    LocalContext env(isolate);

    v8::Local<v8::FunctionTemplate> func_template =
        v8::FunctionTemplate::New(isolate);
    v8::Local<v8::ObjectTemplate> instance_template =
        func_template->InstanceTemplate();

    UnwindingWin64Callbacks accessors;
    v8::Local<v8::External> data = v8::External::New(isolate, &accessors);
    instance_template->SetAccessor(v8_str("foo"),
                                   &UnwindingWin64Callbacks::Getter,
                                   &UnwindingWin64Callbacks::Setter, data);
    v8::Local<v8::Function> func =
        func_template->GetFunction(env.local()).ToLocalChecked();
    v8::Local<v8::Object> instance =
        func->NewInstance(env.local()).ToLocalChecked();
    env->Global()->Set(env.local(), v8_str("instance"), instance).FromJust();

    CompileRun(unwinding_win64_test_source);
    v8::Local<v8::Function> function = v8::Local<v8::Function>::Cast(
        env->Global()->Get(env.local(), v8_str("start")).ToLocalChecked());

    CompileRun("start(1); %OptimizeFunctionOnNextCall(start);");

    int32_t repeat_count = 100;
    v8::Local<v8::Value> args[] = {v8::Integer::New(isolate, repeat_count)};
    function->Call(env.local(), env.local()->Global(), arraysize(args), args)
        .ToLocalChecked();
  }
  isolate->Exit();
  isolate->Dispose();

#endif  // V8_WIN64_UNWINDING_INFO
}

#undef CONTEXT_PC
