Implement Promise.any and AggregateError
authordrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 17 Apr 2020 19:31:08 +0000 (19:31 +0000)
committerdrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 17 Apr 2020 19:31:08 +0000 (19:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=202566

Reviewed by Yusuke Suzuki.

JSTests:

* test262/config.yaml:
* test262/expectations.yaml:

Source/JavaScriptCore:

`Promise.any` resolves when any of the given `promises` resolve, but only rejects if _all_
of the given `promises` reject. In order to support aggregating all of the `reason` values
for all of the rejections, a new error type `AggregateError` is introduced which has an
`get errors` that returns an aggregated array of the `reason` values.

* builtins/PromiseConstructor.js:
(all.newResolveElement):
(allSettled.newResolveRejectElements):
(any): Added.
(any.newRejectElement): Added.
* runtime/JSPromiseConstructor.cpp:

* builtins/BuiltinNames.h:
* bytecode/LinkTimeConstant.h:
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::errorStructure const):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::initializeAggregateErrorConstructor): Added.
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
Expose `@AggregateError` for builtins.

* runtime/AggregateError.h: Added.
(JSC::AggregateError::destroy):
(JSC::AggregateError::subspaceFor):
(JSC::AggregateError::createStructure):
(JSC::AggregateError::create):
(JSC::AggregateError::errors const):
* runtime/AggregateError.cpp: Added.
(JSC::AggregateError::AggregateError):
(JSC::AggregateError::visitChildren):
(JSC::AggregateError::create):
(JSC::AggregateError::finishCreation):
* runtime/AggregateErrorPrototype.h: Added.
* runtime/AggregateErrorPrototype.cpp: Added.
(JSC::AggregateErrorPrototype::AggregateErrorPrototype):
(JSC::AggregateErrorPrototype::finishCreation):
(JSC::aggregateErrorPrototypeAccessorErrors):
* runtime/AggregateErrorConstructor.h: Added.
* runtime/AggregateErrorConstructor.cpp: Added.
(JSC::callAggregateErrorConstructor):
(JSC::constructAggregateErrorConstructor):
(JSC::AggregateErrorConstructor::AggregateErrorConstructor):
(JSC::AggregateErrorConstructor::finishCreation):
* runtime/ErrorType.h:
* runtime/ErrorType.cpp:
(JSC::errorTypeName):

* runtime/VM.h:
* runtime/VM.cpp:
(JSC::VM::VM):
Make an `IsoSubspace` for `AggregateError` as it has a different size than `ErrorInstance`.

* runtime/ErrorInstance.h:
(JSC::ErrorInstance::create):
* runtime/ErrorInstance.cpp:
(JSC::ErrorInstance::finishCreation):
* wasm/js/JSWebAssemblyCompileError.cpp:
(JSC::JSWebAssemblyCompileError::create):
* wasm/js/JSWebAssemblyLinkError.cpp:
(JSC::JSWebAssemblyLinkError::create):
* wasm/js/JSWebAssemblyRuntimeError.cpp:
(JSC::JSWebAssemblyRuntimeError::create):
Assign to `ErrorInstance` member variables inside `ErrorInstance::finishCreation` instead of
inside `ErrorInstance::create` so that subclasses don't have to do the work as well.

* runtime/Error.cpp:
(JSC::createError):

* runtime/ErrorPrototype.h:
(JSC::ErrorPrototype::createStructure):
* runtime/NativeErrorPrototype.h:
(JSC::NativeErrorPrototype::createStructure):
Drive-by: fix incorrect usage of `ErrorInstanceType` since `ErrorPrototype` does not inherit
          from `ErrorInstance` (and therefore neither does `NativeErrorPrototype`).

* runtime/ArgList.h:
Add `WTF_MAKE_NONMOVABLE` to `MarkedArgumentBuffer`.

* Sources.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:

Source/WebInspectorUI:

* UserInterface/Models/IssueMessage.js:
Mark `AggregateError` as a `WI.IssueMessage.Type.SemanticIssue`.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@260273 268f45cc-cd09-0410-ab3c-d52691b4dbfc

34 files changed:
JSTests/ChangeLog
JSTests/test262/config.yaml
JSTests/test262/expectations.yaml
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/Sources.txt
Source/JavaScriptCore/builtins/BuiltinNames.h
Source/JavaScriptCore/builtins/PromiseConstructor.js
Source/JavaScriptCore/bytecode/LinkTimeConstant.h
Source/JavaScriptCore/heap/Heap.cpp
Source/JavaScriptCore/runtime/AggregateError.cpp [new file with mode: 0644]
Source/JavaScriptCore/runtime/AggregateError.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/AggregateErrorConstructor.cpp [new file with mode: 0644]
Source/JavaScriptCore/runtime/AggregateErrorConstructor.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/AggregateErrorPrototype.cpp [new file with mode: 0644]
Source/JavaScriptCore/runtime/AggregateErrorPrototype.h [new file with mode: 0644]
Source/JavaScriptCore/runtime/ArgList.h
Source/JavaScriptCore/runtime/Error.cpp
Source/JavaScriptCore/runtime/ErrorInstance.cpp
Source/JavaScriptCore/runtime/ErrorInstance.h
Source/JavaScriptCore/runtime/ErrorPrototype.h
Source/JavaScriptCore/runtime/ErrorType.cpp
Source/JavaScriptCore/runtime/ErrorType.h
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/JSPromiseConstructor.cpp
Source/JavaScriptCore/runtime/NativeErrorPrototype.h
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyCompileError.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyLinkError.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyRuntimeError.cpp
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Models/IssueMessage.js

index 592992d..f216d7c 100644 (file)
@@ -1,3 +1,13 @@
+2020-04-17  Devin Rousso  <drousso@apple.com>
+
+        Implement Promise.any and AggregateError
+        https://bugs.webkit.org/show_bug.cgi?id=202566
+
+        Reviewed by Yusuke Suzuki.
+
+        * test262/config.yaml:
+        * test262/expectations.yaml:
+
 2020-04-17  Paulo Matos  <pmatos@igalia.com>
 
         Reduce test iterations for stress/array-buffer-view-watchpoint-can-be-fired-in-really-add-in-dfg.js on mips
index 244f705..a0366ce 100644 (file)
@@ -21,9 +21,6 @@ skip:
     # https://bugs.webkit.org/show_bug.cgi?id=202475
     - regexp-match-indices
     - top-level-await
-    # https://bugs.webkit.org/show_bug.cgi?id=202566
-    - Promise.any
-    - AggregateError
     - FinalizationRegistry
     - Intl.DateTimeFormat-datetimestyle
     - Intl.DateTimeFormat-dayPeriod
index f4f37aa..53e43d7 100644 (file)
@@ -1165,18 +1165,15 @@ test/built-ins/Object/values/order-after-define-property.js:
 test/built-ins/Promise/all/invoke-resolve-get-error-close.js:
   default: 'Test262Error: Expected SameValue(«0», «1») to be true'
   strict mode: 'Test262Error: Expected SameValue(«0», «1») to be true'
-test/built-ins/Promise/all/resolve-element-function-nonconstructor.js:
-  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
-  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
 test/built-ins/Promise/allSettled/invoke-resolve-get-error-close.js:
   default: 'Test262Error: Expected SameValue(«0», «1») to be true'
   strict mode: 'Test262Error: Expected SameValue(«0», «1») to be true'
 test/built-ins/Promise/allSettled/reject-element-function-nonconstructor.js:
   default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
   strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
-test/built-ins/Promise/allSettled/resolve-element-function-nonconstructor.js:
-  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
-  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
+test/built-ins/Promise/any/invoke-resolve-get-error-close.js:
+  default: 'Test262:AsyncTestFailure:Test262Error: Test262Error: Expected SameValue(«0», «1») to be true'
+  strict mode: 'Test262:AsyncTestFailure:Test262Error: Test262Error: Expected SameValue(«0», «1») to be true'
 test/built-ins/Promise/create-resolving-functions-reject.js:
   default: 'Test262:AsyncTestFailure:Test262Error: Test262Error: Expected true but got false'
   strict mode: 'Test262:AsyncTestFailure:Test262Error: Test262Error: Expected true but got false'
index 349f727..287b3bb 100644 (file)
@@ -1,3 +1,92 @@
+2020-04-17  Devin Rousso  <drousso@apple.com>
+
+        Implement Promise.any and AggregateError
+        https://bugs.webkit.org/show_bug.cgi?id=202566
+
+        Reviewed by Yusuke Suzuki.
+
+        `Promise.any` resolves when any of the given `promises` resolve, but only rejects if _all_
+        of the given `promises` reject. In order to support aggregating all of the `reason` values
+        for all of the rejections, a new error type `AggregateError` is introduced which has an
+        `get errors` that returns an aggregated array of the `reason` values.
+
+        * builtins/PromiseConstructor.js:
+        (all.newResolveElement):
+        (allSettled.newResolveRejectElements):
+        (any): Added.
+        (any.newRejectElement): Added.
+        * runtime/JSPromiseConstructor.cpp:
+
+        * builtins/BuiltinNames.h:
+        * bytecode/LinkTimeConstant.h:
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::errorStructure const):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::initializeAggregateErrorConstructor): Added.
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        Expose `@AggregateError` for builtins.
+
+        * runtime/AggregateError.h: Added.
+        (JSC::AggregateError::destroy):
+        (JSC::AggregateError::subspaceFor):
+        (JSC::AggregateError::createStructure):
+        (JSC::AggregateError::create):
+        (JSC::AggregateError::errors const):
+        * runtime/AggregateError.cpp: Added.
+        (JSC::AggregateError::AggregateError):
+        (JSC::AggregateError::visitChildren):
+        (JSC::AggregateError::create):
+        (JSC::AggregateError::finishCreation):
+        * runtime/AggregateErrorPrototype.h: Added.
+        * runtime/AggregateErrorPrototype.cpp: Added.
+        (JSC::AggregateErrorPrototype::AggregateErrorPrototype):
+        (JSC::AggregateErrorPrototype::finishCreation):
+        (JSC::aggregateErrorPrototypeAccessorErrors):
+        * runtime/AggregateErrorConstructor.h: Added.
+        * runtime/AggregateErrorConstructor.cpp: Added.
+        (JSC::callAggregateErrorConstructor):
+        (JSC::constructAggregateErrorConstructor):
+        (JSC::AggregateErrorConstructor::AggregateErrorConstructor):
+        (JSC::AggregateErrorConstructor::finishCreation):
+        * runtime/ErrorType.h:
+        * runtime/ErrorType.cpp:
+        (JSC::errorTypeName):
+
+        * runtime/VM.h:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        Make an `IsoSubspace` for `AggregateError` as it has a different size than `ErrorInstance`.
+
+        * runtime/ErrorInstance.h:
+        (JSC::ErrorInstance::create):
+        * runtime/ErrorInstance.cpp:
+        (JSC::ErrorInstance::finishCreation):
+        * wasm/js/JSWebAssemblyCompileError.cpp:
+        (JSC::JSWebAssemblyCompileError::create):
+        * wasm/js/JSWebAssemblyLinkError.cpp:
+        (JSC::JSWebAssemblyLinkError::create):
+        * wasm/js/JSWebAssemblyRuntimeError.cpp:
+        (JSC::JSWebAssemblyRuntimeError::create):
+        Assign to `ErrorInstance` member variables inside `ErrorInstance::finishCreation` instead of
+        inside `ErrorInstance::create` so that subclasses don't have to do the work as well.
+
+        * runtime/Error.cpp:
+        (JSC::createError):
+
+        * runtime/ErrorPrototype.h:
+        (JSC::ErrorPrototype::createStructure):
+        * runtime/NativeErrorPrototype.h:
+        (JSC::NativeErrorPrototype::createStructure):
+        Drive-by: fix incorrect usage of `ErrorInstanceType` since `ErrorPrototype` does not inherit
+                  from `ErrorInstance` (and therefore neither does `NativeErrorPrototype`).
+
+        * runtime/ArgList.h:
+        Add `WTF_MAKE_NONMOVABLE` to `MarkedArgumentBuffer`.
+
+        * Sources.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+
 2020-04-17  Ross Kirsling  <ross.kirsling@sony.com>
 
         Clean up some Intl classes following the ICU upgrade
index b25019f..8c8b469 100644 (file)
                9064337DD4B0402BAF34A592 /* JSScriptFetcher.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BA93C9590484C5BAD9316EA /* JSScriptFetcher.h */; settings = {ATTRIBUTES = (Private, ); }; };
                91278D5521DEB82600B57184 /* InspectorAuditAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 91278D5321DEB82500B57184 /* InspectorAuditAgent.h */; settings = {ATTRIBUTES = (Private, ); }; };
                91278D5821DEDA9600B57184 /* JSGlobalObjectAuditAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 91278D5621DEDA9400B57184 /* JSGlobalObjectAuditAgent.h */; };
+               9168BD872447BA4E0080FFB4 /* AggregateError.h in Headers */ = {isa = PBXBuildFile; fileRef = 9168BD852447BA4D0080FFB4 /* AggregateError.h */; };
                9177A1DC22F958D500B34CA2 /* HeapAnalyzer.h in Headers */ = {isa = PBXBuildFile; fileRef = 9177A1DB22F958D300B34CA2 /* HeapAnalyzer.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               918E15C12447B22700447A56 /* AggregateErrorPrototype.h in Headers */ = {isa = PBXBuildFile; fileRef = 918E15BD2447B22600447A56 /* AggregateErrorPrototype.h */; };
+               918E15C32447B22700447A56 /* AggregateErrorConstructor.h in Headers */ = {isa = PBXBuildFile; fileRef = 918E15BF2447B22700447A56 /* AggregateErrorConstructor.h */; };
                93052C350FB792190048FDC3 /* ParserArena.h in Headers */ = {isa = PBXBuildFile; fileRef = 93052C330FB792190048FDC3 /* ParserArena.h */; settings = {ATTRIBUTES = (Private, ); }; };
                932F5BD30822A1C700736975 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6560A4CF04B3B3E7008AE952 /* CoreFoundation.framework */; };
                932F5BD60822A1C700736975 /* libobjc.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EC0705C86C9A00E6DF1B /* libobjc.dylib */; };
                91278D5321DEB82500B57184 /* InspectorAuditAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorAuditAgent.h; sourceTree = "<group>"; };
                91278D5621DEDA9400B57184 /* JSGlobalObjectAuditAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalObjectAuditAgent.h; sourceTree = "<group>"; };
                91278D5721DEDA9500B57184 /* JSGlobalObjectAuditAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalObjectAuditAgent.cpp; sourceTree = "<group>"; };
+               9168BD842447BA4C0080FFB4 /* AggregateError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AggregateError.cpp; sourceTree = "<group>"; };
+               9168BD852447BA4D0080FFB4 /* AggregateError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AggregateError.h; sourceTree = "<group>"; };
                9177A1DB22F958D300B34CA2 /* HeapAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HeapAnalyzer.h; sourceTree = "<group>"; };
+               918E15BC2447B22600447A56 /* AggregateErrorConstructor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AggregateErrorConstructor.cpp; sourceTree = "<group>"; };
+               918E15BD2447B22600447A56 /* AggregateErrorPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AggregateErrorPrototype.h; sourceTree = "<group>"; };
+               918E15BE2447B22700447A56 /* AggregateErrorPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AggregateErrorPrototype.cpp; sourceTree = "<group>"; };
+               918E15BF2447B22700447A56 /* AggregateErrorConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AggregateErrorConstructor.h; sourceTree = "<group>"; };
                93052C320FB792190048FDC3 /* ParserArena.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParserArena.cpp; sourceTree = "<group>"; };
                93052C330FB792190048FDC3 /* ParserArena.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParserArena.h; sourceTree = "<group>"; };
                930DAD030FB1EB1A0082D205 /* NodeConstructors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NodeConstructors.h; sourceTree = "<group>"; };
                        children = (
                                AD4937C11DDBE60A0077C807 /* AbstractModuleRecord.cpp */,
                                AD4937C21DDBE60A0077C807 /* AbstractModuleRecord.h */,
+                               9168BD842447BA4C0080FFB4 /* AggregateError.cpp */,
+                               9168BD852447BA4D0080FFB4 /* AggregateError.h */,
+                               918E15BC2447B22600447A56 /* AggregateErrorConstructor.cpp */,
+                               918E15BF2447B22700447A56 /* AggregateErrorConstructor.h */,
+                               918E15BE2447B22700447A56 /* AggregateErrorPrototype.cpp */,
+                               918E15BD2447B22600447A56 /* AggregateErrorPrototype.h */,
                                BCF605110E203EF800B9A64D /* ArgList.cpp */,
                                BCF605120E203EF800B9A64D /* ArgList.h */,
                                0FE0500C1AA9091100D33B33 /* ArgumentsMode.h */,
                                534E034E1E4D4B1600213F64 /* AccessCase.h in Headers */,
                                E3BFD0BC1DAF808E0065DEA2 /* AccessCaseSnippetParams.h in Headers */,
                                5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */,
+                               9168BD872447BA4E0080FFB4 /* AggregateError.h in Headers */,
+                               918E15C32447B22700447A56 /* AggregateErrorConstructor.h in Headers */,
+                               918E15C12447B22700447A56 /* AggregateErrorPrototype.h in Headers */,
                                524E9D7322092B5200A6BEEE /* AirAllocateRegistersAndStackAndGenerateCode.h in Headers */,
                                0F2AC56B1E8A0BD50001EE3F /* AirAllocateRegistersAndStackByLinearScan.h in Headers */,
                                7965C2171E5D799600B7591D /* AirAllocateRegistersByGraphColoring.h in Headers */,
index 015ce2a..b3692f5 100644 (file)
@@ -706,6 +706,9 @@ profiler/ProfilerProfiledBytecodes.cpp
 profiler/ProfilerUID.cpp
 
 runtime/AbstractModuleRecord.cpp
+runtime/AggregateError.cpp
+runtime/AggregateErrorConstructor.cpp
+runtime/AggregateErrorPrototype.cpp
 runtime/ArgList.cpp
 runtime/ArrayBuffer.cpp
 runtime/ArrayBufferView.cpp
index 9157ec5..1b66b68 100644 (file)
@@ -130,6 +130,7 @@ namespace JSC {
     macro(replaceUsingStringSearch) \
     macro(replaceAllUsingStringSearch) \
     macro(makeTypeError) \
+    macro(AggregateError) \
     macro(mapBucketHead) \
     macro(mapBucketNext) \
     macro(mapBucketKey) \
index 9905a8f..dbc85ef 100644 (file)
@@ -39,8 +39,7 @@ function all(iterable)
     function newResolveElement(index)
     {
         var alreadyCalled = false;
-        return function (argument)
-        {
+        return (argument) => {
             if (alreadyCalled)
                 return @undefined;
             alreadyCalled = true;
@@ -52,7 +51,7 @@ function all(iterable)
                 return promiseCapability.@resolve.@call(@undefined, values);
 
             return @undefined;
-        }
+        };
     }
 
     try {
@@ -97,7 +96,7 @@ function allSettled(iterable)
         var alreadyCalled = false;
 
         return [
-            function (value) {
+            (value) => {
                 if (alreadyCalled)
                     return @undefined;
                 alreadyCalled = true;
@@ -116,7 +115,7 @@ function allSettled(iterable)
                 return @undefined;
             },
 
-            function (reason) {
+            (reason) => {
                 if (alreadyCalled)
                     return @undefined;
                 alreadyCalled = true;
@@ -161,6 +160,61 @@ function allSettled(iterable)
     return promiseCapability.@promise;
 }
 
+function any(iterable)
+{
+    "use strict";
+
+    if (!@isObject(this))
+        @throwTypeError("|this| is not an object");
+
+    var promiseCapability = @newPromiseCapability(this);
+
+    var errors = [];
+    var remainingElementsCount = 1;
+    var index = 0;
+
+    function newRejectElement(index)
+    {
+        var alreadyCalled = false;
+        return (reason) => {
+            if (alreadyCalled)
+                return @undefined;
+            alreadyCalled = true;
+
+            @putByValDirect(errors, index, reason);
+
+            --remainingElementsCount;
+            if (remainingElementsCount === 0)
+                return promiseCapability.@reject.@call(@undefined, new @AggregateError(errors));
+
+            return @undefined;
+        };
+    }
+
+    try {
+        var promiseResolve = this.resolve;
+        if (typeof promiseResolve !== "function")
+            @throwTypeError("Promise resolve is not a function");
+
+        for (var value of iterable) {
+            @putByValDirect(errors, index, @undefined);
+            var nextPromise = promiseResolve.@call(this, value);
+            var rejectElement = newRejectElement(index);
+            ++remainingElementsCount;
+            nextPromise.then(promiseCapability.@resolve, rejectElement);
+            ++index;
+        }
+
+        --remainingElementsCount;
+        if (remainingElementsCount === 0)
+            throw new @AggregateError(errors);
+    } catch (error) {
+        promiseCapability.@reject.@call(@undefined, error);
+    }
+
+    return promiseCapability.@promise;
+}
+
 function race(iterable)
 {
     "use strict";
index 91621b1..7e38851 100644 (file)
@@ -47,6 +47,7 @@ class JSGlobalObject;
     v(ownKeys, nullptr) \
     v(enqueueJob, nullptr) \
     v(makeTypeError, nullptr) \
+    v(AggregateError, nullptr) \
     v(typedArrayLength, nullptr) \
     v(typedArrayGetOriginalConstructor, nullptr) \
     v(typedArraySort, nullptr) \
index 5c94ae9..86dd6fa 100644 (file)
@@ -622,6 +622,8 @@ void Heap::finalizeUnconditionalFinalizers()
         finalizeMarkedUnconditionalFinalizers<JSWeakObjectRef>(*vm().m_weakObjectRefSpace);
     if (vm().m_errorInstanceSpace)
         finalizeMarkedUnconditionalFinalizers<ErrorInstance>(*vm().m_errorInstanceSpace);
+    if (vm().m_aggregateErrorSpace)
+        finalizeMarkedUnconditionalFinalizers<ErrorInstance>(*vm().m_aggregateErrorSpace);
 
 #if ENABLE(WEBASSEMBLY)
     if (vm().m_webAssemblyCodeBlockSpace)
diff --git a/Source/JavaScriptCore/runtime/AggregateError.cpp b/Source/JavaScriptCore/runtime/AggregateError.cpp
new file mode 100644 (file)
index 0000000..f57a427
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AggregateError.h"
+
+#include "ClassInfo.h"
+#include "ExceptionScope.h"
+#include "IteratorOperations.h"
+#include <wtf/Locker.h>
+
+namespace JSC {
+
+const ClassInfo AggregateError::s_info = { "AggregateError", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(AggregateError) };
+
+AggregateError::AggregateError(VM& vm, Structure* structure, const MarkedArgumentBuffer& errors)
+    : Base(vm, structure)
+    , m_errors(errors.size())
+{
+    for (size_t i = 0; i < errors.size(); ++i)
+        m_errors[i].setWithoutWriteBarrier(errors.at(i));
+}
+
+void AggregateError::visitChildren(JSCell* cell, SlotVisitor& visitor)
+{
+    auto* thisObject = jsCast<AggregateError*>(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+
+    visitor.appendValues(thisObject->m_errors.data(), thisObject->m_errors.size());
+}
+
+AggregateError* AggregateError::create(JSGlobalObject* globalObject, VM& vm, Structure* structure, JSValue errors, JSValue message, SourceAppender appender, RuntimeType type, bool useCurrentFrame)
+{
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    String messageString;
+    if (!message.isUndefined()) {
+        messageString = message.toWTFString(globalObject);
+        RETURN_IF_EXCEPTION(scope, nullptr);
+    }
+
+    MarkedArgumentBuffer errorsList;
+    forEachInIterable(globalObject, errors, [&] (VM&, JSGlobalObject*, JSValue nextValue) {
+        errorsList.append(nextValue);
+        if (UNLIKELY(errorsList.hasOverflowed()))
+            throwOutOfMemoryError(globalObject, scope);
+    });
+    RETURN_IF_EXCEPTION(scope, nullptr);
+
+    RELEASE_AND_RETURN(scope, create(globalObject, vm, structure, errorsList, messageString, appender, type, useCurrentFrame));
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/AggregateError.h b/Source/JavaScriptCore/runtime/AggregateError.h
new file mode 100644 (file)
index 0000000..7a22964
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ArgList.h"
+#include "ErrorInstance.h"
+#include "JSCJSValue.h"
+#include "JSCell.h"
+#include "JSGlobalObject.h"
+#include "SlotVisitor.h"
+#include "Structure.h"
+#include "SubspaceAccess.h"
+#include "VM.h"
+#include "WriteBarrier.h"
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
+namespace JSC {
+
+class AggregateError final : public ErrorInstance {
+public:
+    using Base = ErrorInstance;
+    static constexpr unsigned StructureFlags = Base::StructureFlags;
+    static constexpr bool needsDestruction = Base::needsDestruction;
+
+    static void destroy(JSCell* cell)
+    {
+        static_cast<AggregateError*>(cell)->AggregateError::~AggregateError();
+    }
+
+    template<typename CellType, SubspaceAccess mode>
+    static IsoSubspace* subspaceFor(VM& vm)
+    {
+        return vm.aggregateErrorSpace<mode>();
+    }
+
+    DECLARE_EXPORT_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
+    }
+
+    static void visitChildren(JSCell*, SlotVisitor&);
+
+    static AggregateError* create(JSGlobalObject* globalObject, VM& vm, Structure* structure, const MarkedArgumentBuffer& errors, const String& message, SourceAppender appender = nullptr, RuntimeType type = TypeNothing, bool useCurrentFrame = true)
+    {
+        auto* instance = new (NotNull, allocateCell<AggregateError>(vm.heap)) AggregateError(vm, structure, errors);
+        instance->finishCreation(vm, globalObject, message, appender, type, useCurrentFrame);
+        return instance;
+    }
+
+    static AggregateError* create(JSGlobalObject*, VM&, Structure*, JSValue errors, JSValue message, SourceAppender = nullptr, RuntimeType = TypeNothing, bool useCurrentFrame = true);
+
+    const Vector<WriteBarrier<Unknown>>& errors() const
+    {
+        // This should never be modified after construction.
+        return m_errors;
+    }
+
+protected:
+    explicit AggregateError(VM&, Structure*, const MarkedArgumentBuffer& errors);
+
+private:
+    Vector<WriteBarrier<Unknown>> m_errors;
+};
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/AggregateErrorConstructor.cpp b/Source/JavaScriptCore/runtime/AggregateErrorConstructor.cpp
new file mode 100644 (file)
index 0000000..ecb99b5
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AggregateErrorConstructor.h"
+
+#include "AggregateError.h"
+#include "ClassInfo.h"
+#include "ExceptionScope.h"
+#include "GCAssertions.h"
+#include "RuntimeType.h"
+
+namespace JSC {
+
+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(AggregateErrorConstructor);
+
+const ClassInfo AggregateErrorConstructor::s_info = { "Function", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(AggregateErrorConstructor) };
+
+static EncodedJSValue JSC_HOST_CALL callAggregateErrorConstructor(JSGlobalObject*, CallFrame*);
+static EncodedJSValue JSC_HOST_CALL constructAggregateErrorConstructor(JSGlobalObject*, CallFrame*);
+
+AggregateErrorConstructor::AggregateErrorConstructor(VM& vm, Structure* structure)
+    : Base(vm, structure, callAggregateErrorConstructor, constructAggregateErrorConstructor)
+{
+}
+
+void AggregateErrorConstructor::finishCreation(VM& vm, AggregateErrorPrototype* prototype)
+{
+    Base::finishCreation(vm, errorTypeName(ErrorType::AggregateError), NameAdditionMode::WithoutStructureTransition);
+    ASSERT(inherits(vm, info()));
+
+    putDirectWithoutTransition(vm, vm.propertyNames->length, jsNumber(2), PropertyAttribute::DontEnum | PropertyAttribute::ReadOnly);
+    putDirectWithoutTransition(vm, vm.propertyNames->prototype, prototype, PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum);
+}
+
+static EncodedJSValue JSC_HOST_CALL callAggregateErrorConstructor(JSGlobalObject* globalObject, CallFrame* callFrame)
+{
+    VM& vm = globalObject->vm();
+    JSValue errors = callFrame->argument(0);
+    JSValue message = callFrame->argument(1);
+    Structure* errorStructure = jsCast<AggregateErrorConstructor*>(callFrame->jsCallee())->errorStructure(vm);
+    return JSValue::encode(AggregateError::create(globalObject, vm, errorStructure, errors, message, nullptr, TypeNothing, false));
+}
+
+static EncodedJSValue JSC_HOST_CALL constructAggregateErrorConstructor(JSGlobalObject* globalObject, CallFrame* callFrame)
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+    JSValue errors = callFrame->argument(0);
+    JSValue message = callFrame->argument(1);
+    JSValue newTarget = callFrame->newTarget();
+    ASSERT(newTarget.isObject());
+    Structure* baseStructure = asObject(newTarget)->globalObject(vm)->errorStructure(ErrorType::AggregateError);
+    Structure* errorStructure = InternalFunction::createSubclassStructure(globalObject, callFrame->jsCallee(), newTarget, baseStructure);
+    RETURN_IF_EXCEPTION(scope, encodedJSValue());
+    ASSERT(errorStructure);
+    RELEASE_AND_RETURN(scope, JSValue::encode(AggregateError::create(globalObject, vm, errorStructure, errors, message, nullptr, TypeNothing, false)));
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/AggregateErrorConstructor.h b/Source/JavaScriptCore/runtime/AggregateErrorConstructor.h
new file mode 100644 (file)
index 0000000..8872d0c
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "AggregateErrorPrototype.h"
+#include "ErrorType.h"
+#include "InternalFunction.h"
+#include "JSCJSValue.h"
+#include "JSCell.h"
+#include "JSGlobalObject.h"
+#include "JSTypeInfo.h"
+#include "Structure.h"
+#include "VM.h"
+
+namespace JSC {
+
+class AggregateErrorConstructor final : public InternalFunction {
+public:
+    using Base = InternalFunction;
+
+    DECLARE_INFO;
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(InternalFunctionType, StructureFlags), info());
+    }
+
+    static AggregateErrorConstructor* create(VM& vm, Structure* structure, AggregateErrorPrototype* prototype)
+    {
+        AggregateErrorConstructor* constructor = new (NotNull, allocateCell<AggregateErrorConstructor>(vm.heap)) AggregateErrorConstructor(vm, structure);
+        constructor->finishCreation(vm, prototype);
+        return constructor;
+    }
+
+    Structure* errorStructure(VM&) { return globalObject()->errorStructure(ErrorType::AggregateError); }
+
+private:
+    explicit AggregateErrorConstructor(VM&, Structure*);
+
+    void finishCreation(VM&, AggregateErrorPrototype*);
+};
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/AggregateErrorPrototype.cpp b/Source/JavaScriptCore/runtime/AggregateErrorPrototype.cpp
new file mode 100644 (file)
index 0000000..05ce03b
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AggregateErrorPrototype.h"
+
+#include "CallFrame.h"
+#include "Error.h"
+#include "JSCell.h"
+#include "JSObject.h"
+#include "ThrowScope.h"
+#include <wtf/Locker.h>
+
+namespace JSC {
+
+static EncodedJSValue JSC_HOST_CALL aggregateErrorPrototypeAccessorErrors(JSGlobalObject*, CallFrame*);
+
+AggregateErrorPrototype::AggregateErrorPrototype(VM& vm, Structure* structure)
+    : Base(vm, structure)
+{
+}
+
+void AggregateErrorPrototype::finishCreation(VM& vm, JSGlobalObject* globalObject)
+{
+    Base::finishCreation(vm, errorTypeName(ErrorType::AggregateError));
+    ASSERT(inherits(vm, info()));
+
+    JSC_NATIVE_GETTER_WITHOUT_TRANSITION("errors", aggregateErrorPrototypeAccessorErrors, PropertyAttribute::DontEnum | PropertyAttribute::Accessor);
+}
+
+EncodedJSValue JSC_HOST_CALL aggregateErrorPrototypeAccessorErrors(JSGlobalObject* globalObject, CallFrame* callFrame)
+{
+    VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    JSValue thisValue = callFrame->thisValue();
+    auto* aggregateError = jsDynamicCast<AggregateError*>(vm, thisValue);
+    if (!aggregateError)
+        return throwVMTypeError(globalObject, scope, "The AggregateError.prototype.errors getter can only be called on a AggregateError object"_s);
+
+    auto* result = constructEmptyArray(globalObject, nullptr);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    unsigned index = 0;
+    for (const auto& error : aggregateError->errors()) {
+        result->putDirectIndex(globalObject, index++, error.get());
+        RETURN_IF_EXCEPTION(scope, { });
+    }
+
+    return JSValue::encode(result);
+}
+
+} // namespace JSC
diff --git a/Source/JavaScriptCore/runtime/AggregateErrorPrototype.h b/Source/JavaScriptCore/runtime/AggregateErrorPrototype.h
new file mode 100644 (file)
index 0000000..7145b25
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2020 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "ErrorPrototype.h"
+#include "IsoSubspace.h"
+#include "JSCJSValue.h"
+#include "JSCell.h"
+#include "JSGlobalObject.h"
+#include "JSTypeInfo.h"
+#include "Structure.h"
+#include "VM.h"
+
+namespace JSC {
+
+class AggregateErrorPrototype final : public ErrorPrototypeBase {
+private:
+    AggregateErrorPrototype(VM&, Structure*);
+
+public:
+    using Base = ErrorPrototypeBase;
+
+    template<typename CellType, SubspaceAccess>
+    static IsoSubspace* subspaceFor(VM& vm)
+    {
+        STATIC_ASSERT_ISO_SUBSPACE_SHARABLE(AggregateErrorPrototype, Base);
+        return &vm.plainObjectSpace;
+    }
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+    }
+
+    static AggregateErrorPrototype* create(VM& vm, JSGlobalObject* globalObject, Structure* structure)
+    {
+        AggregateErrorPrototype* prototype = new (NotNull, allocateCell<AggregateErrorPrototype>(vm.heap)) AggregateErrorPrototype(vm, structure);
+        prototype->finishCreation(vm, globalObject);
+        return prototype;
+    }
+
+protected:
+    void finishCreation(VM&, JSGlobalObject*);
+};
+
+} // namespace JSC
index 765ea58..ea4a985 100644 (file)
@@ -30,6 +30,7 @@ namespace JSC {
 
 class MarkedArgumentBuffer : public RecordOverflow {
     WTF_MAKE_NONCOPYABLE(MarkedArgumentBuffer);
+    WTF_MAKE_NONMOVABLE(MarkedArgumentBuffer);
     WTF_FORBID_HEAP_ALLOCATION;
     friend class VM;
     friend class ArgList;
index a1bccbd..7e2b9fa 100644 (file)
@@ -106,6 +106,8 @@ JSObject* createError(JSGlobalObject* globalObject, ErrorType errorType, const S
         return createTypeError(globalObject, message);
     case ErrorType::URIError:
         return createURIError(globalObject, message);
+    case ErrorType::AggregateError:
+        break;
     }
     ASSERT_NOT_REACHED();
     return nullptr;
index 745daaf..c21884f 100644 (file)
@@ -110,10 +110,14 @@ static void appendSourceToError(JSGlobalObject* globalObject, CallFrame* callFra
 
 }
 
-void ErrorInstance::finishCreation(JSGlobalObject* globalObject, VM& vm, const String& message, bool useCurrentFrame)
+void ErrorInstance::finishCreation(VM& vm, JSGlobalObject* globalObject, const String& message, SourceAppender appender, RuntimeType type, bool useCurrentFrame)
 {
     Base::finishCreation(vm);
     ASSERT(inherits(vm, info()));
+
+    m_sourceAppender = appender;
+    m_runtimeTypeForCause = type;
+
     if (!message.isNull())
         putDirect(vm, vm.propertyNames->message, jsString(vm, message), static_cast<unsigned>(PropertyAttribute::DontEnum));
 
index 400608d..5b3253d 100644 (file)
@@ -56,9 +56,7 @@ public:
     static ErrorInstance* create(JSGlobalObject* globalObject, VM& vm, Structure* structure, const String& message, SourceAppender appender = nullptr, RuntimeType type = TypeNothing, bool useCurrentFrame = true)
     {
         ErrorInstance* instance = new (NotNull, allocateCell<ErrorInstance>(vm.heap)) ErrorInstance(vm, structure);
-        instance->m_sourceAppender = appender;
-        instance->m_runtimeTypeForCause = type;
-        instance->finishCreation(globalObject, vm, message, useCurrentFrame);
+        instance->finishCreation(vm, globalObject, message, appender, type, useCurrentFrame);
         return instance;
     }
 
@@ -92,7 +90,7 @@ public:
 protected:
     explicit ErrorInstance(VM&, Structure*);
 
-    void finishCreation(JSGlobalObject*, VM&, const String&, bool useCurrentFrame = true);
+    void finishCreation(VM&, JSGlobalObject*, const String&, SourceAppender = nullptr, RuntimeType = TypeNothing, bool useCurrentFrame = true);
 
     static bool getOwnPropertySlot(JSObject*, JSGlobalObject*, PropertyName, PropertySlot&);
     static void getOwnNonIndexPropertyNames(JSObject*, JSGlobalObject*, PropertyNameArray&, EnumerationMode);
index 922c996..ba1e5b5 100644 (file)
@@ -26,7 +26,7 @@ namespace JSC {
 
 class ObjectPrototype;
 
-// Superclass for ErrorPrototype and NativeErrorPrototype.
+// Superclass for ErrorPrototype, NativeErrorPrototype, and AggregateErrorPrototype.
 class ErrorPrototypeBase : public JSNonFinalObject {
 public:
     using Base = JSNonFinalObject;
@@ -52,7 +52,7 @@ public:
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     }
 
     static ErrorPrototype* create(VM& vm, JSGlobalObject*, Structure* structure)
index b2ac298..8884bcb 100644 (file)
@@ -40,6 +40,7 @@ ASCIILiteral errorTypeName(ErrorType errorType)
         "SyntaxError"_s,
         "TypeError"_s,
         "URIError"_s,
+        "AggregateError"_s,
     };
     return errorTypeNames[static_cast<unsigned>(errorType)];
 }
index 52b49af..27b6cd4 100644 (file)
@@ -37,8 +37,9 @@ enum class ErrorType : uint8_t {
     SyntaxError,
     TypeError,
     URIError,
+    AggregateError,
 };
-static constexpr unsigned NumberOfErrorType { static_cast<unsigned>(ErrorType::URIError) + 1 };
+static constexpr unsigned NumberOfErrorType { static_cast<unsigned>(ErrorType::AggregateError) + 1 };
 ASCIILiteral errorTypeName(ErrorType);
 
 } // namespace JSC
index a6ddb4c..09189b5 100644 (file)
@@ -30,6 +30,9 @@
 #include "config.h"
 #include "JSGlobalObject.h"
 
+#include "AggregateError.h"
+#include "AggregateErrorConstructor.h"
+#include "AggregateErrorPrototype.h"
 #include "ArrayConstructor.h"
 #include "ArrayIteratorPrototype.h"
 #include "ArrayPrototype.h"
@@ -378,6 +381,7 @@ const GlobalObjectMethodTable JSGlobalObject::s_globalObjectMethodTable = {
   SyntaxError           JSGlobalObject::m_syntaxErrorStructure       DontEnum|ClassStructure
   TypeError             JSGlobalObject::m_typeErrorStructure         DontEnum|ClassStructure
   URIError              JSGlobalObject::m_URIErrorStructure          DontEnum|ClassStructure
+  AggregateError        JSGlobalObject::m_aggregateErrorStructure    DontEnum|ClassStructure
   Proxy                 createProxyProperty                          DontEnum|PropertyCallback
   Reflect               createReflectProperty                        DontEnum|PropertyCallback
   JSON                  createJSONProperty                           DontEnum|PropertyCallback
@@ -501,6 +505,13 @@ void JSGlobalObject::initializeErrorConstructor(LazyClassStructure::Initializer&
     init.setConstructor(NativeErrorConstructor<errorType>::create(init.vm, NativeErrorConstructor<errorType>::createStructure(init.vm, this, m_errorStructure.constructor(this)), jsCast<NativeErrorPrototype*>(init.prototype)));
 }
 
+void JSGlobalObject::initializeAggregateErrorConstructor(LazyClassStructure::Initializer& init)
+{
+    init.setPrototype(AggregateErrorPrototype::create(init.vm, this, AggregateErrorPrototype::createStructure(init.vm, this, m_errorStructure.prototype(this))));
+    init.setStructure(AggregateError::createStructure(init.vm, this, init.prototype));
+    init.setConstructor(AggregateErrorConstructor::create(init.vm, AggregateErrorConstructor::createStructure(init.vm, this, m_errorStructure.constructor(this)), jsCast<AggregateErrorPrototype*>(init.prototype)));
+}
+
 void JSGlobalObject::init(VM& vm)
 {
     ASSERT(vm.currentThreadIsHoldingAPILock());
@@ -863,6 +874,10 @@ capitalName ## Constructor* lowerName ## Constructor = featureFlag ? capitalName
         [] (LazyClassStructure::Initializer& init) {
             init.global->initializeErrorConstructor<ErrorType::URIError>(init);
         });
+    m_aggregateErrorStructure.initLater(
+        [] (LazyClassStructure::Initializer& init) {
+            init.global->initializeAggregateErrorConstructor(init);
+        });
 
     m_generatorFunctionPrototype.set(vm, this, GeneratorFunctionPrototype::create(vm, GeneratorFunctionPrototype::createStructure(vm, this, m_functionPrototype.get())));
     GeneratorFunctionConstructor* generatorFunctionConstructor = GeneratorFunctionConstructor::create(vm, GeneratorFunctionConstructor::createStructure(vm, this, functionConstructor), m_generatorFunctionPrototype.get());
@@ -1055,6 +1070,10 @@ capitalName ## Constructor* lowerName ## Constructor = featureFlag ? capitalName
     m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::makeTypeError)].initLater([] (const Initializer<JSCell>& init) {
             init.set(JSFunction::create(init.vm, jsCast<JSGlobalObject*>(init.owner), 0, String(), globalFuncMakeTypeError));
         });
+    m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::AggregateError)].initLater([] (const Initializer<JSCell>& init) {
+            JSGlobalObject* globalObject = jsCast<JSGlobalObject*>(init.owner);
+            init.set(globalObject->m_aggregateErrorStructure.constructor(globalObject));
+        });
     m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::typedArrayLength)].initLater([] (const Initializer<JSCell>& init) {
             init.set(JSFunction::create(init.vm, jsCast<JSGlobalObject*>(init.owner), 0, String(), typedArrayViewPrivateFuncLength));
         });
@@ -1734,6 +1753,7 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
     thisObject->m_syntaxErrorStructure.visit(visitor);
     thisObject->m_typeErrorStructure.visit(visitor);
     thisObject->m_URIErrorStructure.visit(visitor);
+    thisObject->m_aggregateErrorStructure.visit(visitor);
     visitor.append(thisObject->m_arrayConstructor);
     visitor.append(thisObject->m_regExpConstructor);
     visitor.append(thisObject->m_objectConstructor);
index 0e18960..c40a56a 100644 (file)
@@ -280,6 +280,7 @@ public:
     LazyClassStructure m_syntaxErrorStructure;
     LazyClassStructure m_typeErrorStructure;
     LazyClassStructure m_URIErrorStructure;
+    LazyClassStructure m_aggregateErrorStructure;
 
     WriteBarrier<ObjectConstructor> m_objectConstructor;
     WriteBarrier<ArrayConstructor> m_arrayConstructor;
@@ -724,6 +725,8 @@ public:
             return m_typeErrorStructure.get(this);
         case ErrorType::URIError:
             return m_URIErrorStructure.get(this);
+        case ErrorType::AggregateError:
+            return m_aggregateErrorStructure.get(this);
         }
         ASSERT_NOT_REACHED();
         return nullptr;
@@ -1044,6 +1047,8 @@ private:
     template<ErrorType errorType>
     void initializeErrorConstructor(LazyClassStructure::Initializer&);
 
+    void initializeAggregateErrorConstructor(LazyClassStructure::Initializer&);
+
     JS_EXPORT_PRIVATE void init(VM&);
     void fixupPrototypeChainWithObjectPrototype(VM&);
 
index 57ef64a..9b1c28f 100644 (file)
@@ -57,6 +57,7 @@ const ClassInfo JSPromiseConstructor::s_info = { "Function", &Base::s_info, &pro
   race            JSBuiltin             DontEnum|Function 1
   all             JSBuiltin             DontEnum|Function 1
   allSettled      JSBuiltin             DontEnum|Function 1
+  any             JSBuiltin             DontEnum|Function 1
 @end
 */
 
index 67d2fae..8813341 100644 (file)
@@ -39,7 +39,7 @@ public:
 
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
     {
-        return Structure::create(vm, globalObject, prototype, TypeInfo(ErrorInstanceType, StructureFlags), info());
+        return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     }
 
     static NativeErrorPrototype* create(VM& vm, Structure* structure, const String& name)
index f0d34bf..aec2fef 100644 (file)
@@ -29,6 +29,7 @@
 #include "config.h"
 #include "VM.h"
 
+#include "AggregateError.h"
 #include "ArgList.h"
 #include "BigIntObject.h"
 #include "BooleanObject.h"
@@ -308,6 +309,7 @@ VM::VM(VMType vmType, HeapType heapType)
     , immutableButterflyHeapCellType(makeUnique<HeapCellType>(CellAttributes(DoesNotNeedDestruction, HeapCell::JSCellWithInteriorPointers)))
     , cellHeapCellType(makeUnique<HeapCellType>(CellAttributes(DoesNotNeedDestruction, HeapCell::JSCell)))
     , destructibleCellHeapCellType(makeUnique<HeapCellType>(CellAttributes(NeedsDestruction, HeapCell::JSCell)))
+    , aggregateErrorHeapCellType(IsoHeapCellType::create<AggregateError>())
     , apiGlobalObjectHeapCellType(IsoHeapCellType::create<JSAPIGlobalObject>())
     , callbackConstructorHeapCellType(IsoHeapCellType::create<JSCallbackConstructor>())
     , callbackGlobalObjectHeapCellType(IsoHeapCellType::create<JSCallbackObject<JSGlobalObject>>())
@@ -1437,6 +1439,7 @@ void VM::ensureShadowChicken()
     }
 
 
+DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(aggregateErrorSpace, aggregateErrorHeapCellType.get(), AggregateError)
 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(apiGlobalObjectSpace, apiGlobalObjectHeapCellType.get(), JSAPIGlobalObject)
 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(apiValueWrapperSpace, cellHeapCellType.get(), JSAPIValueWrapper)
 DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER_SLOW(arrayBufferSpace, cellHeapCellType.get(), JSArrayBuffer)
index f7b616a..b41dce7 100644 (file)
@@ -370,6 +370,7 @@ public:
     std::unique_ptr<HeapCellType> immutableButterflyHeapCellType;
     std::unique_ptr<HeapCellType> cellHeapCellType;
     std::unique_ptr<HeapCellType> destructibleCellHeapCellType;
+    std::unique_ptr<IsoHeapCellType> aggregateErrorHeapCellType;
     std::unique_ptr<IsoHeapCellType> apiGlobalObjectHeapCellType;
     std::unique_ptr<IsoHeapCellType> callbackConstructorHeapCellType;
     std::unique_ptr<IsoHeapCellType> callbackGlobalObjectHeapCellType;
@@ -493,6 +494,7 @@ public:
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(jscCallbackFunctionSpace)
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(callbackAPIWrapperGlobalObjectSpace)
 #endif
+    DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(aggregateErrorSpace)
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(apiGlobalObjectSpace)
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(apiValueWrapperSpace)
     DYNAMIC_ISO_SUBSPACE_DEFINE_MEMBER(arrayBufferSpace)
index 62ff6aa..2e0b9dd 100644 (file)
@@ -35,9 +35,8 @@ namespace JSC {
 JSWebAssemblyCompileError* JSWebAssemblyCompileError::create(JSGlobalObject* globalObject, VM& vm, Structure* structure, const String& message)
 {
     auto* instance = new (NotNull, allocateCell<JSWebAssemblyCompileError>(vm.heap)) JSWebAssemblyCompileError(vm, structure);
-    instance->m_sourceAppender = defaultSourceAppender;
     bool useCurrentFrame = true;
-    instance->finishCreation(globalObject, vm, message, useCurrentFrame);
+    instance->finishCreation(vm, globalObject, message, defaultSourceAppender, TypeNothing, useCurrentFrame);
     return instance;
 }
 
index 5d05895..03ab8a2 100644 (file)
@@ -35,9 +35,8 @@ namespace JSC {
 JSWebAssemblyLinkError* JSWebAssemblyLinkError::create(JSGlobalObject* globalObject, VM& vm, Structure* structure, const String& message)
 {
     auto* instance = new (NotNull, allocateCell<JSWebAssemblyLinkError>(vm.heap)) JSWebAssemblyLinkError(vm, structure);
-    instance->m_sourceAppender = defaultSourceAppender;
     bool useCurrentFrame = true;
-    instance->finishCreation(globalObject, vm, message, useCurrentFrame);
+    instance->finishCreation(vm, globalObject, message, defaultSourceAppender, TypeNothing, useCurrentFrame);
     return instance;
 }
 
index a59e96c..cfd4eaa 100644 (file)
@@ -35,9 +35,8 @@ namespace JSC {
 JSWebAssemblyRuntimeError* JSWebAssemblyRuntimeError::create(JSGlobalObject* globalObject, VM& vm, Structure* structure, const String& message)
 {
     auto* instance = new (NotNull, allocateCell<JSWebAssemblyRuntimeError>(vm.heap)) JSWebAssemblyRuntimeError(vm, structure);
-    instance->m_sourceAppender = defaultSourceAppender;
     bool useCurrentFrame = true;
-    instance->finishCreation(globalObject, vm, message, useCurrentFrame);
+    instance->finishCreation(vm, globalObject, message, defaultSourceAppender, TypeNothing, useCurrentFrame);
     return instance;
 }
 
index 023160f..23bd420 100644 (file)
@@ -1,3 +1,13 @@
+2020-04-17  Devin Rousso  <drousso@apple.com>
+
+        Implement Promise.any and AggregateError
+        https://bugs.webkit.org/show_bug.cgi?id=202566
+
+        Reviewed by Yusuke Suzuki.
+
+        * UserInterface/Models/IssueMessage.js:
+        Mark `AggregateError` as a `WI.IssueMessage.Type.SemanticIssue`.
+
 2020-04-17  Alexey Shvayka  <shvaikalesh@gmail.com>
 
         MediaQueryList should extend EventTarget
index 3e37c58..2d88175 100644 (file)
@@ -202,6 +202,7 @@ WI.IssueMessage.Event = {
 WI.IssueMessage.Type._prefixTypeMap = {
     "SyntaxError": WI.IssueMessage.Type.SemanticIssue,
     "URIError": WI.IssueMessage.Type.SemanticIssue,
+    "AggregateError": WI.IssueMessage.Type.SemanticIssue,
     "EvalError": WI.IssueMessage.Type.SemanticIssue,
     "INVALID_CHARACTER_ERR": WI.IssueMessage.Type.SemanticIssue,
     "SYNTAX_ERR": WI.IssueMessage.Type.SemanticIssue,