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