Backed out changesets bdb5b50fd858, 74dbcb56456d, 8f319062be85, 9806d7a88802, c08f417d85fd (bug 1273661) for build bustage and CLOSED TREE.

This commit is contained in:
Boris Zbarsky 2016-05-19 00:26:24 -04:00
Родитель 7353927cf9
Коммит 61b3aedfa3
10 изменённых файлов: 22 добавлений и 442 удалений

Просмотреть файл

@ -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,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<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: