зеркало из https://github.com/mozilla/gecko-dev.git
Bug 862629 part 1. Stop playing compartment games with WebIDL callbacks and just use the given object as-is. r=peterv
This commit is contained in:
Родитель
d7b1013b15
Коммит
f3f44cfa74
|
@ -2102,20 +2102,11 @@ nsINode::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
|
|||
return NS_OK; \
|
||||
} \
|
||||
NS_IMETHODIMP nsINode::SetOn##name_(JSContext *cx, const JS::Value &v) { \
|
||||
JSObject *obj = GetWrapper(); \
|
||||
if (!obj) { \
|
||||
/* Just silently do nothing */ \
|
||||
return NS_OK; \
|
||||
} \
|
||||
nsRefPtr<EventHandlerNonNull> handler; \
|
||||
JSObject *callable; \
|
||||
if (v.isObject() && \
|
||||
JS_ObjectIsCallable(cx, callable = &v.toObject())) { \
|
||||
bool ok; \
|
||||
handler = new EventHandlerNonNull(cx, obj, callable, &ok); \
|
||||
if (!ok) { \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
handler = new EventHandlerNonNull(callable); \
|
||||
} \
|
||||
ErrorResult rv; \
|
||||
SetOn##name_(handler, rv); \
|
||||
|
|
|
@ -283,20 +283,11 @@ nsDOMEventTargetHelper::SetEventHandler(nsIAtom* aType,
|
|||
JSContext* aCx,
|
||||
const JS::Value& aValue)
|
||||
{
|
||||
JSObject* obj = GetWrapper();
|
||||
if (!obj) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<EventHandlerNonNull> handler;
|
||||
JSObject* callable;
|
||||
if (aValue.isObject() &&
|
||||
JS_ObjectIsCallable(aCx, callable = &aValue.toObject())) {
|
||||
bool ok;
|
||||
handler = new EventHandlerNonNull(aCx, obj, callable, &ok);
|
||||
if (!ok) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
handler = new EventHandlerNonNull(callable);
|
||||
}
|
||||
ErrorResult rv;
|
||||
SetEventHandler(aType, handler, rv);
|
||||
|
|
|
@ -874,37 +874,16 @@ nsEventListenerManager::CompileEventHandlerInternal(nsListenerStruct *aListenerS
|
|||
context->BindCompiledEventHandler(mTarget, listener->GetEventScope(),
|
||||
handler, &boundHandler);
|
||||
if (listener->EventName() == nsGkAtoms::onerror && win) {
|
||||
bool ok;
|
||||
JSAutoRequest ar(cx);
|
||||
nsRefPtr<OnErrorEventHandlerNonNull> handlerCallback =
|
||||
new OnErrorEventHandlerNonNull(cx, listener->GetEventScope(),
|
||||
boundHandler, &ok);
|
||||
if (!ok) {
|
||||
// JS_WrapObject failed, which means OOM allocating the JSObject.
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
new OnErrorEventHandlerNonNull(boundHandler);
|
||||
listener->SetHandler(handlerCallback);
|
||||
} else if (listener->EventName() == nsGkAtoms::onbeforeunload && win) {
|
||||
bool ok;
|
||||
JSAutoRequest ar(cx);
|
||||
nsRefPtr<BeforeUnloadEventHandlerNonNull> handlerCallback =
|
||||
new BeforeUnloadEventHandlerNonNull(cx, listener->GetEventScope(),
|
||||
boundHandler, &ok);
|
||||
if (!ok) {
|
||||
// JS_WrapObject failed, which means OOM allocating the JSObject.
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
new BeforeUnloadEventHandlerNonNull(boundHandler);
|
||||
listener->SetHandler(handlerCallback);
|
||||
} else {
|
||||
bool ok;
|
||||
JSAutoRequest ar(cx);
|
||||
nsRefPtr<EventHandlerNonNull> handlerCallback =
|
||||
new EventHandlerNonNull(cx, listener->GetEventScope(),
|
||||
boundHandler, &ok);
|
||||
if (!ok) {
|
||||
// JS_WrapObject failed, which means OOM allocating the JSObject.
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
new EventHandlerNonNull(boundHandler);
|
||||
listener->SetHandler(handlerCallback);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -506,20 +506,11 @@ HTMLBodyElement::IsEventAttributeName(nsIAtom *aName)
|
|||
NS_IMETHODIMP \
|
||||
HTMLBodyElement::SetOn##name_(JSContext *cx, const JS::Value &v) \
|
||||
{ \
|
||||
JSObject *obj = GetWrapper(); \
|
||||
if (!obj) { \
|
||||
/* Just silently do nothing */ \
|
||||
return NS_OK; \
|
||||
} \
|
||||
nsRefPtr<type_> handler; \
|
||||
JSObject *callable; \
|
||||
if (v.isObject() && \
|
||||
JS_ObjectIsCallable(cx, callable = &v.toObject())) { \
|
||||
bool ok; \
|
||||
handler = new type_(cx, obj, callable, &ok); \
|
||||
if (!ok) { \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
handler = new type_(callable); \
|
||||
} \
|
||||
ErrorResult rv; \
|
||||
forwardto_::SetOn##name_(handler, rv); \
|
||||
|
|
|
@ -371,20 +371,11 @@ HTMLFrameSetElement::IsEventAttributeName(nsIAtom *aName)
|
|||
NS_IMETHODIMP \
|
||||
HTMLFrameSetElement::SetOn##name_(JSContext *cx, const JS::Value &v) \
|
||||
{ \
|
||||
JSObject *obj = GetWrapper(); \
|
||||
if (!obj) { \
|
||||
/* Just silently do nothing */ \
|
||||
return NS_OK; \
|
||||
} \
|
||||
nsRefPtr<type_> handler; \
|
||||
JSObject *callable; \
|
||||
if (v.isObject() && \
|
||||
JS_ObjectIsCallable(cx, callable = &v.toObject())) { \
|
||||
bool ok; \
|
||||
handler = new type_(cx, obj, callable, &ok); \
|
||||
if (!ok) { \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
handler = new type_(callable); \
|
||||
} \
|
||||
ErrorResult rv; \
|
||||
forwardto_::SetOn##name_(handler, rv); \
|
||||
|
|
|
@ -325,13 +325,9 @@ nsXBLPrototypeHandler::ExecuteHandler(EventTarget* aTarget,
|
|||
if (!JS_WrapObject(cx, bound.address())) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
JS::Rooted<JSObject*> boundHandler(cx, bound);
|
||||
|
||||
nsRefPtr<EventHandlerNonNull> handlerCallback =
|
||||
new EventHandlerNonNull(cx, globalObject, boundHandler, &ok);
|
||||
if (!ok) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
new EventHandlerNonNull(bound);
|
||||
|
||||
nsEventHandler eventHandler(handlerCallback);
|
||||
|
||||
|
|
|
@ -11799,20 +11799,11 @@ nsGlobalWindow::DisableNetworkEvent(uint32_t aType)
|
|||
} \
|
||||
NS_IMETHODIMP nsGlobalWindow::SetOn##name_(JSContext *cx, \
|
||||
const JS::Value &v) { \
|
||||
JSObject *obj = mJSObject; \
|
||||
if (!obj) { \
|
||||
/* Just silently do nothing */ \
|
||||
return NS_OK; \
|
||||
} \
|
||||
nsRefPtr<EventHandlerNonNull> handler; \
|
||||
JSObject *callable; \
|
||||
if (v.isObject() && \
|
||||
JS_ObjectIsCallable(cx, callable = &v.toObject())) { \
|
||||
bool ok; \
|
||||
handler = new EventHandlerNonNull(cx, obj, callable, &ok); \
|
||||
if (!ok) { \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
handler = new EventHandlerNonNull(callable); \
|
||||
} \
|
||||
ErrorResult rv; \
|
||||
SetOn##name_(handler, rv); \
|
||||
|
@ -11839,19 +11830,11 @@ nsGlobalWindow::DisableNetworkEvent(uint32_t aType)
|
|||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
\
|
||||
JSObject *obj = mJSObject; \
|
||||
if (!obj) { \
|
||||
return NS_ERROR_UNEXPECTED; \
|
||||
} \
|
||||
nsRefPtr<OnErrorEventHandlerNonNull> handler; \
|
||||
JSObject *callable; \
|
||||
if (v.isObject() && \
|
||||
JS_ObjectIsCallable(cx, callable = &v.toObject())) { \
|
||||
bool ok; \
|
||||
handler = new OnErrorEventHandlerNonNull(cx, obj, callable, &ok); \
|
||||
if (!ok) { \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
handler = new OnErrorEventHandlerNonNull(callable); \
|
||||
} \
|
||||
return elm->SetEventHandler(handler); \
|
||||
}
|
||||
|
@ -11877,19 +11860,11 @@ nsGlobalWindow::DisableNetworkEvent(uint32_t aType)
|
|||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
\
|
||||
JSObject *obj = mJSObject; \
|
||||
if (!obj) { \
|
||||
return NS_ERROR_UNEXPECTED; \
|
||||
} \
|
||||
nsRefPtr<BeforeUnloadEventHandlerNonNull> handler; \
|
||||
JSObject *callable; \
|
||||
if (v.isObject() && \
|
||||
JS_ObjectIsCallable(cx, callable = &v.toObject())) { \
|
||||
bool ok; \
|
||||
handler = new BeforeUnloadEventHandlerNonNull(cx, obj, callable, &ok); \
|
||||
if (!ok) { \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
handler = new BeforeUnloadEventHandlerNonNull(callable); \
|
||||
} \
|
||||
return elm->SetEventHandler(handler); \
|
||||
}
|
||||
|
|
|
@ -293,12 +293,7 @@ nsJSScriptTimeoutHandler::Init(nsGlobalWindow *aWindow, bool *aIsInterval,
|
|||
} else if (funobj) {
|
||||
NS_HOLD_JS_OBJECTS(this, nsJSScriptTimeoutHandler);
|
||||
|
||||
bool ok;
|
||||
mFunction = new Function(cx, aWindow->FastGetGlobalJSObject(), funobj, &ok);
|
||||
if (!ok) {
|
||||
NS_DROP_JS_OBJECTS(this, nsJSScriptTimeoutHandler);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mFunction = new Function(funobj);
|
||||
|
||||
// Create our arg array. argc is the number of arguments passed
|
||||
// to setTimeout or setInterval; the first two are our callback
|
||||
|
|
|
@ -25,18 +25,10 @@ namespace dom {
|
|||
class CallbackFunction : public CallbackObject
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a CallbackFunction. aCallable is the callable we're wrapping.
|
||||
* aOwner is the object that will be receiving this CallbackFunction as a
|
||||
* method argument, if any. We need this so we can store our callable in the
|
||||
* same compartment as our owner. If *aInited is set to false, an exception
|
||||
* has been thrown.
|
||||
*/
|
||||
CallbackFunction(JSContext* cx, JSObject* aOwner, JSObject* aCallable,
|
||||
bool* aInited)
|
||||
: CallbackObject(cx, aOwner, aCallable, aInited)
|
||||
explicit CallbackFunction(JSObject* aCallable)
|
||||
: CallbackObject(aCallable)
|
||||
{
|
||||
MOZ_ASSERT(JS_ObjectIsCallable(cx, aCallable));
|
||||
MOZ_ASSERT(JS_ObjectIsCallable(nullptr, aCallable));
|
||||
}
|
||||
|
||||
JSObject* Callable() const
|
||||
|
|
|
@ -24,24 +24,6 @@ namespace dom {
|
|||
class CallbackInterface : public CallbackObject
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create a CallbackInterface. aCallback is the callback object we're
|
||||
* wrapping. aOwner is the object that will be receiving this
|
||||
* CallbackInterface as a method argument, if any. We need this so we can
|
||||
* store our callable in the same compartment as our owner. If *aInited is
|
||||
* set to false, an exception has been thrown.
|
||||
*/
|
||||
CallbackInterface(JSContext* cx, JSObject* aOwner, JSObject* aCallback,
|
||||
bool* aInited)
|
||||
: CallbackObject(cx, aOwner, aCallback, aInited)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a CallbackInterface without any sort of interesting games with
|
||||
* compartments, for cases when you want to just use the existing object
|
||||
* as-is. This constructor can never fail.
|
||||
*/
|
||||
explicit CallbackInterface(JSObject* aCallback)
|
||||
: CallbackObject(aCallback)
|
||||
{
|
||||
|
|
|
@ -46,37 +46,6 @@ public:
|
|||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(CallbackObject)
|
||||
|
||||
/**
|
||||
* Create a CallbackObject. aCallback is the callback object we're wrapping.
|
||||
* aOwner is the object that will be receiving this CallbackObject as a method
|
||||
* argument, if any. We need this so we can store our callback object in the
|
||||
* same compartment as our owner. If *aInited is set to false, an exception
|
||||
* has been thrown.
|
||||
*/
|
||||
CallbackObject(JSContext* cx, JSObject* aOwner, JSObject* aCallback,
|
||||
bool* aInited)
|
||||
: mCallback(nullptr)
|
||||
{
|
||||
// If aOwner is not null, enter the compartment of aOwner's
|
||||
// underlying object.
|
||||
if (aOwner) {
|
||||
aOwner = js::UncheckedUnwrap(aOwner);
|
||||
JSAutoCompartment ac(cx, aOwner);
|
||||
if (!JS_WrapObject(cx, &aCallback)) {
|
||||
*aInited = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Init(aCallback);
|
||||
*aInited = true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a CallbackObject without any sort of interesting games with
|
||||
* compartments, for cases when you want to just use the existing object
|
||||
* as-is. This constructor can never fail.
|
||||
*/
|
||||
explicit CallbackObject(JSObject* aCallback)
|
||||
{
|
||||
Init(aCallback);
|
||||
|
@ -377,12 +346,7 @@ public:
|
|||
SafeAutoJSContext cx;
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
|
||||
bool inited;
|
||||
nsRefPtr<WebIDLCallbackT> newCallback =
|
||||
new WebIDLCallbackT(cx, nullptr, obj, &inited);
|
||||
if (!inited) {
|
||||
return nullptr;
|
||||
}
|
||||
nsRefPtr<WebIDLCallbackT> newCallback = new WebIDLCallbackT(obj);
|
||||
return newCallback.forget();
|
||||
}
|
||||
|
||||
|
|
|
@ -2793,11 +2793,8 @@ for (uint32_t i = 0; i < length; ++i) {
|
|||
else:
|
||||
declType = CGGeneric("OwningNonNull<%s>" % name)
|
||||
conversion = (
|
||||
" bool inited;\n"
|
||||
" ${declName} = new %s(cx, ${obj}, &${val}.toObject(), &inited);\n"
|
||||
" if (!inited) {\n"
|
||||
"%s\n"
|
||||
" }\n" % (name, CGIndenter(exceptionCodeIndented).define()))
|
||||
" ${declName} = new %s(&${val}.toObject());\n" % name)
|
||||
|
||||
template = wrapObjectTemplate(conversion, type,
|
||||
"${declName} = nullptr",
|
||||
failureCode)
|
||||
|
@ -3112,11 +3109,7 @@ for (uint32_t i = 0; i < length; ++i) {
|
|||
else:
|
||||
declType = CGGeneric("OwningNonNull<%s>" % name)
|
||||
conversion = (
|
||||
" bool inited;\n"
|
||||
" ${declName} = new %s(cx, ${obj}, &${val}.toObject(), &inited);\n"
|
||||
" if (!inited) {\n"
|
||||
"%s\n"
|
||||
" }\n" % (name, CGIndenter(exceptionCodeIndented).define()))
|
||||
" ${declName} = new %s(&${val}.toObject());\n" % name)
|
||||
|
||||
if allowTreatNonCallableAsNull and type.treatNonCallableAsNull():
|
||||
haveCallable = "JS_ObjectIsCallable(cx, &${val}.toObject())"
|
||||
|
@ -8508,14 +8501,12 @@ class CGCallback(CGClass):
|
|||
|
||||
def getConstructors(self):
|
||||
return [ClassConstructor(
|
||||
[Argument("JSContext*", "cx"),
|
||||
Argument("JSObject*", "aOwner"),
|
||||
Argument("JSObject*", "aCallback"),
|
||||
Argument("bool*", "aInited")],
|
||||
[Argument("JSObject*", "aCallback")],
|
||||
bodyInHeader=True,
|
||||
visibility="public",
|
||||
explicit=True,
|
||||
baseConstructors=[
|
||||
"%s(cx, aOwner, aCallback, aInited)" % self.baseName
|
||||
"%s(aCallback)" % self.baseName
|
||||
])]
|
||||
|
||||
def getMethodImpls(self, method):
|
||||
|
@ -8608,16 +8599,6 @@ class CGCallbackInterface(CGCallback):
|
|||
CGCallback.__init__(self, iface, descriptor, "CallbackInterface",
|
||||
methods, getters=getters, setters=setters)
|
||||
|
||||
def getConstructors(self):
|
||||
return CGCallback.getConstructors(self) + [
|
||||
ClassConstructor(
|
||||
[Argument("JSObject*", "aCallback")],
|
||||
bodyInHeader=True,
|
||||
visibility="public",
|
||||
explicit=True,
|
||||
baseConstructors=["CallbackInterface(aCallback)"])
|
||||
]
|
||||
|
||||
class FakeMember():
|
||||
def __init__(self):
|
||||
self.treatUndefinedAs = self.treatNullAs = "Default"
|
||||
|
|
Загрузка…
Ссылка в новой задаче