зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1477923. Make WebIDL callbacks store a global in addition to the object that's used as a callback. r=mccr8
We want to be able to enter the Realm we were in when the callback was created before calling it, but if the callback stores a cross-compartment wrapper we don't really have a good way to find that Realm. So we store it explicitly by storing a global when the callback is created. The changes to the constructor signatures to use JSObject* instead of JS::Handle<JSObject*> are so we can avoid having to root the global for these calls. These changes make two of the constructors ambiguous when nullptr is being passed for the first arg; this patch adds casts to disambiguate.
This commit is contained in:
Родитель
757eed8c02
Коммит
f771d7e529
|
@ -727,11 +727,13 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
|
||||
JS::RootingContext* rcx = RootingCx();
|
||||
JS::Rooted<JSObject*> object(rcx);
|
||||
JS::Rooted<JSObject*> nonCCWObject(rcx);
|
||||
|
||||
RefPtr<MessageListener> webIDLListener;
|
||||
if (!weakListener) {
|
||||
webIDLListener = listener.mStrongListener;
|
||||
object = webIDLListener->CallbackOrNull();
|
||||
nonCCWObject = webIDLListener->CallbackGlobalOrNull();
|
||||
} else {
|
||||
nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(weakListener);
|
||||
if (!wrappedJS) {
|
||||
|
@ -739,6 +741,9 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
}
|
||||
|
||||
object = wrappedJS->GetJSObject();
|
||||
// This is not really guaranteed to not be a CCW yet, but hopefully bug
|
||||
// 1478359 will help with that.
|
||||
nonCCWObject = object;
|
||||
}
|
||||
|
||||
if (!object) {
|
||||
|
@ -749,10 +754,9 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
|
|||
JSContext* cx = aes.cx();
|
||||
|
||||
// We passed the unwrapped object to AutoEntryScript so we now need to
|
||||
// enter the (maybe wrapper) object's realm. We will have to revisit this
|
||||
// later because CCWs are not associated with a single realm so this
|
||||
// doesn't make much sense. See bug 1477923.
|
||||
JSAutoRealmAllowCCW ar(cx, object);
|
||||
// enter the realm of the non-ccw object that represents the realm of our
|
||||
// callback.
|
||||
JSAutoRealm ar(cx, nonCCWObject);
|
||||
|
||||
RootedDictionary<ReceiveMessageArgument> argument(cx);
|
||||
|
||||
|
|
|
@ -2360,7 +2360,10 @@ nsGlobalWindowInner::GetInstallTrigger()
|
|||
rv.SuppressException();
|
||||
return nullptr;
|
||||
}
|
||||
mInstallTrigger = new InstallTriggerImpl(jsImplObj, this);
|
||||
MOZ_RELEASE_ASSERT(!js::IsWrapper(jsImplObj));
|
||||
JS::Rooted<JSObject*> jsImplGlobal(RootingCx(),
|
||||
JS::GetNonCCWObjectGlobal(jsImplObj));
|
||||
mInstallTrigger = new InstallTriggerImpl(jsImplObj, jsImplGlobal, this);
|
||||
}
|
||||
|
||||
return do_AddRef(mInstallTrigger);
|
||||
|
@ -7451,7 +7454,10 @@ nsGlobalWindowInner::GetExternal(ErrorResult& aRv)
|
|||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
mExternal = new External(jsImplObj, this);
|
||||
MOZ_RELEASE_ASSERT(!js::IsWrapper(jsImplObj));
|
||||
JS::Rooted<JSObject*> jsImplGlobal(RootingCx(),
|
||||
JS::GetNonCCWObjectGlobal(jsImplObj));
|
||||
mExternal = new External(jsImplObj, jsImplGlobal, this);
|
||||
}
|
||||
|
||||
RefPtr<External> external = static_cast<External*>(mExternal.get());
|
||||
|
|
|
@ -27,16 +27,18 @@ class CallbackFunction : public CallbackObject
|
|||
public:
|
||||
// See CallbackObject for an explanation of the arguments.
|
||||
explicit CallbackFunction(JSContext* aCx, JS::Handle<JSObject*> aCallable,
|
||||
JS::Handle<JSObject*> aCallableGlobal,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
: CallbackObject(aCx, aCallable, aIncumbentGlobal)
|
||||
: CallbackObject(aCx, aCallable, aCallableGlobal, aIncumbentGlobal)
|
||||
{
|
||||
}
|
||||
|
||||
// See CallbackObject for an explanation of the arguments.
|
||||
explicit CallbackFunction(JS::Handle<JSObject*> aCallable,
|
||||
JS::Handle<JSObject*> aAsyncStack,
|
||||
explicit CallbackFunction(JSObject* aCallable,
|
||||
JSObject* aCallableGlobal,
|
||||
JSObject* aAsyncStack,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
: CallbackObject(aCallable, aAsyncStack, aIncumbentGlobal)
|
||||
: CallbackObject(aCallable, aCallableGlobal, aAsyncStack, aIncumbentGlobal)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -63,9 +65,10 @@ protected:
|
|||
}
|
||||
|
||||
// See CallbackObject for an explanation of the arguments.
|
||||
CallbackFunction(JS::Handle<JSObject*> aCallable,
|
||||
CallbackFunction(JSObject* aCallable,
|
||||
JSObject* aCallableGlobal,
|
||||
const FastCallbackConstructor&)
|
||||
: CallbackObject(aCallable, FastCallbackConstructor())
|
||||
: CallbackObject(aCallable, aCallableGlobal, FastCallbackConstructor())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
|
@ -26,16 +26,18 @@ class CallbackInterface : public CallbackObject
|
|||
public:
|
||||
// See CallbackObject for an explanation of the arguments.
|
||||
explicit CallbackInterface(JSContext* aCx, JS::Handle<JSObject*> aCallback,
|
||||
JS::Handle<JSObject*> aCallbackGlobal,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
: CallbackObject(aCx, aCallback, aIncumbentGlobal)
|
||||
: CallbackObject(aCx, aCallback, aCallbackGlobal, aIncumbentGlobal)
|
||||
{
|
||||
}
|
||||
|
||||
// See CallbackObject for an explanation of the arguments.
|
||||
explicit CallbackInterface(JS::Handle<JSObject*> aCallback,
|
||||
JS::Handle<JSObject*> aAsyncStack,
|
||||
explicit CallbackInterface(JSObject* aCallback,
|
||||
JSObject* aCallbackGlobal,
|
||||
JSObject* aAsyncStack,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
: CallbackObject(aCallback, aAsyncStack, aIncumbentGlobal)
|
||||
: CallbackObject(aCallback, aCallbackGlobal, aAsyncStack, aIncumbentGlobal)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -44,9 +46,10 @@ protected:
|
|||
JS::MutableHandle<JS::Value> aCallable);
|
||||
|
||||
// See CallbackObject for an explanation of the arguments.
|
||||
CallbackInterface(JS::Handle<JSObject*> aCallable,
|
||||
CallbackInterface(JSObject* aCallback,
|
||||
JSObject* aCallbackGlobal,
|
||||
const FastCallbackConstructor&)
|
||||
: CallbackObject(aCallable, FastCallbackConstructor())
|
||||
: CallbackObject(aCallback, aCallbackGlobal, FastCallbackConstructor())
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
|
@ -81,6 +81,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(CallbackObject)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(CallbackObject)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCallbackGlobal)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mCreationStack)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mIncumbentJSGlobal)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
@ -89,6 +90,7 @@ void
|
|||
CallbackObject::Trace(JSTracer* aTracer)
|
||||
{
|
||||
JS::TraceEdge(aTracer, &mCallback, "CallbackObject.mCallback");
|
||||
JS::TraceEdge(aTracer, &mCallbackGlobal, "CallbackObject.mCallbackGlobal");
|
||||
JS::TraceEdge(aTracer, &mCreationStack, "CallbackObject.mCreationStack");
|
||||
JS::TraceEdge(aTracer, &mIncumbentJSGlobal,
|
||||
"CallbackObject.mIncumbentJSGlobal");
|
||||
|
@ -239,6 +241,7 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
|
|||
// with the cx from mAutoEntryScript, avoiding the cost of finding another
|
||||
// JSContext. (Rooted<> does not care about requests or compartments.)
|
||||
mRootedCallable.emplace(cx, aCallback->CallbackOrNull());
|
||||
mRootedCallableGlobal.emplace(cx, aCallback->CallbackGlobalOrNull());
|
||||
|
||||
mAsyncStack.emplace(cx, aCallback->GetCreationStack());
|
||||
if (*mAsyncStack) {
|
||||
|
@ -250,7 +253,7 @@ CallbackObject::CallSetup::CallSetup(CallbackObject* aCallback,
|
|||
// Note that if the callback is a wrapper, this will not be the same
|
||||
// realm that we ended up in with mAutoEntryScript above, because the
|
||||
// entry point is based off of the unwrapped callback (realCallback).
|
||||
mAr.emplace(cx, *mRootedCallable);
|
||||
mAr.emplace(cx, *mRootedCallableGlobal);
|
||||
|
||||
// And now we're ready to go.
|
||||
mCx = cx;
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
// is invoked. aCx can be nullptr, in which case no stack is
|
||||
// captured.
|
||||
explicit CallbackObject(JSContext* aCx, JS::Handle<JSObject*> aCallback,
|
||||
JS::Handle<JSObject*> aCallbackGlobal,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
{
|
||||
if (aCx && JS::ContextOptionsRef(aCx).asyncStack()) {
|
||||
|
@ -63,20 +64,21 @@ public:
|
|||
if (!JS::CaptureCurrentStack(aCx, &stack)) {
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
Init(aCallback, stack, aIncumbentGlobal);
|
||||
Init(aCallback, aCallbackGlobal, stack, aIncumbentGlobal);
|
||||
} else {
|
||||
Init(aCallback, nullptr, aIncumbentGlobal);
|
||||
Init(aCallback, aCallbackGlobal, nullptr, aIncumbentGlobal);
|
||||
}
|
||||
}
|
||||
|
||||
// Instead of capturing the current stack to use as an async parent when the
|
||||
// callback is invoked, the caller can use this overload to pass in a stack
|
||||
// for that purpose.
|
||||
explicit CallbackObject(JS::Handle<JSObject*> aCallback,
|
||||
JS::Handle<JSObject*> aAsyncStack,
|
||||
explicit CallbackObject(JSObject* aCallback,
|
||||
JSObject* aCallbackGlobal,
|
||||
JSObject* aAsyncStack,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
{
|
||||
Init(aCallback, aAsyncStack, aIncumbentGlobal);
|
||||
Init(aCallback, aCallbackGlobal, aAsyncStack, aIncumbentGlobal);
|
||||
}
|
||||
|
||||
// This is guaranteed to be non-null from the time the CallbackObject is
|
||||
|
@ -93,6 +95,12 @@ public:
|
|||
return CallbackPreserveColor();
|
||||
}
|
||||
|
||||
JSObject* CallbackGlobalOrNull() const
|
||||
{
|
||||
mCallbackGlobal.exposeToActiveJS();
|
||||
return mCallbackGlobal;
|
||||
}
|
||||
|
||||
// Like CallbackOrNull(), but will return a new dead proxy object in the
|
||||
// caller's realm if the callback is null.
|
||||
JSObject* Callback(JSContext* aCx);
|
||||
|
@ -105,6 +113,7 @@ public:
|
|||
void MarkForCC()
|
||||
{
|
||||
mCallback.exposeToActiveJS();
|
||||
mCallbackGlobal.exposeToActiveJS();
|
||||
mCreationStack.exposeToActiveJS();
|
||||
}
|
||||
|
||||
|
@ -165,7 +174,8 @@ protected:
|
|||
|
||||
explicit CallbackObject(CallbackObject* aCallbackObject)
|
||||
{
|
||||
Init(aCallbackObject->mCallback, aCallbackObject->mCreationStack,
|
||||
Init(aCallbackObject->mCallback, aCallbackObject->mCallbackGlobal,
|
||||
aCallbackObject->mCreationStack,
|
||||
aCallbackObject->mIncumbentGlobal);
|
||||
}
|
||||
|
||||
|
@ -199,13 +209,17 @@ protected:
|
|||
};
|
||||
|
||||
private:
|
||||
inline void InitNoHold(JSObject* aCallback, JSObject* aCreationStack,
|
||||
inline void InitNoHold(JSObject* aCallback, JSObject* aCallbackGlobal,
|
||||
JSObject* aCreationStack,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
{
|
||||
MOZ_ASSERT(aCallback && !mCallback);
|
||||
// Set script objects before we hold, on the off chance that a GC could
|
||||
// somehow happen in there... (which would be pretty odd, granted).
|
||||
MOZ_ASSERT(aCallbackGlobal);
|
||||
MOZ_DIAGNOSTIC_ASSERT(js::GetObjectCompartment(aCallback) ==
|
||||
js::GetObjectCompartment(aCallbackGlobal));
|
||||
MOZ_ASSERT(JS_IsGlobalObject(aCallbackGlobal));
|
||||
mCallback = aCallback;
|
||||
mCallbackGlobal = aCallbackGlobal;
|
||||
mCreationStack = aCreationStack;
|
||||
if (aIncumbentGlobal) {
|
||||
mIncumbentGlobal = aIncumbentGlobal;
|
||||
|
@ -213,16 +227,20 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
inline void Init(JSObject* aCallback, JSObject* aCreationStack,
|
||||
inline void Init(JSObject* aCallback, JSObject* aCallbackGlobal,
|
||||
JSObject* aCreationStack,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
{
|
||||
InitNoHold(aCallback, aCreationStack, aIncumbentGlobal);
|
||||
// Set script objects before we hold, on the off chance that a GC could
|
||||
// somehow happen in there... (which would be pretty odd, granted).
|
||||
InitNoHold(aCallback, aCallbackGlobal, aCreationStack, aIncumbentGlobal);
|
||||
mozilla::HoldJSObjects(this);
|
||||
}
|
||||
|
||||
inline void ClearJSReferences()
|
||||
{
|
||||
mCallback = nullptr;
|
||||
mCallbackGlobal = nullptr;
|
||||
mCreationStack = nullptr;
|
||||
mIncumbentJSGlobal = nullptr;
|
||||
}
|
||||
|
@ -262,10 +280,11 @@ protected:
|
|||
// assumption that we will do that last whenever we decide to actually
|
||||
// HoldJSObjects; see FinishSlowJSInitIfMoreThanOneOwner). If you use this,
|
||||
// you MUST ensure that the object is traced until the HoldJSObjects happens!
|
||||
CallbackObject(JS::Handle<JSObject*> aCallback,
|
||||
CallbackObject(JSObject* aCallback,
|
||||
JSObject* aCallbackGlobal,
|
||||
const FastCallbackConstructor&)
|
||||
{
|
||||
InitNoHold(aCallback, nullptr, nullptr);
|
||||
InitNoHold(aCallback, aCallbackGlobal, nullptr, nullptr);
|
||||
}
|
||||
|
||||
// mCallback is not unwrapped, so it can be a cross-compartment-wrapper.
|
||||
|
@ -273,6 +292,11 @@ protected:
|
|||
// its members, directly itself, this code won't call f(), or get its members,
|
||||
// on the code's behalf.
|
||||
JS::Heap<JSObject*> mCallback;
|
||||
// mCallbackGlobal is the global that we were in when we created the
|
||||
// callback. In particular, it is guaranteed to be same-compartment with
|
||||
// aCallback. We store it separately, because we have no way to recover the
|
||||
// global if mCallback is a cross-compartment wrapper.
|
||||
JS::Heap<JSObject*> mCallbackGlobal;
|
||||
JS::Heap<JSObject*> mCreationStack;
|
||||
// Ideally, we'd just hold a reference to the nsIGlobalObject, since that's
|
||||
// what we need to pass to AutoIncumbentScript. Unfortunately, that doesn't
|
||||
|
@ -330,7 +354,9 @@ protected:
|
|||
Maybe<AutoEntryScript> mAutoEntryScript;
|
||||
Maybe<AutoIncumbentScript> mAutoIncumbentScript;
|
||||
|
||||
Maybe<JS::Rooted<JSObject*> > mRootedCallable;
|
||||
Maybe<JS::Rooted<JSObject*>> mRootedCallable;
|
||||
// The global of mRootedCallable.
|
||||
Maybe<JS::Rooted<JSObject*>> mRootedCallableGlobal;
|
||||
|
||||
// Members which are used to set the async stack.
|
||||
Maybe<JS::Rooted<JSObject*>> mAsyncStack;
|
||||
|
|
|
@ -4240,7 +4240,10 @@ class CastableObjectUnwrapper():
|
|||
$*{exceptionCode}
|
||||
}
|
||||
JS::Rooted<JSObject*> jsImplSourceObj(cx, &${source}.toObject());
|
||||
${target} = new ${type}(jsImplSourceObj, contentGlobal);
|
||||
MOZ_RELEASE_ASSERT(!js::IsWrapper(jsImplSourceObj),
|
||||
"Don't return JS implementations from other compartments");
|
||||
JS::Rooted<JSObject*> jsImplSourceGlobal(cx, JS::GetNonCCWObjectGlobal(jsImplSourceObj));
|
||||
${target} = new ${type}(jsImplSourceObj, jsImplSourceGlobal, contentGlobal);
|
||||
} else {
|
||||
$*{codeOnFailure}
|
||||
}
|
||||
|
@ -4297,11 +4300,15 @@ def getCallbackConversionInfo(type, idlObject, isMember, isCallbackReturnValue,
|
|||
not isOptional)
|
||||
if useFastCallback:
|
||||
name = "binding_detail::Fast%s" % name
|
||||
argsPre = ""
|
||||
argsPost = ""
|
||||
rootArgs = ""
|
||||
args = "&${val}.toObject(), JS::CurrentGlobalOrNull(cx)"
|
||||
else:
|
||||
argsPre = "cx, "
|
||||
argsPost = ", GetIncumbentGlobal()"
|
||||
rootArgs = dedent(
|
||||
"""
|
||||
JS::Rooted<JSObject*> tempRoot(cx, &${val}.toObject());
|
||||
JS::Rooted<JSObject*> tempGlobalRoot(cx, JS::CurrentGlobalOrNull(cx));
|
||||
""")
|
||||
args = "cx, tempRoot, tempGlobalRoot, GetIncumbentGlobal()"
|
||||
|
||||
if type.nullable() or isCallbackReturnValue:
|
||||
declType = CGGeneric("RefPtr<%s>" % name)
|
||||
|
@ -4316,14 +4323,14 @@ def getCallbackConversionInfo(type, idlObject, isMember, isCallbackReturnValue,
|
|||
|
||||
conversion = fill(
|
||||
"""
|
||||
{ // scope for tempRoot
|
||||
JS::Rooted<JSObject*> tempRoot(cx, &$${val}.toObject());
|
||||
$${declName} = new ${name}(${argsPre}tempRoot${argsPost});
|
||||
{ // scope for tempRoot and tempGlobalRoot if needed
|
||||
$*{rootArgs}
|
||||
$${declName} = new ${name}(${args});
|
||||
}
|
||||
""",
|
||||
rootArgs=rootArgs,
|
||||
name=name,
|
||||
argsPre=argsPre,
|
||||
argsPost=argsPost)
|
||||
args=args)
|
||||
return (declType, declArgs, conversion)
|
||||
|
||||
|
||||
|
@ -15066,8 +15073,11 @@ def genConstructorBody(descriptor, initCall=""):
|
|||
if (aRv.Failed()) {
|
||||
return nullptr;
|
||||
}
|
||||
// We should be getting the implementation object for the relevant
|
||||
// contract here, which should never be a cross-compartment wrapper.
|
||||
JS::Rooted<JSObject*> jsImplGlobal(cx, JS::GetNonCCWObjectGlobal(jsImplObj));
|
||||
// Build the C++ implementation.
|
||||
RefPtr<${implClass}> impl = new ${implClass}(jsImplObj, globalHolder);
|
||||
RefPtr<${implClass}> impl = new ${implClass}(jsImplObj, jsImplGlobal, globalHolder);
|
||||
$*{initCall}
|
||||
return impl.forget();
|
||||
""",
|
||||
|
@ -15219,14 +15229,14 @@ class CGJSImplClass(CGBindingImplClass):
|
|||
destructor = ClassDestructor(virtual=False, visibility="private")
|
||||
|
||||
baseConstructors = [
|
||||
("mImpl(new %s(nullptr, aJSImplObject, /* aIncumbentGlobal = */ nullptr))" %
|
||||
("mImpl(new %s(nullptr, aJSImplObject, aJSImplGlobal, /* aIncumbentGlobal = */ nullptr))" %
|
||||
jsImplName(descriptor.name)),
|
||||
"mParent(aParent)"]
|
||||
parentInterface = descriptor.interface.parent
|
||||
while parentInterface:
|
||||
if parentInterface.isJSImplemented():
|
||||
baseConstructors.insert(
|
||||
0, "%s(aJSImplObject, aParent)" % parentClass)
|
||||
0, "%s(aJSImplObject, aJSImplGlobal, aParent)" % parentClass)
|
||||
break
|
||||
parentInterface = parentInterface.parent
|
||||
if not parentInterface and descriptor.interface.parent:
|
||||
|
@ -15236,6 +15246,7 @@ class CGJSImplClass(CGBindingImplClass):
|
|||
|
||||
constructor = ClassConstructor(
|
||||
[Argument("JS::Handle<JSObject*>", "aJSImplObject"),
|
||||
Argument("JS::Handle<JSObject*>", "aJSImplGlobal"),
|
||||
Argument("nsIGlobalObject*", "aParent")],
|
||||
visibility="public",
|
||||
baseConstructors=baseConstructors)
|
||||
|
@ -15331,7 +15342,8 @@ class CGJSImplClass(CGBindingImplClass):
|
|||
nsCOMPtr<nsIGlobalObject> globalHolder = do_QueryInterface(global.GetAsSupports());
|
||||
MOZ_ASSERT(globalHolder);
|
||||
JS::Rooted<JSObject*> arg(cx, &args[1].toObject());
|
||||
RefPtr<${implName}> impl = new ${implName}(arg, globalHolder);
|
||||
JS::Rooted<JSObject*> argGlobal(cx, JS::CurrentGlobalOrNull(cx));
|
||||
RefPtr<${implName}> impl = new ${implName}(arg, argGlobal, globalHolder);
|
||||
MOZ_ASSERT(js::IsObjectInContextCompartment(arg, cx));
|
||||
return GetOrCreateDOMReflector(cx, impl, args.rval());
|
||||
""",
|
||||
|
@ -15404,33 +15416,39 @@ class CGCallback(CGClass):
|
|||
ClassConstructor(
|
||||
[Argument("JSContext*", "aCx"),
|
||||
Argument("JS::Handle<JSObject*>", "aCallback"),
|
||||
Argument("JS::Handle<JSObject*>", "aCallbackGlobal"),
|
||||
Argument("nsIGlobalObject*", "aIncumbentGlobal")],
|
||||
bodyInHeader=True,
|
||||
visibility="public",
|
||||
explicit=True,
|
||||
baseConstructors=[
|
||||
"%s(aCx, aCallback, aIncumbentGlobal)" % self.baseName,
|
||||
"%s(aCx, aCallback, aCallbackGlobal, aIncumbentGlobal)" %
|
||||
self.baseName,
|
||||
],
|
||||
body=body),
|
||||
ClassConstructor(
|
||||
[Argument("JS::Handle<JSObject*>", "aCallback"),
|
||||
[Argument("JSObject*", "aCallback"),
|
||||
Argument("JSObject*", "aCallbackGlobal"),
|
||||
Argument("const FastCallbackConstructor&", "")],
|
||||
bodyInHeader=True,
|
||||
visibility="public",
|
||||
explicit=True,
|
||||
baseConstructors=[
|
||||
"%s(aCallback, FastCallbackConstructor())" % self.baseName,
|
||||
"%s(aCallback, aCallbackGlobal, FastCallbackConstructor())" %
|
||||
self.baseName,
|
||||
],
|
||||
body=body),
|
||||
ClassConstructor(
|
||||
[Argument("JS::Handle<JSObject*>", "aCallback"),
|
||||
Argument("JS::Handle<JSObject*>", "aAsyncStack"),
|
||||
[Argument("JSObject*", "aCallback"),
|
||||
Argument("JSObject*", "aCallbackGlobal"),
|
||||
Argument("JSObject*", "aAsyncStack"),
|
||||
Argument("nsIGlobalObject*", "aIncumbentGlobal")],
|
||||
bodyInHeader=True,
|
||||
visibility="public",
|
||||
explicit=True,
|
||||
baseConstructors=[
|
||||
"%s(aCallback, aAsyncStack, aIncumbentGlobal)" % self.baseName,
|
||||
"%s(aCallback, aCallbackGlobal, aAsyncStack, aIncumbentGlobal)" %
|
||||
self.baseName,
|
||||
],
|
||||
body=body)]
|
||||
|
||||
|
@ -15591,12 +15609,13 @@ class CGFastCallback(CGClass):
|
|||
self._deps = idlObject.getDeps()
|
||||
baseName = idlObject.identifier.name
|
||||
constructor = ClassConstructor(
|
||||
[Argument("JS::Handle<JSObject*>", "aCallback")],
|
||||
[Argument("JSObject*", "aCallback"),
|
||||
Argument("JSObject*", "aCallbackGlobal")],
|
||||
bodyInHeader=True,
|
||||
visibility="public",
|
||||
explicit=True,
|
||||
baseConstructors=[
|
||||
"%s(aCallback, FastCallbackConstructor())" %
|
||||
"%s(aCallback, aCallbackGlobal, FastCallbackConstructor())" %
|
||||
baseName,
|
||||
],
|
||||
body="")
|
||||
|
|
|
@ -17,8 +17,9 @@ class TestCImplementedInterface : public TestJSImplInterface
|
|||
{
|
||||
public:
|
||||
TestCImplementedInterface(JS::Handle<JSObject*> aJSImpl,
|
||||
JS::Handle<JSObject*> aJSImplGlobal,
|
||||
nsIGlobalObject* aParent)
|
||||
: TestJSImplInterface(aJSImpl, aParent)
|
||||
: TestJSImplInterface(aJSImpl, aJSImplGlobal, aParent)
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -1054,17 +1054,27 @@ EventListenerManager::CompileEventHandlerInternal(Listener* aListener,
|
|||
NS_ENSURE_SUCCESS(result, result);
|
||||
NS_ENSURE_TRUE(handler, NS_ERROR_FAILURE);
|
||||
|
||||
MOZ_ASSERT(js::IsObjectInContextCompartment(handler, cx));
|
||||
JS::Rooted<JSObject*> handlerGlobal(cx, JS::CurrentGlobalOrNull(cx));
|
||||
|
||||
if (jsEventHandler->EventName() == nsGkAtoms::onerror && win) {
|
||||
RefPtr<OnErrorEventHandlerNonNull> handlerCallback =
|
||||
new OnErrorEventHandlerNonNull(nullptr, handler, /* aIncumbentGlobal = */ nullptr);
|
||||
new OnErrorEventHandlerNonNull(static_cast<JSContext*>(nullptr), handler,
|
||||
handlerGlobal,
|
||||
/* aIncumbentGlobal = */ nullptr);
|
||||
jsEventHandler->SetHandler(handlerCallback);
|
||||
} else if (jsEventHandler->EventName() == nsGkAtoms::onbeforeunload && win) {
|
||||
RefPtr<OnBeforeUnloadEventHandlerNonNull> handlerCallback =
|
||||
new OnBeforeUnloadEventHandlerNonNull(nullptr, handler, /* aIncumbentGlobal = */ nullptr);
|
||||
new OnBeforeUnloadEventHandlerNonNull(static_cast<JSContext*>(nullptr),
|
||||
handler,
|
||||
handlerGlobal,
|
||||
/* aIncumbentGlobal = */ nullptr);
|
||||
jsEventHandler->SetHandler(handlerCallback);
|
||||
} else {
|
||||
RefPtr<EventHandlerNonNull> handlerCallback =
|
||||
new EventHandlerNonNull(nullptr, handler, /* aIncumbentGlobal = */ nullptr);
|
||||
new EventHandlerNonNull(static_cast<JSContext*>(nullptr), handler,
|
||||
handlerGlobal,
|
||||
/* aIncumbentGlobal = */ nullptr);
|
||||
jsEventHandler->SetHandler(handlerCallback);
|
||||
}
|
||||
|
||||
|
|
|
@ -291,8 +291,9 @@ ToEventListener(JSContext* aCx, JS::Handle<JS::Value> aValue)
|
|||
}
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx, &aValue.toObject());
|
||||
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
RefPtr<EventListener> listener =
|
||||
new EventListener(aCx, obj, GetIncumbentGlobal());
|
||||
new EventListener(aCx, obj, global, GetIncumbentGlobal());
|
||||
return listener.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -377,7 +377,9 @@ nsXBLPrototypeHandler::ExecuteHandler(EventTarget* aTarget,
|
|||
NS_ENSURE_TRUE(bound, NS_ERROR_FAILURE);
|
||||
|
||||
RefPtr<EventHandlerNonNull> handlerCallback =
|
||||
new EventHandlerNonNull(nullptr, bound, /* aIncumbentGlobal = */ nullptr);
|
||||
new EventHandlerNonNull(static_cast<JSContext*>(nullptr), bound,
|
||||
scopeObject,
|
||||
/* aIncumbentGlobal = */ nullptr);
|
||||
|
||||
TypedEventHandler typedHandler(handlerCallback);
|
||||
|
||||
|
|
|
@ -131,8 +131,9 @@ nsSessionStoreUtils::AddDynamicFrameFilteredListener(EventTarget* aTarget,
|
|||
NS_ENSURE_TRUE(aTarget, NS_ERROR_NO_INTERFACE);
|
||||
|
||||
JS::Rooted<JSObject*> obj(aCx, &aListener.toObject());
|
||||
JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
RefPtr<EventListener> listener =
|
||||
new EventListener(aCx, obj, GetIncumbentGlobal());
|
||||
new EventListener(aCx, obj, global, GetIncumbentGlobal());
|
||||
|
||||
nsCOMPtr<nsIDOMEventListener> filter(new DynamicFrameEventFilter(listener));
|
||||
|
||||
|
|
|
@ -205,10 +205,12 @@ class PromiseJobRunnable final : public MicroTaskRunnable
|
|||
{
|
||||
public:
|
||||
PromiseJobRunnable(JS::HandleObject aCallback,
|
||||
JS::HandleObject aCallbackGlobal,
|
||||
JS::HandleObject aAllocationSite,
|
||||
nsIGlobalObject* aIncumbentGlobal)
|
||||
:mCallback(
|
||||
new PromiseJobCallback(aCallback, aAllocationSite, aIncumbentGlobal))
|
||||
new PromiseJobCallback(aCallback, aCallbackGlobal, aAllocationSite,
|
||||
aIncumbentGlobal))
|
||||
{
|
||||
MOZ_ASSERT(js::IsFunctionObject(aCallback));
|
||||
}
|
||||
|
@ -266,7 +268,10 @@ CycleCollectedJSContext::EnqueuePromiseJobCallback(JSContext* aCx,
|
|||
if (aIncumbentGlobal) {
|
||||
global = xpc::NativeGlobal(aIncumbentGlobal);
|
||||
}
|
||||
RefPtr<MicroTaskRunnable> runnable = new PromiseJobRunnable(aJob, aAllocationSite, global);
|
||||
JS::RootedObject jobGlobal(aCx, JS::CurrentGlobalOrNull(aCx));
|
||||
RefPtr<MicroTaskRunnable> runnable = new PromiseJobRunnable(aJob, jobGlobal,
|
||||
aAllocationSite,
|
||||
global);
|
||||
self->DispatchToMicroTask(runnable.forget());
|
||||
return true;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче