Confirmed users
497
edits
(→Debug.Object: Fleshed out.) |
|||
| Line 202: | Line 202: | ||
== Debug.Object== | == Debug.Object== | ||
A <code>Debug.Object</code> instance represents an object in the debuggee. Debugger code never accesses debuggee objects directly; instead, it | A <code>Debug.Object</code> instance represents an object in the debuggee. Debugger code never accesses debuggee objects directly; instead, it operates on <code>Debug.Object</code> instances that refer to the debuggee objects. SpiderMonkey's compartment system ensures that this separation is respected. | ||
A <code>Debug.Object</code> instance has reflection-oriented methods to inspect and modify its referent. The referent's properties do not appear directly as properties of the <code>Debug.Object</code> instance; the debugger can access them only through methods like <code>Debug.Object.prototype.getOwnPropertyDescriptor</code> and <code>Debug.Object.prototype.defineProperty</code>, ensuring that the debugger will not inadvertently invoke the referent's getters and setters. | A <code>Debug.Object</code> instance has reflection-oriented methods to inspect and modify its referent. The referent's properties do not appear directly as properties of the <code>Debug.Object</code> instance; the debugger can access them only through methods like <code>Debug.Object.prototype.getOwnPropertyDescriptor</code> and <code>Debug.Object.prototype.defineProperty</code>, ensuring that the debugger will not inadvertently invoke the referent's getters and setters. | ||
SpiderMonkey creates exactly one <code>Debug.Object</code> instance for each debuggee object it presents to the debugger: if the debugger encounters the same object through two different routes (perhaps two functions are called on the same object), SpiderMonkey presents the same <code>Debug.Object</code> instance to the debugger each time. This means that the debugger can use the <code>==</code> operator to recognize when two <code>Debug.Object</code> instances refer to the same debuggee object, and place its own properties on <code>Debug.Object</code> instances and | SpiderMonkey creates exactly one <code>Debug.Object</code> instance for each debuggee object it presents to the debugger: if the debugger encounters the same object through two different routes (perhaps two functions are called on the same object), SpiderMonkey presents the same <code>Debug.Object</code> instance to the debugger each time. This means that the debugger can use the <code>==</code> operator to recognize when two <code>Debug.Object</code> instances refer to the same debuggee object, and place its own properties on a <code>Debug.Object</code> instance to store metadata about particular debuggee objects. | ||
While most <code>Debug.Object</code> instances are created by SpiderMonkey in the process of exposing debuggee's behavior and state to the debugger, the debugger can apply the <code>Debug.Object</code> constructor to its own objects, to copy them into the debuggee; see the description of the <code>Debug.Object</code> constructor below. | |||
<code>Debug.Object</code> instances protect their referents from the garbage collector; as long as the <code>Debug.Object</code> instance is live, the referent remains live. Garbage collection has no debugger-visible effect. | <code>Debug.Object</code> instances protect their referents from the garbage collector; as long as the <code>Debug.Object</code> instance is live, the referent remains live. Garbage collection has no debugger-visible effect. | ||
=== The <code>Debug.Object</code> constructor === | === The <code>Debug.Object</code> constructor === | ||
| Line 220: | Line 220: | ||
=== Properties of the <code>Debug.Object</code> constructor === | === Properties of the <code>Debug.Object</code> constructor === | ||
< | <dl> | ||
<dt>create(<i>prototype</i>, [<i>properties</i>]) | |||
<dd>Create a new object in the debuggee's compartment, and return a <code>Debug.Object</code> referring to it. The new object's prototype is <i>prototype</i>; <i>prototype</i> must be an object. The new object's properties are as given by <i>properties</i>, as if it were passed to the standard <code>Object.defineProperties</code> function. | |||
</dl> | |||
=== Properties of the <code>Debug.Object</code> prototype === | === Properties of the <code>Debug.Object</code> prototype === | ||
<i> | <dl> | ||
<dt>getPrototype() | |||
<dd>Return the prototype of this <code>Debug.Object</code>'s referent (as a new <code>Debug.Object</code> instance), or <code>null</code> if it has no prototype. | |||
<dt>getOwnPropertyDescriptor(<i>name</i>) | |||
<dd>Return a property descriptor for the property named <i>name</i> of the object this <code>Debug.Object</code> instance refers to. (This function behaves like the standard <code>Object.getOwnPropertyDescriptor</code> function, except that the object being inspected is implicit; the property descriptor returned is in the debugger's compartment; and its <code>value</code>, <code>get</code>, and <code>set</code> properties, if present, are debuggee values.) | |||
<dt>getOwnPropertyNames() | |||
<dd>Return an array of strings naming all the own properties of this <code>Debug.Object</code>'s referent, as if <code>Object.getOwnPropertyNames(<i>referent</i>)</code> had been called in the debuggee, and the result copied to the debugger's compartment. | |||
<dt>defineProperty(<i>name</i>, <i>attributes</i>) | |||
<dd>Define a property on this <code>Debug.Object</code>'s referent named <i>name</i>, as described by the property descriptor <i>descriptor</i>. Any <code>value</code>, <code>get</code>, and <code>set</code> properties of <i>attributes</i> must be debuggee values. (This function behaves like <code>Object.defineProperty</code>, except that the target object is implicit, and in a different compartment from the function and descriptor.) | |||
<dt>defineProperties(<i>properties</i>) | |||
<dd>Define properties on this <code>Debug.Object</code>'s referent, as given by <i>properties</i>. (This function behaves like <code>Object.defineProperties</code>, except that the target object is implicit, and in a different compartment from the <i>properties</i> argument.) | |||
<dt>hasOwnProperty(<i>name</i>) | |||
<dd>Return true if this <code>Debug.Object</code>'s referent has an own property named <i>name</i>. | |||
<i> | <dt>deleteProperty(<i>name</i>) | ||
<dd>Remove the property named <i>name</i> from this <code>Debug.Object</code>'s referent. Return true if the property was successfully removed, or if the referent has no such property. Return false if the property is non-configurable. | |||
< | <dt>seal() | ||
<dd>Prevent properties from being added or deleted from this <code>Debug.Object</code>'s referent. Return this <code>Debug.Object</code> instance. (This function behaves like the standard <code>Object.seal</code> function, except that the object to be sealed is implicit and in a different compartment from the caller.) | |||
< | <dt>freeze() | ||
<dd>Prevent properties from being added or deleted from this <code>Debug.Object</code>'s referent, and mark each property as non-writable. Return this <code>Debug.Object</code> instance. (This function behaves like the standard <code>Object.freeze</code> function, except that the object to be sealed is implicit and in a different compartment from the caller.) | |||
< | <dt>preventExtensions() | ||
<dd>Prevent properties from being added to this <code>Debug.Object</code>'s referent. (This function behaves like the standard <code>Object.preventExtensions</code> function, except that the object to operate on is implicit and in a different compartment from the caller.) | |||
< | <dt>isSealed() | ||
<dd>Return true if this <code>Debug.Object</code>'s referent is sealed—that is, if it is not extensible, and all its properties have been marked as non-configurable. (This function behaves like the standard <code>Object.isSealed</code> function, except that the object inspected is implicit and in a different compartment from the caller.) | |||
< | <dt>isFrozen() | ||
<dd>Return true if this <code>Debug.Object</code>'s referent is frozen—that is, if it is not extensible, and all its properties have been marked as non-configurable and read-only. (This function behaves like the standard <code>Object.isFrozen</code> function, except that the object inspected is implicit and in a different compartment from the caller.) | |||
< | <dt>isExtensible() | ||
<dd>Return true if this <code>Debug.Object</code>'s referent is extensible—that is, if it can have new properties defined on it. (This function behaves like the standard <code>Object.isExtensible</code> function, except that the object inspected is implicit and in a different compartment from the caller.) | |||
< | <dt>getClass() | ||
<dd>Return a string naming the ECMAScript <code>[[Class]]</code> of this <code>Debug.Object</code>'s referent. | |||
< | <dt>referentToString() | ||
<dd>Return a string representing this <code>Debug.Object</code>'s referent, showing its class and any other useful information, without invoking its <code>toString</code> or <code>toSource</code> members, or running any other debuggee code. The specific string returned is unspecified. (It is better to add functions to <code>Debug.Object.prototype</code> that retrieve the information you need about the object than to depend on details of <code>safeToString</code>'s behavior.) | |||
< | (Note that simply calling the <code>toString</code> method of a <code>Debug.Object</code> instance applies to instance itself, not its referent, and thus returns something like <code>"[Object Debug.Object]"</code>.) | ||
</dl> | |||