debug-interface.h 16.2 KB
Newer Older
1 2 3 4 5 6 7
// 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_DEBUG_DEBUG_INTERFACE_H_
#define V8_DEBUG_DEBUG_INTERFACE_H_

8
#include "include/v8-inspector.h"
9
#include "include/v8-util.h"
10 11
#include "include/v8.h"

12
#include "src/debug/interface-types.h"
13
#include "src/globals.h"
14

15
namespace v8 {
16 17

namespace internal {
18
struct CoverageBlock;
19 20
struct CoverageFunction;
struct CoverageScript;
21 22
struct TypeProfileEntry;
struct TypeProfileScript;
23
class Coverage;
24
class PostponeInterruptsScope;
25
class Script;
26 27
class TypeProfile;
}  // namespace internal
28

29
namespace debug {
30

31 32 33
void SetContextId(Local<Context> context, int id);
int GetContextId(Local<Context> context);

34 35 36
void SetInspector(Isolate* isolate, v8_inspector::V8Inspector*);
v8_inspector::V8Inspector* GetInspector(Isolate* isolate);

37 38
// Schedule a debugger break to happen when function is called inside given
// isolate.
39
V8_EXPORT_PRIVATE void SetBreakOnNextFunctionCall(Isolate* isolate);
40 41 42

// Remove scheduled debugger break in given isolate if it has not
// happened yet.
43
V8_EXPORT_PRIVATE void ClearBreakOnNextFunctionCall(Isolate* isolate);
44 45 46 47 48 49 50 51

/**
 * Returns array of internal properties specific to the value type. Result has
 * the following format: [<name>, <value>,...,<name>, <value>]. Result array
 * will be allocated in the current context.
 */
MaybeLocal<Array> GetInternalProperties(Isolate* isolate, Local<Value> value);

52 53 54 55 56
/**
 * Returns array of private fields specific to the value type. Result has
 * the following format: [<name>, <value>,...,<name>, <value>]. Result array
 * will be allocated in the current context.
 */
57 58
V8_EXPORT_PRIVATE MaybeLocal<Array> GetPrivateFields(Local<Context> context,
                                                     Local<Object> value);
59

60 61 62 63 64 65
/**
 * Forwards to v8::Object::CreationContext, but with special handling for
 * JSGlobalProxy objects.
 */
Local<Context> GetCreationContext(Local<Object> value);

66 67 68 69 70
enum ExceptionBreakState {
  NoBreakOnException = 0,
  BreakOnUncaughtException = 1,
  BreakOnAnyException = 2
};
71

72 73 74 75 76 77 78 79
/**
 * Defines if VM will pause on exceptions or not.
 * If BreakOnAnyExceptions is set then VM will pause on caught and uncaught
 * exception, if BreakOnUncaughtException is set then VM will pause only on
 * uncaught exception, otherwise VM won't stop on any exception.
 */
void ChangeBreakOnException(Isolate* isolate, ExceptionBreakState state);

80
void RemoveBreakpoint(Isolate* isolate, BreakpointId id);
81 82
void SetBreakPointsActive(Isolate* isolate, bool is_active);

83 84 85
enum StepAction {
  StepOut = 0,   // Step out of the current function.
  StepNext = 1,  // Step to the next statement in the current function.
86
  StepIn = 2     // Step into new functions invoked or the next statement
87 88
                 // in the current function.
};
89

90
void PrepareStep(Isolate* isolate, StepAction action);
91
void ClearStepping(Isolate* isolate);
92
V8_EXPORT_PRIVATE void BreakRightNow(Isolate* isolate);
93

94
bool AllFramesOnStackAreBlackboxed(Isolate* isolate);
95

96 97
class Script;

98 99 100 101 102 103 104 105 106 107 108 109 110
struct LiveEditResult {
  enum Status {
    OK,
    COMPILE_ERROR,
    BLOCKED_BY_RUNNING_GENERATOR,
    BLOCKED_BY_FUNCTION_ABOVE_BREAK_FRAME,
    BLOCKED_BY_FUNCTION_BELOW_NON_DROPPABLE_FRAME,
    BLOCKED_BY_ACTIVE_FUNCTION,
    BLOCKED_BY_NEW_TARGET_IN_RESTART_FRAME,
    FRAME_RESTART_IS_NOT_SUPPORTED
  };
  Status status = OK;
  bool stack_changed = false;
111 112
  // Available only for OK.
  v8::Local<v8::debug::Script> script;
113 114 115 116 117 118
  // Fields below are available only for COMPILE_ERROR.
  v8::Local<v8::String> message;
  int line_number = -1;
  int column_number = -1;
};

119 120 121
/**
 * Native wrapper around v8::internal::Script object.
 */
122
class V8_EXPORT_PRIVATE Script {
123 124 125 126 127
 public:
  v8::Isolate* GetIsolate() const;

  ScriptOriginOptions OriginOptions() const;
  bool WasCompiled() const;
128
  bool IsEmbedded() const;
129 130 131 132 133 134 135
  int Id() const;
  int LineOffset() const;
  int ColumnOffset() const;
  std::vector<int> LineEnds() const;
  MaybeLocal<String> Name() const;
  MaybeLocal<String> SourceURL() const;
  MaybeLocal<String> SourceMappingURL() const;
136
  Maybe<int> ContextId() const;
137 138
  MaybeLocal<String> Source() const;
  bool IsWasm() const;
139
  bool IsModule() const;
140 141 142 143
  bool GetPossibleBreakpoints(
      const debug::Location& start, const debug::Location& end,
      bool restrict_to_function,
      std::vector<debug::BreakLocation>* locations) const;
144 145
  int GetSourceOffset(const debug::Location& location) const;
  v8::debug::Location GetSourceLocation(int offset) const;
146
  bool SetScriptSource(v8::Local<v8::String> newSource, bool preview,
147
                       LiveEditResult* result) const;
148 149
  bool SetBreakpoint(v8::Local<v8::String> condition, debug::Location* location,
                     BreakpointId* id) const;
150
  bool SetBreakpointOnScriptEntry(BreakpointId* id) const;
151
};
152

153 154 155 156
// Specialization for wasm Scripts.
class WasmScript : public Script {
 public:
  static WasmScript* Cast(Script* script);
157

158 159 160
  int NumFunctions() const;
  int NumImportedFunctions() const;

161 162
  std::pair<int, int> GetFunctionRange(int function_index) const;

163
  debug::WasmDisassembly DisassembleFunction(int function_index) const;
164
  uint32_t GetFunctionHash(int function_index);
165 166
};

167 168
V8_EXPORT_PRIVATE void GetLoadedScripts(Isolate* isolate,
                                        PersistentValueVector<Script>& scripts);
169

170 171
MaybeLocal<UnboundScript> CompileInspectorScript(Isolate* isolate,
                                                 Local<String> source);
172

173 174
enum ExceptionType { kException, kPromiseRejection };

175
class DebugDelegate {
176
 public:
177
  virtual ~DebugDelegate() = default;
178
  virtual void ScriptCompiled(v8::Local<Script> script, bool is_live_edited,
179
                              bool has_compile_error) {}
180 181 182
  // |inspector_break_points_hit| contains id of breakpoints installed with
  // debug::Script::SetBreakpoint API.
  virtual void BreakProgramRequested(
183
      v8::Local<v8::Context> paused_context,
184
      const std::vector<debug::BreakpointId>& inspector_break_points_hit) {}
185 186
  virtual void ExceptionThrown(v8::Local<v8::Context> paused_context,
                               v8::Local<v8::Value> exception,
187 188
                               v8::Local<v8::Value> promise, bool is_uncaught,
                               ExceptionType exception_type) {}
189 190 191 192 193
  virtual bool IsFunctionBlackboxed(v8::Local<debug::Script> script,
                                    const debug::Location& start,
                                    const debug::Location& end) {
    return false;
  }
194 195
};

196 197
V8_EXPORT_PRIVATE void SetDebugDelegate(Isolate* isolate,
                                        DebugDelegate* listener);
198

199 200
class AsyncEventDelegate {
 public:
201
  virtual ~AsyncEventDelegate() = default;
202 203 204 205 206 207
  virtual void AsyncEventOccurred(debug::DebugAsyncActionType type, int id,
                                  bool is_blackboxed) = 0;
};

void SetAsyncEventDelegate(Isolate* isolate, AsyncEventDelegate* delegate);

208 209
void ResetBlackboxedStateCache(Isolate* isolate,
                               v8::Local<debug::Script> script);
210

211 212
int EstimatedValueSize(Isolate* isolate, v8::Local<v8::Value> value);

213
enum Builtin { kStringToLowerCase };
214 215 216

Local<Function> GetBuiltin(Isolate* isolate, Builtin builtin);

217 218
V8_EXPORT_PRIVATE void SetConsoleDelegate(Isolate* isolate,
                                          ConsoleDelegate* delegate);
219

220 221
int GetStackFrameId(v8::Local<v8::StackFrame> frame);

222 223 224
v8::Local<v8::StackTrace> GetDetailedStackTrace(Isolate* isolate,
                                                v8::Local<v8::Object> error);

225 226 227 228 229 230 231 232 233 234 235 236 237
/**
 * Native wrapper around v8::internal::JSGeneratorObject object.
 */
class GeneratorObject {
 public:
  v8::MaybeLocal<debug::Script> Script();
  v8::Local<v8::Function> Function();
  debug::Location SuspendedLocation();
  bool IsSuspended();

  static v8::Local<debug::GeneratorObject> Cast(v8::Local<v8::Value> value);
};

238 239 240 241 242
/*
 * Provide API layer between inspector and code coverage.
 */
class V8_EXPORT_PRIVATE Coverage {
 public:
243 244
  MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(Coverage);

245 246 247 248 249 250
  // Forward declarations.
  class ScriptData;
  class FunctionData;

  class V8_EXPORT_PRIVATE BlockData {
   public:
251 252
    MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(BlockData);

253 254 255 256 257
    int StartOffset() const;
    int EndOffset() const;
    uint32_t Count() const;

   private:
258 259 260 261
    explicit BlockData(i::CoverageBlock* block,
                       std::shared_ptr<i::Coverage> coverage)
        : block_(block), coverage_(std::move(coverage)) {}

262
    i::CoverageBlock* block_;
263
    std::shared_ptr<i::Coverage> coverage_;
264 265 266

    friend class v8::debug::Coverage::FunctionData;
  };
267 268

  class V8_EXPORT_PRIVATE FunctionData {
269
   public:
270 271
    MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(FunctionData);

272 273 274 275
    int StartOffset() const;
    int EndOffset() const;
    uint32_t Count() const;
    MaybeLocal<String> Name() const;
276
    size_t BlockCount() const;
277
    bool HasBlockCoverage() const;
278
    BlockData GetBlockData(size_t i) const;
279 280

   private:
281 282 283 284
    explicit FunctionData(i::CoverageFunction* function,
                          std::shared_ptr<i::Coverage> coverage)
        : function_(function), coverage_(std::move(coverage)) {}

285
    i::CoverageFunction* function_;
286
    std::shared_ptr<i::Coverage> coverage_;
287

288 289 290 291 292
    friend class v8::debug::Coverage::ScriptData;
  };

  class V8_EXPORT_PRIVATE ScriptData {
   public:
293 294
    MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(ScriptData);

295 296 297
    Local<debug::Script> GetScript() const;
    size_t FunctionCount() const;
    FunctionData GetFunctionData(size_t i) const;
298 299

   private:
300 301
    explicit ScriptData(size_t index, std::shared_ptr<i::Coverage> c);

302
    i::CoverageScript* script_;
303
    std::shared_ptr<i::Coverage> coverage_;
304 305

    friend class v8::debug::Coverage;
306 307
  };

308 309
  static Coverage CollectPrecise(Isolate* isolate);
  static Coverage CollectBestEffort(Isolate* isolate);
310

311
  static void SelectMode(Isolate* isolate, CoverageMode mode);
312

313 314 315
  size_t ScriptCount() const;
  ScriptData GetScriptData(size_t i) const;
  bool IsEmpty() const { return coverage_ == nullptr; }
316 317

 private:
318 319
  explicit Coverage(std::shared_ptr<i::Coverage> coverage)
      : coverage_(std::move(coverage)) {}
320
  std::shared_ptr<i::Coverage> coverage_;
321
};
322

323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
/*
 * Provide API layer between inspector and type profile.
 */
class V8_EXPORT_PRIVATE TypeProfile {
 public:
  MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(TypeProfile);

  class ScriptData;  // Forward declaration.

  class V8_EXPORT_PRIVATE Entry {
   public:
    MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(Entry);

    int SourcePosition() const;
    std::vector<MaybeLocal<String>> Types() const;

   private:
340 341 342 343
    explicit Entry(const i::TypeProfileEntry* entry,
                   std::shared_ptr<i::TypeProfile> type_profile)
        : entry_(entry), type_profile_(std::move(type_profile)) {}

344
    const i::TypeProfileEntry* entry_;
345
    std::shared_ptr<i::TypeProfile> type_profile_;
346 347 348 349 350 351 352 353 354 355 356 357

    friend class v8::debug::TypeProfile::ScriptData;
  };

  class V8_EXPORT_PRIVATE ScriptData {
   public:
    MOVE_ONLY_NO_DEFAULT_CONSTRUCTOR(ScriptData);

    Local<debug::Script> GetScript() const;
    std::vector<Entry> Entries() const;

   private:
358 359 360
    explicit ScriptData(size_t index,
                        std::shared_ptr<i::TypeProfile> type_profile);

361
    i::TypeProfileScript* script_;
362
    std::shared_ptr<i::TypeProfile> type_profile_;
363 364 365 366 367 368

    friend class v8::debug::TypeProfile;
  };

  static TypeProfile Collect(Isolate* isolate);

369
  static void SelectMode(Isolate* isolate, TypeProfileMode mode);
370 371 372 373 374

  size_t ScriptCount() const;
  ScriptData GetScriptData(size_t i) const;

 private:
375 376 377 378
  explicit TypeProfile(std::shared_ptr<i::TypeProfile> type_profile)
      : type_profile_(std::move(type_profile)) {}

  std::shared_ptr<i::TypeProfile> type_profile_;
379 380
};

381
class V8_EXPORT_PRIVATE ScopeIterator {
382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
 public:
  static std::unique_ptr<ScopeIterator> CreateForFunction(
      v8::Isolate* isolate, v8::Local<v8::Function> func);
  static std::unique_ptr<ScopeIterator> CreateForGeneratorObject(
      v8::Isolate* isolate, v8::Local<v8::Object> generator);

  ScopeIterator() = default;
  virtual ~ScopeIterator() = default;

  enum ScopeType {
    ScopeTypeGlobal = 0,
    ScopeTypeLocal,
    ScopeTypeWith,
    ScopeTypeClosure,
    ScopeTypeCatch,
    ScopeTypeBlock,
    ScopeTypeScript,
    ScopeTypeEval,
    ScopeTypeModule
  };

  virtual bool Done() = 0;
  virtual void Advance() = 0;
  virtual ScopeType GetType() = 0;
  virtual v8::Local<v8::Object> GetObject() = 0;
407 408 409
  virtual v8::Local<v8::Value> GetFunctionDebugName() = 0;
  virtual int GetScriptId() = 0;
  virtual bool HasLocationInfo() = 0;
410 411 412 413 414 415 416 417 418 419
  virtual debug::Location GetStartLocation() = 0;
  virtual debug::Location GetEndLocation() = 0;

  virtual bool SetVariableValue(v8::Local<v8::String> name,
                                v8::Local<v8::Value> value) = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(ScopeIterator);
};

420
class V8_EXPORT_PRIVATE StackTraceIterator {
421 422 423 424 425 426 427 428 429 430
 public:
  static std::unique_ptr<StackTraceIterator> Create(Isolate* isolate,
                                                    int index = 0);
  StackTraceIterator() = default;
  virtual ~StackTraceIterator() = default;

  virtual bool Done() const = 0;
  virtual void Advance() = 0;

  virtual int GetContextId() const = 0;
431
  virtual v8::MaybeLocal<v8::Value> GetReceiver() const = 0;
432
  virtual v8::Local<v8::Value> GetReturnValue() const = 0;
433
  virtual v8::Local<v8::String> GetFunctionDebugName() const = 0;
434 435 436 437 438 439 440 441 442 443 444 445 446
  virtual v8::Local<v8::debug::Script> GetScript() const = 0;
  virtual debug::Location GetSourceLocation() const = 0;
  virtual v8::Local<v8::Function> GetFunction() const = 0;
  virtual std::unique_ptr<ScopeIterator> GetScopeIterator() const = 0;

  virtual bool Restart() = 0;
  virtual v8::MaybeLocal<v8::Value> Evaluate(v8::Local<v8::String> source,
                                             bool throw_on_side_effect) = 0;

 private:
  DISALLOW_COPY_AND_ASSIGN(StackTraceIterator);
};

447 448 449 450 451 452 453 454 455 456
class QueryObjectPredicate {
 public:
  virtual ~QueryObjectPredicate() = default;
  virtual bool Filter(v8::Local<v8::Object> object) = 0;
};

void QueryObjects(v8::Local<v8::Context> context,
                  QueryObjectPredicate* predicate,
                  v8::PersistentValueVector<v8::Object>* objects);

457 458 459
void GlobalLexicalScopeNames(v8::Local<v8::Context> context,
                             v8::PersistentValueVector<v8::String>* names);

460 461
void SetReturnValue(v8::Isolate* isolate, v8::Local<v8::Value> value);

462 463 464
enum class NativeAccessorType {
  None = 0,
  HasGetter = 1 << 0,
465
  HasSetter = 1 << 1
466 467
};

468 469
int64_t GetNextRandomInt64(v8::Isolate* isolate);

470 471 472
V8_EXPORT_PRIVATE v8::MaybeLocal<v8::Value> EvaluateGlobal(
    v8::Isolate* isolate, v8::Local<v8::String> source,
    bool throw_on_side_effect);
473

474 475 476 477 478
int GetDebuggingId(v8::Local<v8::Function> function);

bool SetFunctionBreakpoint(v8::Local<v8::Function> function,
                           v8::Local<v8::String> condition, BreakpointId* id);

479 480
v8::Platform* GetCurrentPlatform();

481 482 483 484 485 486 487 488 489
class PostponeInterruptsScope {
 public:
  explicit PostponeInterruptsScope(v8::Isolate* isolate);
  ~PostponeInterruptsScope();

 private:
  std::unique_ptr<i::PostponeInterruptsScope> scope_;
};

490 491 492 493 494 495 496 497 498 499 500 501 502 503
class WeakMap : public v8::Object {
 public:
  V8_WARN_UNUSED_RESULT v8::MaybeLocal<v8::Value> Get(
      v8::Local<v8::Context> context, v8::Local<v8::Value> key);
  V8_WARN_UNUSED_RESULT v8::MaybeLocal<WeakMap> Set(
      v8::Local<v8::Context> context, v8::Local<v8::Value> key,
      v8::Local<v8::Value> value);

  static Local<WeakMap> New(v8::Isolate* isolate);
  V8_INLINE static WeakMap* Cast(Value* obj);

 private:
  WeakMap();
};
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536

struct PropertyDescriptor {
  bool enumerable : 1;
  bool has_enumerable : 1;
  bool configurable : 1;
  bool has_configurable : 1;
  bool writable : 1;
  bool has_writable : 1;
  v8::Local<v8::Value> value;
  v8::Local<v8::Value> get;
  v8::Local<v8::Value> set;
};

class PropertyIterator {
 public:
  static std::unique_ptr<PropertyIterator> Create(v8::Local<v8::Object> object);

  virtual ~PropertyIterator() = default;

  virtual bool Done() const = 0;
  virtual void Advance() = 0;

  virtual v8::Local<v8::Name> name() const = 0;

  virtual bool is_native_accessor() = 0;
  virtual bool has_native_getter() = 0;
  virtual bool has_native_setter() = 0;
  virtual Maybe<PropertyAttribute> attributes() = 0;
  virtual Maybe<PropertyDescriptor> descriptor() = 0;

  virtual bool is_own() = 0;
  virtual bool is_array_index() = 0;
};
537
}  // namespace debug
538 539 540
}  // namespace v8

#endif  // V8_DEBUG_DEBUG_INTERFACE_H_