|
1 # Debugger.Frame |
|
2 |
|
3 A `Debugger.Frame` instance represents a [visible stack frame][vf]. Given a |
|
4 `Debugger.Frame` instance, you can find the script the frame is executing, |
|
5 walk the stack to older frames, find the lexical environment in which the |
|
6 execution is taking place, and so on. |
|
7 |
|
8 For a given [`Debugger`][debugger-object] instance, SpiderMonkey creates |
|
9 only one `Debugger.Frame` instance for a given visible frame. Every handler |
|
10 method called while the debuggee is running in a given frame is given the |
|
11 same frame object. Similarly, walking the stack back to a previously |
|
12 accessed frame yields the same frame object as before. Debugger code can |
|
13 add its own properties to a frame object and expect to find them later, use |
|
14 `==` to decide whether two expressions refer to the same frame, and so on. |
|
15 |
|
16 (If more than one [`Debugger`][debugger-object] instance is debugging the |
|
17 same code, each [`Debugger`][debugger-object] gets a separate |
|
18 `Debugger.Frame` instance for a given frame. This allows the code using |
|
19 each [`Debugger`][debugger-object] instance to place whatever properties it |
|
20 likes on its `Debugger.Frame` instances, without worrying about interfering |
|
21 with other debuggers.) |
|
22 |
|
23 When the debuggee pops a stack frame (say, because a function call has |
|
24 returned or an exception has been thrown from it), the `Debugger.Frame` |
|
25 instance referring to that frame becomes inactive: its `live` property |
|
26 becomes `false`, and accessing its other properties or calling its methods |
|
27 throws an exception. Note that frames only become inactive at times that |
|
28 are predictable for the debugger: when the debuggee runs, or when the |
|
29 debugger removes frames from the stack itself. |
|
30 |
|
31 Stack frames that represent the control state of generator-iterator objects |
|
32 behave in a special way, described in [Generator Frames][generator] below. |
|
33 |
|
34 |
|
35 ## Visible Frames |
|
36 |
|
37 When inspecting the call stack, [`Debugger`][debugger-object] does not |
|
38 reveal all the frames that are actually present on the stack: while it does |
|
39 reveal all frames running debuggee code, it omits frames running the |
|
40 debugger's own code, and omits most frames running non-debuggee code. We |
|
41 call those stack frames a [`Debugger`][debugger-object] does reveal |
|
42 <i>visible frames</i>. |
|
43 |
|
44 A frame is a visible frame if any of the following are true: |
|
45 |
|
46 * it is running [debuggee code][dbg code]; |
|
47 |
|
48 * its immediate caller is a frame running debuggee code; or |
|
49 |
|
50 * it is a [`"debugger"` frame][inv fr], |
|
51 representing the continuation of debuggee code invoked by the debugger. |
|
52 |
|
53 The "immediate caller" rule means that, when debuggee code calls a |
|
54 non-debuggee function, it looks like a call to a primitive: you see a frame |
|
55 for the non-debuggee function that was accessible to the debuggee, but any |
|
56 further calls that function makes are treated as internal details, and |
|
57 omitted from the stack trace. If the non-debuggee function eventually calls |
|
58 back into debuggee code, then those frames are visible. |
|
59 |
|
60 (Note that the debuggee is not considered an "immediate caller" of handler |
|
61 methods it triggers. Even though the debuggee and debugger share the same |
|
62 JavaScript stack, frames pushed for SpiderMonkey's calls to handler methods |
|
63 to report events in the debuggee are never considered visible frames.) |
|
64 |
|
65 |
|
66 ## Invocation Functions and "debugger" Frames |
|
67 |
|
68 An <i>invocation function</i> is any function in this interface that allows |
|
69 the debugger to invoke code in the debuggee: |
|
70 `Debugger.Object.prototype.call`, `Debugger.Frame.prototype.eval`, and so |
|
71 on. |
|
72 |
|
73 While invocation functions differ in the code to be run and how to pass |
|
74 values to it, they all follow this general procedure: |
|
75 |
|
76 1. Let <i>older</i> be the youngest visible frame on the stack, or `null` |
|
77 if there is no such frame. (This is never one of the the debugger's own |
|
78 frames; those never appear as `Debugger.Frame` instances.) |
|
79 |
|
80 2. Push a `"debugger"` frame on the stack, with <i>older</i> as its |
|
81 `older` property. |
|
82 |
|
83 3. Invoke the debuggee code as appropriate for the given invocation |
|
84 function, with the `"debugger"` frame as its continuation. For example, |
|
85 `Debugger.Frame.prototype.eval` pushes an `"eval"` frame for code it |
|
86 runs, whereas `Debugger.Object.prototype.call` pushes a `"call"` frame. |
|
87 |
|
88 4. When the debuggee code completes, whether by returning, throwing an |
|
89 exception or being terminated, pop the `"debugger"` frame, and return an |
|
90 appropriate [completion value][cv] from the invocation function to the |
|
91 debugger. |
|
92 |
|
93 When a debugger calls an invocation function to run debuggee code, that |
|
94 code's continuation is the debugger, not the next debuggee code frame. |
|
95 Pushing a `"debugger"` frame makes this continuation explicit, and makes it |
|
96 easier to find the extent of the stack created for the invocation. |
|
97 |
|
98 |
|
99 ## Accessor Properties of the Debugger.Frame Prototype Object |
|
100 |
|
101 A `Debugger.Frame` instance inherits the following accessor properties from |
|
102 its prototype: |
|
103 |
|
104 `type` |
|
105 : A string describing what sort of frame this is: |
|
106 |
|
107 * `"call"`: a frame running a function call. (We may not be able to obtain |
|
108 frames for calls to host functions.) |
|
109 |
|
110 * `"eval"`: a frame running code passed to `eval`. |
|
111 |
|
112 * `"global"`: a frame running global code (JavaScript that is neither of |
|
113 the above). |
|
114 |
|
115 * `"debugger"`: a frame for a call to user code invoked by the debugger |
|
116 (see the `eval` method below). |
|
117 |
|
118 `this` |
|
119 : The value of `this` for this frame (a debuggee value). |
|
120 |
|
121 `older` |
|
122 : The next-older visible frame, in which control will resume when this |
|
123 frame completes. If there is no older frame, this is `null`. (On a |
|
124 suspended generator frame, the value of this property is `null`; see |
|
125 [Generator Frames][generator].) |
|
126 |
|
127 `depth` |
|
128 : The depth of this frame, counting from oldest to youngest; the oldest |
|
129 frame has a depth of zero. |
|
130 |
|
131 `live` |
|
132 : True if the frame this `Debugger.Frame` instance refers to is still on |
|
133 the stack (or, in the case of generator-iterator objects, has not yet |
|
134 finished its iteration); false if it has completed execution or been |
|
135 popped in some other way. |
|
136 |
|
137 `script` |
|
138 : The script being executed in this frame (a [`Debugger.Script`][script] |
|
139 instance), or `null` on frames that do not represent calls to debuggee |
|
140 code. On frames whose `callee` property is not null, this is equal to |
|
141 `callee.script`. |
|
142 |
|
143 `offset` |
|
144 : The offset of the bytecode instruction currently being executed in |
|
145 `script`, or `undefined` if the frame's `script` property is `null`. |
|
146 |
|
147 `environment` |
|
148 : The lexical environment within which evaluation is taking place (a |
|
149 [`Debugger.Environment`][environment] instance), or `null` on frames |
|
150 that do not represent the evaluation of debuggee code, like calls |
|
151 non-debuggee functions, host functions or `"debugger"` frames. |
|
152 |
|
153 `callee` |
|
154 : The function whose application created this frame, as a debuggee value, |
|
155 or `null` if this is not a `"call"` frame. |
|
156 |
|
157 `generator` |
|
158 : True if this frame is a generator frame, false otherwise. |
|
159 |
|
160 `constructing` |
|
161 : True if this frame is for a function called as a constructor, false |
|
162 otherwise. |
|
163 |
|
164 `arguments` |
|
165 : The arguments passed to the current frame, or `null` if this is not a |
|
166 `"call"` frame. When non-`null`, this is an object, allocated in the |
|
167 same global as the debugger, with `Array.prototype` on its prototype |
|
168 chain, a non-writable `length` property, and properties whose names are |
|
169 array indices. Each property is a read-only accessor property whose |
|
170 getter returns the current value of the corresponding parameter. When |
|
171 the referent frame is popped, the argument value's properties' getters |
|
172 throw an error. |
|
173 |
|
174 |
|
175 ## Handler Methods of Debugger.Frame Instances |
|
176 |
|
177 Each `Debugger.Frame` instance inherits accessor properties holding handler |
|
178 functions for SpiderMonkey to call when given events occur in the frame. |
|
179 |
|
180 Calls to frames' handler methods are cross-compartment, intra-thread calls: |
|
181 the call takes place in the thread to which the frame belongs, and runs in |
|
182 the compartment to which the handler method belongs. |
|
183 |
|
184 `Debugger.Frame` instances inherit the following handler method properties: |
|
185 |
|
186 `onStep` |
|
187 : This property must be either `undefined` or a function. If it is a |
|
188 function, SpiderMonkey calls it when execution in this frame makes a |
|
189 small amount of progress, passing no arguments and providing this |
|
190 `Debugger.Frame` instance as the `this`value. The function should |
|
191 return a [resumption value][rv] specifying how the debuggee's execution |
|
192 should proceed. |
|
193 |
|
194 What constitutes "a small amount of progress" varies depending on the |
|
195 implementation, but it is fine-grained enough to implement useful |
|
196 "step" and "next" behavior. |
|
197 |
|
198 If multiple [`Debugger`][debugger-object] instances each have |
|
199 `Debugger.Frame` instances for a given stack frame with `onStep` |
|
200 handlers set, their handlers are run in an unspecified order. If any |
|
201 `onStep` handler forces the frame to return early (by returning a |
|
202 resumption value other than `undefined`), any remaining debuggers' |
|
203 `onStep` handlers do not run. |
|
204 |
|
205 This property is ignored on frames that are not executing debuggee |
|
206 code, like `"call"` frames for calls to host functions and `"debugger"` |
|
207 frames. |
|
208 |
|
209 `onPop` |
|
210 : This property must be either `undefined` or a function. If it is a |
|
211 function, SpiderMonkey calls it just before this frame is popped, |
|
212 passing a [completion value][cv] indicating how this frame's execution |
|
213 completed, and providing this `Debugger.Frame` instance as the `this` |
|
214 value. The function should return a [resumption value][rv] indicating |
|
215 how execution should proceed. On newly created frames, this property's |
|
216 value is `undefined`. |
|
217 |
|
218 When an `onPop` call reports the completion of a construction call |
|
219 (that is, a function called via the `new` operator), the completion |
|
220 value passed to the handler describes the value returned by the |
|
221 function body. If this value is not an object, it may be different from |
|
222 the value produced by the `new` expression, which will be the value of |
|
223 the frame's `this` property. (In ECMAScript terms, the `onPop` handler |
|
224 receives the value returned by the `[[Call]]` method, not the value |
|
225 returned by the `[[Construct]]` method.) |
|
226 |
|
227 When a debugger handler function forces a frame to complete early, by |
|
228 returning a `{ return:... }`, `{ throw:... }`, or `null` resumption |
|
229 value, SpiderMonkey calls the frame's `onPop` handler, if any. The |
|
230 completion value passed in this case reflects the resumption value that |
|
231 caused the frame to complete. |
|
232 |
|
233 When SpiderMonkey calls an `onPop` handler for a frame that is throwing |
|
234 an exception or being terminated, and the handler returns `undefined`, |
|
235 then SpiderMonkey proceeds with the exception or termination. That is, |
|
236 an `undefined` resumption value leaves the frame's throwing and |
|
237 termination process undisturbed. |
|
238 |
|
239 <i>(Not yet implemented.)</i> When a generator frame yields a value, |
|
240 SpiderMonkey calls its `Debugger.Frame` instance's `onPop` handler |
|
241 method, if present, passing a `yield` resumption value; however, the |
|
242 `Debugger.Frame` instance remains live. |
|
243 |
|
244 If multiple [`Debugger`][debugger-object] instances each have |
|
245 `Debugger.Frame` instances for a given stack frame with `onPop` |
|
246 handlers set, their handlers are run in an unspecified order. The |
|
247 resumption value each handler returns establishes the completion value |
|
248 reported to the next handler. |
|
249 |
|
250 This property is ignored on `"debugger"` frames. |
|
251 |
|
252 `onResume` |
|
253 : This property must be either `undefined` or a function. If it is a |
|
254 function, SpiderMonkey calls it if the current frame is a generator |
|
255 frame whose execution has just been resumed. The function should return |
|
256 a [resumption value][rv] indicating how execution should proceed. On |
|
257 newly created frames, this property's value is `undefined`. |
|
258 |
|
259 If the program resumed the generator by calling its `send` method and |
|
260 passing a value, then <i>value</i> is that value. Otherwise, |
|
261 <i>value</i> is `undefined`. |
|
262 |
|
263 |
|
264 ## Function Properties of the Debugger.Frame Prototype Object |
|
265 |
|
266 The functions described below may only be called with a `this` value |
|
267 referring to a `Debugger.Frame` instance; they may not be used as |
|
268 methods of other kinds of objects. |
|
269 |
|
270 <code id="eval">eval(<i>code</i>, [<i>options</i>])</code> |
|
271 : Evaluate <i>code</i> in the execution context of this frame, and return |
|
272 a [completion value][cv] describing how it completed. <i>Code</i> is a |
|
273 string. If this frame's `environment` property is `null`, throw a |
|
274 `TypeError`. All extant handler methods, breakpoints, watchpoints, and |
|
275 so on remain active during the call. This function follows the |
|
276 [invocation function conventions][inv fr]. |
|
277 |
|
278 <i>Code</i> is interpreted as strict mode code when it contains a Use |
|
279 Strict Directive, or the code executing in this frame is strict mode |
|
280 code. |
|
281 |
|
282 If <i>code</i> is not strict mode code, then variable declarations in |
|
283 <i>code</i> affect the environment of this frame. (In the terms used by |
|
284 the ECMAScript specification, the `VariableEnvironment` of the |
|
285 execution context for the eval code is the `VariableEnvironment` of the |
|
286 execution context that this frame represents.) If implementation |
|
287 restrictions prevent SpiderMonkey from extending this frame's |
|
288 environment as requested, this call throws an Error exception. |
|
289 |
|
290 If given, <i>options</i> should be an object whose properties specify |
|
291 details of how the evaluation should occur. The `eval` method |
|
292 recognizes the following properties: |
|
293 |
|
294 <code>url</code> |
|
295 : The filename or URL to which we should attribute <i>code</i>. If this |
|
296 property is omitted, the URL defaults to `"debugger eval code"`. |
|
297 |
|
298 <code>lineNumber</code> |
|
299 : The line number at which the evaluated code should be claimed to begin |
|
300 within <i>url</i>. |
|
301 |
|
302 <code>evalWithBindings(<i>code</i>, <i>bindings</i>, [<i>options</i>])</code> |
|
303 : Like `eval`, but evaluate <i>code</i> in the environment of this frame, |
|
304 extended with bindings from the object <i>bindings</i>. For each own |
|
305 enumerable property of <i>bindings</i> named <i>name</i> whose value is |
|
306 <i>value</i>, include a variable in the environment in which |
|
307 <i>code</i> is evaluated named <i>name</i>, whose value is |
|
308 <i>value</i>. Each <i>value</i> must be a debuggee value. (This is not |
|
309 like a `with` statement: <i>code</i> may access, assign to, and delete |
|
310 the introduced bindings without having any effect on the |
|
311 <i>bindings</i> object.) |
|
312 |
|
313 This method allows debugger code to introduce temporary bindings that |
|
314 are visible to the given debuggee code and which refer to debugger-held |
|
315 debuggee values, and do so without mutating any existing debuggee |
|
316 environment. |
|
317 |
|
318 Note that, like `eval`, declarations in the <i>code</i> passed to |
|
319 `evalWithBindings` affect the environment of this frame, even as that |
|
320 environment is extended by bindings visible within <i>code</i>. (In the |
|
321 terms used by the ECMAScript specification, the `VariableEnvironment` |
|
322 of the execution context for the eval code is the `VariableEnvironment` |
|
323 of the execution context that this frame represents, and the |
|
324 <i>bindings</i> appear in a new declarative environment, which is the |
|
325 eval code's `LexicalEnvironment`.) If implementation restrictions |
|
326 prevent SpiderMonkey from extending this frame's environment as |
|
327 requested, this call throws an `Error` exception. |
|
328 |
|
329 The <i>options</i> argument is as for |
|
330 [`Debugger.Frame.prototype.eval`][fr eval], described above. |
|
331 |
|
332 <code>pop(<i>completion</i>)</code> <i>(future plan)</i> |
|
333 : Pop this frame (and any younger frames) from the stack as if this frame |
|
334 had completed as specified by the completion value <i>completion</i>. |
|
335 |
|
336 Note that this does <i>not</i> resume the debuggee's execution; it |
|
337 merely adjusts the debuggee's state to what it would be if this frame's |
|
338 execution had completed. The debuggee will only resume execution when |
|
339 you return from the handler method that brought control to the debugger |
|
340 originally. |
|
341 |
|
342 This cannot remove any `"call"` frames for calls to host functions from |
|
343 the stack. (We might be able to make this work eventually, but it will |
|
344 take some cleverness.) |
|
345 |
|
346 <code>replaceCall(<i>function</i>, <i>this</i>, <i>arguments</i>)</code> <i>(future plan)</i> |
|
347 : Pop any younger frames from the stack, and then change this frame into |
|
348 a frame for a call to <i>function</i>, with the given <i>this</i> value |
|
349 and <i>arguments</i>. <i>This</i> should be a debuggee value, or |
|
350 `{ asConstructor: true }` to invoke <i>function</i> as a constructor, |
|
351 in which case SpiderMonkey provides an appropriate `this` value itself. |
|
352 <i>Arguments</i> should be an array of debuggee values. This frame must |
|
353 be a `"call"` frame. |
|
354 |
|
355 This can be used as a primitive in implementing some forms of a "patch |
|
356 and continue" debugger feature. |
|
357 |
|
358 Note that this does <i>not</i> resume the debuggee's execution; it |
|
359 merely adjusts the debuggee's state to what it would be if this frame |
|
360 were about to make this call. The debuggee will only resume execution |
|
361 when you return from the handler method that brought control to the |
|
362 debugger originally. |
|
363 |
|
364 Like `pop`, this cannot remove `"call"` frames for calls to host |
|
365 functions from the stack. |
|
366 |
|
367 |
|
368 ## Generator Frames |
|
369 |
|
370 <i>Not all behavior described in this section has been implemented |
|
371 yet.</i> |
|
372 |
|
373 SpiderMonkey supports generator-iterator objects, which produce a series of |
|
374 values by repeatedly suspending the execution of a function or expression. |
|
375 For example, calling a function that uses `yield` produces a |
|
376 generator-iterator object, as does evaluating a generator expression like |
|
377 `(i*i for each (i in [1,2,3]))`. |
|
378 |
|
379 A generator-iterator object refers to a stack frame with no fixed |
|
380 continuation frame. While the generator's code is running, its continuation |
|
381 is whatever frame called its `next` method; while the generator is |
|
382 suspended, it has no particular continuation frame; and when it resumes |
|
383 again, the continuation frame for that resumption could be different from |
|
384 that of the previous resumption. |
|
385 |
|
386 A `Debugger.Frame` instance representing a generator frame differs from an |
|
387 ordinary stack frame as follows: |
|
388 |
|
389 * A generator frame's `generator` property is true. |
|
390 |
|
391 * A generator frame disappears from the stack each time the generator |
|
392 yields a value and is suspended, and reappears atop the stack when it is |
|
393 resumed to produce the generator's next value. The same `Debugger.Frame` |
|
394 instance refers to the generator frame until it returns, throws an |
|
395 exception, or is terminated. |
|
396 |
|
397 * A generator frame's `older` property refers to the frame's continuation |
|
398 frame while the generator is running, and is `null` while the generator |
|
399 is suspended. |
|
400 |
|
401 * A generator frame's `depth` property reflects the frame's position on |
|
402 the stack when the generator is resumed, and is `null` while the |
|
403 generator is suspended. |
|
404 |
|
405 * A generator frame's `live` property remains true until the frame |
|
406 returns, throws an exception, or is terminated. Thus, generator frames |
|
407 can be live while not present on the stack. |
|
408 |
|
409 The other `Debugger.Frame` methods and accessor properties work as |
|
410 described on generator frames, even when the generator frame is suspended. |
|
411 You may examine a suspended generator frame's variables, and use its |
|
412 `script` and `offset` members to see which `yield` it is suspended at. |
|
413 |
|
414 A `Debugger.Frame` instance referring to a generator-iterator frame has a |
|
415 strong reference to the generator-iterator object; the frame (and its |
|
416 object) will live as long as the `Debugger.Frame` instance does. However, |
|
417 when the generator function returns, throws an exception, or is terminated, |
|
418 thus ending the iteration, the `Debugger.Frame` instance becomes inactive |
|
419 and its `live` property becomes `false`, just as would occur for any other |
|
420 sort of frame that is popped. A non-live `Debugger.Frame` instance no |
|
421 longer holds a strong reference to the generator-iterator object. |