boa_engine/builtins/dataview/
mod.rs

1//! Boa's implementation of ECMAScript's global `DataView` object.
2//!
3//! More information:
4//!  - [ECMAScript reference][spec]
5//!  - [MDN documentation][mdn]
6//!
7//! [spec]: https://tc39.es/ecma262/#sec-dataview-objects
8//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView
9
10use std::sync::atomic::Ordering;
11
12use crate::{
13    Context, JsArgs, JsData, JsResult, JsString,
14    builtins::BuiltInObject,
15    context::intrinsics::{Intrinsics, StandardConstructor, StandardConstructors},
16    error::JsNativeError,
17    js_string,
18    object::{JsObject, internal_methods::get_prototype_from_constructor},
19    property::Attribute,
20    realm::Realm,
21    string::StaticJsStrings,
22    symbol::JsSymbol,
23    value::JsValue,
24};
25use boa_gc::{Finalize, Trace};
26use bytemuck::{bytes_of, bytes_of_mut};
27
28use super::{
29    BuiltInBuilder, BuiltInConstructor, IntrinsicObject,
30    array_buffer::{
31        BufferObject,
32        utils::{BytesConstPtr, BytesMutPtr, memcpy},
33    },
34    typed_array::{self, TypedArrayElement},
35};
36
37/// The internal representation of a `DataView` object.
38#[derive(Debug, Clone, Trace, Finalize, JsData)]
39pub struct DataView {
40    pub(crate) viewed_array_buffer: BufferObject,
41    pub(crate) byte_length: Option<u64>,
42    pub(crate) byte_offset: u64,
43}
44
45impl DataView {
46    /// Abstract operation [`GetViewByteLength ( viewRecord )`][spec].
47    ///
48    /// [spec]: https://tc39.es/ecma262/#sec-getviewbytelength
49    fn byte_length(&self, buf_byte_len: usize) -> u64 {
50        // 1. Assert: IsViewOutOfBounds(viewRecord) is false.
51        debug_assert!(!self.is_out_of_bounds(buf_byte_len));
52
53        // 2. Let view be viewRecord.[[Object]].
54        // 3. If view.[[ByteLength]] is not auto, return view.[[ByteLength]].
55        if let Some(byte_length) = self.byte_length {
56            return byte_length;
57        }
58
59        // 4. Assert: IsFixedLengthArrayBuffer(view.[[ViewedArrayBuffer]]) is false.
60
61        // 5. Let byteOffset be view.[[ByteOffset]].
62        // 6. Let byteLength be viewRecord.[[CachedBufferByteLength]].
63        // 7. Assert: byteLength is not detached.
64        // 8. Return byteLength - byteOffset.
65        buf_byte_len as u64 - self.byte_offset
66    }
67
68    /// Abstract operation [`IsViewOutOfBounds ( viewRecord )`][spec].
69    ///
70    /// [spec]: https://tc39.es/ecma262/#sec-isviewoutofbounds
71    fn is_out_of_bounds(&self, buf_byte_len: usize) -> bool {
72        let buf_byte_len = buf_byte_len as u64;
73        // 1. Let view be viewRecord.[[Object]].
74        // 2. Let bufferByteLength be viewRecord.[[CachedBufferByteLength]].
75        // 3. Assert: IsDetachedBuffer(view.[[ViewedArrayBuffer]]) is true if and only if bufferByteLength is detached.
76        // 4. If bufferByteLength is detached, return true.
77        // handled by the caller
78
79        // 5. Let byteOffsetStart be view.[[ByteOffset]].
80
81        // 6. If view.[[ByteLength]] is auto, then
82        //     a. Let byteOffsetEnd be bufferByteLength.
83        // 7. Else,
84        //     a. Let byteOffsetEnd be byteOffsetStart + view.[[ByteLength]].
85        let byte_offset_end = self
86            .byte_length
87            .map_or(buf_byte_len, |byte_length| byte_length + self.byte_offset);
88
89        // 8. If byteOffsetStart > bufferByteLength or byteOffsetEnd > bufferByteLength, return true.
90        // 9. NOTE: 0-length DataViews are not considered out-of-bounds.
91        // 10. Return false.
92        self.byte_offset > buf_byte_len || byte_offset_end > buf_byte_len
93    }
94}
95
96impl IntrinsicObject for DataView {
97    fn init(realm: &Realm) {
98        let flag_attributes = Attribute::CONFIGURABLE | Attribute::NON_ENUMERABLE;
99
100        let get_buffer = BuiltInBuilder::callable(realm, Self::get_buffer)
101            .name(js_string!("get buffer"))
102            .build();
103
104        let get_byte_length = BuiltInBuilder::callable(realm, Self::get_byte_length)
105            .name(js_string!("get byteLength"))
106            .build();
107
108        let get_byte_offset = BuiltInBuilder::callable(realm, Self::get_byte_offset)
109            .name(js_string!("get byteOffset"))
110            .build();
111
112        let builder = BuiltInBuilder::from_standard_constructor::<Self>(realm)
113            .accessor(
114                js_string!("buffer"),
115                Some(get_buffer),
116                None,
117                flag_attributes,
118            )
119            .accessor(
120                js_string!("byteLength"),
121                Some(get_byte_length),
122                None,
123                flag_attributes,
124            )
125            .accessor(
126                js_string!("byteOffset"),
127                Some(get_byte_offset),
128                None,
129                flag_attributes,
130            )
131            .method(Self::get_big_int64, js_string!("getBigInt64"), 1)
132            .method(Self::get_big_uint64, js_string!("getBigUint64"), 1)
133            .method(Self::get_float32, js_string!("getFloat32"), 1)
134            .method(Self::get_float64, js_string!("getFloat64"), 1)
135            .method(Self::get_int8, js_string!("getInt8"), 1)
136            .method(Self::get_int16, js_string!("getInt16"), 1)
137            .method(Self::get_int32, js_string!("getInt32"), 1)
138            .method(Self::get_uint8, js_string!("getUint8"), 1)
139            .method(Self::get_uint16, js_string!("getUint16"), 1)
140            .method(Self::get_uint32, js_string!("getUint32"), 1)
141            .method(Self::set_big_int64, js_string!("setBigInt64"), 2)
142            .method(Self::set_big_uint64, js_string!("setBigUint64"), 2)
143            .method(Self::set_float32, js_string!("setFloat32"), 2)
144            .method(Self::set_float64, js_string!("setFloat64"), 2)
145            .method(Self::set_int8, js_string!("setInt8"), 2)
146            .method(Self::set_int16, js_string!("setInt16"), 2)
147            .method(Self::set_int32, js_string!("setInt32"), 2)
148            .method(Self::set_uint8, js_string!("setUint8"), 2)
149            .method(Self::set_uint16, js_string!("setUint16"), 2)
150            .method(Self::set_uint32, js_string!("setUint32"), 2)
151            .property(
152                JsSymbol::to_string_tag(),
153                Self::NAME,
154                Attribute::READONLY | Attribute::NON_ENUMERABLE | Attribute::CONFIGURABLE,
155            );
156
157        #[cfg(feature = "float16")]
158        let builder = builder
159            .method(Self::get_float16, js_string!("getFloat16"), 1)
160            .method(Self::set_float16, js_string!("setFloat16"), 2);
161
162        builder.build();
163    }
164
165    fn get(intrinsics: &Intrinsics) -> JsObject {
166        Self::STANDARD_CONSTRUCTOR(intrinsics.constructors()).constructor()
167    }
168}
169
170impl BuiltInObject for DataView {
171    const NAME: JsString = StaticJsStrings::DATA_VIEW;
172}
173
174impl BuiltInConstructor for DataView {
175    const CONSTRUCTOR_ARGUMENTS: usize = 1;
176    const PROTOTYPE_STORAGE_SLOTS: usize = 29;
177    const CONSTRUCTOR_STORAGE_SLOTS: usize = 0;
178
179    const STANDARD_CONSTRUCTOR: fn(&StandardConstructors) -> &StandardConstructor =
180        StandardConstructors::data_view;
181
182    /// `DataView ( buffer [ , byteOffset [ , byteLength ] ] )`
183    ///
184    /// The `DataView` view provides a low-level interface for reading and writing multiple number
185    /// types in a binary `ArrayBuffer`, without having to care about the platform's endianness.
186    ///
187    /// More information:
188    ///  - [ECMAScript reference][spec]
189    ///  - [MDN][mdn]
190    ///
191    /// [spec]: https://tc39.es/ecma262/#sec-dataview-buffer-byteoffset-bytelength
192    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/DataView
193    fn constructor(
194        new_target: &JsValue,
195        args: &[JsValue],
196        context: &mut Context,
197    ) -> JsResult<JsValue> {
198        // 1. If NewTarget is undefined, throw a TypeError exception.
199        if new_target.is_undefined() {
200            return Err(JsNativeError::typ()
201                .with_message("cannot call `DataView` constructor without `new`")
202                .into());
203        }
204        let byte_len = args.get_or_undefined(2);
205
206        // 2. Perform ? RequireInternalSlot(buffer, [[ArrayBufferData]]).
207        let buffer = args
208            .get_or_undefined(0)
209            .as_object()
210            .and_then(|o| o.clone().into_buffer_object().ok())
211            .ok_or_else(|| JsNativeError::typ().with_message("buffer must be an ArrayBuffer"))?;
212
213        // 3. Let offset be ? ToIndex(byteOffset).
214        let offset = args.get_or_undefined(1).to_index(context)?;
215
216        let (buf_byte_len, is_fixed_len) = {
217            let buffer = buffer.as_buffer();
218
219            // 4. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
220            let Some(slice) = buffer.bytes(Ordering::SeqCst) else {
221                return Err(JsNativeError::typ()
222                    .with_message("ArrayBuffer is detached")
223                    .into());
224            };
225
226            // 5. Let bufferByteLength be ArrayBufferByteLength(buffer, seq-cst).
227            let buf_len = slice.len() as u64;
228
229            // 6. If offset > bufferByteLength, throw a RangeError exception.
230            if offset > buf_len {
231                return Err(JsNativeError::range()
232                    .with_message("Start offset is outside the bounds of the buffer")
233                    .into());
234            }
235
236            // 7. Let bufferIsFixedLength be IsFixedLengthArrayBuffer(buffer).
237
238            (buf_len, buffer.is_fixed_len())
239        };
240
241        // 8. If byteLength is undefined, then
242        let view_byte_len = if byte_len.is_undefined() {
243            // a. If bufferIsFixedLength is true, then
244            //     i. Let viewByteLength be bufferByteLength - offset.
245            // b. Else,
246            //     i. Let viewByteLength be auto.
247            is_fixed_len.then_some(buf_byte_len - offset)
248        } else {
249            // 9. Else,
250            //     a. Let viewByteLength be ? ToIndex(byteLength).
251            let byte_len = byte_len.to_index(context)?;
252
253            //     b. If offset + viewByteLength > bufferByteLength, throw a RangeError exception.
254            if offset + byte_len > buf_byte_len {
255                return Err(JsNativeError::range()
256                    .with_message("Invalid data view length")
257                    .into());
258            }
259            Some(byte_len)
260        };
261
262        // 10. Let O be ? OrdinaryCreateFromConstructor(NewTarget, "%DataView.prototype%",
263        //     « [[DataView]], [[ViewedArrayBuffer]], [[ByteLength]], [[ByteOffset]] »).
264        let prototype =
265            get_prototype_from_constructor(new_target, StandardConstructors::data_view, context)?;
266
267        // 11. If IsDetachedBuffer(buffer) is true, throw a TypeError exception.
268        // 12. Set bufferByteLength to ArrayBufferByteLength(buffer, seq-cst).
269        let Some(buf_byte_len) = buffer
270            .as_buffer()
271            .bytes(Ordering::SeqCst)
272            .map(|s| s.len() as u64)
273        else {
274            return Err(JsNativeError::typ()
275                .with_message("ArrayBuffer can't be detached")
276                .into());
277        };
278
279        // 13. If offset > bufferByteLength, throw a RangeError exception.
280        if offset > buf_byte_len {
281            return Err(JsNativeError::range()
282                .with_message("DataView offset outside of buffer array bounds")
283                .into());
284        }
285
286        // 14. If byteLength is not undefined, then
287        //     a. If offset + viewByteLength > bufferByteLength, throw a RangeError exception.
288        if !byte_len.is_undefined()
289            && let Some(view_byte_len) = view_byte_len
290            && offset + view_byte_len > buf_byte_len
291        {
292            return Err(JsNativeError::range()
293                .with_message("DataView offset outside of buffer array bounds")
294                .into());
295        }
296
297        let obj = JsObject::from_proto_and_data_with_shared_shape(
298            context.root_shape(),
299            prototype,
300            Self {
301                // 15. Set O.[[ViewedArrayBuffer]] to buffer.
302                viewed_array_buffer: buffer,
303                // 16. Set O.[[ByteLength]] to viewByteLength.
304                byte_length: view_byte_len,
305                // 17. Set O.[[ByteOffset]] to offset.
306                byte_offset: offset,
307            },
308        );
309
310        // 18. Return O.
311        Ok(obj.into())
312    }
313}
314
315impl DataView {
316    /// `get DataView.prototype.buffer`
317    ///
318    /// The buffer accessor property represents the `ArrayBuffer` or `SharedArrayBuffer` referenced
319    /// by the `DataView` at construction time.
320    ///
321    /// More information:
322    ///  - [ECMAScript reference][spec]
323    ///  - [MDN][mdn]
324    ///
325    /// [spec]: https://tc39.es/ecma262/#sec-get-dataview.prototype.buffer
326    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/buffer
327    pub(crate) fn get_buffer(
328        this: &JsValue,
329        _args: &[JsValue],
330        _: &mut Context,
331    ) -> JsResult<JsValue> {
332        // 1. Let O be the this value.
333        // 2. Perform ? RequireInternalSlot(O, [[DataView]]).
334        let object = this.as_object();
335        let view = object
336            .as_ref()
337            .and_then(JsObject::downcast_ref::<Self>)
338            .ok_or_else(|| JsNativeError::typ().with_message("`this` is not a DataView"))?;
339        // 3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
340        // 4. Let buffer be O.[[ViewedArrayBuffer]].
341        let buffer = view.viewed_array_buffer.clone();
342        // 5. Return buffer.
343        Ok(buffer.into())
344    }
345
346    /// `get DataView.prototype.byteLength`
347    ///
348    /// The `byteLength` accessor property represents the length (in bytes) of the dataview.
349    ///
350    /// More information:
351    ///  - [ECMAScript reference][spec]
352    ///  - [MDN][mdn]
353    ///
354    /// [spec]: https://tc39.es/ecma262/#sec-get-dataview.prototype.bytelength
355    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/byteLength
356    pub(crate) fn get_byte_length(
357        this: &JsValue,
358        _args: &[JsValue],
359        _: &mut Context,
360    ) -> JsResult<JsValue> {
361        // 1. Let O be the this value.
362        // 2. Perform ? RequireInternalSlot(O, [[DataView]]).
363        // 3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
364        let object = this.as_object();
365        let view = object
366            .as_ref()
367            .and_then(JsObject::downcast_ref::<Self>)
368            .ok_or_else(|| JsNativeError::typ().with_message("`this` is not a DataView"))?;
369
370        // 4. Let viewRecord be MakeDataViewWithBufferWitnessRecord(O, seq-cst).
371        // 5. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
372        let buffer = view.viewed_array_buffer.as_buffer();
373        let Some(slice) = buffer
374            .bytes(Ordering::SeqCst)
375            .filter(|s| !view.is_out_of_bounds(s.len()))
376        else {
377            return Err(JsNativeError::typ()
378                .with_message("view out of bounds for its inner buffer")
379                .into());
380        };
381
382        // 6. Let size be GetViewByteLength(viewRecord).
383        let size = view.byte_length(slice.len());
384
385        // 7. Return 𝔽(size).
386        Ok(size.into())
387    }
388
389    /// `get DataView.prototype.byteOffset`
390    ///
391    /// The `byteOffset` accessor property represents the offset (in bytes) of this view from the
392    /// start of its `ArrayBuffer` or `SharedArrayBuffer`.
393    ///
394    /// More information:
395    ///  - [ECMAScript reference][spec]
396    ///  - [MDN][mdn]
397    ///
398    /// [spec]: https://tc39.es/ecma262/#sec-get-dataview.prototype.byteoffset
399    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/byteOffset
400    pub(crate) fn get_byte_offset(
401        this: &JsValue,
402        _args: &[JsValue],
403        _: &mut Context,
404    ) -> JsResult<JsValue> {
405        // 1. Let O be the this value.
406        // 2. Perform ? RequireInternalSlot(O, [[DataView]]).
407        let object = this.as_object();
408        let view = object
409            .as_ref()
410            .and_then(JsObject::downcast_ref::<Self>)
411            .ok_or_else(|| JsNativeError::typ().with_message("`this` is not a DataView"))?;
412
413        // 3. Assert: O has a [[ViewedArrayBuffer]] internal slot.
414        let buffer = view.viewed_array_buffer.as_buffer();
415        // 4. Let viewRecord be MakeDataViewWithBufferWitnessRecord(O, seq-cst).
416        // 5. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
417        if buffer
418            .bytes(Ordering::SeqCst)
419            .filter(|b| !view.is_out_of_bounds(b.len()))
420            .is_none()
421        {
422            return Err(JsNativeError::typ()
423                .with_message("data view is outside the bounds of its inner buffer")
424                .into());
425        }
426
427        // 6. Let offset be O.[[ByteOffset]].
428        let offset = view.byte_offset;
429        // 7. Return 𝔽(offset).
430        Ok(offset.into())
431    }
432
433    /// `GetViewValue ( view, requestIndex, isLittleEndian, type )`
434    ///
435    /// The abstract operation `GetViewValue` takes arguments view, requestIndex, `isLittleEndian`,
436    /// and type. It is used by functions on `DataView` instances to retrieve values from the
437    /// view's buffer.
438    ///
439    /// More information:
440    ///  - [ECMAScript reference][spec]
441    ///
442    /// [spec]: https://tc39.es/ecma262/#sec-getviewvalue
443    fn get_view_value<T: typed_array::Element>(
444        view: &JsValue,
445        request_index: &JsValue,
446        is_little_endian: &JsValue,
447        context: &mut Context,
448    ) -> JsResult<JsValue> {
449        // 1. Perform ? RequireInternalSlot(view, [[DataView]]).
450        // 2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
451        let object = view.as_object();
452        let view = object
453            .as_ref()
454            .and_then(JsObject::downcast_ref::<Self>)
455            .ok_or_else(|| JsNativeError::typ().with_message("`this` is not a DataView"))?;
456
457        // 3. Let getIndex be ? ToIndex(requestIndex).
458        let get_index = request_index.to_index(context)?;
459
460        // 4. Set isLittleEndian to ToBoolean(isLittleEndian).
461        let is_little_endian = is_little_endian.to_boolean();
462
463        // 6. Let viewRecord be MakeDataViewWithBufferWitnessRecord(view, unordered).
464        // 7. NOTE: Bounds checking is not a synchronizing operation when view's backing buffer is a growable SharedArrayBuffer.
465        // 8. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
466        let buffer = view.viewed_array_buffer.as_buffer();
467        let Some(data) = buffer
468            .bytes(Ordering::Relaxed)
469            .filter(|buf| !view.is_out_of_bounds(buf.len()))
470        else {
471            return Err(JsNativeError::typ()
472                .with_message("view out of bounds for its inner buffer")
473                .into());
474        };
475
476        // 5. Let viewOffset be view.[[ByteOffset]].
477        let view_offset = view.byte_offset;
478
479        // 9. Let viewSize be GetViewByteLength(viewRecord).
480        let view_size = view.byte_length(data.len());
481
482        // 10. Let elementSize be the Element Size value specified in Table 71 for Element Type type.
483        let element_size = size_of::<T>() as u64;
484
485        // 11. If getIndex + elementSize > viewSize, throw a RangeError exception.
486        if get_index + element_size > view_size {
487            return Err(JsNativeError::range()
488                .with_message("Offset is outside the bounds of the DataView")
489                .into());
490        }
491
492        // 12. Let bufferIndex be getIndex + viewOffset.
493        let buffer_index = (get_index + view_offset) as usize;
494
495        let src = data.subslice(buffer_index..);
496
497        debug_assert!(src.len() >= size_of::<T>());
498
499        // 13. Return GetValueFromBuffer(view.[[ViewedArrayBuffer]], bufferIndex, type, false, unordered, isLittleEndian).
500        // SAFETY: All previous checks ensure the element fits in the buffer.
501        let value: TypedArrayElement = unsafe {
502            let mut value = T::zeroed();
503            memcpy(
504                src.as_ptr(),
505                BytesMutPtr::Bytes(bytes_of_mut(&mut value).as_mut_ptr()),
506                size_of::<T>(),
507            );
508
509            if is_little_endian {
510                value.to_little_endian()
511            } else {
512                value.to_big_endian()
513            }
514            .into()
515        };
516
517        Ok(value.into())
518    }
519
520    /// `DataView.prototype.getBigInt64 ( byteOffset [ , littleEndian ] )`
521    ///
522    /// The `getBigInt64()` method gets a signed 64-bit integer (long long) at the specified byte
523    /// offset from the start of the `DataView`.
524    ///
525    /// More information:
526    ///  - [ECMAScript reference][spec]
527    ///  - [MDN][mdn]
528    ///
529    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.getbigint64
530    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getBigInt64
531    pub(crate) fn get_big_int64(
532        this: &JsValue,
533        args: &[JsValue],
534        context: &mut Context,
535    ) -> JsResult<JsValue> {
536        let byte_offset = args.get_or_undefined(0);
537        let is_little_endian = args.get_or_undefined(1);
538        // 1. Let v be the this value.
539        // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64).
540        Self::get_view_value::<i64>(this, byte_offset, is_little_endian, context)
541    }
542
543    /// `DataView.prototype.getBigUint64 ( byteOffset [ , littleEndian ] )`
544    ///
545    /// The `getBigUint64()` method gets an unsigned 64-bit integer (unsigned long long) at the
546    /// specified byte offset from the start of the `DataView`.
547    ///
548    /// More information:
549    ///  - [ECMAScript reference][spec]
550    ///  - [MDN][mdn]
551    ///
552    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.getbiguint64
553    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getBigUint64
554    pub(crate) fn get_big_uint64(
555        this: &JsValue,
556        args: &[JsValue],
557        context: &mut Context,
558    ) -> JsResult<JsValue> {
559        let byte_offset = args.get_or_undefined(0);
560        let is_little_endian = args.get_or_undefined(1);
561        // 1. Let v be the this value.
562        // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64).
563        Self::get_view_value::<u64>(this, byte_offset, is_little_endian, context)
564    }
565
566    /// `DataView.prototype.getFloat16 ( byteOffset [ , littleEndian ] )`
567    ///
568    /// The `getFloat16()` method gets a signed 16-bit float (float) at the specified byte offset
569    /// from the start of the `DataView`.
570    ///
571    /// More information:
572    ///  - [ECMAScript reference][spec]
573    ///  - [MDN][mdn]
574    ///
575    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.getfloat16
576    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getFloat16
577    #[cfg(feature = "float16")]
578    pub(crate) fn get_float16(
579        this: &JsValue,
580        args: &[JsValue],
581        context: &mut Context,
582    ) -> JsResult<JsValue> {
583        let byte_offset = args.get_or_undefined(0);
584        let is_little_endian = args.get_or_undefined(1);
585        // 1. Let v be the this value.
586        // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64).
587        Self::get_view_value::<typed_array::Float16>(this, byte_offset, is_little_endian, context)
588    }
589
590    /// `DataView.prototype.getFloat32 ( byteOffset [ , littleEndian ] )`
591    ///
592    /// The `getFloat32()` method gets a signed 32-bit float (float) at the specified byte offset
593    /// from the start of the `DataView`.
594    ///
595    /// More information:
596    ///  - [ECMAScript reference][spec]
597    ///  - [MDN][mdn]
598    ///
599    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.getfloat32
600    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getFloat32
601    pub(crate) fn get_float32(
602        this: &JsValue,
603        args: &[JsValue],
604        context: &mut Context,
605    ) -> JsResult<JsValue> {
606        let byte_offset = args.get_or_undefined(0);
607        let is_little_endian = args.get_or_undefined(1);
608        // 1. Let v be the this value.
609        // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64).
610        Self::get_view_value::<f32>(this, byte_offset, is_little_endian, context)
611    }
612
613    /// `DataView.prototype.getFloat64 ( byteOffset [ , littleEndian ] )`
614    ///
615    /// The `getFloat64()` method gets a signed 64-bit float (double) at the specified byte offset
616    /// from the start of the `DataView`.
617    ///
618    /// More information:
619    ///  - [ECMAScript reference][spec]
620    ///  - [MDN][mdn]
621    ///
622    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.getfloat64
623    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getFloat64
624    pub(crate) fn get_float64(
625        this: &JsValue,
626        args: &[JsValue],
627        context: &mut Context,
628    ) -> JsResult<JsValue> {
629        let byte_offset = args.get_or_undefined(0);
630        let is_little_endian = args.get_or_undefined(1);
631        // 1. Let v be the this value.
632        // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64).
633        Self::get_view_value::<f64>(this, byte_offset, is_little_endian, context)
634    }
635
636    /// `DataView.prototype.getInt8 ( byteOffset [ , littleEndian ] )`
637    ///
638    /// The `getInt8()` method gets a signed 8-bit integer (byte) at the specified byte offset
639    /// from the start of the `DataView`.
640    ///
641    /// More information:
642    ///  - [ECMAScript reference][spec]
643    ///  - [MDN][mdn]
644    ///
645    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.getint8
646    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getInt8
647    pub(crate) fn get_int8(
648        this: &JsValue,
649        args: &[JsValue],
650        context: &mut Context,
651    ) -> JsResult<JsValue> {
652        let byte_offset = args.get_or_undefined(0);
653        let is_little_endian = args.get_or_undefined(1);
654        // 1. Let v be the this value.
655        // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64).
656        Self::get_view_value::<i8>(this, byte_offset, is_little_endian, context)
657    }
658
659    /// `DataView.prototype.getInt16 ( byteOffset [ , littleEndian ] )`
660    ///
661    /// The `getInt16()` method gets a signed 16-bit integer (short) at the specified byte offset
662    /// from the start of the `DataView`.
663    ///
664    /// More information:
665    ///  - [ECMAScript reference][spec]
666    ///  - [MDN][mdn]
667    ///
668    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.getint16
669    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getInt16
670    pub(crate) fn get_int16(
671        this: &JsValue,
672        args: &[JsValue],
673        context: &mut Context,
674    ) -> JsResult<JsValue> {
675        let byte_offset = args.get_or_undefined(0);
676        let is_little_endian = args.get_or_undefined(1);
677        // 1. Let v be the this value.
678        // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64).
679        Self::get_view_value::<i16>(this, byte_offset, is_little_endian, context)
680    }
681
682    /// `DataView.prototype.getInt32 ( byteOffset [ , littleEndian ] )`
683    ///
684    /// The `getInt32()` method gets a signed 32-bit integer (long) at the specified byte offset
685    /// from the start of the `DataView`.
686    ///
687    /// More information:
688    ///  - [ECMAScript reference][spec]
689    ///  - [MDN][mdn]
690    ///
691    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.getint32
692    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getInt32
693    pub(crate) fn get_int32(
694        this: &JsValue,
695        args: &[JsValue],
696        context: &mut Context,
697    ) -> JsResult<JsValue> {
698        let byte_offset = args.get_or_undefined(0);
699        let is_little_endian = args.get_or_undefined(1);
700        // 1. Let v be the this value.
701        // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64).
702        Self::get_view_value::<i32>(this, byte_offset, is_little_endian, context)
703    }
704
705    /// `DataView.prototype.getUint8 ( byteOffset [ , littleEndian ] )`
706    ///
707    /// The `getUint8()` method gets an unsigned 8-bit integer (unsigned byte) at the specified
708    /// byte offset from the start of the `DataView`.
709    ///
710    /// More information:
711    ///  - [ECMAScript reference][spec]
712    ///  - [MDN][mdn]
713    ///
714    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.getuint8
715    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getUint8
716    pub(crate) fn get_uint8(
717        this: &JsValue,
718        args: &[JsValue],
719        context: &mut Context,
720    ) -> JsResult<JsValue> {
721        let byte_offset = args.get_or_undefined(0);
722        let is_little_endian = args.get_or_undefined(1);
723        // 1. Let v be the this value.
724        // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64).
725        Self::get_view_value::<u8>(this, byte_offset, is_little_endian, context)
726    }
727
728    /// `DataView.prototype.getUint16 ( byteOffset [ , littleEndian ] )`
729    ///
730    /// The `getUint16()` method gets an unsigned 16-bit integer (unsigned short) at the specified
731    /// byte offset from the start of the `DataView`.
732    ///
733    /// More information:
734    ///  - [ECMAScript reference][spec]
735    ///  - [MDN][mdn]
736    ///
737    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.getuint16
738    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getUint16
739    pub(crate) fn get_uint16(
740        this: &JsValue,
741        args: &[JsValue],
742        context: &mut Context,
743    ) -> JsResult<JsValue> {
744        let byte_offset = args.get_or_undefined(0);
745        let is_little_endian = args.get_or_undefined(1);
746        // 1. Let v be the this value.
747        // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64).
748        Self::get_view_value::<u16>(this, byte_offset, is_little_endian, context)
749    }
750
751    /// `DataView.prototype.getUint32 ( byteOffset [ , littleEndian ] )`
752    ///
753    /// The `getUint32()` method gets an unsigned 32-bit integer (unsigned long) at the specified
754    /// byte offset from the start of the `DataView`.
755    ///
756    /// More information:
757    ///  - [ECMAScript reference][spec]
758    ///  - [MDN][mdn]
759    ///
760    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.getuint32
761    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/getUint32
762    pub(crate) fn get_uint32(
763        this: &JsValue,
764        args: &[JsValue],
765        context: &mut Context,
766    ) -> JsResult<JsValue> {
767        let byte_offset = args.get_or_undefined(0);
768        let is_little_endian = args.get_or_undefined(1);
769        // 1. Let v be the this value.
770        // 2. Return ? GetViewValue(v, byteOffset, littleEndian, BigInt64).
771        Self::get_view_value::<u32>(this, byte_offset, is_little_endian, context)
772    }
773
774    /// `SetViewValue ( view, requestIndex, isLittleEndian, type )`
775    ///
776    /// The abstract operation `SetViewValue` takes arguments view, requestIndex, `isLittleEndian`,
777    /// type, and value. It is used by functions on `DataView` instances to store values into the
778    /// view's buffer.
779    ///
780    /// More information:
781    ///  - [ECMAScript reference][spec]
782    ///
783    /// [spec]: https://tc39.es/ecma262/#sec-setviewvalue
784    fn set_view_value<T: typed_array::Element>(
785        view: &JsValue,
786        request_index: &JsValue,
787        is_little_endian: &JsValue,
788        value: &JsValue,
789        context: &mut Context,
790    ) -> JsResult<JsValue> {
791        // 1. Perform ? RequireInternalSlot(view, [[DataView]]).
792        // 2. Assert: view has a [[ViewedArrayBuffer]] internal slot.
793        let object = view.as_object();
794        let view = object
795            .as_ref()
796            .and_then(JsObject::downcast_ref::<Self>)
797            .ok_or_else(|| JsNativeError::typ().with_message("`this` is not a DataView"))?;
798
799        // 3. Let getIndex be ? ToIndex(requestIndex).
800        let get_index = request_index.to_index(context)?;
801
802        // 4. If IsBigIntElementType(type) is true, let numberValue be ? ToBigInt(value).
803        // 5. Otherwise, let numberValue be ? ToNumber(value).
804        let value = T::from_js_value(value, context)?;
805
806        // 6. Set isLittleEndian to ToBoolean(isLittleEndian).
807        let is_little_endian = is_little_endian.to_boolean();
808
809        // 8. Let viewRecord be MakeDataViewWithBufferWitnessRecord(view, unordered).
810        // 9. NOTE: Bounds checking is not a synchronizing operation when view's backing buffer is a growable SharedArrayBuffer.
811        // 10. If IsViewOutOfBounds(viewRecord) is true, throw a TypeError exception.
812        let mut buffer = view.viewed_array_buffer.as_buffer_mut();
813
814        let Some(mut data) = buffer
815            .bytes(Ordering::Relaxed)
816            .filter(|buf| !view.is_out_of_bounds(buf.len()))
817        else {
818            return Err(JsNativeError::typ()
819                .with_message("view out of bounds for its inner buffer")
820                .into());
821        };
822
823        // 11. Let viewSize be GetViewByteLength(viewRecord).
824        let view_size = view.byte_length(data.len());
825
826        // 7. Let viewOffset be view.[[ByteOffset]].
827        let view_offset = view.byte_offset;
828
829        // 12. Let elementSize be the Element Size value specified in Table 71 for Element Type type.
830        let elem_size = size_of::<T>();
831
832        // 13. If getIndex + elementSize > viewSize, throw a RangeError exception.
833        if get_index + elem_size as u64 > view_size {
834            return Err(JsNativeError::range()
835                .with_message("Offset is outside the bounds of DataView")
836                .into());
837        }
838
839        // 14. Let bufferIndex be getIndex + viewOffset.
840        let buffer_index = (get_index + view_offset) as usize;
841
842        let mut target = data.subslice_mut(buffer_index..);
843
844        debug_assert!(target.len() >= size_of::<T>());
845
846        // 15. Perform SetValueInBuffer(view.[[ViewedArrayBuffer]], bufferIndex, type, numberValue, false, unordered, isLittleEndian).
847        // SAFETY: All previous checks ensure the element fits in the buffer.
848        unsafe {
849            let value = if is_little_endian {
850                value.to_little_endian()
851            } else {
852                value.to_big_endian()
853            };
854
855            memcpy(
856                BytesConstPtr::Bytes(bytes_of(&value).as_ptr()),
857                target.as_ptr(),
858                size_of::<T>(),
859            );
860        }
861
862        // 16. Return undefined.
863        Ok(JsValue::undefined())
864    }
865
866    /// `DataView.prototype.setBigInt64 ( byteOffset, value [ , littleEndian ] )`
867    ///
868    /// The `setBigInt64()` method stores a signed 64-bit integer (long long) value at the
869    /// specified byte offset from the start of the `DataView`.
870    ///
871    /// More information:
872    ///  - [ECMAScript reference][spec]
873    ///  - [MDN][mdn]
874    ///
875    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.setbigint64
876    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setBigInt64
877    pub(crate) fn set_big_int64(
878        this: &JsValue,
879        args: &[JsValue],
880        context: &mut Context,
881    ) -> JsResult<JsValue> {
882        let byte_offset = args.get_or_undefined(0);
883        let value = args.get_or_undefined(1);
884        let is_little_endian = args.get_or_undefined(2);
885        // 1. Let v be the this value.
886        // 2. Return ? SetViewValue(v, byteOffset, littleEndian, BigUint64, value).
887        Self::set_view_value::<i64>(this, byte_offset, is_little_endian, value, context)
888    }
889
890    /// `DataView.prototype.setBigUint64 ( byteOffset, value [ , littleEndian ] )`
891    ///
892    /// The `setBigUint64()` method stores an unsigned 64-bit integer (unsigned long long) value at
893    /// the specified byte offset from the start of the `DataView`.
894    ///
895    /// More information:
896    ///  - [ECMAScript reference][spec]
897    ///  - [MDN][mdn]
898    ///
899    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.setbiguint64
900    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setBigUint64
901    pub(crate) fn set_big_uint64(
902        this: &JsValue,
903        args: &[JsValue],
904        context: &mut Context,
905    ) -> JsResult<JsValue> {
906        let byte_offset = args.get_or_undefined(0);
907        let value = args.get_or_undefined(1);
908        let is_little_endian = args.get_or_undefined(2);
909        // 1. Let v be the this value.
910        // 2. Return ? SetViewValue(v, byteOffset, littleEndian, BigUint64, value).
911        Self::set_view_value::<u64>(this, byte_offset, is_little_endian, value, context)
912    }
913
914    /// `DataView.prototype.setFloat16 ( byteOffset, value [ , littleEndian ] )`
915    ///
916    /// The `setFloat16()` method stores a signed 16-bit float (float) value at the specified byte
917    /// offset from the start of the `DataView`.
918    ///
919    /// More information:
920    ///  - [ECMAScript reference][spec]
921    ///  - [MDN][mdn]
922    ///
923    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.setfloat16
924    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setFloat16
925    #[cfg(feature = "float16")]
926    pub(crate) fn set_float16(
927        this: &JsValue,
928        args: &[JsValue],
929        context: &mut Context,
930    ) -> JsResult<JsValue> {
931        let byte_offset = args.get_or_undefined(0);
932        let value = args.get_or_undefined(1);
933        let is_little_endian = args.get_or_undefined(2);
934        // 1. Let v be the this value.
935        // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Float32, value).
936        Self::set_view_value::<typed_array::Float16>(
937            this,
938            byte_offset,
939            is_little_endian,
940            value,
941            context,
942        )
943    }
944
945    /// `DataView.prototype.setFloat32 ( byteOffset, value [ , littleEndian ] )`
946    ///
947    /// The `setFloat32()` method stores a signed 32-bit float (float) value at the specified byte
948    /// offset from the start of the `DataView`.
949    ///
950    /// More information:
951    ///  - [ECMAScript reference][spec]
952    ///  - [MDN][mdn]
953    ///
954    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.setfloat32
955    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setFloat32
956    pub(crate) fn set_float32(
957        this: &JsValue,
958        args: &[JsValue],
959        context: &mut Context,
960    ) -> JsResult<JsValue> {
961        let byte_offset = args.get_or_undefined(0);
962        let value = args.get_or_undefined(1);
963        let is_little_endian = args.get_or_undefined(2);
964        // 1. Let v be the this value.
965        // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Float32, value).
966        Self::set_view_value::<f32>(this, byte_offset, is_little_endian, value, context)
967    }
968
969    /// `DataView.prototype.setFloat64 ( byteOffset, value [ , littleEndian ] )`
970    ///
971    /// The `setFloat64()` method stores a signed 64-bit float (double) value at the specified byte
972    /// offset from the start of the `DataView`.
973    ///
974    /// More information:
975    ///  - [ECMAScript reference][spec]
976    ///  - [MDN][mdn]
977    ///
978    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.setfloat64
979    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setFloat64
980    pub(crate) fn set_float64(
981        this: &JsValue,
982        args: &[JsValue],
983        context: &mut Context,
984    ) -> JsResult<JsValue> {
985        let byte_offset = args.get_or_undefined(0);
986        let value = args.get_or_undefined(1);
987        let is_little_endian = args.get_or_undefined(2);
988        // 1. Let v be the this value.
989        // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Float64, value).
990        Self::set_view_value::<f64>(this, byte_offset, is_little_endian, value, context)
991    }
992
993    /// `DataView.prototype.setInt8 ( byteOffset, value [ , littleEndian ] )`
994    ///
995    /// The `setInt8()` method stores a signed 8-bit integer (byte) value at the specified byte
996    /// offset from the start of the `DataView`.
997    ///
998    /// More information:
999    ///  - [ECMAScript reference][spec]
1000    ///  - [MDN][mdn]
1001    ///
1002    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.setint8
1003    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setInt8
1004    pub(crate) fn set_int8(
1005        this: &JsValue,
1006        args: &[JsValue],
1007        context: &mut Context,
1008    ) -> JsResult<JsValue> {
1009        let byte_offset = args.get_or_undefined(0);
1010        let value = args.get_or_undefined(1);
1011        let is_little_endian = args.get_or_undefined(2);
1012        // 1. Let v be the this value.
1013        // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Int8, value).
1014        Self::set_view_value::<i8>(this, byte_offset, is_little_endian, value, context)
1015    }
1016
1017    /// `DataView.prototype.setInt16 ( byteOffset, value [ , littleEndian ] )`
1018    ///
1019    /// The `setInt16()` method stores a signed 16-bit integer (short) value at the specified byte
1020    /// offset from the start of the `DataView`.
1021    ///
1022    /// More information:
1023    ///  - [ECMAScript reference][spec]
1024    ///  - [MDN][mdn]
1025    ///
1026    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.setint16
1027    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setInt16
1028    pub(crate) fn set_int16(
1029        this: &JsValue,
1030        args: &[JsValue],
1031        context: &mut Context,
1032    ) -> JsResult<JsValue> {
1033        let byte_offset = args.get_or_undefined(0);
1034        let value = args.get_or_undefined(1);
1035        let is_little_endian = args.get_or_undefined(2);
1036        // 1. Let v be the this value.
1037        // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Int16, value).
1038        Self::set_view_value::<i16>(this, byte_offset, is_little_endian, value, context)
1039    }
1040
1041    /// `DataView.prototype.setInt32 ( byteOffset, value [ , littleEndian ] )`
1042    ///
1043    /// The `setInt32()` method stores a signed 32-bit integer (long) value at the specified byte
1044    /// offset from the start of the `DataView`.
1045    ///
1046    /// More information:
1047    ///  - [ECMAScript reference][spec]
1048    ///  - [MDN][mdn]
1049    ///
1050    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.setint32
1051    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setInt32
1052    pub(crate) fn set_int32(
1053        this: &JsValue,
1054        args: &[JsValue],
1055        context: &mut Context,
1056    ) -> JsResult<JsValue> {
1057        let byte_offset = args.get_or_undefined(0);
1058        let value = args.get_or_undefined(1);
1059        let is_little_endian = args.get_or_undefined(2);
1060        // 1. Let v be the this value.
1061        // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Int32, value).
1062        Self::set_view_value::<i32>(this, byte_offset, is_little_endian, value, context)
1063    }
1064
1065    /// `DataView.prototype.setUint8 ( byteOffset, value [ , littleEndian ] )`
1066    ///
1067    /// The `setUint8()` method stores an unsigned 8-bit integer (byte) value at the specified byte
1068    /// offset from the start of the `DataView`.
1069    ///
1070    /// More information:
1071    ///  - [ECMAScript reference][spec]
1072    ///  - [MDN][mdn]
1073    ///
1074    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.setuint8
1075    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setUint8
1076    pub(crate) fn set_uint8(
1077        this: &JsValue,
1078        args: &[JsValue],
1079        context: &mut Context,
1080    ) -> JsResult<JsValue> {
1081        let byte_offset = args.get_or_undefined(0);
1082        let value = args.get_or_undefined(1);
1083        let is_little_endian = args.get_or_undefined(2);
1084        // 1. Let v be the this value.
1085        // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Uint8, value).
1086        Self::set_view_value::<u8>(this, byte_offset, is_little_endian, value, context)
1087    }
1088
1089    /// `DataView.prototype.setUint16 ( byteOffset, value [ , littleEndian ] )`
1090    ///
1091    /// The `setUint16()` method stores an unsigned 16-bit integer (unsigned short) value at the
1092    /// specified byte offset from the start of the `DataView`.
1093    ///
1094    /// More information:
1095    ///  - [ECMAScript reference][spec]
1096    ///  - [MDN][mdn]
1097    ///
1098    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.setuint16
1099    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setUint16
1100    pub(crate) fn set_uint16(
1101        this: &JsValue,
1102        args: &[JsValue],
1103        context: &mut Context,
1104    ) -> JsResult<JsValue> {
1105        let byte_offset = args.get_or_undefined(0);
1106        let value = args.get_or_undefined(1);
1107        let is_little_endian = args.get_or_undefined(2);
1108        // 1. Let v be the this value.
1109        // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Uint16, value).
1110        Self::set_view_value::<u16>(this, byte_offset, is_little_endian, value, context)
1111    }
1112
1113    /// `DataView.prototype.setUint32 ( byteOffset, value [ , littleEndian ] )`
1114    ///
1115    /// The `setUint32()` method stores an unsigned 32-bit integer (unsigned long) value at the
1116    /// specified byte offset from the start of the `DataView`.
1117    ///
1118    /// More information:
1119    ///  - [ECMAScript reference][spec]
1120    ///  - [MDN][mdn]
1121    ///
1122    /// [spec]: https://tc39.es/ecma262/#sec-dataview.prototype.setuint32
1123    /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView/setUint32
1124    pub(crate) fn set_uint32(
1125        this: &JsValue,
1126        args: &[JsValue],
1127        context: &mut Context,
1128    ) -> JsResult<JsValue> {
1129        let byte_offset = args.get_or_undefined(0);
1130        let value = args.get_or_undefined(1);
1131        let is_little_endian = args.get_or_undefined(2);
1132        // 1. Let v be the this value.
1133        // 2. Return ? SetViewValue(v, byteOffset, littleEndian, Uint32, value).
1134        Self::set_view_value::<u32>(this, byte_offset, is_little_endian, value, context)
1135    }
1136}