Home | History | Annotate | Download | only in debug
      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 <functional>
      9 
     10 #include "include/v8-debug.h"
     11 #include "include/v8-util.h"
     12 #include "include/v8.h"
     13 
     14 #include "src/debug/interface-types.h"
     15 #include "src/globals.h"
     16 
     17 namespace v8 {
     18 
     19 namespace internal {
     20 struct CoverageFunction;
     21 struct CoverageScript;
     22 class Coverage;
     23 class Script;
     24 }
     25 
     26 namespace debug {
     27 
     28 /**
     29  * Debugger is running in its own context which is entered while debugger
     30  * messages are being dispatched. This is an explicit getter for this
     31  * debugger context. Note that the content of the debugger context is subject
     32  * to change. The Context exists only when the debugger is active, i.e. at
     33  * least one DebugEventListener or MessageHandler is set.
     34  */
     35 Local<Context> GetDebugContext(Isolate* isolate);
     36 
     37 /**
     38  * Run a JavaScript function in the debugger.
     39  * \param fun the function to call
     40  * \param data passed as second argument to the function
     41  * With this call the debugger is entered and the function specified is called
     42  * with the execution state as the first argument. This makes it possible to
     43  * get access to information otherwise not available during normal JavaScript
     44  * execution e.g. details on stack frames. Receiver of the function call will
     45  * be the debugger context global object, however this is a subject to change.
     46  * The following example shows a JavaScript function which when passed to
     47  * v8::Debug::Call will return the current line of JavaScript execution.
     48  *
     49  * \code
     50  *   function frame_source_line(exec_state) {
     51  *     return exec_state.frame(0).sourceLine();
     52  *   }
     53  * \endcode
     54  */
     55 // TODO(dcarney): data arg should be a MaybeLocal
     56 MaybeLocal<Value> Call(Local<Context> context, v8::Local<v8::Function> fun,
     57                        Local<Value> data = Local<Value>());
     58 
     59 /**
     60  * Enable/disable LiveEdit functionality for the given Isolate
     61  * (default Isolate if not provided). V8 will abort if LiveEdit is
     62  * unexpectedly used. LiveEdit is enabled by default.
     63  */
     64 void SetLiveEditEnabled(Isolate* isolate, bool enable);
     65 
     66 // Schedule a debugger break to happen when JavaScript code is run
     67 // in the given isolate.
     68 void DebugBreak(Isolate* isolate);
     69 
     70 // Remove scheduled debugger break in given isolate if it has not
     71 // happened yet.
     72 void CancelDebugBreak(Isolate* isolate);
     73 
     74 /**
     75  * Returns array of internal properties specific to the value type. Result has
     76  * the following format: [<name>, <value>,...,<name>, <value>]. Result array
     77  * will be allocated in the current context.
     78  */
     79 MaybeLocal<Array> GetInternalProperties(Isolate* isolate, Local<Value> value);
     80 
     81 enum ExceptionBreakState {
     82   NoBreakOnException = 0,
     83   BreakOnUncaughtException = 1,
     84   BreakOnAnyException = 2
     85 };
     86 
     87 /**
     88  * Defines if VM will pause on exceptions or not.
     89  * If BreakOnAnyExceptions is set then VM will pause on caught and uncaught
     90  * exception, if BreakOnUncaughtException is set then VM will pause only on
     91  * uncaught exception, otherwise VM won't stop on any exception.
     92  */
     93 void ChangeBreakOnException(Isolate* isolate, ExceptionBreakState state);
     94 
     95 void SetBreakPointsActive(Isolate* isolate, bool is_active);
     96 
     97 enum StepAction {
     98   StepOut = 0,   // Step out of the current function.
     99   StepNext = 1,  // Step to the next statement in the current function.
    100   StepIn = 2     // Step into new functions invoked or the next statement
    101                  // in the current function.
    102 };
    103 
    104 void PrepareStep(Isolate* isolate, StepAction action);
    105 
    106 bool HasNonBlackboxedFrameOnStack(Isolate* isolate);
    107 
    108 /**
    109  * Out-of-memory callback function.
    110  * The function is invoked when the heap size is close to the hard limit.
    111  *
    112  * \param data the parameter provided during callback installation.
    113  */
    114 typedef void (*OutOfMemoryCallback)(void* data);
    115 void SetOutOfMemoryCallback(Isolate* isolate, OutOfMemoryCallback callback,
    116                             void* data);
    117 
    118 /**
    119  * Native wrapper around v8::internal::Script object.
    120  */
    121 class V8_EXPORT_PRIVATE Script {
    122  public:
    123   v8::Isolate* GetIsolate() const;
    124 
    125   ScriptOriginOptions OriginOptions() const;
    126   bool WasCompiled() const;
    127   int Id() const;
    128   int LineOffset() const;
    129   int ColumnOffset() const;
    130   std::vector<int> LineEnds() const;
    131   MaybeLocal<String> Name() const;
    132   MaybeLocal<String> SourceURL() const;
    133   MaybeLocal<String> SourceMappingURL() const;
    134   MaybeLocal<Value> ContextData() const;
    135   MaybeLocal<String> Source() const;
    136   bool IsWasm() const;
    137   bool IsModule() const;
    138   bool GetPossibleBreakpoints(const debug::Location& start,
    139                               const debug::Location& end,
    140                               std::vector<debug::Location>* locations) const;
    141 
    142  private:
    143   int GetSourcePosition(const debug::Location& location) 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 };
    158 
    159 void GetLoadedScripts(Isolate* isolate, PersistentValueVector<Script>& scripts);
    160 
    161 MaybeLocal<UnboundScript> CompileInspectorScript(Isolate* isolate,
    162                                                  Local<String> source);
    163 
    164 class DebugDelegate {
    165  public:
    166   virtual ~DebugDelegate() {}
    167   virtual void PromiseEventOccurred(debug::PromiseDebugActionType type, int id,
    168                                     int parent_id) {}
    169   virtual void ScriptCompiled(v8::Local<Script> script,
    170                               bool has_compile_error) {}
    171   virtual void BreakProgramRequested(v8::Local<v8::Context> paused_context,
    172                                      v8::Local<v8::Object> exec_state,
    173                                      v8::Local<v8::Value> break_points_hit) {}
    174   virtual void ExceptionThrown(v8::Local<v8::Context> paused_context,
    175                                v8::Local<v8::Object> exec_state,
    176                                v8::Local<v8::Value> exception,
    177                                v8::Local<v8::Value> promise, bool is_uncaught) {
    178   }
    179   virtual bool IsFunctionBlackboxed(v8::Local<debug::Script> script,
    180                                     const debug::Location& start,
    181                                     const debug::Location& end) {
    182     return false;
    183   }
    184 };
    185 
    186 void SetDebugDelegate(Isolate* isolate, DebugDelegate* listener);
    187 
    188 void ResetBlackboxedStateCache(Isolate* isolate,
    189                                v8::Local<debug::Script> script);
    190 
    191 int EstimatedValueSize(Isolate* isolate, v8::Local<v8::Value> value);
    192 
    193 v8::MaybeLocal<v8::Array> EntriesPreview(Isolate* isolate,
    194                                          v8::Local<v8::Value> value,
    195                                          bool* is_key_value);
    196 
    197 /**
    198  * Native wrapper around v8::internal::JSGeneratorObject object.
    199  */
    200 class GeneratorObject {
    201  public:
    202   v8::MaybeLocal<debug::Script> Script();
    203   v8::Local<v8::Function> Function();
    204   debug::Location SuspendedLocation();
    205   bool IsSuspended();
    206 
    207   static v8::Local<debug::GeneratorObject> Cast(v8::Local<v8::Value> value);
    208 };
    209 
    210 /*
    211  * Provide API layer between inspector and code coverage.
    212  */
    213 class V8_EXPORT_PRIVATE Coverage {
    214  public:
    215   class ScriptData;  // Forward declaration.
    216 
    217   class V8_EXPORT_PRIVATE FunctionData {
    218    public:
    219     // 0-based line and colum numbers.
    220     Location Start() { return start_; }
    221     Location End() { return end_; }
    222     uint32_t Count();
    223     MaybeLocal<String> Name();
    224 
    225    private:
    226     FunctionData(i::CoverageFunction* function, Local<debug::Script> script);
    227     i::CoverageFunction* function_;
    228     Location start_;
    229     Location end_;
    230 
    231     friend class v8::debug::Coverage::ScriptData;
    232   };
    233 
    234   class V8_EXPORT_PRIVATE ScriptData {
    235    public:
    236     Local<debug::Script> GetScript();
    237     size_t FunctionCount();
    238     FunctionData GetFunctionData(size_t i);
    239 
    240    private:
    241     explicit ScriptData(i::CoverageScript* script) : script_(script) {}
    242     i::CoverageScript* script_;
    243 
    244     friend class v8::debug::Coverage;
    245   };
    246 
    247   static Coverage Collect(Isolate* isolate, bool reset_count);
    248 
    249   static void TogglePrecise(Isolate* isolate, bool enable);
    250 
    251   size_t ScriptCount();
    252   ScriptData GetScriptData(size_t i);
    253   bool IsEmpty() { return coverage_ == nullptr; }
    254 
    255   ~Coverage();
    256 
    257  private:
    258   explicit Coverage(i::Coverage* coverage) : coverage_(coverage) {}
    259   i::Coverage* coverage_;
    260 };
    261 }  // namespace debug
    262 }  // namespace v8
    263 
    264 #endif  // V8_DEBUG_DEBUG_INTERFACE_H_
    265