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-debug.h"
9 #include "include/v8-util.h"
10 #include "include/v8.h"
11 
12 namespace v8 {
13 
14 class DebugInterface {
15  public:
16   /**
17    * An event details object passed to the debug event listener.
18    */
19   class EventDetails : public v8::Debug::EventDetails {
20    public:
21     /**
22      * Event type.
23      */
24     virtual v8::DebugEvent GetEvent() const = 0;
25 
26     /**
27      * Access to execution state and event data of the debug event. Don't store
28      * these cross callbacks as their content becomes invalid.
29      */
30     virtual Local<Object> GetExecutionState() const = 0;
31     virtual Local<Object> GetEventData() const = 0;
32 
33     /**
34      * Get the context active when the debug event happened. Note this is not
35      * the current active context as the JavaScript part of the debugger is
36      * running in its own context which is entered at this point.
37      */
38     virtual Local<Context> GetEventContext() const = 0;
39 
40     /**
41      * Client data passed with the corresponding callback when it was
42      * registered.
43      */
44     virtual Local<Value> GetCallbackData() const = 0;
45 
~EventDetails()46     virtual ~EventDetails() {}
47   };
48 
49   /**
50    * Debug event callback function.
51    *
52    * \param event_details object providing information about the debug event
53    *
54    * A EventCallback does not take possession of the event data,
55    * and must not rely on the data persisting after the handler returns.
56    */
57   typedef void (*EventCallback)(const EventDetails& event_details);
58 
59   static bool SetDebugEventListener(Isolate* isolate, EventCallback that,
60                                     Local<Value> data = Local<Value>());
61 
62   /**
63    * Debugger is running in its own context which is entered while debugger
64    * messages are being dispatched. This is an explicit getter for this
65    * debugger context. Note that the content of the debugger context is subject
66    * to change. The Context exists only when the debugger is active, i.e. at
67    * least one DebugEventListener or MessageHandler is set.
68    */
69   static Local<Context> GetDebugContext(Isolate* isolate);
70 
71   /**
72    * Run a JavaScript function in the debugger.
73    * \param fun the function to call
74    * \param data passed as second argument to the function
75    * With this call the debugger is entered and the function specified is called
76    * with the execution state as the first argument. This makes it possible to
77    * get access to information otherwise not available during normal JavaScript
78    * execution e.g. details on stack frames. Receiver of the function call will
79    * be the debugger context global object, however this is a subject to change.
80    * The following example shows a JavaScript function which when passed to
81    * v8::Debug::Call will return the current line of JavaScript execution.
82    *
83    * \code
84    *   function frame_source_line(exec_state) {
85    *     return exec_state.frame(0).sourceLine();
86    *   }
87    * \endcode
88    */
89   // TODO(dcarney): data arg should be a MaybeLocal
90   static MaybeLocal<Value> Call(Local<Context> context,
91                                 v8::Local<v8::Function> fun,
92                                 Local<Value> data = Local<Value>());
93 
94   /**
95    * Enable/disable LiveEdit functionality for the given Isolate
96    * (default Isolate if not provided). V8 will abort if LiveEdit is
97    * unexpectedly used. LiveEdit is enabled by default.
98    */
99   static void SetLiveEditEnabled(Isolate* isolate, bool enable);
100 
101   // Schedule a debugger break to happen when JavaScript code is run
102   // in the given isolate.
103   static void DebugBreak(Isolate* isolate);
104 
105   // Remove scheduled debugger break in given isolate if it has not
106   // happened yet.
107   static void CancelDebugBreak(Isolate* isolate);
108 
109   /**
110    * Returns array of internal properties specific to the value type. Result has
111    * the following format: [<name>, <value>,...,<name>, <value>]. Result array
112    * will be allocated in the current context.
113    */
114   static MaybeLocal<Array> GetInternalProperties(Isolate* isolate,
115                                                  Local<Value> value);
116 
117   enum ExceptionBreakState {
118     NoBreakOnException = 0,
119     BreakOnUncaughtException = 1,
120     BreakOnAnyException = 2
121   };
122 
123   /**
124    * Defines if VM will pause on exceptions or not.
125    * If BreakOnAnyExceptions is set then VM will pause on caught and uncaught
126    * exception, if BreakOnUncaughtException is set then VM will pause only on
127    * uncaught exception, otherwise VM won't stop on any exception.
128    */
129   static void ChangeBreakOnException(Isolate* isolate,
130                                      ExceptionBreakState state);
131 
132   enum StepAction {
133     StepOut = 0,   // Step out of the current function.
134     StepNext = 1,  // Step to the next statement in the current function.
135     StepIn = 2,    // Step into new functions invoked or the next statement
136                    // in the current function.
137     StepFrame = 3  // Step into a new frame or return to previous frame.
138   };
139 
140   static void PrepareStep(Isolate* isolate, StepAction action);
141   static void ClearStepping(Isolate* isolate);
142 
143   /**
144    * Defines location inside script.
145    * Lines and columns are 0-based.
146    */
147   class Location {
148    public:
149     Location(int lineNumber, int columnNumber);
150     /**
151      * Create empty location.
152      */
153     Location();
154 
155     int GetLineNumber() const;
156     int GetColumnNumber() const;
157     bool IsEmpty() const;
158 
159    private:
160     int lineNumber_;
161     int columnNumber_;
162   };
163 
164   /**
165    * Native wrapper around v8::internal::Script object.
166    */
167   class Script {
168    public:
169     v8::Isolate* GetIsolate() const;
170 
171     ScriptOriginOptions OriginOptions() const;
172     bool WasCompiled() const;
173     int Id() const;
174     int LineOffset() const;
175     int ColumnOffset() const;
176     std::vector<int> LineEnds() const;
177     MaybeLocal<String> Name() const;
178     MaybeLocal<String> SourceURL() const;
179     MaybeLocal<String> SourceMappingURL() const;
180     MaybeLocal<String> ContextData() const;
181     MaybeLocal<String> Source() const;
182     bool GetPossibleBreakpoints(const Location& start, const Location& end,
183                                 std::vector<Location>* locations) const;
184 
185     /**
186      * script parameter is a wrapper v8::internal::JSObject for
187      * v8::internal::Script.
188      * This function gets v8::internal::Script from v8::internal::JSObject and
189      * wraps it with DebugInterface::Script.
190      * Returns empty local if not called with a valid wrapper of
191      * v8::internal::Script.
192      */
193     static MaybeLocal<Script> Wrap(Isolate* isolate,
194                                    v8::Local<v8::Object> script);
195 
196    private:
197     int GetSourcePosition(const Location& location) const;
198   };
199 
200   /**
201    * Return array of compiled scripts.
202    */
203   static void GetLoadedScripts(Isolate* isolate,
204                                PersistentValueVector<Script>& scripts);
205 };
206 
207 }  // namespace v8
208 
209 #endif  // V8_DEBUG_DEBUG_INTERFACE_H_
210