// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/globals.h"
#if defined(TARGET_OS_WINDOWS)

#include "vm/flags.h"
#include "vm/os.h"
#include "vm/thread_interrupter.h"

namespace dart {

DECLARE_FLAG(bool, thread_interrupter);
DECLARE_FLAG(bool, trace_thread_interrupter);

#define kThreadError -1

class ThreadInterrupterWin : public AllStatic {
 public:
  static bool GrabRegisters(HANDLE handle, InterruptedThreadState* state) {
    CONTEXT context;
    memset(&context, 0, sizeof(context));
#if defined(HOST_ARCH_IA32)
    // On IA32, CONTEXT_CONTROL includes Eip, Ebp, and Esp.
    context.ContextFlags = CONTEXT_CONTROL;
#elif defined(HOST_ARCH_X64)
    // On X64, CONTEXT_CONTROL includes Rip and Rsp. Rbp is classified
    // as an "integer" register.
    context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
#else
#error Unsupported architecture.
#endif
    if (GetThreadContext(handle, &context) != 0) {
#if defined(HOST_ARCH_IA32)
      state->pc = static_cast<uintptr_t>(context.Eip);
      state->fp = static_cast<uintptr_t>(context.Ebp);
      state->csp = static_cast<uintptr_t>(context.Esp);
      state->dsp = static_cast<uintptr_t>(context.Esp);
#elif defined(HOST_ARCH_X64)
      state->pc = static_cast<uintptr_t>(context.Rip);
      state->fp = static_cast<uintptr_t>(context.Rbp);
      state->csp = static_cast<uintptr_t>(context.Rsp);
      state->dsp = static_cast<uintptr_t>(context.Rsp);
#else
#error Unsupported architecture.
#endif
      return true;
    }
    return false;
  }


  static void Interrupt(Thread* thread) {
    ASSERT(!OSThread::Compare(GetCurrentThreadId(), thread->id()));
    HANDLE handle = OpenThread(THREAD_GET_CONTEXT |
                               THREAD_QUERY_INFORMATION |
                               THREAD_SUSPEND_RESUME,
                               false,
                               thread->id());
    ASSERT(handle != NULL);
    DWORD result = SuspendThread(handle);
    if (result == kThreadError) {
      if (FLAG_trace_thread_interrupter) {
        OS::Print("ThreadInterrupter failed to suspend thread %p\n",
                  reinterpret_cast<void*>(thread->id()));
      }
      CloseHandle(handle);
      return;
    }
    InterruptedThreadState its;
    its.tid = thread->id();
    if (!GrabRegisters(handle, &its)) {
      // Failed to get thread registers.
      ResumeThread(handle);
      if (FLAG_trace_thread_interrupter) {
        OS::Print("ThreadInterrupter failed to get registers for %p\n",
                  reinterpret_cast<void*>(thread->id()));
      }
      CloseHandle(handle);
      return;
    }
    ThreadInterruptCallback callback = NULL;
    void* callback_data = NULL;
    if (thread->IsThreadInterrupterEnabled(&callback, &callback_data)) {
      callback(its, callback_data);
    }
    ResumeThread(handle);
    CloseHandle(handle);
  }
};


void ThreadInterrupter::InterruptThread(Thread* thread) {
  if (FLAG_trace_thread_interrupter) {
    OS::Print("ThreadInterrupter suspending %p\n",
              reinterpret_cast<void*>(thread->id()));
  }
  ThreadInterrupterWin::Interrupt(thread);
  if (FLAG_trace_thread_interrupter) {
    OS::Print("ThreadInterrupter resuming %p\n",
              reinterpret_cast<void*>(thread->id()));
  }
}


void ThreadInterrupter::InstallSignalHandler() {
  // Nothing to do on Windows.
}


void ThreadInterrupter::RemoveSignalHandler() {
  // Nothing to do on Windows.
}


}  // namespace dart

#endif  // defined(TARGET_OS_WINDOWS)

