Home | History | Annotate | Download | only in include
      1 // Copyright 2008 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_V8_DEBUG_H_
      6 #define V8_V8_DEBUG_H_
      7 
      8 #include "v8.h"
      9 
     10 /**
     11  * Debugger support for the V8 JavaScript engine.
     12  */
     13 namespace v8 {
     14 
     15 // Debug events which can occur in the V8 JavaScript engine.
     16 enum DebugEvent {
     17   Break = 1,
     18   Exception = 2,
     19   NewFunction = 3,
     20   BeforeCompile = 4,
     21   AfterCompile  = 5,
     22   ScriptCollected = 6,
     23   BreakForCommand = 7
     24 };
     25 
     26 
     27 class V8_EXPORT Debug {
     28  public:
     29   /**
     30    * A client object passed to the v8 debugger whose ownership will be taken by
     31    * it. v8 is always responsible for deleting the object.
     32    */
     33   class ClientData {
     34    public:
     35     virtual ~ClientData() {}
     36   };
     37 
     38 
     39   /**
     40    * A message object passed to the debug message handler.
     41    */
     42   class Message {
     43    public:
     44     /**
     45      * Check type of message.
     46      */
     47     virtual bool IsEvent() const = 0;
     48     virtual bool IsResponse() const = 0;
     49     virtual DebugEvent GetEvent() const = 0;
     50 
     51     /**
     52      * Indicate whether this is a response to a continue command which will
     53      * start the VM running after this is processed.
     54      */
     55     virtual bool WillStartRunning() const = 0;
     56 
     57     /**
     58      * Access to execution state and event data. Don't store these cross
     59      * callbacks as their content becomes invalid. These objects are from the
     60      * debugger event that started the debug message loop.
     61      */
     62     virtual Handle<Object> GetExecutionState() const = 0;
     63     virtual Handle<Object> GetEventData() const = 0;
     64 
     65     /**
     66      * Get the debugger protocol JSON.
     67      */
     68     virtual Handle<String> GetJSON() const = 0;
     69 
     70     /**
     71      * Get the context active when the debug event happened. Note this is not
     72      * the current active context as the JavaScript part of the debugger is
     73      * running in its own context which is entered at this point.
     74      */
     75     virtual Handle<Context> GetEventContext() const = 0;
     76 
     77     /**
     78      * Client data passed with the corresponding request if any. This is the
     79      * client_data data value passed into Debug::SendCommand along with the
     80      * request that led to the message or NULL if the message is an event. The
     81      * debugger takes ownership of the data and will delete it even if there is
     82      * no message handler.
     83      */
     84     virtual ClientData* GetClientData() const = 0;
     85 
     86     virtual Isolate* GetIsolate() const = 0;
     87 
     88     virtual ~Message() {}
     89   };
     90 
     91 
     92   /**
     93    * An event details object passed to the debug event listener.
     94    */
     95   class EventDetails {
     96    public:
     97     /**
     98      * Event type.
     99      */
    100     virtual DebugEvent GetEvent() const = 0;
    101 
    102     /**
    103      * Access to execution state and event data of the debug event. Don't store
    104      * these cross callbacks as their content becomes invalid.
    105      */
    106     virtual Handle<Object> GetExecutionState() const = 0;
    107     virtual Handle<Object> GetEventData() const = 0;
    108 
    109     /**
    110      * Get the context active when the debug event happened. Note this is not
    111      * the current active context as the JavaScript part of the debugger is
    112      * running in its own context which is entered at this point.
    113      */
    114     virtual Handle<Context> GetEventContext() const = 0;
    115 
    116     /**
    117      * Client data passed with the corresponding callback when it was
    118      * registered.
    119      */
    120     virtual Handle<Value> GetCallbackData() const = 0;
    121 
    122     /**
    123      * Client data passed to DebugBreakForCommand function. The
    124      * debugger takes ownership of the data and will delete it even if
    125      * there is no message handler.
    126      */
    127     virtual ClientData* GetClientData() const = 0;
    128 
    129     virtual ~EventDetails() {}
    130   };
    131 
    132   /**
    133    * Debug event callback function.
    134    *
    135    * \param event_details object providing information about the debug event
    136    *
    137    * A EventCallback2 does not take possession of the event data,
    138    * and must not rely on the data persisting after the handler returns.
    139    */
    140   typedef void (*EventCallback)(const EventDetails& event_details);
    141 
    142   /**
    143    * Debug message callback function.
    144    *
    145    * \param message the debug message handler message object
    146    *
    147    * A MessageHandler2 does not take possession of the message data,
    148    * and must not rely on the data persisting after the handler returns.
    149    */
    150   typedef void (*MessageHandler)(const Message& message);
    151 
    152   /**
    153    * Callback function for the host to ensure debug messages are processed.
    154    */
    155   typedef void (*DebugMessageDispatchHandler)();
    156 
    157   static bool SetDebugEventListener(EventCallback that,
    158                                     Handle<Value> data = Handle<Value>());
    159 
    160   // Schedule a debugger break to happen when JavaScript code is run
    161   // in the given isolate.
    162   static void DebugBreak(Isolate* isolate);
    163 
    164   // Remove scheduled debugger break in given isolate if it has not
    165   // happened yet.
    166   static void CancelDebugBreak(Isolate* isolate);
    167 
    168   // Break execution of JavaScript in the given isolate (this method
    169   // can be invoked from a non-VM thread) for further client command
    170   // execution on a VM thread. Client data is then passed in
    171   // EventDetails to EventCallback2 at the moment when the VM actually
    172   // stops.
    173   static void DebugBreakForCommand(Isolate* isolate, ClientData* data);
    174 
    175   // Message based interface. The message protocol is JSON.
    176   static void SetMessageHandler(MessageHandler handler);
    177 
    178   static void SendCommand(Isolate* isolate,
    179                           const uint16_t* command, int length,
    180                           ClientData* client_data = NULL);
    181 
    182  /**
    183   * Run a JavaScript function in the debugger.
    184   * \param fun the function to call
    185   * \param data passed as second argument to the function
    186   * With this call the debugger is entered and the function specified is called
    187   * with the execution state as the first argument. This makes it possible to
    188   * get access to information otherwise not available during normal JavaScript
    189   * execution e.g. details on stack frames. Receiver of the function call will
    190   * be the debugger context global object, however this is a subject to change.
    191   * The following example shows a JavaScript function which when passed to
    192   * v8::Debug::Call will return the current line of JavaScript execution.
    193   *
    194   * \code
    195   *   function frame_source_line(exec_state) {
    196   *     return exec_state.frame(0).sourceLine();
    197   *   }
    198   * \endcode
    199   */
    200   static Local<Value> Call(v8::Handle<v8::Function> fun,
    201                            Handle<Value> data = Handle<Value>());
    202 
    203   /**
    204    * Returns a mirror object for the given object.
    205    */
    206   static Local<Value> GetMirror(v8::Handle<v8::Value> obj);
    207 
    208   /**
    209    * Makes V8 process all pending debug messages.
    210    *
    211    * From V8 point of view all debug messages come asynchronously (e.g. from
    212    * remote debugger) but they all must be handled synchronously: V8 cannot
    213    * do 2 things at one time so normal script execution must be interrupted
    214    * for a while.
    215    *
    216    * Generally when message arrives V8 may be in one of 3 states:
    217    * 1. V8 is running script; V8 will automatically interrupt and process all
    218    * pending messages;
    219    * 2. V8 is suspended on debug breakpoint; in this state V8 is dedicated
    220    * to reading and processing debug messages;
    221    * 3. V8 is not running at all or has called some long-working C++ function;
    222    * by default it means that processing of all debug messages will be deferred
    223    * until V8 gets control again; however, embedding application may improve
    224    * this by manually calling this method.
    225    *
    226    * Technically this method in many senses is equivalent to executing empty
    227    * script:
    228    * 1. It does nothing except for processing all pending debug messages.
    229    * 2. It should be invoked with the same precautions and from the same context
    230    * as V8 script would be invoked from, because:
    231    *   a. with "evaluate" command it can do whatever normal script can do,
    232    *   including all native calls;
    233    *   b. no other thread should call V8 while this method is running
    234    *   (v8::Locker may be used here).
    235    *
    236    * "Evaluate" debug command behavior currently is not specified in scope
    237    * of this method.
    238    */
    239   static void ProcessDebugMessages();
    240 
    241   /**
    242    * Debugger is running in its own context which is entered while debugger
    243    * messages are being dispatched. This is an explicit getter for this
    244    * debugger context. Note that the content of the debugger context is subject
    245    * to change.
    246    */
    247   static Local<Context> GetDebugContext();
    248 
    249 
    250   /**
    251    * Enable/disable LiveEdit functionality for the given Isolate
    252    * (default Isolate if not provided). V8 will abort if LiveEdit is
    253    * unexpectedly used. LiveEdit is enabled by default.
    254    */
    255   static void SetLiveEditEnabled(Isolate* isolate, bool enable);
    256 };
    257 
    258 
    259 }  // namespace v8
    260 
    261 
    262 #undef EXPORT
    263 
    264 
    265 #endif  // V8_V8_DEBUG_H_
    266