• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_INSPECTOR_V8_CONSOLE_H_
6 #define V8_INSPECTOR_V8_CONSOLE_H_
7 
8 #include <map>
9 
10 #include "include/v8-array-buffer.h"
11 #include "include/v8-external.h"
12 #include "include/v8-local-handle.h"
13 #include "src/base/macros.h"
14 #include "src/debug/interface-types.h"
15 
16 namespace v8 {
17 class Set;
18 }  // namespace v8
19 
20 namespace v8_inspector {
21 
22 class InspectedContext;
23 class V8InspectorImpl;
24 
25 // Console API
26 // https://console.spec.whatwg.org/#console-namespace
27 class V8Console : public v8::debug::ConsoleDelegate {
28  public:
29   v8::Local<v8::Object> createCommandLineAPI(v8::Local<v8::Context> context,
30                                              int sessionId);
31   void installMemoryGetter(v8::Local<v8::Context> context,
32                            v8::Local<v8::Object> console);
33   void installAsyncStackTaggingAPI(v8::Local<v8::Context> context,
34                                    v8::Local<v8::Object> console);
35 
36   class V8_NODISCARD CommandLineAPIScope {
37    public:
38     CommandLineAPIScope(v8::Local<v8::Context>,
39                         v8::Local<v8::Object> commandLineAPI,
40                         v8::Local<v8::Object> global);
41     ~CommandLineAPIScope();
42     CommandLineAPIScope(const CommandLineAPIScope&) = delete;
43     CommandLineAPIScope& operator=(const CommandLineAPIScope&) = delete;
44 
45    private:
46     static void accessorGetterCallback(
47         v8::Local<v8::Name>, const v8::PropertyCallbackInfo<v8::Value>&);
48     static void accessorSetterCallback(v8::Local<v8::Name>,
49                                        v8::Local<v8::Value>,
50                                        const v8::PropertyCallbackInfo<void>&);
51 
52     v8::Local<v8::Context> m_context;
53     v8::Local<v8::Object> m_commandLineAPI;
54     v8::Local<v8::Object> m_global;
55     v8::Local<v8::Set> m_installedMethods;
56     v8::Local<v8::ArrayBuffer> m_thisReference;
57   };
58 
59   struct AsyncTaskInfo {
60     int* ptr;
61     bool recurring;
62   };
63 
64   explicit V8Console(V8InspectorImpl* inspector);
65 
66  private:
67   void Debug(const v8::debug::ConsoleCallArguments&,
68              const v8::debug::ConsoleContext& consoleContext) override;
69   void Error(const v8::debug::ConsoleCallArguments&,
70              const v8::debug::ConsoleContext& consoleContext) override;
71   void Info(const v8::debug::ConsoleCallArguments&,
72             const v8::debug::ConsoleContext& consoleContext) override;
73   void Log(const v8::debug::ConsoleCallArguments&,
74            const v8::debug::ConsoleContext& consoleContext) override;
75   void Warn(const v8::debug::ConsoleCallArguments&,
76             const v8::debug::ConsoleContext& consoleContext) override;
77   void Dir(const v8::debug::ConsoleCallArguments&,
78            const v8::debug::ConsoleContext& consoleContext) override;
79   void DirXml(const v8::debug::ConsoleCallArguments&,
80               const v8::debug::ConsoleContext& consoleContext) override;
81   void Table(const v8::debug::ConsoleCallArguments&,
82              const v8::debug::ConsoleContext& consoleContext) override;
83   void Trace(const v8::debug::ConsoleCallArguments&,
84              const v8::debug::ConsoleContext& consoleContext) override;
85   void Group(const v8::debug::ConsoleCallArguments&,
86              const v8::debug::ConsoleContext& consoleContext) override;
87   void GroupCollapsed(const v8::debug::ConsoleCallArguments&,
88                       const v8::debug::ConsoleContext& consoleContext) override;
89   void GroupEnd(const v8::debug::ConsoleCallArguments&,
90                 const v8::debug::ConsoleContext& consoleContext) override;
91   void Clear(const v8::debug::ConsoleCallArguments&,
92              const v8::debug::ConsoleContext& consoleContext) override;
93   void Count(const v8::debug::ConsoleCallArguments&,
94              const v8::debug::ConsoleContext& consoleContext) override;
95   void CountReset(const v8::debug::ConsoleCallArguments&,
96                   const v8::debug::ConsoleContext& consoleContext) override;
97   void Assert(const v8::debug::ConsoleCallArguments&,
98               const v8::debug::ConsoleContext& consoleContext) override;
99   void Profile(const v8::debug::ConsoleCallArguments&,
100                const v8::debug::ConsoleContext& consoleContext) override;
101   void ProfileEnd(const v8::debug::ConsoleCallArguments&,
102                   const v8::debug::ConsoleContext& consoleContext) override;
103   void Time(const v8::debug::ConsoleCallArguments&,
104             const v8::debug::ConsoleContext& consoleContext) override;
105   void TimeLog(const v8::debug::ConsoleCallArguments&,
106                const v8::debug::ConsoleContext& consoleContext) override;
107   void TimeEnd(const v8::debug::ConsoleCallArguments&,
108                const v8::debug::ConsoleContext& consoleContext) override;
109   void TimeStamp(const v8::debug::ConsoleCallArguments&,
110                  const v8::debug::ConsoleContext& consoleContext) override;
111 
112   template <void (V8Console::*func)(const v8::FunctionCallbackInfo<v8::Value>&)>
call(const v8::FunctionCallbackInfo<v8::Value> & info)113   static void call(const v8::FunctionCallbackInfo<v8::Value>& info) {
114     V8Console* console =
115         static_cast<V8Console*>(info.Data().As<v8::External>()->Value());
116     (console->*func)(info);
117   }
118   using CommandLineAPIData = std::pair<V8Console*, int>;
119   template <void (V8Console::*func)(const v8::FunctionCallbackInfo<v8::Value>&,
120                                     int)>
call(const v8::FunctionCallbackInfo<v8::Value> & info)121   static void call(const v8::FunctionCallbackInfo<v8::Value>& info) {
122     CommandLineAPIData* data = static_cast<CommandLineAPIData*>(
123         info.Data().As<v8::ArrayBuffer>()->GetBackingStore()->Data());
124     (data->first->*func)(info, data->second);
125   }
126   template <void (V8Console::*func)(const v8::debug::ConsoleCallArguments&,
127                                     const v8::debug::ConsoleContext&)>
call(const v8::FunctionCallbackInfo<v8::Value> & info)128   static void call(const v8::FunctionCallbackInfo<v8::Value>& info) {
129     CommandLineAPIData* data = static_cast<CommandLineAPIData*>(
130         info.Data().As<v8::ArrayBuffer>()->GetBackingStore()->Data());
131     v8::debug::ConsoleCallArguments args(info);
132     (data->first->*func)(args, v8::debug::ConsoleContext());
133   }
134 
135   // TODO(foolip): There is no spec for the Memory Info API, see blink-dev:
136   // https://groups.google.com/a/chromium.org/d/msg/blink-dev/g5YRCGpC9vs/b4OJz71NmPwJ
137   void memoryGetterCallback(const v8::FunctionCallbackInfo<v8::Value>&);
138   void memorySetterCallback(const v8::FunctionCallbackInfo<v8::Value>&);
139 
140   v8::Maybe<int64_t> ValidateAndGetTaskId(
141       const v8::FunctionCallbackInfo<v8::Value>&);
142   void scheduleAsyncTask(const v8::FunctionCallbackInfo<v8::Value>&);
143   void startAsyncTask(const v8::FunctionCallbackInfo<v8::Value>&);
144   void finishAsyncTask(const v8::FunctionCallbackInfo<v8::Value>&);
145   void cancelAsyncTask(const v8::FunctionCallbackInfo<v8::Value>&);
146 
147   // CommandLineAPI
148   void keysCallback(const v8::FunctionCallbackInfo<v8::Value>&, int sessionId);
149   void valuesCallback(const v8::FunctionCallbackInfo<v8::Value>&,
150                       int sessionId);
151   void debugFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>&,
152                              int sessionId);
153   void undebugFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>&,
154                                int sessionId);
155   void monitorFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>&,
156                                int sessionId);
157   void unmonitorFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>&,
158                                  int sessionId);
159   void lastEvaluationResultCallback(const v8::FunctionCallbackInfo<v8::Value>&,
160                                     int sessionId);
161   void inspectCallback(const v8::FunctionCallbackInfo<v8::Value>&,
162                        int sessionId);
163   void copyCallback(const v8::FunctionCallbackInfo<v8::Value>&, int sessionId);
164   void inspectedObject(const v8::FunctionCallbackInfo<v8::Value>&,
165                        int sessionId, unsigned num);
inspectedObject0(const v8::FunctionCallbackInfo<v8::Value> & info,int sessionId)166   void inspectedObject0(const v8::FunctionCallbackInfo<v8::Value>& info,
167                         int sessionId) {
168     inspectedObject(info, sessionId, 0);
169   }
inspectedObject1(const v8::FunctionCallbackInfo<v8::Value> & info,int sessionId)170   void inspectedObject1(const v8::FunctionCallbackInfo<v8::Value>& info,
171                         int sessionId) {
172     inspectedObject(info, sessionId, 1);
173   }
inspectedObject2(const v8::FunctionCallbackInfo<v8::Value> & info,int sessionId)174   void inspectedObject2(const v8::FunctionCallbackInfo<v8::Value>& info,
175                         int sessionId) {
176     inspectedObject(info, sessionId, 2);
177   }
inspectedObject3(const v8::FunctionCallbackInfo<v8::Value> & info,int sessionId)178   void inspectedObject3(const v8::FunctionCallbackInfo<v8::Value>& info,
179                         int sessionId) {
180     inspectedObject(info, sessionId, 3);
181   }
inspectedObject4(const v8::FunctionCallbackInfo<v8::Value> & info,int sessionId)182   void inspectedObject4(const v8::FunctionCallbackInfo<v8::Value>& info,
183                         int sessionId) {
184     inspectedObject(info, sessionId, 4);
185   }
186   void queryObjectsCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
187                             int sessionId);
188 
189   V8InspectorImpl* m_inspector;
190 
191   // A map of unique pointers used for the scheduling and joining async stacks.
192   // The async stack traces instrumentation is exposed on the console object,
193   // behind a --experimental-async-stack-tagging-api flag. For now, it serves
194   // as a prototype that aims to validate whether the debugging experience can
195   // be improved for userland code that uses custom schedulers.
196   int64_t m_taskIdCounter = 0;
197   std::map<int64_t, AsyncTaskInfo> m_asyncTaskIds;
198 };
199 
200 }  // namespace v8_inspector
201 
202 #endif  // V8_INSPECTOR_V8_CONSOLE_H_
203