Backed out 3 changesets (bug 1623226) for Devtools failures in browser/browser_webconsole_stubs_page_error.js. CLOSED TREE
authorDorel Luca <dluca@mozilla.com>
Tue, 31 Mar 2020 04:16:44 +0300
changeset 521190 ce00073cc7e381802f95f1cfa08030ecc66e78a3
parent 521189 41f5b44d1438042c88723e9340accfeb57665fb9
child 521191 cb87343d4976405a9d9eece15fc1afca7eb7b81d
push id111550
push userdluca@mozilla.com
push dateTue, 31 Mar 2020 01:17:08 +0000
treeherderautoland@ce00073cc7e3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1623226
milestone76.0a1
backs out312da02ea6d6aef4ae98390fd2939543c3cd6b64
798079ba88f77fba158c3a6e0c341240ff9e225c
83f0b1c5399c70fa96a45013c0d73a5486d3eb5a
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
Backed out 3 changesets (bug 1623226) for Devtools failures in browser/browser_webconsole_stubs_page_error.js. CLOSED TREE Backed out changeset 312da02ea6d6 (bug 1623226) Backed out changeset 798079ba88f7 (bug 1623226) Backed out changeset 83f0b1c5399c (bug 1623226)
dom/script/ScriptSettings.cpp
dom/tests/mochitest/bugs/test_onerror_message.html
js/src/jit-test/tests/structured-clone/saved-stack.js
js/src/jsexn.cpp
js/src/jsfriendapi.h
js/src/shell/js.cpp
js/src/vm/SavedFrame.h
js/src/vm/SavedStacks.cpp
js/src/vm/SavedStacks.h
js/src/vm/StructuredClone.cpp
testing/web-platform/tests/html/webappapis/scripting/processing-model-2/window-onerror-runtime-error-throw.html
--- a/dom/script/ScriptSettings.cpp
+++ b/dom/script/ScriptSettings.cpp
@@ -491,17 +491,17 @@ void AutoJSAPI::ReportException() {
     }
   }
   MOZ_ASSERT(JS_IsGlobalObject(errorGlobal));
   JSAutoRealm ar(cx(), errorGlobal);
   JS::Rooted<JS::Value> exn(cx());
   JS::Rooted<JSObject*> exnStack(cx());
   js::ErrorReport jsReport(cx());
   if (StealExceptionAndStack(&exn, &exnStack) &&
-      jsReport.init(cx(), exn, js::ErrorReport::WithSideEffects, exnStack)) {
+      jsReport.init(cx(), exn, js::ErrorReport::WithSideEffects)) {
     if (mIsMainThread) {
       RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
 
       RefPtr<nsGlobalWindowInner> inner = xpc::WindowOrNull(errorGlobal);
       bool isChrome =
           nsContentUtils::ObjectPrincipal(errorGlobal)->IsSystemPrincipal();
       xpcReport->Init(jsReport.report(), jsReport.toStringResult().c_str(),
                       isChrome, inner ? inner->WindowID() : 0);
--- a/dom/tests/mochitest/bugs/test_onerror_message.html
+++ b/dom/tests/mochitest/bugs/test_onerror_message.html
@@ -19,21 +19,21 @@ https://bugzilla.mozilla.org/show_bug.cg
 <script type="application/javascript">
 "use strict";
 
 /** Test for Bug 743049 **/
 
 var expected = [
 { name: "Error", message: "foo", filename: String(location), lineNumber: 45 },
 { name: "Error", message: "foo", filename: "bar", lineNumber: 123 },
-{ name: "", message: "uncaught exception: [object Object]", filename: location.href, lineNumber: 80 },
+{ name: "", message: "uncaught exception: [object Object]" },
 { name: "DuckError", message: "foo", filename: "bar", lineNumber: 123 },
-{ name: "", message: "uncaught exception: [object Object]", filename: location.href, lineNumber: 80 },
+{ name: "", message: "uncaught exception: [object Object]" },
 { name: "", message: "foo", filename: "baz", lineNumber: 123 },
-{ name: "", message: "uncaught exception: [object Object]", filename: location.href, lineNumber: 80 },
+{ name: "", message: "uncaught exception: [object Object]" },
 { name: "InvalidStateError", message: "Cannot set 'responseType' property on XMLHttpRequest after 'send()' (when its state is LOADING or DONE).", filename: String(location), lineNumber: 62 },
 { name: "ReferenceError", message: "xxx is not defined", filename: String(location), lineNumber: 64 },
 { name: "ReferenceError", message: "xxx is not defined", filename: String(location), lineNumber: 66 }
 ];
 
 var counter = 0;
 var origin = location.protocol + "//" + location.host;
 postMessage(counter, origin);
@@ -71,25 +71,27 @@ window.onmessage = function(e) {
 	} catch (e) {
 		if (e instanceof Error || typeof e.message=="string" &&
 			("filename" in e || "fileName" in e) && "lineNumber" in e) {
 			is(e.message, expected[counter].message, counter + " catch message");
 			is(e.filename || e.fileName, expected[counter].filename, counter + " catch filename");
 			is(e.lineNumber, expected[counter].lineNumber, counter + " catch lineno");
 		} else {
 			is("uncaught exception: " + e, expected[counter].message, counter + " catch message");
+			is(undefined, expected[counter].filename, counter + " catch filename");
+			is(undefined, expected[counter].lineNumber, counter + " catch lineno");
 		}
 		throw e;
 	}
 	ok(false, counter + " Error should be thrown or test should finish");
 };
 window.onerror = function(message, filename, lineno) {
 	is(message, Error.prototype.toString.call(expected[counter]), counter + " onerror message");
-	is(filename, expected[counter].filename, counter + " onerror filename");
-	is(lineno, expected[counter].lineNumber, counter + " onerror lineno");
+	is(filename, expected[counter].filename || "", counter + " onerror filename");
+	is(lineno, expected[counter].lineNumber || 0, counter + " onerror lineno");
 	postMessage(++counter, origin);
 	return true;
 };
 
 SimpleTest.waitForExplicitFinish();
 
 </script>
 </pre>
deleted file mode 100644
--- a/js/src/jit-test/tests/structured-clone/saved-stack.js
+++ /dev/null
@@ -1,37 +0,0 @@
-// The following binary data was created with:
-// JS_STRUCTURED_CLONE_VERSION = 8
-//
-// ```
-// function f() {
-//  return saveStack();
-// }
-// function g() {
-//  return f();
-// }
-//
-// let stack = g();
-// print(valueToSource(serialize(stack, undefined, {scope: "DifferentProcess"}).clonebuffer))
-// ```
-
-function checkStack(stack) {
-    print(stack.toString());
-
-    assertEq(stack.functionDisplayName, "f");
-    assertEq(stack.parent.functionDisplayName, "g");
-    assertEq(stack.parent.parent.functionDisplayName, null);
-    assertEq(stack.parent.parent.parent, null);
-}
-
-var clonebuffer = serialize("dummy");
-clonebuffer.clonebuffer = "\x02\x00\x00\x00\x00\x00\xF1\xFF\x18\x00\xFF\xFF\x16\x00\xFF\xFF \x00\x00\x80\x04\x00\xFF\xFF/home/tom/Desktop/saved-stack.js\x11\x00\x00\x00\x03\x00\xFF\xFF\t\x00\x00\x00\x03\x00\xFF\xFF\x01\x00\x00\x80\x04\x00\xFF\xFFf\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x18\x00\xFF\xFF\x16\x00\xFF\xFF \x00\x00\x80\x04\x00\xFF\xFF/home/tom/Desktop/saved-stack.js\x14\x00\x00\x00\x03\x00\xFF\xFF\t\x00\x00\x00\x03\x00\xFF\xFF\x01\x00\x00\x80\x04\x00\xFF\xFFg\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x18\x00\xFF\xFF\x16\x00\xFF\xFF \x00\x00\x80\x04\x00\xFF\xFF/home/tom/Desktop/saved-stack.js\x17\x00\x00\x00\x03\x00\xFF\xFF\r\x00\x00\x00\x03\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00\x00\x00\x13\x00\xFF\xFF\x00\x00\x00\x00\x13\x00\xFF\xFF\x00\x00\x00\x00\x13\x00\xFF\xFF";
-var stack = deserialize(clonebuffer);
-checkStack(stack);
-
-function f() {
- return saveStack();
-}
-function g() {
- return f();
-}
-stack = deserialize(serialize(g()));
-checkStack(stack);
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -23,17 +23,16 @@
 #include "jsapi.h"
 #include "jsfriendapi.h"
 #include "jstypes.h"
 
 #include "gc/Rooting.h"
 #include "js/CharacterEncoding.h"
 #include "js/Class.h"
 #include "js/Conversions.h"
-#include "js/SavedFrameAPI.h"
 #include "js/UniquePtr.h"
 #include "js/Value.h"
 #include "js/Warnings.h"  // JS::{,Set}WarningReporter
 #include "js/Wrapper.h"
 #include "util/Memory.h"
 #include "util/StringBuffer.h"
 #include "vm/Compartment.h"
 #include "vm/ErrorObject.h"
@@ -53,18 +52,16 @@
 #include "vm/ErrorObject-inl.h"
 #include "vm/JSContext-inl.h"
 #include "vm/JSObject-inl.h"
 #include "vm/ObjectOperations-inl.h"  // js::GetProperty
 #include "vm/SavedStacks-inl.h"
 
 using namespace js;
 
-using JS::SavedFrameSelfHosted;
-
 size_t ExtraMallocSize(JSErrorReport* report) {
   if (report->linebuf()) {
     /*
      * Count with null terminator and alignment.
      * See CopyExtraData for the details about alignment.
      */
     return (report->linebufLength() + 1) * sizeof(char16_t) + 1;
   }
@@ -463,18 +460,17 @@ static JSString* ErrorReportToString(JSC
   return FormatErrorMessage(cx, name, message);
 }
 
 ErrorReport::ErrorReport(JSContext* cx) : reportp(nullptr), exnObject(cx) {}
 
 ErrorReport::~ErrorReport() = default;
 
 bool ErrorReport::init(JSContext* cx, HandleValue exn,
-                       SniffingBehavior sniffingBehavior,
-                       HandleObject fallbackStack) {
+                       SniffingBehavior sniffingBehavior) {
   MOZ_ASSERT(!cx->isExceptionPending());
   MOZ_ASSERT(!reportp);
 
   if (exn.isObject()) {
     // Because ToString below could error and an exception object could become
     // unrooted, we must root our exception object, if any.
     exnObject = &exn.toObject();
     reportp = ErrorFromException(cx, exnObject);
@@ -603,72 +599,53 @@ bool ErrorReport::init(JSContext* cx, Ha
   if (!reportp) {
     // This is basically an inlined version of
     //
     //   JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr,
     //                            JSMSG_UNCAUGHT_EXCEPTION, utf8Message);
     //
     // but without the reporting bits.  Instead it just puts all
     // the stuff we care about in our ownedReport and message_.
-    if (!populateUncaughtExceptionReportUTF8(cx, fallbackStack, utf8Message)) {
+    if (!populateUncaughtExceptionReportUTF8(cx, utf8Message)) {
       // Just give up.  We're out of memory or something; not much we can
       // do here.
       return false;
     }
   } else {
     toStringResult_ = JS::ConstUTF8CharsZ(utf8Message, strlen(utf8Message));
   }
 
   return true;
 }
 
-bool ErrorReport::populateUncaughtExceptionReportUTF8(
-    JSContext* cx, HandleObject fallbackStack, ...) {
+bool ErrorReport::populateUncaughtExceptionReportUTF8(JSContext* cx, ...) {
   va_list ap;
-  va_start(ap, fallbackStack);
-  bool ok = populateUncaughtExceptionReportUTF8VA(cx, fallbackStack, ap);
+  va_start(ap, cx);
+  bool ok = populateUncaughtExceptionReportUTF8VA(cx, ap);
   va_end(ap);
   return ok;
 }
 
-bool ErrorReport::populateUncaughtExceptionReportUTF8VA(
-    JSContext* cx, HandleObject fallbackStack, va_list ap) {
+bool ErrorReport::populateUncaughtExceptionReportUTF8VA(JSContext* cx,
+                                                        va_list ap) {
   new (&ownedReport) JSErrorReport();
   ownedReport.isWarning_ = false;
   ownedReport.errorNumber = JSMSG_UNCAUGHT_EXCEPTION;
-
-  bool skippedAsync;
-  RootedSavedFrame frame(
-      cx, UnwrapSavedFrame(cx, cx->realm()->principals(), fallbackStack,
-                           SavedFrameSelfHosted::Exclude, skippedAsync));
-  if (frame) {
-    filename = StringToNewUTF8CharsZ(cx, *frame->getSource());
-    if (!filename) {
-      return false;
-    }
-
-    // |ownedReport.filename| inherits the lifetime of |ErrorReport::filename|.
-    ownedReport.filename = filename.get();
-    ownedReport.sourceId = frame->getSourceId();
-    ownedReport.lineno = frame->getLine();
-    ownedReport.column = FixupColumnForDisplay(frame->getColumn());
-    ownedReport.isMuted = frame->getMutedErrors();
-  } else {
-    // XXXbz this assumes the stack we have right now is still
-    // related to our exception object.
-    NonBuiltinFrameIter iter(cx, cx->realm()->principals());
-    if (!iter.done()) {
-      ownedReport.filename = iter.filename();
-      uint32_t column;
-      ownedReport.sourceId =
-          iter.hasScript() ? iter.script()->scriptSource()->id() : 0;
-      ownedReport.lineno = iter.computeLine(&column);
-      ownedReport.column = FixupColumnForDisplay(column);
-      ownedReport.isMuted = iter.mutedErrors();
-    }
+  // XXXbz this assumes the stack we have right now is still
+  // related to our exception object.  It would be better if we
+  // could accept a passed-in stack of some sort instead.
+  NonBuiltinFrameIter iter(cx, cx->realm()->principals());
+  if (!iter.done()) {
+    ownedReport.filename = iter.filename();
+    uint32_t column;
+    ownedReport.sourceId =
+        iter.hasScript() ? iter.script()->scriptSource()->id() : 0;
+    ownedReport.lineno = iter.computeLine(&column);
+    ownedReport.column = FixupColumnForDisplay(column);
+    ownedReport.isMuted = iter.mutedErrors();
   }
 
   if (!ExpandErrorArgumentsVA(cx, GetErrorMessage, nullptr,
                               JSMSG_UNCAUGHT_EXCEPTION, ArgumentsAreUTF8,
                               &ownedReport, ap)) {
     return false;
   }
 
--- a/js/src/jsfriendapi.h
+++ b/js/src/jsfriendapi.h
@@ -1307,55 +1307,47 @@ struct MOZ_STACK_CLASS JS_FRIEND_API Err
    * observable side effects. (The Error object's JSErrorReport is reused, if
    * it has one.)
    *
    * Otherwise various attempts are made to derive JSErrorReport information
    * from |exn| and from the current execution state.  This process is
    * *definitely* inconsistent with any standard, and particulars of the
    * behavior implemented here generally shouldn't be relied upon.
    *
-   * To fill in information such as file-name or line number the (optional)
-   * stack for the pending exception can be used. For this first SavedFrame
-   * is used.
-   *
    * If the value of |sniffingBehavior| is |WithSideEffects|, some of these
    * attempts *may* invoke user-configurable behavior when |exn| is an object:
    * converting |exn| to a string, detecting and getting properties on |exn|,
    * accessing |exn|'s prototype chain, and others are possible.  Users *must*
    * tolerate |ErrorReport::init| potentially having arbitrary effects.  Any
    * exceptions thrown by these operations will be caught and silently
    * ignored, and "default" values will be substituted into the JSErrorReport.
    *
    * But if the value of |sniffingBehavior| is |NoSideEffects|, these attempts
    * *will not* invoke any observable side effects.  The JSErrorReport will
    * simply contain fewer, less precise details.
    *
    * Unlike some functions involved in error handling, this function adheres
    * to the usual JSAPI return value error behavior.
    */
   bool init(JSContext* cx, JS::HandleValue exn,
-            SniffingBehavior sniffingBehavior,
-            JS::HandleObject fallbackStack = nullptr);
+            SniffingBehavior sniffingBehavior);
 
   JSErrorReport* report() { return reportp; }
 
   const JS::ConstUTF8CharsZ toStringResult() { return toStringResult_; }
 
  private:
   // More or less an equivalent of JS_ReportErrorNumber/js::ReportErrorNumberVA
   // but fills in an ErrorReport instead of reporting it.  Uses varargs to
   // make it simpler to call js::ExpandErrorArgumentsVA.
   //
   // Returns false if we fail to actually populate the ErrorReport
   // for some reason (probably out of memory).
-  bool populateUncaughtExceptionReportUTF8(JSContext* cx,
-                                           JS::HandleObject fallbackStack, ...);
-  bool populateUncaughtExceptionReportUTF8VA(JSContext* cx,
-                                             JS::HandleObject fallbackStack,
-                                             va_list ap);
+  bool populateUncaughtExceptionReportUTF8(JSContext* cx, ...);
+  bool populateUncaughtExceptionReportUTF8VA(JSContext* cx, va_list ap);
 
   // Reports exceptions from add-on scopes to telemetry.
   void ReportAddonExceptionToTelemetry(JSContext* cx);
 
   // We may have a provided JSErrorReport, so need a way to represent that.
   JSErrorReport* reportp;
 
   // Or we may need to synthesize a JSErrorReport one of our own.
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -9559,17 +9559,17 @@ js::shell::AutoReportException::~AutoRep
   RootedValue exn(cx);
   (void)JS_GetPendingException(cx, &exn);
   RootedObject stack(cx, GetPendingExceptionStack(cx));
 
   JS_ClearPendingException(cx);
 
   ShellContext* sc = GetShellContext(cx);
   js::ErrorReport report(cx);
-  if (!report.init(cx, exn, js::ErrorReport::WithSideEffects, stack)) {
+  if (!report.init(cx, exn, js::ErrorReport::WithSideEffects)) {
     fprintf(stderr, "out of memory initializing ErrorReport\n");
     fflush(stderr);
     JS_ClearPendingException(cx);
     return;
   }
 
   MOZ_ASSERT(!report.report()->isWarning());
 
--- a/js/src/vm/SavedFrame.h
+++ b/js/src/vm/SavedFrame.h
@@ -47,17 +47,16 @@ class SavedFrame : public NativeObject {
   JSAtom* getSource();
   uint32_t getSourceId();
   uint32_t getLine();
   uint32_t getColumn();
   JSAtom* getFunctionDisplayName();
   JSAtom* getAsyncCause();
   SavedFrame* getParent() const;
   JSPrincipals* getPrincipals();
-  bool getMutedErrors();
   bool isSelfHosted(JSContext* cx);
   bool isWasm();
 
   // When isWasm():
   uint32_t wasmFuncIndex();
   uint32_t wasmBytecodeOffset();
 
   // Iterator for use with C++11 range based for loops, eg:
@@ -118,19 +117,18 @@ class SavedFrame : public NativeObject {
   void initFromLookup(JSContext* cx, Handle<Lookup> lookup);
   void initSource(JSAtom* source);
   void initSourceId(uint32_t id);
   void initLine(uint32_t line);
   void initColumn(uint32_t column);
   void initFunctionDisplayName(JSAtom* maybeName);
   void initAsyncCause(JSAtom* maybeCause);
   void initParent(SavedFrame* maybeParent);
-  void initPrincipalsAlreadyHeldAndMutedErrors(JSPrincipals* principals,
-                                               bool mutedErrors);
-  void initPrincipalsAndMutedErrors(JSPrincipals* principals, bool mutedErrors);
+  void initPrincipalsAlreadyHeld(JSPrincipals* principals);
+  void initPrincipals(JSPrincipals* principals);
 
   enum {
     // The reserved slots in the SavedFrame class.
     JSSLOT_SOURCE,
     JSSLOT_SOURCEID,
     JSSLOT_LINE,
     JSSLOT_COLUMN,
     JSSLOT_FUNCTIONDISPLAYNAME,
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -170,28 +170,27 @@ void LiveSavedFrameCache::findWithoutInv
   }
 
   frame.set(nullptr);
 }
 
 struct MOZ_STACK_CLASS SavedFrame::Lookup {
   Lookup(JSAtom* source, uint32_t sourceId, uint32_t line, uint32_t column,
          JSAtom* functionDisplayName, JSAtom* asyncCause, SavedFrame* parent,
-         JSPrincipals* principals, bool mutedErrors,
+         JSPrincipals* principals,
          const Maybe<LiveSavedFrameCache::FramePtr>& framePtr = Nothing(),
          jsbytecode* pc = nullptr, Activation* activation = nullptr)
       : source(source),
         sourceId(sourceId),
         line(line),
         column(column),
         functionDisplayName(functionDisplayName),
         asyncCause(asyncCause),
         parent(parent),
         principals(principals),
-        mutedErrors(mutedErrors),
         framePtr(framePtr),
         pc(pc),
         activation(activation) {
     MOZ_ASSERT(source);
     MOZ_ASSERT_IF(framePtr.isSome(), activation);
 #ifdef JS_MORE_DETERMINISTIC
     column = 0;
 #endif
@@ -201,32 +200,30 @@ struct MOZ_STACK_CLASS SavedFrame::Looku
       : source(savedFrame.getSource()),
         sourceId(savedFrame.getSourceId()),
         line(savedFrame.getLine()),
         column(savedFrame.getColumn()),
         functionDisplayName(savedFrame.getFunctionDisplayName()),
         asyncCause(savedFrame.getAsyncCause()),
         parent(savedFrame.getParent()),
         principals(savedFrame.getPrincipals()),
-        mutedErrors(savedFrame.getMutedErrors()),
         framePtr(Nothing()),
         pc(nullptr),
         activation(nullptr) {
     MOZ_ASSERT(source);
   }
 
   JSAtom* source;
   uint32_t sourceId;
   uint32_t line;
   uint32_t column;
   JSAtom* functionDisplayName;
   JSAtom* asyncCause;
   SavedFrame* parent;
   JSPrincipals* principals;
-  bool mutedErrors;
 
   // These are used only by the LiveSavedFrameCache and not used for identity or
   // hashing.
   Maybe<LiveSavedFrameCache::FramePtr> framePtr;
   jsbytecode* pc;
   Activation* activation;
 
   void trace(JSTracer* trc) {
@@ -251,17 +248,16 @@ class WrappedPtrOperations<SavedFrame::L
   JSAtom* source() { return value().source; }
   uint32_t sourceId() { return value().sourceId; }
   uint32_t line() { return value().line; }
   uint32_t column() { return value().column; }
   JSAtom* functionDisplayName() { return value().functionDisplayName; }
   JSAtom* asyncCause() { return value().asyncCause; }
   SavedFrame* parent() { return value().parent; }
   JSPrincipals* principals() { return value().principals; }
-  bool mutedErrors() { return value().mutedErrors; }
   Maybe<LiveSavedFrameCache::FramePtr> framePtr() { return value().framePtr; }
   jsbytecode* pc() { return value().pc; }
   Activation* activation() { return value().activation; }
 };
 
 template <typename Wrapper>
 class MutableWrappedPtrOperations<SavedFrame::Lookup, Wrapper>
     : public WrappedPtrOperations<SavedFrame::Lookup, Wrapper> {
@@ -286,17 +282,17 @@ bool SavedFrame::HashPolicy::ensureHash(
 /* static */
 HashNumber SavedFrame::HashPolicy::hash(const Lookup& lookup) {
   JS::AutoCheckCannotGC nogc;
   // Assume that we can take line mod 2^32 without losing anything of
   // interest.  If that assumption changes, we'll just need to start with 0
   // and add another overload of AddToHash with more arguments.
   return AddToHash(lookup.line, lookup.column, lookup.source,
                    lookup.functionDisplayName, lookup.asyncCause,
-                   lookup.mutedErrors, SavedFramePtrHasher::hash(lookup.parent),
+                   SavedFramePtrHasher::hash(lookup.parent),
                    JSPrincipalsPtrHasher::hash(lookup.principals));
 }
 
 /* static */
 bool SavedFrame::HashPolicy::match(SavedFrame* existing, const Lookup& lookup) {
   MOZ_ASSERT(existing);
 
   if (existing->getLine() != lookup.line) {
@@ -450,25 +446,17 @@ SavedFrame* SavedFrame::getParent() cons
   return v.isObject() ? &v.toObject().as<SavedFrame>() : nullptr;
 }
 
 JSPrincipals* SavedFrame::getPrincipals() {
   const Value& v = getReservedSlot(JSSLOT_PRINCIPALS);
   if (v.isUndefined()) {
     return nullptr;
   }
-  return reinterpret_cast<JSPrincipals*>(uintptr_t(v.toPrivate()) & ~0b1);
-}
-
-bool SavedFrame::getMutedErrors() {
-  const Value& v = getReservedSlot(JSSLOT_PRINCIPALS);
-  if (v.isUndefined()) {
-    return true;
-  }
-  return bool(uintptr_t(v.toPrivate()) & 0b1);
+  return static_cast<JSPrincipals*>(v.toPrivate());
 }
 
 void SavedFrame::initSource(JSAtom* source) {
   MOZ_ASSERT(source);
   initReservedSlot(JSSLOT_SOURCE, StringValue(source));
 }
 
 void SavedFrame::initSourceId(uint32_t sourceId) {
@@ -481,30 +469,26 @@ void SavedFrame::initLine(uint32_t line)
 
 void SavedFrame::initColumn(uint32_t column) {
 #ifdef JS_MORE_DETERMINISTIC
   column = 0;
 #endif
   initReservedSlot(JSSLOT_COLUMN, PrivateUint32Value(column));
 }
 
-void SavedFrame::initPrincipalsAndMutedErrors(JSPrincipals* principals,
-                                              bool mutedErrors) {
+void SavedFrame::initPrincipals(JSPrincipals* principals) {
   if (principals) {
     JS_HoldPrincipals(principals);
   }
-  initPrincipalsAlreadyHeldAndMutedErrors(principals, mutedErrors);
+  initPrincipalsAlreadyHeld(principals);
 }
 
-void SavedFrame::initPrincipalsAlreadyHeldAndMutedErrors(
-    JSPrincipals* principals, bool mutedErrors) {
+void SavedFrame::initPrincipalsAlreadyHeld(JSPrincipals* principals) {
   MOZ_ASSERT_IF(principals, principals->refcount > 0);
-  uintptr_t ptr = uintptr_t(principals) | mutedErrors;
-  initReservedSlot(JSSLOT_PRINCIPALS,
-                   PrivateValue(reinterpret_cast<void*>(ptr)));
+  initReservedSlot(JSSLOT_PRINCIPALS, PrivateValue(principals));
 }
 
 void SavedFrame::initFunctionDisplayName(JSAtom* maybeName) {
   initReservedSlot(JSSLOT_FUNCTIONDISPLAYNAME,
                    maybeName ? StringValue(maybeName) : NullValue());
 }
 
 void SavedFrame::initAsyncCause(JSAtom* maybeCause) {
@@ -534,17 +518,17 @@ void SavedFrame::initFromLookup(JSContex
 
   initSource(lookup.source());
   initSourceId(lookup.sourceId());
   initLine(lookup.line());
   initColumn(lookup.column());
   initFunctionDisplayName(lookup.functionDisplayName());
   initAsyncCause(lookup.asyncCause());
   initParent(lookup.parent());
-  initPrincipalsAndMutedErrors(lookup.principals(), lookup.mutedErrors());
+  initPrincipals(lookup.principals());
 }
 
 /* static */
 SavedFrame* SavedFrame::create(JSContext* cx) {
   RootedGlobalObject global(cx, cx->global());
   cx->check(global);
 
   // Ensure that we don't try to capture the stack again in the
@@ -721,34 +705,35 @@ static MOZ_MUST_USE bool SavedFrame_chec
 //   - Rooted<SavedFrame*> frame (will be non-null)
 #define THIS_SAVEDFRAME(cx, argc, vp, fnName, args, frame) \
   CallArgs args = CallArgsFromVp(argc, vp);                \
   RootedObject frame(cx);                                  \
   if (!SavedFrame_checkThis(cx, args, fnName, &frame)) return false;
 
 } /* namespace js */
 
-js::SavedFrame* js::UnwrapSavedFrame(JSContext* cx, JSPrincipals* principals,
-                                     HandleObject obj,
-                                     JS::SavedFrameSelfHosted selfHosted,
-                                     bool& skippedAsync) {
+namespace JS {
+
+static inline js::SavedFrame* UnwrapSavedFrame(JSContext* cx,
+                                               JSPrincipals* principals,
+                                               HandleObject obj,
+                                               SavedFrameSelfHosted selfHosted,
+                                               bool& skippedAsync) {
   if (!obj) {
     return nullptr;
   }
 
-  RootedSavedFrame frame(cx, obj->maybeUnwrapAs<SavedFrame>());
+  js::RootedSavedFrame frame(cx, obj->maybeUnwrapAs<js::SavedFrame>());
   if (!frame) {
     return nullptr;
   }
 
   return GetFirstSubsumedFrame(cx, principals, frame, selfHosted, skippedAsync);
 }
 
-namespace JS {
-
 JS_PUBLIC_API SavedFrameResult GetSavedFrameSource(
     JSContext* cx, JSPrincipals* principals, HandleObject savedFrame,
     MutableHandleString sourcep,
     SavedFrameSelfHosted selfHosted /* = SavedFrameSelfHosted::Include */) {
   js::AssertHeapIsIdle();
   CHECK_THREAD(cx);
   MOZ_RELEASE_ASSERT(cx->realm());
 
@@ -1476,18 +1461,17 @@ bool SavedStacks::insertFrames(JSContext
 
     auto principals = iter.realm()->principals();
     MOZ_ASSERT_IF(framePtr && !iter.isWasm(), iter.pc());
 
     if (!stackChain.emplaceBack(location.source(), location.sourceId(),
                                 location.line(), location.column(), displayAtom,
                                 nullptr,  // asyncCause
                                 nullptr,  // parent (not known yet)
-                                principals, iter.mutedErrors(), framePtr,
-                                iter.pc(), &activation)) {
+                                principals, framePtr, iter.pc(), &activation)) {
       ReportOutOfMemory(cx);
       return false;
     }
 
     if (captureIsSatisfied(cx, principals, location.source(), capture)) {
       // The stack should end after the frame we just saved.
       parent.set(nullptr);
       break;
@@ -1989,18 +1973,17 @@ JS_PUBLIC_API bool ConstructSavedFrameSt
 
     auto principals =
         js::ReconstructedSavedFramePrincipals::getSingleton(ubiFrame.get());
 
     if (!stackChain.emplaceBack(source, ubiFrame.get().sourceId(),
                                 ubiFrame.get().line(), ubiFrame.get().column(),
                                 functionDisplayName,
                                 /* asyncCause */ nullptr,
-                                /* parent */ nullptr, principals,
-                                /* mutedErrors */ true)) {
+                                /* parent */ nullptr, principals)) {
       ReportOutOfMemory(cx);
       return false;
     }
 
     ubiFrame = ubiFrame.get().parent();
   }
 
   js::RootedSavedFrame parentFrame(cx);
--- a/js/src/vm/SavedStacks.h
+++ b/js/src/vm/SavedStacks.h
@@ -12,20 +12,16 @@
 #include "mozilla/Maybe.h"
 
 #include "js/HashTable.h"
 #include "js/Wrapper.h"
 #include "vm/JSContext.h"
 #include "vm/SavedFrame.h"
 #include "vm/Stack.h"
 
-namespace JS {
-enum class SavedFrameSelfHosted;
-}
-
 namespace js {
 
 // # Saved Stacks
 //
 // The `SavedStacks` class provides a compact way to capture and save JS stacks
 // as `SavedFrame` `JSObject` subclasses. A single `SavedFrame` object
 // represents one frame that was on the stack, and has a strong reference to its
 // parent `SavedFrame` (the next youngest frame). This reference is null when
@@ -330,16 +326,11 @@ struct MutableWrappedPtrOperations<Saved
   }
 };
 
 JS::UniqueChars BuildUTF8StackString(JSContext* cx, JSPrincipals* principals,
                                      HandleObject stack);
 
 uint32_t FixupColumnForDisplay(uint32_t column);
 
-js::SavedFrame* UnwrapSavedFrame(JSContext* cx, JSPrincipals* principals,
-                                 HandleObject obj,
-                                 JS::SavedFrameSelfHosted selfHosted,
-                                 bool& skippedAsync);
-
 } /* namespace js */
 
 #endif /* vm_SavedStacks_h */
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -1629,21 +1629,16 @@ bool JSStructuredCloneWriter::traverseSa
     }
   }
 
   // Write the SavedFrame's reserved slots, except for the parent, which is
   // queued on objs for further traversal.
 
   RootedValue val(context());
 
-  val = BooleanValue(savedFrame->getMutedErrors());
-  if (!startWrite(val)) {
-    return false;
-  }
-
   context()->markAtom(savedFrame->getSource());
   val = StringValue(savedFrame->getSource());
   if (!startWrite(val)) {
     return false;
   }
 
   val = NumberValue(savedFrame->getLine());
   if (!startWrite(val)) {
@@ -2912,46 +2907,22 @@ JSObject* JSStructuredCloneReader::readS
   } else if (principalsTag == SCTAG_NULL_JSPRINCIPALS) {
     principals = nullptr;
   } else {
     JS_ReportErrorNumberASCII(context(), GetErrorMessage, nullptr,
                               JSMSG_SC_BAD_SERIALIZED_DATA,
                               "bad SavedFrame principals");
     return nullptr;
   }
-
-  RootedValue mutedErrors(context());
+  savedFrame->initPrincipalsAlreadyHeld(principals);
+
   RootedValue source(context());
-  {
-    // Read a |mutedErrors| boolean followed by a |source| string.
-    // The |mutedErrors| boolean is present in all new structured-clone data,
-    // but in older data it will be absent and only the |source| string will be
-    // found.
-    if (!startRead(&mutedErrors)) {
-      return nullptr;
-    }
-
-    if (mutedErrors.isBoolean()) {
-      if (!startRead(&source) || !source.isString()) {
-        return nullptr;
-      }
-    } else if (mutedErrors.isString()) {
-      // Backwards compatibility: Handle missing |mutedErrors| boolean,
-      // this is actually just a |source| string.
-      source = mutedErrors;
-      mutedErrors.setBoolean(true);  // Safe default value.
-    } else {
-      // Invalid type.
-      return nullptr;
-    }
+  if (!startRead(&source) || !source.isString()) {
+    return nullptr;
   }
-
-  savedFrame->initPrincipalsAlreadyHeldAndMutedErrors(principals,
-                                                      mutedErrors.toBoolean());
-
   auto atomSource = AtomizeString(context(), source.toString());
   if (!atomSource) {
     return nullptr;
   }
   savedFrame->initSource(atomSource);
 
   RootedValue lineVal(context());
   uint32_t line;
--- a/testing/web-platform/tests/html/webappapis/scripting/processing-model-2/window-onerror-runtime-error-throw.html
+++ b/testing/web-platform/tests/html/webappapis/scripting/processing-model-2/window-onerror-runtime-error-throw.html
@@ -15,20 +15,16 @@
  <body>
 
   <div id="log"></div>
   <script>
     setup({allow_uncaught_exception:true});
     var error_count = 0;
     window.onerror = function(msg, url, lineno) {
       ++error_count;
-      test(function() {assert_equals(url, window.location.href)},
-           "correct url passed to window.onerror");
-      test(function() {assert_equals(lineno, 36)},
-           "correct line number passed to window.onerror");
     };
   </script>
   <script>
   try {
     // This error is caught, so it should NOT trigger onerror.
     throw "foo";
   } catch (ex) {
   }