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 AsyncTaskEvent = 7, 24 }; 25 26 class V8_EXPORT Debug { 27 public: 28 /** 29 * A client object passed to the v8 debugger whose ownership will be taken by 30 * it. v8 is always responsible for deleting the object. 31 */ 32 class ClientData { 33 public: ~ClientData()34 virtual ~ClientData() {} 35 }; 36 37 38 /** 39 * A message object passed to the debug message handler. 40 */ 41 class Message { 42 public: 43 /** 44 * Check type of message. 45 */ 46 virtual bool IsEvent() const = 0; 47 virtual bool IsResponse() const = 0; 48 virtual DebugEvent GetEvent() const = 0; 49 50 /** 51 * Indicate whether this is a response to a continue command which will 52 * start the VM running after this is processed. 53 */ 54 virtual bool WillStartRunning() const = 0; 55 56 /** 57 * Access to execution state and event data. Don't store these cross 58 * callbacks as their content becomes invalid. These objects are from the 59 * debugger event that started the debug message loop. 60 */ 61 virtual Local<Object> GetExecutionState() const = 0; 62 virtual Local<Object> GetEventData() const = 0; 63 64 /** 65 * Get the debugger protocol JSON. 66 */ 67 virtual Local<String> GetJSON() const = 0; 68 69 /** 70 * Get the context active when the debug event happened. Note this is not 71 * the current active context as the JavaScript part of the debugger is 72 * running in its own context which is entered at this point. 73 */ 74 virtual Local<Context> GetEventContext() const = 0; 75 76 /** 77 * Client data passed with the corresponding request if any. This is the 78 * client_data data value passed into Debug::SendCommand along with the 79 * request that led to the message or NULL if the message is an event. The 80 * debugger takes ownership of the data and will delete it even if there is 81 * no message handler. 82 */ 83 virtual ClientData* GetClientData() const = 0; 84 85 virtual Isolate* GetIsolate() const = 0; 86 ~Message()87 virtual ~Message() {} 88 }; 89 90 91 /** 92 * An event details object passed to the debug event listener. 93 */ 94 class EventDetails { 95 public: 96 /** 97 * Event type. 98 */ 99 virtual DebugEvent GetEvent() const = 0; 100 101 /** 102 * Access to execution state and event data of the debug event. Don't store 103 * these cross callbacks as their content becomes invalid. 104 */ 105 virtual Local<Object> GetExecutionState() const = 0; 106 virtual Local<Object> GetEventData() const = 0; 107 108 /** 109 * Get the context active when the debug event happened. Note this is not 110 * the current active context as the JavaScript part of the debugger is 111 * running in its own context which is entered at this point. 112 */ 113 virtual Local<Context> GetEventContext() const = 0; 114 115 /** 116 * Client data passed with the corresponding callback when it was 117 * registered. 118 */ 119 virtual Local<Value> GetCallbackData() const = 0; 120 121 /** 122 * Client data passed to DebugBreakForCommand function. The 123 * debugger takes ownership of the data and will delete it even if 124 * there is no message handler. 125 */ 126 virtual ClientData* GetClientData() const = 0; 127 128 virtual Isolate* GetIsolate() 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 * While in the debug context, this method returns the top-most non-debug 266 * context, if it exists. 267 */ 268 static MaybeLocal<Context> GetDebuggedContext(Isolate* isolate); 269 270 /** 271 * Enable/disable LiveEdit functionality for the given Isolate 272 * (default Isolate if not provided). V8 will abort if LiveEdit is 273 * unexpectedly used. LiveEdit is enabled by default. 274 */ 275 static void SetLiveEditEnabled(Isolate* isolate, bool enable); 276 277 /** 278 * Returns array of internal properties specific to the value type. Result has 279 * the following format: [<name>, <value>,...,<name>, <value>]. Result array 280 * will be allocated in the current context. 281 */ 282 static MaybeLocal<Array> GetInternalProperties(Isolate* isolate, 283 Local<Value> value); 284 285 /** 286 * Defines if the ES2015 tail call elimination feature is enabled or not. 287 * The change of this flag triggers deoptimization of all functions that 288 * contain calls at tail position. 289 */ 290 static bool IsTailCallEliminationEnabled(Isolate* isolate); 291 static void SetTailCallEliminationEnabled(Isolate* isolate, bool enabled); 292 }; 293 294 295 } // namespace v8 296 297 298 #undef EXPORT 299 300 301 #endif // V8_V8_DEBUG_H_ 302