Bug 966452 part 2. Report all unhandled Promise rejections. r=nsm,bholley
authorBoris Zbarsky <bzbarsky@mit.edu>
Fri, 04 Jul 2014 01:24:59 -0400
changeset 217035 f169e4abd298a70cd6b3ecd3a98f33b76f3b17bd
parent 217034 a2f5fa870c8aaabf3ca79e925988baece89391e1
child 217037 d974be1f13cd1a36029c52e7673659ee76ea9c4d
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnsm, bholley
bugs966452
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 966452 part 2. Report all unhandled Promise rejections. r=nsm,bholley
dom/promise/Promise.cpp
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -19,16 +19,19 @@
 #include "PromiseWorkerProxy.h"
 #include "nsContentUtils.h"
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
 #include "nsJSPrincipals.h"
 #include "nsJSUtils.h"
 #include "nsPIDOMWindow.h"
 #include "nsJSEnvironment.h"
+#include "nsIScriptObjectPrincipal.h"
+#include "xpcpublic.h"
+#include "nsGlobalWindow.h"
 
 namespace mozilla {
 namespace dom {
 
 using namespace workers;
 
 NS_IMPL_ISUPPORTS0(PromiseNativeHandler)
 
@@ -1055,50 +1058,61 @@ Promise::RunTask()
 
 void
 Promise::MaybeReportRejected()
 {
   if (mState != Rejected || mHadRejectCallback || mResult.isUndefined()) {
     return;
   }
 
-  if (!mResult.isObject()) {
+  AutoJSAPI jsapi;
+  // We may not have a usable global by now (if it got unlinked
+  // already), so don't init with it.
+  jsapi.Init();
+  JSContext* cx = jsapi.cx();
+  JS::Rooted<JSObject*> obj(cx, GetWrapper());
+  MOZ_ASSERT(obj); // We preserve our wrapper, so should always have one here.
+  JS::Rooted<JS::Value> val(cx, mResult);
+  JS::ExposeValueToActiveJS(val);
+
+  JSAutoCompartment ac(cx, obj);
+  if (!JS_WrapValue(cx, &val)) {
+    JS_ClearPendingException(cx);
     return;
   }
-  ThreadsafeAutoJSContext cx;
-  JS::Rooted<JSObject*> obj(cx, &mResult.toObject());
-  JSAutoCompartment ac(cx, obj);
-  JSErrorReport* report = JS_ErrorFromException(cx, obj);
-  if (!report) {
+
+  js::ErrorReport report(cx);
+  if (!report.init(cx, val)) {
+    JS_ClearPendingException(cx);
     return;
   }
 
   // Remains null in case of worker.
   nsCOMPtr<nsPIDOMWindow> win;
   bool isChromeError = false;
 
   if (MOZ_LIKELY(NS_IsMainThread())) {
-    win =
-      do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(obj));
-    nsIPrincipal* principal = nsContentUtils::ObjectPrincipal(obj);
+    nsIPrincipal* principal;
+    win = xpc::WindowGlobalOrNull(obj);
+    principal = nsContentUtils::ObjectPrincipal(obj);
     isChromeError = nsContentUtils::IsSystemPrincipal(principal);
   } else {
     WorkerPrivate* worker = GetCurrentThreadWorkerPrivate();
     MOZ_ASSERT(worker);
     isChromeError = worker->IsChromeWorker();
   }
 
   // Now post an event to do the real reporting async
   // Since Promises preserve their wrapper, it is essential to nsRefPtr<> the
   // AsyncErrorReporter, otherwise if the call to DispatchToMainThread fails, it
   // will leak. See Bug 958684.
   nsRefPtr<AsyncErrorReporter> r =
-    new AsyncErrorReporter(JS_GetObjectRuntime(obj),
-                           report,
-                           nullptr,
+    new AsyncErrorReporter(CycleCollectedJSRuntime::Get()->Runtime(),
+                           report.report(),
+                           report.message(),
                            isChromeError,
                            win);
   NS_DispatchToMainThread(r);
 }
 
 void
 Promise::MaybeResolveInternal(JSContext* aCx,
                               JS::Handle<JS::Value> aValue,