diff --git a/dom/bindings/BindingDeclarations.h b/dom/bindings/BindingDeclarations.h index f0c442554e7b..78c611be114b 100644 --- a/dom/bindings/BindingDeclarations.h +++ b/dom/bindings/BindingDeclarations.h @@ -17,11 +17,11 @@ #include "js/Value.h" #include "mozilla/Maybe.h" -#include "mozilla/RootedOwningNonNull.h" -#include "mozilla/RootedRefPtr.h" +#include "mozilla/OwningNonNull.h" #include "mozilla/dom/DOMString.h" +#include "nsAutoPtr.h" // for nsRefPtr member variables #include "nsCOMPtr.h" #include "nsStringGlue.h" #include "nsTArray.h" diff --git a/dom/bindings/CallbackFunction.h b/dom/bindings/CallbackFunction.h index b394d4c0dc96..81e7f101665a 100644 --- a/dom/bindings/CallbackFunction.h +++ b/dom/bindings/CallbackFunction.h @@ -56,15 +56,6 @@ protected: : CallbackObject(aCallbackFunction) { } - - // See CallbackObject for an explanation of the arguments. - CallbackFunction(JSContext* aCx, JS::Handle aCallable, - nsIGlobalObject* aIncumbentGlobal, - const FastCallbackConstructor&) - : CallbackObject(aCx, aCallable, aIncumbentGlobal, - FastCallbackConstructor()) - { - } }; } // namespace dom diff --git a/dom/bindings/CallbackInterface.h b/dom/bindings/CallbackInterface.h index 3ba5182e7e9a..274c85ade3f8 100644 --- a/dom/bindings/CallbackInterface.h +++ b/dom/bindings/CallbackInterface.h @@ -26,7 +26,7 @@ class CallbackInterface : public CallbackObject public: // See CallbackObject for an explanation of the arguments. explicit CallbackInterface(JSContext* aCx, JS::Handle aCallback, - nsIGlobalObject* aIncumbentGlobal) + nsIGlobalObject *aIncumbentGlobal) : CallbackObject(aCx, aCallback, aIncumbentGlobal) { } @@ -43,14 +43,6 @@ protected: bool GetCallableProperty(JSContext* cx, JS::Handle aPropId, JS::MutableHandle aCallable); - // See CallbackObject for an explanation of the arguments. - CallbackInterface(JSContext* aCx, JS::Handle aCallable, - nsIGlobalObject* aIncumbentGlobal, - const FastCallbackConstructor&) - : CallbackObject(aCx, aCallable, aIncumbentGlobal, - FastCallbackConstructor()) - { - } }; } // namespace dom diff --git a/dom/bindings/CallbackObject.cpp b/dom/bindings/CallbackObject.cpp index 42dd2280695e..e445475d9857 100644 --- a/dom/bindings/CallbackObject.cpp +++ b/dom/bindings/CallbackObject.cpp @@ -47,27 +47,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CallbackObject) NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mIncumbentJSGlobal) NS_IMPL_CYCLE_COLLECTION_TRACE_END -void -CallbackObject::Trace(JSTracer* aTracer) -{ - JS::TraceEdge(aTracer, &mCallback, "CallbackObject.mCallback"); - JS::TraceEdge(aTracer, &mCreationStack, "CallbackObject.mCreationStack"); - JS::TraceEdge(aTracer, &mIncumbentJSGlobal, - "CallbackObject.mIncumbentJSGlobal"); -} - -void -CallbackObject::HoldJSObjectsIfMoreThanOneOwner() -{ - MOZ_ASSERT(mRefCnt.get() > 0); - if (mRefCnt.get() > 1) { - mozilla::HoldJSObjects(this); - } else { - // We can just forget all our stuff. - ClearJSReferences(); - } -} - CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback, ErrorResult& aRv, const char* aExecutionReason, diff --git a/dom/bindings/CallbackObject.h b/dom/bindings/CallbackObject.h index c8517544d70d..9b2cf429cd87 100644 --- a/dom/bindings/CallbackObject.h +++ b/dom/bindings/CallbackObject.h @@ -25,13 +25,11 @@ #include "mozilla/ErrorResult.h" #include "mozilla/HoldDropJSObjects.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/OwningNonNull.h" #include "mozilla/dom/ScriptSettings.h" #include "nsWrapperCache.h" #include "nsJSEnvironment.h" #include "xpcpublic.h" #include "jsapi.h" -#include "js/TracingAPI.h" namespace mozilla { namespace dom { @@ -56,7 +54,7 @@ public: // is invoked. aCx can be nullptr, in which case no stack is // captured. explicit CallbackObject(JSContext* aCx, JS::Handle aCallback, - nsIGlobalObject* aIncumbentGlobal) + nsIGlobalObject *aIncumbentGlobal) { if (aCx && JS::RuntimeOptionsRef(aCx).asyncStack()) { JS::RootedObject stack(aCx); @@ -74,7 +72,7 @@ public: // for that purpose. explicit CallbackObject(JS::Handle aCallback, JS::Handle aAsyncStack, - nsIGlobalObject* aIncumbentGlobal) + nsIGlobalObject *aIncumbentGlobal) { Init(aCallback, aAsyncStack, aIncumbentGlobal); } @@ -165,8 +163,8 @@ protected: } private: - inline void InitNoHold(JSObject* aCallback, JSObject* aCreationStack, - nsIGlobalObject* aIncumbentGlobal) + inline void Init(JSObject* aCallback, JSObject* aCreationStack, + nsIGlobalObject* aIncumbentGlobal) { MOZ_ASSERT(aCallback && !mCallback); // Set script objects before we hold, on the off chance that a GC could @@ -177,22 +175,9 @@ private: mIncumbentGlobal = aIncumbentGlobal; mIncumbentJSGlobal = aIncumbentGlobal->GetGlobalJSObject(); } - } - - inline void Init(JSObject* aCallback, JSObject* aCreationStack, - nsIGlobalObject* aIncumbentGlobal) - { - InitNoHold(aCallback, aCreationStack, aIncumbentGlobal); mozilla::HoldJSObjects(this); } - inline void ClearJSReferences() - { - mCallback = nullptr; - mCreationStack = nullptr; - mIncumbentJSGlobal = nullptr; - } - CallbackObject(const CallbackObject&) = delete; CallbackObject& operator =(const CallbackObject&) = delete; @@ -201,46 +186,13 @@ protected: { MOZ_ASSERT_IF(mIncumbentJSGlobal, mCallback); if (mCallback) { - ClearJSReferences(); + mCallback = nullptr; + mCreationStack = nullptr; + mIncumbentJSGlobal = nullptr; mozilla::DropJSObjects(this); } } - // For use from subclasses that want to be usable with Rooted. - void Trace(JSTracer* aTracer); - - // For use from subclasses that want to be traced for a bit then possibly - // switch to HoldJSObjects. If we have more than one owner, this will - // HoldJSObjects; otherwise it will just forget all our JS references. - void HoldJSObjectsIfMoreThanOneOwner(); - - // Struct used as a way to force a CallbackObject constructor to not call - // HoldJSObjects. We're putting it here so that CallbackObject subclasses will - // have access to it, but outside code will not. - // - // Places that use this need to ensure that the callback is traced (e.g. via a - // Rooted) until the HoldJSObjects call happens. - struct FastCallbackConstructor { - }; - - // Just like the public version without the FastCallbackConstructor argument, - // except for not calling HoldJSObjects. If you use this, you MUST ensure - // that the object is traced until the HoldJSObjects happens! - CallbackObject(JSContext* aCx, JS::Handle aCallback, - nsIGlobalObject* aIncumbentGlobal, - const FastCallbackConstructor&) - { - if (aCx && JS::RuntimeOptionsRef(aCx).asyncStack()) { - JS::RootedObject stack(aCx); - if (!JS::CaptureCurrentStack(aCx, &stack)) { - JS_ClearPendingException(aCx); - } - InitNoHold(aCallback, stack, aIncumbentGlobal); - } else { - InitNoHold(aCallback, nullptr, aIncumbentGlobal); - } - } - // mCallback is not unwrapped, so it can be a cross-compartment-wrapper. // This is done to ensure that, if JS code can't call a callback f(), or get // its members, directly itself, this code won't call f(), or get its members, @@ -521,98 +473,6 @@ ImplCycleCollectionUnlink(CallbackObjectHolder& aField) aField.UnlinkSelf(); } -// T is expected to be a CallbackObject subclass. This class is used in -// bindings to safely handle nullable Fast* callbacks; it ensures that the -// callback is traced, and that if something is holding onto the callback when -// we're done with it HoldJSObjects is called. I wish I could share this code -// with RootedCallbackOwningNonNull, but I can't figure out how to give two -// different template specializations of the same two-param template (templated -// on T and SmartPtr), different destructors. -template -class RootedCallbackRefPtr : public JS::Rooted> -{ -public: - explicit RootedCallbackRefPtr(JSContext* cx) - : JS::Rooted>(cx) - {} - - // We need a way to make assignment from pointers (how we're normally used) - // work. - template - void operator=(S* arg) - { - this->get().operator=(arg); - } - - // But nullptr can't use the above template, because it doesn't know which S - // to select. So we need a special overload for nullptr. - void operator=(decltype(nullptr) arg) - { - this->get().operator=(arg); - } - - // Codegen relies on being able to do Callback() on us. - JS::Handle Callback() const - { - return this->get()->Callback(); - } - - ~RootedCallbackRefPtr() - { - // Ensure that our callback, if not null, starts holding on to its own JS - // objects as needed. - if (this->get().get()) { - this->get()->HoldJSObjectsIfMoreThanOneOwner(); - } - } -}; - -// T is expected to be a CallbackObject subclass. This class is used in -// bindings to safely handle non-nullable Fast* callbacks; it ensures that the -// callback is traced, and that if something is holding onto the callback when -// we're done with it HoldJSObjects is called. I wish I could share this code -// with RootedCallbackRefPtr, but I can't figure out how to give two different -// template specializations of the same two-param template (templated on T and -// SmartPtr), different destructors. -template -class RootedCallbackOwningNonNull : public JS::Rooted> -{ -public: - explicit RootedCallbackOwningNonNull(JSContext* cx) - : JS::Rooted>(cx) - {} - - // We need a way to make assignment from pointers (how we're normally used) - // work. - template - void operator=(S* arg) - { - this->get().operator=(arg); - } - - // But nullptr can't use the above template, because it doesn't know which S - // to select. So we need a special overload for nullptr. - void operator=(decltype(nullptr) arg) - { - this->get().operator=(arg); - } - - // Codegen relies on being able to do Callback() on us. - JS::Handle Callback() const - { - return this->get()->Callback(); - } - - ~RootedCallbackOwningNonNull() - { - // Ensure that our callback, if initialized (and hence nonnull), starts - // holding on to its own JS objects as needed. - if (this->get().isInitialized()) { - this->get()->HoldJSObjectsIfMoreThanOneOwner(); - } - } -}; - } // namespace dom } // namespace mozilla diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 6ab6dd80f059..2d0af83e249b 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -4186,40 +4186,6 @@ class CGCallbackTempRoot(CGGeneric): CGGeneric.__init__(self, define=define) -def getCallbackConversionInfo(type, idlObject, isMember, isCallbackReturnValue, - isOptional): - """ - Returns a tuple containing the declType, declArgs, and basic - conversion for the given callback type, with the given callback - idl object in the given context (isMember/isCallbackReturnValue/isOptional). - """ - name = idlObject.identifier.name - - # We can't use fast callbacks if isOptional because then we get an - # Optional thing, which is not transparent to consumers. - useFastCallback = (not isMember and not isCallbackReturnValue and - not isOptional) - if useFastCallback: - name = "binding_detail::Fast%s" % name - - if type.nullable() or isCallbackReturnValue: - smartPtrType = "RefPtr" - else: - smartPtrType = "OwningNonNull" - - declType = CGGeneric(name) - - if useFastCallback: - declType = CGTemplatedType("RootedCallback%s" % smartPtrType, declType) - declArgs = "cx" - else: - declType = CGTemplatedType(smartPtrType, declType) - declArgs = None - - conversion = indent(CGCallbackTempRoot(name).define()) - return (declType, declArgs, conversion) - - class JSToNativeConversionInfo(): """ An object representing information about a JS-to-native conversion. @@ -5122,16 +5088,17 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, assert descriptor.nativeType != 'JSObject' if descriptor.interface.isCallback(): - (declType, declArgs, - conversion) = getCallbackConversionInfo(type, descriptor.interface, - isMember, - isCallbackReturnValue, - isOptional) + name = descriptor.interface.identifier.name + if type.nullable() or isCallbackReturnValue: + declType = CGGeneric("RefPtr<%s>" % name) + else: + declType = CGGeneric("OwningNonNull<%s>" % name) + conversion = indent(CGCallbackTempRoot(name).define()) + template = wrapObjectTemplate(conversion, type, "${declName} = nullptr;\n", failureCode) return JSToNativeConversionInfo(template, declType=declType, - declArgs=declArgs, dealWithOptional=isOptional) # This is an interface that we implement as a concrete class @@ -5611,10 +5578,11 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, callback = type.unroll().callback name = callback.identifier.name - (declType, declArgs, - conversion) = getCallbackConversionInfo(type, callback, isMember, - isCallbackReturnValue, - isOptional) + if type.nullable(): + declType = CGGeneric("RefPtr<%s>" % name) + else: + declType = CGGeneric("OwningNonNull<%s>" % name) + conversion = indent(CGCallbackTempRoot(name).define()) if allowTreatNonCallableAsNull and type.treatNonCallableAsNull(): haveCallable = "JS::IsCallable(&${val}.toObject())" @@ -5651,7 +5619,6 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, "${declName} = nullptr;\n", failureCode) return JSToNativeConversionInfo(template, declType=declType, - declArgs=declArgs, dealWithOptional=isOptional) if type.isAny(): @@ -13569,15 +13536,9 @@ class CGBindingRoot(CGThing): cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(False)) for c in mainCallbacks) - cgthings.extend([CGNamespace('binding_detail', CGFastCallback(c)) - for c in mainCallbacks]) - cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(True)) for c in workerCallbacks if c not in mainCallbacks) - cgthings.extend([CGNamespace('binding_detail', CGFastCallback(c)) - for c in workerCallbacks if c not in mainCallbacks]) - # Do codegen for all the descriptors cgthings.extend([CGDescriptor(x) for x in descriptors]) @@ -13585,10 +13546,6 @@ class CGBindingRoot(CGThing): cgthings.extend([CGCallbackInterface(x) for x in callbackDescriptors if not x.workers]) - cgthings.extend([CGNamespace('binding_detail', - CGFastCallback(x.interface)) - for x in callbackDescriptors if not x.workers]) - # Do codegen for JS implemented classes def getParentDescriptor(desc): if not desc.interface.parent: @@ -14862,18 +14819,6 @@ class CGCallback(CGClass): "%s(aCx, aCallback, aIncumbentGlobal)" % self.baseName, ], body=body), - ClassConstructor( - [Argument("JSContext*", "aCx"), - Argument("JS::Handle", "aCallback"), - Argument("nsIGlobalObject*", "aIncumbentGlobal"), - Argument("const FastCallbackConstructor&", "")], - bodyInHeader=True, - visibility="public", - explicit=True, - baseConstructors=[ - "%s(aCx, aCallback, aIncumbentGlobal, FastCallbackConstructor())" % self.baseName, - ], - body=body), ClassConstructor( [Argument("JS::Handle", "aCallback"), Argument("JS::Handle", "aAsyncStack"), @@ -15039,47 +14984,6 @@ class CGCallbackFunction(CGCallback): baseConstructors=["CallbackFunction(aOther)"])] -class CGFastCallback(CGClass): - def __init__(self, idlObject): - self._deps = idlObject.getDeps() - baseName = idlObject.identifier.name - constructor = ClassConstructor( - [Argument("JSContext*", "aCx"), - Argument("JS::Handle", "aCallback"), - Argument("nsIGlobalObject*", "aIncumbentGlobal")], - bodyInHeader=True, - visibility="public", - explicit=True, - baseConstructors=[ - "%s(aCx, aCallback, aIncumbentGlobal, FastCallbackConstructor())" % - baseName, - ], - body="") - - traceMethod = ClassMethod("Trace", "void", - [Argument("JSTracer*", "aTracer")], - inline=True, - bodyInHeader=True, - visibility="public", - body="%s::Trace(aTracer);\n" % baseName) - holdMethod = ClassMethod("HoldJSObjectsIfMoreThanOneOwner", "void", - [], - inline=True, - bodyInHeader=True, - visibility="public", - body=( - "%s::HoldJSObjectsIfMoreThanOneOwner();\n" % - baseName)) - - CGClass.__init__(self, "Fast%s" % baseName, - bases=[ClassBase(baseName)], - constructors=[constructor], - methods=[traceMethod, holdMethod]) - - def deps(self): - return self._deps - - class CGCallbackInterface(CGCallback): def __init__(self, descriptor, typedArraysAreStructs=False): iface = descriptor.interface diff --git a/dom/bindings/RootedOwningNonNull.h b/dom/bindings/RootedOwningNonNull.h deleted file mode 100644 index bb0819119aae..000000000000 --- a/dom/bindings/RootedOwningNonNull.h +++ /dev/null @@ -1,73 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * An implementation of Rooted for OwningNonNull. This works by assuming - * that T has a Trace() method defined on it which will trace whatever things - * inside the T instance need tracing. - * - * This implementation has one serious drawback: operator= doesn't work right - * because it's declared on Rooted directly and expects the type Rooted is - * templated over. - */ - -#ifndef mozilla_RootedOwningNonNull_h__ -#define mozilla_RootedOwningNonNull_h__ - -#include "mozilla/OwningNonNull.h" -#include "js/GCPolicyAPI.h" -#include "js/RootingAPI.h" - -namespace JS { -template -struct GCPolicy> -{ - typedef mozilla::OwningNonNull OwningNonNull; - - static OwningNonNull initial() - { - return OwningNonNull(); - } - - static void trace(JSTracer* trc, OwningNonNull* tp, - const char* name) - { - // We have to be very careful here. Normally, OwningNonNull can't be null. - // But binding code can end up in a situation where it sets up a - // Rooted and then before it gets a chance to assign to it - // (e.g. from the constructor of the thing being assigned) a GC happens. So - // we can land here when *tp stores a null pointer because it's not - // initialized. - // - // So we need to check for that before jumping. - if ((*tp).isInitialized()) { - (*tp)->Trace(trc); - } - } -}; -} // namespace JS - -namespace js { -template -struct RootedBase> -{ - typedef mozilla::OwningNonNull OwningNonNull; - - operator OwningNonNull& () const - { - auto& self = *static_cast*>(this); - return self.get(); - } - - operator T& () const - { - auto& self = *static_cast*>(this); - return self.get(); - } -}; -} // namespace js - -#endif /* mozilla_RootedOwningNonNull_h__ */ diff --git a/dom/bindings/RootedRefPtr.h b/dom/bindings/RootedRefPtr.h deleted file mode 100644 index e27361b24927..000000000000 --- a/dom/bindings/RootedRefPtr.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/** - * An implementation of Rooted for RefPtr. This works by assuming that T has - * a Trace() method defined on it which will trace whatever things inside the T - * instance need tracing. - * - * This implementation has one serious drawback: operator= doesn't work right - * because it's declared on Rooted directly and expects the type Rooted is - * templated over. - */ - -#ifndef mozilla_RootedRefPtr_h__ -#define mozilla_RootedRefPtr_h__ - -#include "mozilla/RefPtr.h" -#include "js/GCPolicyAPI.h" -#include "js/RootingAPI.h" - -namespace JS { -template -struct GCPolicy> -{ - static RefPtr initial() { - return RefPtr(); - } - - static void trace(JSTracer* trc, RefPtr* tp, const char* name) - { - if (*tp) { - (*tp)->Trace(trc); - } - } -}; -} // namespace JS - -namespace js { -template -struct RootedBase> -{ - operator RefPtr& () const - { - auto& self = *static_cast>*>(this); - return self.get(); - } - - operator T*() const - { - auto& self = *static_cast>*>(this); - return self.get(); - } -}; -} // namespace js - -#endif /* mozilla_RootedRefPtr_h__ */ diff --git a/dom/bindings/moz.build b/dom/bindings/moz.build index fcc062d1e2a1..87ea012229e6 100644 --- a/dom/bindings/moz.build +++ b/dom/bindings/moz.build @@ -12,8 +12,6 @@ EXPORTS.ipc += [ EXPORTS.mozilla += [ 'ErrorResult.h', - 'RootedOwningNonNull.h', - 'RootedRefPtr.h', ] EXPORTS.mozilla.dom += [ diff --git a/xpcom/base/OwningNonNull.h b/xpcom/base/OwningNonNull.h index b72a250c401b..45143faf5ca3 100644 --- a/xpcom/base/OwningNonNull.h +++ b/xpcom/base/OwningNonNull.h @@ -126,18 +126,6 @@ public: void swap(U& aOther) { mPtr.swap(aOther); -#ifdef DEBUG - mInited = mPtr; -#endif - } - - // We have some consumers who want to check whether we're inited in non-debug - // builds as well. Luckily, we have the invariant that we're inited precisely - // when mPtr is non-null. - bool isInitialized() const - { - MOZ_ASSERT(!!mPtr == mInited, "mInited out of sync with mPtr?"); - return mPtr; } protected: