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.Environment |
michael@0 | 2 | |
michael@0 | 3 | A `Debugger.Environment` instance represents a lexical environment, |
michael@0 | 4 | associating names with variables. Each [`Debugger.Frame`][frame] instance |
michael@0 | 5 | representing a debuggee frame has an associated environment object |
michael@0 | 6 | describing the variables in scope in that frame; and each |
michael@0 | 7 | [`Debugger.Object`][object] instance representing a debuggee function has an |
michael@0 | 8 | environment object representing the environment the function has closed |
michael@0 | 9 | over. |
michael@0 | 10 | |
michael@0 | 11 | ECMAScript environments form a tree, in which each local environment is |
michael@0 | 12 | parented by its enclosing environment (in ECMAScript terms, its 'outer' |
michael@0 | 13 | environment). We say an environment <i>binds</i> an identifier if that |
michael@0 | 14 | environment itself associates the identifier with a variable, independently |
michael@0 | 15 | of its outer environments. We say an identifier is <i>in scope</i> in an |
michael@0 | 16 | environment if the identifier is bound in that environment or any enclosing |
michael@0 | 17 | environment. |
michael@0 | 18 | |
michael@0 | 19 | SpiderMonkey creates `Debugger.Environment` instances as needed as the |
michael@0 | 20 | debugger inspects stack frames and function objects; calling |
michael@0 | 21 | `Debugger.Environment` as a function or constructor raises a `TypeError` |
michael@0 | 22 | exception. |
michael@0 | 23 | |
michael@0 | 24 | SpiderMonkey creates exactly one `Debugger.Environment` instance for each |
michael@0 | 25 | environment it presents via a given [`Debugger`][debugger-object] instance: |
michael@0 | 26 | if the debugger encounters the same environment through two different |
michael@0 | 27 | routes (perhaps two functions have closed over the same environment), |
michael@0 | 28 | SpiderMonkey presents the same `Debugger.Environment` instance to the |
michael@0 | 29 | debugger each time. This means that the debugger can use the `==` operator |
michael@0 | 30 | to recognize when two `Debugger.Environment` instances refer to the same |
michael@0 | 31 | environment in the debuggee, and place its own properties on a |
michael@0 | 32 | `Debugger.Environment` instance to store metadata about particular |
michael@0 | 33 | environments. |
michael@0 | 34 | |
michael@0 | 35 | (If more than one [`Debugger`][debugger-object] instance is debugging the |
michael@0 | 36 | same code, each [`Debugger`][debugger-object] gets a separate |
michael@0 | 37 | `Debugger.Environment` instance for a given environment. This allows the |
michael@0 | 38 | code using each [`Debugger`][debugger-object] instance to place whatever |
michael@0 | 39 | properties it likes on its own [`Debugger.Object`][object] instances, |
michael@0 | 40 | without worrying about interfering with other debuggers.) |
michael@0 | 41 | |
michael@0 | 42 | If a `Debugger.Environment` instance's referent is not a debuggee |
michael@0 | 43 | environment, then attempting to access its properties (other than |
michael@0 | 44 | `inspectable`) or call any its methods throws an instance of `Error`. |
michael@0 | 45 | |
michael@0 | 46 | `Debugger.Environment` instances protect their referents from the |
michael@0 | 47 | garbage collector; as long as the `Debugger.Environment` instance is |
michael@0 | 48 | live, the referent remains live. Garbage collection has no visible |
michael@0 | 49 | effect on `Debugger.Environment` instances. |
michael@0 | 50 | |
michael@0 | 51 | |
michael@0 | 52 | ## Accessor Properties of the Debugger.Environment Prototype Object |
michael@0 | 53 | |
michael@0 | 54 | A `Debugger.Environment` instance inherits the following accessor |
michael@0 | 55 | properties from its prototype: |
michael@0 | 56 | |
michael@0 | 57 | `inspectable` |
michael@0 | 58 | : True if this environment is a debuggee environment, and can therefore |
michael@0 | 59 | be inspected. False otherwise. All other properties and methods of |
michael@0 | 60 | `Debugger.Environment` instances throw if applied to a non-inspectable |
michael@0 | 61 | environment. |
michael@0 | 62 | |
michael@0 | 63 | `type` |
michael@0 | 64 | : The type of this environment object, one of the following values: |
michael@0 | 65 | |
michael@0 | 66 | * "declarative", indicating that the environment is a declarative |
michael@0 | 67 | environment record. Function calls, calls to `eval`, `let` blocks, |
michael@0 | 68 | `catch` blocks, and the like create declarative environment records. |
michael@0 | 69 | |
michael@0 | 70 | * "object", indicating that the environment's bindings are the |
michael@0 | 71 | properties of an object. The global object and DOM elements appear in |
michael@0 | 72 | the chain of environments via object environments. (Note that `with` |
michael@0 | 73 | statements have their own environment type.) |
michael@0 | 74 | |
michael@0 | 75 | * "with", indicating that the environment was introduced by a `with` |
michael@0 | 76 | statement. |
michael@0 | 77 | |
michael@0 | 78 | `parent` |
michael@0 | 79 | : The environment that encloses this one (the "outer" environment, in |
michael@0 | 80 | ECMAScript terminology), or `null` if this is the outermost environment. |
michael@0 | 81 | |
michael@0 | 82 | `object` |
michael@0 | 83 | : A [`Debugger.Object`][object] instance referring to the object whose |
michael@0 | 84 | properties this environment reflects. If this is a declarative |
michael@0 | 85 | environment record, this accessor throws a `TypeError` (since |
michael@0 | 86 | declarative environment records have no such object). Both `"object"` |
michael@0 | 87 | and `"with"` environments have `object` properties that provide the |
michael@0 | 88 | object whose properties they reflect as variable bindings. |
michael@0 | 89 | |
michael@0 | 90 | `callee` |
michael@0 | 91 | : If this environment represents the variable environment (the top-level |
michael@0 | 92 | environment within the function, which receives `var` definitions) for |
michael@0 | 93 | a call to a function <i>f</i>, then this property's value is a |
michael@0 | 94 | [`Debugger.Object`][object] instance referring to <i>f</i>. Otherwise, |
michael@0 | 95 | this property's value is `null`. |
michael@0 | 96 | |
michael@0 | 97 | |
michael@0 | 98 | |
michael@0 | 99 | ## Function Properties of the Debugger.Environment Prototype Object |
michael@0 | 100 | |
michael@0 | 101 | The methods described below may only be called with a `this` value |
michael@0 | 102 | referring to a `Debugger.Environment` instance; they may not be used as |
michael@0 | 103 | methods of other kinds of objects. |
michael@0 | 104 | |
michael@0 | 105 | `names()` |
michael@0 | 106 | : Return an array of strings giving the names of the identifiers bound by |
michael@0 | 107 | this environment. The result does not include the names of identifiers |
michael@0 | 108 | bound by enclosing environments. |
michael@0 | 109 | |
michael@0 | 110 | <code>getVariable(<i>name</i>)</code> |
michael@0 | 111 | : Return the value of the variable bound to <i>name</i> in this |
michael@0 | 112 | environment, or `undefined` if this environment does not bind |
michael@0 | 113 | <i>name</i>. <i>Name</i> must be a string that is a valid ECMAScript |
michael@0 | 114 | identifier name. The result is a debuggee value. |
michael@0 | 115 | |
michael@0 | 116 | JavaScript engines often omit variables from environments, to save space |
michael@0 | 117 | and reduce execution time. If the given variable should be in scope, but |
michael@0 | 118 | `getVariable` is unable to produce its value, it returns an ordinary |
michael@0 | 119 | JavaScript object (not a [`Debugger.Object`][object] instance) whose |
michael@0 | 120 | `optimizedOut` property is `true`. |
michael@0 | 121 | |
michael@0 | 122 | This is not an [invocation function][inv fr]; |
michael@0 | 123 | if this call would cause debuggee code to run (say, because the |
michael@0 | 124 | environment is a `"with"` environment, and <i>name</i> refers to an |
michael@0 | 125 | accessor property of the `with` statement's operand), this call throws a |
michael@0 | 126 | [`Debugger.DebuggeeWouldRun`][wouldrun] |
michael@0 | 127 | exception. |
michael@0 | 128 | |
michael@0 | 129 | <code>setVariable(<i>name</i>, <i>value</i>)</code> |
michael@0 | 130 | : Store <i>value</i> as the value of the variable bound to <i>name</i> in |
michael@0 | 131 | this environment. <i>Name</i> must be a string that is a valid |
michael@0 | 132 | ECMAScript identifier name; <i>value</i> must be a debuggee value. |
michael@0 | 133 | |
michael@0 | 134 | If this environment binds no variable named <i>name</i>, throw a |
michael@0 | 135 | `ReferenceError`. |
michael@0 | 136 | |
michael@0 | 137 | This is not an [invocation function][inv fr]; |
michael@0 | 138 | if this call would cause debuggee code to run, this call throws a |
michael@0 | 139 | [`Debugger.DebuggeeWouldRun`][wouldrun] |
michael@0 | 140 | exception. |
michael@0 | 141 | |
michael@0 | 142 | <code>getVariableDescriptor(<i>name</i>)</code> |
michael@0 | 143 | : Return an property descriptor describing the variable bound to |
michael@0 | 144 | <i>name</i> in this environment, of the sort returned by |
michael@0 | 145 | `Debugger.Object.prototype.getOwnPropertyDescriptor`. <i>Name</i> must |
michael@0 | 146 | be a string whose value is a valid ECMAScript identifier name. |
michael@0 | 147 | |
michael@0 | 148 | If this is an `"object"` or `"with"` environment record, this simply |
michael@0 | 149 | returns the descriptor for the given property of the environment's |
michael@0 | 150 | object. If this is a declarative environment record, this returns a |
michael@0 | 151 | descriptor reflecting the binding's mutability as the descriptor's |
michael@0 | 152 | `writable` property, and its deletability as the descriptor's |
michael@0 | 153 | `configurable` property. All declarative environment record bindings are |
michael@0 | 154 | marked as `enumerable`. <i>(This isn't great; the semantics of variables |
michael@0 | 155 | in declarative enviroments don't really match those of properties, so |
michael@0 | 156 | writing code that operates properly on descriptors for either kind may |
michael@0 | 157 | be difficult.)</i> |
michael@0 | 158 | |
michael@0 | 159 | If this environment binds no variable named <i>name</i>, throw a |
michael@0 | 160 | `ReferenceError`. |
michael@0 | 161 | |
michael@0 | 162 | <code>defineVariable(<i>name</i>, <i>descriptor</i>)</code> |
michael@0 | 163 | : Create or reconfigure the variable bound to <i>name</i> in this |
michael@0 | 164 | environment according to <i>descriptor</i>. <i>Descriptor</i> is the |
michael@0 | 165 | sort of value returned by `getVariableDescriptor`. On success, return |
michael@0 | 166 | `undefined`; on failure, throw an appropriate exception. <i>Name</i> |
michael@0 | 167 | must be a string whose value is a valid ECMAScript identifier name. |
michael@0 | 168 | |
michael@0 | 169 | If implementation restrictions prevent SpiderMonkey from creating or |
michael@0 | 170 | reconfiguring the variable as requested, this call throws an `Error` |
michael@0 | 171 | exception. |
michael@0 | 172 | |
michael@0 | 173 | <code>deleteVariable(<i>name</i>)</code> |
michael@0 | 174 | : Delete this environment's binding for <i>name</i>. |
michael@0 | 175 | |
michael@0 | 176 | If this environment binds no variable named <i>name</i>, throw a |
michael@0 | 177 | `ReferenceError`. |
michael@0 | 178 | |
michael@0 | 179 | If implementation restrictions prevent SpiderMonkey from deleting the |
michael@0 | 180 | variable as requested, this call throws an `Error` exception. |
michael@0 | 181 | |
michael@0 | 182 | <code>find(<i>name</i>)</code> |
michael@0 | 183 | : Return a reference to the innermost environment, starting with this |
michael@0 | 184 | environment, that binds <i>name</i>. If <i>name</i> is not in scope in |
michael@0 | 185 | this environment, return `null`. <i>Name</i> must be a string whose |
michael@0 | 186 | value is a valid ECMAScript identifier name. |
michael@0 | 187 | |
michael@0 | 188 | <code>eval(<i>code</i>)</code> <i>(future plan)</i> |
michael@0 | 189 | : Evaluate <i>code</i> in this environment, and return a |
michael@0 | 190 | [completion value][cv] describing how it completed. <i>Code</i> is a |
michael@0 | 191 | string. All extant handler methods, breakpoints, watchpoints, and so on |
michael@0 | 192 | remain active during the call. This function follows the |
michael@0 | 193 | [invocation function conventions][inv fr]. |
michael@0 | 194 | |
michael@0 | 195 | <i>Code</i> is interpreted as strict mode code when it contains a Use |
michael@0 | 196 | Strict Directive. |
michael@0 | 197 | |
michael@0 | 198 | If <i>code</i> is not strict mode code, then variable declarations in |
michael@0 | 199 | <i>code</i> affect this environment. (In the terms used by the |
michael@0 | 200 | ECMAScript specification, the `VariableEnvironment` of the execution |
michael@0 | 201 | context for the eval code is the `VariableEnvironment` this |
michael@0 | 202 | `Debugger.Environment` instance represents.) If implementation |
michael@0 | 203 | restrictions prevent SpiderMonkey from extending this environment as |
michael@0 | 204 | requested, this call throws an `Error` exception. |
michael@0 | 205 | |
michael@0 | 206 | <code>evalWithBindings(<i>code</i>, <i>bindings</i>)</code> <i>(future plan)</i> |
michael@0 | 207 | : Like `eval`, but evaluate <i>code</i> in this environment, extended with |
michael@0 | 208 | bindings from the object <i>bindings</i>. For each own enumerable |
michael@0 | 209 | property of <i>bindings</i> named <i>name</i> whose value is |
michael@0 | 210 | <i>value</i>, include a variable in the environment in which <i>code</i> |
michael@0 | 211 | is evaluated named <i>name</i>, whose value is <i>value</i>. Each |
michael@0 | 212 | <i>value</i> must be a debuggee value. (This is not like a `with` |
michael@0 | 213 | statement: <i>code</i> may access, assign to, and delete the introduced |
michael@0 | 214 | bindings without having any effect on the <i>bindings</i> object.) |
michael@0 | 215 | |
michael@0 | 216 | This method allows debugger code to introduce temporary bindings that |
michael@0 | 217 | are visible to the given debuggee code and which refer to debugger-held |
michael@0 | 218 | debuggee values, and do so without mutating any existing debuggee |
michael@0 | 219 | environment. |
michael@0 | 220 | |
michael@0 | 221 | Note that, like `eval`, declarations in the <i>code</i> passed to |
michael@0 | 222 | `evalWithBindings` affect this environment, even as <i>code</i> is |
michael@0 | 223 | evaluated with <i>bindings</i> visible. (In the terms used by the |
michael@0 | 224 | ECMAScript specification, the `VariableEnvironment` of the execution |
michael@0 | 225 | context for the eval code is the `VariableEnvironment` this environment |
michael@0 | 226 | represents, and the <i>bindings</i> appear in a new declarative |
michael@0 | 227 | environment, which is the eval code's `LexicalEnvironment`.) If |
michael@0 | 228 | implementation restrictions prevent SpiderMonkey from extending this |
michael@0 | 229 | environment as requested, this call throws an `Error` exception. |
michael@0 | 230 | |
michael@0 | 231 |