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 AfterCompile = 3, 20 CompileError = 4, 21 AsyncTaskEvent = 5, 22 }; 23 24 class V8_EXPORT Debug { 25 public: 26 /** 27 * A client object passed to the v8 debugger whose ownership will be taken by 28 * it. v8 is always responsible for deleting the object. 29 */ 30 class ClientData { 31 public: ~ClientData()32 virtual ~ClientData() {} 33 }; 34 35 36 /** 37 * A message object passed to the debug message handler. 38 */ 39 class Message { 40 public: 41 /** 42 * Check type of message. 43 */ 44 virtual bool IsEvent() const = 0; 45 virtual bool IsResponse() const = 0; 46 virtual DebugEvent GetEvent() const = 0; 47 48 /** 49 * Indicate whether this is a response to a continue command which will 50 * start the VM running after this is processed. 51 */ 52 virtual bool WillStartRunning() const = 0; 53 54 /** 55 * Access to execution state and event data. Don't store these cross 56 * callbacks as their content becomes invalid. These objects are from the 57 * debugger event that started the debug message loop. 58 */ 59 virtual Local<Object> GetExecutionState() const = 0; 60 virtual Local<Object> GetEventData() const = 0; 61 62 /** 63 * Get the debugger protocol JSON. 64 */ 65 virtual Local<String> GetJSON() const = 0; 66 67 /** 68 * Get the context active when the debug event happened. Note this is not 69 * the current active context as the JavaScript part of the debugger is 70 * running in its own context which is entered at this point. 71 */ 72 virtual Local<Context> GetEventContext() const = 0; 73 74 /** 75 * Client data passed with the corresponding request if any. This is the 76 * client_data data value passed into Debug::SendCommand along with the 77 * request that led to the message or NULL if the message is an event. The 78 * debugger takes ownership of the data and will delete it even if there is 79 * no message handler. 80 */ 81 virtual ClientData* GetClientData() const = 0; 82 83 virtual Isolate* GetIsolate() const = 0; 84 ~Message()85 virtual ~Message() {} 86 }; 87 88 /** 89 * An event details object passed to the debug event listener. 90 */ 91 class EventDetails { 92 public: 93 /** 94 * Event type. 95 */ 96 virtual DebugEvent GetEvent() const = 0; 97 98 /** 99 * Access to execution state and event data of the debug event. Don't store 100 * these cross callbacks as their content becomes invalid. 101 */ 102 virtual Local<Object> GetExecutionState() const = 0; 103 virtual Local<Object> GetEventData() const = 0; 104 105 /** 106 * Get the context active when the debug event happened. Note this is not 107 * the current active context as the JavaScript part of the debugger is 108 * running in its own context which is entered at this point. 109 */ 110 virtual Local<Context> GetEventContext() const = 0; 111 112 /** 113 * Client data passed with the corresponding callback when it was 114 * registered. 115 */ 116 virtual Local<Value> GetCallbackData() const = 0; 117 118 /** 119 * This is now a dummy that returns nullptr. 120 */ 121 virtual ClientData* GetClientData() const = 0; 122 123 virtual Isolate* GetIsolate() const = 0; 124 ~EventDetails()125 virtual ~EventDetails() {} 126 }; 127 128 /** 129 * Debug event callback function. 130 * 131 * \param event_details object providing information about the debug event 132 * 133 * A EventCallback does not take possession of the event data, 134 * and must not rely on the data persisting after the handler returns. 135 */ 136 typedef void (*EventCallback)(const EventDetails& event_details); 137 138 /** 139 * This is now a no-op. 140 */ 141 typedef void (*MessageHandler)(const Message& message); 142 143 /** 144 * This is now a no-op. 145 */ 146 typedef void (*DebugMessageDispatchHandler)(); 147 148 static bool SetDebugEventListener(Isolate* isolate, EventCallback that, 149 Local<Value> data = Local<Value>()); 150 151 // Schedule a debugger break to happen when JavaScript code is run 152 // in the given isolate. 153 static void DebugBreak(Isolate* isolate); 154 155 // Remove scheduled debugger break in given isolate if it has not 156 // happened yet. 157 static void CancelDebugBreak(Isolate* isolate); 158 159 // Check if a debugger break is scheduled in the given isolate. 160 V8_DEPRECATED("No longer supported", 161 static bool CheckDebugBreak(Isolate* isolate)); 162 163 // This is now a no-op. 164 V8_DEPRECATED("No longer supported", 165 static void SetMessageHandler(Isolate* isolate, 166 MessageHandler handler)); 167 168 // This is now a no-op. 169 V8_DEPRECATED("No longer supported", 170 static void SendCommand(Isolate* isolate, 171 const uint16_t* command, int length, 172 ClientData* client_data = NULL)); 173 174 /** 175 * Run a JavaScript function in the debugger. 176 * \param fun the function to call 177 * \param data passed as second argument to the function 178 * With this call the debugger is entered and the function specified is called 179 * with the execution state as the first argument. This makes it possible to 180 * get access to information otherwise not available during normal JavaScript 181 * execution e.g. details on stack frames. Receiver of the function call will 182 * be the debugger context global object, however this is a subject to change. 183 * The following example shows a JavaScript function which when passed to 184 * v8::Debug::Call will return the current line of JavaScript execution. 185 * 186 * \code 187 * function frame_source_line(exec_state) { 188 * return exec_state.frame(0).sourceLine(); 189 * } 190 * \endcode 191 */ 192 // TODO(dcarney): data arg should be a MaybeLocal 193 static MaybeLocal<Value> Call(Local<Context> context, 194 v8::Local<v8::Function> fun, 195 Local<Value> data = Local<Value>()); 196 197 // This is now a no-op. 198 V8_DEPRECATED("No longer supported", 199 static void ProcessDebugMessages(Isolate* isolate)); 200 201 /** 202 * Debugger is running in its own context which is entered while debugger 203 * messages are being dispatched. This is an explicit getter for this 204 * debugger context. Note that the content of the debugger context is subject 205 * to change. The Context exists only when the debugger is active, i.e. at 206 * least one DebugEventListener or MessageHandler is set. 207 */ 208 V8_DEPRECATED("Use v8-inspector", 209 static Local<Context> GetDebugContext(Isolate* isolate)); 210 211 /** 212 * While in the debug context, this method returns the top-most non-debug 213 * context, if it exists. 214 */ 215 V8_DEPRECATED( 216 "No longer supported", 217 static MaybeLocal<Context> GetDebuggedContext(Isolate* isolate)); 218 219 /** 220 * Enable/disable LiveEdit functionality for the given Isolate 221 * (default Isolate if not provided). V8 will abort if LiveEdit is 222 * unexpectedly used. LiveEdit is enabled by default. 223 */ 224 static void SetLiveEditEnabled(Isolate* isolate, bool enable); 225 226 /** 227 * Returns array of internal properties specific to the value type. Result has 228 * the following format: [<name>, <value>,...,<name>, <value>]. Result array 229 * will be allocated in the current context. 230 */ 231 static MaybeLocal<Array> GetInternalProperties(Isolate* isolate, 232 Local<Value> value); 233 234 /** 235 * Defines if the ES2015 tail call elimination feature is enabled or not. 236 * The change of this flag triggers deoptimization of all functions that 237 * contain calls at tail position. 238 */ 239 static bool IsTailCallEliminationEnabled(Isolate* isolate); 240 static void SetTailCallEliminationEnabled(Isolate* isolate, bool enabled); 241 }; 242 243 244 } // namespace v8 245 246 247 #undef EXPORT 248 249 250 #endif // V8_V8_DEBUG_H_ 251