зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changesets bdb5b50fd858, 74dbcb56456d, 8f319062be85, 9806d7a88802, c08f417d85fd (bug 1273661) for build bustage and CLOSED TREE.
This commit is contained in:
Родитель
7353927cf9
Коммит
61b3aedfa3
|
@ -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"
|
||||
|
|
|
@ -56,15 +56,6 @@ protected:
|
|||
: CallbackObject(aCallbackFunction)
|
||||
{
|
||||
}
|
||||
|
||||
// See CallbackObject for an explanation of the arguments.
|
||||
CallbackFunction(JSContext* aCx, JS::Handle<JSObject*> aCallable,
|
||||
nsIGlobalObject* aIncumbentGlobal,
|
||||
const FastCallbackConstructor&)
|
||||
: CallbackObject(aCx, aCallable, aIncumbentGlobal,
|
||||
FastCallbackConstructor())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -26,7 +26,7 @@ class CallbackInterface : public CallbackObject
|
|||
public:
|
||||
// See CallbackObject for an explanation of the arguments.
|
||||
explicit CallbackInterface(JSContext* aCx, JS::Handle<JSObject*> aCallback,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
nsIGlobalObject *aIncumbentGlobal)
|
||||
: CallbackObject(aCx, aCallback, aIncumbentGlobal)
|
||||
{
|
||||
}
|
||||
|
@ -43,14 +43,6 @@ protected:
|
|||
bool GetCallableProperty(JSContext* cx, JS::Handle<jsid> aPropId,
|
||||
JS::MutableHandle<JS::Value> aCallable);
|
||||
|
||||
// See CallbackObject for an explanation of the arguments.
|
||||
CallbackInterface(JSContext* aCx, JS::Handle<JSObject*> aCallable,
|
||||
nsIGlobalObject* aIncumbentGlobal,
|
||||
const FastCallbackConstructor&)
|
||||
: CallbackObject(aCx, aCallable, aIncumbentGlobal,
|
||||
FastCallbackConstructor())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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<JSObject*> 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<JSObject*> aCallback,
|
||||
JS::Handle<JSObject*> aAsyncStack,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
nsIGlobalObject *aIncumbentGlobal)
|
||||
{
|
||||
Init(aCallback, aAsyncStack, aIncumbentGlobal);
|
||||
}
|
||||
|
@ -165,7 +163,7 @@ protected:
|
|||
}
|
||||
|
||||
private:
|
||||
inline void InitNoHold(JSObject* aCallback, JSObject* aCreationStack,
|
||||
inline void Init(JSObject* aCallback, JSObject* aCreationStack,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
{
|
||||
MOZ_ASSERT(aCallback && !mCallback);
|
||||
|
@ -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<JSObject*> 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<T, U>& 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<T>), different destructors.
|
||||
template<typename T>
|
||||
class RootedCallbackRefPtr : public JS::Rooted<RefPtr<T>>
|
||||
{
|
||||
public:
|
||||
explicit RootedCallbackRefPtr(JSContext* cx)
|
||||
: JS::Rooted<RefPtr<T>>(cx)
|
||||
{}
|
||||
|
||||
// We need a way to make assignment from pointers (how we're normally used)
|
||||
// work.
|
||||
template<typename S>
|
||||
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<JSObject*> 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<T>), different destructors.
|
||||
template<typename T>
|
||||
class RootedCallbackOwningNonNull : public JS::Rooted<OwningNonNull<T>>
|
||||
{
|
||||
public:
|
||||
explicit RootedCallbackOwningNonNull(JSContext* cx)
|
||||
: JS::Rooted<OwningNonNull<T>>(cx)
|
||||
{}
|
||||
|
||||
// We need a way to make assignment from pointers (how we're normally used)
|
||||
// work.
|
||||
template<typename S>
|
||||
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<JSObject*> 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
|
||||
|
||||
|
|
|
@ -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<RootedCallback> 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<JSObject*>", "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<JSObject*>", "aCallback"),
|
||||
Argument("JS::Handle<JSObject*>", "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<JSObject*>", "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
|
||||
|
|
|
@ -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<T>. 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<typename T>
|
||||
struct GCPolicy<mozilla::OwningNonNull<T>>
|
||||
{
|
||||
typedef mozilla::OwningNonNull<T> 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<OwningNonNull> 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<typename T>
|
||||
struct RootedBase<mozilla::OwningNonNull<T>>
|
||||
{
|
||||
typedef mozilla::OwningNonNull<T> OwningNonNull;
|
||||
|
||||
operator OwningNonNull& () const
|
||||
{
|
||||
auto& self = *static_cast<const JS::Rooted<OwningNonNull>*>(this);
|
||||
return self.get();
|
||||
}
|
||||
|
||||
operator T& () const
|
||||
{
|
||||
auto& self = *static_cast<const JS::Rooted<OwningNonNull>*>(this);
|
||||
return self.get();
|
||||
}
|
||||
};
|
||||
} // namespace js
|
||||
|
||||
#endif /* mozilla_RootedOwningNonNull_h__ */
|
|
@ -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<T>. 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<typename T>
|
||||
struct GCPolicy<RefPtr<T>>
|
||||
{
|
||||
static RefPtr<T> initial() {
|
||||
return RefPtr<T>();
|
||||
}
|
||||
|
||||
static void trace(JSTracer* trc, RefPtr<T>* tp, const char* name)
|
||||
{
|
||||
if (*tp) {
|
||||
(*tp)->Trace(trc);
|
||||
}
|
||||
}
|
||||
};
|
||||
} // namespace JS
|
||||
|
||||
namespace js {
|
||||
template<typename T>
|
||||
struct RootedBase<RefPtr<T>>
|
||||
{
|
||||
operator RefPtr<T>& () const
|
||||
{
|
||||
auto& self = *static_cast<const JS::Rooted<RefPtr<T>>*>(this);
|
||||
return self.get();
|
||||
}
|
||||
|
||||
operator T*() const
|
||||
{
|
||||
auto& self = *static_cast<const JS::Rooted<RefPtr<T>>*>(this);
|
||||
return self.get();
|
||||
}
|
||||
};
|
||||
} // namespace js
|
||||
|
||||
#endif /* mozilla_RootedRefPtr_h__ */
|
|
@ -12,8 +12,6 @@ EXPORTS.ipc += [
|
|||
|
||||
EXPORTS.mozilla += [
|
||||
'ErrorResult.h',
|
||||
'RootedOwningNonNull.h',
|
||||
'RootedRefPtr.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.dom += [
|
||||
|
|
|
@ -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:
|
||||
|
|
Загрузка…
Ссылка в новой задаче