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