Bug 1506475 - Add JS::AutoSuppressWarningReporter. r=jwalden
authorTed Campbell <tcampbell@mozilla.com>
Fri, 30 Nov 2018 04:01:10 +0000
changeset 505348 04278c8117a33780adeace5cae0bee2f746ced27
parent 505347 27ff7165e2e3e9b8023bd9a93a9358386e48e81e
child 505349 8a30088cd2b2446add5d4ec4bf2813eecc792b04
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwalden
bugs1506475
milestone65.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 1506475 - Add JS::AutoSuppressWarningReporter. r=jwalden Differential Revision: https://phabricator.services.mozilla.com/D11586
ipc/testshell/XPCShellEnvironment.cpp
js/src/jsapi.h
js/src/vm/CompilationAndEvaluation.cpp
js/src/vm/Debugger.cpp
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -337,27 +337,25 @@ XPCShellEnvironment::ProcessFile(JSConte
         /* Clear any pending exception from previous failed compiles.  */
         JS_ClearPendingException(cx);
 
         JS::CompileOptions options(cx);
         options.setFileAndLine("typein", startline);
 
         JS::Rooted<JSScript*> script(cx);
         if (JS::CompileUtf8(cx, options, buffer, strlen(buffer), &script)) {
-            JS::WarningReporter older;
 
             ok = JS_ExecuteScript(cx, script, &result);
             if (ok && !result.isUndefined()) {
                 /* Suppress warnings from JS::ToString(). */
-                older = JS::SetWarningReporter(cx, nullptr);
+                JS::AutoSuppressWarningReporter suppressWarnings(cx);
                 str = JS::ToString(cx, result);
                 JS::UniqueChars bytes;
                 if (str)
                     bytes = JS_EncodeStringToLatin1(cx, str);
-                JS::SetWarningReporter(cx, older);
 
                 if (!!bytes)
                     fprintf(stdout, "%s\n", bytes.get());
                 else
                     ok = false;
             }
         }
     } while (!hitEOF && !env->IsQuitting());
@@ -507,22 +505,22 @@ XPCShellEnvironment::EvaluateString(cons
 
   if (aResult) {
       aResult->Truncate();
   }
 
   JS::Rooted<JS::Value> result(cx);
   bool ok = JS_ExecuteScript(cx, script, &result);
   if (ok && !result.isUndefined()) {
-      JS::WarningReporter old = JS::SetWarningReporter(cx, nullptr);
+      /* Suppress warnings from JS::ToString(). */
+      JS::AutoSuppressWarningReporter suppressWarnings(cx);
       JSString* str = JS::ToString(cx, result);
       nsAutoJSString autoStr;
       if (str)
           autoStr.init(cx, str);
-      JS::SetWarningReporter(cx, old);
 
       if (!autoStr.IsEmpty() && aResult) {
           aResult->Assign(autoStr);
       }
   }
 
   return true;
 }
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -4187,16 +4187,40 @@ namespace JS {
 using WarningReporter = void (*)(JSContext* cx, JSErrorReport* report);
 
 extern JS_PUBLIC_API WarningReporter
 SetWarningReporter(JSContext* cx, WarningReporter reporter);
 
 extern JS_PUBLIC_API WarningReporter
 GetWarningReporter(JSContext* cx);
 
+// Suppress the Warning Reporter callback temporarily.
+class MOZ_RAII JS_PUBLIC_API AutoSuppressWarningReporter
+{
+    JSContext* context_;
+    WarningReporter prevReporter_;
+
+  public:
+    explicit AutoSuppressWarningReporter(JSContext* cx)
+        : context_(cx)
+    {
+        prevReporter_ = SetWarningReporter(context_, nullptr);
+    }
+
+    ~AutoSuppressWarningReporter()
+    {
+#ifdef DEBUG
+        WarningReporter reporter =
+#endif
+            SetWarningReporter(context_, prevReporter_);
+        MOZ_ASSERT(reporter == nullptr, "Unexpected WarningReporter active");
+        SetWarningReporter(context_, prevReporter_);
+    }
+};
+
 extern JS_PUBLIC_API bool
 CreateError(JSContext* cx, JSExnType type, HandleObject stack,
             HandleString fileName, uint32_t lineNumber, uint32_t columnNumber,
             JSErrorReport* report, HandleString message, MutableHandleValue rval);
 
 /************************************************************************/
 
 /*
--- a/js/src/vm/CompilationAndEvaluation.cpp
+++ b/js/src/vm/CompilationAndEvaluation.cpp
@@ -243,32 +243,31 @@ JS_Utf8BufferIsCompilableUnit(JSContext*
     UsedNameTracker usedNames(cx);
 
     Rooted<ScriptSourceObject*> sourceObject(cx);
     sourceObject = CreateScriptSourceObject(cx, options, mozilla::Nothing());
     if (!sourceObject) {
         return false;
     }
 
+    JS::AutoSuppressWarningReporter suppressWarnings(cx);
     Parser<FullParseHandler, char16_t> parser(cx, cx->tempLifoAlloc(), options,
                                               chars.get(), length, /* foldConstants = */ true,
                                               usedNames, nullptr, nullptr, sourceObject,
                                               ParseGoal::Script);
-    JS::WarningReporter older = JS::SetWarningReporter(cx, nullptr);
     if (!parser.checkOptions() || !parser.parse()) {
         // We ran into an error. If it was because we ran out of source, we
         // return false so our caller knows to try to collect more buffered
         // source.
         if (parser.isUnexpectedEOF()) {
             result = false;
         }
 
         cx->clearPendingException();
     }
-    JS::SetWarningReporter(cx, older);
 
     return result;
 }
 
 /*
  * enclosingScope is a scope, if any (e.g. a WithScope).  If the scope is the
  * global scope, this must be null.
  *
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -5663,41 +5663,40 @@ Debugger::isCompilableUnit(JSContext* cx
     frontend::UsedNameTracker usedNames(cx);
 
     RootedScriptSourceObject sourceObject(cx, frontend::CreateScriptSourceObject(cx, options,
                                                                                  Nothing()));
     if (!sourceObject) {
         return false;
     }
 
+    JS::AutoSuppressWarningReporter suppressWarnings(cx);
     frontend::Parser<frontend::FullParseHandler, char16_t> parser(cx, cx->tempLifoAlloc(),
                                                                   options, chars.twoByteChars(),
                                                                   length,
                                                                   /* foldConstants = */ true,
                                                                   usedNames, nullptr, nullptr,
                                                                   sourceObject,
                                                                   frontend::ParseGoal::Script);
-    JS::WarningReporter older = JS::SetWarningReporter(cx, nullptr);
     if (!parser.checkOptions() || !parser.parse()) {
         // We ran into an error. If it was because we ran out of memory we report
         // it in the usual way.
         if (cx->isThrowingOutOfMemory()) {
-            JS::SetWarningReporter(cx, older);
             return false;
         }
 
         // If it was because we ran out of source, we return false so our caller
         // knows to try to collect more [source].
         if (parser.isUnexpectedEOF()) {
             result = false;
         }
 
         cx->clearPendingException();
     }
-    JS::SetWarningReporter(cx, older);
+
     args.rval().setBoolean(result);
     return true;
 }
 
 /* static */ bool
 Debugger::recordReplayProcessKind(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);