diff --git a/nova_vm/src/ecmascript/builtins/control_abstraction_objects/promise_objects/promise_abstract_operations/promise_group_record.rs b/nova_vm/src/ecmascript/builtins/control_abstraction_objects/promise_objects/promise_abstract_operations/promise_group_record.rs index 801f27503..f2a5af8e0 100644 --- a/nova_vm/src/ecmascript/builtins/control_abstraction_objects/promise_objects/promise_abstract_operations/promise_group_record.rs +++ b/nova_vm/src/ecmascript/builtins/control_abstraction_objects/promise_objects/promise_abstract_operations/promise_group_record.rs @@ -23,11 +23,12 @@ use crate::{ }, }; -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum PromiseGroupType { All, AllSettled, Any, + Race, } #[derive(Debug, Clone, Copy)] @@ -89,6 +90,14 @@ impl<'a> PromiseGroup<'a> { self.reject(agent, index, value.unbind(), gc.reborrow()); } }, + PromiseGroupType::Race => match reaction_type { + PromiseReactionType::Fulfill => { + self.immediately_resolve(agent, value.unbind(), gc.reborrow()); + } + PromiseReactionType::Reject => { + self.immediately_reject(agent, value.unbind(), gc.nogc()); + } + }, } } diff --git a/nova_vm/src/ecmascript/builtins/control_abstraction_objects/promise_objects/promise_constructor.rs b/nova_vm/src/ecmascript/builtins/control_abstraction_objects/promise_objects/promise_constructor.rs index c4cbee21d..2ced2ecdb 100644 --- a/nova_vm/src/ecmascript/builtins/control_abstraction_objects/promise_objects/promise_constructor.rs +++ b/nova_vm/src/ecmascript/builtins/control_abstraction_objects/promise_objects/promise_constructor.rs @@ -285,11 +285,11 @@ impl PromiseConstructor { /// > method. fn race<'gc>( agent: &mut Agent, - _this_value: Value, - _arguments: ArgumentsList, + this_value: Value, + arguments: ArgumentsList, gc: GcScope<'gc, '_>, ) -> JsResult<'gc, Value<'gc>> { - Err(agent.todo("Promise.race", gc.into_nogc())) + promise_group(agent, this_value, arguments, PromiseGroupType::Race, gc) } /// ### [27.2.4.6 Promise.reject ( r )](https://tc39.es/ecma262/#sec-promise.reject) @@ -680,6 +680,7 @@ fn promise_group<'gc>( /// ### [27.2.4.1.2 PerformPromiseAll ( iteratorRecord, constructor, resultCapability, promiseResolve )](https://tc39.es/ecma262/#sec-performpromiseall) /// ### [27.2.4.2.1 PerformPromiseAllSettled ( iteratorRecord, constructor, resultCapability, promiseResolve )](https://tc39.es/ecma262/#sec-performpromiseallsettled) /// ### [27.2.4.3.1 PerformPromiseAny ( iteratorRecord, constructor, resultCapability, promiseResolve )](https://tc39.es/ecma262/#sec-performpromiseany) +/// ### [27.2.4.5.1 PerformPromiseRace ( iteratorRecord, constructor, resultCapability, promiseResolve )](https://tc39.es/ecma262/#sec-performpromiserace) #[allow(clippy::too_many_arguments)] fn perform_promise_group<'gc>( agent: &mut Agent, @@ -743,6 +744,10 @@ fn perform_promise_group<'gc>( // b. If next is done, then let Some(next) = next else { + if promise_group_type == PromiseGroupType::Race { + return Ok(promise.get(agent)); + } + *iterator_done = true; let promise_group = promise_group_reference.get(agent).bind(gc.nogc()); let data = promise_group.get_mut(agent); diff --git a/tests/expectations.json b/tests/expectations.json index fd2b19261..afcd4b1b4 100644 --- a/tests/expectations.json +++ b/tests/expectations.json @@ -1305,92 +1305,30 @@ "built-ins/Promise/prototype/then/ctor-poisoned.js": "FAIL", "built-ins/Promise/prototype/then/ctor-throws.js": "FAIL", "built-ins/Promise/prototype/then/deferred-is-resolved-value.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A2.1_T1.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A2.2_T1.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A2.2_T2.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A2.2_T3.js": "FAIL", "built-ins/Promise/race/S25.4.4.3_A3.1_T1.js": "FAIL", "built-ins/Promise/race/S25.4.4.3_A3.1_T2.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A4.1_T1.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A4.1_T2.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A5.1_T1.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A6.1_T1.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A6.2_T1.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A7.1_T1.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A7.1_T2.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A7.1_T3.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A7.2_T1.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A7.3_T1.js": "FAIL", - "built-ins/Promise/race/S25.4.4.3_A7.3_T2.js": "FAIL", "built-ins/Promise/race/capability-executor-called-twice.js": "FAIL", "built-ins/Promise/race/capability-executor-not-callable.js": "FAIL", "built-ins/Promise/race/ctx-ctor-throws.js": "FAIL", "built-ins/Promise/race/ctx-ctor.js": "FAIL", "built-ins/Promise/race/ctx-non-ctor.js": "FAIL", "built-ins/Promise/race/ctx-non-object.js": "FAIL", - "built-ins/Promise/race/invoke-resolve-error-close.js": "FAIL", "built-ins/Promise/race/invoke-resolve-error-reject.js": "FAIL", - "built-ins/Promise/race/invoke-resolve-get-error-reject.js": "FAIL", - "built-ins/Promise/race/invoke-resolve-get-error.js": "FAIL", - "built-ins/Promise/race/invoke-resolve-get-once-multiple-calls.js": "FAIL", - "built-ins/Promise/race/invoke-resolve-get-once-no-calls.js": "FAIL", "built-ins/Promise/race/invoke-resolve-on-promises-every-iteration-of-custom.js": "FAIL", - "built-ins/Promise/race/invoke-resolve-on-promises-every-iteration-of-promise.js": "FAIL", - "built-ins/Promise/race/invoke-resolve-on-values-every-iteration-of-promise.js": "FAIL", "built-ins/Promise/race/invoke-resolve-return.js": "FAIL", - "built-ins/Promise/race/invoke-resolve.js": "FAIL", - "built-ins/Promise/race/invoke-then-error-close.js": "FAIL", - "built-ins/Promise/race/invoke-then-error-reject.js": "FAIL", - "built-ins/Promise/race/invoke-then-get-error-close.js": "FAIL", - "built-ins/Promise/race/invoke-then-get-error-reject.js": "FAIL", + "built-ins/Promise/race/invoke-then-error-close.js": "TIMEOUT", + "built-ins/Promise/race/invoke-then-error-reject.js": "UNRESOLVED", + "built-ins/Promise/race/invoke-then-get-error-close.js": "TIMEOUT", + "built-ins/Promise/race/invoke-then-get-error-reject.js": "UNRESOLVED", "built-ins/Promise/race/invoke-then.js": "FAIL", - "built-ins/Promise/race/iter-arg-is-false-reject.js": "FAIL", - "built-ins/Promise/race/iter-arg-is-null-reject.js": "FAIL", - "built-ins/Promise/race/iter-arg-is-number-reject.js": "FAIL", - "built-ins/Promise/race/iter-arg-is-string-resolve.js": "FAIL", - "built-ins/Promise/race/iter-arg-is-symbol-reject.js": "FAIL", - "built-ins/Promise/race/iter-arg-is-true-reject.js": "FAIL", - "built-ins/Promise/race/iter-arg-is-undefined-reject.js": "FAIL", - "built-ins/Promise/race/iter-assigned-false-reject.js": "FAIL", - "built-ins/Promise/race/iter-assigned-null-reject.js": "FAIL", - "built-ins/Promise/race/iter-assigned-number-reject.js": "FAIL", - "built-ins/Promise/race/iter-assigned-string-reject.js": "FAIL", - "built-ins/Promise/race/iter-assigned-symbol-reject.js": "FAIL", - "built-ins/Promise/race/iter-assigned-true-reject.js": "FAIL", - "built-ins/Promise/race/iter-assigned-undefined-reject.js": "FAIL", "built-ins/Promise/race/iter-next-val-err-no-close.js": "FAIL", - "built-ins/Promise/race/iter-next-val-err-reject.js": "FAIL", - "built-ins/Promise/race/iter-returns-false-reject.js": "FAIL", - "built-ins/Promise/race/iter-returns-null-reject.js": "FAIL", - "built-ins/Promise/race/iter-returns-number-reject.js": "FAIL", - "built-ins/Promise/race/iter-returns-string-reject.js": "FAIL", - "built-ins/Promise/race/iter-returns-symbol-reject.js": "FAIL", - "built-ins/Promise/race/iter-returns-true-reject.js": "FAIL", - "built-ins/Promise/race/iter-returns-undefined-reject.js": "FAIL", "built-ins/Promise/race/iter-step-err-no-close.js": "FAIL", - "built-ins/Promise/race/iter-step-err-reject.js": "FAIL", - "built-ins/Promise/race/reject-deferred.js": "FAIL", "built-ins/Promise/race/reject-from-same-thenable.js": "FAIL", - "built-ins/Promise/race/reject-ignored-deferred.js": "FAIL", - "built-ins/Promise/race/reject-ignored-immed.js": "FAIL", - "built-ins/Promise/race/reject-immed.js": "FAIL", "built-ins/Promise/race/resolve-from-same-thenable.js": "FAIL", - "built-ins/Promise/race/resolve-ignores-late-rejection-deferred.js": "FAIL", - "built-ins/Promise/race/resolve-ignores-late-rejection.js": "FAIL", - "built-ins/Promise/race/resolve-non-callable.js": "FAIL", - "built-ins/Promise/race/resolve-non-obj.js": "FAIL", - "built-ins/Promise/race/resolve-non-thenable.js": "FAIL", - "built-ins/Promise/race/resolve-poisoned-then.js": "FAIL", "built-ins/Promise/race/resolve-prms-cstm-then.js": "FAIL", "built-ins/Promise/race/resolve-self.js": "FAIL", - "built-ins/Promise/race/resolve-thenable.js": "FAIL", "built-ins/Promise/race/resolve-throws-iterator-return-is-not-callable.js": "FAIL", "built-ins/Promise/race/resolve-throws-iterator-return-null-or-undefined.js": "FAIL", - "built-ins/Promise/race/resolved-sequence-extra-ticks.js": "FAIL", - "built-ins/Promise/race/resolved-sequence-mixed.js": "FAIL", - "built-ins/Promise/race/resolved-sequence-with-rejections.js": "FAIL", - "built-ins/Promise/race/resolved-sequence.js": "FAIL", - "built-ins/Promise/race/resolved-then-catch-finally.js": "FAIL", "built-ins/Promise/race/same-reject-function.js": "FAIL", "built-ins/Promise/race/same-resolve-function.js": "FAIL", "built-ins/Promise/race/species-get-error.js": "FAIL", @@ -7769,7 +7707,6 @@ "staging/sm/PrivateName/proxy-init-set.js": "FAIL", "staging/sm/PrivateName/read-private-eval.js": "FAIL", "staging/sm/Promise/bug-1288382.js": "FAIL", - "staging/sm/Promise/for-of-iterator-uses-getv.js": "FAIL", "staging/sm/Proxy/getPrototypeOf.js": "FAIL", "staging/sm/Proxy/hasInstance.js": "FAIL", "staging/sm/Proxy/json-stringify-replacer-array-revocable-proxy.js": "FAIL", diff --git a/tests/metrics.json b/tests/metrics.json index 880202e22..67f2fc63a 100644 --- a/tests/metrics.json +++ b/tests/metrics.json @@ -1,11 +1,11 @@ { "results": { "crash": 105, - "fail": 7907, - "pass": 39350, + "fail": 7840, + "pass": 39410, "skip": 3325, - "timeout": 11, - "unresolved": 35 + "timeout": 16, + "unresolved": 37 }, "total": 50733 } \ No newline at end of file