In SpiderMonkey, a split object is made up of two JSObjects: an inner object and an outer object.

Each half of a split object always has a pointer to the other half. Inner objects implement the JSExtendedClass.outerObject hook, which returns a pointer to the corresponding outer object. Outer objects implement the JSExtendedClass.innerObject hook. But the association is not fixed. An outer object may be associated with different inner objects at different times.

This feature is complicated. Programs other than Mozilla that embed SpiderMonkey should avoid using split objects.

The window object

Split objects were introduced to resolve a problem posed by the window object. Three interrelated requirements on the window object seemed to conflict.

Split objects were the solution. The inner window object is different for each page a browser window visits. It serves as the "globals" object and provides the JSPrincipals for scripts on that page. Access to inner window properties is fast. The outer window object is the object returned by window.open. It represents the window or tab itself and survives as the user navigates in that window or tab. The window object's JSClass.resolve hook ensures that properties of the inner object are visible via the outer object, if the running code has the right principals to access them. This privilege check may be slow.

See wikimo:Gecko:SplitWindow and bugĀ 296639 for more discussion.

See also http://groups.google.com/group/mozil...81825b338fb84f

Details

This section describes split objects as a feature of the JSAPI. It catalogues (and tries to explain) the subtle ways in which split objects affect SpiderMonkey's behavior.

Split objects are only useful for implementing objects that will be on the scope chain of functions. SpiderMonkey assumes that inner and outer objects are dangerous in two different and complementary ways.

Inner objects are dangerous because they have fast property accessors that do not perform security checks. Therefore, no function may be allowed to see an inner object that has different JSPrincipals. Apart from the security issue, if one page directly or indirectly gets a reference to another page's window object, that window object must appear to behave like the outer window and navigate from page to page. SpiderMonkey arranges this by not allowing JS code to see inner objects at all. To enforce this rule:

Outer objects are dangerous because their JSPrincipals may change over time. Because a Function inherits the JSPrincipals of its lexical scope (specifically, the nearest principals-aware object in its scope chain), untrusted code must never be able to make an outer object appear in a Function's scope chain. Again, SpiderMonkey enforces a slightly stronger rule: outer objects may never appear in a scope chain at all, except when put there by an explicit C-level JSAPI call (to JS_SetParent or equivalent). (Several objects, such as window.location and window.navigator, are intentionally parented to the outer window object using such APIs.) To enforce this rule:

Inner and outer objects are in certain other respects the same object:

Note that none of the rules listed here affects ordinary property accesses. SpiderMonkey's split object support, by itself, does not cause inner object properties to appear on the outer object or vice versa. Split objects that need this behavior must implement it in custom JSClass hooks. In the case of window, each half has custom hooks.