• 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_DEBUG_DEBUG_INTERFACE_H_
6 #define V8_DEBUG_DEBUG_INTERFACE_H_
7 
8 #include "include/v8-inspector.h"
9 #include "include/v8-util.h"
10 #include "include/v8.h"
11 
12 #include "src/debug/interface-types.h"
13 #include "src/globals.h"
14 
15 namespace v8 {
16 
17 namespace internal {
18 struct CoverageBlock;
19 struct CoverageFunction;
20 struct CoverageScript;
21 struct TypeProfileEntry;
22 struct TypeProfileScript;
23 class Coverage;
24 class PostponeInterruptsScope;
25 class Script;
26 class TypeProfile;
27 }  // namespace internal
28 
29 namespace debug {
30 
31 void SetContextId(Local<Context> context, int id);
32 int GetContextId(Local<Context> context);
33 
34 void SetInspector(Isolate* isolate, v8_inspector::V8Inspector*);
35 v8_inspector::V8Inspector* GetInspector(Isolate* isolate);
36 
37 // Schedule a debugger break to happen when function is called inside given
38 // isolate.
39 void SetBreakOnNextFunctionCall(Isolate* isolate);
40 
41 // Remove scheduled debugger break in given isolate if it has not
42 // happened yet.
43 void ClearBreakOnNextFunctionCall(Isolate* isolate);
44 
45 /**
46  * Returns array of internal properties specific to the value type. Result has
47  * the following format: [<name>, <value>,...,<name>, <value>]. Result array
48  * will be allocated in the current context.
49  */
50 MaybeLocal<Array> GetInternalProperties(Isolate* isolate, Local<Value> value);
51 
52 enum ExceptionBreakState {
53   NoBreakOnException = 0,
54   BreakOnUncaughtException = 1,
55   BreakOnAnyException = 2
56 };
57 
58 /**
59  * Defines if VM will pause on exceptions or not.
60  * If BreakOnAnyExceptions is set then VM will pause on caught and uncaught
61  * exception, if BreakOnUncaughtException is set then VM will pause only on
62  * uncaught exception, otherwise VM won't stop on any exception.
63  */
64 void ChangeBreakOnException(Isolate* isolate, ExceptionBreakState state);
65 
66 void RemoveBreakpoint(Isolate* isolate, BreakpointId id);
67 void SetBreakPointsActive(Isolate* isolate, bool is_active);
68 
69 enum StepAction {
70   StepOut = 0,   // Step out of the current function.
71   StepNext = 1,  // Step to the next statement in the current function.
72   StepIn = 2     // Step into new functions invoked or the next statement
73                  // in the current function.
74 };
75 
76 void PrepareStep(Isolate* isolate, StepAction action);
77 void ClearStepping(Isolate* isolate);
78 void BreakRightNow(Isolate* isolate);
79 
80 bool AllFramesOnStackAreBlackboxed(Isolate* isolate);
81 
82 class Script;
83 
84 struct LiveEditResult {
85   enum Status {
86     OK,
87     COMPILE_ERROR,
88     BLOCKED_BY_RUNNING_GENERATOR,
89     BLOCKED_BY_FUNCTION_ABOVE_BREAK_FRAME,
90     BLOCKED_BY_FUNCTION_BELOW_NON_DROPPABLE_FRAME,
91     BLOCKED_BY_ACTIVE_FUNCTION,
92     BLOCKED_BY_NEW_TARGET_IN_RESTART_FRAME,
93     FRAME_RESTART_IS_NOT_SUPPORTED
94   };
95   Status status = OK;
96   bool stack_changed = false;
97   // Available only for OK.
98   v8::Local<v8::debug::Script> script;
99   // Fields below are available only for COMPILE_ERROR.
100   v8::Local<v8::String> message;
101   int line_number = -1;
102   int column_number = -1;
103 };
104 
105 /**
106  * Native wrapper around v8::internal::Script object.
107  */
108 class V8_EXPORT_PRIVATE Script {
109  public:
110   v8::Isolate* GetIsolate() const;
111 
112   ScriptOriginOptions OriginOptions() const;
113   bool WasCompiled() const;
114   bool IsEmbedded() const;
115   int Id() const;
116   int LineOffset() const;
117   int ColumnOffset() const;
118   std::vector<int> LineEnds() const;
119   MaybeLocal<String> Name() const;
120   MaybeLocal<String> SourceURL() const;
121   MaybeLocal<String> SourceMappingURL() const;
122   Maybe<int> ContextId() const;
123   MaybeLocal<String> Source() const;
124   bool IsWasm() const;
125   bool IsModule() const;
126   bool GetPossibleBreakpoints(
127       const debug::Location& start, const debug::Location& end,
128       bool restrict_to_function,
129       std::vector<debug::BreakLocation>* locations) const;
130   int GetSourceOffset(const debug::Location& location) const;
131   v8::debug::Location GetSourceLocation(int offset) const;
132   bool SetScriptSource(v8::Local<v8::String> newSource, bool preview,
133                        LiveEditResult* result) const;
134   bool SetBreakpoint(v8::Local<v8::String> condition, debug::Location* location,
135                      BreakpointId* id) const;
136 };
137 
138 // Specialization for wasm Scripts.
139 class WasmScript : public Script {
140  public:
141   static WasmScript* Cast(Script* script);
142 
143   int NumFunctions() const;
144   int NumImportedFunctions() const;
145 
146   std::pair<int, int> GetFunctionRange(int function_index) const;
147 
148   debug::WasmDisassembly DisassembleFunction(int function_index) const;
149   uint32_t GetFunctionHash(int function_index);
150 };
151 
152 void GetLoadedScripts(Isolate* isolate, PersistentValueVector<Script>& scripts);
153 
154 MaybeLocal<UnboundScript> CompileInspectorScript(Isolate* isolate,
155                                                  Local<String> source);
156 
157 class DebugDelegate {
158  public:
~DebugDelegate()159   virtual ~DebugDelegate() {}
ScriptCompiled(v8::Local<Script> script,bool is_live_edited,bool has_compile_error)160   virtual void ScriptCompiled(v8::Local<Script> script, bool is_live_edited,
161                               bool has_compile_error) {}
162   // |inspector_break_points_hit| contains id of breakpoints installed with
163   // debug::Script::SetBreakpoint API.
BreakProgramRequested(v8::Local<v8::Context> paused_context,const std::vector<debug::BreakpointId> & inspector_break_points_hit)164   virtual void BreakProgramRequested(
165       v8::Local<v8::Context> paused_context,
166       const std::vector<debug::BreakpointId>& inspector_break_points_hit) {}
ExceptionThrown(v8::Local<v8::Context> paused_context,v8::Local<v8::Value> exception,v8::Local<v8::Value> promise,bool is_uncaught)167   virtual void ExceptionThrown(v8::Local<v8::Context> paused_context,
168                                v8::Local<v8::Value> exception,
169                                v8::Local<v8::Value> promise, bool is_uncaught) {
170   }
IsFunctionBlackboxed(v8::Local<debug::Script> script,const debug::Location & start,const debug::Location & end)171   virtual bool IsFunctionBlackboxed(v8::Local<debug::Script> script,
172                                     const debug::Location& start,
173                                     const debug::Location& end) {
174     return false;
175   }
176 };
177 
178 void SetDebugDelegate(Isolate* isolate, DebugDelegate* listener);
179 
180 class AsyncEventDelegate {
181  public:
~AsyncEventDelegate()182   virtual ~AsyncEventDelegate() {}
183   virtual void AsyncEventOccurred(debug::DebugAsyncActionType type, int id,
184                                   bool is_blackboxed) = 0;
185 };
186 
187 void SetAsyncEventDelegate(Isolate* isolate, AsyncEventDelegate* delegate);
188 
189 void ResetBlackboxedStateCache(Isolate* isolate,
190                                v8::Local<debug::Script> script);
191 
192 int EstimatedValueSize(Isolate* isolate, v8::Local<v8::Value> value);
193 
194 enum Builtin {
195   kObjectKeys,
196   kObjectGetPrototypeOf,
197   kObjectGetOwnPropertyDescriptor,
198   kObjectGetOwnPropertyNames,
199   kObjectGetOwnPropertySymbols,
200 };
201 
202 Local<Function> GetBuiltin(Isolate* isolate, Builtin builtin);
203 
204 V8_EXPORT_PRIVATE void SetConsoleDelegate(Isolate* isolate,
205                                           ConsoleDelegate* delegate);
206 
207 int GetStackFrameId(v8::Local<v8::StackFrame> frame);
208 
209 v8::Local<v8::StackTrace> GetDetailedStackTrace(Isolate* isolate,
210                                                 v8::Local<v8::Object> error);
211 
212 /**
213  * Native wrapper around v8::internal::JSGeneratorObject object.
214  */
215 class GeneratorObject {
216  public:
217   v8::MaybeLocal<debug::Script> Script();
218   v8::Local<v8::Function> Function();
219   debug::Location SuspendedLocation();
220   bool IsSuspended();
221 
222   static v8::Local<debug::GeneratorObject> Cast(v8::Local<v8::Value> value);
223 };
224 
225 /*
226  * Provide API layer between inspector and code coverage.
227  */
228 class V8_EXPORT_PRIVATE Coverage {
229  public:
230   MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(Coverage);
231 
232   enum Mode {
233     // Make use of existing information in feedback vectors on the heap.
234     // Only return a yes/no result. Optimization and GC are not affected.
235     // Collecting best effort coverage does not reset counters.
236     kBestEffort,
237     // Disable optimization and prevent feedback vectors from being garbage
238     // collected in order to preserve precise invocation counts. Collecting
239     // precise count coverage resets counters to get incremental updates.
240     kPreciseCount,
241     // We are only interested in a yes/no result for the function. Optimization
242     // and GC can be allowed once a function has been invoked. Collecting
243     // precise binary coverage resets counters for incremental updates.
244     kPreciseBinary,
245     // Similar to the precise coverage modes but provides coverage at a
246     // lower granularity. Design doc: goo.gl/lA2swZ.
247     kBlockCount,
248     kBlockBinary,
249   };
250 
251   // Forward declarations.
252   class ScriptData;
253   class FunctionData;
254 
255   class V8_EXPORT_PRIVATE BlockData {
256    public:
257     MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(BlockData);
258 
259     int StartOffset() const;
260     int EndOffset() const;
261     uint32_t Count() const;
262 
263    private:
BlockData(i::CoverageBlock * block,std::shared_ptr<i::Coverage> coverage)264     explicit BlockData(i::CoverageBlock* block,
265                        std::shared_ptr<i::Coverage> coverage)
266         : block_(block), coverage_(std::move(coverage)) {}
267 
268     i::CoverageBlock* block_;
269     std::shared_ptr<i::Coverage> coverage_;
270 
271     friend class v8::debug::Coverage::FunctionData;
272   };
273 
274   class V8_EXPORT_PRIVATE FunctionData {
275    public:
276     MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(FunctionData);
277 
278     int StartOffset() const;
279     int EndOffset() const;
280     uint32_t Count() const;
281     MaybeLocal<String> Name() const;
282     size_t BlockCount() const;
283     bool HasBlockCoverage() const;
284     BlockData GetBlockData(size_t i) const;
285 
286    private:
FunctionData(i::CoverageFunction * function,std::shared_ptr<i::Coverage> coverage)287     explicit FunctionData(i::CoverageFunction* function,
288                           std::shared_ptr<i::Coverage> coverage)
289         : function_(function), coverage_(std::move(coverage)) {}
290 
291     i::CoverageFunction* function_;
292     std::shared_ptr<i::Coverage> coverage_;
293 
294     friend class v8::debug::Coverage::ScriptData;
295   };
296 
297   class V8_EXPORT_PRIVATE ScriptData {
298    public:
299     MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(ScriptData);
300 
301     Local<debug::Script> GetScript() const;
302     size_t FunctionCount() const;
303     FunctionData GetFunctionData(size_t i) const;
304 
305    private:
306     explicit ScriptData(size_t index, std::shared_ptr<i::Coverage> c);
307 
308     i::CoverageScript* script_;
309     std::shared_ptr<i::Coverage> coverage_;
310 
311     friend class v8::debug::Coverage;
312   };
313 
314   static Coverage CollectPrecise(Isolate* isolate);
315   static Coverage CollectBestEffort(Isolate* isolate);
316 
317   static void SelectMode(Isolate* isolate, Mode mode);
318 
319   size_t ScriptCount() const;
320   ScriptData GetScriptData(size_t i) const;
IsEmpty()321   bool IsEmpty() const { return coverage_ == nullptr; }
322 
323  private:
Coverage(std::shared_ptr<i::Coverage> coverage)324   explicit Coverage(std::shared_ptr<i::Coverage> coverage)
325       : coverage_(std::move(coverage)) {}
326   std::shared_ptr<i::Coverage> coverage_;
327 };
328 
329 /*
330  * Provide API layer between inspector and type profile.
331  */
332 class V8_EXPORT_PRIVATE TypeProfile {
333  public:
334   MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeProfile);
335 
336   enum Mode {
337     kNone,
338     kCollect,
339   };
340   class ScriptData;  // Forward declaration.
341 
342   class V8_EXPORT_PRIVATE Entry {
343    public:
344     MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(Entry);
345 
346     int SourcePosition() const;
347     std::vector<MaybeLocal<String>> Types() const;
348 
349    private:
Entry(const i::TypeProfileEntry * entry,std::shared_ptr<i::TypeProfile> type_profile)350     explicit Entry(const i::TypeProfileEntry* entry,
351                    std::shared_ptr<i::TypeProfile> type_profile)
352         : entry_(entry), type_profile_(std::move(type_profile)) {}
353 
354     const i::TypeProfileEntry* entry_;
355     std::shared_ptr<i::TypeProfile> type_profile_;
356 
357     friend class v8::debug::TypeProfile::ScriptData;
358   };
359 
360   class V8_EXPORT_PRIVATE ScriptData {
361    public:
362     MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(ScriptData);
363 
364     Local<debug::Script> GetScript() const;
365     std::vector<Entry> Entries() const;
366 
367    private:
368     explicit ScriptData(size_t index,
369                         std::shared_ptr<i::TypeProfile> type_profile);
370 
371     i::TypeProfileScript* script_;
372     std::shared_ptr<i::TypeProfile> type_profile_;
373 
374     friend class v8::debug::TypeProfile;
375   };
376 
377   static TypeProfile Collect(Isolate* isolate);
378 
379   static void SelectMode(Isolate* isolate, Mode mode);
380 
381   size_t ScriptCount() const;
382   ScriptData GetScriptData(size_t i) const;
383 
384  private:
TypeProfile(std::shared_ptr<i::TypeProfile> type_profile)385   explicit TypeProfile(std::shared_ptr<i::TypeProfile> type_profile)
386       : type_profile_(std::move(type_profile)) {}
387 
388   std::shared_ptr<i::TypeProfile> type_profile_;
389 };
390 
391 class ScopeIterator {
392  public:
393   static std::unique_ptr<ScopeIterator> CreateForFunction(
394       v8::Isolate* isolate, v8::Local<v8::Function> func);
395   static std::unique_ptr<ScopeIterator> CreateForGeneratorObject(
396       v8::Isolate* isolate, v8::Local<v8::Object> generator);
397 
398   ScopeIterator() = default;
399   virtual ~ScopeIterator() = default;
400 
401   enum ScopeType {
402     ScopeTypeGlobal = 0,
403     ScopeTypeLocal,
404     ScopeTypeWith,
405     ScopeTypeClosure,
406     ScopeTypeCatch,
407     ScopeTypeBlock,
408     ScopeTypeScript,
409     ScopeTypeEval,
410     ScopeTypeModule
411   };
412 
413   virtual bool Done() = 0;
414   virtual void Advance() = 0;
415   virtual ScopeType GetType() = 0;
416   virtual v8::Local<v8::Object> GetObject() = 0;
417   virtual v8::Local<v8::Value> GetFunctionDebugName() = 0;
418   virtual int GetScriptId() = 0;
419   virtual bool HasLocationInfo() = 0;
420   virtual debug::Location GetStartLocation() = 0;
421   virtual debug::Location GetEndLocation() = 0;
422 
423   virtual bool SetVariableValue(v8::Local<v8::String> name,
424                                 v8::Local<v8::Value> value) = 0;
425 
426  private:
427   DISALLOW_COPY_AND_ASSIGN(ScopeIterator);
428 };
429 
430 class StackTraceIterator {
431  public:
432   static std::unique_ptr<StackTraceIterator> Create(Isolate* isolate,
433                                                     int index = 0);
434   StackTraceIterator() = default;
435   virtual ~StackTraceIterator() = default;
436 
437   virtual bool Done() const = 0;
438   virtual void Advance() = 0;
439 
440   virtual int GetContextId() const = 0;
441   virtual v8::MaybeLocal<v8::Value> GetReceiver() const = 0;
442   virtual v8::Local<v8::Value> GetReturnValue() const = 0;
443   virtual v8::Local<v8::String> GetFunctionDebugName() const = 0;
444   virtual v8::Local<v8::debug::Script> GetScript() const = 0;
445   virtual debug::Location GetSourceLocation() const = 0;
446   virtual v8::Local<v8::Function> GetFunction() const = 0;
447   virtual std::unique_ptr<ScopeIterator> GetScopeIterator() const = 0;
448 
449   virtual bool Restart() = 0;
450   virtual v8::MaybeLocal<v8::Value> Evaluate(v8::Local<v8::String> source,
451                                              bool throw_on_side_effect) = 0;
452 
453  private:
454   DISALLOW_COPY_AND_ASSIGN(StackTraceIterator);
455 };
456 
457 class QueryObjectPredicate {
458  public:
459   virtual ~QueryObjectPredicate() = default;
460   virtual bool Filter(v8::Local<v8::Object> object) = 0;
461 };
462 
463 void QueryObjects(v8::Local<v8::Context> context,
464                   QueryObjectPredicate* predicate,
465                   v8::PersistentValueVector<v8::Object>* objects);
466 
467 void GlobalLexicalScopeNames(v8::Local<v8::Context> context,
468                              v8::PersistentValueVector<v8::String>* names);
469 
470 void SetReturnValue(v8::Isolate* isolate, v8::Local<v8::Value> value);
471 
472 enum class NativeAccessorType {
473   None = 0,
474   HasGetter = 1 << 0,
475   HasSetter = 1 << 1,
476   IsBuiltin = 1 << 2
477 };
478 
479 int GetNativeAccessorDescriptor(v8::Local<v8::Context> context,
480                                 v8::Local<v8::Object> object,
481                                 v8::Local<v8::Name> name);
482 
483 int64_t GetNextRandomInt64(v8::Isolate* isolate);
484 
485 v8::MaybeLocal<v8::Value> EvaluateGlobal(v8::Isolate* isolate,
486                                          v8::Local<v8::String> source,
487                                          bool throw_on_side_effect);
488 
489 int GetDebuggingId(v8::Local<v8::Function> function);
490 
491 bool SetFunctionBreakpoint(v8::Local<v8::Function> function,
492                            v8::Local<v8::String> condition, BreakpointId* id);
493 
494 v8::Platform* GetCurrentPlatform();
495 
496 class PostponeInterruptsScope {
497  public:
498   explicit PostponeInterruptsScope(v8::Isolate* isolate);
499   ~PostponeInterruptsScope();
500 
501  private:
502   std::unique_ptr<i::PostponeInterruptsScope> scope_;
503 };
504 
505 }  // namespace debug
506 }  // namespace v8
507 
508 #endif  // V8_DEBUG_DEBUG_INTERFACE_H_
509