/src/serenity/Userland/Libraries/LibJS/Runtime/ArrayBufferConstructor.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <AK/TypeCasts.h> |
8 | | #include <LibJS/Runtime/ArrayBuffer.h> |
9 | | #include <LibJS/Runtime/ArrayBufferConstructor.h> |
10 | | #include <LibJS/Runtime/DataView.h> |
11 | | #include <LibJS/Runtime/Error.h> |
12 | | #include <LibJS/Runtime/GlobalObject.h> |
13 | | #include <LibJS/Runtime/TypedArray.h> |
14 | | |
15 | | namespace JS { |
16 | | |
17 | | JS_DEFINE_ALLOCATOR(ArrayBufferConstructor); |
18 | | |
19 | | ArrayBufferConstructor::ArrayBufferConstructor(Realm& realm) |
20 | 0 | : NativeFunction(realm.vm().names.ArrayBuffer.as_string(), realm.intrinsics().function_prototype()) |
21 | 0 | { |
22 | 0 | } |
23 | | |
24 | | void ArrayBufferConstructor::initialize(Realm& realm) |
25 | 0 | { |
26 | 0 | auto& vm = this->vm(); |
27 | 0 | Base::initialize(realm); |
28 | | |
29 | | // 25.1.5.2 ArrayBuffer.prototype, https://tc39.es/ecma262/#sec-arraybuffer.prototype |
30 | 0 | define_direct_property(vm.names.prototype, realm.intrinsics().array_buffer_prototype(), 0); |
31 | |
|
32 | 0 | u8 attr = Attribute::Writable | Attribute::Configurable; |
33 | 0 | define_native_function(realm, vm.names.isView, is_view, 1, attr); |
34 | | |
35 | | // 25.1.6.7 ArrayBuffer.prototype [ @@toStringTag ], https://tc39.es/ecma262/#sec-arraybuffer.prototype-@@tostringtag |
36 | 0 | define_native_accessor(realm, vm.well_known_symbol_species(), symbol_species_getter, {}, Attribute::Configurable); |
37 | |
|
38 | 0 | define_direct_property(vm.names.length, Value(1), Attribute::Configurable); |
39 | 0 | } |
40 | | |
41 | | // 25.1.4.1 ArrayBuffer ( length [ , options ] ), https://tc39.es/ecma262/#sec-arraybuffer-length |
42 | | ThrowCompletionOr<Value> ArrayBufferConstructor::call() |
43 | 0 | { |
44 | 0 | auto& vm = this->vm(); |
45 | | |
46 | | // 1. If NewTarget is undefined, throw a TypeError exception. |
47 | 0 | return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, vm.names.ArrayBuffer); |
48 | 0 | } |
49 | | |
50 | | // 25.1.4.1 ArrayBuffer ( length [ , options ] ), https://tc39.es/ecma262/#sec-arraybuffer-length |
51 | | ThrowCompletionOr<NonnullGCPtr<Object>> ArrayBufferConstructor::construct(FunctionObject& new_target) |
52 | 0 | { |
53 | 0 | auto& vm = this->vm(); |
54 | |
|
55 | 0 | auto length = vm.argument(0); |
56 | 0 | auto options = vm.argument(1); |
57 | | |
58 | | // 2. Let byteLength be ? ToIndex(length). |
59 | 0 | auto byte_length_or_error = length.to_index(vm); |
60 | |
|
61 | 0 | if (byte_length_or_error.is_error()) { |
62 | 0 | auto error = byte_length_or_error.release_error(); |
63 | 0 | if (error.value()->is_object() && is<RangeError>(error.value()->as_object())) { |
64 | | // Re-throw more specific RangeError |
65 | 0 | return vm.throw_completion<RangeError>(ErrorType::InvalidLength, "array buffer"); |
66 | 0 | } |
67 | 0 | return error; |
68 | 0 | } |
69 | | |
70 | | // 3. Let requestedMaxByteLength be ? GetArrayBufferMaxByteLengthOption(options). |
71 | 0 | auto requested_max_byte_length = TRY(get_array_buffer_max_byte_length_option(vm, options)); |
72 | | |
73 | | // 3. Return ? AllocateArrayBuffer(NewTarget, byteLength, requestedMaxByteLength). |
74 | 0 | return *TRY(allocate_array_buffer(vm, new_target, byte_length_or_error.release_value(), requested_max_byte_length)); |
75 | 0 | } |
76 | | |
77 | | // 25.1.5.1 ArrayBuffer.isView ( arg ), https://tc39.es/ecma262/#sec-arraybuffer.isview |
78 | | JS_DEFINE_NATIVE_FUNCTION(ArrayBufferConstructor::is_view) |
79 | 0 | { |
80 | 0 | auto arg = vm.argument(0); |
81 | | |
82 | | // 1. If arg is not an Object, return false. |
83 | 0 | if (!arg.is_object()) |
84 | 0 | return Value(false); |
85 | | |
86 | | // 2. If arg has a [[ViewedArrayBuffer]] internal slot, return true. |
87 | 0 | if (arg.as_object().is_typed_array()) |
88 | 0 | return Value(true); |
89 | 0 | if (is<DataView>(arg.as_object())) |
90 | 0 | return Value(true); |
91 | | |
92 | | // 3. Return false. |
93 | 0 | return Value(false); |
94 | 0 | } |
95 | | |
96 | | // 25.1.5.3 get ArrayBuffer [ @@species ], https://tc39.es/ecma262/#sec-get-arraybuffer-@@species |
97 | | JS_DEFINE_NATIVE_FUNCTION(ArrayBufferConstructor::symbol_species_getter) |
98 | 0 | { |
99 | | // 1. Return the this value. |
100 | 0 | return vm.this_value(); |
101 | 0 | } |
102 | | |
103 | | } |