|
| 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_ |
0 commit comments