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