// Copyright (c) 2012, 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.

#ifndef RUNTIME_VM_DEBUGGER_H_
#define RUNTIME_VM_DEBUGGER_H_

#include <memory>

#include "include/dart_tools_api.h"

#include "vm/kernel_isolate.h"
#include "vm/object.h"
#include "vm/port.h"
#include "vm/scopes.h"
#include "vm/service_event.h"
#include "vm/simulator.h"
#include "vm/stack_frame.h"
#include "vm/stack_trace.h"

#if !defined(PRODUCT)

DECLARE_FLAG(bool, verbose_debug);

// 'Trace Debugger' TD_Print.
#if defined(_MSC_VER)
#define TD_Print(format, ...)                                                  \
  if (FLAG_verbose_debug) Log::Current()->Print(format, __VA_ARGS__)
#else
#define TD_Print(format, ...)                                                  \
  if (FLAG_verbose_debug) Log::Current()->Print(format, ##__VA_ARGS__)
#endif

namespace dart {

class CodeBreakpoint;
class Isolate;
class JSONArray;
class JSONStream;
class ObjectPointerVisitor;
class BreakpointLocation;
class StackFrame;

// A user-defined breakpoint, which either fires once, for a particular closure,
// or always. The API's notion of a breakpoint corresponds to this object.
class Breakpoint {
 public:
  Breakpoint(intptr_t id, BreakpointLocation* bpt_location)
      : id_(id),
        kind_(Breakpoint::kNone),
        next_(NULL),
        closure_(Instance::null()),
        bpt_location_(bpt_location),
        is_synthetic_async_(false) {}

  intptr_t id() const { return id_; }
  Breakpoint* next() const { return next_; }
  void set_next(Breakpoint* n) { next_ = n; }

  BreakpointLocation* bpt_location() const { return bpt_location_; }
  void set_bpt_location(BreakpointLocation* new_bpt_location);

  bool IsRepeated() const { return kind_ == kRepeated; }
  bool IsSingleShot() const { return kind_ == kSingleShot; }
  bool IsPerClosure() const { return kind_ == kPerClosure; }
  InstancePtr closure() const { return closure_; }

  void SetIsRepeated() {
    ASSERT(kind_ == kNone);
    kind_ = kRepeated;
  }

  void SetIsSingleShot() {
    ASSERT(kind_ == kNone);
    kind_ = kSingleShot;
  }

  void SetIsPerClosure(const Instance& closure) {
    ASSERT(kind_ == kNone);
    kind_ = kPerClosure;
    closure_ = closure.ptr();
  }

  void Enable() {
    ASSERT(!enabled_);
    enabled_ = true;
  }

  void Disable() {
    ASSERT(enabled_);
    enabled_ = false;
  }

  bool is_enabled() const { return enabled_; }

  // Mark that this breakpoint is a result of a step OverAwait request.
  void set_is_synthetic_async(bool is_synthetic_async) {
    is_synthetic_async_ = is_synthetic_async;
  }
  bool is_synthetic_async() const { return is_synthetic_async_; }

  void PrintJSON(JSONStream* stream);

 private:
  void VisitObjectPointers(ObjectPointerVisitor* visitor);

  enum ConditionKind {
    kNone,
    kRepeated,
    kSingleShot,
    kPerClosure,
  };

  intptr_t id_;
  ConditionKind kind_;
  Breakpoint* next_;
  InstancePtr closure_;
  BreakpointLocation* bpt_location_;
  bool is_synthetic_async_;
  bool enabled_ = false;

  friend class BreakpointLocation;
  DISALLOW_COPY_AND_ASSIGN(Breakpoint);
};

// BreakpointLocation represents a collection of breakpoint conditions at the
// same token position in Dart source. There may be more than one CodeBreakpoint
// object per BreakpointLocation.
// An unresolved breakpoint is one where the underlying code has not
// been compiled yet. Since the code has not been compiled, we don't know
// the definitive source location yet. The requested source location may
// change when the underlying code gets compiled.
// A latent breakpoint represents a breakpoint location in Dart source
// that is not loaded in the VM when the breakpoint is requested.
// When a script with matching url is loaded, a latent breakpoint
// becomes an unresolved breakpoint.
class BreakpointLocation {
 public:
  // Create a new unresolved breakpoint.
  BreakpointLocation(Debugger* debugger,
                     const GrowableHandlePtrArray<const Script>& scripts,
                     TokenPosition token_pos,
                     TokenPosition end_token_pos,
                     intptr_t requested_line_number,
                     intptr_t requested_column_number);
  // Create a new latent breakpoint.
  BreakpointLocation(Debugger* debugger,
                     const String& url,
                     intptr_t requested_line_number,
                     intptr_t requested_column_number);

  ~BreakpointLocation();

  TokenPosition token_pos() const { return token_pos_.load(); }
  intptr_t line_number();
  TokenPosition end_token_pos() const { return end_token_pos_.load(); }

  ScriptPtr script() const {
    if (scripts_.length() == 0) {
      return Script::null();
    }
    return scripts_.At(0);
  }
  StringPtr url() const { return url_; }

  intptr_t requested_line_number() const { return requested_line_number_; }
  intptr_t requested_column_number() const { return requested_column_number_; }

  void GetCodeLocation(Script* script, TokenPosition* token_pos) const;

  Breakpoint* AddRepeated(Debugger* dbg);
  Breakpoint* AddSingleShot(Debugger* dbg);
  Breakpoint* AddPerClosure(Debugger* dbg,
                            const Instance& closure,
                            bool for_over_await);

  bool AnyEnabled() const;
  bool IsResolved() const { return code_token_pos_.IsReal(); }
  bool IsLatent() const { return !token_pos().IsReal(); }

  bool EnsureIsResolved(const Function& target_function,
                        TokenPosition exact_token_pos);

  Debugger* debugger() { return debugger_; }

 private:
  void VisitObjectPointers(ObjectPointerVisitor* visitor);

  void SetResolved(const Function& func, TokenPosition token_pos);

  BreakpointLocation* next() const { return this->next_; }
  void set_next(BreakpointLocation* value) { next_ = value; }

  void AddBreakpoint(Breakpoint* bpt, Debugger* dbg);

  Breakpoint* breakpoints() const { return this->conditions_; }
  void set_breakpoints(Breakpoint* head) { this->conditions_ = head; }

  // Finds the breakpoint we hit at |location|.
  Breakpoint* FindHitBreakpoint(ActivationFrame* top_frame);

  SafepointRwLock* line_number_lock() { return line_number_lock_.get(); }

  Debugger* debugger_;
  MallocGrowableArray<ScriptPtr> scripts_;
  StringPtr url_;
  std::unique_ptr<SafepointRwLock> line_number_lock_;
  intptr_t line_number_;  // lazily computed for token_pos_
  std::atomic<TokenPosition> token_pos_;
  std::atomic<TokenPosition> end_token_pos_;
  BreakpointLocation* next_;
  Breakpoint* conditions_;
  intptr_t requested_line_number_;
  intptr_t requested_column_number_;

  // Valid for resolved breakpoints:
  TokenPosition code_token_pos_;

  friend class Debugger;
  friend class GroupDebugger;
  DISALLOW_COPY_AND_ASSIGN(BreakpointLocation);
};

// CodeBreakpoint represents a location in compiled code.
// There may be more than one CodeBreakpoint for one BreakpointLocation,
// e.g. when a function gets compiled as a regular function and as a closure.
// There may be more than one BreakpointLocation associated with CodeBreakpoint,
// one for for every isolate in a group that sets a breakpoint at particular
// code location represented by the CodeBreakpoint.
// Each BreakpointLocation might be enabled/disabled based on whether it has
// any actual breakpoints associated with it.
// The CodeBreakpoint is enabled if it has any such BreakpointLocations
// associated with it.
// The class is not thread-safe - users of this class need to ensure the access
// is synchronized, guarded by mutexes or run inside of a safepoint scope.
class CodeBreakpoint {
 public:
  // Unless CodeBreakpoint is unlinked and is no longer used there should be at
  // least one BreakpointLocation associated with CodeBreakpoint. If there are
  // more BreakpointLocation added assumption is is that all of them point to
  // the same source so have the same token pos.
  CodeBreakpoint(const Code& code,
                 BreakpointLocation* loc,
                 uword pc,
                 UntaggedPcDescriptors::Kind kind);
  ~CodeBreakpoint();

  // Used by GroupDebugger to find CodeBreakpoint associated with
  // particular function.
  FunctionPtr function() const { return Code::Handle(code_).function(); }

  uword pc() const { return pc_; }
  bool HasBreakpointLocation(BreakpointLocation* breakpoint_location);
  bool FindAndDeleteBreakpointLocation(BreakpointLocation* breakpoint_location);
  bool HasNoBreakpointLocations() {
    return breakpoint_locations_.length() == 0;
  }

  void Enable();
  void Disable();
  bool IsEnabled() const { return enabled_count_ > 0; }

  CodePtr OrigStubAddress() const;

  const char* ToCString() const;

 private:
  void VisitObjectPointers(ObjectPointerVisitor* visitor);

  // Finds right BreakpointLocation for a given Isolate's debugger.
  BreakpointLocation* FindBreakpointForDebugger(Debugger* debugger);
  // Adds new BreakpointLocation for another isolate that wants to
  // break at the same function/code location that this CodeBreakpoint
  // represents.
  void AddBreakpointLocation(BreakpointLocation* breakpoint_location) {
    ASSERT(breakpoint_locations_.length() == 0 ||
           (breakpoint_location->token_pos() ==
                breakpoint_locations_.At(0)->token_pos() &&
            breakpoint_location->url() == breakpoint_locations_.At(0)->url()));
    breakpoint_locations_.Add(breakpoint_location);
  }

  void set_next(CodeBreakpoint* value) { next_ = value; }
  CodeBreakpoint* next() const { return this->next_; }

  void PatchCode();
  void RestoreCode();

  CodePtr code_;
  uword pc_;
  int enabled_count_;  // incremented for every enabled breakpoint location

  // Breakpoint locations from different debuggers/isolates that
  // point to this code breakpoint.
  MallocGrowableArray<BreakpointLocation*> breakpoint_locations_;
  CodeBreakpoint* next_;

  UntaggedPcDescriptors::Kind breakpoint_kind_;
  CodePtr saved_value_;

  friend class Debugger;
  friend class GroupDebugger;
  DISALLOW_COPY_AND_ASSIGN(CodeBreakpoint);
};

// ActivationFrame represents one dart function activation frame
// on the call stack.
class ActivationFrame : public ZoneAllocated {
 public:
  enum Kind {
    kRegular,
    kAsyncSuspensionMarker,
    kAsyncCausal,
    kAsyncActivation,
  };

  ActivationFrame(uword pc,
                  uword fp,
                  uword sp,
                  const Code& code,
                  const Array& deopt_frame,
                  intptr_t deopt_frame_offset,
                  Kind kind = kRegular);

  ActivationFrame(uword pc, const Code& code);

  explicit ActivationFrame(Kind kind);

  explicit ActivationFrame(const Closure& async_activation);

  uword pc() const { return pc_; }
  uword fp() const { return fp_; }
  uword sp() const { return sp_; }

  uword GetCallerSp() const { return fp() + (kCallerSpSlotFromFp * kWordSize); }

  const Function& function() const {
    return function_;
  }
  const Code& code() const {
    ASSERT(!code_.IsNull());
    return code_;
  }

  enum Relation {
    kCallee,
    kSelf,
    kCaller,
  };

  Relation CompareTo(uword other_fp) const;

  StringPtr QualifiedFunctionName();
  StringPtr SourceUrl();
  ScriptPtr SourceScript();
  LibraryPtr Library();
  TokenPosition TokenPos();
  intptr_t LineNumber();
  intptr_t ColumnNumber();

  // Returns true if this frame is for a function that is visible
  // to the user and can be debugged.
  bool IsDebuggable() const;

  // Returns true if it is possible to rewind the debugger to this frame.
  bool IsRewindable() const;

  // The context level of a frame is the context level at the
  // PC/token index of the frame. It determines the depth of the context
  // chain that belongs to the function of this activation frame.
  intptr_t ContextLevel();

  const char* ToCString();

  intptr_t NumLocalVariables();

  void VariableAt(intptr_t i,
                  String* name,
                  TokenPosition* declaration_token_pos,
                  TokenPosition* visible_start_token_pos,
                  TokenPosition* visible_end_token_pos,
                  Object* value);

  ArrayPtr GetLocalVariables();
  ObjectPtr GetParameter(intptr_t index);
  ClosurePtr GetClosure();
  ObjectPtr GetReceiver();

  const Context& GetSavedCurrentContext();
  ObjectPtr GetAsyncOperation();

  TypeArgumentsPtr BuildParameters(
      const GrowableObjectArray& param_names,
      const GrowableObjectArray& param_values,
      const GrowableObjectArray& type_params_names);

  ObjectPtr EvaluateCompiledExpression(const ExternalTypedData& kernel_data,
                                       const Array& arguments,
                                       const Array& type_definitions,
                                       const TypeArguments& type_arguments);

  void PrintToJSONObject(JSONObject* jsobj);

  // Get Closure that await'ed this async frame.
  ObjectPtr GetAsyncAwaiter(CallerClosureFinder* caller_closure_finder);

  bool HandlesException(const Instance& exc_obj);

 private:
  void PrintToJSONObjectRegular(JSONObject* jsobj);
  void PrintToJSONObjectAsyncCausal(JSONObject* jsobj);
  void PrintToJSONObjectAsyncSuspensionMarker(JSONObject* jsobj);
  void PrintContextMismatchError(intptr_t ctx_slot,
                                 intptr_t frame_ctx_level,
                                 intptr_t var_ctx_level);
  void PrintDescriptorsError(const char* message);

  intptr_t TryIndex();
  intptr_t DeoptId();
  void GetPcDescriptors();
  void GetVarDescriptors();
  void GetDescIndices();

  ObjectPtr GetAsyncContextVariable(const String& name);

  // Get the current continuation index in the :await_jump_var pulled from the
  // context.
  intptr_t GetAwaitJumpVariable();

  void ExtractTokenPositionFromAsyncClosure();

  bool IsAsyncMachinery() const;

  static const char* KindToCString(Kind kind) {
    switch (kind) {
      case kRegular:
        return "Regular";
      case kAsyncCausal:
        return "AsyncCausal";
      case kAsyncSuspensionMarker:
        return "AsyncSuspensionMarker";
      case kAsyncActivation:
        return "AsyncActivation";
      default:
        UNREACHABLE();
        return "";
    }
  }

  ObjectPtr GetStackVar(VariableIndex var_index);
  ObjectPtr GetRelativeContextVar(intptr_t ctxt_level,
                                  intptr_t slot_index,
                                  intptr_t frame_ctx_level);
  ObjectPtr GetContextVar(intptr_t ctxt_level, intptr_t slot_index);

  uword pc_;
  uword fp_;
  uword sp_;

  // The anchor of the context chain for this function.
  Context& ctx_;
  Code& code_;
  Function& function_;
  bool live_frame_;  // Is this frame a live frame?
  bool token_pos_initialized_;
  TokenPosition token_pos_;
  intptr_t try_index_;
  intptr_t deopt_id_;

  intptr_t line_number_;
  intptr_t column_number_;
  intptr_t context_level_;

  // Some frames are deoptimized into a side array in order to inspect them.
  const Array& deopt_frame_;
  const intptr_t deopt_frame_offset_;

  Kind kind_;

  bool vars_initialized_;
  LocalVarDescriptors& var_descriptors_;
  ZoneGrowableArray<intptr_t> desc_indices_;
  PcDescriptors& pc_desc_;

  friend class Debugger;
  friend class DebuggerStackTrace;
  DISALLOW_COPY_AND_ASSIGN(ActivationFrame);
};

// Array of function activations on the call stack.
class DebuggerStackTrace : public ZoneAllocated {
 public:
  explicit DebuggerStackTrace(int capacity) : trace_(capacity) {}

  intptr_t Length() const { return trace_.length(); }

  ActivationFrame* FrameAt(int i) const { return trace_[i]; }

  ActivationFrame* GetHandlerFrame(const Instance& exc_obj) const;

  static DebuggerStackTrace* CollectAwaiterReturn();
  static DebuggerStackTrace* Collect();
  // Returns a debugger stack trace corresponding to a dart.core.StackTrace.
  // Frames corresponding to invisible functions are omitted. It is not valid
  // to query local variables in the returned stack.
  static DebuggerStackTrace* From(const class StackTrace& ex_trace);

 private:
  void AddActivation(ActivationFrame* frame);
  void AddMarker(ActivationFrame::Kind marker);
  void AddAsyncCausalFrame(uword pc, const Code& code);

  void AppendCodeFrames(Thread* thread,
                        Isolate* isolate,
                        Zone* zone,
                        StackFrame* frame,
                        Code* code,
                        Code* inlined_code,
                        Array* deopt_frame);

  static DebuggerStackTrace* CollectAsyncCausal();
  static DebuggerStackTrace* CollectAsyncLazy();

  ZoneGrowableArray<ActivationFrame*> trace_;

  friend class Debugger;

  DISALLOW_COPY_AND_ASSIGN(DebuggerStackTrace);
};

// On which exceptions to pause.
typedef enum {
  kNoPauseOnExceptions = 1,
  kPauseOnUnhandledExceptions,
  kPauseOnAllExceptions,
  kInvalidExceptionPauseInfo
} Dart_ExceptionPauseInfo;

class DebuggerKeyValueTrait : public AllStatic {
 public:
  typedef const Debugger* Key;
  typedef bool Value;

  struct Pair {
    Key key;
    Value value;
    Pair() : key(NULL), value(false) {}
    Pair(const Key key, const Value& value) : key(key), value(value) {}
    Pair(const Pair& other) : key(other.key), value(other.value) {}
    Pair& operator=(const Pair&) = default;
  };

  static Key KeyOf(Pair kv) { return kv.key; }
  static Value ValueOf(Pair kv) { return kv.value; }
  static uword Hash(Key key) {
    return Utils::WordHash(reinterpret_cast<intptr_t>(key));
  }
  static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; }
};

class DebuggerSet : public MallocDirectChainedHashMap<DebuggerKeyValueTrait> {
 public:
  typedef DebuggerKeyValueTrait::Key Key;
  typedef DebuggerKeyValueTrait::Value Value;
  typedef DebuggerKeyValueTrait::Pair Pair;

  virtual ~DebuggerSet() { Clear(); }

  void Insert(const Key& key) {
    Pair pair(key, /*value=*/true);
    MallocDirectChainedHashMap<DebuggerKeyValueTrait>::Insert(pair);
  }

  void Remove(const Key& key) {
    MallocDirectChainedHashMap<DebuggerKeyValueTrait>::Remove(key);
  }
};

class BoolCallable : public ValueObject {
 public:
  BoolCallable() {}
  virtual ~BoolCallable() {}

  virtual bool Call() = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(BoolCallable);
};

template <typename T>
class LambdaBoolCallable : public BoolCallable {
 public:
  explicit LambdaBoolCallable(T& lambda) : lambda_(lambda) {}
  bool Call() { return lambda_(); }

 private:
  T& lambda_;
  DISALLOW_COPY_AND_ASSIGN(LambdaBoolCallable);
};

class GroupDebugger {
 public:
  explicit GroupDebugger(IsolateGroup* isolate_group);
  ~GroupDebugger();

  void MakeCodeBreakpointAt(const Function& func, BreakpointLocation* bpt);

  // Returns [nullptr] if no breakpoint exists for the given address.
  CodeBreakpoint* GetCodeBreakpoint(uword breakpoint_address);
  BreakpointLocation* GetBreakpointLocationFor(Debugger* debugger,
                                               uword breakpoint_address,
                                               CodeBreakpoint** pcbpt);
  CodePtr GetPatchedStubAddress(uword breakpoint_address);

  void RegisterBreakpointLocation(BreakpointLocation* location);
  void UnregisterBreakpointLocation(BreakpointLocation* location);

  void RemoveBreakpointLocation(BreakpointLocation* bpt_location);
  void UnlinkCodeBreakpoints(BreakpointLocation* bpt_location);

  // Returns true if the call at address pc is patched to point to
  // a debugger stub.
  bool HasActiveBreakpoint(uword pc);
  bool HasCodeBreakpointInFunction(const Function& func);
  bool HasCodeBreakpointInCode(const Code& code);

  bool HasBreakpointInFunction(const Function& func);
  bool HasBreakpointInCode(const Code& code);

  void SyncBreakpointLocation(BreakpointLocation* loc);

  void Pause();

  bool EnsureLocationIsInFunction(Zone* zone,
                                  const Function& function,
                                  BreakpointLocation* location);
  void NotifyCompilation(const Function& func);

  void VisitObjectPointers(ObjectPointerVisitor* visitor);

  SafepointRwLock* code_breakpoints_lock() {
    return code_breakpoints_lock_.get();
  }

  SafepointRwLock* breakpoint_locations_lock() {
    return breakpoint_locations_lock_.get();
  }

  SafepointRwLock* single_stepping_set_lock() {
    return single_stepping_set_lock_.get();
  }
  void RegisterSingleSteppingDebugger(Thread* thread, const Debugger* debugger);
  void UnregisterSingleSteppingDebugger(Thread* thread,
                                        const Debugger* debugger);

  bool RunUnderReadLockIfNeededCallable(Thread* thread,
                                        SafepointRwLock* rw_lock,
                                        BoolCallable* callable);

  template <typename T>
  bool RunUnderReadLockIfNeeded(Thread* thread,
                                SafepointRwLock* rw_lock,
                                T function) {
    LambdaBoolCallable<T> callable(function);
    return RunUnderReadLockIfNeededCallable(thread, rw_lock, &callable);
  }

  // Returns [true] if there is at least one breakpoint set in function or code.
  // Checks for both user-defined and internal temporary breakpoints.
  bool HasBreakpoint(Thread* thread, const Function& function);
  bool IsDebugging(Thread* thread, const Function& function);

 private:
  IsolateGroup* isolate_group_;

  std::unique_ptr<SafepointRwLock> code_breakpoints_lock_;
  CodeBreakpoint* code_breakpoints_;

  // Secondary list of all breakpoint_locations_(primary is in Debugger class).
  // This list is kept in sync with all the lists in Isolate Debuggers and is
  // used to quickly scan BreakpointLocations when new Function is compiled.
  std::unique_ptr<SafepointRwLock> breakpoint_locations_lock_;
  MallocGrowableArray<BreakpointLocation*> breakpoint_locations_;

  std::unique_ptr<SafepointRwLock> single_stepping_set_lock_;
  DebuggerSet single_stepping_set_;

  void RemoveUnlinkedCodeBreakpoints();
  void RegisterCodeBreakpoint(CodeBreakpoint* bpt);

  bool needs_breakpoint_cleanup_;
};

class Debugger {
 public:
  enum ResumeAction {
    kContinue,
    kStepInto,
    kStepOver,
    kStepOut,
    kStepRewind,
    kStepOverAsyncSuspension,
  };

  explicit Debugger(Isolate* isolate);
  ~Debugger();

  void NotifyIsolateCreated();
  void Shutdown();

  void NotifyDoneLoading();

  // Set breakpoint at closest location to function entry.
  Breakpoint* SetBreakpointAtEntry(const Function& target_function,
                                   bool single_shot);
  Breakpoint* SetBreakpointAtActivation(const Instance& closure,
                                        bool for_over_await);
  Breakpoint* BreakpointAtActivation(const Instance& closure);

  // TODO(turnidge): script_url may no longer be specific enough.
  Breakpoint* SetBreakpointAtLine(const String& script_url,
                                  intptr_t line_number);
  Breakpoint* SetBreakpointAtLineCol(const String& script_url,
                                     intptr_t line_number,
                                     intptr_t column_number);

  // Sets synthetic breakpoint at async_op to step over the synthetic part of
  // the stack trace.
  Breakpoint* SetBreakpointAtAsyncOp(const Function& async_op);

  BreakpointLocation* BreakpointLocationAtLineCol(const String& script_url,
                                                  intptr_t line_number,
                                                  intptr_t column_number);

  // Returns true if the breakpoint's state changed.
  bool SetBreakpointState(Breakpoint* bpt, bool enable);

  void RemoveBreakpoint(intptr_t bp_id);
  Breakpoint* GetBreakpointById(intptr_t id);

  void MaybeAsyncStepInto(const Closure& async_op);
  void AsyncStepInto(const Closure& async_op);

  void Continue();

  bool SetResumeAction(ResumeAction action,
                       intptr_t frame_index = 1,
                       const char** error = NULL);

  bool IsStepping() const { return resume_action_ != kContinue; }

  bool IsSingleStepping() const { return resume_action_ == kStepInto; }

  bool IsPaused() const { return pause_event_ != NULL; }

  bool ignore_breakpoints() const { return ignore_breakpoints_; }
  void set_ignore_breakpoints(bool ignore_breakpoints) {
    ignore_breakpoints_ = ignore_breakpoints;
  }

  // Put the isolate into single stepping mode when Dart code next runs.
  //
  // This is used by the vm service to allow the user to step while
  // paused at isolate start.
  void EnterSingleStepMode();

  // Indicates why the debugger is currently paused.  If the debugger
  // is not paused, this returns NULL.  Note that the debugger can be
  // paused for breakpoints, isolate interruption, and (sometimes)
  // exceptions.
  const ServiceEvent* PauseEvent() const { return pause_event_; }

  void SetExceptionPauseInfo(Dart_ExceptionPauseInfo pause_info);
  Dart_ExceptionPauseInfo GetExceptionPauseInfo() const;

  void VisitObjectPointers(ObjectPointerVisitor* visitor);

  // Returns a stack trace with frames corresponding to invisible functions
  // omitted. CurrentStackTrace always returns a new trace on the current stack.
  // The trace returned by StackTrace may have been cached; it is suitable for
  // use when stepping, but otherwise may be out of sync with the current stack.
  DebuggerStackTrace* StackTrace();

  DebuggerStackTrace* AsyncCausalStackTrace();

  DebuggerStackTrace* AwaiterStackTrace();

  // Pause execution for a breakpoint.  Called from generated code.
  ErrorPtr PauseBreakpoint();

  // Pause execution due to stepping.  Called from generated code.
  ErrorPtr PauseStepping();

  // Pause execution due to isolate interrupt.
  ErrorPtr PauseInterrupted();

  // Pause after a reload request.
  ErrorPtr PausePostRequest();

  // Pause execution due to an uncaught exception.
  void PauseException(const Instance& exc);

  // Pause execution due to a call to the debugger() function from
  // Dart.
  void PauseDeveloper(const String& msg);

  void PrintBreakpointsToJSONArray(JSONArray* jsarr) const;
  void PrintSettingsToJSONObject(JSONObject* jsobj) const;

  static bool IsDebuggable(const Function& func);

  intptr_t limitBreakpointId() { return next_id_; }

  // Callback to the debugger to continue frame rewind, post-deoptimization.
  void RewindPostDeopt();

 private:
  ErrorPtr PauseRequest(ServiceEvent::EventKind kind);

  // Will return false if we are not at an await.
  bool SetupStepOverAsyncSuspension(const char** error);

  bool NeedsIsolateEvents();
  bool NeedsDebugEvents();

  void SendBreakpointEvent(ServiceEvent::EventKind kind, Breakpoint* bpt);

  void FindCompiledFunctions(
      const GrowableHandlePtrArray<const Script>& scripts,
      TokenPosition start_pos,
      TokenPosition end_pos,
      GrowableObjectArray* code_function_list);
  bool FindBestFit(const Script& script,
                   TokenPosition token_pos,
                   TokenPosition last_token_pos,
                   Function* best_fit);
  void DeoptimizeWorld();
  void NotifySingleStepping(bool value) const;
  BreakpointLocation* SetCodeBreakpoints(
      const GrowableHandlePtrArray<const Script>& scripts,
      TokenPosition token_pos,
      TokenPosition last_token_pos,
      intptr_t requested_line,
      intptr_t requested_column,
      TokenPosition exact_token_pos,
      const GrowableObjectArray& functions);
  BreakpointLocation* SetBreakpoint(const Script& script,
                                    TokenPosition token_pos,
                                    TokenPosition last_token_pos,
                                    intptr_t requested_line,
                                    intptr_t requested_column,
                                    const Function& function);
  BreakpointLocation* SetBreakpoint(
      const GrowableHandlePtrArray<const Script>& scripts,
      TokenPosition token_pos,
      TokenPosition last_token_pos,
      intptr_t requested_line,
      intptr_t requested_column,
      const Function& function);
  bool RemoveBreakpointFromTheList(intptr_t bp_id, BreakpointLocation** list);
  Breakpoint* GetBreakpointByIdInTheList(intptr_t id, BreakpointLocation* list);
  BreakpointLocation* GetLatentBreakpoint(const String& url,
                                          intptr_t line,
                                          intptr_t column);
  void RegisterBreakpointLocation(BreakpointLocation* bpt);
  BreakpointLocation* GetResolvedBreakpointLocation(
      const String& script_url,
      TokenPosition code_token_pos);
  BreakpointLocation* GetBreakpointLocation(
      const String& script_url,
      TokenPosition token_pos,
      intptr_t requested_line,
      intptr_t requested_column,
      TokenPosition code_token_pos = TokenPosition::kNoSource);

  void PrintBreakpointsListToJSONArray(BreakpointLocation* sbpt,
                                       JSONArray* jsarr) const;

  void SignalPausedEvent(ActivationFrame* top_frame, Breakpoint* bpt);

  intptr_t nextId() { return next_id_++; }

  bool ShouldPauseOnException(DebuggerStackTrace* stack_trace,
                              const Instance& exc);

  // Handles any events which pause vm execution.  Breakpoints,
  // interrupts, etc.
  void Pause(ServiceEvent* event);

  void HandleSteppingRequest(DebuggerStackTrace* stack_trace,
                             bool skip_next_step = false);

  void CacheStackTraces(DebuggerStackTrace* stack_trace,
                        DebuggerStackTrace* async_causal_stack_trace,
                        DebuggerStackTrace* awaiter_stack_trace);
  void ClearCachedStackTraces();

  void RewindToFrame(intptr_t frame_index);
  void RewindToUnoptimizedFrame(StackFrame* frame, const Code& code);
  void RewindToOptimizedFrame(StackFrame* frame,
                              const Code& code,
                              intptr_t post_deopt_frame_index);

  void ResetSteppingFramePointers();
  bool SteppedForSyntheticAsyncBreakpoint() const;
  void CleanupSyntheticAsyncBreakpoint();
  void RememberTopFrameAwaiter();
  void SetAsyncSteppingFramePointer(DebuggerStackTrace* stack_trace);
  void SetSyncSteppingFramePointer(DebuggerStackTrace* stack_trace);

  GroupDebugger* group_debugger() { return isolate_->group()->debugger(); }

  Isolate* isolate_;

  // ID number generator.
  intptr_t next_id_;

  BreakpointLocation* latent_locations_;
  BreakpointLocation* breakpoint_locations_;

  // Tells debugger what to do when resuming execution after a breakpoint.
  ResumeAction resume_action_;
  void set_resume_action(ResumeAction action);
  intptr_t resume_frame_index_;
  intptr_t post_deopt_frame_index_;

  // Do not call back to breakpoint handler if this flag is set.
  // Effectively this means ignoring breakpoints. Set when Dart code may
  // be run as a side effect of getting values of fields.
  bool ignore_breakpoints_;

  // Indicates why the debugger is currently paused.  If the debugger
  // is not paused, this is NULL.  Note that the debugger can be
  // paused for breakpoints, isolate interruption, and (sometimes)
  // exceptions.
  ServiceEvent* pause_event_;

  // Current stack trace. Valid only while IsPaused().
  DebuggerStackTrace* stack_trace_;
  DebuggerStackTrace* async_causal_stack_trace_;
  DebuggerStackTrace* awaiter_stack_trace_;

  // When stepping through code, only pause the program if the top
  // frame corresponds to this fp value, or if the top frame is
  // lower on the stack.
  uword stepping_fp_;

  // When stepping through code, do not stop more than once in the same
  // token position range.
  uword last_stepping_fp_;
  TokenPosition last_stepping_pos_;

  // Used to track the current async/async* function.
  uword async_stepping_fp_;
  ObjectPtr top_frame_awaiter_;

  // If we step while at a breakpoint, we would hit the same pc twice.
  // We use this field to let us skip the next single-step after a
  // breakpoint.
  bool skip_next_step_;

  // We keep this breakpoint alive until after the debugger does the step over
  // async continuation machinery so that we can report that we've stopped
  // at the breakpoint.
  Breakpoint* synthetic_async_breakpoint_;

  Dart_ExceptionPauseInfo exc_pause_info_;

  friend class Isolate;
  friend class BreakpointLocation;
  DISALLOW_COPY_AND_ASSIGN(Debugger);
};

class DisableBreakpointsScope : public ValueObject {
 public:
  DisableBreakpointsScope(Debugger* debugger, bool disable)
      : debugger_(debugger) {
    ASSERT(debugger_ != NULL);
    initial_state_ = debugger_->ignore_breakpoints();
    debugger_->set_ignore_breakpoints(disable);
  }

  ~DisableBreakpointsScope() {
    debugger_->set_ignore_breakpoints(initial_state_);
  }

 private:
  Debugger* debugger_;
  bool initial_state_;

  DISALLOW_COPY_AND_ASSIGN(DisableBreakpointsScope);
};

}  // namespace dart

#endif  // !defined(PRODUCT)

#endif  // RUNTIME_VM_DEBUGGER_H_
