зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1273661 part 1. Add a way to construct a callback object without calling HoldJSObjects. r=smaug
This commit is contained in:
Родитель
cf35c3398f
Коммит
384428f2af
|
@ -56,6 +56,15 @@ 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,6 +43,14 @@ 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
|
||||
|
|
|
@ -54,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);
|
||||
|
@ -72,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);
|
||||
}
|
||||
|
@ -163,8 +163,8 @@ protected:
|
|||
}
|
||||
|
||||
private:
|
||||
inline void Init(JSObject* aCallback, JSObject* aCreationStack,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
inline void InitNoHold(JSObject* aCallback, JSObject* aCreationStack,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
{
|
||||
MOZ_ASSERT(aCallback && !mCallback);
|
||||
// Set script objects before we hold, on the off chance that a GC could
|
||||
|
@ -175,6 +175,12 @@ private:
|
|||
mIncumbentGlobal = aIncumbentGlobal;
|
||||
mIncumbentJSGlobal = aIncumbentGlobal->GetGlobalJSObject();
|
||||
}
|
||||
}
|
||||
|
||||
inline void Init(JSObject* aCallback, JSObject* aCreationStack,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
{
|
||||
InitNoHold(aCallback, aCreationStack, aIncumbentGlobal);
|
||||
mozilla::HoldJSObjects(this);
|
||||
}
|
||||
|
||||
|
@ -193,6 +199,33 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
// 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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче