| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2023-01-27 21:25:31 +00:00
										 |  |  |  * Copyright (c) 2020-2023, Linus Groh <linusg@serenityos.org> | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-23 13:41:50 +01:00
										 |  |  | #include <AK/TypeCasts.h>
 | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  | #include <LibJS/Runtime/ArrayBuffer.h>
 | 
					
						
							|  |  |  | #include <LibJS/Runtime/ArrayBufferConstructor.h>
 | 
					
						
							| 
									
										
										
										
											2021-07-01 01:21:46 +03:00
										 |  |  | #include <LibJS/Runtime/DataView.h>
 | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  | #include <LibJS/Runtime/Error.h>
 | 
					
						
							|  |  |  | #include <LibJS/Runtime/GlobalObject.h>
 | 
					
						
							|  |  |  | #include <LibJS/Runtime/TypedArray.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace JS { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-11-19 09:45:05 +01:00
										 |  |  | JS_DEFINE_ALLOCATOR(ArrayBufferConstructor); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-16 00:20:49 +01:00
										 |  |  | ArrayBufferConstructor::ArrayBufferConstructor(Realm& realm) | 
					
						
							| 
									
										
										
										
											2023-04-13 00:47:15 +02:00
										 |  |  |     : NativeFunction(realm.vm().names.ArrayBuffer.as_string(), realm.intrinsics().function_prototype()) | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-07 08:41:28 +02:00
										 |  |  | void ArrayBufferConstructor::initialize(Realm& realm) | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     auto& vm = this->vm(); | 
					
						
							| 
									
										
										
										
											2023-08-07 08:41:28 +02:00
										 |  |  |     Base::initialize(realm); | 
					
						
							| 
									
										
										
										
											2021-06-13 00:22:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // 25.1.4.2 ArrayBuffer.prototype, https://tc39.es/ecma262/#sec-arraybuffer.prototype
 | 
					
						
							| 
									
										
										
										
											2022-08-27 00:54:55 +01:00
										 |  |  |     define_direct_property(vm.names.prototype, realm.intrinsics().array_buffer_prototype(), 0); | 
					
						
							| 
									
										
										
										
											2021-06-13 00:22:35 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     u8 attr = Attribute::Writable | Attribute::Configurable; | 
					
						
							| 
									
										
										
										
											2022-08-22 21:47:35 +01:00
										 |  |  |     define_native_function(realm, vm.names.isView, is_view, 1, attr); | 
					
						
							| 
									
										
										
										
											2021-06-07 19:31:32 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 00:22:35 +01:00
										 |  |  |     // 25.1.5.4 ArrayBuffer.prototype [ @@toStringTag ], https://tc39.es/ecma262/#sec-arraybuffer.prototype-@@tostringtag
 | 
					
						
							| 
									
										
										
										
											2023-04-13 01:14:45 +02:00
										 |  |  |     define_native_accessor(realm, vm.well_known_symbol_species(), symbol_species_getter, {}, Attribute::Configurable); | 
					
						
							| 
									
										
										
										
											2021-07-08 02:49:53 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     define_direct_property(vm.names.length, Value(1), Attribute::Configurable); | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 00:22:35 +01:00
										 |  |  | // 25.1.3.1 ArrayBuffer ( length ), https://tc39.es/ecma262/#sec-arraybuffer-length
 | 
					
						
							| 
									
										
										
										
											2021-10-20 21:16:30 +01:00
										 |  |  | ThrowCompletionOr<Value> ArrayBufferConstructor::call() | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     auto& vm = this->vm(); | 
					
						
							| 
									
										
										
										
											2023-01-27 21:25:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // 1. If NewTarget is undefined, throw a TypeError exception.
 | 
					
						
							| 
									
										
										
										
											2022-08-16 20:33:17 +01:00
										 |  |  |     return vm.throw_completion<TypeError>(ErrorType::ConstructorWithoutNew, vm.names.ArrayBuffer); | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 00:22:35 +01:00
										 |  |  | // 25.1.3.1 ArrayBuffer ( length ), https://tc39.es/ecma262/#sec-arraybuffer-length
 | 
					
						
							| 
									
										
										
										
											2022-12-14 19:18:10 +00:00
										 |  |  | ThrowCompletionOr<NonnullGCPtr<Object>> ArrayBufferConstructor::construct(FunctionObject& new_target) | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     auto& vm = this->vm(); | 
					
						
							| 
									
										
										
										
											2023-01-27 21:25:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // 2. Let byteLength be ? ToIndex(length).
 | 
					
						
							| 
									
										
										
										
											2022-08-21 14:00:56 +01:00
										 |  |  |     auto byte_length_or_error = vm.argument(0).to_index(vm); | 
					
						
							| 
									
										
										
										
											2022-03-02 11:44:32 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-18 00:05:01 +03:00
										 |  |  |     if (byte_length_or_error.is_error()) { | 
					
						
							|  |  |  |         auto error = byte_length_or_error.release_error(); | 
					
						
							| 
									
										
										
										
											2021-12-28 17:42:14 +01:00
										 |  |  |         if (error.value()->is_object() && is<RangeError>(error.value()->as_object())) { | 
					
						
							| 
									
										
										
										
											2021-06-10 22:39:44 +03:00
										 |  |  |             // Re-throw more specific RangeError
 | 
					
						
							| 
									
										
										
										
											2022-08-16 20:33:17 +01:00
										 |  |  |             return vm.throw_completion<RangeError>(ErrorType::InvalidLength, "array buffer"); | 
					
						
							| 
									
										
										
										
											2021-06-10 22:39:44 +03:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2021-10-20 21:16:30 +01:00
										 |  |  |         return error; | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2023-01-27 21:25:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // 3. Return ? AllocateArrayBuffer(NewTarget, byteLength).
 | 
					
						
							| 
									
										
										
										
											2022-12-14 19:18:10 +00:00
										 |  |  |     return *TRY(allocate_array_buffer(vm, new_target, byte_length_or_error.release_value())); | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 00:22:35 +01:00
										 |  |  | // 25.1.4.1 ArrayBuffer.isView ( arg ), https://tc39.es/ecma262/#sec-arraybuffer.isview
 | 
					
						
							| 
									
										
										
										
											2021-10-29 00:53:57 +03:00
										 |  |  | JS_DEFINE_NATIVE_FUNCTION(ArrayBufferConstructor::is_view) | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  | { | 
					
						
							|  |  |  |     auto arg = vm.argument(0); | 
					
						
							| 
									
										
										
										
											2023-01-27 21:25:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // 1. If arg is not an Object, return false.
 | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  |     if (!arg.is_object()) | 
					
						
							|  |  |  |         return Value(false); | 
					
						
							| 
									
										
										
										
											2023-01-27 21:25:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // 2. If arg has a [[ViewedArrayBuffer]] internal slot, return true.
 | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  |     if (arg.as_object().is_typed_array()) | 
					
						
							|  |  |  |         return Value(true); | 
					
						
							| 
									
										
										
										
											2021-07-01 01:21:46 +03:00
										 |  |  |     if (is<DataView>(arg.as_object())) | 
					
						
							|  |  |  |         return Value(true); | 
					
						
							| 
									
										
										
										
											2023-01-27 21:25:31 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // 3. Return false.
 | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  |     return Value(false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-13 00:22:35 +01:00
										 |  |  | // 25.1.4.3 get ArrayBuffer [ @@species ], https://tc39.es/ecma262/#sec-get-arraybuffer-@@species
 | 
					
						
							| 
									
										
										
										
											2021-10-29 00:53:57 +03:00
										 |  |  | JS_DEFINE_NATIVE_FUNCTION(ArrayBufferConstructor::symbol_species_getter) | 
					
						
							| 
									
										
										
										
											2021-06-07 19:31:32 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-27 21:25:31 +00:00
										 |  |  |     // 1. Return the this value.
 | 
					
						
							| 
									
										
										
										
											2022-08-20 09:48:43 +01:00
										 |  |  |     return vm.this_value(); | 
					
						
							| 
									
										
										
										
											2021-06-07 19:31:32 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-02 20:49:31 +00:00
										 |  |  | } |