diff options
author | Linus Groh <mail@linusgroh.de> | 2023-01-27 21:50:00 +0000 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2023-01-28 00:41:18 +0000 |
commit | 39301cce707397a0f34580b1649cd066bed6e481 (patch) | |
tree | 9a9262a5b919a00c4f8b5a48512ab736c946bce4 /Userland/Libraries | |
parent | 814e7260f3d410ac65eec1bbf45260ff4f4b4f48 (diff) | |
download | serenity-39301cce707397a0f34580b1649cd066bed6e481.zip |
LibJS: Add spec comments to DataViewPrototype
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/DataViewPrototype.cpp | 170 |
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()); -} - } |