diff options
author | Linus Groh <mail@linusgroh.de> | 2023-01-27 21:36:31 +0000 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2023-01-28 00:41:18 +0000 |
commit | 814e7260f3d410ac65eec1bbf45260ff4f4b4f48 (patch) | |
tree | 0d0ad7d68b579228929d01186bf0c63174ffb32b /Userland/Libraries/LibJS/Runtime/DataViewConstructor.cpp | |
parent | 0f3899b24af5b61adab5a5b28931677cde7c8b3f (diff) | |
download | serenity-814e7260f3d410ac65eec1bbf45260ff4f4b4f48.zip |
LibJS: Add spec comments to DataViewConstructor
Diffstat (limited to 'Userland/Libraries/LibJS/Runtime/DataViewConstructor.cpp')
-rw-r--r-- | Userland/Libraries/LibJS/Runtime/DataViewConstructor.cpp | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/Userland/Libraries/LibJS/Runtime/DataViewConstructor.cpp b/Userland/Libraries/LibJS/Runtime/DataViewConstructor.cpp index d606ec02a5..697f0aaed6 100644 --- a/Userland/Libraries/LibJS/Runtime/DataViewConstructor.cpp +++ b/Userland/Libraries/LibJS/Runtime/DataViewConstructor.cpp @@ -34,6 +34,8 @@ void DataViewConstructor::initialize(Realm& realm) ThrowCompletionOr<Value> DataViewConstructor::call() { auto& vm = this->vm(); + + // 1. If NewTarget is undefined, throw a TypeError exception. return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, vm.names.DataView); } @@ -43,35 +45,58 @@ ThrowCompletionOr<NonnullGCPtr<Object>> DataViewConstructor::construct(FunctionO auto& vm = this->vm(); auto buffer = vm.argument(0); + auto byte_offset = vm.argument(1); + auto byte_length = vm.argument(2); + + // 2. Perform ? RequireInternalSlot(buffer, [[ArrayBufferData]]). if (!buffer.is_object() || !is<ArrayBuffer>(buffer.as_object())) return vm.throw_completion<TypeError>(ErrorType::IsNotAn, buffer.to_string_without_side_effects(), vm.names.ArrayBuffer); auto& array_buffer = static_cast<ArrayBuffer&>(buffer.as_object()); - auto offset = TRY(vm.argument(1).to_index(vm)); + // 3. Let offset be ? ToIndex(byteOffset). + auto offset = TRY(byte_offset.to_index(vm)); + // 4. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. if (array_buffer.is_detached()) return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer); + // 5. Let bufferByteLength be buffer.[[ArrayBufferByteLength]]. auto buffer_byte_length = array_buffer.byte_length(); + + // 6. If offset > bufferByteLength, throw a RangeError exception. if (offset > buffer_byte_length) return vm.throw_completion<RangeError>(ErrorType::DataViewOutOfRangeByteOffset, offset, buffer_byte_length); size_t view_byte_length; - if (vm.argument(2).is_undefined()) { + + // 7. If byteLength is undefined, then + if (byte_length.is_undefined()) { + // a. Let viewByteLength be bufferByteLength - offset. view_byte_length = buffer_byte_length - offset; - } else { - view_byte_length = TRY(vm.argument(2).to_index(vm)); + } + // 8. Else, + else { + // a. Let viewByteLength be ? ToIndex(byteLength). + view_byte_length = TRY(byte_length.to_index(vm)); + + // b. If offset + viewByteLength > bufferByteLength, throw a RangeError exception. auto const checked_add = AK::make_checked(view_byte_length) + AK::make_checked(offset); if (checked_add.has_overflow() || checked_add.value() > buffer_byte_length) return vm.throw_completion<RangeError>(ErrorType::InvalidLength, vm.names.DataView); } + // 9. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%DataView.prototype%", ยซ [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] ยป). + // 11. Set O.[[ViewedArrayBuffer]] to buffer. + // 12. Set O.[[ByteLength]] to viewByteLength. + // 13. Set O.[[ByteOffset]] to offset. auto data_view = TRY(ordinary_create_from_constructor<DataView>(vm, new_target, &Intrinsics::data_view_prototype, &array_buffer, view_byte_length, offset)); + // 10. If IsDetachedBuffer(buffer) is true, throw a TypeError exception. if (array_buffer.is_detached()) return vm.throw_completion<TypeError>(ErrorType::DetachedArrayBuffer); + // 14. Return O. return data_view; } |