// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef V8_TOP_H_
#define V8_TOP_H_

#include "atomicops.h"
#include "compilation-cache.h"
#include "frames-inl.h"
#include "runtime-profiler.h"

namespace v8 {
namespace internal {

class Simulator;

#define RETURN_IF_SCHEDULED_EXCEPTION() \
  if (Top::has_scheduled_exception()) return Top::PromoteScheduledException()

#define RETURN_IF_EMPTY_HANDLE_VALUE(call, value) \
  if (call.is_null()) {                           \
    ASSERT(Top::has_pending_exception());         \
    return value;                                 \
  }

#define RETURN_IF_EMPTY_HANDLE(call)      \
  RETURN_IF_EMPTY_HANDLE_VALUE(call, Failure::Exception())

// Top has static variables used for JavaScript execution.

class SaveContext;  // Forward declaration.
class ThreadVisitor;  // Defined in v8threads.h
class VMState;  // Defined in vm-state.h

class ThreadLocalTop BASE_EMBEDDED {
 public:
  // Initialize the thread data.
  void Initialize();

  // Get the top C++ try catch handler or NULL if none are registered.
  //
  // This method is not guarenteed to return an address that can be
  // used for comparison with addresses into the JS stack.  If such an
  // address is needed, use try_catch_handler_address.
  v8::TryCatch* TryCatchHandler();

  // Get the address of the top C++ try catch handler or NULL if
  // none are registered.
  //
  // This method always returns an address that can be compared to
  // pointers into the JavaScript stack.  When running on actual
  // hardware, try_catch_handler_address and TryCatchHandler return
  // the same pointer.  When running on a simulator with a separate JS
  // stack, try_catch_handler_address returns a JS stack address that
  // corresponds to the place on the JS stack where the C++ handler
  // would have been if the stack were not separate.
  inline Address try_catch_handler_address() {
    return try_catch_handler_address_;
  }

  // Set the address of the top C++ try catch handler.
  inline void set_try_catch_handler_address(Address address) {
    try_catch_handler_address_ = address;
  }

  void Free() {
    ASSERT(!has_pending_message_);
    ASSERT(!external_caught_exception_);
    ASSERT(try_catch_handler_address_ == NULL);
  }

  // The context where the current execution method is created and for variable
  // lookups.
  Context* context_;
  int thread_id_;
  MaybeObject* pending_exception_;
  bool has_pending_message_;
  const char* pending_message_;
  Object* pending_message_obj_;
  Script* pending_message_script_;
  int pending_message_start_pos_;
  int pending_message_end_pos_;
  // Use a separate value for scheduled exceptions to preserve the
  // invariants that hold about pending_exception.  We may want to
  // unify them later.
  MaybeObject* scheduled_exception_;
  bool external_caught_exception_;
  SaveContext* save_context_;
  v8::TryCatch* catcher_;

  // Stack.
  Address c_entry_fp_;  // the frame pointer of the top c entry frame
  Address handler_;   // try-blocks are chained through the stack

#ifdef USE_SIMULATOR
#ifdef V8_TARGET_ARCH_ARM
  Simulator* simulator_;
#elif V8_TARGET_ARCH_MIPS
  assembler::mips::Simulator* simulator_;
#endif
#endif  // USE_SIMULATOR

#ifdef ENABLE_LOGGING_AND_PROFILING
  Address js_entry_sp_;  // the stack pointer of the bottom js entry frame
  Address external_callback_;  // the external callback we're currently in
#endif

#ifdef ENABLE_VMSTATE_TRACKING
  StateTag current_vm_state_;

  // Used for communication with the runtime profiler thread.
  // Possible values are specified in RuntimeProfilerState.
  Atomic32 runtime_profiler_state_;
#endif

  // Generated code scratch locations.
  int32_t formal_count_;

  // Call back function to report unsafe JS accesses.
  v8::FailedAccessCheckCallback failed_access_check_callback_;

 private:
  Address try_catch_handler_address_;
};

#define TOP_ADDRESS_LIST(C)            \
  C(handler_address)                   \
  C(c_entry_fp_address)                \
  C(context_address)                   \
  C(pending_exception_address)         \
  C(external_caught_exception_address)

#ifdef ENABLE_LOGGING_AND_PROFILING
#define TOP_ADDRESS_LIST_PROF(C)       \
  C(js_entry_sp_address)
#else
#define TOP_ADDRESS_LIST_PROF(C)
#endif


class Top {
 public:
  enum AddressId {
#define C(name) k_##name,
    TOP_ADDRESS_LIST(C)
    TOP_ADDRESS_LIST_PROF(C)
#undef C
    k_top_address_count
  };

  static Address get_address_from_id(AddressId id);

  // Access to top context (where the current function object was created).
  static Context* context() { return thread_local_.context_; }
  static void set_context(Context* context) {
    thread_local_.context_ = context;
  }
  static Context** context_address() { return &thread_local_.context_; }

  static SaveContext* save_context() {return thread_local_.save_context_; }
  static void set_save_context(SaveContext* save) {
    thread_local_.save_context_ = save;
  }

  // Access to current thread id.
  static int thread_id() { return thread_local_.thread_id_; }
  static void set_thread_id(int id) { thread_local_.thread_id_ = id; }

  // Interface to pending exception.
  static MaybeObject* pending_exception() {
    ASSERT(has_pending_exception());
    return thread_local_.pending_exception_;
  }
  static bool external_caught_exception() {
    return thread_local_.external_caught_exception_;
  }
  static void set_pending_exception(MaybeObject* exception) {
    thread_local_.pending_exception_ = exception;
  }
  static void clear_pending_exception() {
    thread_local_.pending_exception_ = Heap::the_hole_value();
  }

  static MaybeObject** pending_exception_address() {
    return &thread_local_.pending_exception_;
  }
  static bool has_pending_exception() {
    return !thread_local_.pending_exception_->IsTheHole();
  }
  static void clear_pending_message() {
    thread_local_.has_pending_message_ = false;
    thread_local_.pending_message_ = NULL;
    thread_local_.pending_message_obj_ = Heap::the_hole_value();
    thread_local_.pending_message_script_ = NULL;
  }
  static v8::TryCatch* try_catch_handler() {
    return thread_local_.TryCatchHandler();
  }
  static Address try_catch_handler_address() {
    return thread_local_.try_catch_handler_address();
  }
  // This method is called by the api after operations that may throw
  // exceptions.  If an exception was thrown and not handled by an external
  // handler the exception is scheduled to be rethrown when we return to running
  // JavaScript code.  If an exception is scheduled true is returned.
  static bool OptionalRescheduleException(bool is_bottom_call);


  static bool* external_caught_exception_address() {
    return &thread_local_.external_caught_exception_;
  }

  static MaybeObject** scheduled_exception_address() {
    return &thread_local_.scheduled_exception_;
  }

  static MaybeObject* scheduled_exception() {
    ASSERT(has_scheduled_exception());
    return thread_local_.scheduled_exception_;
  }
  static bool has_scheduled_exception() {
    return !thread_local_.scheduled_exception_->IsTheHole();
  }
  static void clear_scheduled_exception() {
    thread_local_.scheduled_exception_ = Heap::the_hole_value();
  }

  static bool IsExternallyCaught();

  static void SetCaptureStackTraceForUncaughtExceptions(
      bool capture,
      int frame_limit,
      StackTrace::StackTraceOptions options);

  // Tells whether the current context has experienced an out of memory
  // exception.
  static bool is_out_of_memory();

  static bool is_catchable_by_javascript(MaybeObject* exception) {
    return (exception != Failure::OutOfMemoryException()) &&
        (exception != Heap::termination_exception());
  }

  // JS execution stack (see frames.h).
  static Address c_entry_fp(ThreadLocalTop* thread) {
    return thread->c_entry_fp_;
  }
  static Address handler(ThreadLocalTop* thread) { return thread->handler_; }

  static inline Address* c_entry_fp_address() {
    return &thread_local_.c_entry_fp_;
  }
  static inline Address* handler_address() { return &thread_local_.handler_; }

#ifdef ENABLE_LOGGING_AND_PROFILING
  // Bottom JS entry (see StackTracer::Trace in log.cc).
  static Address js_entry_sp(ThreadLocalTop* thread) {
    return thread->js_entry_sp_;
  }
  static inline Address* js_entry_sp_address() {
    return &thread_local_.js_entry_sp_;
  }

  static Address external_callback() {
    return thread_local_.external_callback_;
  }
  static void set_external_callback(Address callback) {
    thread_local_.external_callback_ = callback;
  }
#endif

#ifdef ENABLE_VMSTATE_TRACKING
  static StateTag current_vm_state() {
    return thread_local_.current_vm_state_;
  }

  static void SetCurrentVMState(StateTag state) {
    if (RuntimeProfiler::IsEnabled()) {
      if (state == JS) {
        // JS or non-JS -> JS transition.
        RuntimeProfilerState old_state = SwapRuntimeProfilerState(PROF_IN_JS);
        if (old_state == PROF_NOT_IN_JS_WAITING_FOR_JS) {
          // If the runtime profiler was waiting, we reset the eager
          // optimizing data in the compilation cache to get a fresh
          // start after not running JavaScript code for a while and
          // signal the runtime profiler so it can resume.
          CompilationCache::ResetEagerOptimizingData();
          runtime_profiler_semaphore_->Signal();
        }
      } else if (thread_local_.current_vm_state_ == JS) {
        // JS -> non-JS transition. Update the runtime profiler state.
        ASSERT(IsInJSState());
        SetRuntimeProfilerState(PROF_NOT_IN_JS);
      }
    }
    thread_local_.current_vm_state_ = state;
  }

  // Called in the runtime profiler thread.
  // Returns whether the current VM state is set to JS.
  static bool IsInJSState() {
    ASSERT(RuntimeProfiler::IsEnabled());
    return static_cast<RuntimeProfilerState>(
        NoBarrier_Load(&thread_local_.runtime_profiler_state_)) == PROF_IN_JS;
  }

  // Called in the runtime profiler thread.
  // Waits for the VM state to transtion from non-JS to JS. Returns
  // true when notified of the transition, false when the current
  // state is not the expected non-JS state.
  static bool WaitForJSState() {
    ASSERT(RuntimeProfiler::IsEnabled());
    // Try to switch to waiting state.
    RuntimeProfilerState old_state = CompareAndSwapRuntimeProfilerState(
        PROF_NOT_IN_JS, PROF_NOT_IN_JS_WAITING_FOR_JS);
    if (old_state == PROF_NOT_IN_JS) {
      runtime_profiler_semaphore_->Wait();
      return true;
    }
    return false;
  }

  // When shutting down we join the profiler thread. Doing so while
  // it's waiting on a semaphore will cause a deadlock, so we have to
  // wake it up first.
  static void WakeUpRuntimeProfilerThreadBeforeShutdown() {
    runtime_profiler_semaphore_->Signal();
  }
#endif

  // Generated code scratch locations.
  static void* formal_count_address() { return &thread_local_.formal_count_; }

  static void PrintCurrentStackTrace(FILE* out);
  static void PrintStackTrace(FILE* out, char* thread_data);
  static void PrintStack(StringStream* accumulator);
  static void PrintStack();
  static Handle<String> StackTraceString();
  static Handle<JSArray> CaptureCurrentStackTrace(
      int frame_limit,
      StackTrace::StackTraceOptions options);

  // Returns if the top context may access the given global object. If
  // the result is false, the pending exception is guaranteed to be
  // set.
  static bool MayNamedAccess(JSObject* receiver,
                             Object* key,
                             v8::AccessType type);
  static bool MayIndexedAccess(JSObject* receiver,
                               uint32_t index,
                               v8::AccessType type);

  static void SetFailedAccessCheckCallback(
      v8::FailedAccessCheckCallback callback);
  static void ReportFailedAccessCheck(JSObject* receiver, v8::AccessType type);

  // Exception throwing support. The caller should use the result
  // of Throw() as its return value.
  static Failure* Throw(Object* exception, MessageLocation* location = NULL);
  // Re-throw an exception.  This involves no error reporting since
  // error reporting was handled when the exception was thrown
  // originally.
  static Failure* ReThrow(MaybeObject* exception,
                          MessageLocation* location = NULL);
  static void ScheduleThrow(Object* exception);
  static void ReportPendingMessages();
  static Failure* ThrowIllegalOperation();

  // Promote a scheduled exception to pending. Asserts has_scheduled_exception.
  static Failure* PromoteScheduledException();
  static void DoThrow(MaybeObject* exception,
                      MessageLocation* location,
                      const char* message);
  // Checks if exception should be reported and finds out if it's
  // caught externally.
  static bool ShouldReportException(bool* can_be_caught_externally,
                                    bool catchable_by_javascript);

  // Attempts to compute the current source location, storing the
  // result in the target out parameter.
  static void ComputeLocation(MessageLocation* target);

  // Override command line flag.
  static void TraceException(bool flag);

  // Out of resource exception helpers.
  static Failure* StackOverflow();
  static Failure* TerminateExecution();

  // Administration
  static void Initialize();
  static void TearDown();
  static void Iterate(ObjectVisitor* v);
  static void Iterate(ObjectVisitor* v, ThreadLocalTop* t);
  static char* Iterate(ObjectVisitor* v, char* t);
  static void IterateThread(ThreadVisitor* v);
  static void IterateThread(ThreadVisitor* v, char* t);

  // Returns the global object of the current context. It could be
  // a builtin object, or a js global object.
  static Handle<GlobalObject> global() {
    return Handle<GlobalObject>(context()->global());
  }

  // Returns the global proxy object of the current context.
  static Object* global_proxy() {
    return context()->global_proxy();
  }

  // Returns the current global context.
  static Handle<Context> global_context();

  // Returns the global context of the calling JavaScript code.  That
  // is, the global context of the top-most JavaScript frame.
  static Handle<Context> GetCallingGlobalContext();

  static Handle<JSBuiltinsObject> builtins() {
    return Handle<JSBuiltinsObject>(thread_local_.context_->builtins());
  }

  static void RegisterTryCatchHandler(v8::TryCatch* that);
  static void UnregisterTryCatchHandler(v8::TryCatch* that);

#define TOP_GLOBAL_CONTEXT_FIELD_ACCESSOR(index, type, name)  \
  static Handle<type> name() {                                \
    return Handle<type>(context()->global_context()->name()); \
  }
  GLOBAL_CONTEXT_FIELDS(TOP_GLOBAL_CONTEXT_FIELD_ACCESSOR)
#undef TOP_GLOBAL_CONTEXT_FIELD_ACCESSOR

  static inline ThreadLocalTop* GetCurrentThread() { return &thread_local_; }
  static int ArchiveSpacePerThread() { return sizeof(ThreadLocalTop); }
  static char* ArchiveThread(char* to);
  static char* RestoreThread(char* from);
  static void FreeThreadResources() { thread_local_.Free(); }

  static const char* kStackOverflowMessage;

 private:
#ifdef ENABLE_VMSTATE_TRACKING
  // Set of states used when communicating with the runtime profiler.
  //
  // The set of possible transitions is divided between the VM and the
  // profiler threads.
  //
  // The VM thread can perform these transitions:
  //   o IN_JS -> NOT_IN_JS
  //   o NOT_IN_JS -> IN_JS
  //   o NOT_IN_JS_WAITING_FOR_JS -> IN_JS notifying the profiler thread
  //     using the semaphore.
  // All the above transitions are caused by VM state changes.
  //
  // The profiler thread can only perform a single transition
  // NOT_IN_JS -> NOT_IN_JS_WAITING_FOR_JS before it starts waiting on
  // the semaphore.
  enum RuntimeProfilerState {
    PROF_NOT_IN_JS,
    PROF_NOT_IN_JS_WAITING_FOR_JS,
    PROF_IN_JS
  };

  static void SetRuntimeProfilerState(RuntimeProfilerState state) {
    NoBarrier_Store(&thread_local_.runtime_profiler_state_, state);
  }

  static RuntimeProfilerState SwapRuntimeProfilerState(
      RuntimeProfilerState state) {
    return static_cast<RuntimeProfilerState>(
        NoBarrier_AtomicExchange(&thread_local_.runtime_profiler_state_,
                                 state));
  }

  static RuntimeProfilerState CompareAndSwapRuntimeProfilerState(
      RuntimeProfilerState old_state,
      RuntimeProfilerState state) {
    return static_cast<RuntimeProfilerState>(
        NoBarrier_CompareAndSwap(&thread_local_.runtime_profiler_state_,
                                 old_state,
                                 state));
  }

  static Semaphore* runtime_profiler_semaphore_;
#endif  // ENABLE_VMSTATE_TRACKING

  // The context that initiated this JS execution.
  static ThreadLocalTop thread_local_;
  static void InitializeThreadLocal();
  static void PrintStackTrace(FILE* out, ThreadLocalTop* thread);
  static void MarkCompactPrologue(bool is_compacting,
                                  ThreadLocalTop* archived_thread_data);
  static void MarkCompactEpilogue(bool is_compacting,
                                  ThreadLocalTop* archived_thread_data);

  // Debug.
  // Mutex for serializing access to break control structures.
  static Mutex* break_access_;

  friend class SaveContext;
  friend class AssertNoContextChange;
  friend class ExecutionAccess;
  friend class ThreadLocalTop;

  static void FillCache();
};


// If the GCC version is 4.1.x or 4.2.x an additional field is added to the
// class as a work around for a bug in the generated code found with these
// versions of GCC. See V8 issue 122 for details.
class SaveContext BASE_EMBEDDED {
 public:
  SaveContext()
      : context_(Top::context()),
#if __GNUC_VERSION__ >= 40100 && __GNUC_VERSION__ < 40300
        dummy_(Top::context()),
#endif
        prev_(Top::save_context()) {
    Top::set_save_context(this);

    // If there is no JS frame under the current C frame, use the value 0.
    JavaScriptFrameIterator it;
    js_sp_ = it.done() ? 0 : it.frame()->sp();
  }

  ~SaveContext() {
    Top::set_context(*context_);
    Top::set_save_context(prev_);
  }

  Handle<Context> context() { return context_; }
  SaveContext* prev() { return prev_; }

  // Returns true if this save context is below a given JavaScript frame.
  bool below(JavaScriptFrame* frame) {
    return (js_sp_ == 0) || (frame->sp() < js_sp_);
  }

 private:
  Handle<Context> context_;
#if __GNUC_VERSION__ >= 40100 && __GNUC_VERSION__ < 40300
  Handle<Context> dummy_;
#endif
  SaveContext* prev_;
  Address js_sp_;  // The top JS frame's sp when saving context.
};


class AssertNoContextChange BASE_EMBEDDED {
#ifdef DEBUG
 public:
  AssertNoContextChange() :
      context_(Top::context()) {
  }

  ~AssertNoContextChange() {
    ASSERT(Top::context() == *context_);
  }

 private:
  HandleScope scope_;
  Handle<Context> context_;
#else
 public:
  AssertNoContextChange() { }
#endif
};


class ExecutionAccess BASE_EMBEDDED {
 public:
  ExecutionAccess() { Lock(); }
  ~ExecutionAccess() { Unlock(); }

  static void Lock() { Top::break_access_->Lock(); }
  static void Unlock() { Top::break_access_->Unlock(); }

  static bool TryLock() {
    return Top::break_access_->TryLock();
  }
};

} }  // namespace v8::internal

#endif  // V8_TOP_H_
