From 9f2475087899c0248c427e5ce21d9e757c632062 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 18 May 2018 16:18:19 -0400 Subject: [PATCH] Bug 1461711 part 1. Change CustomElementRegistry::Define to just take a JSContext from the caller instead of setting up an AutoJSAPI itself. r=smaug This more closely matches what should happen with entry/incumbent globals in the spec. --- dom/base/CustomElementRegistry.cpp | 54 +++++++++++++----------------- dom/base/CustomElementRegistry.h | 3 +- dom/bindings/Bindings.conf | 4 +++ 3 files changed, 29 insertions(+), 32 deletions(-) diff --git a/dom/base/CustomElementRegistry.cpp b/dom/base/CustomElementRegistry.cpp index 3d3901815427..2c79f86b8d25 100644 --- a/dom/base/CustomElementRegistry.cpp +++ b/dom/base/CustomElementRegistry.cpp @@ -650,24 +650,16 @@ CustomElementRegistry::GetDocGroup() const // https://html.spec.whatwg.org/multipage/scripting.html#element-definition void -CustomElementRegistry::Define(const nsAString& aName, +CustomElementRegistry::Define(JSContext* aCx, + const nsAString& aName, Function& aFunctionConstructor, const ElementDefinitionOptions& aOptions, ErrorResult& aRv) { - aRv.MightThrowJSException(); - - AutoJSAPI jsapi; - if (NS_WARN_IF(!jsapi.Init(mWindow))) { - aRv.Throw(NS_ERROR_FAILURE); - return; - } - - JSContext *cx = jsapi.cx(); // Note: No calls that might run JS or trigger CC before this point, or // there's a (vanishingly small) chance of our constructor being nulled // before we access it. - JS::Rooted constructor(cx, aFunctionConstructor.CallableOrNull()); + JS::Rooted constructor(aCx, aFunctionConstructor.CallableOrNull()); /** * 1. If IsConstructor(constructor) is false, then throw a TypeError and abort @@ -675,7 +667,7 @@ CustomElementRegistry::Define(const nsAString& aName, */ // For now, all wrappers are constructable if they are callable. So we need to // unwrap constructor to check it is really constructable. - JS::Rooted constructorUnwrapped(cx, js::CheckedUnwrap(constructor)); + JS::Rooted constructorUnwrapped(aCx, js::CheckedUnwrap(constructor)); if (!constructorUnwrapped) { // If the caller's compartment does not have permission to access the // unwrapped constructor then throw. @@ -763,7 +755,7 @@ CustomElementRegistry::Define(const nsAString& aName, return; } - JS::Rooted constructorPrototype(cx); + JS::Rooted constructorPrototype(aCx); nsAutoPtr callbacksHolder(new LifecycleCallbacks()); nsTArray> observedAttributes; { // Set mIsCustomDefinitionRunning. @@ -776,12 +768,12 @@ CustomElementRegistry::Define(const nsAString& aName, /** * 10.1. Let prototype be Get(constructor, "prototype"). Rethrow any exceptions. */ - JSAutoRealm ar(cx, constructor); + JSAutoRealm ar(aCx, constructor); // The .prototype on the constructor passed could be an "expando" of a // wrapper. So we should get it from wrapper instead of the underlying // object. - if (!JS_GetProperty(cx, constructor, "prototype", &constructorPrototype)) { - aRv.StealExceptionFromJSContext(cx); + if (!JS_GetProperty(aCx, constructor, "prototype", &constructorPrototype)) { + aRv.NoteJSContextException(aCx); return; } @@ -795,7 +787,7 @@ CustomElementRegistry::Define(const nsAString& aName, } // Leave constructor's realm. JS::Rooted constructorProtoUnwrapped( - cx, js::CheckedUnwrap(&constructorPrototype.toObject())); + aCx, js::CheckedUnwrap(&constructorPrototype.toObject())); if (!constructorProtoUnwrapped) { // If the caller's compartment does not have permission to access the // unwrapped prototype then throw. @@ -804,7 +796,7 @@ CustomElementRegistry::Define(const nsAString& aName, } { // Enter constructorProtoUnwrapped's compartment - JSAutoRealm ar(cx, constructorProtoUnwrapped); + JSAutoRealm ar(aCx, constructorProtoUnwrapped); /** * 10.3. Let lifecycleCallbacks be a map with the four keys @@ -821,9 +813,9 @@ CustomElementRegistry::Define(const nsAString& aName, */ // Note: We call the init from the constructorProtoUnwrapped's compartment // here. - JS::RootedValue rootedv(cx, JS::ObjectValue(*constructorProtoUnwrapped)); - if (!JS_WrapValue(cx, &rootedv) || !callbacksHolder->Init(cx, rootedv)) { - aRv.StealExceptionFromJSContext(cx); + JS::RootedValue rootedv(aCx, JS::ObjectValue(*constructorProtoUnwrapped)); + if (!JS_WrapValue(aCx, &rootedv) || !callbacksHolder->Init(aCx, rootedv)) { + aRv.NoteJSContextException(aCx); return; } @@ -840,12 +832,12 @@ CustomElementRegistry::Define(const nsAString& aName, */ if (callbacksHolder->mAttributeChangedCallback.WasPassed()) { // Enter constructor's realm. - JSAutoRealm ar(cx, constructor); - JS::Rooted observedAttributesIterable(cx); + JSAutoRealm ar(aCx, constructor); + JS::Rooted observedAttributesIterable(aCx); - if (!JS_GetProperty(cx, constructor, "observedAttributes", + if (!JS_GetProperty(aCx, constructor, "observedAttributes", &observedAttributesIterable)) { - aRv.StealExceptionFromJSContext(cx); + aRv.NoteJSContextException(aCx); return; } @@ -855,9 +847,9 @@ CustomElementRegistry::Define(const nsAString& aName, return; } - JS::ForOfIterator iter(cx); + JS::ForOfIterator iter(aCx); if (!iter.init(observedAttributesIterable, JS::ForOfIterator::AllowNonIterable)) { - aRv.StealExceptionFromJSContext(cx); + aRv.NoteJSContextException(aCx); return; } @@ -866,11 +858,11 @@ CustomElementRegistry::Define(const nsAString& aName, return; } - JS::Rooted attribute(cx); + JS::Rooted attribute(aCx); while (true) { bool done; if (!iter.next(&attribute, &done)) { - aRv.StealExceptionFromJSContext(cx); + aRv.NoteJSContextException(aCx); return; } if (done) { @@ -878,8 +870,8 @@ CustomElementRegistry::Define(const nsAString& aName, } nsAutoString attrStr; - if (!ConvertJSValueToString(cx, attribute, eStringify, eStringify, attrStr)) { - aRv.StealExceptionFromJSContext(cx); + if (!ConvertJSValueToString(aCx, attribute, eStringify, eStringify, attrStr)) { + aRv.NoteJSContextException(aCx); return; } diff --git a/dom/base/CustomElementRegistry.h b/dom/base/CustomElementRegistry.h index 06f4eb266e3c..9ad346b2a8e0 100644 --- a/dom/base/CustomElementRegistry.h +++ b/dom/base/CustomElementRegistry.h @@ -510,7 +510,8 @@ public: virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; - void Define(const nsAString& aName, Function& aFunctionConstructor, + void Define(JSContext* aCx, const nsAString& aName, + Function& aFunctionConstructor, const ElementDefinitionOptions& aOptions, ErrorResult& aRv); void Get(JSContext* cx, const nsAString& name, diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index c4487b44b381..aaf47168c793 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -210,6 +210,10 @@ DOMInterfaces = { 'binaryNames': { 'ownerRule': 'DOMOwnerRule' }, }, +'CustomElementRegistry': { + 'implicitJSContext': ['define'], +}, + 'DedicatedWorkerGlobalScope': { 'headerFile': 'mozilla/dom/WorkerScope.h', },