Confirmed users
497
edits
(→Debugging hooks: Describe "slow script"-style termination. Explain what non-function code is.) |
(→Debug.Frame: First cut.) |
||
| Line 104: | Line 104: | ||
==Debug.Frame== | ==Debug.Frame== | ||
A <code>Debug.Frame</code> instance represents a debuggee stack frame. It provides operations for finding the script the frame is executing, the frame that invoked it, and the lexical scope in which the execution is taking place. | |||
A <code>Debug.Frame</code> instance is a weak reference to the frame; once the debuggee destroys the frame (perhaps by returning from a function or completing an <code>eval</code> call), further operations on the <code>Debug.Frame</code> instance will raise an error. | |||
SpiderMonkey creates instances of <code>Debug.Frame</code> as needed in two situations: when calling a hook function that expects a frame as an argument; and when an existing frame's <code>older</code> property is accessed. SpiderMonkey creates only one <code>Debug.Frame</code> instance for a given debuggee frame; every hook function called while the debuggee is running in a given frame receives the same frame object. Thus, debugger code can place its own properties on a frame object and expect to find them later, use <code>==</code> to decide whether two expressions refer to the same frame, and so on. | |||
A <code>Debug.Frame</code> instance has the following properties, which are all non-writable and non-configurable: | |||
<dl> | |||
<dt>type | |||
<dd>A string describing what sort of frame this is: | |||
<ul> | |||
<li><code>"call"</code>: a frame running a function that was called. | |||
<li><code>"eval"</code>: a frame running code passed to <code>eval</code>. | |||
<li><code>"global"</code>: a frame running global code (JavaScript that is neither of the above) | |||
<li><code>"host"</code>: a frame for a call to a host function (I'm not sure if we can obtain these) | |||
<li><code>"debugger"</code>: a frame for a call to user code invoked by the debugger | |||
<li><code>"dummy"</code>: a frame pushed for stupid people (rather—I don't know what this is) | |||
</ul> | |||
</dl> | |||
(Note that a <code>"debugger"</code> frame represents the debugger continuation expecting the expression's value; the expression itself has its own <code>"eval"</code> frame.) | |||
<dt>older | |||
<dd>The frame in which control will resume when this frame completes. | |||
<dt>depth | |||
<dd>The depth of this frame, counting the oldest frame as frame zero. | |||
<dt>callee | |||
<dd>The function whose application created this frame. Present only on <code>"call"</code> and <code>"host"</code> frames. | |||
<dt>generator | |||
<dd>True if this frame is a generator frame; false otherwise. Present only on frames whose type is <code>"call"</code>. | |||
<dt>constructing | |||
<dd>True if this frame is for a function called as a constructor. Present on <code>"call"</code> and <code>"host"</code> frames. | |||
<dt>script | |||
<dd>The script being executed in this frame (a <code>Debug.Script</code> instance). Present on <code>"call"</code>, <code>"eval"</code>, and <code>"global"</code> frames. On <code>"call"</code> frames, this is equal to <code>callee.script</code>. | |||
<dt>offset | |||
<dd>The offset of the bytecode instruction currently being executed in <code>script</code>. Present when <code>script</code> is. | |||
<dt>environment | |||
<dd>The lexical environment within which evaluation is taking place (a debuggee value). Present on <code>"call"</code>, <code>"eval"</code>, and <code>"global"</code> frames. | |||
<dt>this | |||
<dd>The value of <code>this</code> for the current frame&mdash (a debuggee value). Present on <code>"call"</code>, <code>"eval"</code>, and <code>"host"</code> frames. | |||
<dt>arguments | |||
<dd>The arguments passed to the current frame, as an array of debuggee values. (The array itself is an ordinary array in the debugger compartment.) Present on <code>"call"</code>, <code>"eval"</code>, and <code>"host"</code> frames. | |||
</dl> | |||
A <code>Debug.Frame</code> instance has the following methods: | |||
<dl> | |||
<dt>eval(<i>code</i>) | |||
<dd>Begin evaluating <i>code</i> in the scope of this frame. <i>Code</i> is a string. This pushes a <code>"debugger"</code> frame on the debuggee's stack, evaluates <i>code</i> with all extant hook functions active, and returns a value of the sort passed to an <code>enterFrame</code> completion function describing how the code completed. | |||
<dt>finish(<i>result</i>) <i>(future plan)</i> | |||
<dd>Pop this frame (and any younger frames) from the stack as if this frame had completed. <i>Result</i> is a value of the sort that the <code>interrupt</code> hook might return, indicating how execution should be prepared to continue. Note that this does <emph>not</emph> resume the debuggee's execution; it merely adjusts the debuggee's state to what it would be if this frame's execution had completed. You must return <code>true</code> from the hook function to resume execution in that state. | |||
This cannot remove any <code>"host"</code> frames (calls through C++) from the stack. (With some clever hacking we might be able to make this work, but it would be ugly.) | |||
<dt>restart(<i>function</i>, <i>this</i>, <i>arguments</i>) <i>(future plan)</i> | |||
<dd>Pop any younger frames from the stack, and then turn this frame into a frame about to begin executing <i>function</i>, with the given <i>this</i> value and <i>arguments</i>. <i>This</i> should be a debuggee value, or <code>{ asConstructor: true }</code> to invoke <i>function</i> as a constructor. <i>Arguments</i> should be an array of debuggee values. This frame must be a <code>"call"</code> frame. Note that this does <emph>not</emph> resume the debuggee's execution; it merely adjusts the debuggee's state to what it would be if this frame were about to make this call. You must return <code>true</code> from the hook function to resume execution in that state. | |||
Like <code>finish</code>, this cannot remove <code>"host"</code> frames from the stack. | |||
</dl> | |||
===Generator Frames=== | |||
SpiderMonkey supports generator-iterator objects, which produce a series of values by repeatedly suspending the execution of a function or expression. For example, calling a function that uses <code>yield</code> produces a generator-iterator object, as does evaluating a generator expression. | |||
A generator-iterator object refers to a stack frame with no fixed continuation frame. While the generator's code is running, its continuation is whatever frame called its <code>next</code> method; while the generator is suspended, it has no particular continuation frame; and when it resumes again, the continuation frame for that resumption could be different from that of the previous resumption. | |||
When you use the <code>Debug</code> object to inspect a program that is running a generator frame, that frame appears on the stack like any other call frame, except that its <code>generator</code> property is <code>true</code>. Such a frame will disappear from the stack when it is suspended, and reappear (possibly with a different <code>older</code> frame) each time it is resumed. | |||
==Debug.Script== | ==Debug.Script== | ||