зеркало из 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 "js/Value.h"
|
||||||
|
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
#include "mozilla/RootedOwningNonNull.h"
|
#include "mozilla/OwningNonNull.h"
|
||||||
#include "mozilla/RootedRefPtr.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/DOMString.h"
|
#include "mozilla/dom/DOMString.h"
|
||||||
|
|
||||||
|
#include "nsAutoPtr.h" // for nsRefPtr member variables
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsStringGlue.h"
|
#include "nsStringGlue.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
|
|
|
@ -56,15 +56,6 @@ protected:
|
||||||
: CallbackObject(aCallbackFunction)
|
: 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
|
} // namespace dom
|
||||||
|
|
|
@ -26,7 +26,7 @@ class CallbackInterface : public CallbackObject
|
||||||
public:
|
public:
|
||||||
// See CallbackObject for an explanation of the arguments.
|
// See CallbackObject for an explanation of the arguments.
|
||||||
explicit CallbackInterface(JSContext* aCx, JS::Handle<JSObject*> aCallback,
|
explicit CallbackInterface(JSContext* aCx, JS::Handle<JSObject*> aCallback,
|
||||||
nsIGlobalObject* aIncumbentGlobal)
|
nsIGlobalObject *aIncumbentGlobal)
|
||||||
: CallbackObject(aCx, aCallback, aIncumbentGlobal)
|
: CallbackObject(aCx, aCallback, aIncumbentGlobal)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -43,14 +43,6 @@ protected:
|
||||||
bool GetCallableProperty(JSContext* cx, JS::Handle<jsid> aPropId,
|
bool GetCallableProperty(JSContext* cx, JS::Handle<jsid> aPropId,
|
||||||
JS::MutableHandle<JS::Value> aCallable);
|
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
|
} // 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_JS_MEMBER_CALLBACK(mIncumbentJSGlobal)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
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,
|
CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
|
||||||
ErrorResult& aRv,
|
ErrorResult& aRv,
|
||||||
const char* aExecutionReason,
|
const char* aExecutionReason,
|
||||||
|
|
|
@ -25,13 +25,11 @@
|
||||||
#include "mozilla/ErrorResult.h"
|
#include "mozilla/ErrorResult.h"
|
||||||
#include "mozilla/HoldDropJSObjects.h"
|
#include "mozilla/HoldDropJSObjects.h"
|
||||||
#include "mozilla/MemoryReporting.h"
|
#include "mozilla/MemoryReporting.h"
|
||||||
#include "mozilla/OwningNonNull.h"
|
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
#include "nsWrapperCache.h"
|
#include "nsWrapperCache.h"
|
||||||
#include "nsJSEnvironment.h"
|
#include "nsJSEnvironment.h"
|
||||||
#include "xpcpublic.h"
|
#include "xpcpublic.h"
|
||||||
#include "jsapi.h"
|
#include "jsapi.h"
|
||||||
#include "js/TracingAPI.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
@ -56,7 +54,7 @@ public:
|
||||||
// is invoked. aCx can be nullptr, in which case no stack is
|
// is invoked. aCx can be nullptr, in which case no stack is
|
||||||
// captured.
|
// captured.
|
||||||
explicit CallbackObject(JSContext* aCx, JS::Handle<JSObject*> aCallback,
|
explicit CallbackObject(JSContext* aCx, JS::Handle<JSObject*> aCallback,
|
||||||
nsIGlobalObject* aIncumbentGlobal)
|
nsIGlobalObject *aIncumbentGlobal)
|
||||||
{
|
{
|
||||||
if (aCx && JS::RuntimeOptionsRef(aCx).asyncStack()) {
|
if (aCx && JS::RuntimeOptionsRef(aCx).asyncStack()) {
|
||||||
JS::RootedObject stack(aCx);
|
JS::RootedObject stack(aCx);
|
||||||
|
@ -74,7 +72,7 @@ public:
|
||||||
// for that purpose.
|
// for that purpose.
|
||||||
explicit CallbackObject(JS::Handle<JSObject*> aCallback,
|
explicit CallbackObject(JS::Handle<JSObject*> aCallback,
|
||||||
JS::Handle<JSObject*> aAsyncStack,
|
JS::Handle<JSObject*> aAsyncStack,
|
||||||
nsIGlobalObject* aIncumbentGlobal)
|
nsIGlobalObject *aIncumbentGlobal)
|
||||||
{
|
{
|
||||||
Init(aCallback, aAsyncStack, aIncumbentGlobal);
|
Init(aCallback, aAsyncStack, aIncumbentGlobal);
|
||||||
}
|
}
|
||||||
|
@ -165,8 +163,8 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline void InitNoHold(JSObject* aCallback, JSObject* aCreationStack,
|
inline void Init(JSObject* aCallback, JSObject* aCreationStack,
|
||||||
nsIGlobalObject* aIncumbentGlobal)
|
nsIGlobalObject* aIncumbentGlobal)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aCallback && !mCallback);
|
MOZ_ASSERT(aCallback && !mCallback);
|
||||||
// Set script objects before we hold, on the off chance that a GC could
|
// Set script objects before we hold, on the off chance that a GC could
|
||||||
|
@ -177,22 +175,9 @@ private:
|
||||||
mIncumbentGlobal = aIncumbentGlobal;
|
mIncumbentGlobal = aIncumbentGlobal;
|
||||||
mIncumbentJSGlobal = aIncumbentGlobal->GetGlobalJSObject();
|
mIncumbentJSGlobal = aIncumbentGlobal->GetGlobalJSObject();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline void Init(JSObject* aCallback, JSObject* aCreationStack,
|
|
||||||
nsIGlobalObject* aIncumbentGlobal)
|
|
||||||
{
|
|
||||||
InitNoHold(aCallback, aCreationStack, aIncumbentGlobal);
|
|
||||||
mozilla::HoldJSObjects(this);
|
mozilla::HoldJSObjects(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void ClearJSReferences()
|
|
||||||
{
|
|
||||||
mCallback = nullptr;
|
|
||||||
mCreationStack = nullptr;
|
|
||||||
mIncumbentJSGlobal = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
CallbackObject(const CallbackObject&) = delete;
|
CallbackObject(const CallbackObject&) = delete;
|
||||||
CallbackObject& operator =(const CallbackObject&) = delete;
|
CallbackObject& operator =(const CallbackObject&) = delete;
|
||||||
|
|
||||||
|
@ -201,46 +186,13 @@ protected:
|
||||||
{
|
{
|
||||||
MOZ_ASSERT_IF(mIncumbentJSGlobal, mCallback);
|
MOZ_ASSERT_IF(mIncumbentJSGlobal, mCallback);
|
||||||
if (mCallback) {
|
if (mCallback) {
|
||||||
ClearJSReferences();
|
mCallback = nullptr;
|
||||||
|
mCreationStack = nullptr;
|
||||||
|
mIncumbentJSGlobal = nullptr;
|
||||||
mozilla::DropJSObjects(this);
|
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.
|
// 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
|
// 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,
|
// 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();
|
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 dom
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
@ -4186,40 +4186,6 @@ class CGCallbackTempRoot(CGGeneric):
|
||||||
CGGeneric.__init__(self, define=define)
|
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():
|
class JSToNativeConversionInfo():
|
||||||
"""
|
"""
|
||||||
An object representing information about a JS-to-native conversion.
|
An object representing information about a JS-to-native conversion.
|
||||||
|
@ -5122,16 +5088,17 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
assert descriptor.nativeType != 'JSObject'
|
assert descriptor.nativeType != 'JSObject'
|
||||||
|
|
||||||
if descriptor.interface.isCallback():
|
if descriptor.interface.isCallback():
|
||||||
(declType, declArgs,
|
name = descriptor.interface.identifier.name
|
||||||
conversion) = getCallbackConversionInfo(type, descriptor.interface,
|
if type.nullable() or isCallbackReturnValue:
|
||||||
isMember,
|
declType = CGGeneric("RefPtr<%s>" % name)
|
||||||
isCallbackReturnValue,
|
else:
|
||||||
isOptional)
|
declType = CGGeneric("OwningNonNull<%s>" % name)
|
||||||
|
conversion = indent(CGCallbackTempRoot(name).define())
|
||||||
|
|
||||||
template = wrapObjectTemplate(conversion, type,
|
template = wrapObjectTemplate(conversion, type,
|
||||||
"${declName} = nullptr;\n",
|
"${declName} = nullptr;\n",
|
||||||
failureCode)
|
failureCode)
|
||||||
return JSToNativeConversionInfo(template, declType=declType,
|
return JSToNativeConversionInfo(template, declType=declType,
|
||||||
declArgs=declArgs,
|
|
||||||
dealWithOptional=isOptional)
|
dealWithOptional=isOptional)
|
||||||
|
|
||||||
# This is an interface that we implement as a concrete class
|
# 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
|
callback = type.unroll().callback
|
||||||
name = callback.identifier.name
|
name = callback.identifier.name
|
||||||
(declType, declArgs,
|
if type.nullable():
|
||||||
conversion) = getCallbackConversionInfo(type, callback, isMember,
|
declType = CGGeneric("RefPtr<%s>" % name)
|
||||||
isCallbackReturnValue,
|
else:
|
||||||
isOptional)
|
declType = CGGeneric("OwningNonNull<%s>" % name)
|
||||||
|
conversion = indent(CGCallbackTempRoot(name).define())
|
||||||
|
|
||||||
if allowTreatNonCallableAsNull and type.treatNonCallableAsNull():
|
if allowTreatNonCallableAsNull and type.treatNonCallableAsNull():
|
||||||
haveCallable = "JS::IsCallable(&${val}.toObject())"
|
haveCallable = "JS::IsCallable(&${val}.toObject())"
|
||||||
|
@ -5651,7 +5619,6 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
"${declName} = nullptr;\n",
|
"${declName} = nullptr;\n",
|
||||||
failureCode)
|
failureCode)
|
||||||
return JSToNativeConversionInfo(template, declType=declType,
|
return JSToNativeConversionInfo(template, declType=declType,
|
||||||
declArgs=declArgs,
|
|
||||||
dealWithOptional=isOptional)
|
dealWithOptional=isOptional)
|
||||||
|
|
||||||
if type.isAny():
|
if type.isAny():
|
||||||
|
@ -13569,15 +13536,9 @@ class CGBindingRoot(CGThing):
|
||||||
cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(False))
|
cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(False))
|
||||||
for c in mainCallbacks)
|
for c in mainCallbacks)
|
||||||
|
|
||||||
cgthings.extend([CGNamespace('binding_detail', CGFastCallback(c))
|
|
||||||
for c in mainCallbacks])
|
|
||||||
|
|
||||||
cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(True))
|
cgthings.extend(CGCallbackFunction(c, config.getDescriptorProvider(True))
|
||||||
for c in workerCallbacks if c not in mainCallbacks)
|
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
|
# Do codegen for all the descriptors
|
||||||
cgthings.extend([CGDescriptor(x) for x in 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
|
cgthings.extend([CGCallbackInterface(x) for x in callbackDescriptors if
|
||||||
not x.workers])
|
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
|
# Do codegen for JS implemented classes
|
||||||
def getParentDescriptor(desc):
|
def getParentDescriptor(desc):
|
||||||
if not desc.interface.parent:
|
if not desc.interface.parent:
|
||||||
|
@ -14862,18 +14819,6 @@ class CGCallback(CGClass):
|
||||||
"%s(aCx, aCallback, aIncumbentGlobal)" % self.baseName,
|
"%s(aCx, aCallback, aIncumbentGlobal)" % self.baseName,
|
||||||
],
|
],
|
||||||
body=body),
|
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(
|
ClassConstructor(
|
||||||
[Argument("JS::Handle<JSObject*>", "aCallback"),
|
[Argument("JS::Handle<JSObject*>", "aCallback"),
|
||||||
Argument("JS::Handle<JSObject*>", "aAsyncStack"),
|
Argument("JS::Handle<JSObject*>", "aAsyncStack"),
|
||||||
|
@ -15039,47 +14984,6 @@ class CGCallbackFunction(CGCallback):
|
||||||
baseConstructors=["CallbackFunction(aOther)"])]
|
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):
|
class CGCallbackInterface(CGCallback):
|
||||||
def __init__(self, descriptor, typedArraysAreStructs=False):
|
def __init__(self, descriptor, typedArraysAreStructs=False):
|
||||||
iface = descriptor.interface
|
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 += [
|
EXPORTS.mozilla += [
|
||||||
'ErrorResult.h',
|
'ErrorResult.h',
|
||||||
'RootedOwningNonNull.h',
|
|
||||||
'RootedRefPtr.h',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
EXPORTS.mozilla.dom += [
|
EXPORTS.mozilla.dom += [
|
||||||
|
|
|
@ -126,18 +126,6 @@ public:
|
||||||
void swap(U& aOther)
|
void swap(U& aOther)
|
||||||
{
|
{
|
||||||
mPtr.swap(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:
|
protected:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче