Bug 1277267 - Convert PAC runtime to autoJSAPIOwnsErrorReporting. r=bz
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 02 Jun 2016 08:29:18 +0200
changeset 339109 c6667fa95dff09f216fe345e1ffcf33b795a58ce
parent 339057 5c3ef07cd34c800c5032e45d90b1114b48cf7977
child 339110 44d925279d364d462f026f9fc68094290f8f3323
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1277267
milestone49.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 1277267 - Convert PAC runtime to autoJSAPIOwnsErrorReporting. r=bz
netwerk/base/ProxyAutoConfig.cpp
--- a/netwerk/base/ProxyAutoConfig.cpp
+++ b/netwerk/base/ProxyAutoConfig.cpp
@@ -314,28 +314,67 @@ void PACLogToConsole(nsString &aMessage)
   nsCOMPtr<nsIConsoleService> consoleService =
     do_GetService(NS_CONSOLESERVICE_CONTRACTID);
   if (!consoleService)
     return;
 
   consoleService->LogStringMessage(aMessage.get());
 }
 
-// Javascript errors are logged to the main error console
+// Javascript errors and warnings are logged to the main error console
 static void
-PACErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
+PACLogErrorOrWarning(const nsAString& aKind, JSErrorReport* aReport)
 {
-  nsString formattedMessage(NS_LITERAL_STRING("PAC Execution Error: "));
-  formattedMessage += report->ucmessage;
+  nsString formattedMessage(NS_LITERAL_STRING("PAC Execution "));
+  formattedMessage += aKind;
+  formattedMessage += NS_LITERAL_STRING(": ");
+  formattedMessage += aReport->ucmessage;
   formattedMessage += NS_LITERAL_STRING(" [");
-  formattedMessage.Append(report->linebuf(), report->linebufLength());
+  formattedMessage.Append(aReport->linebuf(), aReport->linebufLength());
   formattedMessage += NS_LITERAL_STRING("]");
   PACLogToConsole(formattedMessage);
 }
 
+static void
+PACWarningReporter(JSContext* aCx, const char* aMessage, JSErrorReport* aReport)
+{
+  MOZ_ASSERT(aReport);
+  MOZ_ASSERT(JSREPORT_IS_WARNING(aReport->flags));
+
+  PACLogErrorOrWarning(NS_LITERAL_STRING("Warning"), aReport);
+}
+
+class MOZ_STACK_CLASS AutoPACErrorReporter
+{
+  JSContext* mCx;
+
+public:
+  explicit AutoPACErrorReporter(JSContext* aCx)
+    : mCx(aCx)
+  {}
+  ~AutoPACErrorReporter() {
+    if (!JS_IsExceptionPending(mCx)) {
+      return;
+    }
+    JS::RootedValue exn(mCx);
+    if (!JS_GetPendingException(mCx, &exn)) {
+      return;
+    }
+    JS_ClearPendingException(mCx);
+
+    js::ErrorReport report(mCx);
+    if (!report.init(mCx, exn, js::ErrorReport::WithSideEffects)) {
+      JS_ClearPendingException(mCx);
+      return;
+    }
+
+    PACLogErrorOrWarning(NS_LITERAL_STRING("Error"), report.report());
+  }
+};
+
 // timeout of 0 means the normal necko timeout strategy, otherwise the dns request
 // will be canceled after aTimeout milliseconds
 static
 bool PACResolve(const nsCString &aHostName, NetAddr *aNetAddr,
                 unsigned int aTimeout)
 {
   if (!GetRunning()) {
     NS_WARNING("PACResolve without a running ProxyAutoConfig object");
@@ -638,36 +677,44 @@ private:
   nsresult Init()
   {
     /*
      * Not setting this will cause JS_CHECK_RECURSION to report false
      * positives
      */
     JS_SetNativeStackQuota(mRuntime, 128 * sizeof(size_t) * 1024);
 
-    JS_SetErrorReporter(mRuntime, PACErrorReporter);
+    JS_SetErrorReporter(mRuntime, PACWarningReporter);
 
     mContext = JS_NewContext(mRuntime, 0);
     NS_ENSURE_TRUE(mContext, NS_ERROR_OUT_OF_MEMORY);
 
+    JS::ContextOptionsRef(mContext).setAutoJSAPIOwnsErrorReporting(true);
+
     JSAutoRequest ar(mContext);
 
     JS::CompartmentOptions options;
     options.creationOptions().setZone(JS::SystemZone);
     options.behaviors().setVersion(JSVERSION_LATEST);
     mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, nullptr,
                                  JS::DontFireOnNewGlobalHook, options);
-    NS_ENSURE_TRUE(mGlobal, NS_ERROR_OUT_OF_MEMORY);
+    if (!mGlobal) {
+      JS_ClearPendingException(mContext);
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
     JS::Rooted<JSObject*> global(mContext, mGlobal);
 
     JSAutoCompartment ac(mContext, global);
-    JS_InitStandardClasses(mContext, global);
-
-    if (!JS_DefineFunctions(mContext, global, PACGlobalFunctions))
+    AutoPACErrorReporter aper(mContext);
+    if (!JS_InitStandardClasses(mContext, global)) {
       return NS_ERROR_FAILURE;
+    }
+    if (!JS_DefineFunctions(mContext, global, PACGlobalFunctions)) {
+      return NS_ERROR_FAILURE;
+    }
 
     JS_FireOnNewGlobalObject(mContext, global);
 
     return NS_OK;
   }
 };
 
 static const JSClassOps sJSRuntimeWrapperGlobalClassOps = {
@@ -718,16 +765,17 @@ ProxyAutoConfig::SetupJS()
 
   mJSRuntime = JSRuntimeWrapper::Create();
   if (!mJSRuntime)
     return NS_ERROR_FAILURE;
 
   JSContext* cx = mJSRuntime->Context();
   JSAutoRequest ar(cx);
   JSAutoCompartment ac(cx, mJSRuntime->Global());
+  AutoPACErrorReporter aper(cx);
 
   // check if this is a data: uri so that we don't spam the js console with
   // huge meaningless strings. this is not on the main thread, so it can't
   // use nsIRUI scheme methods
   bool isDataURI = nsDependentCSubstring(mPACURI, 0, 5).LowerCaseEqualsASCII("data:", 5);
 
   SetRunning(this);
   JS::Rooted<JSObject*> global(cx, mJSRuntime->Global());
@@ -780,16 +828,17 @@ ProxyAutoConfig::GetProxyForURI(const ns
     SetupJS();
 
   if (!mJSRuntime || !mJSRuntime->IsOK())
     return NS_ERROR_NOT_AVAILABLE;
 
   JSContext *cx = mJSRuntime->Context();
   JSAutoRequest ar(cx);
   JSAutoCompartment ac(cx, mJSRuntime->Global());
+  AutoPACErrorReporter aper(cx);
 
   // the sRunning flag keeps a new PAC file from being installed
   // while the event loop is spinning on a DNS function. Don't early return.
   SetRunning(this);
   mRunningHost = aTestHost;
   mRunningAppId = aAppId;
   mRunningAppOrigin = aAppOrigin;
   mRunningIsInIsolatedMozBrowser = aIsInIsolatedMozBrowser;