1/*
2 * Copyright (c) 2010, Google Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 *     * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *     * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 *     * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#ifndef V8_INSPECTOR_V8_INSPECTOR_IMPL_H_
32#define V8_INSPECTOR_V8_INSPECTOR_IMPL_H_
33
34#include <functional>
35#include <map>
36#include <memory>
37#include <unordered_map>
38
39#include "include/v8-inspector.h"
40#include "src/base/macros.h"
41#include "src/base/platform/mutex.h"
42#include "src/inspector/injected-script.h"
43#include "src/inspector/protocol/Protocol.h"
44
45namespace v8_inspector {
46
47class InspectedContext;
48class V8Console;
49class V8ConsoleMessageStorage;
50class V8Debugger;
51class V8DebuggerAgentImpl;
52class V8InspectorSessionImpl;
53class V8ProfilerAgentImpl;
54class V8RuntimeAgentImpl;
55class V8StackTraceImpl;
56
57class V8InspectorImpl : public V8Inspector {
58 public:
59  V8_EXPORT_PRIVATE V8InspectorImpl(v8::Isolate*, V8InspectorClient*);
60  ~V8InspectorImpl() override;
61  V8InspectorImpl(const V8InspectorImpl&) = delete;
62  V8InspectorImpl& operator=(const V8InspectorImpl&) = delete;
63
64  v8::Isolate* isolate() const { return m_isolate; }
65  V8InspectorClient* client() { return m_client; }
66  V8Debugger* debugger() { return m_debugger.get(); }
67  int contextGroupId(v8::Local<v8::Context>) const;
68  int contextGroupId(int contextId) const;
69  uint64_t isolateId() const { return m_isolateId; }
70  int resolveUniqueContextId(internal::V8DebuggerId uniqueId) const;
71
72  v8::MaybeLocal<v8::Value> compileAndRunInternalScript(v8::Local<v8::Context>,
73                                                        v8::Local<v8::String>);
74  v8::MaybeLocal<v8::Script> compileScript(v8::Local<v8::Context>,
75                                           const String16& code,
76                                           const String16& fileName);
77  v8::MaybeLocal<v8::Context> regexContext();
78  v8::MaybeLocal<v8::Context> exceptionMetaDataContext();
79
80  // V8Inspector implementation.
81  std::unique_ptr<V8InspectorSession> connect(int contextGroupId,
82                                              V8Inspector::Channel*,
83                                              StringView state) override;
84  void contextCreated(const V8ContextInfo&) override;
85  void contextDestroyed(v8::Local<v8::Context>) override;
86  v8::MaybeLocal<v8::Context> contextById(int contextId) override;
87  V8DebuggerId uniqueDebuggerId(int contextId) override;
88  void contextCollected(int contextGroupId, int contextId);
89  void resetContextGroup(int contextGroupId) override;
90  void idleStarted() override;
91  void idleFinished() override;
92  unsigned exceptionThrown(v8::Local<v8::Context>, StringView message,
93                           v8::Local<v8::Value> exception,
94                           StringView detailedMessage, StringView url,
95                           unsigned lineNumber, unsigned columnNumber,
96                           std::unique_ptr<V8StackTrace>,
97                           int scriptId) override;
98  void exceptionRevoked(v8::Local<v8::Context>, unsigned exceptionId,
99                        StringView message) override;
100  std::unique_ptr<V8StackTrace> createStackTrace(
101      v8::Local<v8::StackTrace>) override;
102  std::unique_ptr<V8StackTrace> captureStackTrace(bool fullStack) override;
103  void asyncTaskScheduled(StringView taskName, void* task,
104                          bool recurring) override;
105  void asyncTaskCanceled(void* task) override;
106  void asyncTaskStarted(void* task) override;
107  void asyncTaskFinished(void* task) override;
108  void allAsyncTasksCanceled() override;
109
110  V8StackTraceId storeCurrentStackTrace(StringView description) override;
111  void externalAsyncTaskStarted(const V8StackTraceId& parent) override;
112  void externalAsyncTaskFinished(const V8StackTraceId& parent) override;
113
114  V8_EXPORT_PRIVATE bool associateExceptionData(
115      v8::Local<v8::Context>, v8::Local<v8::Value> exception,
116      v8::Local<v8::Name> key, v8::Local<v8::Value> value) override;
117
118  unsigned nextExceptionId() { return ++m_lastExceptionId; }
119  void muteExceptions(int contextGroupId);
120  void unmuteExceptions(int contextGroupId);
121  V8ConsoleMessageStorage* ensureConsoleMessageStorage(int contextGroupId);
122  bool hasConsoleMessageStorage(int contextGroupId);
123  void discardInspectedContext(int contextGroupId, int contextId);
124  void disconnect(V8InspectorSessionImpl*);
125  V8InspectorSessionImpl* sessionById(int contextGroupId, int sessionId);
126  InspectedContext* getContext(int groupId, int contextId) const;
127  InspectedContext* getContext(int contextId) const;
128  V8Console* console();
129  void forEachContext(int contextGroupId,
130                      const std::function<void(InspectedContext*)>& callback);
131  void forEachSession(
132      int contextGroupId,
133      const std::function<void(V8InspectorSessionImpl*)>& callback);
134  int64_t generateUniqueId();
135  V8_EXPORT_PRIVATE v8::MaybeLocal<v8::Object> getAssociatedExceptionData(
136      v8::Local<v8::Value> exception);
137  std::unique_ptr<protocol::DictionaryValue>
138  getAssociatedExceptionDataForProtocol(v8::Local<v8::Value> exception);
139
140  class EvaluateScope {
141   public:
142    explicit EvaluateScope(const InjectedScript::Scope& scope);
143    ~EvaluateScope();
144
145    protocol::Response setTimeout(double timeout);
146
147   private:
148    class TerminateTask;
149    struct CancelToken;
150
151    const InjectedScript::Scope& m_scope;
152    v8::Isolate* m_isolate;
153    std::shared_ptr<CancelToken> m_cancelToken;
154    v8::Isolate::SafeForTerminationScope m_safeForTerminationScope;
155  };
156
157 private:
158  v8::Isolate* m_isolate;
159  V8InspectorClient* m_client;
160  std::unique_ptr<V8Debugger> m_debugger;
161  v8::Global<v8::Context> m_regexContext;
162  v8::Global<v8::Context> m_exceptionMetaDataContext;
163  v8::Global<v8::debug::EphemeronTable> m_exceptionMetaData;
164  unsigned m_lastExceptionId;
165  int m_lastContextId;
166  int m_lastSessionId = 0;
167  uint64_t m_isolateId;
168
169  using MuteExceptionsMap = std::unordered_map<int, int>;
170  MuteExceptionsMap m_muteExceptionsMap;
171
172  using ContextByIdMap =
173      std::unordered_map<int, std::unique_ptr<InspectedContext>>;
174  using ContextsByGroupMap =
175      std::unordered_map<int, std::unique_ptr<ContextByIdMap>>;
176  ContextsByGroupMap m_contexts;
177
178  // contextGroupId -> sessionId -> session
179  std::unordered_map<int, std::map<int, V8InspectorSessionImpl*>> m_sessions;
180
181  using ConsoleStorageMap =
182      std::unordered_map<int, std::unique_ptr<V8ConsoleMessageStorage>>;
183  ConsoleStorageMap m_consoleStorageMap;
184
185  std::unordered_map<int, int> m_contextIdToGroupIdMap;
186  std::map<std::pair<int64_t, int64_t>, int> m_uniqueIdToContextId;
187
188  std::unique_ptr<V8Console> m_console;
189};
190
191}  // namespace v8_inspector
192
193#endif  // V8_INSPECTOR_V8_INSPECTOR_IMPL_H_
194