use crate::{
builtins::array_buffer::ArrayBuffer,
context::intrinsics::StandardConstructors,
object::{
internal_methods::get_prototype_from_constructor, JsObject, JsObjectType, ObjectData,
},
Context, JsResult, JsValue,
};
use boa_gc::{Finalize, Trace};
use std::ops::Deref;
#[derive(Debug, Clone, Trace, Finalize)]
pub struct JsArrayBuffer {
inner: JsObject,
}
impl JsArrayBuffer {
#[inline]
pub fn new(byte_length: usize, context: &mut Context) -> JsResult<Self> {
let inner = ArrayBuffer::allocate(
&context
.intrinsics()
.constructors()
.array_buffer()
.constructor()
.into(),
byte_length as u64,
context,
)?;
Ok(Self { inner })
}
#[inline]
pub fn from_byte_block(byte_block: Vec<u8>, context: &mut Context) -> JsResult<Self> {
let byte_length = byte_block.len();
let constructor = context
.intrinsics()
.constructors()
.array_buffer()
.constructor()
.into();
let prototype = get_prototype_from_constructor(
&constructor,
StandardConstructors::array_buffer,
context,
)?;
let obj = context.construct_object();
obj.set_prototype(prototype.into());
let block = byte_block;
obj.borrow_mut().data = ObjectData::array_buffer(ArrayBuffer {
array_buffer_data: Some(block),
array_buffer_byte_length: byte_length as u64,
array_buffer_detach_key: JsValue::Undefined,
});
Ok(Self { inner: obj })
}
#[inline]
pub fn from_object(object: JsObject, context: &mut Context) -> JsResult<Self> {
if object.borrow().is_array_buffer() {
Ok(Self { inner: object })
} else {
context.throw_type_error("object is not an ArrayBuffer")
}
}
#[inline]
pub fn byte_length(&self, context: &mut Context) -> usize {
ArrayBuffer::get_byte_length(&self.inner.clone().into(), &[], context)
.expect("it should not throw")
.as_number()
.expect("expected a number") as usize
}
}
impl From<JsArrayBuffer> for JsObject {
#[inline]
fn from(o: JsArrayBuffer) -> Self {
o.inner.clone()
}
}
impl From<JsArrayBuffer> for JsValue {
#[inline]
fn from(o: JsArrayBuffer) -> Self {
o.inner.clone().into()
}
}
impl Deref for JsArrayBuffer {
type Target = JsObject;
#[inline]
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl JsObjectType for JsArrayBuffer {}