Bug 993047 - Support outerizing and addProperty hooks on globals with WebIDL bindings. r=bz.

--HG--
extra : rebase_source : cc8f013525dca74a4d7926f3cbb301ac42aab406
This commit is contained in:
Peter Van der Beken 2014-02-15 22:12:33 +01:00
parent bc34bf3fb1
commit d38e26a2ce
3 changed files with 80 additions and 7 deletions

View File

@ -1940,6 +1940,39 @@ nsGlobalWindow::TraceGlobalJSObject(JSTracer* aTrc)
TraceWrapper(aTrc, "active window global");
}
/* static */
JSObject*
nsGlobalWindow::OuterObject(JSContext* aCx, JS::HandleObject aObj)
{
nsGlobalWindow *origWin;
UNWRAP_OBJECT(Window, aObj, origWin);
nsGlobalWindow *win = origWin->GetOuterWindowInternal();
if (!win) {
// If we no longer have an outer window. No code should ever be
// running on a window w/o an outer, which means this hook should
// never be called when we have no outer. But just in case, return
// null to prevent leaking an inner window to code in a different
// window.
NS_WARNING("nsGlobalWindow::OuterObject shouldn't fail!");
return nullptr;
}
JS::Rooted<JSObject*> winObj(aCx, win->FastGetGlobalJSObject());
MOZ_ASSERT(winObj);
// Note that while |wrapper| is same-compartment with cx, the outer window
// might not be. If we're running script in an inactive scope and evalute
// |this|, the outer window is actually a cross-compartment wrapper. So we
// need to wrap here.
if (!JS_WrapObject(aCx, &winObj)) {
NS_WARNING("nsGlobalWindow::OuterObject shouldn't fail!");
return nullptr;
}
return winObj;
}
bool
nsGlobalWindow::WouldReuseInnerWindow(nsIDocument *aNewDocument)
{
@ -4360,10 +4393,10 @@ nsGlobalWindow::SetOpener(nsIDOMWindow* aOpener, ErrorResult& aError)
{
// Check if we were called from a privileged chrome script. If not, and if
// aOpener is not null, just define aOpener on our inner window's JS object,
// wapped into the current compartment so that for Xrays we define on the Xray
// expando object, but don't set it on the outer window, so that it'll get
// reset on navigation. This is just like replaceable properties, but we're
// not quite readonly.
// wrapped into the current compartment so that for Xrays we define on the
// Xray expando object, but don't set it on the outer window, so that it'll
// get reset on navigation. This is just like replaceable properties, but
// we're not quite readonly.
if (aOpener && !nsContentUtils::IsCallerChrome()) {
// JS_WrapObject will outerize, so we don't care if aOpener is an inner.
nsCOMPtr<nsIGlobalObject> glob = do_QueryInterface(aOpener);

View File

@ -372,6 +372,8 @@ public:
virtual bool IsBlackForCC(bool aTracingNeeded = true);
static JSObject* OuterObject(JSContext* aCx, JS::HandleObject aObj);
// nsIScriptObjectPrincipal
virtual nsIPrincipal* GetPrincipal();

View File

@ -53,7 +53,8 @@ def isTypeCopyConstructible(type):
def wantsAddProperty(desc):
return (desc.concrete and
desc.wrapperCache and
not desc.interface.getExtendedAttribute("Global"))
not (desc.workers and
desc.interface.getExtendedAttribute("Global")))
# We'll want to insert the indent at the beginnings of lines, but we
@ -330,9 +331,46 @@ class CGDOMJSClass(CGThing):
callHook = LEGACYCALLER_HOOK_NAME if self.descriptor.operations["LegacyCaller"] else 'nullptr'
slotCount = INSTANCE_RESERVED_SLOTS + self.descriptor.interface.totalMembersInSlots
classFlags = "JSCLASS_IS_DOMJSCLASS | "
classExtensionAndObjectOps = """\
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
"""
if self.descriptor.interface.getExtendedAttribute("Global"):
classFlags += "JSCLASS_DOM_GLOBAL | JSCLASS_GLOBAL_FLAGS_WITH_SLOTS(DOM_GLOBAL_SLOTS) | JSCLASS_IMPLEMENTS_BARRIERS"
traceHook = "JS_GlobalObjectTraceHook"
if not self.descriptor.workers:
classExtensionAndObjectOps = """\
{
nsGlobalWindow::OuterObject, /* outerObject */
nullptr, /* innerObject */
nullptr, /* iteratorObject */
false, /* isWrappedNative */
nullptr /* weakmapKeyDelegateOp */
},
{
nullptr, /* lookupGeneric */
nullptr, /* lookupProperty */
nullptr, /* lookupElement */
nullptr, /* defineGeneric */
nullptr, /* defineProperty */
nullptr, /* defineElement */
nullptr, /* getGeneric */
nullptr, /* getProperty */
nullptr, /* getElement */
nullptr, /* setGeneric */
nullptr, /* setProperty */
nullptr, /* setElement */
nullptr, /* getGenericAttributes */
nullptr, /* setGenericAttributes */
nullptr, /* deleteProperty */
nullptr, /* deleteElement */
nullptr, /* watch */
nullptr, /* unwatch */
nullptr, /* slice */
nullptr, /* enumerate */
JS_ObjectToOuterObject /* thisObject */
}
"""
else:
classFlags += "JSCLASS_HAS_RESERVED_SLOTS(%d)" % slotCount
if self.descriptor.interface.getExtendedAttribute("NeedNewResolve"):
@ -366,8 +404,7 @@ class CGDOMJSClass(CGThing):
nullptr, /* construct */
${trace}, /* trace */
JS_NULL_CLASS_SPEC,
JS_NULL_CLASS_EXT,
JS_NULL_OBJECT_OPS
$*{classExtensionAndObjectOps}
},
$*{descriptor}
};
@ -380,6 +417,7 @@ class CGDOMJSClass(CGThing):
finalize=FINALIZE_HOOK_NAME,
call=callHook,
trace=traceHook,
classExtensionAndObjectOps=classExtensionAndObjectOps,
descriptor=DOMClass(self.descriptor))