LibJS: Propagate OOM from GetValueFromBuffer AO

This commit is contained in:
Shannon Booth 2023-06-28 21:00:05 +12:00 committed by Linus Groh
parent 49c8d22f50
commit 3bb15d3dae
5 changed files with 12 additions and 13 deletions

View file

@ -72,7 +72,7 @@ public:
Unordered
};
template<typename type>
Value get_value(size_t byte_index, bool is_typed_array, Order, bool is_little_endian = true);
ThrowCompletionOr<Value> get_value(size_t byte_index, bool is_typed_array, Order, bool is_little_endian = true);
template<typename type>
void set_value(size_t byte_index, Value value, bool is_typed_array, Order, bool is_little_endian = true);
template<typename T>
@ -149,7 +149,7 @@ static Value raw_bytes_to_numeric(VM& vm, ByteBuffer raw_value, bool is_little_e
// Implementation for 25.1.2.10 GetValueFromBuffer, used in TypedArray<T>::get_value_from_buffer().
template<typename T>
Value ArrayBuffer::get_value(size_t byte_index, [[maybe_unused]] bool is_typed_array, Order, bool is_little_endian)
ThrowCompletionOr<Value> ArrayBuffer::get_value(size_t byte_index, [[maybe_unused]] bool is_typed_array, Order, bool is_little_endian)
{
auto& vm = this->vm();
@ -157,8 +157,7 @@ Value ArrayBuffer::get_value(size_t byte_index, [[maybe_unused]] bool is_typed_a
// FIXME: Check for shared buffer
// FIXME: Propagate errors.
auto raw_value = MUST(buffer_impl().slice(byte_index, element_size));
auto raw_value = TRY_OR_THROW_OOM(vm, buffer_impl().slice(byte_index, element_size));
return raw_bytes_to_numeric<T>(vm, move(raw_value), is_little_endian);
}

View file

@ -189,7 +189,7 @@ static ThrowCompletionOr<void> initialize_typed_array_from_typed_array(VM& vm, T
// g. Repeat, while count > 0,
for (u32 i = 0; i < element_length; ++i) {
// i. Let value be GetValueFromBuffer(srcData, srcByteIndex, srcType, true, Unordered).
auto value = src_array.get_value_from_buffer(src_byte_index, ArrayBuffer::Order::Unordered);
auto value = MUST_OR_THROW_OOM(src_array.get_value_from_buffer(src_byte_index, ArrayBuffer::Order::Unordered));
// ii. Perform SetValueInBuffer(data, targetByteIndex, elementType, value, true, Unordered).
data->template set_value<T>(target_byte_index, value, true, ArrayBuffer::Order::Unordered);

View file

@ -54,7 +54,7 @@ public:
// 25.1.2.7 IsBigIntElementType ( type ), https://tc39.es/ecma262/#sec-isbigintelementtype
virtual bool is_bigint_element_type() const = 0;
// 25.1.2.10 GetValueFromBuffer ( arrayBuffer, byteIndex, type, isTypedArray, order [ , isLittleEndian ] ), https://tc39.es/ecma262/#sec-getvaluefrombuffer
virtual Value get_value_from_buffer(size_t byte_index, ArrayBuffer::Order, bool is_little_endian = true) const = 0;
virtual ThrowCompletionOr<Value> get_value_from_buffer(size_t byte_index, ArrayBuffer::Order, bool is_little_endian = true) const = 0;
// 25.1.2.12 SetValueInBuffer ( arrayBuffer, byteIndex, type, value, isTypedArray, order [ , isLittleEndian ] ), https://tc39.es/ecma262/#sec-setvalueinbuffer
virtual void set_value_in_buffer(size_t byte_index, Value, ArrayBuffer::Order, bool is_little_endian = true) = 0;
// 25.1.2.13 GetModifySetValueInBuffer ( arrayBuffer, byteIndex, type, value, op [ , isLittleEndian ] ), https://tc39.es/ecma262/#sec-getmodifysetvalueinbuffer
@ -100,7 +100,7 @@ inline bool is_valid_integer_index(TypedArrayBase const& typed_array, CanonicalI
// 10.4.5.10 IntegerIndexedElementGet ( O, index ), https://tc39.es/ecma262/#sec-integerindexedelementget
template<typename T>
inline Value integer_indexed_element_get(TypedArrayBase const& typed_array, CanonicalIndex property_index)
inline ThrowCompletionOr<Value> integer_indexed_element_get(TypedArrayBase const& typed_array, CanonicalIndex property_index)
{
// 1. If IsValidIntegerIndex(O, index) is false, return undefined.
if (!is_valid_integer_index(typed_array, property_index))
@ -195,7 +195,7 @@ public:
// b. If numericIndex is not undefined, then
if (!numeric_index.is_undefined()) {
// i. Let value be IntegerIndexedElementGet(O, numericIndex).
auto value = integer_indexed_element_get<T>(*this, numeric_index);
auto value = MUST_OR_THROW_OOM(integer_indexed_element_get<T>(*this, numeric_index));
// ii. If value is undefined, return undefined.
if (value.is_undefined())
@ -437,7 +437,7 @@ public:
return is_bigint;
}
Value get_value_from_buffer(size_t byte_index, ArrayBuffer::Order order, bool is_little_endian = true) const override { return viewed_array_buffer()->template get_value<T>(byte_index, true, order, is_little_endian); }
ThrowCompletionOr<Value> get_value_from_buffer(size_t byte_index, ArrayBuffer::Order order, bool is_little_endian = true) const override { return viewed_array_buffer()->template get_value<T>(byte_index, true, order, is_little_endian); }
void set_value_in_buffer(size_t byte_index, Value value, ArrayBuffer::Order order, bool is_little_endian = true) override { viewed_array_buffer()->template set_value<T>(byte_index, value, true, order, is_little_endian); }
ThrowCompletionOr<Value> get_modify_set_value_in_buffer(size_t byte_index, Value value, ReadWriteModifyFunction operation, bool is_little_endian = true) override { return viewed_array_buffer()->template get_modify_set_value<T>(byte_index, value, move(operation), is_little_endian); }

View file

@ -415,7 +415,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::copy_within)
// k. Repeat, while countBytes > 0,
for (; count_bytes > 0; --count_bytes) {
// i. Let value be GetValueFromBuffer(buffer, fromByteIndex, Uint8, true, Unordered).
auto value = buffer->get_value<u8>(from_byte_index, true, ArrayBuffer::Order::Unordered);
auto value = MUST_OR_THROW_OOM(buffer->get_value<u8>(from_byte_index, true, ArrayBuffer::Order::Unordered));
// ii. Perform SetValueInBuffer(buffer, toByteIndex, Uint8, value, true, Unordered).
buffer->set_value<u8>(to_byte_index, value, true, ArrayBuffer::Order::Unordered);
@ -1231,7 +1231,7 @@ static ThrowCompletionOr<void> set_typed_array_from_typed_array(VM& vm, TypedArr
// a. Repeat, while targetByteIndex < limit,
while (target_byte_index < limit) {
// i. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, srcType, true, Unordered).
auto value = source.get_value_from_buffer(source_byte_index, ArrayBuffer::Unordered);
auto value = MUST_OR_THROW_OOM(source.get_value_from_buffer(source_byte_index, ArrayBuffer::Unordered));
// ii. Perform SetValueInBuffer(targetBuffer, targetByteIndex, targetType, value, true, Unordered).
target.set_value_in_buffer(target_byte_index, value, ArrayBuffer::Unordered);
// iii. Set srcByteIndex to srcByteIndex + srcElementSize.
@ -1459,7 +1459,7 @@ JS_DEFINE_NATIVE_FUNCTION(TypedArrayPrototype::slice)
// ix. Repeat, while targetByteIndex < limit,
for (; target_byte_index < limit.value(); ++source_byte_index, ++target_byte_index) {
// 1. Let value be GetValueFromBuffer(srcBuffer, srcByteIndex, Uint8, true, Unordered).
auto value = source_buffer.get_value<u8>(source_byte_index.value(), true, ArrayBuffer::Unordered);
auto value = MUST_OR_THROW_OOM(source_buffer.get_value<u8>(source_byte_index.value(), true, ArrayBuffer::Unordered));
// 2. Perform SetValueInBuffer(targetBuffer, targetByteIndex, Uint8, value, true, Unordered).
target_buffer.set_value<u8>(target_byte_index, value, true, ArrayBuffer::Unordered);

View file

@ -74,7 +74,7 @@ ErrorOr<ByteBuffer> get_buffer_source_copy(JS::Object const& buffer_source)
// 9. For i in the range offset to offset + length 1, inclusive, set bytes[i offset] to ! GetValueFromBuffer(esArrayBuffer, i, Uint8, true, Unordered).
for (u64 i = offset; i < offset + length; ++i) {
auto value = es_array_buffer->get_value<u8>(i, true, JS::ArrayBuffer::Unordered);
auto value = es_array_buffer->get_value<u8>(i, true, JS::ArrayBuffer::Unordered).release_allocated_value_but_fixme_should_propagate_errors();
bytes[i - offset] = static_cast<u8>(value.as_double());
}