mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 10:48:11 +00:00
LibJS: Rename TypedArray element get and set methods
This renames IntegerIndexedElementGet to TypedArrayGetElement, and IntegerIndexedElementSet to TypedArraySetElement. This also renames the indexedPosition variable inside these method definitions to byteIndexInBuffer. These are part of a couple editorial changes in the ECMA-262 spec. See:03e4410
a1a4d48
The remainder of the changes in those commits apply to the resizable ArrayBuffer spec, which is not implemented in LibJS as of this commit.
This commit is contained in:
parent
4f32392426
commit
98cdf36fb0
3 changed files with 48 additions and 49 deletions
|
@ -23,7 +23,7 @@ namespace JS::Bytecode {
|
||||||
// NOTE: This function assumes that the index is valid within the TypedArray,
|
// NOTE: This function assumes that the index is valid within the TypedArray,
|
||||||
// and that the TypedArray is not detached.
|
// and that the TypedArray is not detached.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline Value fast_integer_indexed_element_get(TypedArrayBase& typed_array, u32 index)
|
inline Value fast_typed_array_get_element(TypedArrayBase& typed_array, u32 index)
|
||||||
{
|
{
|
||||||
Checked<u32> offset_into_array_buffer = index;
|
Checked<u32> offset_into_array_buffer = index;
|
||||||
offset_into_array_buffer *= sizeof(T);
|
offset_into_array_buffer *= sizeof(T);
|
||||||
|
@ -41,7 +41,7 @@ inline Value fast_integer_indexed_element_get(TypedArrayBase& typed_array, u32 i
|
||||||
// NOTE: This function assumes that the index is valid within the TypedArray,
|
// NOTE: This function assumes that the index is valid within the TypedArray,
|
||||||
// and that the TypedArray is not detached.
|
// and that the TypedArray is not detached.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void fast_integer_indexed_element_set(TypedArrayBase& typed_array, u32 index, T value)
|
inline void fast_typed_array_set_element(TypedArrayBase& typed_array, u32 index, T value)
|
||||||
{
|
{
|
||||||
Checked<u32> offset_into_array_buffer = index;
|
Checked<u32> offset_into_array_buffer = index;
|
||||||
offset_into_array_buffer *= sizeof(T);
|
offset_into_array_buffer *= sizeof(T);
|
||||||
|
@ -117,23 +117,22 @@ ThrowCompletionOr<Value> get_by_value(VM& vm, Value base_value, Value property_k
|
||||||
// For typed arrays:
|
// For typed arrays:
|
||||||
if (object.is_typed_array()) {
|
if (object.is_typed_array()) {
|
||||||
auto& typed_array = static_cast<TypedArrayBase&>(object);
|
auto& typed_array = static_cast<TypedArrayBase&>(object);
|
||||||
|
|
||||||
if (!typed_array.viewed_array_buffer()->is_detached() && index < typed_array.array_length()) {
|
if (!typed_array.viewed_array_buffer()->is_detached() && index < typed_array.array_length()) {
|
||||||
switch (typed_array.kind()) {
|
switch (typed_array.kind()) {
|
||||||
case TypedArrayBase::Kind::Uint8Array:
|
case TypedArrayBase::Kind::Uint8Array:
|
||||||
return fast_integer_indexed_element_get<u8>(typed_array, index);
|
return fast_typed_array_get_element<u8>(typed_array, index);
|
||||||
case TypedArrayBase::Kind::Uint16Array:
|
case TypedArrayBase::Kind::Uint16Array:
|
||||||
return fast_integer_indexed_element_get<u16>(typed_array, index);
|
return fast_typed_array_get_element<u16>(typed_array, index);
|
||||||
case TypedArrayBase::Kind::Uint32Array:
|
case TypedArrayBase::Kind::Uint32Array:
|
||||||
return fast_integer_indexed_element_get<u32>(typed_array, index);
|
return fast_typed_array_get_element<u32>(typed_array, index);
|
||||||
case TypedArrayBase::Kind::Int8Array:
|
case TypedArrayBase::Kind::Int8Array:
|
||||||
return fast_integer_indexed_element_get<i8>(typed_array, index);
|
return fast_typed_array_get_element<i8>(typed_array, index);
|
||||||
case TypedArrayBase::Kind::Int16Array:
|
case TypedArrayBase::Kind::Int16Array:
|
||||||
return fast_integer_indexed_element_get<i16>(typed_array, index);
|
return fast_typed_array_get_element<i16>(typed_array, index);
|
||||||
case TypedArrayBase::Kind::Int32Array:
|
case TypedArrayBase::Kind::Int32Array:
|
||||||
return fast_integer_indexed_element_get<i32>(typed_array, index);
|
return fast_typed_array_get_element<i32>(typed_array, index);
|
||||||
case TypedArrayBase::Kind::Uint8ClampedArray:
|
case TypedArrayBase::Kind::Uint8ClampedArray:
|
||||||
return fast_integer_indexed_element_get<u8>(typed_array, index);
|
return fast_typed_array_get_element<u8>(typed_array, index);
|
||||||
default:
|
default:
|
||||||
// FIXME: Support more TypedArray kinds.
|
// FIXME: Support more TypedArray kinds.
|
||||||
break;
|
break;
|
||||||
|
@ -144,7 +143,7 @@ ThrowCompletionOr<Value> get_by_value(VM& vm, Value base_value, Value property_k
|
||||||
switch (typed_array.kind()) {
|
switch (typed_array.kind()) {
|
||||||
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
|
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
|
||||||
case TypedArrayBase::Kind::ClassName: \
|
case TypedArrayBase::Kind::ClassName: \
|
||||||
return integer_indexed_element_get<Type>(typed_array, canonical_index);
|
return typed_array_get_element<Type>(typed_array, canonical_index);
|
||||||
JS_ENUMERATE_TYPED_ARRAYS
|
JS_ENUMERATE_TYPED_ARRAYS
|
||||||
#undef __JS_ENUMERATE
|
#undef __JS_ENUMERATE
|
||||||
}
|
}
|
||||||
|
@ -399,25 +398,25 @@ ThrowCompletionOr<void> put_by_value(VM& vm, Value base, Value property_key_valu
|
||||||
if (!typed_array.viewed_array_buffer()->is_detached() && index < typed_array.array_length() && value.is_int32()) {
|
if (!typed_array.viewed_array_buffer()->is_detached() && index < typed_array.array_length() && value.is_int32()) {
|
||||||
switch (typed_array.kind()) {
|
switch (typed_array.kind()) {
|
||||||
case TypedArrayBase::Kind::Uint8Array:
|
case TypedArrayBase::Kind::Uint8Array:
|
||||||
fast_integer_indexed_element_set<u8>(typed_array, index, static_cast<u8>(value.as_i32()));
|
fast_typed_array_set_element<u8>(typed_array, index, static_cast<u8>(value.as_i32()));
|
||||||
return {};
|
return {};
|
||||||
case TypedArrayBase::Kind::Uint16Array:
|
case TypedArrayBase::Kind::Uint16Array:
|
||||||
fast_integer_indexed_element_set<u16>(typed_array, index, static_cast<u16>(value.as_i32()));
|
fast_typed_array_set_element<u16>(typed_array, index, static_cast<u16>(value.as_i32()));
|
||||||
return {};
|
return {};
|
||||||
case TypedArrayBase::Kind::Uint32Array:
|
case TypedArrayBase::Kind::Uint32Array:
|
||||||
fast_integer_indexed_element_set<u32>(typed_array, index, static_cast<u32>(value.as_i32()));
|
fast_typed_array_set_element<u32>(typed_array, index, static_cast<u32>(value.as_i32()));
|
||||||
return {};
|
return {};
|
||||||
case TypedArrayBase::Kind::Int8Array:
|
case TypedArrayBase::Kind::Int8Array:
|
||||||
fast_integer_indexed_element_set<i8>(typed_array, index, static_cast<i8>(value.as_i32()));
|
fast_typed_array_set_element<i8>(typed_array, index, static_cast<i8>(value.as_i32()));
|
||||||
return {};
|
return {};
|
||||||
case TypedArrayBase::Kind::Int16Array:
|
case TypedArrayBase::Kind::Int16Array:
|
||||||
fast_integer_indexed_element_set<i16>(typed_array, index, static_cast<i16>(value.as_i32()));
|
fast_typed_array_set_element<i16>(typed_array, index, static_cast<i16>(value.as_i32()));
|
||||||
return {};
|
return {};
|
||||||
case TypedArrayBase::Kind::Int32Array:
|
case TypedArrayBase::Kind::Int32Array:
|
||||||
fast_integer_indexed_element_set<i32>(typed_array, index, value.as_i32());
|
fast_typed_array_set_element<i32>(typed_array, index, value.as_i32());
|
||||||
return {};
|
return {};
|
||||||
case TypedArrayBase::Kind::Uint8ClampedArray:
|
case TypedArrayBase::Kind::Uint8ClampedArray:
|
||||||
fast_integer_indexed_element_set<u8>(typed_array, index, clamp(value.as_i32(), 0, 255));
|
fast_typed_array_set_element<u8>(typed_array, index, clamp(value.as_i32(), 0, 255));
|
||||||
return {};
|
return {};
|
||||||
default:
|
default:
|
||||||
// FIXME: Support more TypedArray kinds.
|
// FIXME: Support more TypedArray kinds.
|
||||||
|
@ -428,7 +427,7 @@ ThrowCompletionOr<void> put_by_value(VM& vm, Value base, Value property_key_valu
|
||||||
switch (typed_array.kind()) {
|
switch (typed_array.kind()) {
|
||||||
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
|
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
|
||||||
case TypedArrayBase::Kind::ClassName: \
|
case TypedArrayBase::Kind::ClassName: \
|
||||||
return integer_indexed_element_set<Type>(typed_array, canonical_index, value);
|
return typed_array_set_element<Type>(typed_array, canonical_index, value);
|
||||||
JS_ENUMERATE_TYPED_ARRAYS
|
JS_ENUMERATE_TYPED_ARRAYS
|
||||||
#undef __JS_ENUMERATE
|
#undef __JS_ENUMERATE
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,9 +110,9 @@ inline bool is_valid_integer_index(TypedArrayBase const& typed_array, CanonicalI
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10.4.5.15 IntegerIndexedElementGet ( O, index ), https://tc39.es/ecma262/#sec-integerindexedelementget
|
// 10.4.5.15 TypedArrayGetElement ( O, index ), https://tc39.es/ecma262/#sec-typedarraygetelement
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline ThrowCompletionOr<Value> integer_indexed_element_get(TypedArrayBase const& typed_array, CanonicalIndex property_index)
|
inline ThrowCompletionOr<Value> typed_array_get_element(TypedArrayBase const& typed_array, CanonicalIndex property_index)
|
||||||
{
|
{
|
||||||
// 1. If IsValidIntegerIndex(O, index) is false, return undefined.
|
// 1. If IsValidIntegerIndex(O, index) is false, return undefined.
|
||||||
if (!is_valid_integer_index(typed_array, property_index))
|
if (!is_valid_integer_index(typed_array, property_index))
|
||||||
|
@ -122,26 +122,26 @@ inline ThrowCompletionOr<Value> integer_indexed_element_get(TypedArrayBase const
|
||||||
auto offset = typed_array.byte_offset();
|
auto offset = typed_array.byte_offset();
|
||||||
|
|
||||||
// 3. Let elementSize be TypedArrayElementSize(O).
|
// 3. Let elementSize be TypedArrayElementSize(O).
|
||||||
// 4. Let indexedPosition be (ℝ(index) × elementSize) + offset.
|
// 4. Let byteIndexInBuffer be (ℝ(index) × elementSize) + offset.
|
||||||
Checked<size_t> indexed_position = property_index.as_index();
|
Checked<size_t> byte_index_in_buffer = property_index.as_index();
|
||||||
indexed_position *= typed_array.element_size();
|
byte_index_in_buffer *= typed_array.element_size();
|
||||||
indexed_position += offset;
|
byte_index_in_buffer += offset;
|
||||||
// FIXME: Not exactly sure what we should do when overflow occurs.
|
// FIXME: Not exactly sure what we should do when overflow occurs.
|
||||||
// Just return as if it's an invalid index for now.
|
// Just return as if it's an invalid index for now.
|
||||||
if (indexed_position.has_overflow()) {
|
if (byte_index_in_buffer.has_overflow()) {
|
||||||
dbgln("integer_indexed_element_get(): indexed_position overflowed, returning as if it's an invalid index.");
|
dbgln("typed_array_get_element(): byte_index_in_buffer overflowed, returning as if it's an invalid index.");
|
||||||
return js_undefined();
|
return js_undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. Let elementType be TypedArrayElementType(O).
|
// 5. Let elementType be TypedArrayElementType(O).
|
||||||
// 6. Return GetValueFromBuffer(O.[[ViewedArrayBuffer]], indexedPosition, elementType, true, Unordered).
|
// 6. Return GetValueFromBuffer(O.[[ViewedArrayBuffer]], byteIndexInBuffer, elementType, true, unordered).
|
||||||
return typed_array.viewed_array_buffer()->template get_value<T>(indexed_position.value(), true, ArrayBuffer::Order::Unordered);
|
return typed_array.viewed_array_buffer()->template get_value<T>(byte_index_in_buffer.value(), true, ArrayBuffer::Order::Unordered);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10.4.5.16 IntegerIndexedElementSet ( O, index, value ), https://tc39.es/ecma262/#sec-integerindexedelementset
|
// 10.4.5.16 TypedArraySetElement ( O, index, value ), https://tc39.es/ecma262/#sec-typedarraysetelement
|
||||||
// NOTE: In error cases, the function will return as if it succeeded.
|
// NOTE: In error cases, the function will return as if it succeeded.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline ThrowCompletionOr<void> integer_indexed_element_set(TypedArrayBase& typed_array, CanonicalIndex property_index, Value value)
|
inline ThrowCompletionOr<void> typed_array_set_element(TypedArrayBase& typed_array, CanonicalIndex property_index, Value value)
|
||||||
{
|
{
|
||||||
VERIFY(!value.is_empty());
|
VERIFY(!value.is_empty());
|
||||||
auto& vm = typed_array.vm();
|
auto& vm = typed_array.vm();
|
||||||
|
@ -164,20 +164,20 @@ inline ThrowCompletionOr<void> integer_indexed_element_set(TypedArrayBase& typed
|
||||||
auto offset = typed_array.byte_offset();
|
auto offset = typed_array.byte_offset();
|
||||||
|
|
||||||
// b. Let elementSize be TypedArrayElementSize(O).
|
// b. Let elementSize be TypedArrayElementSize(O).
|
||||||
// c. Let indexedPosition be (ℝ(index) × elementSize) + offset.
|
// c. Let byteIndexInBuffer be (ℝ(index) × elementSize) + offset.
|
||||||
Checked<size_t> indexed_position = property_index.as_index();
|
Checked<size_t> byte_index_in_buffer = property_index.as_index();
|
||||||
indexed_position *= typed_array.element_size();
|
byte_index_in_buffer *= typed_array.element_size();
|
||||||
indexed_position += offset;
|
byte_index_in_buffer += offset;
|
||||||
// FIXME: Not exactly sure what we should do when overflow occurs.
|
// FIXME: Not exactly sure what we should do when overflow occurs.
|
||||||
// Just return as if it succeeded for now.
|
// Just return as if it succeeded for now.
|
||||||
if (indexed_position.has_overflow()) {
|
if (byte_index_in_buffer.has_overflow()) {
|
||||||
dbgln("integer_indexed_element_set(): indexed_position overflowed, returning as if succeeded.");
|
dbgln("typed_array_set_element(): byte_index_in_buffer overflowed, returning as if succeeded.");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// d. Let elementType be TypedArrayElementType(O).
|
// d. Let elementType be TypedArrayElementType(O).
|
||||||
// e. Perform SetValueInBuffer(O.[[ViewedArrayBuffer]], indexedPosition, elementType, numValue, true, Unordered).
|
// e. Perform SetValueInBuffer(O.[[ViewedArrayBuffer]], byteIndexInBuffer, elementType, numValue, true, unordered).
|
||||||
typed_array.viewed_array_buffer()->template set_value<T>(indexed_position.value(), num_value, true, ArrayBuffer::Order::Unordered);
|
typed_array.viewed_array_buffer()->template set_value<T>(byte_index_in_buffer.value(), num_value, true, ArrayBuffer::Order::Unordered);
|
||||||
|
|
||||||
// 4. Return unused.
|
// 4. Return unused.
|
||||||
return {};
|
return {};
|
||||||
|
@ -206,8 +206,8 @@ public:
|
||||||
auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
|
auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
|
||||||
// b. If numericIndex is not undefined, then
|
// b. If numericIndex is not undefined, then
|
||||||
if (!numeric_index.is_undefined()) {
|
if (!numeric_index.is_undefined()) {
|
||||||
// i. Let value be IntegerIndexedElementGet(O, numericIndex).
|
// i. Let value be TypedArrayGetElement(O, numericIndex).
|
||||||
auto value = MUST_OR_THROW_OOM(integer_indexed_element_get<T>(*this, numeric_index));
|
auto value = MUST_OR_THROW_OOM(typed_array_get_element<T>(*this, numeric_index));
|
||||||
|
|
||||||
// ii. If value is undefined, return undefined.
|
// ii. If value is undefined, return undefined.
|
||||||
if (value.is_undefined())
|
if (value.is_undefined())
|
||||||
|
@ -286,9 +286,9 @@ public:
|
||||||
if (property_descriptor.writable.has_value() && !*property_descriptor.writable)
|
if (property_descriptor.writable.has_value() && !*property_descriptor.writable)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// vi. If Desc has a [[Value]] field, perform ? IntegerIndexedElementSet(O, numericIndex, Desc.[[Value]]).
|
// vi. If Desc has a [[Value]] field, perform ? TypedArraySetElement(O, numericIndex, Desc.[[Value]]).
|
||||||
if (property_descriptor.value.has_value())
|
if (property_descriptor.value.has_value())
|
||||||
TRY(integer_indexed_element_set<T>(*this, numeric_index, *property_descriptor.value));
|
TRY(typed_array_set_element<T>(*this, numeric_index, *property_descriptor.value));
|
||||||
|
|
||||||
// vii. Return true.
|
// vii. Return true.
|
||||||
return true;
|
return true;
|
||||||
|
@ -316,8 +316,8 @@ public:
|
||||||
auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
|
auto numeric_index = canonical_numeric_index_string(property_key, CanonicalIndexMode::DetectNumericRoundtrip);
|
||||||
// b. If numericIndex is not undefined, then
|
// b. If numericIndex is not undefined, then
|
||||||
if (!numeric_index.is_undefined()) {
|
if (!numeric_index.is_undefined()) {
|
||||||
// i. Return IntegerIndexedElementGet(O, numericIndex).
|
// i. Return TypedArrayGetElement(O, numericIndex).
|
||||||
return integer_indexed_element_get<T>(*this, numeric_index);
|
return typed_array_get_element<T>(*this, numeric_index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,8 +345,8 @@ public:
|
||||||
if (!numeric_index.is_undefined()) {
|
if (!numeric_index.is_undefined()) {
|
||||||
// i. If SameValue(O, Receiver) is true, then
|
// i. If SameValue(O, Receiver) is true, then
|
||||||
if (same_value(this, receiver)) {
|
if (same_value(this, receiver)) {
|
||||||
// 1. Perform ? IntegerIndexedElementSet(O, numericIndex, V).
|
// 1. Perform ? TypedArraySetElement(O, numericIndex, V).
|
||||||
TRY(integer_indexed_element_set<T>(*this, numeric_index, value));
|
TRY(typed_array_set_element<T>(*this, numeric_index, value));
|
||||||
|
|
||||||
// 2. Return true.
|
// 2. Return true.
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1288,11 +1288,11 @@ static ThrowCompletionOr<void> set_typed_array_from_array_like(VM& vm, TypedArra
|
||||||
// NOTE: We verify above that target_offset + source_length is valid, so this cannot fail.
|
// NOTE: We verify above that target_offset + source_length is valid, so this cannot fail.
|
||||||
auto target_index = MUST(CanonicalIndex::from_double(vm, CanonicalIndex::Type::Index, target_offset + k));
|
auto target_index = MUST(CanonicalIndex::from_double(vm, CanonicalIndex::Type::Index, target_offset + k));
|
||||||
|
|
||||||
// d. Perform ? IntegerIndexedElementSet(target, targetIndex, value).
|
// d. Perform ? TypedArraySetElement(target, targetIndex, value).
|
||||||
// FIXME: This is very awkward.
|
// FIXME: This is very awkward.
|
||||||
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
|
#define __JS_ENUMERATE(ClassName, snake_name, PrototypeName, ConstructorName, Type) \
|
||||||
if (is<ClassName>(target)) \
|
if (is<ClassName>(target)) \
|
||||||
TRY(integer_indexed_element_set<Type>(target, target_index, value));
|
TRY(typed_array_set_element<Type>(target, target_index, value));
|
||||||
JS_ENUMERATE_TYPED_ARRAYS
|
JS_ENUMERATE_TYPED_ARRAYS
|
||||||
#undef __JS_ENUMERATE
|
#undef __JS_ENUMERATE
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue