From 701e8430d27579bdfaa160718440692a3d54a50f Mon Sep 17 00:00:00 2001 From: Yuto Yoshino Date: Thu, 6 Feb 2025 05:52:13 +0900 Subject: [PATCH] feat(ecmascript): %TypedArray%.prototype.forEach (#553) --- .../typed_array_intrinsic_object.rs | 75 +++++++++++++++++-- tests/expectations.json | 54 ++----------- tests/metrics.json | 10 +-- tests/skip.json | 26 +++++-- 4 files changed, 101 insertions(+), 64 deletions(-) diff --git a/nova_vm/src/ecmascript/builtins/indexed_collections/typed_array_objects/typed_array_intrinsic_object.rs b/nova_vm/src/ecmascript/builtins/indexed_collections/typed_array_objects/typed_array_intrinsic_object.rs index f6dedb552..713f28035 100644 --- a/nova_vm/src/ecmascript/builtins/indexed_collections/typed_array_objects/typed_array_intrinsic_object.rs +++ b/nova_vm/src/ecmascript/builtins/indexed_collections/typed_array_objects/typed_array_intrinsic_object.rs @@ -723,13 +723,78 @@ impl TypedArrayPrototype { todo!() } + // ### [ 23.2.3.15 %TypedArray%.prototype.forEach ( callback [ , thisArg ] )](https://tc39.es/ecma262/multipage/indexed-collections.html#sec-%typedarray%.prototype.foreach) + // The interpretation and use of the arguments of this method are the same as for Array.prototype.forEach as defined in 23.1.3.15. fn for_each( - _agent: &mut Agent, - _this_value: Value, - _: ArgumentsList, - _gc: GcScope, + agent: &mut Agent, + this_value: Value, + arguments: ArgumentsList, + mut gc: GcScope, ) -> JsResult { - todo!() + let callback = arguments.get(0).bind(gc.nogc()); + let this_arg = arguments.get(1).bind(gc.nogc()); + // 1. Let O be the this value. + let o = this_value; + // 2. Let taRecord be ? ValidateTypedArray(O, seq-cst). + let ta_record = validate_typed_array(agent, o, Ordering::SeqCst, gc.nogc())?; + // 3. Let len be TypedArrayLength(taRecord). + let mut o = ta_record.object; + let scoped_o = o.scope(agent, gc.nogc()); + let len = match o { + TypedArray::Int8Array(_) + | TypedArray::Uint8Array(_) + | TypedArray::Uint8ClampedArray(_) => { + typed_array_length::(agent, &ta_record, gc.nogc()) + } + TypedArray::Int16Array(_) | TypedArray::Uint16Array(_) => { + typed_array_length::(agent, &ta_record, gc.nogc()) + } + #[cfg(feature = "proposal-float16array")] + TypedArray::Float16Array(_) => typed_array_length::(agent, &ta_record, gc.nogc()), + TypedArray::Int32Array(_) + | TypedArray::Uint32Array(_) + | TypedArray::Float32Array(_) => { + typed_array_length::(agent, &ta_record, gc.nogc()) + } + TypedArray::BigInt64Array(_) + | TypedArray::BigUint64Array(_) + | TypedArray::Float64Array(_) => { + typed_array_length::(agent, &ta_record, gc.nogc()) + } + }; + // 4. If IsCallable(callback) is false, throw a TypeError exception. + let Some(callback) = is_callable(callback, gc.nogc()) else { + return Err(agent.throw_exception_with_static_message( + ExceptionType::TypeError, + "Callback is not callable", + gc.nogc(), + )); + }; + let callback = callback.scope(agent, gc.nogc()); + // 5. Let k be 0. + let mut k = 0; + // 6. Repeat, while k < len, + while k < len { + // a. Let Pk be ! ToString(𝔽(k)). + let pk: PropertyKey = k.try_into().unwrap(); + // b. Let kValue be ! Get(O, Pk). + let k_value = unwrap_try(try_get(agent, o, pk, gc.nogc())); + // c. Perform ? Call(callback, thisArg, « kValue, 𝔽(k), O »). + // // SAFETY: pk is Integer, which is what we want for fk as well. + let fk = unsafe { pk.into_value_unchecked() }; + call_function( + agent, + callback.get(agent), + this_arg, + Some(ArgumentsList(&[k_value, fk, o.into_value()])), + gc.reborrow(), + )?; + // d. Set k to k + 1. + k += 1; + o = scoped_o.get(agent).bind(gc.nogc()); + } + // 7. Return undefined. + Ok(Value::Undefined) } fn includes( diff --git a/tests/expectations.json b/tests/expectations.json index 5297e902e..33219b07c 100644 --- a/tests/expectations.json +++ b/tests/expectations.json @@ -3581,7 +3581,7 @@ "built-ins/RegExp/property-escapes/character-class.js": "CRASH", "built-ins/RegExp/property-escapes/generated/ASCII.js": "CRASH", "built-ins/RegExp/property-escapes/generated/ASCII_Hex_Digit.js": "CRASH", - "built-ins/RegExp/property-escapes/generated/Alphabetic.js": "TIMEOUT", + "built-ins/RegExp/property-escapes/generated/Alphabetic.js": "CRASH", "built-ins/RegExp/property-escapes/generated/Any.js": "CRASH", "built-ins/RegExp/property-escapes/generated/Assigned.js": "CRASH", "built-ins/RegExp/property-escapes/generated/Bidi_Control.js": "CRASH", @@ -3616,7 +3616,7 @@ "built-ins/RegExp/property-escapes/generated/General_Category_-_Final_Punctuation.js": "CRASH", "built-ins/RegExp/property-escapes/generated/General_Category_-_Format.js": "CRASH", "built-ins/RegExp/property-escapes/generated/General_Category_-_Initial_Punctuation.js": "CRASH", - "built-ins/RegExp/property-escapes/generated/General_Category_-_Letter.js": "TIMEOUT", + "built-ins/RegExp/property-escapes/generated/General_Category_-_Letter.js": "CRASH", "built-ins/RegExp/property-escapes/generated/General_Category_-_Letter_Number.js": "CRASH", "built-ins/RegExp/property-escapes/generated/General_Category_-_Line_Separator.js": "CRASH", "built-ins/RegExp/property-escapes/generated/General_Category_-_Lowercase_Letter.js": "CRASH", @@ -3641,15 +3641,15 @@ "built-ins/RegExp/property-escapes/generated/General_Category_-_Surrogate.js": "CRASH", "built-ins/RegExp/property-escapes/generated/General_Category_-_Symbol.js": "CRASH", "built-ins/RegExp/property-escapes/generated/General_Category_-_Titlecase_Letter.js": "CRASH", - "built-ins/RegExp/property-escapes/generated/General_Category_-_Unassigned.js": "TIMEOUT", + "built-ins/RegExp/property-escapes/generated/General_Category_-_Unassigned.js": "CRASH", "built-ins/RegExp/property-escapes/generated/General_Category_-_Uppercase_Letter.js": "CRASH", - "built-ins/RegExp/property-escapes/generated/Grapheme_Base.js": "TIMEOUT", + "built-ins/RegExp/property-escapes/generated/Grapheme_Base.js": "CRASH", "built-ins/RegExp/property-escapes/generated/Grapheme_Extend.js": "CRASH", "built-ins/RegExp/property-escapes/generated/Hex_Digit.js": "CRASH", "built-ins/RegExp/property-escapes/generated/IDS_Binary_Operator.js": "CRASH", "built-ins/RegExp/property-escapes/generated/IDS_Trinary_Operator.js": "CRASH", - "built-ins/RegExp/property-escapes/generated/ID_Continue.js": "TIMEOUT", - "built-ins/RegExp/property-escapes/generated/ID_Start.js": "TIMEOUT", + "built-ins/RegExp/property-escapes/generated/ID_Continue.js": "CRASH", + "built-ins/RegExp/property-escapes/generated/ID_Start.js": "CRASH", "built-ins/RegExp/property-escapes/generated/Ideographic.js": "CRASH", "built-ins/RegExp/property-escapes/generated/Join_Control.js": "CRASH", "built-ins/RegExp/property-escapes/generated/Logical_Order_Exception.js": "CRASH", @@ -4008,8 +4008,8 @@ "built-ins/RegExp/property-escapes/generated/Uppercase.js": "CRASH", "built-ins/RegExp/property-escapes/generated/Variation_Selector.js": "CRASH", "built-ins/RegExp/property-escapes/generated/White_Space.js": "CRASH", - "built-ins/RegExp/property-escapes/generated/XID_Continue.js": "TIMEOUT", - "built-ins/RegExp/property-escapes/generated/XID_Start.js": "TIMEOUT", + "built-ins/RegExp/property-escapes/generated/XID_Continue.js": "CRASH", + "built-ins/RegExp/property-escapes/generated/XID_Start.js": "CRASH", "built-ins/RegExp/property-escapes/generated/strings/Basic_Emoji-negative-CharacterClass.js": "FAIL", "built-ins/RegExp/property-escapes/generated/strings/Basic_Emoji-negative-P.js": "FAIL", "built-ins/RegExp/property-escapes/generated/strings/Basic_Emoji-negative-u.js": "FAIL", @@ -9903,44 +9903,8 @@ "built-ins/TypedArray/prototype/findLastIndex/return-negative-one-if-predicate-returns-false-value.js": "CRASH", "built-ins/TypedArray/prototype/findLastIndex/this-is-not-object.js": "CRASH", "built-ins/TypedArray/prototype/findLastIndex/this-is-not-typedarray-instance.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/BigInt/arraylength-internal.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/BigInt/callbackfn-arguments-with-thisarg.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/BigInt/callbackfn-arguments-without-thisarg.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/BigInt/callbackfn-detachbuffer.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/BigInt/callbackfn-is-not-callable.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/BigInt/callbackfn-no-interaction-over-non-integer.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/BigInt/callbackfn-not-called-on-empty.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/BigInt/callbackfn-return-does-not-change-instance.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/BigInt/callbackfn-returns-abrupt.js": "CRASH", "built-ins/TypedArray/prototype/forEach/BigInt/callbackfn-set-value-during-interaction.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/BigInt/callbackfn-this.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/BigInt/detached-buffer.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/BigInt/return-abrupt-from-this-out-of-bounds.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/BigInt/returns-undefined.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/BigInt/values-are-not-cached.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/arraylength-internal.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/callbackfn-arguments-with-thisarg.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/callbackfn-arguments-without-thisarg.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/callbackfn-detachbuffer.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/callbackfn-is-not-callable.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/callbackfn-no-interaction-over-non-integer.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/callbackfn-not-called-on-empty.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/callbackfn-resize.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/callbackfn-return-does-not-change-instance.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/callbackfn-returns-abrupt.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/callbackfn-set-value-during-interaction.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/callbackfn-this.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/detached-buffer.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/invoked-as-func.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/invoked-as-method.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/resizable-buffer-grow-mid-iteration.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/resizable-buffer-shrink-mid-iteration.js": "CRASH", "built-ins/TypedArray/prototype/forEach/resizable-buffer.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/return-abrupt-from-this-out-of-bounds.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/returns-undefined.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/this-is-not-object.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/this-is-not-typedarray-instance.js": "CRASH", - "built-ins/TypedArray/prototype/forEach/values-are-not-cached.js": "CRASH", "built-ins/TypedArray/prototype/includes/BigInt/detached-buffer-during-fromIndex-returns-false-for-zero.js": "CRASH", "built-ins/TypedArray/prototype/includes/BigInt/detached-buffer-during-fromIndex-returns-true-for-undefined.js": "CRASH", "built-ins/TypedArray/prototype/includes/BigInt/detached-buffer.js": "CRASH", @@ -11372,8 +11336,6 @@ "language/block-scope/syntax/redeclaration/inner-block-var-redeclaration-attempt-after-function.js": "FAIL", "language/block-scope/syntax/redeclaration/var-name-redeclaration-attempt-with-function.js": "FAIL", "language/block-scope/syntax/redeclaration/var-redeclaration-attempt-after-function.js": "FAIL", - "language/comments/S7.4_A5.js": "TIMEOUT", - "language/comments/S7.4_A6.js": "TIMEOUT", "language/comments/hashbang/eval-indirect.js": "FAIL", "language/comments/hashbang/use-strict.js": "CRASH", "language/computed-property-names/object/accessor/getter-super.js": "CRASH", diff --git a/tests/metrics.json b/tests/metrics.json index ef912777a..870845b0e 100644 --- a/tests/metrics.json +++ b/tests/metrics.json @@ -1,10 +1,10 @@ { "results": { - "crash": 13225, - "fail": 9061, - "pass": 24456, - "skip": 55, - "timeout": 4, + "crash": 13174, + "fail": 9070, + "pass": 24492, + "skip": 65, + "timeout": 0, "unresolved": 0 }, "total": 46801 diff --git a/tests/skip.json b/tests/skip.json index a579844d3..835463072 100644 --- a/tests/skip.json +++ b/tests/skip.json @@ -30,11 +30,21 @@ "built-ins/Object/defineProperty/15.2.3.6-4-183.js", "built-ins/parseFloat/S15.1.2.3_A6.js", "built-ins/parseInt/S15.1.2.2_A8.js", + "built-ins/RegExp/property-escapes/generated/Alphabetic.js", + "built-ins/RegExp/property-escapes/generated/General_Category_-_Letter.js", + "built-ins/RegExp/property-escapes/generated/General_Category_-_Other_Letter.js", + "built-ins/RegExp/property-escapes/generated/General_Category_-_Unassigned.js", + "built-ins/RegExp/property-escapes/generated/Grapheme_Base.js", + "built-ins/RegExp/property-escapes/generated/ID_Continue.js", + "built-ins/RegExp/property-escapes/generated/ID_Start.js", + "built-ins/RegExp/property-escapes/generated/XID_Continue.js", + "built-ins/RegExp/property-escapes/generated/XID_Start.js", "built-ins/TypedArray/prototype/copyWithin/coerced-values-end-detached-prototype.js", "built-ins/TypedArray/prototype/copyWithin/coerced-values-end-detached.js", "built-ins/TypedArray/prototype/copyWithin/coerced-values-start-detached.js", - "built-ins/RegExp/property-escapes/generated/General_Category_-_Other_Letter.js", "harness/propertyhelper-verifywritable-array-length.js", + "language/comments/S7.4_A5.js", + "language/comments/S7.4_A6.js", "language/identifiers/part-unicode-15.1.0-escaped.js", "language/identifiers/part-unicode-15.1.0.js", "language/identifiers/part-unicode-16.0.0-class-escaped.js", @@ -49,13 +59,13 @@ "language/identifiers/start-unicode-8.0.0.js", "language/identifiers/start-unicode-9.0.0-escaped.js", "language/identifiers/start-unicode-9.0.0.js", - "staging/sm/Proxy/ownkeys-linear.js", - "staging/sm/class/compPropNames.js", - "staging/sm/regress/regress-610026.js", + "staging/sm/Array/length-truncate-nonconfigurable-sparse.js", + "staging/sm/Array/length-truncate-with-indexed.js", "staging/sm/Array/sort_small.js", - "staging/sm/String/normalize-generateddata-input.js", + "staging/sm/class/compPropNames.js", "staging/sm/JSON/parse-reviver-array-delete.js", - "staging/sm/Array/length-truncate-nonconfigurable-sparse.js", - "staging/sm/Array/length-truncate-with-indexed.js" + "staging/sm/Proxy/ownkeys-linear.js", + "staging/sm/regress/regress-610026.js", + "staging/sm/String/normalize-generateddata-input.js" ] -} \ No newline at end of file +}