// 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_ #include #include "include/v8-callbacks.h" #include "include/v8-date.h" #include "include/v8-debug.h" #include "include/v8-embedder-heap.h" #include "include/v8-isolate.h" #include "include/v8-local-handle.h" #include "include/v8-memory-span.h" #include "include/v8-promise.h" #include "include/v8-script.h" #include "include/v8-util.h" #include "src/base/enum-set.h" #include "src/base/vector.h" #include "src/common/globals.h" #include "src/debug/interface-types.h" namespace v8_inspector { class V8Inspector; } // namespace v8_inspector namespace v8 { class Platform; namespace internal { struct CoverageBlock; struct CoverageFunction; struct CoverageScript; class Coverage; class DisableBreak; class PostponeInterruptsScope; class Script; } // namespace internal namespace debug { void SetContextId(Local context, int id); int GetContextId(Local context); void SetInspector(Isolate* isolate, v8_inspector::V8Inspector*); v8_inspector::V8Inspector* GetInspector(Isolate* isolate); // Returns a debug string representation of the bigint without tailing `n`. Local GetBigIntStringValue(Isolate* isolate, Local bigint); // Returns a debug string representation of the bigint. Local GetBigIntDescription(Isolate* isolate, Local bigint); // Returns a debug string representation of the date. Local GetDateDescription(Local date); // Returns a debug string representation of the function. Local GetFunctionDescription(Local function); // Schedule a debugger break to happen when function is called inside given // isolate. V8_EXPORT_PRIVATE void SetBreakOnNextFunctionCall(Isolate* isolate); // Remove scheduled debugger break in given isolate if it has not // happened yet. V8_EXPORT_PRIVATE void ClearBreakOnNextFunctionCall(Isolate* isolate); /** * Returns array of internal properties specific to the value type. Result has * the following format: [, ,...,, ]. Result array * will be allocated in the current context. */ MaybeLocal GetInternalProperties(Isolate* isolate, Local value); /** * Returns through the out parameters names_out a vector of names * in v8::String for private members, including fields, methods, * accessors specific to the value type. * The values are returned through the out parameter values_out in the * corresponding indices. Private fields and methods are returned directly * while accessors are returned as v8::debug::AccessorPair. Missing components * in the accessor pairs are null. * If an exception occurs, false is returned. Otherwise true is returned. * Results will be allocated in the current context and handle scope. */ V8_EXPORT_PRIVATE bool GetPrivateMembers(Local context, Local value, std::vector>* names_out, std::vector>* values_out); /** * Forwards to v8::Object::CreationContext, but with special handling for * JSGlobalProxy objects. */ MaybeLocal GetCreationContext(Local value); enum ExceptionBreakState { NoBreakOnException = 0, BreakOnUncaughtException = 1, BreakOnAnyException = 2 }; /** * 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); void RemoveBreakpoint(Isolate* isolate, BreakpointId id); void SetBreakPointsActive(Isolate* isolate, bool is_active); enum StepAction { StepOut = 0, // Step out of the current function. StepOver = 1, // Step to the next statement in the current function. StepInto = 2 // Step into new functions invoked or the next statement // in the current function. }; // Record the reason for why the debugger breaks. enum class BreakReason : uint8_t { kAlreadyPaused, kStep, kAsyncStep, kException, kAssert, kDebuggerStatement, kOOM, kScheduled, kAgent }; typedef base::EnumSet BreakReasons; void PrepareStep(Isolate* isolate, StepAction action); bool PrepareRestartFrame(Isolate* isolate, int callFrameOrdinal); void ClearStepping(Isolate* isolate); V8_EXPORT_PRIVATE void BreakRightNow( Isolate* isolate, base::EnumSet break_reason = {}); // Use `SetTerminateOnResume` to indicate that an TerminateExecution interrupt // should be set shortly before resuming, i.e. shortly before returning into // the JavaScript stack frames on the stack. In contrast to setting the // interrupt with `RequestTerminateExecution` directly, this flag allows // the isolate to be entered for further JavaScript execution. V8_EXPORT_PRIVATE void SetTerminateOnResume(Isolate* isolate); bool CanBreakProgram(Isolate* isolate); class Script; struct LiveEditResult { enum Status { OK, COMPILE_ERROR, BLOCKED_BY_RUNNING_GENERATOR, BLOCKED_BY_ACTIVE_FUNCTION }; Status status = OK; bool stack_changed = false; // Available only for OK. v8::Local script; bool restart_top_frame_required = false; // Fields below are available only for COMPILE_ERROR. v8::Local message; int line_number = -1; int column_number = -1; }; /** * An internal representation of the source for a given * `v8::debug::Script`, which can be a `v8::String`, in * which case it represents JavaScript source, or it can * be a managed pointer to a native Wasm module, or it * can be undefined to indicate that source is unavailable. */ class V8_EXPORT_PRIVATE ScriptSource { public: // The number of characters in case of JavaScript or // the size of the memory in case of WebAssembly. size_t Length() const; // The actual size of the source in bytes. size_t Size() const; MaybeLocal JavaScriptCode() const; #if V8_ENABLE_WEBASSEMBLY Maybe> WasmBytecode() const; #endif // V8_ENABLE_WEBASSEMBLY }; /** * Native wrapper around v8::internal::Script object. */ class V8_EXPORT_PRIVATE Script { public: v8::Isolate* GetIsolate() const; ScriptOriginOptions OriginOptions() const; bool WasCompiled() const; bool IsEmbedded() const; int Id() const; int StartLine() const; int StartColumn() const; int EndLine() const; int EndColumn() const; MaybeLocal Name() const; MaybeLocal SourceURL() const; MaybeLocal SourceMappingURL() const; MaybeLocal GetSha256Hash() const; Maybe ContextId() const; Local Source() const; bool IsModule() const; bool GetPossibleBreakpoints( const debug::Location& start, const debug::Location& end, bool restrict_to_function, std::vector* locations) const; enum class GetSourceOffsetMode { kStrict, kClamp }; Maybe GetSourceOffset( const debug::Location& location, GetSourceOffsetMode mode = GetSourceOffsetMode::kStrict) const; v8::debug::Location GetSourceLocation(int offset) const; bool SetScriptSource(v8::Local newSource, bool preview, bool allow_top_frame_live_editing, LiveEditResult* result) const; bool SetBreakpoint(v8::Local condition, debug::Location* location, BreakpointId* id) const; #if V8_ENABLE_WEBASSEMBLY bool IsWasm() const; void RemoveWasmBreakpoint(BreakpointId id); #endif // V8_ENABLE_WEBASSEMBLY bool SetInstrumentationBreakpoint(BreakpointId* id) const; }; class DisassemblyCollector { public: virtual void ReserveLineCount(size_t count) = 0; virtual void AddLine(const char* src, size_t length, uint32_t bytecode_offset) = 0; }; #if V8_ENABLE_WEBASSEMBLY // Specialization for wasm Scripts. class WasmScript : public Script { public: static WasmScript* Cast(Script* script); enum class DebugSymbolsType { None, SourceMap, EmbeddedDWARF, ExternalDWARF }; DebugSymbolsType GetDebugSymbolType() const; MemorySpan ExternalSymbolsURL() const; int NumFunctions() const; int NumImportedFunctions() const; std::pair GetFunctionRange(int function_index) const; int GetContainingFunction(int byte_offset) const; void Disassemble(DisassemblyCollector* collector, std::vector* function_body_offsets); uint32_t GetFunctionHash(int function_index); int CodeOffset() const; int CodeLength() const; }; #endif // V8_ENABLE_WEBASSEMBLY V8_EXPORT_PRIVATE void GetLoadedScripts( Isolate* isolate, std::vector>& scripts); MaybeLocal CompileInspectorScript(Isolate* isolate, Local source); enum ExceptionType { kException, kPromiseRejection }; class DebugDelegate { public: virtual ~DebugDelegate() = default; virtual void ScriptCompiled(v8::Local