Merge mozilla-central to autoland. a=merge CLOSED TREE
Merge mozilla-central to autoland. a=merge CLOSED TREE
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -58,18 +58,23 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Promise)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mGlobal)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(Promise)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mPromiseObj);
NS_IMPL_CYCLE_COLLECTION_TRACE_END
-NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(Promise, AddRef);
-NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(Promise, Release);
+NS_IMPL_CYCLE_COLLECTING_ADDREF(Promise)
+NS_IMPL_CYCLE_COLLECTING_RELEASE(Promise)
+
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Promise)
+ NS_INTERFACE_MAP_ENTRY(nsISupports)
+ NS_INTERFACE_MAP_ENTRY(Promise)
+NS_INTERFACE_MAP_END
Promise::Promise(nsIGlobalObject* aGlobal)
: mGlobal(aGlobal)
, mPromiseObj(nullptr)
{
MOZ_ASSERT(mGlobal);
mozilla::HoldJSObjects(this);
--- a/dom/promise/Promise.h
+++ b/dom/promise/Promise.h
@@ -27,25 +27,31 @@ namespace mozilla {
namespace dom {
class AnyCallback;
class MediaStreamError;
class PromiseInit;
class PromiseNativeHandler;
class PromiseDebugging;
-class Promise : public SupportsWeakPtr<Promise>
+#define NS_PROMISE_IID \
+ { 0x1b8d6215, 0x3e67, 0x43ba, \
+ { 0x8a, 0xf9, 0x31, 0x5e, 0x8f, 0xce, 0x75, 0x65 } }
+
+class Promise : public nsISupports,
+ public SupportsWeakPtr<Promise>
{
friend class PromiseTask;
friend class PromiseWorkerProxy;
friend class PromiseWorkerProxyRunnable;
public:
- NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(Promise)
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(Promise)
+ NS_DECLARE_STATIC_IID_ACCESSOR(NS_PROMISE_IID)
+ NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+ NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(Promise)
MOZ_DECLARE_WEAKREFERENCE_TYPENAME(Promise)
// Promise creation tries to create a JS reflector for the Promise, so is
// fallible. Furthermore, we don't want to do JS-wrapping on a 0-refcount
// object, so we addref before doing that and return the addrefed pointer
// here.
static already_AddRefed<Promise>
Create(nsIGlobalObject* aGlobal, ErrorResult& aRv);
@@ -193,12 +199,14 @@ private:
void HandleException(JSContext* aCx);
RefPtr<nsIGlobalObject> mGlobal;
JS::Heap<JSObject*> mPromiseObj;
};
+NS_DEFINE_STATIC_IID_ACCESSOR(Promise, NS_PROMISE_IID)
+
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_Promise_h
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -886,16 +886,31 @@ XPCConvert::NativeInterface2JSObject(Mut
}
if (flat) {
if (allowNativeWrapper && !JS_WrapObject(cx, &flat))
return false;
d.setObjectOrNull(flat);
return true;
}
+ // NOTE(nika): Remove if Promise becomes non-nsISupports
+ if (iid->Equals(NS_GET_IID(nsISupports))) {
+ // Check for a Promise being returned via nsISupports. In that
+ // situation, we want to dig out its underlying JS object and return
+ // that.
+ RefPtr<Promise> promise = do_QueryObject(aHelper.Object());
+ if (promise) {
+ flat = promise->PromiseObj();
+ if (!JS_WrapObject(cx, &flat))
+ return false;
+ d.setObjectOrNull(flat);
+ return true;
+ }
+ }
+
// Don't double wrap CPOWs. This is a temporary measure for compatibility
// with objects that don't provide necessary QIs (such as objects under
// the new DOM bindings). We expect the other side of the CPOW to have
// the appropriate wrappers in place.
RootedObject cpow(cx, UnwrapNativeCPOW(aHelper.Object()));
if (cpow) {
if (!JS_WrapObject(cx, &cpow))
return false;
@@ -1012,16 +1027,28 @@ XPCConvert::JSObject2NativeInterface(voi
if (nsCOMPtr<mozIDOMWindow> inner = do_QueryInterface(iface)) {
iface = nsPIDOMWindowInner::From(inner)->GetOuterWindow();
return NS_SUCCEEDED(iface->QueryInterface(*iid, dest));
}
}
return false;
}
+
+ // NOTE(nika): Remove if Promise becomes non-nsISupports
+ // Deal with Promises being passed as nsISupports. In that situation we
+ // want to create a dom::Promise and use that.
+ if (iid->Equals(NS_GET_IID(nsISupports))) {
+ RootedObject innerObj(cx, inner);
+ if (IsPromiseObject(innerObj)) {
+ nsIGlobalObject* glob = NativeGlobal(innerObj);
+ RefPtr<Promise> p = Promise::CreateFromExisting(glob, innerObj);
+ return p && NS_SUCCEEDED(p->QueryInterface(*iid, dest));
+ }
+ }
}
RefPtr<nsXPCWrappedJS> wrapper;
nsresult rv = nsXPCWrappedJS::GetNewOrUsed(src, *iid, getter_AddRefs(wrapper));
if (pErr)
*pErr = rv;
if (NS_FAILED(rv) || !wrapper)