Backed out 10 changesets (bug 1568903) for causing mochitest failures
authorNoemi Erli <nerli@mozilla.com>
Fri, 15 Nov 2019 13:50:40 +0200
changeset 502156 cfe990fab350df1c36c24affdac448f7932379aa
parent 502155 4158e16441d6fe5762cf55c6466468007ee456e7
child 502157 27a1fb60c2863d29755521c69d6fceb1f2be18d7
push id114172
push userdluca@mozilla.com
push dateTue, 19 Nov 2019 11:31:10 +0000
treeherdermozilla-inbound@b5c5ba07d3db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1568903
milestone72.0a1
backs out76ad398222a6809bef3116d77b580ef3e9339cce
f4d9fda6d7f2504b1e8bde4f50603a7013f0917f
379d0f2de211fb18470dfe40f41199dcc8b44cb4
3f4aee7f2893f625f0e88dbd623ac9cb41824e97
595accbef95e27f253a0c4539a31c6858f1cae7c
567d497a39f42a347f0cdddb720cfc68256167a2
127a44494b67989bfe3afcd02ee48041ca566f16
27c54b414c35ad96a4319eba9ba2da7782fb37e4
d2b01a1ad0a966ea1cbd871d33ecdad59a7eee68
58c002a9cb78fa913cbd3b8dce38d1f0032b6bda
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 10 changesets (bug 1568903) for causing mochitest failures Backed out changeset 76ad398222a6 (bug 1568903) Backed out changeset f4d9fda6d7f2 (bug 1568903) Backed out changeset 379d0f2de211 (bug 1568903) Backed out changeset 3f4aee7f2893 (bug 1568903) Backed out changeset 595accbef95e (bug 1568903) Backed out changeset 567d497a39f4 (bug 1568903) Backed out changeset 127a44494b67 (bug 1568903) Backed out changeset 27c54b414c35 (bug 1568903) Backed out changeset d2b01a1ad0a9 (bug 1568903) Backed out changeset 58c002a9cb78 (bug 1568903)
js/public/ErrorReport.h
js/public/ProtoKey.h
js/src/builtin/Object.cpp
js/src/builtin/Promise.cpp
js/src/builtin/TestingFunctions.cpp
js/src/builtin/Utilities.js
js/src/jit-test/tests/promise/promise-any-with-non-default-resolving.js
js/src/jit/RangeAnalysis.cpp
js/src/js.msg
js/src/jsexn.cpp
js/src/jsexn.h
js/src/jsfriendapi.cpp
js/src/tests/non262/Error/AggregateError.js
js/src/tests/non262/Promise/any-stack.js
js/src/tests/non262/Promise/any.js
js/src/vm/CommonPropertyNames.h
js/src/vm/ErrorObject.cpp
js/src/vm/ErrorObject.h
js/src/vm/GlobalObject.cpp
js/src/vm/GlobalObject.h
js/src/vm/JSContext.cpp
js/src/vm/ObjectGroup.cpp
js/src/vm/SelfHosting.cpp
js/src/wasm/WasmCode.cpp
js/src/wasm/WasmJS.cpp
js/xpconnect/tests/chrome/test_xrayToJS.xhtml
js/xpconnect/wrappers/XrayWrapper.cpp
--- a/js/public/ErrorReport.h
+++ b/js/public/ErrorReport.h
@@ -41,17 +41,16 @@ class JS_PUBLIC_API JSString;
  * JSEXN_WARN is used for warnings in js.msg files (for instance because we
  * don't want to prepend 'Error:' to warning messages). This value can go away
  * if we ever decide to use an entirely separate mechanism for warnings.
  */
 enum JSExnType {
   JSEXN_ERR,
   JSEXN_FIRST = JSEXN_ERR,
   JSEXN_INTERNALERR,
-  JSEXN_AGGREGATEERR,
   JSEXN_EVALERR,
   JSEXN_RANGEERR,
   JSEXN_REFERENCEERR,
   JSEXN_SYNTAXERR,
   JSEXN_TYPEERR,
   JSEXN_URIERR,
   JSEXN_DEBUGGEEWOULDRUN,
   JSEXN_WASMCOMPILEERROR,
--- a/js/public/ProtoKey.h
+++ b/js/public/ProtoKey.h
@@ -57,17 +57,16 @@
   REAL(JSON, InitJSONClass, CLASP(JSON))                                     \
   REAL(Date, InitViaClassSpec, OCLASP(Date))                                 \
   REAL(Math, InitMathClass, CLASP(Math))                                     \
   REAL(Number, InitNumberClass, OCLASP(Number))                              \
   REAL(String, InitStringClass, OCLASP(String))                              \
   REAL(RegExp, InitViaClassSpec, OCLASP(RegExp))                             \
   REAL(Error, InitViaClassSpec, ERROR_CLASP(JSEXN_ERR))                      \
   REAL(InternalError, InitViaClassSpec, ERROR_CLASP(JSEXN_INTERNALERR))      \
-  REAL(AggregateError, InitViaClassSpec, ERROR_CLASP(JSEXN_AGGREGATEERR))    \
   REAL(EvalError, InitViaClassSpec, ERROR_CLASP(JSEXN_EVALERR))              \
   REAL(RangeError, InitViaClassSpec, ERROR_CLASP(JSEXN_RANGEERR))            \
   REAL(ReferenceError, InitViaClassSpec, ERROR_CLASP(JSEXN_REFERENCEERR))    \
   REAL(SyntaxError, InitViaClassSpec, ERROR_CLASP(JSEXN_SYNTAXERR))          \
   REAL(TypeError, InitViaClassSpec, ERROR_CLASP(JSEXN_TYPEERR))              \
   REAL(URIError, InitViaClassSpec, ERROR_CLASP(JSEXN_URIERR))                \
   REAL(DebuggeeWouldRun, InitViaClassSpec,                                   \
        ERROR_CLASP(JSEXN_DEBUGGEEWOULDRUN))                                  \
--- a/js/src/builtin/Object.cpp
+++ b/js/src/builtin/Object.cpp
@@ -16,17 +16,16 @@
 #include "frontend/BytecodeCompiler.h"
 #include "jit/InlinableNatives.h"
 #include "js/PropertySpec.h"
 #include "js/UniquePtr.h"
 #include "util/StringBuffer.h"
 #include "vm/AsyncFunction.h"
 #include "vm/DateObject.h"
 #include "vm/EqualityOperations.h"  // js::SameValue
-#include "vm/ErrorObject.h"
 #include "vm/JSContext.h"
 #include "vm/RegExpObject.h"
 
 #include "vm/JSObject-inl.h"
 #include "vm/NativeObject-inl.h"
 #include "vm/Shape-inl.h"
 
 #ifdef FUZZING
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -15,29 +15,26 @@
 #include "jsexn.h"
 #include "jsfriendapi.h"
 
 #include "gc/Heap.h"
 #include "js/Debug.h"
 #include "js/ForOfIterator.h"  // JS::ForOfIterator
 #include "js/PropertySpec.h"
 #include "util/Poison.h"
-#include "vm/ArrayObject.h"
 #include "vm/AsyncFunction.h"
 #include "vm/AsyncIteration.h"
-#include "vm/ErrorObject.h"
 #include "vm/GeneratorObject.h"
 #include "vm/Iteration.h"
 #include "vm/JSContext.h"
 #include "vm/JSObject.h"
 #include "vm/SelfHosting.h"
 
 #include "debugger/DebugAPI-inl.h"
 #include "vm/Compartment-inl.h"
-#include "vm/ErrorObject-inl.h"
 #include "vm/JSObject-inl.h"
 #include "vm/NativeObject-inl.h"
 
 using namespace js;
 
 static double MillisecondsSinceStartup(
     const mozilla::Maybe<mozilla::TimeStamp>& maybeNow) {
   auto now = maybeNow.isSome() ? maybeNow.ref() : mozilla::TimeStamp::Now();
@@ -90,19 +87,24 @@ enum ResolveFunctionSlots {
   ResolveFunctionSlot_RejectFunction,
 };
 
 enum RejectFunctionSlots {
   RejectFunctionSlot_Promise = 0,
   RejectFunctionSlot_ResolveFunction,
 };
 
-enum PromiseCombinatorElementFunctionSlots {
-  PromiseCombinatorElementFunctionSlot_Data = 0,
-  PromiseCombinatorElementFunctionSlot_ElementIndex,
+enum PromiseAllResolveElementFunctionSlots {
+  PromiseAllResolveElementFunctionSlot_Data = 0,
+  PromiseAllResolveElementFunctionSlot_ElementIndex,
+};
+
+enum PromiseAllSettledElementFunctionSlots {
+  PromiseAllSettledElementFunctionSlot_Data = 0,
+  PromiseAllSettledElementFunctionSlot_ElementIndex,
 };
 
 enum ReactionJobSlots {
   ReactionJobSlot_ReactionRecord = 0,
 };
 
 enum ThenableJobSlots {
   // The handler to use as the Promise reaction. It is a callable object
@@ -129,16 +131,24 @@ enum BuiltinThenableJobSlots {
   // The Promise to resolve using the given thenable.
   BuiltinThenableJobSlot_Promise = 0,
 
   // The thenable to use as the receiver when calling the built-in `then`
   // function.
   BuiltinThenableJobSlot_Thenable,
 };
 
+enum PromiseAllDataHolderSlots {
+  PromiseAllDataHolderSlot_Promise = 0,
+  PromiseAllDataHolderSlot_RemainingElements,
+  PromiseAllDataHolderSlot_ValuesArray,
+  PromiseAllDataHolderSlot_ResolveFunction,
+  PromiseAllDataHolderSlots,
+};
+
 struct PromiseCapability {
   JSObject* promise = nullptr;
   JSObject* resolve = nullptr;
   JSObject* reject = nullptr;
 
   PromiseCapability() = default;
 
   void trace(JSTracer* trc);
@@ -190,198 +200,74 @@ class MutableWrappedPtrOperations<Promis
   }
   MutableHandleObject reject() {
     return MutableHandleObject::fromMarkedLocation(&capability().reject);
   }
 };
 
 }  // namespace js
 
-struct PromiseCombinatorElements;
-
-class PromiseCombinatorDataHolder : public NativeObject {
-  enum {
-    Slot_Promise = 0,
-    Slot_RemainingElements,
-    Slot_ValuesArray,
-    Slot_ResolveOrRejectFunction,
-    SlotsCount,
-  };
-
+class PromiseAllDataHolder : public NativeObject {
  public:
   static const JSClass class_;
-  JSObject* promiseObj() { return &getFixedSlot(Slot_Promise).toObject(); }
-  JSObject* resolveOrRejectObj() {
-    return &getFixedSlot(Slot_ResolveOrRejectFunction).toObject();
-  }
-  Value valuesArray() { return getFixedSlot(Slot_ValuesArray); }
+  JSObject* promiseObj() {
+    return &getFixedSlot(PromiseAllDataHolderSlot_Promise).toObject();
+  }
+  JSObject* resolveObj() {
+    return &getFixedSlot(PromiseAllDataHolderSlot_ResolveFunction).toObject();
+  }
+  Value valuesArray() {
+    return getFixedSlot(PromiseAllDataHolderSlot_ValuesArray);
+  }
   int32_t remainingCount() {
-    return getFixedSlot(Slot_RemainingElements).toInt32();
+    return getFixedSlot(PromiseAllDataHolderSlot_RemainingElements).toInt32();
   }
   int32_t increaseRemainingCount() {
-    int32_t remainingCount = getFixedSlot(Slot_RemainingElements).toInt32();
+    int32_t remainingCount =
+        getFixedSlot(PromiseAllDataHolderSlot_RemainingElements).toInt32();
     remainingCount++;
-    setFixedSlot(Slot_RemainingElements, Int32Value(remainingCount));
+    setFixedSlot(PromiseAllDataHolderSlot_RemainingElements,
+                 Int32Value(remainingCount));
     return remainingCount;
   }
   int32_t decreaseRemainingCount() {
-    int32_t remainingCount = getFixedSlot(Slot_RemainingElements).toInt32();
+    int32_t remainingCount =
+        getFixedSlot(PromiseAllDataHolderSlot_RemainingElements).toInt32();
     remainingCount--;
-    MOZ_ASSERT(remainingCount >= 0, "unpaired calls to decreaseRemainingCount");
-    setFixedSlot(Slot_RemainingElements, Int32Value(remainingCount));
+    setFixedSlot(PromiseAllDataHolderSlot_RemainingElements,
+                 Int32Value(remainingCount));
     return remainingCount;
   }
-
-  static PromiseCombinatorDataHolder* New(
-      JSContext* cx, HandleObject resultPromise,
-      Handle<PromiseCombinatorElements> elements, HandleObject resolveOrReject);
-};
-
-const JSClass PromiseCombinatorDataHolder::class_ = {
-    "PromiseCombinatorDataHolder", JSCLASS_HAS_RESERVED_SLOTS(SlotsCount)};
-
-// Smart pointer to the "F.[[Values]]" part of the state of a Promise.all or
-// Promise.allSettled invocation, or the "F.[[Errors]]" part of the state of a
-// Promise.any invocation. Copes with compartment issues when setting an
-// element.
-struct MOZ_STACK_CLASS PromiseCombinatorElements final {
-  // Object value holding the elements array. The object can be a wrapper.
-  Value value;
-
-  // Unwrapped elements array. May not belong to the current compartment!
-  ArrayObject* unwrappedArray = nullptr;
-
-  // Set to true if the |setElement| method needs to wrap its input value.
-  bool setElementNeedsWrapping = false;
-
-  PromiseCombinatorElements() = default;
-
-  void trace(JSTracer* trc);
-};
-
-void PromiseCombinatorElements::trace(JSTracer* trc) {
-  TraceRoot(trc, &value, "PromiseCombinatorElements::value");
-  if (unwrappedArray) {
-    TraceRoot(trc, &unwrappedArray,
-              "PromiseCombinatorElements::unwrappedArray");
-  }
-}
-
-namespace js {
-
-template <typename Wrapper>
-class WrappedPtrOperations<PromiseCombinatorElements, Wrapper> {
-  const PromiseCombinatorElements& elements() const {
-    return static_cast<const Wrapper*>(this)->get();
-  }
-
- public:
-  HandleValue value() const {
-    return HandleValue::fromMarkedLocation(&elements().value);
-  }
-
-  HandleArrayObject unwrappedArray() const {
-    return HandleArrayObject::fromMarkedLocation(&elements().unwrappedArray);
-  }
 };
 
-template <typename Wrapper>
-class MutableWrappedPtrOperations<PromiseCombinatorElements, Wrapper>
-    : public WrappedPtrOperations<PromiseCombinatorElements, Wrapper> {
-  PromiseCombinatorElements& elements() {
-    return static_cast<Wrapper*>(this)->get();
-  }
-
- public:
-  MutableHandleValue value() {
-    return MutableHandleValue::fromMarkedLocation(&elements().value);
-  }
-
-  MutableHandle<ArrayObject*> unwrappedArray() {
-    return MutableHandle<ArrayObject*>::fromMarkedLocation(
-        &elements().unwrappedArray);
-  }
-
-  void initialize(ArrayObject* arrayObj) {
-    unwrappedArray().set(arrayObj);
-    value().setObject(*arrayObj);
-
-    // |needsWrapping| isn't tracked here, because all modifications on the
-    // initial elements don't require any wrapping.
-  }
-
-  void initialize(PromiseCombinatorDataHolder* data, ArrayObject* arrayObj,
-                  bool needsWrapping) {
-    unwrappedArray().set(arrayObj);
-    value().set(data->valuesArray());
-    elements().setElementNeedsWrapping = needsWrapping;
-  }
-
-  MOZ_MUST_USE bool pushUndefined(JSContext* cx) {
-    // Helper for the AutoRealm we need to work with |array|. We mostly do this
-    // for performance; we could go ahead and do the define via a cross-
-    // compartment proxy instead...
-    AutoRealm ar(cx, unwrappedArray());
-
-    HandleArrayObject arrayObj = unwrappedArray();
-    return js::NewbornArrayPush(cx, arrayObj, UndefinedValue());
-  }
-
-  // `Promise.all` Resolve Element Functions
-  // Step 9. Set values[index] to x.
-  //
-  // `Promise.allSettled` Resolve Element Functions
-  // `Promise.allSettled` Reject Element Functions
-  // Step 12. Set values[index] to obj.
-  //
-  // `Promise.any` Reject Element Functions
-  // Step 9. Set errors[index] to x.
-  //
-  // These handler functions are always created in the compartment of the
-  // Promise.all/allSettled/any function, which isn't necessarily the same
-  // compartment as unwrappedArray as explained in NewPromiseCombinatorElements.
-  // So before storing |val| we may need to enter unwrappedArray's compartment.
-  MOZ_MUST_USE bool setElement(JSContext* cx, uint32_t index, HandleValue val) {
-    // The index is guaranteed to be initialized to `undefined`.
-    MOZ_ASSERT(unwrappedArray()->getDenseElement(index).isUndefined());
-
-    if (elements().setElementNeedsWrapping) {
-      AutoRealm ar(cx, unwrappedArray());
-
-      RootedValue rootedVal(cx, val);
-      if (!cx->compartment()->wrap(cx, &rootedVal)) {
-        return false;
-      }
-      unwrappedArray()->setDenseElement(index, rootedVal);
-    } else {
-      unwrappedArray()->setDenseElement(index, val);
-    }
-    return true;
-  }
-};
-
-}  // namespace js
-
-PromiseCombinatorDataHolder* PromiseCombinatorDataHolder::New(
-    JSContext* cx, HandleObject resultPromise,
-    Handle<PromiseCombinatorElements> elements, HandleObject resolveOrReject) {
-  auto* dataHolder = NewBuiltinClassInstance<PromiseCombinatorDataHolder>(cx);
+const JSClass PromiseAllDataHolder::class_ = {
+    "PromiseAllDataHolder",
+    JSCLASS_HAS_RESERVED_SLOTS(PromiseAllDataHolderSlots)};
+
+static PromiseAllDataHolder* NewPromiseAllDataHolder(JSContext* cx,
+                                                     HandleObject resultPromise,
+                                                     HandleValue valuesArray,
+                                                     HandleObject resolve) {
+  PromiseAllDataHolder* dataHolder =
+      NewBuiltinClassInstance<PromiseAllDataHolder>(cx);
   if (!dataHolder) {
     return nullptr;
   }
 
   cx->check(resultPromise);
-  cx->check(elements.value());
-  cx->check(resolveOrReject);
-
-  dataHolder->setFixedSlot(Slot_Promise, ObjectValue(*resultPromise));
-  dataHolder->setFixedSlot(Slot_RemainingElements, Int32Value(1));
-  dataHolder->setFixedSlot(Slot_ValuesArray, elements.value());
-  dataHolder->setFixedSlot(Slot_ResolveOrRejectFunction,
-                           ObjectValue(*resolveOrReject));
+  cx->check(valuesArray);
+  cx->check(resolve);
+
+  dataHolder->setFixedSlot(PromiseAllDataHolderSlot_Promise,
+                           ObjectValue(*resultPromise));
+  dataHolder->setFixedSlot(PromiseAllDataHolderSlot_RemainingElements,
+                           Int32Value(1));
+  dataHolder->setFixedSlot(PromiseAllDataHolderSlot_ValuesArray, valuesArray);
+  dataHolder->setFixedSlot(PromiseAllDataHolderSlot_ResolveFunction,
+                           ObjectValue(*resolve));
   return dataHolder;
 }
 
 namespace {
 // Generator used by PromiseObject::getID.
 mozilla::Atomic<uint64_t> gIDGenerator(0);
 }  // namespace
 
@@ -2387,56 +2273,48 @@ class MOZ_STACK_CLASS PromiseForOfIterat
 static MOZ_MUST_USE bool PerformPromiseAll(
     JSContext* cx, PromiseForOfIterator& iterator, HandleObject C,
     Handle<PromiseCapability> resultCapability, bool* done);
 
 static MOZ_MUST_USE bool PerformPromiseAllSettled(
     JSContext* cx, PromiseForOfIterator& iterator, HandleObject C,
     Handle<PromiseCapability> resultCapability, bool* done);
 
-static MOZ_MUST_USE bool PerformPromiseAny(
-    JSContext* cx, PromiseForOfIterator& iterator, HandleObject C,
-    Handle<PromiseCapability> resultCapability, bool* done);
-
 static MOZ_MUST_USE bool PerformPromiseRace(
     JSContext* cx, PromiseForOfIterator& iterator, HandleObject C,
     Handle<PromiseCapability> resultCapability, bool* done);
 
-enum class CombinatorKind { All, AllSettled, Any, Race };
-
-// ES2020 draft rev e97c95d064750fb949b6778584702dd658cf5624
+enum class IterationMode { All, AllSettled, Race };
+
+// ES2020 draft rev dc1e21c454bd316810be1c0e7af0131a2d7f38e9
 //
 // Unified implementation of
 // 25.6.4.1 Promise.all ( iterable )
-// 25.6.4.2 Promise.allSettled ( iterable )
-// 25.6.4.4 Promise.race ( iterable )
+// 25.6.4.3 Promise.race ( iterable )
 //
-// Promise.any (Stage 3 proposal)
-// https://tc39.es/proposal-promise-any/
+// Promise.allSettled (Stage 4 proposal)
+// https://tc39.github.io/proposal-promise-allSettled/
 //
-// Promise.any ( iterable )
-static MOZ_MUST_USE bool CommonPromiseCombinator(JSContext* cx, CallArgs& args,
-                                                 CombinatorKind kind) {
+// Promise.allSettled ( iterable )
+static MOZ_MUST_USE bool CommonStaticAllRace(JSContext* cx, CallArgs& args,
+                                             IterationMode mode) {
   HandleValue iterable = args.get(0);
 
   // Step 2 (moved from NewPromiseCapability, step 1).
   HandleValue CVal = args.thisv();
   if (!CVal.isObject()) {
     const char* message;
-    switch (kind) {
-      case CombinatorKind::All:
+    switch (mode) {
+      case IterationMode::All:
         message = "Receiver of Promise.all call";
         break;
-      case CombinatorKind::AllSettled:
+      case IterationMode::AllSettled:
         message = "Receiver of Promise.allSettled call";
         break;
-      case CombinatorKind::Any:
-        message = "Receiver of Promise.any call";
-        break;
-      case CombinatorKind::Race:
+      case IterationMode::Race:
         message = "Receiver of Promise.race call";
         break;
     }
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                               JSMSG_OBJECT_REQUIRED, message);
     return false;
   }
 
@@ -2452,48 +2330,42 @@ static MOZ_MUST_USE bool CommonPromiseCo
   // Steps 3-4.
   PromiseForOfIterator iter(cx);
   if (!iter.init(iterable, JS::ForOfIterator::AllowNonIterable)) {
     return AbruptRejectPromise(cx, args, promiseCapability);
   }
 
   if (!iter.valueIsIterable()) {
     const char* message;
-    switch (kind) {
-      case CombinatorKind::All:
+    switch (mode) {
+      case IterationMode::All:
         message = "Argument of Promise.all";
         break;
-      case CombinatorKind::AllSettled:
+      case IterationMode::AllSettled:
         message = "Argument of Promise.allSettled";
         break;
-      case CombinatorKind::Any:
-        message = "Argument of Promise.any";
-        break;
-      case CombinatorKind::Race:
+      case IterationMode::Race:
         message = "Argument of Promise.race";
         break;
     }
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_ITERABLE,
                               message);
     return AbruptRejectPromise(cx, args, promiseCapability);
   }
 
   // Step 5.
   bool done, result;
-  switch (kind) {
-    case CombinatorKind::All:
+  switch (mode) {
+    case IterationMode::All:
       result = PerformPromiseAll(cx, iter, C, promiseCapability, &done);
       break;
-    case CombinatorKind::AllSettled:
+    case IterationMode::AllSettled:
       result = PerformPromiseAllSettled(cx, iter, C, promiseCapability, &done);
       break;
-    case CombinatorKind::Any:
-      result = PerformPromiseAny(cx, iter, C, promiseCapability, &done);
-      break;
-    case CombinatorKind::Race:
+    case IterationMode::Race:
       result = PerformPromiseRace(cx, iter, C, promiseCapability, &done);
       break;
   }
 
   // Step 6.
   if (!result) {
     // Step 6.a.
     if (!done) {
@@ -2508,32 +2380,28 @@ static MOZ_MUST_USE bool CommonPromiseCo
   args.rval().setObject(*promiseCapability.promise());
   return true;
 }
 
 // ES2020 draft rev dc1e21c454bd316810be1c0e7af0131a2d7f38e9
 // 25.6.4.1 Promise.all ( iterable )
 static bool Promise_static_all(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
-  return CommonPromiseCombinator(cx, args, CombinatorKind::All);
+  return CommonStaticAllRace(cx, args, IterationMode::All);
 }
 
 static MOZ_MUST_USE bool PerformPromiseThen(
     JSContext* cx, Handle<PromiseObject*> promise, HandleValue onFulfilled_,
     HandleValue onRejected_, Handle<PromiseCapability> resultCapability);
 
 static MOZ_MUST_USE bool PerformPromiseThenWithoutSettleHandlers(
     JSContext* cx, Handle<PromiseObject*> promise,
     Handle<PromiseObject*> promiseToResolve,
     Handle<PromiseCapability> resultCapability);
 
-static JSFunction* NewPromiseCombinatorElementFunction(
-    JSContext* cx, Native native,
-    Handle<PromiseCombinatorDataHolder*> dataHolder, uint32_t index);
-
 static bool PromiseAllResolveElementFunction(JSContext* cx, unsigned argc,
                                              Value* vp);
 
 // Unforgeable version of ES2016, 25.4.4.1.
 MOZ_MUST_USE JSObject* js::GetWaitForAllPromise(
     JSContext* cx, JS::HandleObjectVector promises) {
 #ifdef DEBUG
   for (size_t i = 0, len = promises.length(); i < len; i++) {
@@ -2563,35 +2431,33 @@ MOZ_MUST_USE JSObject* js::GetWaitForAll
   // Step 7.
   // Implemented as an inlined, simplied version of ES2016 25.4.4.1.1,
   // PerformPromiseAll.
   {
     uint32_t promiseCount = promises.length();
     // Sub-steps 1-2 (omitted).
 
     // Sub-step 3.
-    Rooted<PromiseCombinatorElements> values(cx);
-    {
-      auto* valuesArray = NewDenseFullyAllocatedArray(cx, promiseCount);
-      if (!valuesArray) {
-        return nullptr;
-      }
-      valuesArray->ensureDenseInitializedLength(cx, 0, promiseCount);
-
-      values.initialize(valuesArray);
+    RootedNativeObject valuesArray(
+        cx, NewDenseFullyAllocatedArray(cx, promiseCount));
+    if (!valuesArray) {
+      return nullptr;
     }
+    valuesArray->ensureDenseInitializedLength(cx, 0, promiseCount);
 
     // Sub-step 4.
     // Create our data holder that holds all the things shared across
     // every step of the iterator.  In particular, this holds the
     // remainingElementsCount (as an integer reserved slot), the array of
     // values, and the resolve function from our PromiseCapability.
-    Rooted<PromiseCombinatorDataHolder*> dataHolder(cx);
-    dataHolder = PromiseCombinatorDataHolder::New(
-        cx, resultCapability.promise(), values, resultCapability.resolve());
+    RootedValue valuesArrayVal(cx, ObjectValue(*valuesArray));
+    Rooted<PromiseAllDataHolder*> dataHolder(cx);
+    dataHolder =
+        NewPromiseAllDataHolder(cx, resultCapability.promise(), valuesArrayVal,
+                                resultCapability.resolve());
     if (!dataHolder) {
       return nullptr;
     }
 
     // Call PerformPromiseThen with resolve and reject set to nullptr.
     Rooted<PromiseCapability> resultCapabilityWithoutResolving(cx);
     resultCapabilityWithoutResolving.promise().set(resultCapability.promise());
 
@@ -2599,28 +2465,36 @@ MOZ_MUST_USE JSObject* js::GetWaitForAll
 
     // Sub-step 6.
     for (uint32_t index = 0; index < promiseCount; index++) {
       // Steps a-c (omitted).
       // Step d (implemented after the loop).
       // Steps e-g (omitted).
 
       // Step h.
-      values.unwrappedArray()->setDenseElement(index, UndefinedHandleValue);
+      valuesArray->setDenseElement(index, UndefinedHandleValue);
 
       // Step i, vastly simplified.
       RootedObject nextPromiseObj(cx, promises[index]);
 
-      // Steps j-o.
-      JSFunction* resolveFunc = NewPromiseCombinatorElementFunction(
-          cx, PromiseAllResolveElementFunction, dataHolder, index);
+      // Step j.
+      RootedFunction resolveFunc(
+          cx,
+          NewNativeFunction(cx, PromiseAllResolveElementFunction, 1, nullptr,
+                            gc::AllocKind::FUNCTION_EXTENDED, GenericObject));
       if (!resolveFunc) {
         return nullptr;
       }
 
+      // Steps k-o.
+      resolveFunc->setExtendedSlot(PromiseAllResolveElementFunctionSlot_Data,
+                                   ObjectValue(*dataHolder));
+      resolveFunc->setExtendedSlot(
+          PromiseAllResolveElementFunctionSlot_ElementIndex, Int32Value(index));
+
       // Step p.
       dataHolder->increaseRemainingCount();
 
       // Step q, very roughly.
       RootedValue resolveFunVal(cx, ObjectValue(*resolveFunc));
       RootedValue rejectFunVal(cx, ObjectValue(*resultCapability.reject()));
       Rooted<PromiseObject*> nextPromise(cx);
 
@@ -2641,18 +2515,19 @@ MOZ_MUST_USE JSObject* js::GetWaitForAll
     }
 
     // Sub-step d.i (implicit).
     // Sub-step d.ii.
     int32_t remainingCount = dataHolder->decreaseRemainingCount();
 
     // Sub-step d.iii-iv.
     if (remainingCount == 0) {
+      RootedValue valuesArrayVal(cx, ObjectValue(*valuesArray));
       if (!ResolvePromiseInternal(cx, resultCapability.promise(),
-                                  values.value())) {
+                                  valuesArrayVal)) {
         return nullptr;
       }
     }
   }
 
   // Step 8 (omitted).
 
   // Step 9.
@@ -2718,26 +2593,25 @@ static MOZ_MUST_USE bool RunResolutionFu
 }
 
 static MOZ_MUST_USE JSObject* CommonStaticResolveRejectImpl(
     JSContext* cx, HandleValue thisVal, HandleValue argVal,
     ResolutionMode mode);
 
 static bool IsPromiseSpecies(JSContext* cx, JSFunction* species);
 
-// ES2020 draft rev e97c95d064750fb949b6778584702dd658cf5624
+// ES2020 draft rev dc1e21c454bd316810be1c0e7af0131a2d7f38e9
 // 25.6.4.1.1 Runtime Semantics: PerformPromiseAll, steps 5-6 and step 8.
-// 25.6.4.2.1 Runtime Semantics: PerformPromiseAllSettled, steps 5-6 and step 8.
-// 25.6.4.4.1 Runtime Semantics: PerformPromiseRace, steps 3-5.
+// 25.6.4.3.1 Runtime Semantics: PerformPromiseRace, steps 3-5.
 //
-// Promise.any (Stage 3 proposal)
-// https://tc39.es/proposal-promise-any/
-// Runtime Semantics: PerformPromiseAny, steps 6-8.
+// Promise.allSettled (Stage 4 proposal)
+// https://tc39.github.io/proposal-promise-allSettled/
+// Runtime Semantics: PerformPromiseAllSettled, steps 5-6 and step 8.
 template <typename T>
-static MOZ_MUST_USE bool CommonPerformPromiseCombinator(
+static MOZ_MUST_USE bool CommonPerformPromiseAllRace(
     JSContext* cx, PromiseForOfIterator& iterator, HandleObject C,
     HandleObject resultPromise, bool* done, bool resolveReturnsUndefined,
     T getResolveAndReject) {
   RootedObject promiseCtor(
       cx, GlobalObject::getOrCreatePromiseConstructor(cx, cx->global()));
   if (!promiseCtor) {
     return false;
   }
@@ -3025,284 +2899,241 @@ static MOZ_MUST_USE bool CommonPerformPr
         if (!AddDummyPromiseReactionForDebugger(cx, promise, blockedPromise)) {
           return false;
         }
       }
     }
   }
 }
 
-// Create the elements for the Promise combinators Promise.all and
-// Promise.allSettled.
-static MOZ_MUST_USE bool NewPromiseCombinatorElements(
-    JSContext* cx, Handle<PromiseCapability> resultCapability,
-    MutableHandle<PromiseCombinatorElements> elements) {
-  // We have to be very careful about which compartments we create things for
-  // the Promise combinators. In particular, we have to maintain the invariant
-  // that anything stored in a reserved slot is same-compartment with the object
-  // whose reserved slot it's in. But we want to create the values array in the
-  // compartment of the result capability's Promise, because that array can get
-  // exposed as the Promise's resolution value to code that has access to the
-  // Promise (in particular code from that compartment), and that should work,
-  // even if the Promise compartment is less-privileged than our caller
-  // compartment.
-  //
-  // So the plan is as follows: Create the values array in the promise
-  // compartment. Create the promise resolving functions and the data holder in
-  // our current compartment, i.e. the compartment of the Promise combinator
-  // function. Store a cross-compartment wrapper to the values array in the
-  // holder. This should be OK because the only things we hand the promise
-  // resolving functions to are the "then" calls we do and in the case when the
-  // Promise's compartment is not the current compartment those are happening
-  // over Xrays anyway, which means they get the canonical "then" function and
-  // content can't see our promise resolving functions.
-
-  if (IsWrapper(resultCapability.promise())) {
-    JSObject* unwrappedPromiseObj =
-        CheckedUnwrapStatic(resultCapability.promise());
-    MOZ_ASSERT(unwrappedPromiseObj);
-
-    {
-      AutoRealm ar(cx, unwrappedPromiseObj);
-      auto* array = NewDenseEmptyArray(cx);
-      if (!array) {
-        return false;
-      }
-      elements.initialize(array);
-    }
-
-    if (!cx->compartment()->wrap(cx, elements.value())) {
-      return false;
-    }
-  } else {
-    auto* array = NewDenseEmptyArray(cx);
-    if (!array) {
-      return false;
-    }
-
-    elements.initialize(array);
-  }
-  return true;
-}
-
-// Retrieve the combinator elements from the data holder.
-static MOZ_MUST_USE bool GetPromiseCombinatorElements(
-    JSContext* cx, Handle<PromiseCombinatorDataHolder*> data,
-    MutableHandle<PromiseCombinatorElements> elements) {
-  bool needsWrapping = false;
-  JSObject* valuesObj = &data->valuesArray().toObject();
-  if (IsProxy(valuesObj)) {
-    // See comment for NewPromiseCombinatorElements for why we unwrap here.
-    valuesObj = UncheckedUnwrap(valuesObj);
-
-    if (JS_IsDeadWrapper(valuesObj)) {
-      JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
-                                JSMSG_DEAD_OBJECT);
-      return false;
-    }
-
-    needsWrapping = true;
-  }
-
-  elements.initialize(data, &valuesObj->as<ArrayObject>(), needsWrapping);
-  return true;
-}
-
-static JSFunction* NewPromiseCombinatorElementFunction(
-    JSContext* cx, Native native,
-    Handle<PromiseCombinatorDataHolder*> dataHolder, uint32_t index) {
-  JSFunction* fn = NewNativeFunction(
-      cx, native, 1, nullptr, gc::AllocKind::FUNCTION_EXTENDED, GenericObject);
-  if (!fn) {
-    return nullptr;
-  }
-
-  fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_Data,
-                      ObjectValue(*dataHolder));
-  fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_ElementIndex,
-                      Int32Value(index));
-  return fn;
-}
-
-// ES2020 draft rev e97c95d064750fb949b6778584702dd658cf5624
-// 25.6.4.1.2 Promise.all Resolve Element Functions
-// 25.6.4.2.2 Promise.allSettled Resolve Element Functions
-// 25.6.4.2.3 Promise.allSettled Reject Element Functions
-//
-// Common implementation for Promise combinator element functions to check if
-// they've already been called.
-static bool PromiseCombinatorElementFunctionAlreadyCalled(
-    const CallArgs& args, MutableHandle<PromiseCombinatorDataHolder*> data,
-    uint32_t* index) {
-  // Step 1.
-  JSFunction* fn = &args.callee().as<JSFunction>();
-
-  // Step 2.
-  const Value& dataVal =
-      fn->getExtendedSlot(PromiseCombinatorElementFunctionSlot_Data);
-
-  // Step 3.
-  // We use the existence of the data holder as a signal for whether the Promise
-  // combinator element function was already called. Upon resolution, it's reset
-  // to `undefined`.
-  if (dataVal.isUndefined()) {
-    return true;
-  }
-
-  data.set(&dataVal.toObject().as<PromiseCombinatorDataHolder>());
-
-  // Step 4.
-  fn->setExtendedSlot(PromiseCombinatorElementFunctionSlot_Data,
-                      UndefinedValue());
-
-  // Step 5.
-  int32_t idx =
-      fn->getExtendedSlot(PromiseCombinatorElementFunctionSlot_ElementIndex)
-          .toInt32();
-  MOZ_ASSERT(idx >= 0);
-  *index = uint32_t(idx);
-
-  return false;
-}
-
 // ES2020 draft rev dc1e21c454bd316810be1c0e7af0131a2d7f38e9
 // 25.6.4.1.1 PerformPromiseAll (iteratorRecord, constructor, resultCapability)
 static MOZ_MUST_USE bool PerformPromiseAll(
     JSContext* cx, PromiseForOfIterator& iterator, HandleObject C,
     Handle<PromiseCapability> resultCapability, bool* done) {
   *done = false;
 
   // Step 1.
   MOZ_ASSERT(C->isConstructor());
 
   // Step 2 (omitted).
 
   // Step 3.
-  Rooted<PromiseCombinatorElements> values(cx);
-  if (!NewPromiseCombinatorElements(cx, resultCapability, &values)) {
-    return false;
+  // We have to be very careful about which compartments we create things in
+  // here.  In particular, we have to maintain the invariant that anything
+  // stored in a reserved slot is same-compartment with the object whose
+  // reserved slot it's in.  But we want to create the values array in the
+  // Promise's compartment, because that array can get exposed to
+  // code that has access to the Promise (in particular code from
+  // that compartment), and that should work, even if the Promise
+  // compartment is less-privileged than our caller compartment.
+  //
+  // So the plan is as follows: Create the values array in the promise
+  // compartment.  Create the PromiseAllResolveElement function
+  // and the data holder in our current compartment.  Store a
+  // cross-compartment wrapper to the values array in the holder.  This
+  // should be OK because the only things we hand the
+  // PromiseAllResolveElement function to are the "then" calls we do and in
+  // the case when the Promise's compartment is not the current compartment
+  // those are happening over Xrays anyway, which means they get the
+  // canonical "then" function and content can't see our
+  // PromiseAllResolveElement.
+  RootedArrayObject valuesArray(cx);
+  RootedValue valuesArrayVal(cx);
+  if (IsWrapper(resultCapability.promise())) {
+    JSObject* unwrappedPromiseObj =
+        CheckedUnwrapStatic(resultCapability.promise());
+    MOZ_ASSERT(unwrappedPromiseObj);
+
+    {
+      AutoRealm ar(cx, unwrappedPromiseObj);
+      valuesArray = NewDenseEmptyArray(cx);
+      if (!valuesArray) {
+        return false;
+      }
+    }
+
+    valuesArrayVal.setObject(*valuesArray);
+    if (!cx->compartment()->wrap(cx, &valuesArrayVal)) {
+      return false;
+    }
+  } else {
+    valuesArray = NewDenseEmptyArray(cx);
+    if (!valuesArray) {
+      return false;
+    }
+
+    valuesArrayVal.setObject(*valuesArray);
   }
 
   // Step 4.
   // Create our data holder that holds all the things shared across
   // every step of the iterator.  In particular, this holds the
   // remainingElementsCount (as an integer reserved slot), the array of
   // values, and the resolve function from our PromiseCapability.
-  Rooted<PromiseCombinatorDataHolder*> dataHolder(cx);
-  dataHolder = PromiseCombinatorDataHolder::New(
-      cx, resultCapability.promise(), values, resultCapability.resolve());
+  Rooted<PromiseAllDataHolder*> dataHolder(cx);
+  dataHolder =
+      NewPromiseAllDataHolder(cx, resultCapability.promise(), valuesArrayVal,
+                              resultCapability.resolve());
   if (!dataHolder) {
     return false;
   }
 
   // Step 7.
   uint32_t index = 0;
 
-  auto getResolveAndReject = [cx, &resultCapability, &values, &dataHolder,
+  auto getResolveAndReject = [cx, &resultCapability, &valuesArray, &dataHolder,
                               &index](MutableHandleValue resolveFunVal,
                                       MutableHandleValue rejectFunVal) {
     // Step 8.h.
-    if (!values.pushUndefined(cx)) {
-      return false;
+    {  // Scope for the AutoRealm we need to work with valuesArray.  We
+      // mostly do this for performance; we could go ahead and do the define via
+      // a cross-compartment proxy instead...
+      AutoRealm ar(cx, valuesArray);
+
+      if (!NewbornArrayPush(cx, valuesArray, UndefinedValue())) {
+        return false;
+      }
     }
 
-    // Steps 8.j-p.
-    JSFunction* resolveFunc = NewPromiseCombinatorElementFunction(
-        cx, PromiseAllResolveElementFunction, dataHolder, index);
+    // Steps 8.j-k.
+    JSFunction* resolveFunc =
+        NewNativeFunction(cx, PromiseAllResolveElementFunction, 1, nullptr,
+                          gc::AllocKind::FUNCTION_EXTENDED, GenericObject);
     if (!resolveFunc) {
       return false;
     }
 
+    // Steps 8.l, 8.n-p.
+    resolveFunc->setExtendedSlot(PromiseAllResolveElementFunctionSlot_Data,
+                                 ObjectValue(*dataHolder));
+
+    // Step 8.m.
+    resolveFunc->setExtendedSlot(
+        PromiseAllResolveElementFunctionSlot_ElementIndex, Int32Value(index));
+
     // Step 8.q.
     dataHolder->increaseRemainingCount();
 
     // Step 8.s.
     index++;
     MOZ_ASSERT(index > 0);
 
     resolveFunVal.setObject(*resolveFunc);
     rejectFunVal.setObject(*resultCapability.reject());
     return true;
   };
 
   // Steps 5-6 and 8.
-  if (!CommonPerformPromiseCombinator(cx, iterator, C,
-                                      resultCapability.promise(), done, true,
-                                      getResolveAndReject)) {
+  if (!CommonPerformPromiseAllRace(cx, iterator, C, resultCapability.promise(),
+                                   done, true, getResolveAndReject)) {
     return false;
   }
 
   // Step 8.d.ii.
   int32_t remainingCount = dataHolder->decreaseRemainingCount();
 
   // Steps 8.d.iii-iv.
   if (remainingCount == 0) {
-    return RunResolutionFunction(cx, resultCapability.resolve(), values.value(),
+    return RunResolutionFunction(cx, resultCapability.resolve(), valuesArrayVal,
                                  ResolveMode, resultCapability.promise());
   }
 
   return true;
 }
 
-// ES2020 draft rev e97c95d064750fb949b6778584702dd658cf5624
-// 25.6.4.1.2 Promise.all Resolve Element Functions
+// ES2016, 25.4.4.1.2.
 static bool PromiseAllResolveElementFunction(JSContext* cx, unsigned argc,
                                              Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
-  HandleValue xVal = args.get(0);
-
-  // Steps 1-5.
-  Rooted<PromiseCombinatorDataHolder*> data(cx);
-  uint32_t index;
-  if (PromiseCombinatorElementFunctionAlreadyCalled(args, &data, &index)) {
+
+  JSFunction* resolve = &args.callee().as<JSFunction>();
+  RootedValue xVal(cx, args.get(0));
+
+  // Step 1.
+  const Value& dataVal =
+      resolve->getExtendedSlot(PromiseAllResolveElementFunctionSlot_Data);
+
+  // Step 2.
+  // We use the existence of the data holder as a signal for whether the
+  // Promise was already resolved. Upon resolution, it's reset to
+  // `undefined`.
+  if (dataVal.isUndefined()) {
     args.rval().setUndefined();
     return true;
   }
 
-  // Step 6.
-  Rooted<PromiseCombinatorElements> values(cx);
-  if (!GetPromiseCombinatorElements(cx, data, &values)) {
-    return false;
-  }
-
-  // Step 7 (moved under step 11).
-  // Step 8 (moved to step 10).
-
-  // Step 9.
-  if (!values.setElement(cx, index, xVal)) {
-    return false;
-  }
-
-  // Steps 8,10.
+  Rooted<PromiseAllDataHolder*> data(
+      cx, &dataVal.toObject().as<PromiseAllDataHolder>());
+
+  // Step 3.
+  resolve->setExtendedSlot(PromiseAllResolveElementFunctionSlot_Data,
+                           UndefinedValue());
+
+  // Step 4.
+  int32_t index =
+      resolve
+          ->getExtendedSlot(PromiseAllResolveElementFunctionSlot_ElementIndex)
+          .toInt32();
+
+  // Step 5.
+  RootedValue valuesVal(cx, data->valuesArray());
+  RootedObject valuesObj(cx, &valuesVal.toObject());
+  if (IsProxy(valuesObj)) {
+    // See comment for PerformPromiseAll, step 3 for why we unwrap here.
+    valuesObj = UncheckedUnwrap(valuesObj);
+
+    if (JS_IsDeadWrapper(valuesObj)) {
+      JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                                JSMSG_DEAD_OBJECT);
+      return false;
+    }
+
+    AutoRealm ar(cx, valuesObj);
+    if (!cx->compartment()->wrap(cx, &xVal)) {
+      return false;
+    }
+  }
+  HandleNativeObject values = valuesObj.as<NativeObject>();
+
+  // Step 6 (moved under step 10).
+  // Step 7 (moved to step 9).
+
+  // Step 8.
+  // The index is guaranteed to be initialized to `undefined`.
+  MOZ_ASSERT(values->getDenseElement(index).isUndefined());
+  values->setDenseElement(index, xVal);
+
+  // Steps 7,9.
   uint32_t remainingCount = data->decreaseRemainingCount();
 
-  // Step 11.
+  // Step 10.
   if (remainingCount == 0) {
-    // Step 11.a. (Omitted, happened in PerformPromiseAll.)
-    // Step 11.b.
-
-    // Step 7 (Adapted to work with PromiseCombinatorDataHolder's layout).
-    RootedObject resolveAllFun(cx, data->resolveOrRejectObj());
+    // Step 10.a. (Omitted, happened in PerformPromiseAll.)
+    // Step 10.b.
+
+    // Step 6 (Adapted to work with PromiseAllDataHolder's layout).
+    RootedObject resolveAllFun(cx, data->resolveObj());
     RootedObject promiseObj(cx, data->promiseObj());
-    if (!RunResolutionFunction(cx, resolveAllFun, values.value(), ResolveMode,
+    if (!RunResolutionFunction(cx, resolveAllFun, valuesVal, ResolveMode,
                                promiseObj)) {
       return false;
     }
   }
 
-  // Step 12.
+  // Step 11.
   args.rval().setUndefined();
   return true;
 }
 
 // ES2020 draft rev dc1e21c454bd316810be1c0e7af0131a2d7f38e9
 // 25.6.4.3 Promise.race ( iterable )
 static bool Promise_static_race(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
-  return CommonPromiseCombinator(cx, args, CombinatorKind::Race);
+  return CommonStaticAllRace(cx, args, IterationMode::Race);
 }
 
 // ES2020 draft rev dc1e21c454bd316810be1c0e7af0131a2d7f38e9
 // 25.6.4.3.1 PerformPromiseRace (iteratorRecord, constructor, resultCapability)
 static MOZ_MUST_USE bool PerformPromiseRace(
     JSContext* cx, PromiseForOfIterator& iterator, HandleObject C,
     Handle<PromiseCapability> resultCapability, bool* done) {
   *done = false;
@@ -3322,166 +3153,233 @@ static MOZ_MUST_USE bool PerformPromiseR
                                  MutableHandleValue resolveFunVal,
                                  MutableHandleValue rejectFunVal) {
     resolveFunVal.setObject(*resultCapability.resolve());
     rejectFunVal.setObject(*resultCapability.reject());
     return true;
   };
 
   // Steps 3-5.
-  return CommonPerformPromiseCombinator(
-      cx, iterator, C, resultCapability.promise(), done, isDefaultResolveFn,
-      getResolveAndReject);
+  return CommonPerformPromiseAllRace(cx, iterator, C,
+                                     resultCapability.promise(), done,
+                                     isDefaultResolveFn, getResolveAndReject);
 }
 
 enum class PromiseAllSettledElementFunctionKind { Resolve, Reject };
 
-// ES2020 draft rev e97c95d064750fb949b6778584702dd658cf5624
-// 25.6.4.2 Promise.allSettled ( iterable )
+// Promise.allSettled (Stage 4 proposal)
+// https://tc39.github.io/proposal-promise-allSettled/
 //
 // Promise.allSettled Resolve Element Functions
 // Promise.allSettled Reject Element Functions
 template <PromiseAllSettledElementFunctionKind Kind>
 static bool PromiseAllSettledElementFunction(JSContext* cx, unsigned argc,
                                              Value* vp);
 
-// ES2020 draft rev e97c95d064750fb949b6778584702dd658cf5624
-// 25.6.4.2 Promise.allSettled ( iterable )
+// Promise.allSettled (Stage 4 proposal)
+// https://tc39.github.io/proposal-promise-allSettled/
 //
 // Promise.allSettled ( iterable )
 static bool Promise_static_allSettled(JSContext* cx, unsigned argc, Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
-  return CommonPromiseCombinator(cx, args, CombinatorKind::AllSettled);
+  return CommonStaticAllRace(cx, args, IterationMode::AllSettled);
 }
 
-// ES2020 draft rev e97c95d064750fb949b6778584702dd658cf5624
-// 25.6.4.2 Promise.allSettled ( iterable )
+// Promise.allSettled (Stage 4 proposal)
+// https://tc39.github.io/proposal-promise-allSettled/
 //
 // PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability )
 static MOZ_MUST_USE bool PerformPromiseAllSettled(
     JSContext* cx, PromiseForOfIterator& iterator, HandleObject C,
     Handle<PromiseCapability> resultCapability, bool* done) {
   *done = false;
 
   // Step 1.
   MOZ_ASSERT(C->isConstructor());
 
   // Step 2 (omitted).
 
   // Step 3.
-  Rooted<PromiseCombinatorElements> values(cx);
-  if (!NewPromiseCombinatorElements(cx, resultCapability, &values)) {
-    return false;
+  // See the big comment in PerformPromiseAll about which objects should be
+  // created in which compartments.
+  RootedArrayObject valuesArray(cx);
+  RootedValue valuesArrayVal(cx);
+  if (IsWrapper(resultCapability.promise())) {
+    JSObject* unwrappedPromiseObj =
+        CheckedUnwrapStatic(resultCapability.promise());
+    MOZ_ASSERT(unwrappedPromiseObj);
+
+    {
+      AutoRealm ar(cx, unwrappedPromiseObj);
+      valuesArray = NewDenseEmptyArray(cx);
+      if (!valuesArray) {
+        return false;
+      }
+    }
+
+    valuesArrayVal.setObject(*valuesArray);
+    if (!cx->compartment()->wrap(cx, &valuesArrayVal)) {
+      return false;
+    }
+  } else {
+    valuesArray = NewDenseEmptyArray(cx);
+    if (!valuesArray) {
+      return false;
+    }
+
+    valuesArrayVal.setObject(*valuesArray);
   }
 
   // Step 4.
   // Create our data holder that holds all the things shared across every step
   // of the iterator. In particular, this holds the remainingElementsCount
   // (as an integer reserved slot), the array of values, and the resolve
   // function from our PromiseCapability.
-  Rooted<PromiseCombinatorDataHolder*> dataHolder(cx);
-  dataHolder = PromiseCombinatorDataHolder::New(
-      cx, resultCapability.promise(), values, resultCapability.resolve());
+  Rooted<PromiseAllDataHolder*> dataHolder(cx);
+  dataHolder =
+      NewPromiseAllDataHolder(cx, resultCapability.promise(), valuesArrayVal,
+                              resultCapability.resolve());
   if (!dataHolder) {
     return false;
   }
 
   // Step 7.
   uint32_t index = 0;
 
-  auto getResolveAndReject = [cx, &values, &dataHolder, &index](
+  auto getResolveAndReject = [cx, &valuesArray, &dataHolder, &index](
                                  MutableHandleValue resolveFunVal,
                                  MutableHandleValue rejectFunVal) {
     // Step 8.h.
-    if (!values.pushUndefined(cx)) {
-      return false;
+    {  // Scope for the AutoRealm we need to work with valuesArray.  We
+      // mostly do this for performance; we could go ahead and do the define via
+      // a cross-compartment proxy instead...
+      AutoRealm ar(cx, valuesArray);
+
+      if (!NewbornArrayPush(cx, valuesArray, UndefinedValue())) {
+        return false;
+      }
     }
 
     auto PromiseAllSettledResolveElementFunction =
         PromiseAllSettledElementFunction<
             PromiseAllSettledElementFunctionKind::Resolve>;
     auto PromiseAllSettledRejectElementFunction =
         PromiseAllSettledElementFunction<
             PromiseAllSettledElementFunctionKind::Reject>;
 
-    // Steps 8.j-q.
-    JSFunction* resolveFunc = NewPromiseCombinatorElementFunction(
-        cx, PromiseAllSettledResolveElementFunction, dataHolder, index);
+    // Steps 8.j-m.
+    JSFunction* resolveFunc = NewNativeFunction(
+        cx, PromiseAllSettledResolveElementFunction, 1, nullptr,
+        gc::AllocKind::FUNCTION_EXTENDED, GenericObject);
     if (!resolveFunc) {
       return false;
     }
     resolveFunVal.setObject(*resolveFunc);
 
-    // Steps 8.r-x.
-    JSFunction* rejectFunc = NewPromiseCombinatorElementFunction(
-        cx, PromiseAllSettledRejectElementFunction, dataHolder, index);
+    // Steps 8.o-q.
+    resolveFunc->setExtendedSlot(PromiseAllSettledElementFunctionSlot_Data,
+                                 ObjectValue(*dataHolder));
+
+    // Step 8.n.
+    resolveFunc->setExtendedSlot(
+        PromiseAllSettledElementFunctionSlot_ElementIndex, Int32Value(index));
+
+    // Steps 8.r-t.
+    JSFunction* rejectFunc = NewNativeFunction(
+        cx, PromiseAllSettledRejectElementFunction, 1, nullptr,
+        gc::AllocKind::FUNCTION_EXTENDED, GenericObject);
     if (!rejectFunc) {
       return false;
     }
     rejectFunVal.setObject(*rejectFunc);
 
+    // Steps 8.v-x.
+    rejectFunc->setExtendedSlot(PromiseAllSettledElementFunctionSlot_Data,
+                                ObjectValue(*dataHolder));
+
+    // Step 8.u.
+    rejectFunc->setExtendedSlot(
+        PromiseAllSettledElementFunctionSlot_ElementIndex, Int32Value(index));
+
     // Step 8.y.
     dataHolder->increaseRemainingCount();
 
     // Step 8.aa.
     index++;
     MOZ_ASSERT(index > 0);
 
     return true;
   };
 
   // Steps 5-6 and 8.
-  if (!CommonPerformPromiseCombinator(cx, iterator, C,
-                                      resultCapability.promise(), done, true,
-                                      getResolveAndReject)) {
+  if (!CommonPerformPromiseAllRace(cx, iterator, C, resultCapability.promise(),
+                                   done, true, getResolveAndReject)) {
     return false;
   }
 
   // Step 8.d.ii.
   int32_t remainingCount = dataHolder->decreaseRemainingCount();
 
   // Steps 8.d.iii-iv.
   if (remainingCount == 0) {
-    return RunResolutionFunction(cx, resultCapability.resolve(), values.value(),
+    return RunResolutionFunction(cx, resultCapability.resolve(), valuesArrayVal,
                                  ResolveMode, resultCapability.promise());
   }
 
   return true;
 }
 
-// ES2020 draft rev e97c95d064750fb949b6778584702dd658cf5624
-// 25.6.4.2.2 Promise.allSettled Resolve Element Functions
-// 25.6.4.2.3 Promise.allSettled Reject Element Functions
+// Promise.allSettled (Stage 4 proposal)
+// https://tc39.github.io/proposal-promise-allSettled/
+//
+// Promise.allSettled Resolve Element Functions
+// Promise.allSettled Reject Element Functions
 template <PromiseAllSettledElementFunctionKind Kind>
 static bool PromiseAllSettledElementFunction(JSContext* cx, unsigned argc,
                                              Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   HandleValue valueOrReason = args.get(0);
 
-  // Steps 1-5.
-  Rooted<PromiseCombinatorDataHolder*> data(cx);
-  uint32_t index;
-  if (PromiseCombinatorElementFunctionAlreadyCalled(args, &data, &index)) {
-    args.rval().setUndefined();
-    return true;
-  }
+  // Step 1.
+  JSFunction* resolve = &args.callee().as<JSFunction>();
+  Rooted<PromiseAllDataHolder*> data(
+      cx, &resolve->getExtendedSlot(PromiseAllSettledElementFunctionSlot_Data)
+               .toObject()
+               .as<PromiseAllDataHolder>());
+
+  // Steps 2-4 (moved below).
+
+  // Step 5.
+  int32_t index =
+      resolve
+          ->getExtendedSlot(PromiseAllSettledElementFunctionSlot_ElementIndex)
+          .toInt32();
 
   // Step 6.
-  Rooted<PromiseCombinatorElements> values(cx);
-  if (!GetPromiseCombinatorElements(cx, data, &values)) {
-    return false;
-  }
+  RootedValue valuesVal(cx, data->valuesArray());
+  RootedObject valuesObj(cx, &valuesVal.toObject());
+  bool needsWrapping = false;
+  if (IsProxy(valuesObj)) {
+    // See comment for PerformPromiseAllSettled, step 3 for why we unwrap here.
+    valuesObj = UncheckedUnwrap(valuesObj);
+
+    if (JS_IsDeadWrapper(valuesObj)) {
+      JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
+                                JSMSG_DEAD_OBJECT);
+      return false;
+    }
+
+    needsWrapping = true;
+  }
+  HandleNativeObject values = valuesObj.as<NativeObject>();
 
   // Steps 2-3.
-  // The already-called check above only handles the case when |this| function
-  // is called repeatedly, so we still need to check if the other pair of this
-  // resolving function was already called:
   // We use the element value as a signal for whether the Promise was already
   // fulfilled. Upon resolution, it's set to the result object created below.
-  if (!values.unwrappedArray()->getDenseElement(index).isUndefined()) {
+  if (!values->getDenseElement(index).isUndefined()) {
     args.rval().setUndefined();
     return true;
   }
 
   // Steps 7-8 (moved below).
 
   // Step 9.
   RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
@@ -3506,262 +3404,49 @@ static bool PromiseAllSettledElementFunc
     id = NameToId(cx->names().value);
   } else {
     id = NameToId(cx->names().reason);
   }
   if (!NativeDefineDataProperty(cx, obj, id, valueOrReason, JSPROP_ENUMERATE)) {
     return false;
   }
 
+  RootedValue objVal(cx, ObjectValue(*obj));
+  if (needsWrapping) {
+    AutoRealm ar(cx, valuesObj);
+    if (!cx->compartment()->wrap(cx, &objVal)) {
+      return false;
+    }
+  }
+
   // Steps 4, 12.
-  RootedValue objVal(cx, ObjectValue(*obj));
-  if (!values.setElement(cx, index, objVal)) {
-    return false;
-  }
+  values->setDenseElement(index, objVal);
 
   // Steps 8, 13.
   uint32_t remainingCount = data->decreaseRemainingCount();
 
   // Step 14.
   if (remainingCount == 0) {
     // Step 14.a. (Omitted, happened in PerformPromiseAllSettled.)
     // Step 14.b.
 
-    // Step 7 (Adapted to work with PromiseCombinatorDataHolder's layout).
-    RootedObject resolveAllFun(cx, data->resolveOrRejectObj());
+    // Step 7 (Adapted to work with PromiseAllDataHolder's layout).
+    RootedObject resolveAllFun(cx, data->resolveObj());
     RootedObject promiseObj(cx, data->promiseObj());
-    if (!RunResolutionFunction(cx, resolveAllFun, values.value(), ResolveMode,
+    if (!RunResolutionFunction(cx, resolveAllFun, valuesVal, ResolveMode,
                                promiseObj)) {
       return false;
     }
   }
 
   // Step 15.
   args.rval().setUndefined();
   return true;
 }
 
-// Promise.any (Stage 3 proposal)
-// https://tc39.es/proposal-promise-any/
-//
-// Promise.any ( iterable )
-static bool Promise_static_any(JSContext* cx, unsigned argc, Value* vp) {
-  CallArgs args = CallArgsFromVp(argc, vp);
-  return CommonPromiseCombinator(cx, args, CombinatorKind::Any);
-}
-
-// Promise.any (Stage 3 proposal)
-// https://tc39.es/proposal-promise-any/
-//
-// Promise.any Reject Element Functions
-static bool PromiseAnyRejectElementFunction(JSContext* cx, unsigned argc,
-                                            Value* vp);
-
-// Promise.any (Stage 3 proposal)
-// https://tc39.es/proposal-promise-any/
-//
-// ThrowAggregateError ( errors )
-static void ThrowAggregateError(JSContext* cx,
-                                Handle<PromiseCombinatorElements> errors,
-                                HandleObject promise);
-
-// Promise.any (Stage 3 proposal)
-// https://tc39.es/proposal-promise-any/
-//
-// PerformPromiseAny ( iteratorRecord, constructor, resultCapability )
-static MOZ_MUST_USE bool PerformPromiseAny(
-    JSContext* cx, PromiseForOfIterator& iterator, HandleObject C,
-    Handle<PromiseCapability> resultCapability, bool* done) {
-  *done = false;
-
-  // Step 1.
-  MOZ_ASSERT(C->isConstructor());
-
-  // Step 2 (omitted).
-
-  // Step 3.
-  Rooted<PromiseCombinatorElements> errors(cx);
-  if (!NewPromiseCombinatorElements(cx, resultCapability, &errors)) {
-    return false;
-  }
-
-  // Step 4.
-  // Create our data holder that holds all the things shared across every step
-  // of the iterator. In particular, this holds the remainingElementsCount (as
-  // an integer reserved slot), the array of errors, and the reject function
-  // from our PromiseCapability.
-  Rooted<PromiseCombinatorDataHolder*> dataHolder(cx);
-  dataHolder = PromiseCombinatorDataHolder::New(
-      cx, resultCapability.promise(), errors, resultCapability.reject());
-  if (!dataHolder) {
-    return false;
-  }
-
-  // Step 5.
-  uint32_t index = 0;
-
-  auto getResolveAndReject = [cx, &resultCapability, &errors, &dataHolder,
-                              &index](MutableHandleValue resolveFunVal,
-                                      MutableHandleValue rejectFunVal) {
-    // Step 8.h.
-    if (!errors.pushUndefined(cx)) {
-      return false;
-    }
-
-    // Steps 8.j-p.
-    JSFunction* rejectFunc = NewPromiseCombinatorElementFunction(
-        cx, PromiseAnyRejectElementFunction, dataHolder, index);
-    if (!rejectFunc) {
-      return false;
-    }
-
-    // Step 8.q.
-    dataHolder->increaseRemainingCount();
-
-    // Step 8.s.
-    index++;
-    MOZ_ASSERT(index > 0);
-
-    resolveFunVal.setObject(*resultCapability.resolve());
-    rejectFunVal.setObject(*rejectFunc);
-    return true;
-  };
-
-  // BlockOnPromise fast path requires the passed onFulfilled function doesn't
-  // return an object value, because otherwise the skipped promise creation is
-  // detectable due to missing property lookups.
-  bool isDefaultResolveFn =
-      IsNativeFunction(resultCapability.resolve(), ResolvePromiseFunction);
-
-  // Steps 6-8.
-  if (!CommonPerformPromiseCombinator(
-          cx, iterator, C, resultCapability.promise(), done, isDefaultResolveFn,
-          getResolveAndReject)) {
-    return false;
-  }
-
-  // Step 8.d.ii.
-  int32_t remainingCount = dataHolder->decreaseRemainingCount();
-
-  // Step 8.d.iii.
-  if (remainingCount == 0) {
-    ThrowAggregateError(cx, errors, resultCapability.promise());
-    return false;
-  }
-
-  // Step 8.d.iv.
-  return true;
-}
-
-// Promise.any (Stage 3 proposal)
-// https://tc39.es/proposal-promise-any/
-//
-// Promise.any Reject Element Functions
-static bool PromiseAnyRejectElementFunction(JSContext* cx, unsigned argc,
-                                            Value* vp) {
-  CallArgs args = CallArgsFromVp(argc, vp);
-  HandleValue xVal = args.get(0);
-
-  // Steps 1-5.
-  Rooted<PromiseCombinatorDataHolder*> data(cx);
-  uint32_t index;
-  if (PromiseCombinatorElementFunctionAlreadyCalled(args, &data, &index)) {
-    args.rval().setUndefined();
-    return true;
-  }
-
-  // Step 6.
-  Rooted<PromiseCombinatorElements> errors(cx);
-  if (!GetPromiseCombinatorElements(cx, data, &errors)) {
-    return false;
-  }
-
-  // Step 9.
-  if (!errors.setElement(cx, index, xVal)) {
-    return false;
-  }
-
-  // Steps 8, 10.
-  uint32_t remainingCount = data->decreaseRemainingCount();
-
-  // Step 11.
-  if (remainingCount == 0) {
-    // Step 7 (Adapted to work with PromiseCombinatorDataHolder's layout).
-    RootedObject rejectFun(cx, data->resolveOrRejectObj());
-    RootedObject promiseObj(cx, data->promiseObj());
-
-    ThrowAggregateError(cx, errors, promiseObj);
-
-    RootedValue reason(cx);
-    if (!MaybeGetAndClearException(cx, &reason)) {
-      return false;
-    }
-
-    if (!RunResolutionFunction(cx, rejectFun, reason, RejectMode, promiseObj)) {
-      return false;
-    }
-  }
-
-  // Step 12.
-  args.rval().setUndefined();
-  return true;
-}
-
-// Promise.any (Stage 3 proposal)
-// https://tc39.es/proposal-promise-any/
-//
-// ThrowAggregateError ( errors )
-static void ThrowAggregateError(JSContext* cx,
-                                Handle<PromiseCombinatorElements> errors,
-                                HandleObject promise) {
-  MOZ_ASSERT(!cx->isExceptionPending());
-
-  // Create the AggregateError in the same realm as the array object.
-  AutoRealm ar(cx, errors.unwrappedArray());
-
-  RootedObject allocationSite(cx);
-  mozilla::Maybe<JS::AutoSetAsyncStackForNewCalls> asyncStack;
-
-  // Provide a more useful error stack if possible: This function is typically
-  // called from Promise job queue, which doesn't have any JS frames on the
-  // stack. So when we create the AggregateError below, its stack property will
-  // be set to the empty string, which makes it harder to debug the error cause.
-  // To avoid this situation set-up an async stack based on the Promise
-  // allocation site, which should point to calling site of |Promise.any|.
-  if (promise->is<PromiseObject>()) {
-    allocationSite = promise->as<PromiseObject>().allocationSite();
-    if (allocationSite) {
-      asyncStack.emplace(
-          cx, allocationSite, "Promise.any",
-          JS::AutoSetAsyncStackForNewCalls::AsyncCallKind::IMPLICIT);
-    }
-  }
-
-  // AutoSetAsyncStackForNewCalls requires a new activation before it takes
-  // effect, so call into the self-hosting helper to set-up new call frames.
-  RootedValue error(cx);
-  if (!GetAggregateError(cx, JSMSG_PROMISE_ANY_REJECTION, &error)) {
-    return;
-  }
-
-  // |error| isn't guaranteed to be an AggregateErrorObject in case of OOM.
-  RootedSavedFrame stack(cx);
-  if (error.isObject() && error.toObject().is<AggregateErrorObject>()) {
-    auto* aggregateError = &error.toObject().as<AggregateErrorObject>();
-    aggregateError->setAggregateErrors(errors.unwrappedArray());
-
-    // Adopt the existing saved frames when present.
-    if (JSObject* errorStack = aggregateError->stack()) {
-      stack = &errorStack->as<SavedFrame>();
-    }
-  }
-
-  cx->setPendingException(error, stack);
-}
-
 // https://tc39.github.io/ecma262/#sec-promise.reject
 //
 // Unified implementation of
 // 25.6.4.4 Promise.reject ( r )
 // 25.6.4.5 Promise.resolve ( x )
 // 25.6.4.5.1 PromiseResolve ( C, x )
 static MOZ_MUST_USE JSObject* CommonStaticResolveRejectImpl(
     JSContext* cx, HandleValue thisVal, HandleValue argVal,
@@ -6068,19 +5753,16 @@ static const JSFunctionSpec promise_meth
     JS_SELF_HOSTED_FN("finally", "Promise_finally", 1, 0), JS_FS_END};
 
 static const JSPropertySpec promise_properties[] = {
     JS_STRING_SYM_PS(toStringTag, "Promise", JSPROP_READONLY), JS_PS_END};
 
 static const JSFunctionSpec promise_static_methods[] = {
     JS_FN("all", Promise_static_all, 1, 0),
     JS_FN("allSettled", Promise_static_allSettled, 1, 0),
-#ifdef NIGHTLY_BUILD
-    JS_FN("any", Promise_static_any, 1, 0),
-#endif
     JS_FN("race", Promise_static_race, 1, 0),
     JS_FN("reject", Promise_reject, 1, 0),
     JS_FN("resolve", Promise_static_resolve, 1, 0),
     JS_FS_END};
 
 static const JSPropertySpec promise_static_properties[] = {
     JS_SYM_GET(species, Promise_static_species, 0), JS_PS_END};
 
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -64,17 +64,16 @@
 #include "js/UniquePtr.h"
 #include "js/Vector.h"
 #include "js/Wrapper.h"
 #include "threading/CpuCount.h"
 #include "util/StringBuffer.h"
 #include "util/Text.h"
 #include "vm/AsyncFunction.h"
 #include "vm/AsyncIteration.h"
-#include "vm/ErrorObject.h"
 #include "vm/GlobalObject.h"
 #include "vm/Interpreter.h"
 #include "vm/Iteration.h"
 #include "vm/JSContext.h"
 #include "vm/JSObject.h"
 #include "vm/ProxyObject.h"
 #include "vm/SavedStacks.h"
 #include "vm/Stack.h"
--- a/js/src/builtin/Utilities.js
+++ b/js/src/builtin/Utilities.js
@@ -172,25 +172,16 @@ function GetTypeError(msg) {
     try {
         FUN_APPLY(ThrowTypeError, undefined, arguments);
     } catch (e) {
         return e;
     }
     assert(false, "the catch block should've returned from this function.");
 }
 
-function GetAggregateError(msg) {
-    try {
-        FUN_APPLY(ThrowAggregateError, undefined, arguments);
-    } catch (e) {
-        return e;
-    }
-    assert(false, "the catch block should've returned from this function.");
-}
-
 function GetInternalError(msg) {
     try {
         FUN_APPLY(ThrowInternalError, undefined, arguments);
     } catch (e) {
         return e;
     }
     assert(false, "the catch block should've returned from this function.");
 }
deleted file mode 100644
--- a/js/src/jit-test/tests/promise/promise-any-with-non-default-resolving.js
+++ /dev/null
@@ -1,58 +0,0 @@
-// |jit-test| skip-if: !Promise.any
-
-function newPromiseCapability() {
-    var resolve, reject, promise = new Promise(function(r1, r2) {
-        resolve = r1;
-        reject = r2;
-    });
-    return {promise, resolve, reject};
-}
-
-function neverCalled() {
-    // Quit with non-zero exit code to ensure a test suite error is shown,
-    // even when this function is called within promise handlers which normally
-    // swallow any exceptions.
-    quit(1);
-}
-
-var {promise, resolve} = newPromiseCapability();
-
-var getterCount = 0;
-
-class P extends Promise {
-    constructor(executor) {
-        var {promise, resolve, reject} = newPromiseCapability();
-
-        executor(function(v) {
-            // Resolve the promise.
-            resolve(v);
-
-            // But then return an object from the resolve function. This object
-            // must be treated as the resolution value for the otherwise
-            // skipped promise which gets created when Promise.prototype.then is
-            // called in PerformPromiseRace.
-            return {
-                get then() {
-                    getterCount++;
-                }
-            };
-        }, neverCalled);
-
-        return promise;
-    }
-
-    // Default to the standard Promise.resolve function, so we don't create
-    // another instance of this class when resolving the passed promise objects
-    // in Promise.race.
-    static resolve(v) {
-        return Promise.resolve(v);
-    }
-}
-
-P.any([promise]);
-
-resolve(0);
-
-drainJobQueue();
-
-assertEq(getterCount, 1);
--- a/js/src/jit/RangeAnalysis.cpp
+++ b/js/src/jit/RangeAnalysis.cpp
@@ -6,18 +6,16 @@
 
 #include "jit/RangeAnalysis.h"
 
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/TemplateLib.h"
 
 #include <algorithm>
 
-#include "jsnum.h"
-
 #include "jit/Ion.h"
 #include "jit/IonAnalysis.h"
 #include "jit/JitSpewer.h"
 #include "jit/MIR.h"
 #include "jit/MIRGenerator.h"
 #include "jit/MIRGraph.h"
 #include "js/Conversions.h"
 #include "vm/ArgumentsObject.h"
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -639,17 +639,16 @@ MSG_DEF(JSMSG_DYNAMIC_IMPORT_FAILED,    
 MSG_DEF(JSMSG_BAD_MODULE_SPECIFIER,      1, JSEXN_TYPEERR, "error resolving module specifier '{0}'")
 
 // Promise
 MSG_DEF(JSMSG_CANNOT_RESOLVE_PROMISE_WITH_ITSELF,       0, JSEXN_TYPEERR, "A promise cannot be resolved with itself.")
 MSG_DEF(JSMSG_PROMISE_CAPABILITY_HAS_SOMETHING_ALREADY, 0, JSEXN_TYPEERR, "GetCapabilitiesExecutor function already invoked with non-undefined values.")
 MSG_DEF(JSMSG_PROMISE_RESOLVE_FUNCTION_NOT_CALLABLE,    0, JSEXN_TYPEERR, "A Promise subclass passed a non-callable value as the resolve function.")
 MSG_DEF(JSMSG_PROMISE_REJECT_FUNCTION_NOT_CALLABLE,     0, JSEXN_TYPEERR, "A Promise subclass passed a non-callable value as the reject function.")
 MSG_DEF(JSMSG_PROMISE_ERROR_IN_WRAPPED_REJECTION_REASON,0, JSEXN_INTERNALERR, "Promise rejection value is a non-unwrappable cross-compartment wrapper.")
-MSG_DEF(JSMSG_PROMISE_ANY_REJECTION, 0, JSEXN_AGGREGATEERR, "No Promise in Promise.any was resolved")
 
 // Iterator
 MSG_DEF(JSMSG_RETURN_NOT_CALLABLE,     0, JSEXN_TYPEERR, "property 'return' of iterator is not callable")
 MSG_DEF(JSMSG_ITERATOR_NO_THROW,       0, JSEXN_TYPEERR, "iterator does not have a 'throw' method")
 
 // Async Function
 MSG_DEF(JSMSG_UNHANDLABLE_PROMISE_REJECTION_WARNING, 0, JSEXN_WARN, "unhandlable error after resolving async function's promise")
 
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -5,61 +5,171 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /*
  * JS standard exception implementation.
  */
 
 #include "jsexn.h"
 
-#include "mozilla/Assertions.h"
 #include "mozilla/ScopeExit.h"
+#include "mozilla/Sprintf.h"
 
-#include <new>
-#include <stdarg.h>
-#include <stdint.h>
-#include <stdio.h>
 #include <string.h>
 #include <utility>
 
 #include "jsapi.h"
-#include "jsfriendapi.h"
+#include "jsnum.h"
 #include "jstypes.h"
 
-#include "gc/Rooting.h"
+#include "gc/FreeOp.h"
+#include "gc/Marking.h"
 #include "js/CharacterEncoding.h"
-#include "js/Class.h"
-#include "js/Conversions.h"
+#include "js/PropertySpec.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"
 #include "vm/FrameIter.h"  // js::NonBuiltinFrameIter
-#include "vm/JSAtom.h"
+#include "vm/GlobalObject.h"
 #include "vm/JSContext.h"
+#include "vm/JSFunction.h"
 #include "vm/JSObject.h"
 #include "vm/JSScript.h"
-#include "vm/Realm.h"
-#include "vm/SavedFrame.h"
 #include "vm/SavedStacks.h"
 #include "vm/SelfHosting.h"
-#include "vm/Stack.h"
 #include "vm/StringType.h"
-#include "vm/SymbolType.h"
 
 #include "vm/ErrorObject-inl.h"
-#include "vm/JSContext-inl.h"
+#include "vm/JSObject-inl.h"
 #include "vm/SavedStacks-inl.h"
 
 using namespace js;
 
+static void exn_finalize(JSFreeOp* fop, JSObject* obj);
+
+static bool exn_toSource(JSContext* cx, unsigned argc, Value* vp);
+
+#define IMPLEMENT_ERROR_PROTO_CLASS(name)                        \
+  {                                                              \
+    js_Object_str, JSCLASS_HAS_CACHED_PROTO(JSProto_##name),     \
+        JS_NULL_CLASS_OPS,                                       \
+        &ErrorObject::classSpecs[JSProto_##name - JSProto_Error] \
+  }
+
+const JSClass ErrorObject::protoClasses[JSEXN_ERROR_LIMIT] = {
+    IMPLEMENT_ERROR_PROTO_CLASS(Error),
+
+    IMPLEMENT_ERROR_PROTO_CLASS(InternalError),
+    IMPLEMENT_ERROR_PROTO_CLASS(EvalError),
+    IMPLEMENT_ERROR_PROTO_CLASS(RangeError),
+    IMPLEMENT_ERROR_PROTO_CLASS(ReferenceError),
+    IMPLEMENT_ERROR_PROTO_CLASS(SyntaxError),
+    IMPLEMENT_ERROR_PROTO_CLASS(TypeError),
+    IMPLEMENT_ERROR_PROTO_CLASS(URIError),
+
+    IMPLEMENT_ERROR_PROTO_CLASS(DebuggeeWouldRun),
+    IMPLEMENT_ERROR_PROTO_CLASS(CompileError),
+    IMPLEMENT_ERROR_PROTO_CLASS(LinkError),
+    IMPLEMENT_ERROR_PROTO_CLASS(RuntimeError)};
+
+static const JSFunctionSpec error_methods[] = {
+    JS_FN(js_toSource_str, exn_toSource, 0, 0),
+    JS_SELF_HOSTED_FN(js_toString_str, "ErrorToString", 0, 0), JS_FS_END};
+
+static const JSPropertySpec error_properties[] = {
+    JS_STRING_PS("message", "", 0), JS_STRING_PS("name", "Error", 0),
+    // Only Error.prototype has .stack!
+    JS_PSGS("stack", ErrorObject::getStack, ErrorObject::setStack, 0),
+    JS_PS_END};
+
+#define IMPLEMENT_ERROR_PROPERTIES(name) \
+  { JS_STRING_PS("message", "", 0), JS_STRING_PS("name", #name, 0), JS_PS_END }
+
+static const JSPropertySpec other_error_properties[JSEXN_ERROR_LIMIT - 1][3] = {
+    IMPLEMENT_ERROR_PROPERTIES(InternalError),
+    IMPLEMENT_ERROR_PROPERTIES(EvalError),
+    IMPLEMENT_ERROR_PROPERTIES(RangeError),
+    IMPLEMENT_ERROR_PROPERTIES(ReferenceError),
+    IMPLEMENT_ERROR_PROPERTIES(SyntaxError),
+    IMPLEMENT_ERROR_PROPERTIES(TypeError),
+    IMPLEMENT_ERROR_PROPERTIES(URIError),
+    IMPLEMENT_ERROR_PROPERTIES(DebuggeeWouldRun),
+    IMPLEMENT_ERROR_PROPERTIES(CompileError),
+    IMPLEMENT_ERROR_PROPERTIES(LinkError),
+    IMPLEMENT_ERROR_PROPERTIES(RuntimeError)};
+
+#define IMPLEMENT_NATIVE_ERROR_SPEC(name)                                    \
+  {                                                                          \
+    ErrorObject::createConstructor, ErrorObject::createProto, nullptr,       \
+        nullptr, nullptr,                                                    \
+        other_error_properties[JSProto_##name - JSProto_Error - 1], nullptr, \
+        JSProto_Error                                                        \
+  }
+
+#define IMPLEMENT_NONGLOBAL_ERROR_SPEC(name)                                 \
+  {                                                                          \
+    ErrorObject::createConstructor, ErrorObject::createProto, nullptr,       \
+        nullptr, nullptr,                                                    \
+        other_error_properties[JSProto_##name - JSProto_Error - 1], nullptr, \
+        JSProto_Error | ClassSpec::DontDefineConstructor                     \
+  }
+
+const ClassSpec ErrorObject::classSpecs[JSEXN_ERROR_LIMIT] = {
+    {ErrorObject::createConstructor, ErrorObject::createProto, nullptr, nullptr,
+     error_methods, error_properties},
+
+    IMPLEMENT_NATIVE_ERROR_SPEC(InternalError),
+    IMPLEMENT_NATIVE_ERROR_SPEC(EvalError),
+    IMPLEMENT_NATIVE_ERROR_SPEC(RangeError),
+    IMPLEMENT_NATIVE_ERROR_SPEC(ReferenceError),
+    IMPLEMENT_NATIVE_ERROR_SPEC(SyntaxError),
+    IMPLEMENT_NATIVE_ERROR_SPEC(TypeError),
+    IMPLEMENT_NATIVE_ERROR_SPEC(URIError),
+
+    IMPLEMENT_NONGLOBAL_ERROR_SPEC(DebuggeeWouldRun),
+    IMPLEMENT_NONGLOBAL_ERROR_SPEC(CompileError),
+    IMPLEMENT_NONGLOBAL_ERROR_SPEC(LinkError),
+    IMPLEMENT_NONGLOBAL_ERROR_SPEC(RuntimeError)};
+
+#define IMPLEMENT_ERROR_CLASS(name)                                   \
+  {                                                                   \
+    js_Error_str, /* yes, really */                                   \
+        JSCLASS_HAS_CACHED_PROTO(JSProto_##name) |                    \
+            JSCLASS_HAS_RESERVED_SLOTS(ErrorObject::RESERVED_SLOTS) | \
+            JSCLASS_BACKGROUND_FINALIZE,                              \
+        &ErrorObjectClassOps,                                         \
+        &ErrorObject::classSpecs[JSProto_##name - JSProto_Error]      \
+  }
+
+static const JSClassOps ErrorObjectClassOps = {
+    nullptr,               /* addProperty */
+    nullptr,               /* delProperty */
+    nullptr,               /* enumerate */
+    nullptr,               /* newEnumerate */
+    nullptr,               /* resolve */
+    nullptr,               /* mayResolve */
+    exn_finalize, nullptr, /* call        */
+    nullptr,               /* hasInstance */
+    nullptr,               /* construct   */
+    nullptr,               /* trace       */
+};
+
+const JSClass ErrorObject::classes[JSEXN_ERROR_LIMIT] = {
+    IMPLEMENT_ERROR_CLASS(Error), IMPLEMENT_ERROR_CLASS(InternalError),
+    IMPLEMENT_ERROR_CLASS(EvalError), IMPLEMENT_ERROR_CLASS(RangeError),
+    IMPLEMENT_ERROR_CLASS(ReferenceError), IMPLEMENT_ERROR_CLASS(SyntaxError),
+    IMPLEMENT_ERROR_CLASS(TypeError), IMPLEMENT_ERROR_CLASS(URIError),
+    // These Error subclasses are not accessible via the global object:
+    IMPLEMENT_ERROR_CLASS(DebuggeeWouldRun),
+    IMPLEMENT_ERROR_CLASS(CompileError), IMPLEMENT_ERROR_CLASS(LinkError),
+    IMPLEMENT_ERROR_CLASS(RuntimeError)};
+
 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;
   }
@@ -202,17 +312,17 @@ struct SuppressErrorsGuard {
 
   ~SuppressErrorsGuard() { JS::SetWarningReporter(cx, prevReporter); }
 };
 
 // Cut off the stack if it gets too deep (most commonly for infinite recursion
 // errors).
 static const size_t MAX_REPORTED_STACK_DEPTH = 1u << 7;
 
-bool js::CaptureStack(JSContext* cx, MutableHandleObject stack) {
+static bool CaptureStack(JSContext* cx, MutableHandleObject stack) {
   return CaptureCurrentStack(
       cx, stack, JS::StackCapture(JS::MaxFrames(MAX_REPORTED_STACK_DEPTH)));
 }
 
 JSString* js::ComputeStackString(JSContext* cx) {
   SuppressErrorsGuard seg(cx);
 
   RootedObject stack(cx);
@@ -223,16 +333,24 @@ JSString* js::ComputeStackString(JSConte
   RootedString str(cx);
   if (!BuildStackString(cx, cx->realm()->principals(), stack, &str)) {
     return nullptr;
   }
 
   return str.get();
 }
 
+static void exn_finalize(JSFreeOp* fop, JSObject* obj) {
+  MOZ_ASSERT(fop->maybeOnHelperThread());
+  if (JSErrorReport* report = obj->as<ErrorObject>().getErrorReport()) {
+    // Bug 1560019: This allocation is not currently tracked.
+    fop->deleteUntracked(report);
+  }
+}
+
 JSErrorReport* js::ErrorFromException(JSContext* cx, HandleObject objArg) {
   // It's ok to UncheckedUnwrap here, since all we do is get the
   // JSErrorReport, and consumers are careful with the information they get
   // from that anyway.  Anyone doing things that would expose anything in the
   // JSErrorReport to page script either does a security check on the
   // JSErrorReport's principal or also tries to do toString on our object and
   // will fail if they can't unwrap it.
   RootedObject obj(cx, UncheckedUnwrap(objArg));
@@ -266,16 +384,222 @@ JS_PUBLIC_API uint64_t JS::ExceptionTime
   ErrorObject* obj = value.toObject().maybeUnwrapIf<ErrorObject>();
   if (!obj) {
     return 0;
   }
 
   return obj->timeWarpTarget();
 }
 
+bool Error(JSContext* cx, unsigned argc, Value* vp) {
+  CallArgs args = CallArgsFromVp(argc, vp);
+
+  // ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when
+  // called as functions, without operator new.  But as we do not give
+  // each constructor a distinct JSClass, we must get the exception type
+  // ourselves.
+  JSExnType exnType =
+      JSExnType(args.callee().as<JSFunction>().getExtendedSlot(0).toInt32());
+
+  JSProtoKey protoKey =
+      JSCLASS_CACHED_PROTO_KEY(&ErrorObject::classes[exnType]);
+
+  // ES6 19.5.1.1 mandates the .prototype lookup happens before the toString
+  RootedObject proto(cx);
+  if (!GetPrototypeFromBuiltinConstructor(cx, args, protoKey, &proto)) {
+    return false;
+  }
+
+  // Compute the error message, if any.
+  RootedString message(cx, nullptr);
+  if (args.hasDefined(0)) {
+    message = ToString<CanGC>(cx, args[0]);
+    if (!message) {
+      return false;
+    }
+  }
+
+  // Find the scripted caller, but only ones we're allowed to know about.
+  NonBuiltinFrameIter iter(cx, cx->realm()->principals());
+
+  RootedString fileName(cx);
+  uint32_t sourceId = 0;
+  if (args.length() > 1) {
+    fileName = ToString<CanGC>(cx, args[1]);
+  } else {
+    fileName = cx->runtime()->emptyString;
+    if (!iter.done()) {
+      if (const char* cfilename = iter.filename()) {
+        fileName = JS_NewStringCopyZ(cx, cfilename);
+      }
+      if (iter.hasScript()) {
+        sourceId = iter.script()->scriptSource()->id();
+      }
+    }
+  }
+  if (!fileName) {
+    return false;
+  }
+
+  uint32_t lineNumber, columnNumber = 0;
+  if (args.length() > 2) {
+    if (!ToUint32(cx, args[2], &lineNumber)) {
+      return false;
+    }
+  } else {
+    lineNumber = iter.done() ? 0 : iter.computeLine(&columnNumber);
+    columnNumber = FixupColumnForDisplay(columnNumber);
+  }
+
+  RootedObject stack(cx);
+  if (!CaptureStack(cx, &stack)) {
+    return false;
+  }
+
+  RootedObject obj(cx, ErrorObject::create(cx, exnType, stack, fileName,
+                                           sourceId, lineNumber, columnNumber,
+                                           nullptr, message, proto));
+  if (!obj) {
+    return false;
+  }
+
+  args.rval().setObject(*obj);
+  return true;
+}
+
+/*
+ * Return a string that may eval to something similar to the original object.
+ */
+static bool exn_toSource(JSContext* cx, unsigned argc, Value* vp) {
+  if (!CheckRecursionLimit(cx)) {
+    return false;
+  }
+  CallArgs args = CallArgsFromVp(argc, vp);
+
+  RootedObject obj(cx, ToObject(cx, args.thisv()));
+  if (!obj) {
+    return false;
+  }
+
+  RootedValue nameVal(cx);
+  RootedString name(cx);
+  if (!GetProperty(cx, obj, obj, cx->names().name, &nameVal) ||
+      !(name = ToString<CanGC>(cx, nameVal))) {
+    return false;
+  }
+
+  RootedValue messageVal(cx);
+  RootedString message(cx);
+  if (!GetProperty(cx, obj, obj, cx->names().message, &messageVal) ||
+      !(message = ValueToSource(cx, messageVal))) {
+    return false;
+  }
+
+  RootedValue filenameVal(cx);
+  RootedString filename(cx);
+  if (!GetProperty(cx, obj, obj, cx->names().fileName, &filenameVal) ||
+      !(filename = ValueToSource(cx, filenameVal))) {
+    return false;
+  }
+
+  RootedValue linenoVal(cx);
+  uint32_t lineno;
+  if (!GetProperty(cx, obj, obj, cx->names().lineNumber, &linenoVal) ||
+      !ToUint32(cx, linenoVal, &lineno)) {
+    return false;
+  }
+
+  JSStringBuilder sb(cx);
+  if (!sb.append("(new ") || !sb.append(name) || !sb.append("(")) {
+    return false;
+  }
+
+  if (!sb.append(message)) {
+    return false;
+  }
+
+  if (!filename->empty()) {
+    if (!sb.append(", ") || !sb.append(filename)) {
+      return false;
+    }
+  }
+  if (lineno != 0) {
+    /* We have a line, but no filename, add empty string */
+    if (filename->empty() && !sb.append(", \"\"")) {
+      return false;
+    }
+
+    JSString* linenumber = ToString<CanGC>(cx, linenoVal);
+    if (!linenumber) {
+      return false;
+    }
+    if (!sb.append(", ") || !sb.append(linenumber)) {
+      return false;
+    }
+  }
+
+  if (!sb.append("))")) {
+    return false;
+  }
+
+  JSString* str = sb.finishString();
+  if (!str) {
+    return false;
+  }
+  args.rval().setString(str);
+  return true;
+}
+
+/* static */
+JSObject* ErrorObject::createProto(JSContext* cx, JSProtoKey key) {
+  JSExnType type = ExnTypeFromProtoKey(key);
+
+  if (type == JSEXN_ERR) {
+    return GlobalObject::createBlankPrototype(
+        cx, cx->global(), &ErrorObject::protoClasses[JSEXN_ERR]);
+  }
+
+  RootedObject protoProto(
+      cx, GlobalObject::getOrCreateErrorPrototype(cx, cx->global()));
+  if (!protoProto) {
+    return nullptr;
+  }
+
+  return GlobalObject::createBlankPrototypeInheriting(
+      cx, &ErrorObject::protoClasses[type], protoProto);
+}
+
+/* static */
+JSObject* ErrorObject::createConstructor(JSContext* cx, JSProtoKey key) {
+  JSExnType type = ExnTypeFromProtoKey(key);
+  RootedObject ctor(cx);
+
+  if (type == JSEXN_ERR) {
+    ctor = GenericCreateConstructor<Error, 1, gc::AllocKind::FUNCTION_EXTENDED>(
+        cx, key);
+  } else {
+    RootedFunction proto(
+        cx, GlobalObject::getOrCreateErrorConstructor(cx, cx->global()));
+    if (!proto) {
+      return nullptr;
+    }
+
+    ctor = NewFunctionWithProto(
+        cx, Error, 1, FunctionFlags::NATIVE_CTOR, nullptr, ClassName(key, cx),
+        proto, gc::AllocKind::FUNCTION_EXTENDED, SingletonObject);
+  }
+
+  if (!ctor) {
+    return nullptr;
+  }
+
+  ctor->as<JSFunction>().setExtendedSlot(0, Int32Value(type));
+  return ctor;
+}
+
 JS_FRIEND_API JSLinearString* js::GetErrorTypeName(JSContext* cx,
                                                    int16_t exnType) {
   /*
    * JSEXN_INTERNALERR returns null to prevent that "InternalError: "
    * is prepended before "uncaught exception: "
    */
   if (exnType < 0 || exnType >= JSEXN_LIMIT || exnType == JSEXN_INTERNALERR ||
       exnType == JSEXN_WARN || exnType == JSEXN_NOTE) {
@@ -786,16 +1110,8 @@ bool js::GetInternalError(JSContext* cx,
 
 bool js::GetTypeError(JSContext* cx, unsigned errorNumber,
                       MutableHandleValue error) {
   FixedInvokeArgs<1> args(cx);
   args[0].set(Int32Value(errorNumber));
   return CallSelfHostedFunction(cx, cx->names().GetTypeError, NullHandleValue,
                                 args, error);
 }
-
-bool js::GetAggregateError(JSContext* cx, unsigned errorNumber,
-                           MutableHandleValue error) {
-  FixedInvokeArgs<1> args(cx);
-  args[0].set(Int32Value(errorNumber));
-  return CallSelfHostedFunction(cx, cx->names().GetAggregateError,
-                                NullHandleValue, args, error);
-}
--- a/js/src/jsexn.h
+++ b/js/src/jsexn.h
@@ -6,39 +6,30 @@
 
 /*
  * JS runtime exception classes.
  */
 
 #ifndef jsexn_h
 #define jsexn_h
 
-#include "mozilla/Assertions.h"
-
 #include "jsapi.h"
-#include "jspubtd.h"
-#include "jstypes.h"
 #include "NamespaceImports.h"
 
-#include "js/ErrorReport.h"
-#include "js/RootingAPI.h"
-#include "js/TypeDecls.h"
 #include "js/UniquePtr.h"
-#include "js/Utility.h"
+#include "vm/JSContext.h"
 
 namespace js {
 class ErrorObject;
 
 UniquePtr<JSErrorNotes::Note> CopyErrorNote(JSContext* cx,
                                             JSErrorNotes::Note* note);
 
 UniquePtr<JSErrorReport> CopyErrorReport(JSContext* cx, JSErrorReport* report);
 
-bool CaptureStack(JSContext* cx, MutableHandleObject stack);
-
 JSString* ComputeStackString(JSContext* cx);
 
 /*
  * Given a JSErrorReport, check to see if there is an exception associated with
  * the error number.  If there is, then create an appropriate exception object,
  * set it as the pending exception, and set the JSREPORT_EXCEPTION flag on the
  * error report.
  *
@@ -63,17 +54,16 @@ extern JSErrorReport* ErrorFromException
  * prototype objects (errobj->getPrivate() must not be nullptr).
  */
 extern JSObject* CopyErrorObject(JSContext* cx,
                                  JS::Handle<ErrorObject*> errobj);
 
 static_assert(
     JSEXN_ERR == 0 &&
         JSProto_Error + JSEXN_INTERNALERR == JSProto_InternalError &&
-        JSProto_Error + JSEXN_AGGREGATEERR == JSProto_AggregateError &&
         JSProto_Error + JSEXN_EVALERR == JSProto_EvalError &&
         JSProto_Error + JSEXN_RANGEERR == JSProto_RangeError &&
         JSProto_Error + JSEXN_REFERENCEERR == JSProto_ReferenceError &&
         JSProto_Error + JSEXN_SYNTAXERR == JSProto_SyntaxError &&
         JSProto_Error + JSEXN_TYPEERR == JSProto_TypeError &&
         JSProto_Error + JSEXN_URIERR == JSProto_URIError &&
         JSProto_Error + JSEXN_DEBUGGEEWOULDRUN == JSProto_DebuggeeWouldRun &&
         JSProto_Error + JSEXN_WASMCOMPILEERROR == JSProto_CompileError &&
@@ -114,14 +104,12 @@ class AutoClearPendingException {
 
 extern const char* ValueToSourceForError(JSContext* cx, HandleValue val,
                                          JS::UniqueChars& bytes);
 
 bool GetInternalError(JSContext* cx, unsigned errorNumber,
                       MutableHandleValue error);
 bool GetTypeError(JSContext* cx, unsigned errorNumber,
                   MutableHandleValue error);
-bool GetAggregateError(JSContext* cx, unsigned errorNumber,
-                       MutableHandleValue error);
 
 }  // namespace js
 
 #endif /* jsexn_h */
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -23,17 +23,16 @@
 #include "js/CharacterEncoding.h"
 #include "js/Printf.h"
 #include "js/Proxy.h"
 #include "js/Wrapper.h"
 #include "proxy/DeadObjectProxy.h"
 #include "util/Poison.h"
 #include "vm/ArgumentsObject.h"
 #include "vm/DateObject.h"
-#include "vm/ErrorObject.h"
 #include "vm/FrameIter.h"  // js::FrameIter
 #include "vm/JSContext.h"
 #include "vm/JSObject.h"
 #include "vm/Printer.h"
 #include "vm/Realm.h"
 #include "vm/Time.h"
 #include "vm/WrapperObject.h"
 
deleted file mode 100644
--- a/js/src/tests/non262/Error/AggregateError.js
+++ /dev/null
@@ -1,82 +0,0 @@
-// |reftest| skip-if(release_or_beta)
-
-assertEq(typeof AggregateError, "function");
-assertEq(Object.getPrototypeOf(AggregateError), Error);
-assertEq(AggregateError.name, "AggregateError");
-assertEq(AggregateError.length, 2);
-
-assertEq(Object.getPrototypeOf(AggregateError.prototype), Error.prototype);
-assertEq(AggregateError.prototype.name, "AggregateError");
-assertEq(AggregateError.prototype.message, "");
-
-// AggregateError.prototype isn't an AggregateError instance.
-assertThrowsInstanceOf(() => AggregateError.prototype.errors, TypeError);
-
-// The |errors| argument is mandatory.
-assertThrowsInstanceOf(() => new AggregateError(), TypeError);
-assertThrowsInstanceOf(() => AggregateError(), TypeError);
-
-// The .errors getter returns an array object.
-{
-  let err = new AggregateError([]);
-
-  let {errors} = err;
-  assertEq(Array.isArray(errors), true);
-  assertEq(errors.length, 0);
-
-  // A fresh object is returned each time calling the getter.
-  assertEq(errors === err.errors, false);
-
-  // The errors object is modifiable.
-  errors.push(123);
-  assertEq(errors.length, 1);
-  assertEq(errors[0], 123);
-}
-
-// The errors argument can be any iterable.
-{
-  function* g() { yield* [1, 2, 3]; }
-
-  let {errors} = new AggregateError(g());
-  assertEqArray(errors, [1, 2, 3]);
-}
-
-// The message property is populated by the second argument.
-{
-  let err;
-
-  err = new AggregateError([]);
-  assertEq(err.message, "");
-
-  err = new AggregateError([], "my message");
-  assertEq(err.message, "my message");
-}
-
-{
-  const {
-    get: getErrors,
-    set: setErrors,
-  } = Object.getOwnPropertyDescriptor(AggregateError.prototype, "errors");
-  assertEq(typeof getErrors, "function");
-  assertEq(typeof setErrors, "undefined");
-
-  // The |this| argument must be an AggregateError instance.
-  assertThrowsInstanceOf(() => getErrors.call(null), TypeError);
-  assertThrowsInstanceOf(() => getErrors.call({}), TypeError);
-  assertThrowsInstanceOf(() => getErrors.call(new Error), TypeError);
-
-  const g = newGlobal();
-
-  let obj = {};
-  let errors = getErrors.call(new g.AggregateError([obj]));
-
-  assertEq(errors.length, 1);
-  assertEq(errors[0], obj);
-
-  // The prototype is (incorrectly) |g.Array.prototype| in the cross-compartment case.
-  let proto = Object.getPrototypeOf(errors);
-  assertEq(proto === Array.prototype || proto === g.Array.prototype, true);
-}
-
-if (typeof reportCompare === "function")
-  reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/non262/Promise/any-stack.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// |reftest| skip-if(!Promise.any)
-
-function toMessage(stack) {
-  // Provide the stack string in the error message for debugging.
-  return `[stack: ${stack.replace(/\n/g, "\\n")}]`;
-}
-
-// Test when AggregateError isn't created from a Promise Job.
-{
-  let p = Promise.any([]); // line 10
-
-  p.then(v => {
-    reportCompare(0, 1, "expected error");
-  }, e => {
-    assertEq(e.name, "AggregateError");
-    var {stack} = e;
-
-    assertEq(/^@.+any-stack.js:10/m.test(stack), true, toMessage(stack));
-  });
-}
-
-// Same as above, but now with surrounding function context.
-function testNoJobQueue() {
-  let p = Promise.any([]); // line 24
-
-  p.then(v => {
-    reportCompare(0, 1, "expected error");
-  }, e => {
-    assertEq(e.name, "AggregateError");
-    var {stack} = e;
-
-    assertEq(/^testNoJobQueue@.+any-stack.js:24/m.test(stack), true, toMessage(stack));
-  });
-}
-testNoJobQueue();
-
-// Test when AggregateError is created from a Promise Job.
-{
-  let rejected = Promise.reject(0);
-  let p = Promise.any([rejected]); // line 40
-
-  p.then(v => {
-    reportCompare(0, 1, "expected error");
-  }, e => {
-    assertEq(e.name, "AggregateError");
-    var {stack} = e;
-
-    assertEq(/^Promise.any\*@.+any-stack.js:40/m.test(stack), true, toMessage(stack));
-  });
-}
-
-// Same as above, but now with surrounding function context.
-function testFromJobQueue() {
-  let rejected = Promise.reject(0);
-  let p = Promise.any([rejected]); // line 55
-
-  p.then(v => {
-    reportCompare(0, 1, "expected error");
-  }, e => {
-    assertEq(e.name, "AggregateError");
-    var {stack} = e;
-
-    assertEq(/^Promise.any\*testFromJobQueue@.+any-stack.js:55/m.test(stack), true, toMessage(stack));
-  });
-}
-testFromJobQueue();
-
-if (typeof reportCompare === "function")
-  reportCompare(0, 0);
deleted file mode 100644
--- a/js/src/tests/non262/Promise/any.js
+++ /dev/null
@@ -1,78 +0,0 @@
-// |reftest| skip-if(!Promise.any)
-
-// Smoke test for `Promise.any`, test262 should cover the function in
-// more detail.
-
-function expectedError() {
-  reportCompare(true, false, "expected error");
-}
-
-// Empty elements.
-Promise.any([]).then(expectedError, e => {
-  assertEq(e instanceof AggregateError, true);
-  assertEq(e.errors.length, 0);
-});
-
-// Single element.
-Promise.any([Promise.resolve(0)]).then(v => {
-  assertEq(v, 0);
-});
-Promise.any([Promise.reject(1)]).then(expectedError, e => {
-  assertEq(e instanceof AggregateError, true);
-  assertEq(e.errors.length, 1);
-  assertEq(e.errors[0], 1);
-});
-
-// Multiple elements.
-Promise.any([Promise.resolve(1), Promise.resolve(2)]).then(v => {
-  assertEq(v, 1);
-});
-Promise.any([Promise.resolve(3), Promise.reject(4)]).then(v => {
-  assertEq(v, 3);
-});
-Promise.any([Promise.reject(5), Promise.resolve(6)]).then(v => {
-  assertEq(v, 6);
-});
-Promise.any([Promise.reject(7), Promise.reject(8)]).then(expectedError, e => {
-  assertEq(e instanceof AggregateError, true);
-  assertEq(e.errors.length, 2);
-  assertEq(e.errors[0], 7);
-  assertEq(e.errors[1], 8);
-});
-
-// Cross-Realm tests.
-//
-// Note: When |g| is a cross-compartment global, Promise.any creates the errors
-// array and the AggregateError in |g|'s Realm. This doesn't follow the spec, but
-// the code in js/src/builtin/Promise.cpp claims this is useful when the Promise
-// compartment is less-privileged. This means for this test we can't use
-// assertDeepEq below, because the result array/error may have the wrong prototype.
-let g = newGlobal();
-
-if (typeof isSameCompartment !== "function") {
-  var isSameCompartment = SpecialPowers.Cu.getJSTestingFunctions().isSameCompartment;
-}
-
-// Test wrapping when no `Promise.any Reject Element Function` is called.
-Promise.any.call(g.Promise, []).then(expectedError, e => {
-  assertEq(e.name, "AggregateError");
-
-  assertEq(isSameCompartment(e, g), true);
-  assertEq(isSameCompartment(e.errors, g), true);
-
-  assertEq(e.errors.length, 0);
-});
-
-// Test wrapping in `Promise.any Reject Element Function`.
-Promise.any.call(g.Promise, [Promise.reject("err")]).then(expectedError, e => {
-  assertEq(e.name, "AggregateError");
-
-  assertEq(isSameCompartment(e, g), true);
-  assertEq(isSameCompartment(e.errors, g), true);
-
-  assertEq(e.errors.length, 1);
-  assertEq(e.errors[0], "err");
-});
-
-if (typeof reportCompare === "function")
-  reportCompare(0, 0);
--- a/js/src/vm/CommonPropertyNames.h
+++ b/js/src/vm/CommonPropertyNames.h
@@ -180,17 +180,16 @@
   MACRO(futexOK, futexOK, "ok")                                                \
   MACRO(futexTimedOut, futexTimedOut, "timed-out")                             \
   MACRO(gcCycleNumber, gcCycleNumber, "gcCycleNumber")                         \
   MACRO(Generator, Generator, "Generator")                                     \
   MACRO(GeneratorNext, GeneratorNext, "GeneratorNext")                         \
   MACRO(GeneratorReturn, GeneratorReturn, "GeneratorReturn")                   \
   MACRO(GeneratorThrow, GeneratorThrow, "GeneratorThrow")                      \
   MACRO(get, get, "get")                                                       \
-  MACRO(GetAggregateError, GetAggregateError, "GetAggregateError")             \
   MACRO(GetInternalError, GetInternalError, "GetInternalError")                \
   MACRO(getBigInt64, getBigInt64, "getBigInt64")                               \
   MACRO(getBigUint64, getBigUint64, "getBigUint64")                            \
   MACRO(getInternals, getInternals, "getInternals")                            \
   MACRO(GetModuleNamespace, GetModuleNamespace, "GetModuleNamespace")          \
   MACRO(getOwnPropertyDescriptor, getOwnPropertyDescriptor,                    \
         "getOwnPropertyDescriptor")                                            \
   MACRO(getOwnPropertyNames, getOwnPropertyNames, "getOwnPropertyNames")       \
--- a/js/src/vm/ErrorObject.cpp
+++ b/js/src/vm/ErrorObject.cpp
@@ -2,419 +2,35 @@
  * vim: set ts=8 sw=2 et tw=80:
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "vm/ErrorObject-inl.h"
 
-#include "mozilla/Assertions.h"
-#include "mozilla/Attributes.h"
-#include "mozilla/DebugOnly.h"
-#include "mozilla/RecordReplay.h"
+#include "mozilla/Range.h"
 
 #include <utility>
 
-#include "jsapi.h"
 #include "jsexn.h"
-#include "jsfriendapi.h"
-#include "jsnum.h"
-#include "jspubtd.h"
-#include "NamespaceImports.h"
 
-#include "builtin/Array.h"
-#include "gc/AllocKind.h"
-#include "gc/FreeOp.h"
-#include "gc/Rooting.h"
 #include "js/CallArgs.h"
-#include "js/CallNonGenericMethod.h"
 #include "js/CharacterEncoding.h"
-#include "js/Class.h"
-#include "js/Conversions.h"
-#include "js/ErrorReport.h"
-#include "js/ForOfIterator.h"
-#include "js/PropertySpec.h"
-#include "js/RootingAPI.h"
-#include "js/TypeDecls.h"
-#include "js/Utility.h"
-#include "js/Value.h"
-#include "js/Wrapper.h"
-#include "util/StringBuffer.h"
 #include "vm/GlobalObject.h"
-#include "vm/JSAtom.h"
-#include "vm/JSFunction.h"
-#include "vm/JSObject.h"
-#include "vm/NativeObject.h"
-#include "vm/ObjectGroup.h"
-#include "vm/ObjectOperations.h"
-#include "vm/SavedStacks.h"
 #include "vm/SelfHosting.h"
-#include "vm/Shape.h"
-#include "vm/Stack.h"
 #include "vm/StringType.h"
 
-#include "vm/ArrayObject-inl.h"
-#include "vm/JSContext-inl.h"
 #include "vm/JSObject-inl.h"
 #include "vm/NativeObject-inl.h"
-#include "vm/ObjectOperations-inl.h"
 #include "vm/SavedStacks-inl.h"
 #include "vm/Shape-inl.h"
 
 using namespace js;
 
-#define IMPLEMENT_ERROR_PROTO_CLASS(name)                        \
-  {                                                              \
-    js_Object_str, JSCLASS_HAS_CACHED_PROTO(JSProto_##name),     \
-        JS_NULL_CLASS_OPS,                                       \
-        &ErrorObject::classSpecs[JSProto_##name - JSProto_Error] \
-  }
-
-const JSClass ErrorObject::protoClasses[JSEXN_ERROR_LIMIT] = {
-    IMPLEMENT_ERROR_PROTO_CLASS(Error),
-
-    IMPLEMENT_ERROR_PROTO_CLASS(InternalError),
-    IMPLEMENT_ERROR_PROTO_CLASS(AggregateError),
-    IMPLEMENT_ERROR_PROTO_CLASS(EvalError),
-    IMPLEMENT_ERROR_PROTO_CLASS(RangeError),
-    IMPLEMENT_ERROR_PROTO_CLASS(ReferenceError),
-    IMPLEMENT_ERROR_PROTO_CLASS(SyntaxError),
-    IMPLEMENT_ERROR_PROTO_CLASS(TypeError),
-    IMPLEMENT_ERROR_PROTO_CLASS(URIError),
-
-    IMPLEMENT_ERROR_PROTO_CLASS(DebuggeeWouldRun),
-    IMPLEMENT_ERROR_PROTO_CLASS(CompileError),
-    IMPLEMENT_ERROR_PROTO_CLASS(LinkError),
-    IMPLEMENT_ERROR_PROTO_CLASS(RuntimeError)};
-
-static bool exn_toSource(JSContext* cx, unsigned argc, Value* vp);
-
-static const JSFunctionSpec error_methods[] = {
-    JS_FN(js_toSource_str, exn_toSource, 0, 0),
-    JS_SELF_HOSTED_FN(js_toString_str, "ErrorToString", 0, 0), JS_FS_END};
-
-// Error.prototype and NativeError.prototype have own .message and .name
-// properties.
-#define COMMON_ERROR_PROPERTIES(name) \
-  JS_STRING_PS("message", "", 0), JS_STRING_PS("name", #name, 0)
-
-static const JSPropertySpec error_properties[] = {
-    COMMON_ERROR_PROPERTIES(Error),
-    // Only Error.prototype has .stack!
-    JS_PSGS("stack", ErrorObject::getStack, ErrorObject::setStack, 0),
-    JS_PS_END};
-
-static const JSPropertySpec AggregateError_properties[] = {
-    COMMON_ERROR_PROPERTIES(AggregateError),
-    // Only AggregateError.prototype has .errors!
-    JS_PSG("errors", AggregateErrorObject::getErrors, 0), JS_PS_END};
-
-#define IMPLEMENT_NATIVE_ERROR_PROPERTIES(name)       \
-  static const JSPropertySpec name##_properties[] = { \
-      COMMON_ERROR_PROPERTIES(name), JS_PS_END};
-
-IMPLEMENT_NATIVE_ERROR_PROPERTIES(InternalError)
-IMPLEMENT_NATIVE_ERROR_PROPERTIES(EvalError)
-IMPLEMENT_NATIVE_ERROR_PROPERTIES(RangeError)
-IMPLEMENT_NATIVE_ERROR_PROPERTIES(ReferenceError)
-IMPLEMENT_NATIVE_ERROR_PROPERTIES(SyntaxError)
-IMPLEMENT_NATIVE_ERROR_PROPERTIES(TypeError)
-IMPLEMENT_NATIVE_ERROR_PROPERTIES(URIError)
-IMPLEMENT_NATIVE_ERROR_PROPERTIES(DebuggeeWouldRun)
-IMPLEMENT_NATIVE_ERROR_PROPERTIES(CompileError)
-IMPLEMENT_NATIVE_ERROR_PROPERTIES(LinkError)
-IMPLEMENT_NATIVE_ERROR_PROPERTIES(RuntimeError)
-
-#define IMPLEMENT_NATIVE_ERROR_SPEC(name)                              \
-  {                                                                    \
-    ErrorObject::createConstructor, ErrorObject::createProto, nullptr, \
-        nullptr, nullptr, name##_properties, nullptr, JSProto_Error    \
-  }
-
-#define IMPLEMENT_NONGLOBAL_ERROR_SPEC(name)                           \
-  {                                                                    \
-    ErrorObject::createConstructor, ErrorObject::createProto, nullptr, \
-        nullptr, nullptr, name##_properties, nullptr,                  \
-        JSProto_Error | ClassSpec::DontDefineConstructor               \
-  }
-
-const ClassSpec ErrorObject::classSpecs[JSEXN_ERROR_LIMIT] = {
-    {ErrorObject::createConstructor, ErrorObject::createProto, nullptr, nullptr,
-     error_methods, error_properties},
-
-    IMPLEMENT_NATIVE_ERROR_SPEC(InternalError),
-    IMPLEMENT_NATIVE_ERROR_SPEC(AggregateError),
-    IMPLEMENT_NATIVE_ERROR_SPEC(EvalError),
-    IMPLEMENT_NATIVE_ERROR_SPEC(RangeError),
-    IMPLEMENT_NATIVE_ERROR_SPEC(ReferenceError),
-    IMPLEMENT_NATIVE_ERROR_SPEC(SyntaxError),
-    IMPLEMENT_NATIVE_ERROR_SPEC(TypeError),
-    IMPLEMENT_NATIVE_ERROR_SPEC(URIError),
-
-    IMPLEMENT_NONGLOBAL_ERROR_SPEC(DebuggeeWouldRun),
-    IMPLEMENT_NONGLOBAL_ERROR_SPEC(CompileError),
-    IMPLEMENT_NONGLOBAL_ERROR_SPEC(LinkError),
-    IMPLEMENT_NONGLOBAL_ERROR_SPEC(RuntimeError)};
-
-#define IMPLEMENT_ERROR_CLASS_FROM(clazz, name)                  \
-  {                                                              \
-    js_Error_str, /* yes, really */                              \
-        JSCLASS_HAS_CACHED_PROTO(JSProto_##name) |               \
-            JSCLASS_HAS_RESERVED_SLOTS(clazz::RESERVED_SLOTS) |  \
-            JSCLASS_BACKGROUND_FINALIZE,                         \
-        &ErrorObjectClassOps,                                    \
-        &ErrorObject::classSpecs[JSProto_##name - JSProto_Error] \
-  }
-
-#define IMPLEMENT_ERROR_CLASS(name) \
-  IMPLEMENT_ERROR_CLASS_FROM(ErrorObject, name)
-
-static void exn_finalize(JSFreeOp* fop, JSObject* obj);
-
-static const JSClassOps ErrorObjectClassOps = {
-    nullptr,               /* addProperty */
-    nullptr,               /* delProperty */
-    nullptr,               /* enumerate */
-    nullptr,               /* newEnumerate */
-    nullptr,               /* resolve */
-    nullptr,               /* mayResolve */
-    exn_finalize, nullptr, /* call        */
-    nullptr,               /* hasInstance */
-    nullptr,               /* construct   */
-    nullptr,               /* trace       */
-};
-
-const JSClass ErrorObject::classes[JSEXN_ERROR_LIMIT] = {
-    IMPLEMENT_ERROR_CLASS(Error), IMPLEMENT_ERROR_CLASS(InternalError),
-    IMPLEMENT_ERROR_CLASS_FROM(AggregateErrorObject, AggregateError),
-    IMPLEMENT_ERROR_CLASS(EvalError), IMPLEMENT_ERROR_CLASS(RangeError),
-    IMPLEMENT_ERROR_CLASS(ReferenceError), IMPLEMENT_ERROR_CLASS(SyntaxError),
-    IMPLEMENT_ERROR_CLASS(TypeError), IMPLEMENT_ERROR_CLASS(URIError),
-    // These Error subclasses are not accessible via the global object:
-    IMPLEMENT_ERROR_CLASS(DebuggeeWouldRun),
-    IMPLEMENT_ERROR_CLASS(CompileError), IMPLEMENT_ERROR_CLASS(LinkError),
-    IMPLEMENT_ERROR_CLASS(RuntimeError)};
-
-static void exn_finalize(JSFreeOp* fop, JSObject* obj) {
-  MOZ_ASSERT(fop->maybeOnHelperThread());
-  if (JSErrorReport* report = obj->as<ErrorObject>().getErrorReport()) {
-    // Bug 1560019: This allocation is not currently tracked.
-    fop->deleteUntracked(report);
-  }
-}
-
-static ErrorObject* CreateErrorObject(JSContext* cx, const CallArgs& args,
-                                      unsigned messageArg, JSExnType exnType,
-                                      HandleObject proto) {
-  // Compute the error message, if any.
-  RootedString message(cx, nullptr);
-  if (args.hasDefined(messageArg)) {
-    message = ToString<CanGC>(cx, args[messageArg]);
-    if (!message) {
-      return nullptr;
-    }
-  }
-
-  // Find the scripted caller, but only ones we're allowed to know about.
-  NonBuiltinFrameIter iter(cx, cx->realm()->principals());
-
-  RootedString fileName(cx);
-  uint32_t sourceId = 0;
-  if (args.length() > messageArg + 1) {
-    fileName = ToString<CanGC>(cx, args[messageArg + 1]);
-  } else {
-    fileName = cx->runtime()->emptyString;
-    if (!iter.done()) {
-      if (const char* cfilename = iter.filename()) {
-        fileName = JS_NewStringCopyZ(cx, cfilename);
-      }
-      if (iter.hasScript()) {
-        sourceId = iter.script()->scriptSource()->id();
-      }
-    }
-  }
-  if (!fileName) {
-    return nullptr;
-  }
-
-  uint32_t lineNumber, columnNumber = 0;
-  if (args.length() > messageArg + 2) {
-    if (!ToUint32(cx, args[messageArg + 2], &lineNumber)) {
-      return nullptr;
-    }
-  } else {
-    lineNumber = iter.done() ? 0 : iter.computeLine(&columnNumber);
-    columnNumber = FixupColumnForDisplay(columnNumber);
-  }
-
-  RootedObject stack(cx);
-  if (!CaptureStack(cx, &stack)) {
-    return nullptr;
-  }
-
-  return ErrorObject::create(cx, exnType, stack, fileName, sourceId, lineNumber,
-                             columnNumber, nullptr, message, proto);
-}
-
-static bool Error(JSContext* cx, unsigned argc, Value* vp) {
-  CallArgs args = CallArgsFromVp(argc, vp);
-
-  // ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when
-  // called as functions, without operator new.  But as we do not give
-  // each constructor a distinct JSClass, we must get the exception type
-  // ourselves.
-  JSExnType exnType =
-      JSExnType(args.callee().as<JSFunction>().getExtendedSlot(0).toInt32());
-
-  MOZ_ASSERT(exnType != JSEXN_AGGREGATEERR,
-             "AggregateError has its own constructor function");
-
-  JSProtoKey protoKey =
-      JSCLASS_CACHED_PROTO_KEY(&ErrorObject::classes[exnType]);
-
-  // ES6 19.5.1.1 mandates the .prototype lookup happens before the toString
-  RootedObject proto(cx);
-  if (!GetPrototypeFromBuiltinConstructor(cx, args, protoKey, &proto)) {
-    return false;
-  }
-
-  auto* obj = CreateErrorObject(cx, args, 0, exnType, proto);
-  if (!obj) {
-    return false;
-  }
-
-  args.rval().setObject(*obj);
-  return true;
-}
-
-static ArrayObject* IterableToArray(JSContext* cx, HandleValue iterable) {
-  JS::ForOfIterator iterator(cx);
-  if (!iterator.init(iterable, JS::ForOfIterator::ThrowOnNonIterable)) {
-    return nullptr;
-  }
-
-  RootedArrayObject array(cx, NewDenseEmptyArray(cx));
-
-  RootedValue nextValue(cx);
-  while (true) {
-    bool done;
-    if (!iterator.next(&nextValue, &done)) {
-      return nullptr;
-    }
-    if (done) {
-      return array;
-    }
-
-    if (!NewbornArrayPush(cx, array, nextValue)) {
-      return nullptr;
-    }
-  }
-}
-
-// AggregateError ( errors, message )
-static bool AggregateError(JSContext* cx, unsigned argc, Value* vp) {
-  CallArgs args = CallArgsFromVp(argc, vp);
-
-  mozilla::DebugOnly<JSExnType> exnType =
-      JSExnType(args.callee().as<JSFunction>().getExtendedSlot(0).toInt32());
-
-  MOZ_ASSERT(exnType == JSEXN_AGGREGATEERR);
-
-  // Steps 1-2. (9.1.13 OrdinaryCreateFromConstructor, steps 1-2).
-  RootedObject proto(cx);
-  if (!GetPrototypeFromBuiltinConstructor(cx, args, JSProto_AggregateError,
-                                          &proto)) {
-    return false;
-  }
-
-  // Step 3 (Inlined IterableToList).
-
-  if (!args.requireAtLeast(cx, "AggregateError", 1)) {
-    return false;
-  }
-
-  RootedArrayObject errorsList(cx, IterableToArray(cx, args.get(0)));
-  if (!errorsList) {
-    return false;
-  }
-
-  // 9.1.13 OrdinaryCreateFromConstructor, step 3.
-  // Step 5.
-  auto* obj = CreateErrorObject(cx, args, 1, JSEXN_AGGREGATEERR, proto);
-  if (!obj) {
-    return false;
-  }
-
-  // Step 4.
-  obj->as<AggregateErrorObject>().setAggregateErrors(errorsList);
-
-  // Step 6.
-  args.rval().setObject(*obj);
-  return true;
-}
-
-/* static */
-JSObject* ErrorObject::createProto(JSContext* cx, JSProtoKey key) {
-  JSExnType type = ExnTypeFromProtoKey(key);
-
-  if (type == JSEXN_ERR) {
-    return GlobalObject::createBlankPrototype(
-        cx, cx->global(), &ErrorObject::protoClasses[JSEXN_ERR]);
-  }
-
-  RootedObject protoProto(
-      cx, GlobalObject::getOrCreateErrorPrototype(cx, cx->global()));
-  if (!protoProto) {
-    return nullptr;
-  }
-
-  return GlobalObject::createBlankPrototypeInheriting(
-      cx, &ErrorObject::protoClasses[type], protoProto);
-}
-
-/* static */
-JSObject* ErrorObject::createConstructor(JSContext* cx, JSProtoKey key) {
-  JSExnType type = ExnTypeFromProtoKey(key);
-  RootedObject ctor(cx);
-
-  if (type == JSEXN_ERR) {
-    ctor = GenericCreateConstructor<Error, 1, gc::AllocKind::FUNCTION_EXTENDED>(
-        cx, key);
-  } else {
-    RootedFunction proto(
-        cx, GlobalObject::getOrCreateErrorConstructor(cx, cx->global()));
-    if (!proto) {
-      return nullptr;
-    }
-
-    Native native;
-    unsigned nargs;
-    if (type == JSEXN_AGGREGATEERR) {
-      native = AggregateError;
-      nargs = 2;
-    } else {
-      native = Error;
-      nargs = 1;
-    }
-
-    ctor =
-        NewFunctionWithProto(cx, native, nargs, FunctionFlags::NATIVE_CTOR,
-                             nullptr, ClassName(key, cx), proto,
-                             gc::AllocKind::FUNCTION_EXTENDED, SingletonObject);
-  }
-
-  if (!ctor) {
-    return nullptr;
-  }
-
-  ctor->as<JSFunction>().setExtendedSlot(0, Int32Value(type));
-  return ctor;
-}
-
 /* static */
 Shape* js::ErrorObject::assignInitialShape(JSContext* cx,
                                            Handle<ErrorObject*> obj) {
   MOZ_ASSERT(obj->empty());
 
   if (!NativeObject::addDataProperty(cx, obj, cx->names().fileName,
                                      FILENAME_SLOT, 0)) {
     return nullptr;
@@ -693,159 +309,8 @@ bool js::ErrorObject::setStack_impl(JSCo
 
   if (!args.requireAtLeast(cx, "(set stack)", 1)) {
     return false;
   }
   RootedValue val(cx, args[0]);
 
   return DefineDataProperty(cx, thisObj, cx->names().stack, val);
 }
-
-/*
- * Return a string that may eval to something similar to the original object.
- */
-static bool exn_toSource(JSContext* cx, unsigned argc, Value* vp) {
-  if (!CheckRecursionLimit(cx)) {
-    return false;
-  }
-  CallArgs args = CallArgsFromVp(argc, vp);
-
-  RootedObject obj(cx, ToObject(cx, args.thisv()));
-  if (!obj) {
-    return false;
-  }
-
-  RootedValue nameVal(cx);
-  RootedString name(cx);
-  if (!GetProperty(cx, obj, obj, cx->names().name, &nameVal) ||
-      !(name = ToString<CanGC>(cx, nameVal))) {
-    return false;
-  }
-
-  RootedValue messageVal(cx);
-  RootedString message(cx);
-  if (!GetProperty(cx, obj, obj, cx->names().message, &messageVal) ||
-      !(message = ValueToSource(cx, messageVal))) {
-    return false;
-  }
-
-  RootedValue filenameVal(cx);
-  RootedString filename(cx);
-  if (!GetProperty(cx, obj, obj, cx->names().fileName, &filenameVal) ||
-      !(filename = ValueToSource(cx, filenameVal))) {
-    return false;
-  }
-
-  RootedValue linenoVal(cx);
-  uint32_t lineno;
-  if (!GetProperty(cx, obj, obj, cx->names().lineNumber, &linenoVal) ||
-      !ToUint32(cx, linenoVal, &lineno)) {
-    return false;
-  }
-
-  JSStringBuilder sb(cx);
-  if (!sb.append("(new ") || !sb.append(name) || !sb.append("(")) {
-    return false;
-  }
-
-  if (!sb.append(message)) {
-    return false;
-  }
-
-  if (!filename->empty()) {
-    if (!sb.append(", ") || !sb.append(filename)) {
-      return false;
-    }
-  }
-  if (lineno != 0) {
-    /* We have a line, but no filename, add empty string */
-    if (filename->empty() && !sb.append(", \"\"")) {
-      return false;
-    }
-
-    JSString* linenumber = ToString<CanGC>(cx, linenoVal);
-    if (!linenumber) {
-      return false;
-    }
-    if (!sb.append(", ") || !sb.append(linenumber)) {
-      return false;
-    }
-  }
-
-  if (!sb.append("))")) {
-    return false;
-  }
-
-  JSString* str = sb.finishString();
-  if (!str) {
-    return false;
-  }
-  args.rval().setString(str);
-  return true;
-}
-
-ArrayObject* js::AggregateErrorObject::aggregateErrors() const {
-  const Value& val = getReservedSlot(AGGREGATE_ERRORS_SLOT);
-  if (val.isUndefined()) {
-    return nullptr;
-  }
-  return &val.toObject().as<ArrayObject>();
-}
-
-void js::AggregateErrorObject::setAggregateErrors(ArrayObject* errors) {
-  MOZ_ASSERT(!aggregateErrors(),
-             "aggregated errors mustn't be modified once set");
-  setReservedSlot(AGGREGATE_ERRORS_SLOT, ObjectValue(*errors));
-}
-
-static inline bool IsAggregateError(HandleValue v) {
-  return v.isObject() && v.toObject().is<AggregateErrorObject>();
-}
-
-// get AggregateError.prototype.errors
-bool js::AggregateErrorObject::getErrors(JSContext* cx, unsigned argc,
-                                         Value* vp) {
-  CallArgs args = CallArgsFromVp(argc, vp);
-
-  // Steps 1-4.
-  return CallNonGenericMethod<IsAggregateError, getErrors_impl>(cx, args);
-}
-
-// get AggregateError.prototype.errors
-bool js::AggregateErrorObject::getErrors_impl(JSContext* cx,
-                                              const CallArgs& args) {
-  MOZ_ASSERT(IsAggregateError(args.thisv()));
-
-  auto* obj = &args.thisv().toObject().as<AggregateErrorObject>();
-
-  // Step 5.
-  // Create a copy of the [[AggregateErrors]] list.
-
-  RootedArrayObject errorsList(cx, obj->aggregateErrors());
-
-  // [[AggregateErrors]] may be absent when this error was created through
-  // JS_ReportError.
-  if (!errorsList) {
-    ArrayObject* result = NewDenseEmptyArray(cx);
-    if (!result) {
-      return false;
-    }
-
-    args.rval().setObject(*result);
-    return true;
-  }
-
-  uint32_t length = errorsList->length();
-
-  ArrayObject* result = NewDenseFullyAllocatedArray(cx, length);
-  if (!result) {
-    return false;
-  }
-
-  result->setLength(cx, length);
-
-  if (length > 0) {
-    result->initDenseElements(errorsList, 0, length);
-  }
-
-  args.rval().setObject(*result);
-  return true;
-}
--- a/js/src/vm/ErrorObject.h
+++ b/js/src/vm/ErrorObject.h
@@ -3,42 +3,37 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_ErrorObject_h_
 #define vm_ErrorObject_h_
 
 #include "mozilla/ArrayUtils.h"
-#include "mozilla/Assertions.h"
 
-#include <stdint.h>
-
-#include "jspubtd.h"
-#include "NamespaceImports.h"
-
-#include "gc/Barrier.h"
-#include "js/Class.h"
-#include "js/ErrorReport.h"
-#include "js/RootingAPI.h"
-#include "js/TypeDecls.h"
 #include "js/UniquePtr.h"
-#include "js/Value.h"
-#include "vm/JSObject.h"
 #include "vm/NativeObject.h"
+#include "vm/SavedStacks.h"
 #include "vm/Shape.h"
 
 namespace js {
-class ArrayObject;
+
+/*
+ * Initialize the exception constructor/prototype hierarchy.
+ */
+extern JSObject* InitExceptionClasses(JSContext* cx, HandleObject obj);
 
 class ErrorObject : public NativeObject {
   static JSObject* createProto(JSContext* cx, JSProtoKey key);
 
   static JSObject* createConstructor(JSContext* cx, JSProtoKey key);
 
+  /* For access to createProto. */
+  friend JSObject* js::InitExceptionClasses(JSContext* cx, HandleObject global);
+
   static bool init(JSContext* cx, Handle<ErrorObject*> obj, JSExnType type,
                    UniquePtr<JSErrorReport> errorReport, HandleString fileName,
                    HandleObject stack, uint32_t sourceId, uint32_t lineNumber,
                    uint32_t columnNumber, HandleString message);
 
   static const ClassSpec classSpecs[JSEXN_ERROR_LIMIT];
   static const JSClass protoClasses[JSEXN_ERROR_LIMIT];
 
@@ -114,37 +109,16 @@ class ErrorObject : public NativeObject 
 
   // Getter and setter for the Error.prototype.stack accessor.
   static bool getStack(JSContext* cx, unsigned argc, Value* vp);
   static bool getStack_impl(JSContext* cx, const CallArgs& args);
   static bool setStack(JSContext* cx, unsigned argc, Value* vp);
   static bool setStack_impl(JSContext* cx, const CallArgs& args);
 };
 
-class AggregateErrorObject : public ErrorObject {
-  friend class ErrorObject;
-
-  // [[AggregateErrors]] slot of AggregateErrorObjects.
-  static const uint32_t AGGREGATE_ERRORS_SLOT = ErrorObject::RESERVED_SLOTS;
-  static const uint32_t RESERVED_SLOTS = AGGREGATE_ERRORS_SLOT + 1;
-
- public:
-  ArrayObject* aggregateErrors() const;
-  void setAggregateErrors(ArrayObject* errors);
-
-  // Getter for the AggregateError.prototype.errors accessor.
-  static bool getErrors(JSContext* cx, unsigned argc, Value* vp);
-  static bool getErrors_impl(JSContext* cx, const CallArgs& args);
-};
-
 }  // namespace js
 
 template <>
 inline bool JSObject::is<js::ErrorObject>() const {
   return js::ErrorObject::isErrorClass(getClass());
 }
 
-template <>
-inline bool JSObject::is<js::AggregateErrorObject>() const {
-  return hasClass(js::ErrorObject::classForType(JSEXN_AGGREGATEERR));
-}
-
 #endif  // vm_ErrorObject_h_
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -44,17 +44,16 @@
 #include "builtin/WeakSetObject.h"
 #include "debugger/DebugAPI.h"
 #include "gc/FreeOp.h"
 #include "js/ProtoKey.h"
 #include "vm/AsyncFunction.h"
 #include "vm/AsyncIteration.h"
 #include "vm/DateObject.h"
 #include "vm/EnvironmentObject.h"
-#include "vm/ErrorObject.h"
 #include "vm/GeneratorObject.h"
 #include "vm/HelperThreads.h"
 #include "vm/JSContext.h"
 #include "vm/PIC.h"
 #include "vm/RegExpStatics.h"
 #include "vm/RegExpStaticsObject.h"
 
 #include "gc/FreeOp-inl.h"
@@ -136,21 +135,16 @@ bool GlobalObject::skipDeselectedConstru
     // Return true if the given constructor has been disabled at run-time.
     case JSProto_Atomics:
     case JSProto_SharedArrayBuffer:
       return !cx->realm()->creationOptions().getSharedMemoryAndAtomicsEnabled();
 
     case JSProto_FinalizationGroup:
       return !cx->realm()->creationOptions().getWeakRefsEnabled();
 
-#ifndef NIGHTLY_BUILD
-    case JSProto_AggregateError:
-      return true;
-#endif
-
     default:
       return false;
   }
 }
 
 /* static*/
 bool GlobalObject::resolveConstructor(JSContext* cx,
                                       Handle<GlobalObject*> global,
--- a/js/src/vm/GlobalObject.h
+++ b/js/src/vm/GlobalObject.h
@@ -2,62 +2,33 @@
  * vim: set ts=8 sts=2 et sw=2 tw=80:
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_GlobalObject_h
 #define vm_GlobalObject_h
 
-#include "mozilla/Assertions.h"
-#include "mozilla/DebugOnly.h"
-
-#include <stdint.h>
-#include <type_traits>
-
-#include "jsapi.h"
 #include "jsexn.h"
-#include "jsfriendapi.h"
-#include "jspubtd.h"
-#include "jstypes.h"
-#include "NamespaceImports.h"
+#include "jsnum.h"
 
-#include "gc/AllocKind.h"
-#include "gc/Rooting.h"
-#include "js/CallArgs.h"
-#include "js/Class.h"
-#include "js/ErrorReport.h"
-#include "js/PropertyDescriptor.h"
-#include "js/RootingAPI.h"
-#include "js/TypeDecls.h"
-#include "js/Value.h"
-#include "vm/JSContext.h"
+#include "builtin/Array.h"
+#include "builtin/Boolean.h"
+#include "js/Vector.h"
+#include "vm/ArrayBufferObject.h"
+#include "vm/ErrorObject.h"
 #include "vm/JSFunction.h"
-#include "vm/JSObject.h"
-#include "vm/NativeObject.h"
 #include "vm/Realm.h"
 #include "vm/Runtime.h"
-#include "vm/Shape.h"
-#include "vm/StringType.h"
-
-struct JSFunctionSpec;
-struct JSPrincipals;
-struct JSPropertySpec;
-
-namespace JS {
-class JS_PUBLIC_API RealmOptions;
-};
 
 namespace js {
 
-class GlobalScope;
+class TypedObjectModuleObject;
 class LexicalEnvironmentObject;
 class RegExpStatics;
-class TypeDescr;
-class TypedObjectModuleObject;
 
 enum class ReferenceType;
 
 /*
  * Global object slots are reserved as follows:
  *
  * [0, APPLICATION_SLOTS)
  *   Pre-reserved slots in all global objects set aside for the embedding's
@@ -951,16 +922,19 @@ extern bool LinkConstructorAndPrototype(
 /*
  * Define properties and/or functions on any object. Either ps or fs, or both,
  * may be null.
  */
 extern bool DefinePropertiesAndFunctions(JSContext* cx, HandleObject obj,
                                          const JSPropertySpec* ps,
                                          const JSFunctionSpec* fs);
 
+typedef HashSet<GlobalObject*, DefaultHasher<GlobalObject*>, SystemAllocPolicy>
+    GlobalObjectSet;
+
 extern bool DefineToStringTag(JSContext* cx, HandleObject obj, JSAtom* tag);
 
 /*
  * Convenience templates to generic constructor and prototype creation functions
  * for ClassSpecs.
  */
 
 template <JSNative ctor, unsigned length, gc::AllocKind kind,
--- a/js/src/vm/JSContext.cpp
+++ b/js/src/vm/JSContext.cpp
@@ -45,17 +45,16 @@
 #ifdef JS_SIMULATOR_ARM
 #  include "jit/arm/Simulator-arm.h"
 #endif
 #include "util/DiagnosticAssertions.h"
 #include "util/DoubleToString.h"
 #include "util/NativeStack.h"
 #include "util/Windows.h"
 #include "vm/BytecodeUtil.h"
-#include "vm/ErrorObject.h"
 #include "vm/ErrorReporting.h"
 #include "vm/HelperThreads.h"
 #include "vm/Iteration.h"
 #include "vm/JSAtom.h"
 #include "vm/JSFunction.h"
 #include "vm/JSObject.h"
 #include "vm/JSScript.h"
 #include "vm/Realm.h"
@@ -1398,19 +1397,23 @@ void JSContext::setPendingException(Hand
   // overRecursed_ is set after the fact by ReportOverRecursed.
   this->overRecursed_ = false;
   this->throwing = true;
   this->unwrappedException() = v;
   this->unwrappedExceptionStack() = stack;
   check(v);
 }
 
+static const size_t MAX_REPORTED_STACK_DEPTH = 1u << 7;
+
 void JSContext::setPendingExceptionAndCaptureStack(HandleValue value) {
   RootedObject stack(this);
-  if (!CaptureStack(this, &stack)) {
+  if (!CaptureCurrentStack(
+          this, &stack,
+          JS::StackCapture(JS::MaxFrames(MAX_REPORTED_STACK_DEPTH)))) {
     clearPendingException();
   }
 
   RootedSavedFrame nstack(this);
   if (stack) {
     nstack = &stack->as<SavedFrame>();
   }
   setPendingException(value, nstack);
--- a/js/src/vm/ObjectGroup.cpp
+++ b/js/src/vm/ObjectGroup.cpp
@@ -14,17 +14,16 @@
 #include "builtin/DataViewObject.h"
 #include "gc/FreeOp.h"
 #include "gc/HashUtil.h"
 #include "gc/Policy.h"
 #include "gc/StoreBuffer.h"
 #include "js/CharacterEncoding.h"
 #include "js/UniquePtr.h"
 #include "vm/ArrayObject.h"
-#include "vm/ErrorObject.h"
 #include "vm/GlobalObject.h"
 #include "vm/JSObject.h"
 #include "vm/RegExpObject.h"
 #include "vm/Shape.h"
 #include "vm/TaggedProto.h"
 
 #include "gc/Marking-inl.h"
 #include "gc/ObjectKind-inl.h"
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -386,25 +386,16 @@ static bool intrinsic_ThrowSyntaxError(J
                                        Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   MOZ_ASSERT(args.length() >= 1);
 
   ThrowErrorWithType(cx, JSEXN_SYNTAXERR, args);
   return false;
 }
 
-static bool intrinsic_ThrowAggregateError(JSContext* cx, unsigned argc,
-                                          Value* vp) {
-  CallArgs args = CallArgsFromVp(argc, vp);
-  MOZ_ASSERT(args.length() >= 1);
-
-  ThrowErrorWithType(cx, JSEXN_AGGREGATEERR, args);
-  return false;
-}
-
 static bool intrinsic_ThrowInternalError(JSContext* cx, unsigned argc,
                                          Value* vp) {
   CallArgs args = CallArgsFromVp(argc, vp);
   MOZ_ASSERT(args.length() >= 1);
 
   ThrowErrorWithType(cx, JSEXN_INTERNALERR, args);
   return false;
 }
@@ -2173,17 +2164,16 @@ static const JSFunctionSpec intrinsic_fu
     JS_INLINABLE_FN("IsConstructor", intrinsic_IsConstructor, 1, 0,
                     IntrinsicIsConstructor),
     JS_FN("GetBuiltinConstructorImpl", intrinsic_GetBuiltinConstructor, 1, 0),
     JS_FN("MakeConstructible", intrinsic_MakeConstructible, 2, 0),
     JS_FN("_ConstructFunction", intrinsic_ConstructFunction, 2, 0),
     JS_FN("ThrowRangeError", intrinsic_ThrowRangeError, 4, 0),
     JS_FN("ThrowTypeError", intrinsic_ThrowTypeError, 4, 0),
     JS_FN("ThrowSyntaxError", intrinsic_ThrowSyntaxError, 4, 0),
-    JS_FN("ThrowAggregateError", intrinsic_ThrowAggregateError, 4, 0),
     JS_FN("ThrowInternalError", intrinsic_ThrowInternalError, 4, 0),
     JS_FN("GetErrorMessage", intrinsic_GetErrorMessage, 1, 0),
     JS_FN("CreateModuleSyntaxError", intrinsic_CreateModuleSyntaxError, 4, 0),
     JS_FN("AssertionFailed", intrinsic_AssertionFailed, 1, 0),
     JS_FN("DumpMessage", intrinsic_DumpMessage, 1, 0),
     JS_FN("MakeDefaultConstructor", intrinsic_MakeDefaultConstructor, 2, 0),
     JS_FN("_ConstructorForTypedArray", intrinsic_ConstructorForTypedArray, 1,
           0),
--- a/js/src/wasm/WasmCode.cpp
+++ b/js/src/wasm/WasmCode.cpp
@@ -18,18 +18,16 @@
 
 #include "wasm/WasmCode.h"
 
 #include "mozilla/BinarySearch.h"
 #include "mozilla/EnumeratedRange.h"
 
 #include <algorithm>
 
-#include "jsnum.h"
-
 #include "jit/ExecutableAllocator.h"
 #ifdef JS_ION_PERF
 #  include "jit/PerfSpewer.h"
 #endif
 #include "util/Poison.h"
 #ifdef MOZ_VTUNE
 #  include "vtune/VTuneWrapper.h"
 #endif
--- a/js/src/wasm/WasmJS.cpp
+++ b/js/src/wasm/WasmJS.cpp
@@ -30,17 +30,16 @@
 #include "gc/FreeOp.h"
 #include "jit/AtomicOperations.h"
 #include "jit/JitOptions.h"
 #include "jit/Simulator.h"
 #include "js/Printf.h"
 #include "js/PropertySpec.h"  // JS_{PS,FN}{,_END}
 #include "util/StringBuffer.h"
 #include "util/Text.h"
-#include "vm/ErrorObject.h"
 #include "vm/Interpreter.h"
 #include "vm/StringType.h"
 #include "wasm/WasmBaselineCompile.h"
 #include "wasm/WasmCompile.h"
 #include "wasm/WasmCraneliftCompile.h"
 #include "wasm/WasmInstance.h"
 #include "wasm/WasmIonCompile.h"
 #include "wasm/WasmModule.h"
--- a/js/xpconnect/tests/chrome/test_xrayToJS.xhtml
+++ b/js/xpconnect/tests/chrome/test_xrayToJS.xhtml
@@ -27,48 +27,30 @@ https://bugzilla.mozilla.org/show_bug.cg
       f();
       ok(false, "Should have thrown: " + msg);
     } catch (e) {
       ok(true, "Threw as expected: " + msg);
       ok(rgxp.test(e), "Message correct: " + e);
     }
   }
 
-  var {AppConstants} = SpecialPowers.Cu.import("resource://gre/modules/AppConstants.jsm", {});
-  var isNightlyBuild = AppConstants.NIGHTLY_BUILD;
-  var isReleaseOrBeta = AppConstants.RELEASE_OR_BETA;
-
   typedArrayClasses = ['Uint8Array', 'Int8Array', 'Uint16Array', 'Int16Array',
                        'Uint32Array', 'Int32Array', 'Float32Array', 'Float64Array',
                        'Uint8ClampedArray'];
   errorObjectClasses = ['Error', 'InternalError', 'EvalError', 'RangeError', 'ReferenceError',
                         'SyntaxError', 'TypeError', 'URIError'];
-  if (isNightlyBuild) {
-    errorObjectClasses.push('AggregateError');
-  }
 
   // A simpleConstructors entry can either be the name of a constructor as a
   // string, or an object containing the properties `name`, and `args`.
   // In the former case, the constructor is invoked without any args; in the
   // latter case, it is invoked with `args` as the arguments list.
   simpleConstructors = ['Object', 'Function', 'Array', 'Boolean', 'Date', 'Number',
                         'String', 'RegExp', 'ArrayBuffer', 'WeakMap', 'WeakSet', 'Map', 'Set',
-                        {name: 'Promise', args: [function(){}]}];
-
-  // All TypedArray constructors can be called with zero arguments.
-  simpleConstructors = simpleConstructors.concat(typedArrayClasses);
-
-  // All Error constructors except AggregateError can be called with zero arguments.
-  simpleConstructors = simpleConstructors.concat(errorObjectClasses.map(name) => {
-    if (name === 'AggregateError') {
-      // AggregateError throws when called without an iterable object as its first argument.
-      return {name: 'AggregateError', args: [[]]};
-    }
-    return name;
-  });
+                        {name: 'Promise', args: [function(){}]}].concat(typedArrayClasses)
+                                                                .concat(errorObjectClasses);
 
   function go() {
     window.iwin = document.getElementById('ifr').contentWindow;
 
     // Test constructors that can be instantiated with zero arguments, or with
     // a fixed set of arguments provided using `...rest`.
     for (var c of simpleConstructors) {
       var args = [];
@@ -180,16 +162,19 @@ https://bugzilla.mozilla.org/show_bug.cg
     SimpleTest.finish();
   }
 
   // Maintain a static list of the properties that are available on each standard
   // prototype, so that we make sure to audit any new ones to make sure they're
   // Xray-safe.
   //
   // DO NOT CHANGE WTIHOUT REVIEW FROM AN XPCONNECT PEER.
+  var {AppConstants} = SpecialPowers.Cu.import("resource://gre/modules/AppConstants.jsm", {});
+  var isNightlyBuild = AppConstants.NIGHTLY_BUILD;
+  var isReleaseOrBeta = AppConstants.RELEASE_OR_BETA;
   var gPrototypeProperties = {};
   var gConstructorProperties = {};
   function constructorProps(arr) {
     // Some props live on all constructors
     return arr.concat(["prototype", "length", "name"]);
   }
   gPrototypeProperties['Date'] =
     ["getTime", "getTimezoneOffset", "getYear", "getFullYear", "getUTCFullYear",
@@ -234,19 +219,16 @@ https://bugzilla.mozilla.org/show_bug.cg
      "reverse", "join", "every", "some", "reduce", "reduceRight", "entries", "keys", "values",
      "slice", "map", "filter"];
   // There is no TypedArray constructor, looks like.
   is(window.TypedArray, undefined, "If this ever changes, add to this test!");
   for (var c of errorObjectClasses) {
       gPrototypeProperties[c] = ["constructor", "name", "message", "stack"];
       gConstructorProperties[c] = constructorProps([]);
   }
-  if (gPrototypeProperties['AggregateError']) {
-      gPrototypeProperties['AggregateError'].push("errors");
-  }
   // toString and toSource only live on the parent proto (Error.prototype).
   gPrototypeProperties['Error'].push('toString');
   gPrototypeProperties['Error'].push('toSource');
 
   gPrototypeProperties['Function'] =
     ["constructor", "toSource", "toString", "apply", "call", "bind",
      "length", "name", "arguments", "caller", Symbol.hasInstance];
   gConstructorProperties['Function'] = constructorProps([])
@@ -260,19 +242,16 @@ https://bugzilla.mozilla.org/show_bug.cg
                       "leftContext", "rightContext", "$1", "$2", "$3", "$4",
                       "$5", "$6", "$7", "$8", "$9", "$_", "$&", "$+",
                       "$`", "$'", Symbol.species])
 
   gPrototypeProperties['Promise'] =
     ["constructor", "catch", "then", "finally", Symbol.toStringTag];
   gConstructorProperties['Promise'] =
     constructorProps(["resolve", "reject", "all", "allSettled", "race", Symbol.species]);
-  if (isNightlyBuild) {
-    gConstructorProperties['Promise'].push("any");
-  }
 
   gPrototypeProperties['ArrayBuffer'] =
     ["constructor", "byteLength", "slice", Symbol.toStringTag];
   gConstructorProperties['ArrayBuffer'] =
     constructorProps(["isView", Symbol.species]);
 
   is(typeof SharedArrayBuffer, "undefined", "Enable tests!");
 
@@ -832,54 +811,33 @@ https://bugzilla.mozilla.org/show_bug.cg
   function testErrorObjects() {
     // We only invoke testXray with Error, because that function isn't set up
     // to deal with dependent classes and fixing it up is more trouble than
     // it's worth.
     testXray('Error', new iwin.Error('some error message'), new iwin.Error());
 
     // Make sure that the dependent classes have their prototypes set up correctly.
     for (let c of errorObjectClasses.filter(x => x != "Error")) {
-      var args = ['some message'];
-      if (c === 'AggregateError') {
-        // AggregateError's first argument is the list of aggregated errors.
-        args.unshift(['error 1', 'error 2']);
-      }
-      var e = new iwin[c](...args);
+      var e = new iwin[c]('some message');
       is(Object.getPrototypeOf(e).name, c, "Prototype has correct name");
       is(Object.getPrototypeOf(Object.getPrototypeOf(e)), iwin.Error.prototype, "Dependent prototype set up correctly");
       is(e.name, c, "Exception name inherited correctly");
 
       function testProperty(name, criterion, goodReplacement, faultyReplacement) {
         ok(criterion(e[name]), name + " property is correct: " + e[name]);
         e.wrappedJSObject[name] = goodReplacement;
         is(e[name], goodReplacement, name + " property ok after replacement: " + goodReplacement);
         e.wrappedJSObject[name] = faultyReplacement;
         is(e[name], name == 'message' ? "" : undefined, name + " property skipped after suspicious replacement");
       }
       testProperty('message', x => x == 'some message', 'some other message', 42);
       testProperty('fileName', x => x == '', 'otherFilename.html', new iwin.Object());
       testProperty('columnNumber', x => x == 1, 99, 99.5);
       testProperty('lineNumber', x => x == 0, 50, 'foo');
 
-      if (c === 'AggregateError') {
-        let {errors} = e;
-        is(errors.length, 2, "errors property has the correct length");
-        is(errors[0], 'error 1', "errors[0] has the correct value");
-        is(errors[1], 'error 2', "errors[1] has the correct value");
-
-        try {
-          e.wrappedJSObject.errors = [];
-
-          throw new Error("Missing exception");
-        } catch (exc) {
-          is(exc.name, "TypeError", "setting the errors property throws a TypeError");
-        }
-        is(e.errors.length, 2, "errors property can't be set");
-      }
-
       // Note - an Exception newed via Xrays is going to have an empty stack given the
       // current semantics and implementation. This tests the current behavior, but that
       // may change in bug 1036527 or similar.
       //
       // Furthermore, xrays should always return an error's original stack, and
       // not overwrite it.
       var stack = e.stack;
       ok(/^\s*$/.test(stack), "stack property should be correct");
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -40,25 +40,25 @@ using js::UncheckedUnwrap;
 using js::Wrapper;
 
 namespace xpc {
 
 using namespace XrayUtils;
 
 #define Between(x, a, b) (a <= x && x <= b)
 
-static_assert(JSProto_URIError - JSProto_Error == 8,
+static_assert(JSProto_URIError - JSProto_Error == 7,
               "New prototype added in error object range");
 #define AssertErrorObjectKeyInBounds(key)                      \
   static_assert(Between(key, JSProto_Error, JSProto_URIError), \
                 "We depend on js/ProtoKey.h ordering here");
 MOZ_FOR_EACH(AssertErrorObjectKeyInBounds, (),
-             (JSProto_Error, JSProto_InternalError, JSProto_AggregateError,
-              JSProto_EvalError, JSProto_RangeError, JSProto_ReferenceError,
-              JSProto_SyntaxError, JSProto_TypeError, JSProto_URIError));
+             (JSProto_Error, JSProto_InternalError, JSProto_EvalError,
+              JSProto_RangeError, JSProto_ReferenceError, JSProto_SyntaxError,
+              JSProto_TypeError, JSProto_URIError));
 
 static_assert(JSProto_Uint8ClampedArray - JSProto_Int8Array == 8,
               "New prototype added in typed array range");
 #define AssertTypedArrayKeyInBounds(key)                                    \
   static_assert(Between(key, JSProto_Int8Array, JSProto_Uint8ClampedArray), \
                 "We depend on js/ProtoKey.h ordering here");
 MOZ_FOR_EACH(AssertTypedArrayKeyInBounds, (),
              (JSProto_Int8Array, JSProto_Uint8Array, JSProto_Int16Array,