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.Object |
michael@0 | 2 | |
michael@0 | 3 | A `Debugger.Object` instance represents an object in the debuggee, |
michael@0 | 4 | providing reflection-oriented methods to inspect and modify its referent. |
michael@0 | 5 | The referent's properties do not appear directly as properties of the |
michael@0 | 6 | `Debugger.Object` instance; the debugger can access them only through |
michael@0 | 7 | methods like `Debugger.Object.prototype.getOwnPropertyDescriptor` and |
michael@0 | 8 | `Debugger.Object.prototype.defineProperty`, ensuring that the debugger will |
michael@0 | 9 | not inadvertently invoke the referent's getters and setters. |
michael@0 | 10 | |
michael@0 | 11 | SpiderMonkey creates exactly one `Debugger.Object` instance for each |
michael@0 | 12 | debuggee object it presents to a given [`Debugger`][debugger-object] |
michael@0 | 13 | instance: if the debugger encounters the same object through two different |
michael@0 | 14 | routes (perhaps two functions are called on the same object), SpiderMonkey |
michael@0 | 15 | presents the same `Debugger.Object` instance to the debugger each time. |
michael@0 | 16 | This means that the debugger can use the `==` operator to recognize when |
michael@0 | 17 | two `Debugger.Object` instances refer to the same debuggee object, and |
michael@0 | 18 | place its own properties on a `Debugger.Object` instance to store metadata |
michael@0 | 19 | about particular debuggee objects. |
michael@0 | 20 | |
michael@0 | 21 | JavaScript code in different compartments can have different views of the |
michael@0 | 22 | same object. For example, in Firefox, code in privileged compartments sees |
michael@0 | 23 | content DOM element objects without redefinitions or extensions made to |
michael@0 | 24 | that object's properties by content code. (In Firefox terminology, |
michael@0 | 25 | privileged code sees the element through an "xray wrapper".) To ensure that |
michael@0 | 26 | debugger code sees each object just as the debuggee would, each |
michael@0 | 27 | `Debugger.Object` instance presents its referent as it would be seen from a |
michael@0 | 28 | particular compartment. This "viewing compartment" is chosen to match the |
michael@0 | 29 | way the debugger came across the referent. As a consequence, a single |
michael@0 | 30 | [`Debugger`][debugger-object] instance may actually have several |
michael@0 | 31 | `Debugger.Object` instances: one for each compartment from which the |
michael@0 | 32 | referent is viewed. |
michael@0 | 33 | |
michael@0 | 34 | If more than one [`Debugger`][debugger-object] instance is debugging the |
michael@0 | 35 | same code, each [`Debugger`][debugger-object] gets a separate |
michael@0 | 36 | `Debugger.Object` instance for a given object. This allows the code using |
michael@0 | 37 | each [`Debugger`][debugger-object] instance to place whatever properties it |
michael@0 | 38 | likes on its own `Debugger.Object` instances, without worrying about |
michael@0 | 39 | interfering with other debuggers. |
michael@0 | 40 | |
michael@0 | 41 | While most `Debugger.Object` instances are created by SpiderMonkey in the |
michael@0 | 42 | process of exposing debuggee's behavior and state to the debugger, the |
michael@0 | 43 | debugger can use `Debugger.Object.prototype.makeDebuggeeValue` to create |
michael@0 | 44 | `Debugger.Object` instances for given debuggee objects, or use |
michael@0 | 45 | `Debugger.Object.prototype.copy` and `Debugger.Object.prototype.create` to |
michael@0 | 46 | create new objects in debuggee compartments, allocated as if by particular |
michael@0 | 47 | debuggee globals. |
michael@0 | 48 | |
michael@0 | 49 | `Debugger.Object` instances protect their referents from the garbage |
michael@0 | 50 | collector; as long as the `Debugger.Object` instance is live, the referent |
michael@0 | 51 | remains live. This means that garbage collection has no visible effect on |
michael@0 | 52 | `Debugger.Object` instances. |
michael@0 | 53 | |
michael@0 | 54 | |
michael@0 | 55 | ## Accessor Properties of the Debugger.Object prototype |
michael@0 | 56 | |
michael@0 | 57 | A `Debugger.Object` instance inherits the following accessor properties |
michael@0 | 58 | from its prototype: |
michael@0 | 59 | |
michael@0 | 60 | `proto` |
michael@0 | 61 | : The referent's prototype (as a new `Debugger.Object` instance), or |
michael@0 | 62 | `null` if it has no prototype. |
michael@0 | 63 | |
michael@0 | 64 | `class` |
michael@0 | 65 | : A string naming the ECMAScript `[[Class]]` of the referent. |
michael@0 | 66 | |
michael@0 | 67 | `callable` |
michael@0 | 68 | : `true` if the referent is a callable object (such as a function or a |
michael@0 | 69 | function proxy); false otherwise. |
michael@0 | 70 | |
michael@0 | 71 | `name` |
michael@0 | 72 | : The name of the referent, if it is a named function. If the referent is |
michael@0 | 73 | an anonymous function, or not a function at all, this is `undefined`. |
michael@0 | 74 | |
michael@0 | 75 | This accessor returns whatever name appeared after the `function` |
michael@0 | 76 | keyword in the source code, regardless of whether the function is the |
michael@0 | 77 | result of instantiating a function declaration (which binds the |
michael@0 | 78 | function to its name in the enclosing scope) or evaluating a function |
michael@0 | 79 | expression (which binds the function to its name only within the |
michael@0 | 80 | function's body). |
michael@0 | 81 | |
michael@0 | 82 | `displayName` |
michael@0 | 83 | : The referent's display name, if the referent is a function with a |
michael@0 | 84 | display name. If the referent is not a function, or if it has no display |
michael@0 | 85 | name, this is `undefined`. |
michael@0 | 86 | |
michael@0 | 87 | If a function has a given name, its display name is the same as its |
michael@0 | 88 | given name. In this case, the `displayName` and `name` properties are |
michael@0 | 89 | equal. |
michael@0 | 90 | |
michael@0 | 91 | If a function has no name, SpiderMonkey attempts to infer an appropriate |
michael@0 | 92 | name for it given its context. For example: |
michael@0 | 93 | |
michael@0 | 94 | function f() {} // display name: f (the given name) |
michael@0 | 95 | var g = function () {}; // display name: g |
michael@0 | 96 | o.p = function () {}; // display name: o.p |
michael@0 | 97 | var q = { |
michael@0 | 98 | r: function () {} // display name: q.r |
michael@0 | 99 | }; |
michael@0 | 100 | |
michael@0 | 101 | Note that the display name may not be a proper JavaScript identifier, |
michael@0 | 102 | or even a proper expression: we attempt to find helpful names even when |
michael@0 | 103 | the function is not immediately assigned as the value of some variable |
michael@0 | 104 | or property. Thus, we use <code><i>a</i>/<i>b</i></code> to refer to |
michael@0 | 105 | the <i>b</i> defined within <i>a</i>, and <code><i>a</i><</code> to |
michael@0 | 106 | refer to a function that occurs somewhere within an expression that is |
michael@0 | 107 | assigned to <i>a</i>. For example: |
michael@0 | 108 | |
michael@0 | 109 | function h() { |
michael@0 | 110 | var i = function() {}; // display name: h/i |
michael@0 | 111 | f(function () {}); // display name: h/< |
michael@0 | 112 | } |
michael@0 | 113 | var s = f(function () {}); // display name: s< |
michael@0 | 114 | |
michael@0 | 115 | `parameterNames` |
michael@0 | 116 | : If the referent is a debuggee function, the names of the its parameters, |
michael@0 | 117 | as an array of strings. If the referent is not a debuggee function, or |
michael@0 | 118 | not a function at all, this is `undefined`. |
michael@0 | 119 | |
michael@0 | 120 | If the referent is a host function for which parameter names are not |
michael@0 | 121 | available, return an array with one element per parameter, each of which |
michael@0 | 122 | is `undefined`. |
michael@0 | 123 | |
michael@0 | 124 | If the referent is a function proxy, return an empty array. |
michael@0 | 125 | |
michael@0 | 126 | If the referent uses destructuring parameters, then the array's elements |
michael@0 | 127 | reflect the structure of the parameters. For example, if the referent is |
michael@0 | 128 | a function declared in this way: |
michael@0 | 129 | |
michael@0 | 130 | function f(a, [b, c], {d, e:f}) { ... } |
michael@0 | 131 | |
michael@0 | 132 | then this `Debugger.Object` instance's `parameterNames` property would |
michael@0 | 133 | have the value: |
michael@0 | 134 | |
michael@0 | 135 | ["a", ["b", "c"], {d:"d", e:"f"}] |
michael@0 | 136 | |
michael@0 | 137 | `script` |
michael@0 | 138 | : If the referent is a function that is debuggee code, this is that |
michael@0 | 139 | function's script, as a [`Debugger.Script`][script] instance. If the |
michael@0 | 140 | referent is a function proxy or not debuggee code, this is `undefined`. |
michael@0 | 141 | |
michael@0 | 142 | `environment` |
michael@0 | 143 | : If the referent is a function that is debuggee code, a |
michael@0 | 144 | [`Debugger.Environment`][environment] instance representing the lexical |
michael@0 | 145 | environment enclosing the function when it was created. If the referent |
michael@0 | 146 | is a function proxy or not debuggee code, this is `undefined`. |
michael@0 | 147 | |
michael@0 | 148 | `proxyHandler` |
michael@0 | 149 | : If the referent is a proxy whose handler object was allocated by |
michael@0 | 150 | debuggee code, this is its handler object—the object whose methods are |
michael@0 | 151 | invoked to implement accesses of the proxy's properties. If the referent |
michael@0 | 152 | is not a proxy whose handler object was allocated by debuggee code, this |
michael@0 | 153 | is `null`. |
michael@0 | 154 | |
michael@0 | 155 | `proxyCallTrap` |
michael@0 | 156 | : If the referent is a function proxy whose handler object was allocated |
michael@0 | 157 | by debuggee code, this is its call trap function—the function called |
michael@0 | 158 | when the function proxy is called. If the referent is not a function |
michael@0 | 159 | proxy whose handler object was allocated by debuggee code, this is |
michael@0 | 160 | `null`. |
michael@0 | 161 | |
michael@0 | 162 | `proxyConstructTrap` |
michael@0 | 163 | : If the referent is a function proxy whose handler object was allocated |
michael@0 | 164 | by debuggee code, its construction trap function—the function called |
michael@0 | 165 | when the function proxy is called via a `new` expression. If the |
michael@0 | 166 | referent is not a function proxy whose handler object was allocated by |
michael@0 | 167 | debuggee code, this is `null`. |
michael@0 | 168 | |
michael@0 | 169 | `global` |
michael@0 | 170 | : A `Debugger.Object` instance referring to the global object in whose |
michael@0 | 171 | scope the referent was allocated. This does not unwrap cross-compartment |
michael@0 | 172 | wrappers: if the referent is a wrapper, the result refers to the |
michael@0 | 173 | wrapper's global, not the wrapped object's global. The result refers to |
michael@0 | 174 | the global directly, not via a wrapper. |
michael@0 | 175 | |
michael@0 | 176 | `hostAnnotations` |
michael@0 | 177 | : A JavaScript object providing further metadata about the referent, or |
michael@0 | 178 | `null` if none is available. The metadata object is in the same |
michael@0 | 179 | compartment as this `Debugger.Object` instance. The same metadata |
michael@0 | 180 | object is returned each time for a given `Debugger.Object` instance. |
michael@0 | 181 | |
michael@0 | 182 | A typical JavaScript embedding provides "host objects" to expose |
michael@0 | 183 | application-specific functionality to scripts. The `hostAnnotations` |
michael@0 | 184 | accessor consults the embedding for additional information about the |
michael@0 | 185 | referent that might be of interest to the debugger. The returned |
michael@0 | 186 | object's properties' meanings are up to the embedding. For example, a |
michael@0 | 187 | web browser might provide host annotations for global objects to |
michael@0 | 188 | distinguish top-level windows, iframes, and internal JavaScript scopes. |
michael@0 | 189 | |
michael@0 | 190 | By convention, host annotation objects have a string-valued `"type"` |
michael@0 | 191 | property that, taken together with the object's class, indicate what |
michael@0 | 192 | sort of thing the referent is. The host annotation object's other |
michael@0 | 193 | properties provide further details, as appropriate for the type. For |
michael@0 | 194 | example, in Firefox, a metadata object for a JavaScript Module's global |
michael@0 | 195 | object might look like this: |
michael@0 | 196 | |
michael@0 | 197 | { "type":"jsm", "uri":"resource:://gre/modules/XPCOMUtils.jsm" } |
michael@0 | 198 | |
michael@0 | 199 | Firefox provides [DebuggerHostAnnotationsForFirefox annotations] for its |
michael@0 | 200 | host objects. |
michael@0 | 201 | |
michael@0 | 202 | |
michael@0 | 203 | |
michael@0 | 204 | ## Function Properties of the Debugger.Object prototype |
michael@0 | 205 | |
michael@0 | 206 | The functions described below may only be called with a `this` value |
michael@0 | 207 | referring to a `Debugger.Object` instance; they may not be used as methods |
michael@0 | 208 | of other kinds of objects. The descriptions use "referent" to mean "the |
michael@0 | 209 | referent of this `Debugger.Object` instance". |
michael@0 | 210 | |
michael@0 | 211 | Unless otherwise specified, these methods are not |
michael@0 | 212 | [invocation functions][inv fr]; if a call would cause debuggee code to run |
michael@0 | 213 | (say, because it gets or sets an accessor property whose handler is |
michael@0 | 214 | debuggee code, or because the referent is a proxy whose traps are debuggee |
michael@0 | 215 | code), the call throws a [`Debugger.DebuggeeWouldRun`][wouldrun] exception. |
michael@0 | 216 | |
michael@0 | 217 | <code>getProperty(<i>name</i>)</code> |
michael@0 | 218 | : Return the value of the referent's property named <i>name</i>, or |
michael@0 | 219 | `undefined` if it has no such property. <i>Name</i> must be a string. |
michael@0 | 220 | The result is a debuggee value. |
michael@0 | 221 | |
michael@0 | 222 | <code>setProperty(<i>name</i>, <i>value</i>)</code> |
michael@0 | 223 | : Store <i>value</i> as the value of the referent's property named |
michael@0 | 224 | <i>name</i>, creating the property if it does not exist. <i>Name</i> |
michael@0 | 225 | must be a string; <i>value</i> must be a debuggee value. |
michael@0 | 226 | |
michael@0 | 227 | <code>getOwnPropertyDescriptor(<i>name</i>)</code> |
michael@0 | 228 | : Return a property descriptor for the property named <i>name</i> of the |
michael@0 | 229 | referent. If the referent has no such property, return `undefined`. |
michael@0 | 230 | (This function behaves like the standard |
michael@0 | 231 | `Object.getOwnPropertyDescriptor` function, except that the object being |
michael@0 | 232 | inspected is implicit; the property descriptor returned is allocated as |
michael@0 | 233 | if by code scoped to the debugger's global object (and is thus in the |
michael@0 | 234 | debugger's compartment); and its `value`, `get`, and `set` properties, |
michael@0 | 235 | if present, are debuggee values.) |
michael@0 | 236 | |
michael@0 | 237 | `getOwnPropertyNames()` |
michael@0 | 238 | : Return an array of strings naming all the referent's own properties, as |
michael@0 | 239 | if <code>Object.getOwnPropertyNames(<i>referent</i>)</code> had been |
michael@0 | 240 | called in the debuggee, and the result copied in the scope of the |
michael@0 | 241 | debugger's global object. |
michael@0 | 242 | |
michael@0 | 243 | <code>defineProperty(<i>name</i>, <i>attributes</i>)</code> |
michael@0 | 244 | : Define a property on the referent named <i>name</i>, as described by |
michael@0 | 245 | the property descriptor <i>descriptor</i>. Any `value`, `get`, and |
michael@0 | 246 | `set` properties of <i>attributes</i> must be debuggee values. (This |
michael@0 | 247 | function behaves like `Object.defineProperty`, except that the target |
michael@0 | 248 | object is implicit, and in a different compartment from the function |
michael@0 | 249 | and descriptor.) |
michael@0 | 250 | |
michael@0 | 251 | <code>defineProperties(<i>properties</i>)</code> |
michael@0 | 252 | : Add the properties given by <i>properties</i> to the referent. (This |
michael@0 | 253 | function behaves like `Object.defineProperties`, except that the target |
michael@0 | 254 | object is implicit, and in a different compartment from the |
michael@0 | 255 | <i>properties</i> argument.) |
michael@0 | 256 | |
michael@0 | 257 | <code>deleteProperty(<i>name</i>)</code> |
michael@0 | 258 | : Remove the referent's property named <i>name</i>. Return true if the |
michael@0 | 259 | property was successfully removed, or if the referent has no such |
michael@0 | 260 | property. Return false if the property is non-configurable. |
michael@0 | 261 | |
michael@0 | 262 | `seal()` |
michael@0 | 263 | : Prevent properties from being added to or deleted from the referent. |
michael@0 | 264 | Return this `Debugger.Object` instance. (This function behaves like the |
michael@0 | 265 | standard `Object.seal` function, except that the object to be sealed is |
michael@0 | 266 | implicit and in a different compartment from the caller.) |
michael@0 | 267 | |
michael@0 | 268 | `freeze()` |
michael@0 | 269 | : Prevent properties from being added to or deleted from the referent, and |
michael@0 | 270 | mark each property as non-writable. Return this `Debugger.Object` |
michael@0 | 271 | instance. (This function behaves like the standard `Object.freeze` |
michael@0 | 272 | function, except that the object to be sealed is implicit and in a |
michael@0 | 273 | different compartment from the caller.) |
michael@0 | 274 | |
michael@0 | 275 | `preventExtensions()` |
michael@0 | 276 | : Prevent properties from being added to the referent. (This function |
michael@0 | 277 | behaves like the standard `Object.preventExtensions` function, except |
michael@0 | 278 | that the object to operate on is implicit and in a different compartment |
michael@0 | 279 | from the caller.) |
michael@0 | 280 | |
michael@0 | 281 | `isSealed()` |
michael@0 | 282 | : Return true if the referent is sealed—that is, if it is not extensible, |
michael@0 | 283 | and all its properties have been marked as non-configurable. (This |
michael@0 | 284 | function behaves like the standard `Object.isSealed` function, except |
michael@0 | 285 | that the object inspected is implicit and in a different compartment |
michael@0 | 286 | from the caller.) |
michael@0 | 287 | |
michael@0 | 288 | `isFrozen()` |
michael@0 | 289 | : Return true if the referent is frozen—that is, if it is not extensible, |
michael@0 | 290 | and all its properties have been marked as non-configurable and |
michael@0 | 291 | read-only. (This function behaves like the standard `Object.isFrozen` |
michael@0 | 292 | function, except that the object inspected is implicit and in a |
michael@0 | 293 | different compartment from the caller.) |
michael@0 | 294 | |
michael@0 | 295 | `isExtensible()` |
michael@0 | 296 | : Return true if the referent is extensible—that is, if it can have new |
michael@0 | 297 | properties defined on it. (This function behaves like the standard |
michael@0 | 298 | `Object.isExtensible` function, except that the object inspected is |
michael@0 | 299 | implicit and in a different compartment from the caller.) |
michael@0 | 300 | |
michael@0 | 301 | <code>copy(<i>value</i>)</code> |
michael@0 | 302 | : Apply the HTML5 "structured cloning" algorithm to create a copy of |
michael@0 | 303 | <i>value</i> in the referent's global object (and thus in the referent's |
michael@0 | 304 | compartment), and return a `Debugger.Object` instance referring to the |
michael@0 | 305 | copy. |
michael@0 | 306 | |
michael@0 | 307 | Note that this returns primitive values unchanged. This means you can |
michael@0 | 308 | use `Debugger.Object.prototype.copy` as a generic "debugger value to |
michael@0 | 309 | debuggee value" conversion function—within the limitations of the |
michael@0 | 310 | "structured cloning" algorithm. |
michael@0 | 311 | |
michael@0 | 312 | <code>create(<i>prototype</i>, [<i>properties</i>])</code> |
michael@0 | 313 | : Create a new object in the referent's global (and thus in the |
michael@0 | 314 | referent's compartment), and return a `Debugger.Object` referring to |
michael@0 | 315 | it. The new object's prototype is <i>prototype</i>, which must be an |
michael@0 | 316 | `Debugger.Object` instance. The new object's properties are as given by |
michael@0 | 317 | <i>properties</i>, as if <i>properties</i> were passed to |
michael@0 | 318 | `Debugger.Object.prototype.defineProperties`, with the new |
michael@0 | 319 | `Debugger.Object` instance as the `this` value. |
michael@0 | 320 | |
michael@0 | 321 | <code>makeDebuggeeValue(<i>value</i>)</code> |
michael@0 | 322 | : Return the debuggee value that represents <i>value</i> in the debuggee. |
michael@0 | 323 | If <i>value</i> is a primitive, we return it unchanged; if <i>value</i> |
michael@0 | 324 | is an object, we return the `Debugger.Object` instance representing |
michael@0 | 325 | that object, wrapped appropriately for use in this `Debugger.Object`'s |
michael@0 | 326 | referent's compartment. |
michael@0 | 327 | |
michael@0 | 328 | Note that, if <i>value</i> is an object, it need not be one allocated |
michael@0 | 329 | in a debuggee global, nor even a debuggee compartment; it can be any |
michael@0 | 330 | object the debugger wishes to use as a debuggee value. |
michael@0 | 331 | |
michael@0 | 332 | As described above, each `Debugger.Object` instance presents its |
michael@0 | 333 | referent as viewed from a particular compartment. Given a |
michael@0 | 334 | `Debugger.Object` instance <i>d</i> and an object <i>o</i>, the call |
michael@0 | 335 | <code><i>d</i>.makeDebuggeeValue(<i>o</i>)</code> returns a |
michael@0 | 336 | `Debugger.Object` instance that presents <i>o</i> as it would be seen |
michael@0 | 337 | by code in <i>d</i>'s compartment. |
michael@0 | 338 | |
michael@0 | 339 | <code>decompile([<i>pretty</i>])</code> |
michael@0 | 340 | : If the referent is a function that is debuggee code, return the |
michael@0 | 341 | JavaScript source code for a function definition equivalent to the |
michael@0 | 342 | referent function in its effect and result, as a string. If |
michael@0 | 343 | <i>pretty</i> is present and true, produce indented code with line |
michael@0 | 344 | breaks. If the referent is not a function that is debuggee code, return |
michael@0 | 345 | `undefined`. |
michael@0 | 346 | |
michael@0 | 347 | <code>call(<i>this</i>, <i>argument</i>, ...)</code> |
michael@0 | 348 | : If the referent is callable, call it with the given <i>this</i> value |
michael@0 | 349 | and <i>argument</i> values, and return a [completion value][cv] |
michael@0 | 350 | describing how the call completed. <i>This</i> should be a debuggee |
michael@0 | 351 | value, or `{ asConstructor: true }` to invoke the referent as a |
michael@0 | 352 | constructor, in which case SpiderMonkey provides an appropriate `this` |
michael@0 | 353 | value itself. Each <i>argument</i> must be a debuggee value. All extant |
michael@0 | 354 | handler methods, breakpoints, watchpoints, and so on remain active |
michael@0 | 355 | during the call. If the referent is not callable, throw a `TypeError`. |
michael@0 | 356 | This function follows the [invocation function conventions][inv fr]. |
michael@0 | 357 | |
michael@0 | 358 | <code>apply(<i>this</i>, <i>arguments</i>)</code> |
michael@0 | 359 | : If the referent is callable, call it with the given <i>this</i> value |
michael@0 | 360 | and the argument values in <i>arguments</i>, and return a |
michael@0 | 361 | [completion value][cv] describing how the call completed. <i>This</i> |
michael@0 | 362 | should be a debuggee value, or `{ asConstructor: true }` to invoke |
michael@0 | 363 | <i>function</i> as a constructor, in which case SpiderMonkey provides |
michael@0 | 364 | an appropriate `this` value itself. <i>Arguments</i> must either be an |
michael@0 | 365 | array (in the debugger) of debuggee values, or `null` or `undefined`, |
michael@0 | 366 | which are treated as an empty array. All extant handler methods, |
michael@0 | 367 | breakpoints, watchpoints, and so on remain active during the call. If |
michael@0 | 368 | the referent is not callable, throw a `TypeError`. This function |
michael@0 | 369 | follows the [invocation function conventions][inv fr]. |
michael@0 | 370 | |
michael@0 | 371 | <code>evalInGlobal(<i>code</i>, [<i>options</i>])</code> |
michael@0 | 372 | : If the referent is a global object, evaluate <i>code</i> in that global |
michael@0 | 373 | environment, and return a [completion value][cv] describing how it completed. |
michael@0 | 374 | <i>Code</i> is a string. All extant handler methods, breakpoints, |
michael@0 | 375 | watchpoints, and so on remain active during the call. This function |
michael@0 | 376 | follows the [invocation function conventions][inv fr]. |
michael@0 | 377 | If the referent is not a global object, throw a `TypeError` exception. |
michael@0 | 378 | |
michael@0 | 379 | <i>Code</i> is interpreted as strict mode code when it contains a Use |
michael@0 | 380 | Strict Directive. |
michael@0 | 381 | |
michael@0 | 382 | If <i>code</i> is not strict mode code, then variable declarations in |
michael@0 | 383 | <i>code</i> affect the referent global object. (In the terms used by the |
michael@0 | 384 | ECMAScript specification, the `VariableEnvironment` of the execution |
michael@0 | 385 | context for the eval code is the referent.) |
michael@0 | 386 | |
michael@0 | 387 | The <i>options</i> argument is as for [`Debugger.Frame.prototype.eval`][fr eval]. |
michael@0 | 388 | |
michael@0 | 389 | <code>evalInGlobalWithBindings(<i>code</i>, <i>bindings</i>, [<i>options</i>])</code> |
michael@0 | 390 | : Like `evalInGlobal`, but evaluate <i>code</i> using the referent as the |
michael@0 | 391 | variable object, but with a lexical environment extended with bindings |
michael@0 | 392 | from the object <i>bindings</i>. For each own enumerable property of |
michael@0 | 393 | <i>bindings</i> named <i>name</i> whose value is <i>value</i>, include a |
michael@0 | 394 | variable in the lexical environment in which <i>code</i> is evaluated |
michael@0 | 395 | named <i>name</i>, whose value is <i>value</i>. Each <i>value</i> must |
michael@0 | 396 | be a debuggee value. (This is not like a `with` statement: <i>code</i> |
michael@0 | 397 | may access, assign to, and delete the introduced bindings without having |
michael@0 | 398 | any effect on the <i>bindings</i> object.) |
michael@0 | 399 | |
michael@0 | 400 | This method allows debugger code to introduce temporary bindings that |
michael@0 | 401 | are visible to the given debuggee code and which refer to debugger-held |
michael@0 | 402 | debuggee values, and do so without mutating any existing debuggee |
michael@0 | 403 | environment. |
michael@0 | 404 | |
michael@0 | 405 | Note that, like `evalInGlobal`, if the code passed to |
michael@0 | 406 | `evalInGlobalWithBindings` is not strict mode code, then any |
michael@0 | 407 | declarations it contains affect the referent global object, even as |
michael@0 | 408 | <i>code</i> is evaluated in an environment extended according to |
michael@0 | 409 | <i>bindings</i>. (In the terms used by the ECMAScript specification, the |
michael@0 | 410 | `VariableEnvironment` of the execution context for non-strict eval code |
michael@0 | 411 | is the referent, and the <i>bindings</i> appear in a new declarative |
michael@0 | 412 | environment, which is the eval code's `LexicalEnvironment`.) |
michael@0 | 413 | |
michael@0 | 414 | The <i>options</i> argument is as for [`Debugger.Frame.prototype.eval`][fr eval]. |
michael@0 | 415 | |
michael@0 | 416 | `asEnvironment()` |
michael@0 | 417 | : If the referent is a global object, return the [`Debugger.Environment`][environment] |
michael@0 | 418 | instance representing the referent as a variable environment for |
michael@0 | 419 | evaluating code. If the referent is not a global object, throw a |
michael@0 | 420 | `TypeError`. |
michael@0 | 421 | |
michael@0 | 422 | <code>setObjectWatchpoint(<i>handler</i>)</code> <i>(future plan)</i> |
michael@0 | 423 | : Set a watchpoint on all the referent's own properties, reporting events |
michael@0 | 424 | by calling <i>handler</i>'s methods. Any previous watchpoint handler on |
michael@0 | 425 | this `Debugger.Object` instance is replaced. If <i>handler</i> is null, |
michael@0 | 426 | the referent is no longer watched. <i>Handler</i> may have the following |
michael@0 | 427 | methods, called under the given circumstances: |
michael@0 | 428 | |
michael@0 | 429 | <code>add(<i>frame</i>, <i>name</i>, <i>descriptor</i>)</code> |
michael@0 | 430 | : A property named <i>name</i> has been added to the referent. |
michael@0 | 431 | <i>Descriptor</i> is a property descriptor of the sort accepted by |
michael@0 | 432 | `Debugger.Object.prototype.defineProperty`, giving the newly added |
michael@0 | 433 | property's attributes. |
michael@0 | 434 | |
michael@0 | 435 | <code>delete(<i>frame</i>, <i>name</i>)</code> |
michael@0 | 436 | : The property named <i>name</i> is about to be deleted from the referent. |
michael@0 | 437 | |
michael@0 | 438 | <code>change(<i>frame</i>, <i>name</i>, <i>oldDescriptor</i>, <i>newDescriptor</i>)</code> |
michael@0 | 439 | : The existing property named <i>name</i> on the referent is being changed |
michael@0 | 440 | from those given by <i>oldDescriptor</i> to those given by |
michael@0 | 441 | <i>newDescriptor</i>. This handler method is only called when attributes |
michael@0 | 442 | of the property other than its value are being changed; if only the |
michael@0 | 443 | value is changing, SpiderMonkey calls the handler's `set` method. |
michael@0 | 444 | |
michael@0 | 445 | <code>set(<i>frame</i>, <i>oldValue</i>, <i>newValue</i>)</code> |
michael@0 | 446 | : The data property named <i>name</i> of the referent is about to have its |
michael@0 | 447 | value changed from <i>oldValue</i> to <i>newValue</i>. |
michael@0 | 448 | |
michael@0 | 449 | SpiderMonkey only calls this method on assignments to data properties |
michael@0 | 450 | that will succeed; assignments to un-writable data properties fail |
michael@0 | 451 | without notifying the debugger. |
michael@0 | 452 | |
michael@0 | 453 | <code>extensionsPrevented(<i>frame</i>)</code> |
michael@0 | 454 | : The referent has been made non-extensible, as if by a call to |
michael@0 | 455 | `Object.preventExtensions`. |
michael@0 | 456 | |
michael@0 | 457 | For all watchpoint handler methods: |
michael@0 | 458 | |
michael@0 | 459 | * Handler calls receive the handler object itself as the `this` value. |
michael@0 | 460 | |
michael@0 | 461 | * The <i>frame</i> argument is the current stack frame, whose code is |
michael@0 | 462 | about to perform the operation on the object being reported. |
michael@0 | 463 | |
michael@0 | 464 | * If the method returns `undefined`, then SpiderMonkey makes the announced |
michael@0 | 465 | change to the object, and continues execution normally. If the method |
michael@0 | 466 | returns an object: |
michael@0 | 467 | |
michael@0 | 468 | * If the object has a `superseded` property whose value is a true value, |
michael@0 | 469 | then SpiderMonkey does not make the announced change. |
michael@0 | 470 | |
michael@0 | 471 | * If the object has a `resume` property, its value is taken as a |
michael@0 | 472 | [resumption value][rv], indicating how |
michael@0 | 473 | execution should proceed. (However, `return` resumption values are not |
michael@0 | 474 | supported.) |
michael@0 | 475 | |
michael@0 | 476 | * If a given method is absent from <i>handler</i>, then events of that |
michael@0 | 477 | sort are ignored. The watchpoint consults <i>handler</i>'s properties |
michael@0 | 478 | each time an event occurs, so adding methods to or removing methods from |
michael@0 | 479 | <i>handler</i> after setting the watchpoint enables or disables |
michael@0 | 480 | reporting of the corresponding events. |
michael@0 | 481 | |
michael@0 | 482 | * Values passed to <i>handler</i>'s methods are debuggee values. |
michael@0 | 483 | Descriptors passed to <i>handler</i>'s methods are ordinary objects in |
michael@0 | 484 | the debugger's compartment, except for `value`, `get`, and `set` |
michael@0 | 485 | properties in descriptors, which are debuggee values; they are the sort |
michael@0 | 486 | of value expected by `Debugger.Object.prototype.defineProperty`. |
michael@0 | 487 | |
michael@0 | 488 | * Watchpoint handler calls are cross-compartment, intra-thread calls: the |
michael@0 | 489 | call takes place in the same thread that changed the property, and in |
michael@0 | 490 | <i>handler</i>'s method's compartment (typically the same as the |
michael@0 | 491 | debugger's compartment). |
michael@0 | 492 | |
michael@0 | 493 | The new watchpoint belongs to the [`Debugger`][debugger-object] instance to which this |
michael@0 | 494 | `Debugger.Object` instance belongs; disabling the [`Debugger`][debugger-object] instance |
michael@0 | 495 | disables this watchpoint. |
michael@0 | 496 | |
michael@0 | 497 | `clearObjectWatchpoint()` <i>(future plan)</i> |
michael@0 | 498 | : Remove any object watchpoint set on the referent. |
michael@0 | 499 | |
michael@0 | 500 | <code>setPropertyWatchpoint(<i>name</i>, <i>handler</i>)</code> <i>(future plan)</i> |
michael@0 | 501 | : Set a watchpoint on the referent's property named <i>name</i>, reporting |
michael@0 | 502 | events by calling <i>handler</i>'s methods. Any previous watchpoint |
michael@0 | 503 | handler on this property for this `Debugger.Object` instance is |
michael@0 | 504 | replaced. If <i>handler</i> is null, the property is no longer watched. |
michael@0 | 505 | <i>Handler</i> is as described for |
michael@0 | 506 | `Debugger.Object.prototype.setObjectWatchpoint`, except that it does not |
michael@0 | 507 | receive `extensionsPrevented` events. |
michael@0 | 508 | |
michael@0 | 509 | <code>clearPropertyWatchpoint(<i>name</i>)</code> <i>(future plan)</i> |
michael@0 | 510 | : Remove any watchpoint set on the referent's property named <i>name</i>. |
michael@0 | 511 | |
michael@0 | 512 | `unwrap()` |
michael@0 | 513 | : If the referent is a wrapper that this `Debugger.Object`'s compartment |
michael@0 | 514 | is permitted to unwrap, return a `Debugger.Object` instance referring to |
michael@0 | 515 | the wrapped object. If we are not permitted to unwrap the referent, |
michael@0 | 516 | return `null`. If the referent is not a wrapper, return this |
michael@0 | 517 | `Debugger.Object` instance unchanged. |
michael@0 | 518 | |
michael@0 | 519 | `unsafeDereference()` |
michael@0 | 520 | : Return the referent of this `Debugger.Object` instance. |
michael@0 | 521 | |
michael@0 | 522 | If the referent is an inner object (say, an HTML5 `Window` object), |
michael@0 | 523 | return the corresponding outer object (say, the HTML5 `WindowProxy` |
michael@0 | 524 | object). This makes `unsafeDereference` more useful in producing values |
michael@0 | 525 | appropriate for direct use by debuggee code, without using [invocation functions][inv fr]. |
michael@0 | 526 | |
michael@0 | 527 | This method pierces the membrane of `Debugger.Object` instances meant to |
michael@0 | 528 | protect debugger code from debuggee code, and allows debugger code to |
michael@0 | 529 | access debuggee objects through the standard cross-compartment wrappers, |
michael@0 | 530 | rather than via `Debugger.Object`'s reflection-oriented interfaces. This |
michael@0 | 531 | method makes it easier to gradually adapt large code bases to this |
michael@0 | 532 | Debugger API: adapted portions of the code can use `Debugger.Object` |
michael@0 | 533 | instances, but use this method to pass direct object references to code |
michael@0 | 534 | that has not yet been updated. |