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}