1 // Copyright 2016 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_INSPECTOR_H_ 6 #define V8_V8_INSPECTOR_H_ 7 8 #include <stdint.h> 9 #include <cctype> 10 11 #include <memory> 12 13 #include "v8.h" // NOLINT(build/include) 14 15 namespace v8_inspector { 16 17 namespace protocol { 18 namespace Debugger { 19 namespace API { 20 class SearchMatch; 21 } 22 } 23 namespace Runtime { 24 namespace API { 25 class RemoteObject; 26 class StackTrace; 27 } 28 } 29 namespace Schema { 30 namespace API { 31 class Domain; 32 } 33 } 34 } // namespace protocol 35 36 class V8_EXPORT StringView { 37 public: 38 StringView() : m_is8Bit(true), m_length(0), m_characters8(nullptr) {} 39 40 StringView(const uint8_t* characters, size_t length) 41 : m_is8Bit(true), m_length(length), m_characters8(characters) {} 42 43 StringView(const uint16_t* characters, size_t length) 44 : m_is8Bit(false), m_length(length), m_characters16(characters) {} 45 46 bool is8Bit() const { return m_is8Bit; } 47 size_t length() const { return m_length; } 48 49 // TODO(dgozman): add DCHECK(m_is8Bit) to accessors once platform can be used 50 // here. 51 const uint8_t* characters8() const { return m_characters8; } 52 const uint16_t* characters16() const { return m_characters16; } 53 54 private: 55 bool m_is8Bit; 56 size_t m_length; 57 union { 58 const uint8_t* m_characters8; 59 const uint16_t* m_characters16; 60 }; 61 }; 62 63 class V8_EXPORT StringBuffer { 64 public: 65 virtual ~StringBuffer() {} 66 virtual const StringView& string() = 0; 67 // This method copies contents. 68 static std::unique_ptr<StringBuffer> create(const StringView&); 69 }; 70 71 class V8_EXPORT V8ContextInfo { 72 public: 73 V8ContextInfo(v8::Local<v8::Context> context, int contextGroupId, 74 const StringView& humanReadableName) 75 : context(context), 76 contextGroupId(contextGroupId), 77 humanReadableName(humanReadableName), 78 hasMemoryOnConsole(false) {} 79 80 v8::Local<v8::Context> context; 81 // Each v8::Context is a part of a group. The group id must be non-zero. 82 int contextGroupId; 83 StringView humanReadableName; 84 StringView origin; 85 StringView auxData; 86 bool hasMemoryOnConsole; 87 88 private: 89 // Disallow copying and allocating this one. 90 enum NotNullTagEnum { NotNullLiteral }; 91 void* operator new(size_t) = delete; 92 void* operator new(size_t, NotNullTagEnum, void*) = delete; 93 void* operator new(size_t, void*) = delete; 94 V8ContextInfo(const V8ContextInfo&) = delete; 95 V8ContextInfo& operator=(const V8ContextInfo&) = delete; 96 }; 97 98 class V8_EXPORT V8StackTrace { 99 public: 100 virtual bool isEmpty() const = 0; 101 virtual StringView topSourceURL() const = 0; 102 virtual int topLineNumber() const = 0; 103 virtual int topColumnNumber() const = 0; 104 virtual StringView topScriptId() const = 0; 105 virtual StringView topFunctionName() const = 0; 106 107 virtual ~V8StackTrace() {} 108 virtual std::unique_ptr<protocol::Runtime::API::StackTrace> 109 buildInspectorObject() const = 0; 110 virtual std::unique_ptr<StringBuffer> toString() const = 0; 111 112 // Safe to pass between threads, drops async chain. 113 virtual std::unique_ptr<V8StackTrace> clone() = 0; 114 }; 115 116 class V8_EXPORT V8InspectorSession { 117 public: 118 virtual ~V8InspectorSession() {} 119 120 // Cross-context inspectable values (DOM nodes in different worlds, etc.). 121 class V8_EXPORT Inspectable { 122 public: 123 virtual v8::Local<v8::Value> get(v8::Local<v8::Context>) = 0; 124 virtual ~Inspectable() {} 125 }; 126 virtual void addInspectedObject(std::unique_ptr<Inspectable>) = 0; 127 128 // Dispatching protocol messages. 129 static bool canDispatchMethod(const StringView& method); 130 virtual void dispatchProtocolMessage(const StringView& message) = 0; 131 virtual std::unique_ptr<StringBuffer> stateJSON() = 0; 132 virtual std::vector<std::unique_ptr<protocol::Schema::API::Domain>> 133 supportedDomains() = 0; 134 135 // Debugger actions. 136 virtual void schedulePauseOnNextStatement(const StringView& breakReason, 137 const StringView& breakDetails) = 0; 138 virtual void cancelPauseOnNextStatement() = 0; 139 virtual void breakProgram(const StringView& breakReason, 140 const StringView& breakDetails) = 0; 141 virtual void setSkipAllPauses(bool) = 0; 142 virtual void resume() = 0; 143 virtual void stepOver() = 0; 144 virtual std::vector<std::unique_ptr<protocol::Debugger::API::SearchMatch>> 145 searchInTextByLines(const StringView& text, const StringView& query, 146 bool caseSensitive, bool isRegex) = 0; 147 148 // Remote objects. 149 virtual std::unique_ptr<protocol::Runtime::API::RemoteObject> wrapObject( 150 v8::Local<v8::Context>, v8::Local<v8::Value>, 151 const StringView& groupName) = 0; 152 virtual bool unwrapObject(std::unique_ptr<StringBuffer>* error, 153 const StringView& objectId, v8::Local<v8::Value>*, 154 v8::Local<v8::Context>*, 155 std::unique_ptr<StringBuffer>* objectGroup) = 0; 156 virtual void releaseObjectGroup(const StringView&) = 0; 157 }; 158 159 enum class V8ConsoleAPIType { kClear, kDebug, kLog, kInfo, kWarning, kError }; 160 161 class V8_EXPORT V8InspectorClient { 162 public: 163 virtual ~V8InspectorClient() {} 164 165 virtual void runMessageLoopOnPause(int contextGroupId) {} 166 virtual void quitMessageLoopOnPause() {} 167 virtual void runIfWaitingForDebugger(int contextGroupId) {} 168 169 virtual void muteMetrics(int contextGroupId) {} 170 virtual void unmuteMetrics(int contextGroupId) {} 171 172 virtual void beginUserGesture() {} 173 virtual void endUserGesture() {} 174 175 virtual std::unique_ptr<StringBuffer> valueSubtype(v8::Local<v8::Value>) { 176 return nullptr; 177 } 178 virtual bool formatAccessorsAsProperties(v8::Local<v8::Value>) { 179 return false; 180 } 181 virtual bool isInspectableHeapObject(v8::Local<v8::Object>) { return true; } 182 183 virtual v8::Local<v8::Context> ensureDefaultContextInGroup( 184 int contextGroupId) { 185 return v8::Local<v8::Context>(); 186 } 187 virtual void beginEnsureAllContextsInGroup(int contextGroupId) {} 188 virtual void endEnsureAllContextsInGroup(int contextGroupId) {} 189 190 virtual void installAdditionalCommandLineAPI(v8::Local<v8::Context>, 191 v8::Local<v8::Object>) {} 192 virtual void consoleAPIMessage(int contextGroupId, V8ConsoleAPIType, 193 const StringView& message, 194 const StringView& url, unsigned lineNumber, 195 unsigned columnNumber, V8StackTrace*) {} 196 virtual v8::MaybeLocal<v8::Value> memoryInfo(v8::Isolate*, 197 v8::Local<v8::Context>) { 198 return v8::MaybeLocal<v8::Value>(); 199 } 200 201 virtual void consoleTime(const StringView& title) {} 202 virtual void consoleTimeEnd(const StringView& title) {} 203 virtual void consoleTimeStamp(const StringView& title) {} 204 virtual double currentTimeMS() { return 0; } 205 typedef void (*TimerCallback)(void*); 206 virtual void startRepeatingTimer(double, TimerCallback, void* data) {} 207 virtual void cancelTimer(void* data) {} 208 209 // TODO(dgozman): this was added to support service worker shadow page. We 210 // should not connect at all. 211 virtual bool canExecuteScripts(int contextGroupId) { return true; } 212 }; 213 214 class V8_EXPORT V8Inspector { 215 public: 216 static std::unique_ptr<V8Inspector> create(v8::Isolate*, V8InspectorClient*); 217 virtual ~V8Inspector() {} 218 219 // Contexts instrumentation. 220 virtual void contextCreated(const V8ContextInfo&) = 0; 221 virtual void contextDestroyed(v8::Local<v8::Context>) = 0; 222 virtual void resetContextGroup(int contextGroupId) = 0; 223 224 // Various instrumentation. 225 virtual void willExecuteScript(v8::Local<v8::Context>, int scriptId) = 0; 226 virtual void didExecuteScript(v8::Local<v8::Context>) = 0; 227 virtual void idleStarted() = 0; 228 virtual void idleFinished() = 0; 229 230 // Async stack traces instrumentation. 231 virtual void asyncTaskScheduled(const StringView& taskName, void* task, 232 bool recurring) = 0; 233 virtual void asyncTaskCanceled(void* task) = 0; 234 virtual void asyncTaskStarted(void* task) = 0; 235 virtual void asyncTaskFinished(void* task) = 0; 236 virtual void allAsyncTasksCanceled() = 0; 237 238 // Exceptions instrumentation. 239 virtual unsigned exceptionThrown( 240 v8::Local<v8::Context>, const StringView& message, 241 v8::Local<v8::Value> exception, const StringView& detailedMessage, 242 const StringView& url, unsigned lineNumber, unsigned columnNumber, 243 std::unique_ptr<V8StackTrace>, int scriptId) = 0; 244 virtual void exceptionRevoked(v8::Local<v8::Context>, unsigned exceptionId, 245 const StringView& message) = 0; 246 247 // Connection. 248 class V8_EXPORT Channel { 249 public: 250 virtual ~Channel() {} 251 virtual void sendProtocolResponse(int callId, 252 const StringView& message) = 0; 253 virtual void sendProtocolNotification(const StringView& message) = 0; 254 virtual void flushProtocolNotifications() = 0; 255 }; 256 virtual std::unique_ptr<V8InspectorSession> connect( 257 int contextGroupId, Channel*, const StringView& state) = 0; 258 259 // API methods. 260 virtual std::unique_ptr<V8StackTrace> createStackTrace( 261 v8::Local<v8::StackTrace>) = 0; 262 virtual std::unique_ptr<V8StackTrace> captureStackTrace(bool fullStack) = 0; 263 }; 264 265 } // namespace v8_inspector 266 267 #endif // V8_V8_INSPECTOR_H_ 268