With this patch, all holders are created lazily. There are two common accessors,
getHolder() and ensureHolder(). The former returns null if no holder exists, the
latter lazily creates the holder if it doesn't exist. It does this by calling into
a virtual trap on XrayTraits, which lets the appropriate Xray type do its thing.
The current name potentially implies that the object returned is an inner
object in the JS sense, which isn't true. Really we just want the thing
we're Xraying to.
There's some code that can be shared between different Xray traits, but can't
(yet) be hoisted into XrayWrapper, because it needs to be callable from outside
XrayWrapper where we don't have the appropriate template parameters. Moreover,
this code benefits from virtual function specialization. The use case here is
illuminated in the next patch.
For the moment, we skip converting the bulk of the traits calls to virtual
methods, because they're working just fine.
We might as well do this dynamically, which simplifies the code. Note that we
could avoid the reserved slot by parenting the holder to the wrapper. But the
JS parent API is deprecated, and we need to move away from it to reserved slots
anyhow. We might as well start here, with the added advantage that parenting
to the global makes us consistent with the other Xray types.
We want this right now so that we can avoid the scary warning when content Components
access happens in XBL (which we're allowing going forward). This patch would be overkill
just for that, but I also have plans to introduce a SOW-like protection of the Components
wrapper filtering policy. I can't just do the filename hack for that though, because real-
world XBL filenames might be all over the place. So let's just be safe here.
There are really two questions to be asked: is the caller chrome, and does the
caller subsume the callee. We have other, more precise ways of asking both of
these questions.
There are really two questions to be asked: is the caller chrome, and does the
caller subsume the callee. We have other, more precise ways of asking both of
these questions.
There are really two questions to be asked: is the caller chrome, and does the
caller subsume the callee. We have other, more precise ways of asking both of
these questions.
We currently set this for system globals and anything whose parent
chain leads to a system global. Maybe this was relevant before, but
with CPG this is just equivalent to asking whether the object is in
a system compartment. And the only place where we _check_ this bit
is immediately after checking for a system compartment, in
WrapperFactory. So AFAICT this can go away entirely.
We currently set this for system globals and anything whose parent
chain leads to a system global. Maybe this was relevant before, but
with CPG this is just equivalent to asking whether the object is in
a system compartment. And the only place where we _check_ this bit
is immediately after checking for a system compartment, in
WrapperFactory. So AFAICT this can go away entirely.
This can happen if chrome sets its proto to a content object from a different scope
than the one doing the wrapping. In this case, the prototype chain looks like this:
chromeobj => CCW(examplecom_obj) => CCW(examplecom_scope.Object.prototype)
When wrapping chromeobj for exampleorg_scope, things will look like this:
COW(chromeobj) => CCW(examplecom_obj) => CCW(examplecom_scope.Object.prototype)
Note that we don't remap the proto of CCW(examplecom_scope) to
exampleorg_scope.Object.prototype, because the proto remapping only happens when
the object we're wrapping is chrome. There's no reason it has to be this way, but
even if we changed it we still wouldn't get the nice remapped lookup behavior to
exampleorg_scope.Object.prototype, because the proxy handler for CCW(examplecom_obj)
isn't a ChromeObjectWrapper, and thus doesn't know how to to the prototype bouncing
correctly.
Anyway, I suspect this case isn't worth worrying about as long as we don't crash.
Now that we have nsExpandedPrincipal, the current way of doing things is wrong. For some reason, the old document.domain hackery was hiding the failures here.
Note: This overloads the naming of some of the existing infrastructure,
but the signatures etc are sufficient to disambiguate. The other infrastructure
goes away in a subsequent patch.
Note: We tag sandbox expandos with their global to make sure that the expandos
are never shared between sandboxes. A consequence of this scheme is that an
expando from a sandbox to an object will _always_ result in a GC edge back to
the sandbox, meaning that the sandbox is always kept alive for the lifetime of
the expando target. This could happen before, but only if a non-primitive expando
was placed (since the value of the expando would live in the consumer's
compartment). We could avoid this edge by using a reference-counted Identity()
object instead, but I suspect it's not worth worrying about.