| // Copyright 2016 the V8 project authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef V8_V8_INSPECTOR_H_ | 
 | #define V8_V8_INSPECTOR_H_ | 
 |  | 
 | #include <stdint.h> | 
 | #include <cctype> | 
 |  | 
 | #include <memory> | 
 | #include <unordered_map> | 
 |  | 
 | #include "v8.h"  // NOLINT(build/include_directory) | 
 |  | 
 | namespace v8_inspector { | 
 |  | 
 | namespace protocol { | 
 | namespace Debugger { | 
 | namespace API { | 
 | class SearchMatch; | 
 | } | 
 | } | 
 | namespace Runtime { | 
 | namespace API { | 
 | class RemoteObject; | 
 | class StackTrace; | 
 | class StackTraceId; | 
 | } | 
 | } | 
 | namespace Schema { | 
 | namespace API { | 
 | class Domain; | 
 | } | 
 | } | 
 | }  // namespace protocol | 
 |  | 
 | class V8_EXPORT StringView { | 
 |  public: | 
 |   StringView() : m_is8Bit(true), m_length(0), m_characters8(nullptr) {} | 
 |  | 
 |   StringView(const uint8_t* characters, size_t length) | 
 |       : m_is8Bit(true), m_length(length), m_characters8(characters) {} | 
 |  | 
 |   StringView(const uint16_t* characters, size_t length) | 
 |       : m_is8Bit(false), m_length(length), m_characters16(characters) {} | 
 |  | 
 |   bool is8Bit() const { return m_is8Bit; } | 
 |   size_t length() const { return m_length; } | 
 |  | 
 |   // TODO(dgozman): add DCHECK(m_is8Bit) to accessors once platform can be used | 
 |   // here. | 
 |   const uint8_t* characters8() const { return m_characters8; } | 
 |   const uint16_t* characters16() const { return m_characters16; } | 
 |  | 
 |  private: | 
 |   bool m_is8Bit; | 
 |   size_t m_length; | 
 |   union { | 
 |     const uint8_t* m_characters8; | 
 |     const uint16_t* m_characters16; | 
 |   }; | 
 | }; | 
 |  | 
 | class V8_EXPORT StringBuffer { | 
 |  public: | 
 |   virtual ~StringBuffer() = default; | 
 |   virtual StringView string() const = 0; | 
 |   // This method copies contents. | 
 |   static std::unique_ptr<StringBuffer> create(StringView); | 
 | }; | 
 |  | 
 | class V8_EXPORT V8ContextInfo { | 
 |  public: | 
 |   V8ContextInfo(v8::Local<v8::Context> context, int contextGroupId, | 
 |                 StringView humanReadableName) | 
 |       : context(context), | 
 |         contextGroupId(contextGroupId), | 
 |         humanReadableName(humanReadableName), | 
 |         hasMemoryOnConsole(false) {} | 
 |  | 
 |   v8::Local<v8::Context> context; | 
 |   // Each v8::Context is a part of a group. The group id must be non-zero. | 
 |   int contextGroupId; | 
 |   StringView humanReadableName; | 
 |   StringView origin; | 
 |   StringView auxData; | 
 |   bool hasMemoryOnConsole; | 
 |  | 
 |   static int executionContextId(v8::Local<v8::Context> context); | 
 |  | 
 |   // Disallow copying and allocating this one. | 
 |   enum NotNullTagEnum { NotNullLiteral }; | 
 |   void* operator new(size_t) = delete; | 
 |   void* operator new(size_t, NotNullTagEnum, void*) = delete; | 
 |   void* operator new(size_t, void*) = delete; | 
 |   V8ContextInfo(const V8ContextInfo&) = delete; | 
 |   V8ContextInfo& operator=(const V8ContextInfo&) = delete; | 
 | }; | 
 |  | 
 | class V8_EXPORT V8StackTrace { | 
 |  public: | 
 |   virtual StringView firstNonEmptySourceURL() const = 0; | 
 |   virtual bool isEmpty() const = 0; | 
 |   virtual StringView topSourceURL() const = 0; | 
 |   virtual int topLineNumber() const = 0; | 
 |   virtual int topColumnNumber() const = 0; | 
 |   virtual StringView topScriptId() const = 0; | 
 |   virtual StringView topFunctionName() const = 0; | 
 |  | 
 |   virtual ~V8StackTrace() = default; | 
 |   virtual std::unique_ptr<protocol::Runtime::API::StackTrace> | 
 |   buildInspectorObject() const = 0; | 
 |   virtual std::unique_ptr<protocol::Runtime::API::StackTrace> | 
 |   buildInspectorObject(int maxAsyncDepth) const = 0; | 
 |   virtual std::unique_ptr<StringBuffer> toString() const = 0; | 
 |  | 
 |   // Safe to pass between threads, drops async chain. | 
 |   virtual std::unique_ptr<V8StackTrace> clone() = 0; | 
 | }; | 
 |  | 
 | class V8_EXPORT V8InspectorSession { | 
 |  public: | 
 |   virtual ~V8InspectorSession() = default; | 
 |  | 
 |   // Cross-context inspectable values (DOM nodes in different worlds, etc.). | 
 |   class V8_EXPORT Inspectable { | 
 |    public: | 
 |     virtual v8::Local<v8::Value> get(v8::Local<v8::Context>) = 0; | 
 |     virtual ~Inspectable() = default; | 
 |   }; | 
 |   virtual void addInspectedObject(std::unique_ptr<Inspectable>) = 0; | 
 |  | 
 |   // Dispatching protocol messages. | 
 |   static bool canDispatchMethod(StringView method); | 
 |   virtual void dispatchProtocolMessage(StringView message) = 0; | 
 |   virtual std::vector<uint8_t> state() = 0; | 
 |   virtual std::vector<std::unique_ptr<protocol::Schema::API::Domain>> | 
 |   supportedDomains() = 0; | 
 |  | 
 |   // Debugger actions. | 
 |   virtual void schedulePauseOnNextStatement(StringView breakReason, | 
 |                                             StringView breakDetails) = 0; | 
 |   virtual void cancelPauseOnNextStatement() = 0; | 
 |   virtual void breakProgram(StringView breakReason, | 
 |                             StringView breakDetails) = 0; | 
 |   virtual void setSkipAllPauses(bool) = 0; | 
 |   virtual void resume(bool setTerminateOnResume = false) = 0; | 
 |   virtual void stepOver() = 0; | 
 |   virtual std::vector<std::unique_ptr<protocol::Debugger::API::SearchMatch>> | 
 |   searchInTextByLines(StringView text, StringView query, bool caseSensitive, | 
 |                       bool isRegex) = 0; | 
 |  | 
 |   // Remote objects. | 
 |   virtual std::unique_ptr<protocol::Runtime::API::RemoteObject> wrapObject( | 
 |       v8::Local<v8::Context>, v8::Local<v8::Value>, StringView groupName, | 
 |       bool generatePreview) = 0; | 
 |  | 
 |   virtual bool unwrapObject(std::unique_ptr<StringBuffer>* error, | 
 |                             StringView objectId, v8::Local<v8::Value>*, | 
 |                             v8::Local<v8::Context>*, | 
 |                             std::unique_ptr<StringBuffer>* objectGroup) = 0; | 
 |   virtual void releaseObjectGroup(StringView) = 0; | 
 |   virtual void triggerPreciseCoverageDeltaUpdate(StringView occassion) = 0; | 
 | }; | 
 |  | 
 | class V8_EXPORT V8InspectorClient { | 
 |  public: | 
 |   virtual ~V8InspectorClient() = default; | 
 |  | 
 |   virtual void runMessageLoopOnPause(int contextGroupId) {} | 
 |   virtual void quitMessageLoopOnPause() {} | 
 |   virtual void runIfWaitingForDebugger(int contextGroupId) {} | 
 |  | 
 |   virtual void muteMetrics(int contextGroupId) {} | 
 |   virtual void unmuteMetrics(int contextGroupId) {} | 
 |  | 
 |   virtual void beginUserGesture() {} | 
 |   virtual void endUserGesture() {} | 
 |  | 
 |   virtual std::unique_ptr<StringBuffer> valueSubtype(v8::Local<v8::Value>) { | 
 |     return nullptr; | 
 |   } | 
 |   virtual std::unique_ptr<StringBuffer> descriptionForValueSubtype( | 
 |       v8::Local<v8::Context>, v8::Local<v8::Value>) { | 
 |     return nullptr; | 
 |   } | 
 |   virtual bool formatAccessorsAsProperties(v8::Local<v8::Value>) { | 
 |     return false; | 
 |   } | 
 |   virtual bool isInspectableHeapObject(v8::Local<v8::Object>) { return true; } | 
 |  | 
 |   virtual v8::Local<v8::Context> ensureDefaultContextInGroup( | 
 |       int contextGroupId) { | 
 |     return v8::Local<v8::Context>(); | 
 |   } | 
 |   virtual void beginEnsureAllContextsInGroup(int contextGroupId) {} | 
 |   virtual void endEnsureAllContextsInGroup(int contextGroupId) {} | 
 |  | 
 |   virtual void installAdditionalCommandLineAPI(v8::Local<v8::Context>, | 
 |                                                v8::Local<v8::Object>) {} | 
 |   virtual void consoleAPIMessage(int contextGroupId, | 
 |                                  v8::Isolate::MessageErrorLevel level, | 
 |                                  const StringView& message, | 
 |                                  const StringView& url, unsigned lineNumber, | 
 |                                  unsigned columnNumber, V8StackTrace*) {} | 
 |   virtual v8::MaybeLocal<v8::Value> memoryInfo(v8::Isolate*, | 
 |                                                v8::Local<v8::Context>) { | 
 |     return v8::MaybeLocal<v8::Value>(); | 
 |   } | 
 |  | 
 |   virtual void consoleTime(const StringView& title) {} | 
 |   virtual void consoleTimeEnd(const StringView& title) {} | 
 |   virtual void consoleTimeStamp(const StringView& title) {} | 
 |   virtual void consoleClear(int contextGroupId) {} | 
 |   virtual double currentTimeMS() { return 0; } | 
 |   typedef void (*TimerCallback)(void*); | 
 |   virtual void startRepeatingTimer(double, TimerCallback, void* data) {} | 
 |   virtual void cancelTimer(void* data) {} | 
 |  | 
 |   // TODO(dgozman): this was added to support service worker shadow page. We | 
 |   // should not connect at all. | 
 |   virtual bool canExecuteScripts(int contextGroupId) { return true; } | 
 |  | 
 |   virtual void maxAsyncCallStackDepthChanged(int depth) {} | 
 |  | 
 |   virtual std::unique_ptr<StringBuffer> resourceNameToUrl( | 
 |       const StringView& resourceName) { | 
 |     return nullptr; | 
 |   } | 
 | }; | 
 |  | 
 | // These stack trace ids are intended to be passed between debuggers and be | 
 | // resolved later. This allows to track cross-debugger calls and step between | 
 | // them if a single client connects to multiple debuggers. | 
 | struct V8_EXPORT V8StackTraceId { | 
 |   uintptr_t id; | 
 |   std::pair<int64_t, int64_t> debugger_id; | 
 |   bool should_pause = false; | 
 |  | 
 |   V8StackTraceId(); | 
 |   V8StackTraceId(const V8StackTraceId&) = default; | 
 |   V8StackTraceId(uintptr_t id, const std::pair<int64_t, int64_t> debugger_id); | 
 |   V8StackTraceId(uintptr_t id, const std::pair<int64_t, int64_t> debugger_id, | 
 |                  bool should_pause); | 
 |   explicit V8StackTraceId(StringView); | 
 |   V8StackTraceId& operator=(const V8StackTraceId&) = default; | 
 |   V8StackTraceId& operator=(V8StackTraceId&&) noexcept = default; | 
 |   ~V8StackTraceId() = default; | 
 |  | 
 |   bool IsInvalid() const; | 
 |   std::unique_ptr<StringBuffer> ToString(); | 
 | }; | 
 |  | 
 | class V8_EXPORT V8Inspector { | 
 |  public: | 
 |   static std::unique_ptr<V8Inspector> create(v8::Isolate*, V8InspectorClient*); | 
 |   virtual ~V8Inspector() = default; | 
 |  | 
 |   // Exposed so Cobalt's debugger can have a hybrid implementation using | 
 |   // JavaScript without it showing up as debuggable source in DevTools. | 
 |   virtual v8::MaybeLocal<v8::Value> compileAndRunInternalScript( | 
 |       v8::Local<v8::Context>, v8::Local<v8::String>) = 0; | 
 |  | 
 |   // Contexts instrumentation. | 
 |   virtual void contextCreated(const V8ContextInfo&) = 0; | 
 |   virtual void contextDestroyed(v8::Local<v8::Context>) = 0; | 
 |   virtual void resetContextGroup(int contextGroupId) = 0; | 
 |   virtual v8::MaybeLocal<v8::Context> contextById(int contextId) = 0; | 
 |  | 
 |   // Various instrumentation. | 
 |   virtual void idleStarted() = 0; | 
 |   virtual void idleFinished() = 0; | 
 |  | 
 |   // Async stack traces instrumentation. | 
 |   virtual void asyncTaskScheduled(StringView taskName, void* task, | 
 |                                   bool recurring) = 0; | 
 |   virtual void asyncTaskCanceled(void* task) = 0; | 
 |   virtual void asyncTaskStarted(void* task) = 0; | 
 |   virtual void asyncTaskFinished(void* task) = 0; | 
 |   virtual void allAsyncTasksCanceled() = 0; | 
 |  | 
 |   virtual V8StackTraceId storeCurrentStackTrace(StringView description) = 0; | 
 |   virtual void externalAsyncTaskStarted(const V8StackTraceId& parent) = 0; | 
 |   virtual void externalAsyncTaskFinished(const V8StackTraceId& parent) = 0; | 
 |  | 
 |   // Exceptions instrumentation. | 
 |   virtual unsigned exceptionThrown(v8::Local<v8::Context>, StringView message, | 
 |                                    v8::Local<v8::Value> exception, | 
 |                                    StringView detailedMessage, StringView url, | 
 |                                    unsigned lineNumber, unsigned columnNumber, | 
 |                                    std::unique_ptr<V8StackTrace>, | 
 |                                    int scriptId) = 0; | 
 |   virtual void exceptionRevoked(v8::Local<v8::Context>, unsigned exceptionId, | 
 |                                 StringView message) = 0; | 
 |  | 
 |   // Connection. | 
 |   class V8_EXPORT Channel { | 
 |    public: | 
 |     virtual ~Channel() = default; | 
 |     virtual void sendResponse(int callId, | 
 |                               std::unique_ptr<StringBuffer> message) = 0; | 
 |     virtual void sendNotification(std::unique_ptr<StringBuffer> message) = 0; | 
 |     virtual void flushProtocolNotifications() = 0; | 
 |   }; | 
 |   virtual std::unique_ptr<V8InspectorSession> connect(int contextGroupId, | 
 |                                                       Channel*, | 
 |                                                       StringView state) = 0; | 
 |  | 
 |   // API methods. | 
 |   virtual std::unique_ptr<V8StackTrace> createStackTrace( | 
 |       v8::Local<v8::StackTrace>) = 0; | 
 |   virtual std::unique_ptr<V8StackTrace> captureStackTrace(bool fullStack) = 0; | 
 |  | 
 |   // Performance counters. | 
 |   class V8_EXPORT Counters : public std::enable_shared_from_this<Counters> { | 
 |    public: | 
 |     explicit Counters(v8::Isolate* isolate); | 
 |     ~Counters(); | 
 |     const std::unordered_map<std::string, int>& getCountersMap() const { | 
 |       return m_countersMap; | 
 |     } | 
 |  | 
 |    private: | 
 |     static int* getCounterPtr(const char* name); | 
 |  | 
 |     v8::Isolate* m_isolate; | 
 |     std::unordered_map<std::string, int> m_countersMap; | 
 |   }; | 
 |  | 
 |   virtual std::shared_ptr<Counters> enableCounters() = 0; | 
 | }; | 
 |  | 
 | }  // namespace v8_inspector | 
 |  | 
 | #endif  // V8_V8_INSPECTOR_H_ |