mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:32:44 +00:00 
			
		
		
		
	LibJS: Add spec comments to TypedArrayPrototype
This commit is contained in:
		
							parent
							
								
									aefa053473
								
							
						
					
					
						commit
						89bcc05a0d
					
				
					 1 changed files with 119 additions and 22 deletions
				
			
		|  | @ -1,5 +1,5 @@ | ||||||
| /*
 | /*
 | ||||||
|  * Copyright (c) 2020-2022, Linus Groh <linusg@serenityos.org> |  * Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org> | ||||||
|  * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org> |  * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org> | ||||||
|  * Copyright (c) 2021-2022, Idan Horowitz <idan.horowitz@serenityos.org> |  * Copyright (c) 2021-2022, Idan Horowitz <idan.horowitz@serenityos.org> | ||||||
|  * |  * | ||||||
|  | @ -169,52 +169,101 @@ static ThrowCompletionOr<TypedArrayBase*> typed_array_species_create(VM& vm, Typ | ||||||
| // 23.2.3.1 %TypedArray%.prototype.at ( index ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.at
 | // 23.2.3.1 %TypedArray%.prototype.at ( index ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.at
 | ||||||
| JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::at) | JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::at) | ||||||
| { | { | ||||||
|  |     // 1. Let O be the this value.
 | ||||||
|  |     // 2. Perform ? ValidateTypedArray(O).
 | ||||||
|     auto* typed_array = TRY(validate_typed_array_from_this(vm)); |     auto* typed_array = TRY(validate_typed_array_from_this(vm)); | ||||||
|  | 
 | ||||||
|  |     // 3. Let len be O.[[ArrayLength]].
 | ||||||
|     auto length = typed_array->array_length(); |     auto length = typed_array->array_length(); | ||||||
|  | 
 | ||||||
|  |     // 4. Let relativeIndex be ? ToIntegerOrInfinity(index).
 | ||||||
|     auto relative_index = TRY(vm.argument(0).to_integer_or_infinity(vm)); |     auto relative_index = TRY(vm.argument(0).to_integer_or_infinity(vm)); | ||||||
|  | 
 | ||||||
|     if (Value(relative_index).is_infinity()) |     if (Value(relative_index).is_infinity()) | ||||||
|         return js_undefined(); |         return js_undefined(); | ||||||
|  | 
 | ||||||
|     Checked<size_t> index { 0 }; |     Checked<size_t> index { 0 }; | ||||||
|  | 
 | ||||||
|  |     // 5. If relativeIndex ≥ 0, then
 | ||||||
|     if (relative_index >= 0) { |     if (relative_index >= 0) { | ||||||
|  |         // a. Let k be relativeIndex.
 | ||||||
|         index += relative_index; |         index += relative_index; | ||||||
|     } else { |     } | ||||||
|  |     // 6. Else,
 | ||||||
|  |     else { | ||||||
|  |         // a. Let k be len + relativeIndex.
 | ||||||
|         index += length; |         index += length; | ||||||
|         index -= -relative_index; |         index -= -relative_index; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     // 7. If k < 0 or k ≥ len, return undefined.
 | ||||||
|     if (index.has_overflow() || index.value() >= length) |     if (index.has_overflow() || index.value() >= length) | ||||||
|         return js_undefined(); |         return js_undefined(); | ||||||
|     return TRY(typed_array->get(index.value())); | 
 | ||||||
|  |     // 8. Return ! Get(O, ! ToString(𝔽(k))).
 | ||||||
|  |     return MUST(typed_array->get(index.value())); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // 23.2.3.2 get %TypedArray%.prototype.buffer, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.buffer
 | // 23.2.3.2 get %TypedArray%.prototype.buffer, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.buffer
 | ||||||
| JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::buffer_getter) | JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::buffer_getter) | ||||||
| { | { | ||||||
|  |     // 1. Let O be the this value.
 | ||||||
|  |     // 2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
 | ||||||
|     auto* typed_array = TRY(typed_array_from_this(vm)); |     auto* typed_array = TRY(typed_array_from_this(vm)); | ||||||
|     auto* array_buffer = typed_array->viewed_array_buffer(); | 
 | ||||||
|     VERIFY(array_buffer); |     // 3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
 | ||||||
|     return Value(array_buffer); |     // 4. Let buffer be O.[[ViewedArrayBuffer]].
 | ||||||
|  |     auto* buffer = typed_array->viewed_array_buffer(); | ||||||
|  |     VERIFY(buffer); | ||||||
|  | 
 | ||||||
|  |     // 5. Return buffer.
 | ||||||
|  |     return Value(buffer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // 23.2.3.3 get %TypedArray%.prototype.byteLength, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.bytelength
 | // 23.2.3.3 get %TypedArray%.prototype.byteLength, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.bytelength
 | ||||||
| JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::byte_length_getter) | JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::byte_length_getter) | ||||||
| { | { | ||||||
|  |     // 1. Let O be the this value.
 | ||||||
|  |     // 2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
 | ||||||
|     auto* typed_array = TRY(typed_array_from_this(vm)); |     auto* typed_array = TRY(typed_array_from_this(vm)); | ||||||
|     auto* array_buffer = typed_array->viewed_array_buffer(); | 
 | ||||||
|     VERIFY(array_buffer); |     // 3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
 | ||||||
|     if (array_buffer->is_detached()) |     // 4. Let buffer be O.[[ViewedArrayBuffer]].
 | ||||||
|  |     auto* buffer = typed_array->viewed_array_buffer(); | ||||||
|  |     VERIFY(buffer); | ||||||
|  | 
 | ||||||
|  |     // 5. If IsDetachedBuffer(buffer) is true, return +0𝔽.
 | ||||||
|  |     if (buffer->is_detached()) | ||||||
|         return Value(0); |         return Value(0); | ||||||
|     return Value(typed_array->byte_length()); | 
 | ||||||
|  |     // 6. Let size be O.[[ByteLength]].
 | ||||||
|  |     auto size = typed_array->byte_length(); | ||||||
|  | 
 | ||||||
|  |     // 7. Return 𝔽(size).
 | ||||||
|  |     return Value(size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // 23.2.3.4 get %TypedArray%.prototype.byteOffset, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.byteoffset
 | // 23.2.3.4 get %TypedArray%.prototype.byteOffset, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.byteoffset
 | ||||||
| JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::byte_offset_getter) | JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::byte_offset_getter) | ||||||
| { | { | ||||||
|  |     // 1. Let O be the this value.
 | ||||||
|  |     // 2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
 | ||||||
|     auto* typed_array = TRY(typed_array_from_this(vm)); |     auto* typed_array = TRY(typed_array_from_this(vm)); | ||||||
|     auto* array_buffer = typed_array->viewed_array_buffer(); | 
 | ||||||
|     VERIFY(array_buffer); |     // 3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
 | ||||||
|     if (array_buffer->is_detached()) |     // 4. Let buffer be O.[[ViewedArrayBuffer]].
 | ||||||
|  |     auto* buffer = typed_array->viewed_array_buffer(); | ||||||
|  |     VERIFY(buffer); | ||||||
|  | 
 | ||||||
|  |     // 5. If IsDetachedBuffer(buffer) is true, return +0𝔽.
 | ||||||
|  |     if (buffer->is_detached()) | ||||||
|         return Value(0); |         return Value(0); | ||||||
|     return Value(typed_array->byte_offset()); | 
 | ||||||
|  |     // 6. Let offset be O.[[ByteOffset]].
 | ||||||
|  |     auto offset = typed_array->byte_offset(); | ||||||
|  | 
 | ||||||
|  |     // 7. Return 𝔽(offset).
 | ||||||
|  |     return Value(offset); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // 23.2.3.6 %TypedArray%.prototype.copyWithin ( target, start [ , end ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.copywithin
 | // 23.2.3.6 %TypedArray%.prototype.copyWithin ( target, start [ , end ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.copywithin
 | ||||||
|  | @ -801,55 +850,91 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::keys) | ||||||
| // 23.2.3.20 %TypedArray%.prototype.lastIndexOf ( searchElement [ , fromIndex ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.lastindexof
 | // 23.2.3.20 %TypedArray%.prototype.lastIndexOf ( searchElement [ , fromIndex ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.lastindexof
 | ||||||
| JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::last_index_of) | JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::last_index_of) | ||||||
| { | { | ||||||
|     auto typed_array = TRY(validate_typed_array_from_this(vm)); |     auto search_element = vm.argument(0); | ||||||
|  |     auto from_index = vm.argument(1); | ||||||
| 
 | 
 | ||||||
|  |     // 1. Let O be the this value.
 | ||||||
|  |     // 2. Perform ? ValidateTypedArray(O).
 | ||||||
|  |     auto* typed_array = TRY(validate_typed_array_from_this(vm)); | ||||||
|  | 
 | ||||||
|  |     // 3. Let len be O.[[ArrayLength]].
 | ||||||
|     auto length = typed_array->array_length(); |     auto length = typed_array->array_length(); | ||||||
| 
 | 
 | ||||||
|  |     // 4. If len = 0, return -1𝔽.
 | ||||||
|     if (length == 0) |     if (length == 0) | ||||||
|         return Value(-1); |         return Value(-1); | ||||||
| 
 | 
 | ||||||
|     double n; |     double n; | ||||||
|  | 
 | ||||||
|  |     // 5. If fromIndex is present, let n be ? ToIntegerOrInfinity(fromIndex); else let n be len - 1.
 | ||||||
|     if (vm.argument_count() > 1) |     if (vm.argument_count() > 1) | ||||||
|         n = TRY(vm.argument(1).to_integer_or_infinity(vm)); |         n = TRY(from_index.to_integer_or_infinity(vm)); | ||||||
|     else |     else | ||||||
|         n = length - 1; |         n = length - 1; | ||||||
| 
 | 
 | ||||||
|  |     // 6. If n = -∞, return -1𝔽.
 | ||||||
|     if (Value(n).is_negative_infinity()) |     if (Value(n).is_negative_infinity()) | ||||||
|         return Value(-1); |         return Value(-1); | ||||||
| 
 | 
 | ||||||
|     i32 k; |     i32 k; | ||||||
|  | 
 | ||||||
|  |     // 7. If n ≥ 0, then
 | ||||||
|     if (n >= 0) { |     if (n >= 0) { | ||||||
|  |         // a. Let k be min(n, len - 1).
 | ||||||
|         k = min(n, (i32)length - 1); |         k = min(n, (i32)length - 1); | ||||||
|     } else { |     } | ||||||
|  |     // 8. Else,
 | ||||||
|  |     else { | ||||||
|  |         // a. Let k be len + n.
 | ||||||
|         auto relative_k = length + n; |         auto relative_k = length + n; | ||||||
|         if (relative_k < 0) // ensures we dont underflow `k`
 |         if (relative_k < 0) // ensures we dont underflow `k`
 | ||||||
|             relative_k = -1; |             relative_k = -1; | ||||||
|         k = relative_k; |         k = relative_k; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     auto search_element = vm.argument(0); |     // 9. Repeat, while k ≥ 0,
 | ||||||
|     for (; k >= 0; --k) { |     for (; k >= 0; --k) { | ||||||
|  |         // a. Let kPresent be ! HasProperty(O, ! ToString(𝔽(k))).
 | ||||||
|         auto k_present = MUST(typed_array->has_property(k)); |         auto k_present = MUST(typed_array->has_property(k)); | ||||||
|  | 
 | ||||||
|  |         // b. If kPresent is true, then
 | ||||||
|         if (k_present) { |         if (k_present) { | ||||||
|  |             // i. Let elementK be ! Get(O, ! ToString(𝔽(k))).
 | ||||||
|             auto element_k = MUST(typed_array->get(k)); |             auto element_k = MUST(typed_array->get(k)); | ||||||
| 
 | 
 | ||||||
|  |             // ii. If IsStrictlyEqual(searchElement, elementK) is true, return 𝔽(k).
 | ||||||
|             if (is_strictly_equal(search_element, element_k)) |             if (is_strictly_equal(search_element, element_k)) | ||||||
|                 return Value(k); |                 return Value(k); | ||||||
|         } |         } | ||||||
|  | 
 | ||||||
|  |         // c. Set k to k - 1.
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // 10. Return -1𝔽.
 | ||||||
|     return Value(-1); |     return Value(-1); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // 23.2.3.21 get %TypedArray%.prototype.length, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.length
 | // 23.2.3.21 get %TypedArray%.prototype.length, https://tc39.es/ecma262/#sec-get-%typedarray%.prototype.length
 | ||||||
| JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::length_getter) | JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::length_getter) | ||||||
| { | { | ||||||
|  |     // 1. Let O be the this value.
 | ||||||
|  |     // 2. Perform ? RequireInternalSlot(O, [[TypedArrayName]]).
 | ||||||
|     auto* typed_array = TRY(typed_array_from_this(vm)); |     auto* typed_array = TRY(typed_array_from_this(vm)); | ||||||
|     auto* array_buffer = typed_array->viewed_array_buffer(); | 
 | ||||||
|     VERIFY(array_buffer); |     // 3. Assert: O has [[ViewedArrayBuffer]] and [[ArrayLength]] internal slots.
 | ||||||
|     if (array_buffer->is_detached()) |     // 4. Let buffer be O.[[ViewedArrayBuffer]].
 | ||||||
|  |     auto* buffer = typed_array->viewed_array_buffer(); | ||||||
|  |     VERIFY(buffer); | ||||||
|  | 
 | ||||||
|  |     // 5. If IsDetachedBuffer(buffer) is true, return +0𝔽.
 | ||||||
|  |     if (buffer->is_detached()) | ||||||
|         return Value(0); |         return Value(0); | ||||||
|     return Value(typed_array->array_length()); | 
 | ||||||
|  |     // 6. Let length be O.[[ArrayLength]].
 | ||||||
|  |     auto length = typed_array->array_length(); | ||||||
|  | 
 | ||||||
|  |     // 7. Return 𝔽(length).
 | ||||||
|  |     return Value(length); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // 23.2.3.22 %TypedArray%.prototype.map ( callbackfn [ , thisArg ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.map
 | // 23.2.3.22 %TypedArray%.prototype.map ( callbackfn [ , thisArg ] ), https://tc39.es/ecma262/#sec-%typedarray%.prototype.map
 | ||||||
|  | @ -1611,6 +1696,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_reversed) | ||||||
| JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_sorted) | JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_sorted) | ||||||
| { | { | ||||||
|     auto comparefn = vm.argument(0); |     auto comparefn = vm.argument(0); | ||||||
|  | 
 | ||||||
|     // 1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
 |     // 1. If comparefn is not undefined and IsCallable(comparefn) is false, throw a TypeError exception.
 | ||||||
|     if (!comparefn.is_undefined() && !comparefn.is_function()) |     if (!comparefn.is_undefined() && !comparefn.is_function()) | ||||||
|         return vm.throw_completion<TypeError>(ErrorType::NotAFunction, comparefn); |         return vm.throw_completion<TypeError>(ErrorType::NotAFunction, comparefn); | ||||||
|  | @ -1647,6 +1733,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_sorted) | ||||||
|         // b. Set j to j + 1.
 |         // b. Set j to j + 1.
 | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // 11. Return A.
 | ||||||
|     return return_array; |     return return_array; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1730,12 +1817,22 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::with) | ||||||
| // 23.2.3.38 get %TypedArray%.prototype [ @@toStringTag ], https://tc39.es/ecma262/#sec-get-%typedarray%.prototype-@@tostringtag
 | // 23.2.3.38 get %TypedArray%.prototype [ @@toStringTag ], https://tc39.es/ecma262/#sec-get-%typedarray%.prototype-@@tostringtag
 | ||||||
| JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_string_tag_getter) | JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::to_string_tag_getter) | ||||||
| { | { | ||||||
|  |     // 1. Let O be the this value.
 | ||||||
|     auto this_value = vm.this_value(); |     auto this_value = vm.this_value(); | ||||||
|  | 
 | ||||||
|  |     // 2. If O is not an Object, return undefined.
 | ||||||
|     if (!this_value.is_object()) |     if (!this_value.is_object()) | ||||||
|         return js_undefined(); |         return js_undefined(); | ||||||
|  | 
 | ||||||
|     auto& this_object = this_value.as_object(); |     auto& this_object = this_value.as_object(); | ||||||
|  | 
 | ||||||
|  |     // 3. If O does not have a [[TypedArrayName]] internal slot, return undefined.
 | ||||||
|     if (!this_object.is_typed_array()) |     if (!this_object.is_typed_array()) | ||||||
|         return js_undefined(); |         return js_undefined(); | ||||||
|  | 
 | ||||||
|  |     // 4. Let name be O.[[TypedArrayName]].
 | ||||||
|  |     // 5. Assert: name is a String.
 | ||||||
|  |     // 6. Return name.
 | ||||||
|     return PrimitiveString::create(vm, static_cast<TypedArrayBase&>(this_object).element_name()); |     return PrimitiveString::create(vm, static_cast<TypedArrayBase&>(this_object).element_name()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Linus Groh
						Linus Groh