summaryrefslogtreecommitdiff
path: root/Userland/Libraries
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2023-01-27 21:50:00 +0000
committerLinus Groh <mail@linusgroh.de>2023-01-28 00:41:18 +0000
commit39301cce707397a0f34580b1649cd066bed6e481 (patch)
tree9a9262a5b919a00c4f8b5a48512ab736c946bce4 /Userland/Libraries
parent814e7260f3d410ac65eec1bbf45260ff4f4b4f48 (diff)
downloadserenity-39301cce707397a0f34580b1649cd066bed6e481.zip
LibJS: Add spec comments to DataViewPrototype
Diffstat (limited to 'Userland/Libraries')
-rw-r--r--Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp170
1 files changed, 145 insertions, 25 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp b/Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp
index 5fb6cc62f6..102ca0ef4e 100644
--- a/Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp
+++ b/Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp
@@ -54,28 +54,44 @@ void DataViewPrototype::initialize(Realm& realm)
template<typename T>
static ThrowCompletionOr<Value> get_view_value(VM& vm, Value request_index, Value is_little_endian)
{
+ // 1. Perform ? RequireInternalSlot(view, [[DataView]]).
+ // 2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
auto* view = TRY(DataViewPrototype::typed_this_value(vm));
+
+ // 3. Let getIndex be ? ToIndex(requestIndex).
auto get_index = TRY(request_index.to_index(vm));
+
+ // 4. Set isLittleEndian to ToBoolean(isLittleEndian).
auto little_endian = is_little_endian.to_boolean();
+ // 5. Let buffer be view.[[ViewedArrayBuffer]].
auto buffer = view->viewed_array_buffer();
+
+ // 6. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
if (buffer->is_detached())
return vm.template throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
+ // 7. Let viewOffset be view.[[ByteOffset]].
auto view_offset = view->byte_offset();
+
+ // 8. Let viewSize be view.[[ByteLength]].
auto view_size = view->byte_length();
+ // 9. Let elementSize be the Element Size value specified in Table 68 for Element Type type.
auto element_size = sizeof(T);
+ // 11. Let bufferIndex be getIndex + viewOffset.
Checked<size_t> buffer_index = get_index;
buffer_index += view_offset;
Checked<size_t> end_index = get_index;
end_index += element_size;
+ // 10. If getIndex + elementSize > viewSize, throw a RangeError exception.
if (buffer_index.has_overflow() || end_index.has_overflow() || end_index.value() > view_size)
return vm.throw_completion<RangeError>(ErrorType::DataViewOutOfRangeByteOffset, get_index, view_size);
+ // 12. Return GetValueFromBuffer(buffer, bufferIndex, type, false, Unordered, isLittleEndian).
return buffer->get_value<T>(buffer_index.value(), false, ArrayBuffer::Order::Unordered, little_endian);
}
@@ -83,174 +99,278 @@ static ThrowCompletionOr<Value> get_view_value(VM& vm, Value request_index, Valu
template<typename T>
static ThrowCompletionOr<Value> set_view_value(VM& vm, Value request_index, Value is_little_endian, Value value)
{
+ // 1. Perform ? RequireInternalSlot(view, [[DataView]]).
+ // 2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
auto* view = TRY(DataViewPrototype::typed_this_value(vm));
+
+ // 3. Let getIndex be ? ToIndex(requestIndex).
auto get_index = TRY(request_index.to_index(vm));
Value number_value;
+
+ // 4. If IsBigIntElementType(type) is true, let numberValue be ? ToBigInt(value).
if constexpr (IsIntegral<T> && sizeof(T) == 8)
number_value = TRY(value.to_bigint(vm));
+ // 5. Otherwise, let numberValue be ? ToNumber(value).
else
number_value = TRY(value.to_number(vm));
+ // 6. Set isLittleEndian to ToBoolean(isLittleEndian).
auto little_endian = is_little_endian.to_boolean();
+ // 7. Let buffer be view.[[ViewedArrayBuffer]].
auto buffer = view->viewed_array_buffer();
+
+ // 8. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
if (buffer->is_detached())
return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
+ // 9. Let viewOffset be view.[[ByteOffset]].
auto view_offset = view->byte_offset();
+
+ // 10. Let viewSize be view.[[ByteLength]].
auto view_size = view->byte_length();
+ // 11. Let elementSize be the Element Size value specified in Table 68 for Element Type type.
auto element_size = sizeof(T);
+ // 13. Let bufferIndex be getIndex + viewOffset.
Checked<size_t> buffer_index = get_index;
buffer_index += view_offset;
Checked<size_t> end_index = get_index;
end_index += element_size;
+ // 12. If getIndex + elementSize > viewSize, throw a RangeError exception.
if (buffer_index.has_overflow() || end_index.has_overflow() || end_index.value() > view_size)
return vm.throw_completion<RangeError>(ErrorType::DataViewOutOfRangeByteOffset, get_index, view_size);
+ // 14. Perform SetValueInBuffer(buffer, bufferIndex, type, numberValue, false, Unordered, isLittleEndian).
buffer->set_value<T>(buffer_index.value(), number_value, false, ArrayBuffer::Order::Unordered, little_endian);
+ // 15. Return undefined.
return js_undefined();
}
+// 25.3.4.1 get DataView.prototype.buffer, https://tc39.es/ecma262/#sec-get-dataview.prototype.buffer
+JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::buffer_getter)
+{
+ // 1. Let O be the this value.
+ // 2. Perform ? RequireInternalSlot(O, [[DataView]]).
+ // 3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
+ auto* data_view = TRY(typed_this_value(vm));
+
+ // 4. Let buffer be O.[[ViewedArrayBuffer]].
+ // 5. Return buffer.
+ return data_view->viewed_array_buffer();
+}
+
+// 25.3.4.2 get DataView.prototype.byteLength, https://tc39.es/ecma262/#sec-get-dataview.prototype.bytelength
+JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::byte_length_getter)
+{
+ // 1. Let O be the this value.
+ // 2. Perform ? RequireInternalSlot(O, [[DataView]]).
+ // 3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
+ auto* data_view = TRY(typed_this_value(vm));
+
+ // 4. Let buffer be O.[[ViewedArrayBuffer]].
+ // 5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
+ if (data_view->viewed_array_buffer()->is_detached())
+ return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
+
+ // 6. Let size be O.[[ByteLength]].
+ // 7. Return 𝔽(size).
+ return Value(data_view->byte_length());
+}
+
+// 25.3.4.3 get DataView.prototype.byteOffset, https://tc39.es/ecma262/#sec-get-dataview.prototype.byteoffset
+JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::byte_offset_getter)
+{
+ // 1. Let O be the this value.
+ // 2. Perform ? RequireInternalSlot(O, [[DataView]]).
+ // 3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
+ auto* data_view = TRY(typed_this_value(vm));
+
+ // 4. Let buffer be O.[[ViewedArrayBuffer]].
+ // 5. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
+ if (data_view->viewed_array_buffer()->is_detached())
+ return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
+
+ // 6. Let offset be O.[[ByteOffset]].
+ // 7. Return 𝔽(offset).
+ return Value(data_view->byte_offset());
+}
+
// 25.3.4.5 DataView.prototype.getBigInt64 ( byteOffset [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.getbigint64
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::get_big_int_64)
{
+ // 1. Let v be the this value.
+ // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64).
return get_view_value<i64>(vm, vm.argument(0), vm.argument(1));
}
// 25.3.4.6 DataView.prototype.getBigUint64 ( byteOffset [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.getbiguint64
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::get_big_uint_64)
{
+ // 1. Let v be the this value.
+ // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigUint64).
return get_view_value<u64>(vm, vm.argument(0), vm.argument(1));
}
// 25.3.4.7 DataView.prototype.getFloat32 ( byteOffset [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.getfloat32
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::get_float_32)
{
+ // 1. Let v be the this value.
+ // 2. If littleEndian is not present, set littleEndian to false.
+ // 3. Return ? GetViewValue(v, byteOffset, littleEndian, Float32).
return get_view_value<float>(vm, vm.argument(0), vm.argument(1));
}
// 25.3.4.8 DataView.prototype.getFloat64 ( byteOffset [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.getfloat64
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::get_float_64)
{
+ // 1. Let v be the this value.
+ // 2. If littleEndian is not present, set littleEndian to false.
+ // 3. Return ? GetViewValue(v, byteOffset, littleEndian, Float64).
return get_view_value<double>(vm, vm.argument(0), vm.argument(1));
}
// 25.3.4.9 DataView.prototype.getInt8 ( byteOffset ), https://tc39.es/ecma262/#sec-dataview.prototype.getint8
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::get_int_8)
{
+ // 1. Let v be the this value.
+ // 2. Return ? GetViewValue(v, byteOffset, true, Int8).
return get_view_value<i8>(vm, vm.argument(0), Value(true));
}
// 25.3.4.10 DataView.prototype.getInt16 ( byteOffset [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.getint16
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::get_int_16)
{
+ // 1. Let v be the this value.
+ // 2. If littleEndian is not present, set littleEndian to false.
+ // 3. Return ? GetViewValue(v, byteOffset, littleEndian, Int16).
return get_view_value<i16>(vm, vm.argument(0), vm.argument(1));
}
// 25.3.4.11 DataView.prototype.getInt32 ( byteOffset [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.getint32
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::get_int_32)
{
+ // 1. Let v be the this value.
+ // 2. If littleEndian is not present, set littleEndian to false.
+ // 3. Return ? GetViewValue(v, byteOffset, littleEndian, Int32).
return get_view_value<i32>(vm, vm.argument(0), vm.argument(1));
}
// 25.3.4.12 DataView.prototype.getUint8 ( byteOffset ), https://tc39.es/ecma262/#sec-dataview.prototype.getuint8
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::get_uint_8)
{
+ // 1. Let v be the this value.
+ // 2. Return ? GetViewValue(v, byteOffset, true, Uint8).
return get_view_value<u8>(vm, vm.argument(0), Value(true));
}
// 25.3.4.13 DataView.prototype.getUint16 ( byteOffset [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.getuint16
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::get_uint_16)
{
+ // 1. Let v be the this value.
+ // 2. If littleEndian is not present, set littleEndian to false.
+ // 3. Return ? GetViewValue(v, byteOffset, littleEndian, Uint16).
return get_view_value<u16>(vm, vm.argument(0), vm.argument(1));
}
// 25.3.4.14 DataView.prototype.getUint32 ( byteOffset [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.getuint32
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::get_uint_32)
{
+ // 1. Let v be the this value.
+ // 2. If littleEndian is not present, set littleEndian to false.
+ // 3. Return ? GetViewValue(v, byteOffset, littleEndian, Uint32).
return get_view_value<u32>(vm, vm.argument(0), vm.argument(1));
}
// 25.3.4.15 DataView.prototype.setBigInt64 ( byteOffset, value [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.setbigint64
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::set_big_int_64)
{
+ // 1. Let v be the this value.
+ // 2. Return ? SetViewValue(v, byteOffset, littleEndian, BigInt64, value).
return set_view_value<i64>(vm, vm.argument(0), vm.argument(2), vm.argument(1));
}
+// 25.3.4.16 DataView.prototype.setBigUint64 ( byteOffset, value [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.setbiguint64
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::set_big_uint_64)
{
+ // 1. Let v be the this value.
+ // 2. Return ? SetViewValue(v, byteOffset, littleEndian, BigUint64, value).
return set_view_value<u64>(vm, vm.argument(0), vm.argument(2), vm.argument(1));
}
+// 25.3.4.17 DataView.prototype.setFloat32 ( byteOffset, value [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.setfloat32
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::set_float_32)
{
+ // 1. Let v be the this value.
+ // 2. If littleEndian is not present, set littleEndian to false.
+ // 3. Return ? SetViewValue(v, byteOffset, littleEndian, Float32, value).
return set_view_value<float>(vm, vm.argument(0), vm.argument(2), vm.argument(1));
}
+// 25.3.4.18 DataView.prototype.setFloat64 ( byteOffset, value [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.setfloat64
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::set_float_64)
{
+ // 1. Let v be the this value.
+ // 2. If littleEndian is not present, set littleEndian to false.
+ // 3. Return ? SetViewValue(v, byteOffset, littleEndian, Float64, value).
return set_view_value<double>(vm, vm.argument(0), vm.argument(2), vm.argument(1));
}
+// 25.3.4.19 DataView.prototype.setInt8 ( byteOffset, value ), https://tc39.es/ecma262/#sec-dataview.prototype.setint8
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::set_int_8)
{
+ // 1. Let v be the this value.
+ // 2. Return ? SetViewValue(v, byteOffset, true, Int8, value).
return set_view_value<i8>(vm, vm.argument(0), Value(true), vm.argument(1));
}
+// 25.3.4.20 DataView.prototype.setInt16 ( byteOffset, value [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.setint16
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::set_int_16)
{
+ // 1. Let v be the this value.
+ // 2. If littleEndian is not present, set littleEndian to false.
+ // 3. Return ? SetViewValue(v, byteOffset, littleEndian, Int16, value).
return set_view_value<i16>(vm, vm.argument(0), vm.argument(2), vm.argument(1));
}
+// 25.3.4.21 DataView.prototype.setInt32 ( byteOffset, value [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.setint32
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::set_int_32)
{
+ // 1. Let v be the this value.
+ // 2. If littleEndian is not present, set littleEndian to false.
+ // 3. Return ? SetViewValue(v, byteOffset, littleEndian, Int32, value).
return set_view_value<i32>(vm, vm.argument(0), vm.argument(2), vm.argument(1));
}
+// 25.3.4.22 DataView.prototype.setUint8 ( byteOffset, value ), https://tc39.es/ecma262/#sec-dataview.prototype.setuint8
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::set_uint_8)
{
+ // 1. Let v be the this value.
+ // 2. Return ? SetViewValue(v, byteOffset, true, Uint8, value).
return set_view_value<u8>(vm, vm.argument(0), Value(true), vm.argument(1));
}
+// 25.3.4.23 DataView.prototype.setUint16 ( byteOffset, value [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.setuint16
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::set_uint_16)
{
+ // 1. Let v be the this value.
+ // 2. If littleEndian is not present, set littleEndian to false.
+ // 3. Return ? SetViewValue(v, byteOffset, littleEndian, Uint16, value).
return set_view_value<u16>(vm, vm.argument(0), vm.argument(2), vm.argument(1));
}
+// 25.3.4.24 DataView.prototype.setUint32 ( byteOffset, value [ , littleEndian ] ), https://tc39.es/ecma262/#sec-dataview.prototype.setuint32
JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::set_uint_32)
{
+ // 1. Let v be the this value.
+ // 2. If littleEndian is not present, set littleEndian to false.
+ // 3. Return ? SetViewValue(v, byteOffset, littleEndian, Uint32, value).
return set_view_value<u32>(vm, vm.argument(0), vm.argument(2), vm.argument(1));
}
-// 25.3.4.1 get DataView.prototype.buffer, https://tc39.es/ecma262/#sec-get-dataview.prototype.buffer
-JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::buffer_getter)
-{
- auto* data_view = TRY(typed_this_value(vm));
- return data_view->viewed_array_buffer();
-}
-
-// 25.3.4.2 get DataView.prototype.byteLength, https://tc39.es/ecma262/#sec-get-dataview.prototype.bytelength
-JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::byte_length_getter)
-{
- auto* data_view = TRY(typed_this_value(vm));
- if (data_view->viewed_array_buffer()->is_detached())
- return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
- return Value(data_view->byte_length());
-}
-
-// 25.3.4.3 get DataView.prototype.byteOffset, https://tc39.es/ecma262/#sec-get-dataview.prototype.byteoffset
-JS_DEFINE_NATIVE_FUNCTION(DataViewPrototype::byte_offset_getter)
-{
- auto* data_view = TRY(typed_this_value(vm));
- if (data_view->viewed_array_buffer()->is_detached())
- return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer);
- return Value(data_view->byte_offset());
-}
-
}