diff --git a/components/script/dom/audiobuffer.rs b/components/script/dom/audiobuffer.rs index 3dfa2d0a25a..9bb797cba09 100644 --- a/components/script/dom/audiobuffer.rs +++ b/components/script/dom/audiobuffer.rs @@ -6,9 +6,10 @@ use std::cmp::min; use dom_struct::dom_struct; use js::rust::{CustomAutoRooterGuard, HandleObject}; -use js::typedarray::Float32Array; +use js::typedarray::{Float32, Float32Array}; use servo_media::audio::buffer_source_node::AudioBuffer as ServoMediaAudioBuffer; +use super::bindings::typedarrays::HeapTypedArray; use crate::dom::audionode::MAX_CHANNEL_COUNT; use crate::dom::bindings::cell::{DomRefCell, Ref}; use crate::dom::bindings::codegen::Bindings::AudioBufferBinding::{ @@ -18,7 +19,6 @@ use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::num::Finite; use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector}; use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::typedarrays::HeapFloat32Array; use crate::dom::globalscope::GlobalScope; use crate::dom::window::Window; use crate::realms::enter_realm; @@ -42,7 +42,7 @@ pub struct AudioBuffer { reflector_: Reflector, /// Float32Arrays returned by calls to GetChannelData. #[ignore_malloc_size_of = "mozjs"] - js_channels: DomRefCell>, + js_channels: DomRefCell>>, /// Aggregates the data from js_channels. /// This is Some iff the buffers in js_channels are detached. #[ignore_malloc_size_of = "servo_media"] @@ -63,7 +63,7 @@ impl AudioBuffer { #[allow(unsafe_code)] pub fn new_inherited(number_of_channels: u32, length: u32, sample_rate: f32) -> AudioBuffer { let vec = (0..number_of_channels) - .map(|_| HeapFloat32Array::default()) + .map(|_| HeapTypedArray::default()) .collect(); AudioBuffer { reflector_: Reflector::new(), diff --git a/components/script/dom/bindings/typedarrays.rs b/components/script/dom/bindings/typedarrays.rs index ddda71911bf..a85f07f9298 100644 --- a/components/script/dom/bindings/typedarrays.rs +++ b/components/script/dom/bindings/typedarrays.rs @@ -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 { internal: Box>, + phantom: PhantomData, } -impl HeapFloat32Array { - pub fn set_data(&self, cx: JSContext, data: &[f32]) -> Result<(), ()> { +unsafe impl crate::dom::bindings::trace::JSTraceable for HeapTypedArray { + #[inline] + unsafe fn trace(&self, tracer: *mut js::jsapi::JSTracer) { + self.internal.trace(tracer); + } +} + +impl HeapTypedArray +where + T: TypedArrayElement + TypedArrayElementCreator, + T::Element: Clone + Copy, +{ + pub fn default() -> HeapTypedArray { + 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::()); - let _: Float32Array = create_typed_array(cx, data, array.handle_mut())?; + let _: TypedArray = create_typed_array(cx, data, array.handle_mut())?; self.internal.set(*array); Ok(()) } - pub fn acquire_data(&self, cx: JSContext) -> Result, ()> { + pub fn acquire_data(&self, cx: JSContext) -> Result, ()> { 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>, &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>, &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, + source: CustomAutoRooterGuard>, 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>, &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::from(self.internal.get()) + pub fn get_internal(&self) -> Result, ()> { + TypedArray::from(self.internal.get()) } - pub fn internal_to_option(&self) -> Option { + pub fn internal_to_option(&self) -> Option> { 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( +pub fn create_typed_array( cx: JSContext, data: &[T::Element], dest: MutableHandleObject, -) -> Result, ()> +) -> Result, ()> where - T: TypedArrayElementCreator + TypedArrayElement, - S: JSObjectStorage, + T: TypedArrayElement + TypedArrayElementCreator, { - let res = unsafe { TypedArray::::create(*cx, CreateWith::Slice(data), dest) }; + let res = unsafe { TypedArray::::create(*cx, CreateWith::Slice(data), dest) }; if res.is_err() { Err(()) diff --git a/components/script/dom/gamepadpose.rs b/components/script/dom/gamepadpose.rs index 60b2e4521a7..709c6fd7648 100644 --- a/components/script/dom/gamepadpose.rs +++ b/components/script/dom/gamepadpose.rs @@ -3,9 +3,9 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use dom_struct::dom_struct; -use js::typedarray::Float32Array; +use js::typedarray::{Float32, Float32Array}; -use super::bindings::typedarrays::HeapFloat32Array; +use super::bindings::typedarrays::HeapTypedArray; use crate::dom::bindings::codegen::Bindings::GamepadPoseBinding::GamepadPoseMethods; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::DomRoot; @@ -16,17 +16,17 @@ use crate::script_runtime::JSContext; pub struct GamepadPose { reflector_: Reflector, #[ignore_malloc_size_of = "mozjs"] - position: HeapFloat32Array, + position: HeapTypedArray, #[ignore_malloc_size_of = "mozjs"] - orientation: HeapFloat32Array, + orientation: HeapTypedArray, #[ignore_malloc_size_of = "mozjs"] - linear_vel: HeapFloat32Array, + linear_vel: HeapTypedArray, #[ignore_malloc_size_of = "mozjs"] - angular_vel: HeapFloat32Array, + angular_vel: HeapTypedArray, #[ignore_malloc_size_of = "mozjs"] - linear_acc: HeapFloat32Array, + linear_acc: HeapTypedArray, #[ignore_malloc_size_of = "mozjs"] - angular_acc: HeapFloat32Array, + angular_acc: HeapTypedArray, } // TODO: support gamepad discovery @@ -35,12 +35,12 @@ impl GamepadPose { fn new_inherited() -> GamepadPose { GamepadPose { reflector_: Reflector::new(), - position: HeapFloat32Array::default(), - orientation: HeapFloat32Array::default(), - linear_vel: HeapFloat32Array::default(), - angular_vel: HeapFloat32Array::default(), - linear_acc: HeapFloat32Array::default(), - angular_acc: HeapFloat32Array::default(), + position: HeapTypedArray::default(), + orientation: HeapTypedArray::default(), + linear_vel: HeapTypedArray::default(), + angular_vel: HeapTypedArray::default(), + linear_acc: HeapTypedArray::default(), + angular_acc: HeapTypedArray::default(), } } diff --git a/components/script/dom/xrray.rs b/components/script/dom/xrray.rs index 62d1d1aa6eb..a91395acb8a 100644 --- a/components/script/dom/xrray.rs +++ b/components/script/dom/xrray.rs @@ -5,15 +5,15 @@ use dom_struct::dom_struct; use euclid::{Angle, RigidTransform3D, Rotation3D, Vector3D}; use js::rust::HandleObject; -use js::typedarray::Float32Array; +use js::typedarray::{Float32, Float32Array}; use webxr_api::{ApiSpace, Ray}; +use super::bindings::typedarrays::HeapTypedArray; use crate::dom::bindings::codegen::Bindings::DOMPointBinding::DOMPointInit; use crate::dom::bindings::codegen::Bindings::XRRayBinding::{XRRayDirectionInit, XRRayMethods}; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject, Reflector}; use crate::dom::bindings::root::DomRoot; -use crate::dom::bindings::typedarrays::HeapFloat32Array; use crate::dom::dompointreadonly::DOMPointReadOnly; use crate::dom::globalscope::GlobalScope; use crate::dom::window::Window; @@ -27,7 +27,7 @@ pub struct XRRay { #[no_trace] ray: Ray, #[ignore_malloc_size_of = "defined in mozjs"] - matrix: HeapFloat32Array, + matrix: HeapTypedArray, } impl XRRay { @@ -35,7 +35,7 @@ impl XRRay { XRRay { reflector_: Reflector::new(), ray, - matrix: HeapFloat32Array::default(), + matrix: HeapTypedArray::default(), } } diff --git a/components/script/dom/xrrigidtransform.rs b/components/script/dom/xrrigidtransform.rs index c30b2f20a2e..b5677cd48ba 100644 --- a/components/script/dom/xrrigidtransform.rs +++ b/components/script/dom/xrrigidtransform.rs @@ -5,14 +5,14 @@ use dom_struct::dom_struct; use euclid::{RigidTransform3D, Rotation3D, Vector3D}; use js::rust::HandleObject; -use js::typedarray::Float32Array; +use js::typedarray::{Float32, Float32Array}; +use super::bindings::typedarrays::HeapTypedArray; use crate::dom::bindings::codegen::Bindings::DOMPointBinding::DOMPointInit; use crate::dom::bindings::codegen::Bindings::XRRigidTransformBinding::XRRigidTransformMethods; use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject, Reflector}; use crate::dom::bindings::root::{DomRoot, MutNullableDom}; -use crate::dom::bindings::typedarrays::HeapFloat32Array; use crate::dom::dompointreadonly::DOMPointReadOnly; use crate::dom::globalscope::GlobalScope; use crate::dom::window::Window; @@ -29,7 +29,7 @@ pub struct XRRigidTransform { transform: ApiRigidTransform, inverse: MutNullableDom, #[ignore_malloc_size_of = "defined in mozjs"] - matrix: HeapFloat32Array, + matrix: HeapTypedArray, } impl XRRigidTransform { @@ -40,7 +40,7 @@ impl XRRigidTransform { orientation: MutNullableDom::default(), transform, inverse: MutNullableDom::default(), - matrix: HeapFloat32Array::default(), + matrix: HeapTypedArray::default(), } } diff --git a/components/script/dom/xrview.rs b/components/script/dom/xrview.rs index 15a273319a2..6c8c7ab2f7d 100644 --- a/components/script/dom/xrview.rs +++ b/components/script/dom/xrview.rs @@ -4,13 +4,13 @@ use dom_struct::dom_struct; use euclid::RigidTransform3D; -use js::typedarray::Float32Array; +use js::typedarray::{Float32, Float32Array}; use webxr_api::{ApiSpace, View}; +use super::bindings::typedarrays::HeapTypedArray; use crate::dom::bindings::codegen::Bindings::XRViewBinding::{XREye, XRViewMethods}; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; -use crate::dom::bindings::typedarrays::HeapFloat32Array; use crate::dom::globalscope::GlobalScope; use crate::dom::xrrigidtransform::XRRigidTransform; use crate::dom::xrsession::{cast_transform, BaseSpace, BaseTransform, XRSession}; @@ -23,7 +23,7 @@ pub struct XRView { eye: XREye, viewport_index: usize, #[ignore_malloc_size_of = "mozjs"] - proj: HeapFloat32Array, + proj: HeapTypedArray, #[ignore_malloc_size_of = "defined in rust-webxr"] #[no_trace] view: View, @@ -43,7 +43,7 @@ impl XRView { session: Dom::from_ref(session), eye, viewport_index, - proj: HeapFloat32Array::default(), + proj: HeapTypedArray::default(), view, transform: Dom::from_ref(transform), }