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