Make HeapFloat32Array generic (#31167)

* Make HeapFloat32Array generic

Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com>

* Define all the methods defaults on the HeapTypedArray trait

Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com>

* Use generic type instead of trait

Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com>

---------

Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com>
This commit is contained in:
Taym Haddadi 2024-01-29 12:57:50 +01:00 committed by GitHub
parent 7d1b19c865
commit 742d3ed97f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 78 additions and 56 deletions

View file

@ -4,35 +4,53 @@
#![allow(unsafe_code)]
use std::marker::PhantomData;
use std::ptr;
use js::jsapi::{Heap, JSObject, JS_GetArrayBufferViewBuffer};
use js::rust::wrappers::DetachArrayBuffer;
use js::rust::{CustomAutoRooterGuard, MutableHandleObject};
use js::typedarray::{
CreateWith, Float32Array, JSObjectStorage, TypedArray, TypedArrayElement,
TypedArrayElementCreator,
};
use js::typedarray::{CreateWith, TypedArray, TypedArrayElement, TypedArrayElementCreator};
use crate::script_runtime::JSContext;
#[derive(Default, JSTraceable)]
pub struct HeapFloat32Array {
pub struct HeapTypedArray<T> {
internal: Box<Heap<*mut JSObject>>,
phantom: PhantomData<T>,
}
impl HeapFloat32Array {
pub fn set_data(&self, cx: JSContext, data: &[f32]) -> Result<(), ()> {
unsafe impl<T> crate::dom::bindings::trace::JSTraceable for HeapTypedArray<T> {
#[inline]
unsafe fn trace(&self, tracer: *mut js::jsapi::JSTracer) {
self.internal.trace(tracer);
}
}
impl<T> HeapTypedArray<T>
where
T: TypedArrayElement + TypedArrayElementCreator,
T::Element: Clone + Copy,
{
pub fn default() -> HeapTypedArray<T> {
HeapTypedArray {
internal: Box::new(Heap::default()),
phantom: PhantomData::default(),
}
}
pub fn set_data(&self, cx: JSContext, data: &[T::Element]) -> Result<(), ()> {
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
let _: Float32Array = create_typed_array(cx, data, array.handle_mut())?;
let _: TypedArray<T, *mut JSObject> = create_typed_array(cx, data, array.handle_mut())?;
self.internal.set(*array);
Ok(())
}
pub fn acquire_data(&self, cx: JSContext) -> Result<Vec<f32>, ()> {
pub fn acquire_data(&self, cx: JSContext) -> Result<Vec<T::Element>, ()> {
assert!(self.is_initialized());
typedarray!(in(*cx) let array: Float32Array = self.internal.get());
let data = if let Ok(array) = array {
typedarray!(in(*cx) let array: TypedArray = self.internal.get());
let data = if let Ok(array) =
array as Result<CustomAutoRooterGuard<'_, TypedArray<T, *mut JSObject>>, &mut ()>
{
let data = array.to_vec();
let mut is_shared = false;
unsafe {
@ -53,13 +71,15 @@ impl HeapFloat32Array {
pub fn copy_data_to(
&self,
cx: JSContext,
dest: &mut [f32],
dest: &mut [T::Element],
source_start: usize,
length: usize,
) -> Result<(), ()> {
assert!(self.is_initialized());
typedarray!(in(*cx) let array: Float32Array = self.internal.get());
let Ok(array) = array else { return Err(()) };
typedarray!(in(*cx) let array: TypedArray = self.internal.get());
let Ok(array) = array as Result<CustomAutoRooterGuard<'_, TypedArray<T, *mut JSObject>>, &mut ()> else{
return Err(())
};
unsafe {
let slice = (*array).as_slice();
dest.copy_from_slice(&slice[source_start..length]);
@ -70,13 +90,16 @@ impl HeapFloat32Array {
pub fn copy_data_from(
&self,
cx: JSContext,
source: CustomAutoRooterGuard<Float32Array>,
source: CustomAutoRooterGuard<TypedArray<T, *mut JSObject>>,
dest_start: usize,
length: usize,
) -> Result<(), ()> {
assert!(self.is_initialized());
typedarray!(in(*cx) let mut array: Float32Array = self.internal.get());
let Ok(mut array) = array else { return Err(()) };
typedarray!(in(*cx) let mut array: TypedArray = self.internal.get());
let Ok(mut array) = array as Result<CustomAutoRooterGuard<'_, TypedArray<T, *mut JSObject>>, &mut ()> else
{
return Err(())
};
unsafe {
let slice = (*array).as_mut_slice();
let (_, dest) = slice.split_at_mut(dest_start);
@ -89,11 +112,11 @@ impl HeapFloat32Array {
!self.internal.get().is_null()
}
pub fn get_internal(&self) -> Result<Float32Array, ()> {
Float32Array::from(self.internal.get())
pub fn get_internal(&self) -> Result<TypedArray<T, *mut JSObject>, ()> {
TypedArray::from(self.internal.get())
}
pub fn internal_to_option(&self) -> Option<Float32Array> {
pub fn internal_to_option(&self) -> Option<TypedArray<T, *mut JSObject>> {
if self.is_initialized() {
Some(self.get_internal().expect("Failed to get internal."))
} else {
@ -103,16 +126,15 @@ impl HeapFloat32Array {
}
}
pub fn create_typed_array<T, S>(
pub fn create_typed_array<T>(
cx: JSContext,
data: &[T::Element],
dest: MutableHandleObject,
) -> Result<TypedArray<T, S>, ()>
) -> Result<TypedArray<T, *mut JSObject>, ()>
where
T: TypedArrayElementCreator + TypedArrayElement,
S: JSObjectStorage,
T: TypedArrayElement + TypedArrayElementCreator,
{
let res = unsafe { TypedArray::<T, S>::create(*cx, CreateWith::Slice(data), dest) };
let res = unsafe { TypedArray::<T, *mut JSObject>::create(*cx, CreateWith::Slice(data), dest) };
if res.is_err() {
Err(())