js/src/doc/Debugger/Debugger.Object.md

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

mercurial