mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
WedIDL: bring dom/bindings/typedarray further in line with spec (#31375)
* WedIDL: bring dom/bindings/typedarray further in line with spec Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com> * Rename HeapBufferSourceTypes to HeapBufferSource Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com> * fmt code Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com> --------- Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com>
This commit is contained in:
parent
32f1d07323
commit
d0b663800f
15 changed files with 505 additions and 317 deletions
|
@ -9,7 +9,7 @@ use js::rust::{CustomAutoRooterGuard, HandleObject};
|
|||
use js::typedarray::{Float32, Float32Array};
|
||||
use servo_media::audio::buffer_source_node::AudioBuffer as ServoMediaAudioBuffer;
|
||||
|
||||
use super::bindings::typedarrays::HeapTypedArray;
|
||||
use super::bindings::buffer_source::HeapBufferSource;
|
||||
use crate::dom::audionode::MAX_CHANNEL_COUNT;
|
||||
use crate::dom::bindings::cell::{DomRefCell, Ref};
|
||||
use crate::dom::bindings::codegen::Bindings::AudioBufferBinding::{
|
||||
|
@ -42,7 +42,7 @@ pub struct AudioBuffer {
|
|||
reflector_: Reflector,
|
||||
/// Float32Arrays returned by calls to GetChannelData.
|
||||
#[ignore_malloc_size_of = "mozjs"]
|
||||
js_channels: DomRefCell<Vec<HeapTypedArray<Float32>>>,
|
||||
js_channels: DomRefCell<Vec<HeapBufferSource<Float32>>>,
|
||||
/// Aggregates the data from js_channels.
|
||||
/// This is Some<T> iff the buffers in js_channels are detached.
|
||||
#[ignore_malloc_size_of = "servo_media"]
|
||||
|
@ -60,10 +60,9 @@ pub struct AudioBuffer {
|
|||
|
||||
impl AudioBuffer {
|
||||
#[allow(crown::unrooted_must_root)]
|
||||
#[allow(unsafe_code)]
|
||||
pub fn new_inherited(number_of_channels: u32, length: u32, sample_rate: f32) -> AudioBuffer {
|
||||
let vec = (0..number_of_channels)
|
||||
.map(|_| HeapTypedArray::default())
|
||||
.map(|_| HeapBufferSource::default())
|
||||
.collect();
|
||||
AudioBuffer {
|
||||
reflector_: Reflector::new(),
|
||||
|
@ -238,7 +237,7 @@ impl AudioBufferMethods for AudioBuffer {
|
|||
}
|
||||
|
||||
self.js_channels.borrow()[channel as usize]
|
||||
.get_internal()
|
||||
.get_buffer()
|
||||
.map_err(|_| Error::JSFailed)
|
||||
}
|
||||
|
||||
|
|
441
components/script/dom/bindings/buffer_source.rs
Normal file
441
components/script/dom/bindings/buffer_source.rs
Normal file
|
@ -0,0 +1,441 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#![allow(unsafe_code)]
|
||||
|
||||
use std::borrow::BorrowMut;
|
||||
use std::ffi::c_void;
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use js::jsapi::{
|
||||
Heap, JSObject, JS_GetArrayBufferViewBuffer, JS_IsArrayBufferViewObject, NewExternalArrayBuffer,
|
||||
};
|
||||
use js::rust::wrappers::DetachArrayBuffer;
|
||||
use js::rust::{CustomAutoRooterGuard, Handle, MutableHandleObject};
|
||||
use js::typedarray::{CreateWith, TypedArray, TypedArrayElement, TypedArrayElementCreator};
|
||||
|
||||
use crate::script_runtime::JSContext;
|
||||
|
||||
/// <https://webidl.spec.whatwg.org/#BufferSource>
|
||||
#[allow(dead_code)]
|
||||
pub enum BufferSource {
|
||||
Int8Array(Box<Heap<*mut JSObject>>),
|
||||
Int16Array(Box<Heap<*mut JSObject>>),
|
||||
Int32Array(Box<Heap<*mut JSObject>>),
|
||||
Uint8Array(Box<Heap<*mut JSObject>>),
|
||||
Uint16Array(Box<Heap<*mut JSObject>>),
|
||||
Uint32Array(Box<Heap<*mut JSObject>>),
|
||||
Uint8ClampedArray(Box<Heap<*mut JSObject>>),
|
||||
BigInt64Array(Box<Heap<*mut JSObject>>),
|
||||
BigUint64Array(Box<Heap<*mut JSObject>>),
|
||||
Float32Array(Box<Heap<*mut JSObject>>),
|
||||
Float64Array(Box<Heap<*mut JSObject>>),
|
||||
DataView(Box<Heap<*mut JSObject>>),
|
||||
ArrayBuffer(Box<Heap<*mut JSObject>>),
|
||||
Default(Box<Heap<*mut JSObject>>),
|
||||
}
|
||||
|
||||
pub struct HeapBufferSource<T> {
|
||||
buffer_source: BufferSource,
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
unsafe impl<T> crate::dom::bindings::trace::JSTraceable for HeapBufferSource<T> {
|
||||
#[inline]
|
||||
unsafe fn trace(&self, tracer: *mut js::jsapi::JSTracer) {
|
||||
match &self.buffer_source {
|
||||
BufferSource::Int8Array(buffer) |
|
||||
BufferSource::Int16Array(buffer) |
|
||||
BufferSource::Int32Array(buffer) |
|
||||
BufferSource::Uint8Array(buffer) |
|
||||
BufferSource::Uint16Array(buffer) |
|
||||
BufferSource::Uint32Array(buffer) |
|
||||
BufferSource::Uint8ClampedArray(buffer) |
|
||||
BufferSource::BigInt64Array(buffer) |
|
||||
BufferSource::BigUint64Array(buffer) |
|
||||
BufferSource::Float32Array(buffer) |
|
||||
BufferSource::Float64Array(buffer) |
|
||||
BufferSource::DataView(buffer) |
|
||||
BufferSource::ArrayBuffer(buffer) |
|
||||
BufferSource::Default(buffer) => {
|
||||
buffer.trace(tracer);
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_initialized_heap_buffer_source_types<T>(
|
||||
init: HeapTypedArrayInit,
|
||||
) -> Result<HeapBufferSource<T>, ()>
|
||||
where
|
||||
T: TypedArrayElement + TypedArrayElementCreator,
|
||||
T::Element: Clone + Copy,
|
||||
{
|
||||
let heap_buffer_source_types = match init {
|
||||
HeapTypedArrayInit::Buffer(buffer_source) => HeapBufferSource {
|
||||
buffer_source: buffer_source,
|
||||
phantom: PhantomData::default(),
|
||||
},
|
||||
HeapTypedArrayInit::Info { len, cx } => {
|
||||
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
|
||||
let typed_array_result =
|
||||
create_buffer_source_types_with_length::<T>(cx, len as usize, array.handle_mut());
|
||||
if typed_array_result.is_err() {
|
||||
return Err(());
|
||||
}
|
||||
let heap_buffer_source_types = HeapBufferSource::<T>::default();
|
||||
|
||||
match &heap_buffer_source_types.buffer_source {
|
||||
BufferSource::Int8Array(buffer) |
|
||||
BufferSource::Int16Array(buffer) |
|
||||
BufferSource::Int32Array(buffer) |
|
||||
BufferSource::Uint8Array(buffer) |
|
||||
BufferSource::Uint16Array(buffer) |
|
||||
BufferSource::Uint32Array(buffer) |
|
||||
BufferSource::Uint8ClampedArray(buffer) |
|
||||
BufferSource::BigInt64Array(buffer) |
|
||||
BufferSource::BigUint64Array(buffer) |
|
||||
BufferSource::Float32Array(buffer) |
|
||||
BufferSource::Float64Array(buffer) |
|
||||
BufferSource::DataView(buffer) |
|
||||
BufferSource::ArrayBuffer(buffer) |
|
||||
BufferSource::Default(buffer) => {
|
||||
buffer.set(*array);
|
||||
},
|
||||
}
|
||||
heap_buffer_source_types
|
||||
},
|
||||
};
|
||||
Ok(heap_buffer_source_types)
|
||||
}
|
||||
|
||||
pub enum HeapTypedArrayInit {
|
||||
Buffer(BufferSource),
|
||||
Info { len: u32, cx: JSContext },
|
||||
}
|
||||
|
||||
impl<T> HeapBufferSource<T>
|
||||
where
|
||||
T: TypedArrayElement + TypedArrayElementCreator,
|
||||
T::Element: Clone + Copy,
|
||||
{
|
||||
pub fn default() -> HeapBufferSource<T> {
|
||||
HeapBufferSource {
|
||||
buffer_source: BufferSource::Default(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 _: TypedArray<T, *mut JSObject> =
|
||||
create_buffer_source_types(cx, data, array.handle_mut())?;
|
||||
|
||||
match &self.buffer_source {
|
||||
BufferSource::Int8Array(buffer) |
|
||||
BufferSource::Int16Array(buffer) |
|
||||
BufferSource::Int32Array(buffer) |
|
||||
BufferSource::Uint8Array(buffer) |
|
||||
BufferSource::Uint16Array(buffer) |
|
||||
BufferSource::Uint32Array(buffer) |
|
||||
BufferSource::Uint8ClampedArray(buffer) |
|
||||
BufferSource::BigInt64Array(buffer) |
|
||||
BufferSource::BigUint64Array(buffer) |
|
||||
BufferSource::Float32Array(buffer) |
|
||||
BufferSource::Float64Array(buffer) |
|
||||
BufferSource::DataView(buffer) |
|
||||
BufferSource::ArrayBuffer(buffer) |
|
||||
BufferSource::Default(buffer) => {
|
||||
buffer.set(*array);
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn acquire_data(&self, cx: JSContext) -> Result<Vec<T::Element>, ()> {
|
||||
assert!(self.is_initialized());
|
||||
|
||||
typedarray!(in(*cx) let array: TypedArray = match &self.buffer_source {
|
||||
BufferSource::Int8Array(buffer) |
|
||||
BufferSource::Int16Array(buffer) |
|
||||
BufferSource::Int32Array(buffer) |
|
||||
BufferSource::Uint8Array(buffer) |
|
||||
BufferSource::Uint16Array(buffer) |
|
||||
BufferSource::Uint32Array(buffer) |
|
||||
BufferSource::Uint8ClampedArray(buffer) |
|
||||
BufferSource::BigInt64Array(buffer) |
|
||||
BufferSource::BigUint64Array(buffer) |
|
||||
BufferSource::Float32Array(buffer) |
|
||||
BufferSource::Float64Array(buffer) |
|
||||
BufferSource::DataView(buffer) |
|
||||
BufferSource::ArrayBuffer(buffer) |
|
||||
BufferSource::Default(buffer) => {
|
||||
buffer.get()
|
||||
},
|
||||
});
|
||||
let data = if let Ok(array) =
|
||||
array as Result<CustomAutoRooterGuard<'_, TypedArray<T, *mut JSObject>>, &mut ()>
|
||||
{
|
||||
let data = array.to_vec();
|
||||
let _ = self.detach_buffer(cx);
|
||||
Ok(data)
|
||||
} else {
|
||||
Err(())
|
||||
};
|
||||
|
||||
match &self.buffer_source {
|
||||
BufferSource::Int8Array(buffer) |
|
||||
BufferSource::Int16Array(buffer) |
|
||||
BufferSource::Int32Array(buffer) |
|
||||
BufferSource::Uint8Array(buffer) |
|
||||
BufferSource::Uint16Array(buffer) |
|
||||
BufferSource::Uint32Array(buffer) |
|
||||
BufferSource::Uint8ClampedArray(buffer) |
|
||||
BufferSource::BigInt64Array(buffer) |
|
||||
BufferSource::BigUint64Array(buffer) |
|
||||
BufferSource::Float32Array(buffer) |
|
||||
BufferSource::Float64Array(buffer) |
|
||||
BufferSource::DataView(buffer) |
|
||||
BufferSource::ArrayBuffer(buffer) |
|
||||
BufferSource::Default(buffer) => {
|
||||
buffer.set(ptr::null_mut());
|
||||
},
|
||||
}
|
||||
data
|
||||
}
|
||||
|
||||
/// <https://tc39.es/ecma262/#sec-detacharraybuffer>
|
||||
pub fn detach_buffer(&self, cx: JSContext) -> bool {
|
||||
match &self.buffer_source {
|
||||
BufferSource::Int8Array(buffer) |
|
||||
BufferSource::Int16Array(buffer) |
|
||||
BufferSource::Int32Array(buffer) |
|
||||
BufferSource::Uint8Array(buffer) |
|
||||
BufferSource::Uint16Array(buffer) |
|
||||
BufferSource::Uint32Array(buffer) |
|
||||
BufferSource::Uint8ClampedArray(buffer) |
|
||||
BufferSource::BigInt64Array(buffer) |
|
||||
BufferSource::BigUint64Array(buffer) |
|
||||
BufferSource::Float32Array(buffer) |
|
||||
BufferSource::Float64Array(buffer) |
|
||||
BufferSource::DataView(buffer) |
|
||||
BufferSource::ArrayBuffer(buffer) |
|
||||
BufferSource::Default(buffer) => {
|
||||
assert!(self.is_initialized());
|
||||
let mut is_shared = false;
|
||||
unsafe {
|
||||
if JS_IsArrayBufferViewObject(*buffer.handle()) {
|
||||
// If it is an ArrayBuffer view, get the buffer using JS_GetArrayBufferViewBuffer
|
||||
rooted!(in (*cx) let view_buffer =
|
||||
JS_GetArrayBufferViewBuffer(*cx, buffer.handle(), &mut is_shared));
|
||||
// This buffer is always created unshared
|
||||
debug_assert!(!is_shared);
|
||||
// Detach the ArrayBuffer
|
||||
DetachArrayBuffer(*cx, view_buffer.handle())
|
||||
} else {
|
||||
// If it's not an ArrayBuffer view, Detach the buffer directly
|
||||
DetachArrayBuffer(*cx, Handle::from_raw(buffer.handle()))
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_data_to(
|
||||
&self,
|
||||
cx: JSContext,
|
||||
dest: &mut [T::Element],
|
||||
source_start: usize,
|
||||
length: usize,
|
||||
) -> Result<(), ()> {
|
||||
assert!(self.is_initialized());
|
||||
typedarray!(in(*cx) let array: TypedArray = match &self.buffer_source {
|
||||
BufferSource::Int8Array(buffer) |
|
||||
BufferSource::Int16Array(buffer) |
|
||||
BufferSource::Int32Array(buffer) |
|
||||
BufferSource::Uint8Array(buffer) |
|
||||
BufferSource::Uint16Array(buffer) |
|
||||
BufferSource::Uint32Array(buffer) |
|
||||
BufferSource::Uint8ClampedArray(buffer) |
|
||||
BufferSource::BigInt64Array(buffer) |
|
||||
BufferSource::BigUint64Array(buffer) |
|
||||
BufferSource::Float32Array(buffer) |
|
||||
BufferSource::Float64Array(buffer) |
|
||||
BufferSource::DataView(buffer) |
|
||||
BufferSource::ArrayBuffer(buffer) |
|
||||
BufferSource::Default(buffer) => {
|
||||
buffer.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]);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn copy_data_from(
|
||||
&self,
|
||||
cx: JSContext,
|
||||
source: CustomAutoRooterGuard<TypedArray<T, *mut JSObject>>,
|
||||
dest_start: usize,
|
||||
length: usize,
|
||||
) -> Result<(), ()> {
|
||||
assert!(self.is_initialized());
|
||||
typedarray!(in(*cx) let mut array: TypedArray = match &self.buffer_source {
|
||||
BufferSource::Int8Array(buffer) |
|
||||
BufferSource::Int16Array(buffer) |
|
||||
BufferSource::Int32Array(buffer) |
|
||||
BufferSource::Uint8Array(buffer) |
|
||||
BufferSource::Uint16Array(buffer) |
|
||||
BufferSource::Uint32Array(buffer) |
|
||||
BufferSource::Uint8ClampedArray(buffer) |
|
||||
BufferSource::BigInt64Array(buffer) |
|
||||
BufferSource::BigUint64Array(buffer) |
|
||||
BufferSource::Float32Array(buffer) |
|
||||
BufferSource::Float64Array(buffer) |
|
||||
BufferSource::DataView(buffer) |
|
||||
BufferSource::ArrayBuffer(buffer) |
|
||||
BufferSource::Default(buffer) => {
|
||||
buffer.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);
|
||||
dest[0..length].copy_from_slice(&source.as_slice()[0..length])
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_initialized(&self) -> bool {
|
||||
match &self.buffer_source {
|
||||
BufferSource::Int8Array(buffer) |
|
||||
BufferSource::Int16Array(buffer) |
|
||||
BufferSource::Int32Array(buffer) |
|
||||
BufferSource::Uint8Array(buffer) |
|
||||
BufferSource::Uint16Array(buffer) |
|
||||
BufferSource::Uint32Array(buffer) |
|
||||
BufferSource::Uint8ClampedArray(buffer) |
|
||||
BufferSource::BigInt64Array(buffer) |
|
||||
BufferSource::BigUint64Array(buffer) |
|
||||
BufferSource::Float32Array(buffer) |
|
||||
BufferSource::Float64Array(buffer) |
|
||||
BufferSource::DataView(buffer) |
|
||||
BufferSource::ArrayBuffer(buffer) |
|
||||
BufferSource::Default(buffer) => !buffer.get().is_null(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_buffer(&self) -> Result<TypedArray<T, *mut JSObject>, ()> {
|
||||
TypedArray::from(match &self.buffer_source {
|
||||
BufferSource::Int8Array(buffer) |
|
||||
BufferSource::Int16Array(buffer) |
|
||||
BufferSource::Int32Array(buffer) |
|
||||
BufferSource::Uint8Array(buffer) |
|
||||
BufferSource::Uint16Array(buffer) |
|
||||
BufferSource::Uint32Array(buffer) |
|
||||
BufferSource::Uint8ClampedArray(buffer) |
|
||||
BufferSource::BigInt64Array(buffer) |
|
||||
BufferSource::BigUint64Array(buffer) |
|
||||
BufferSource::Float32Array(buffer) |
|
||||
BufferSource::Float64Array(buffer) |
|
||||
BufferSource::DataView(buffer) |
|
||||
BufferSource::ArrayBuffer(buffer) |
|
||||
BufferSource::Default(buffer) => buffer.get(),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn buffer_to_option(&self) -> Option<TypedArray<T, *mut JSObject>> {
|
||||
if self.is_initialized() {
|
||||
Some(self.get_buffer().expect("Failed to get buffer."))
|
||||
} else {
|
||||
warn!("Buffer not initialized.");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://webidl.spec.whatwg.org/#arraybufferview-create>
|
||||
pub fn create_buffer_source_types<T>(
|
||||
cx: JSContext,
|
||||
data: &[T::Element],
|
||||
dest: MutableHandleObject,
|
||||
) -> Result<TypedArray<T, *mut JSObject>, ()>
|
||||
where
|
||||
T: TypedArrayElement + TypedArrayElementCreator,
|
||||
{
|
||||
let res = unsafe { TypedArray::<T, *mut JSObject>::create(*cx, CreateWith::Slice(data), dest) };
|
||||
|
||||
if res.is_err() {
|
||||
Err(())
|
||||
} else {
|
||||
TypedArray::from(dest.get())
|
||||
}
|
||||
}
|
||||
|
||||
fn create_buffer_source_types_with_length<T>(
|
||||
cx: JSContext,
|
||||
len: usize,
|
||||
dest: MutableHandleObject,
|
||||
) -> Result<TypedArray<T, *mut JSObject>, ()>
|
||||
where
|
||||
T: TypedArrayElement + TypedArrayElementCreator,
|
||||
{
|
||||
let res = unsafe { TypedArray::<T, *mut JSObject>::create(*cx, CreateWith::Length(len), dest) };
|
||||
|
||||
if res.is_err() {
|
||||
Err(())
|
||||
} else {
|
||||
TypedArray::from(dest.get())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_new_external_array_buffer<T>(
|
||||
cx: JSContext,
|
||||
mapping: Arc<Mutex<Vec<T::Element>>>,
|
||||
offset: usize,
|
||||
range_size: usize,
|
||||
m_end: usize,
|
||||
) -> HeapBufferSource<T>
|
||||
where
|
||||
T: TypedArrayElement + TypedArrayElementCreator,
|
||||
T::Element: Clone + Copy,
|
||||
{
|
||||
/// `freeFunc()` must be threadsafe, should be safely callable from any thread
|
||||
/// without causing conflicts , unexpected behavior.
|
||||
/// <https://github.com/servo/mozjs/blob/main/mozjs-sys/mozjs/js/public/ArrayBuffer.h#L89>
|
||||
unsafe extern "C" fn free_func(_contents: *mut c_void, free_user_data: *mut c_void) {
|
||||
let _ = Arc::from_raw(free_user_data as _);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let mapping_slice_ptr =
|
||||
mapping.lock().unwrap().borrow_mut()[offset as usize..m_end as usize].as_mut_ptr();
|
||||
|
||||
// rooted! is needed to ensure memory safety and prevent potential garbage collection issues.
|
||||
// https://github.com/mozilla-spidermonkey/spidermonkey-embedding-examples/blob/esr78/docs/GC%20Rooting%20Guide.md#performance-tweaking
|
||||
rooted!(in(*cx) let array_buffer = NewExternalArrayBuffer(
|
||||
*cx,
|
||||
range_size as usize,
|
||||
mapping_slice_ptr as _,
|
||||
Some(free_func),
|
||||
Arc::into_raw(mapping) as _,
|
||||
));
|
||||
|
||||
HeapBufferSource {
|
||||
buffer_source: BufferSource::ArrayBuffer(Heap::boxed(*array_buffer)),
|
||||
phantom: PhantomData::default(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -134,6 +134,7 @@
|
|||
#![deny(missing_docs)]
|
||||
#![deny(non_snake_case)]
|
||||
|
||||
pub mod buffer_source;
|
||||
pub mod callback;
|
||||
pub mod cell;
|
||||
pub mod constant;
|
||||
|
@ -159,7 +160,6 @@ pub mod str;
|
|||
pub mod structuredclone;
|
||||
pub mod trace;
|
||||
pub mod transferable;
|
||||
pub mod typedarrays;
|
||||
pub mod utils;
|
||||
pub mod weakref;
|
||||
pub mod xmlname;
|
||||
|
|
|
@ -1,250 +0,0 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#![allow(unsafe_code)]
|
||||
|
||||
use std::borrow::BorrowMut;
|
||||
use std::ffi::c_void;
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use js::jsapi::{
|
||||
Heap, JSObject, JS_GetArrayBufferViewBuffer, JS_IsArrayBufferViewObject, NewExternalArrayBuffer,
|
||||
};
|
||||
use js::rust::wrappers::DetachArrayBuffer;
|
||||
use js::rust::{CustomAutoRooterGuard, Handle, MutableHandleObject};
|
||||
use js::typedarray::{CreateWith, TypedArray, TypedArrayElement, TypedArrayElementCreator};
|
||||
|
||||
use crate::script_runtime::JSContext;
|
||||
|
||||
pub struct HeapTypedArray<T> {
|
||||
internal: Box<Heap<*mut JSObject>>,
|
||||
phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_initialized_heap_typed_array<T>(
|
||||
init: HeapTypedArrayInit,
|
||||
) -> Result<HeapTypedArray<T>, ()>
|
||||
where
|
||||
T: TypedArrayElement + TypedArrayElementCreator,
|
||||
T::Element: Clone + Copy,
|
||||
{
|
||||
let heap_typed_array = match init {
|
||||
HeapTypedArrayInit::Object(js_object) => HeapTypedArray {
|
||||
internal: Heap::boxed(js_object),
|
||||
phantom: PhantomData::default(),
|
||||
},
|
||||
HeapTypedArrayInit::Info { len, cx } => {
|
||||
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
|
||||
let typed_array_result =
|
||||
create_typed_array_with_length::<T>(cx, len as usize, array.handle_mut());
|
||||
if typed_array_result.is_err() {
|
||||
return Err(());
|
||||
}
|
||||
let heap_typed_array = HeapTypedArray::<T>::default();
|
||||
heap_typed_array.internal.set(*array);
|
||||
heap_typed_array
|
||||
},
|
||||
};
|
||||
Ok(heap_typed_array)
|
||||
}
|
||||
|
||||
pub enum HeapTypedArrayInit {
|
||||
Object(*mut JSObject),
|
||||
Info { len: u32, cx: JSContext },
|
||||
}
|
||||
|
||||
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 _: 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<T::Element>, ()> {
|
||||
assert!(self.is_initialized());
|
||||
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 _ = self.detach_internal(cx);
|
||||
Ok(data)
|
||||
} else {
|
||||
Err(())
|
||||
};
|
||||
self.internal.set(ptr::null_mut());
|
||||
data
|
||||
}
|
||||
|
||||
/// <https://tc39.es/ecma262/#sec-detacharraybuffer>
|
||||
pub fn detach_internal(&self, cx: JSContext) -> bool {
|
||||
assert!(self.is_initialized());
|
||||
let mut is_shared = false;
|
||||
unsafe {
|
||||
if JS_IsArrayBufferViewObject(*self.internal.handle()) {
|
||||
// If it is an ArrayBuffer view, get the buffer using JS_GetArrayBufferViewBuffer
|
||||
rooted!(in (*cx) let view_buffer =
|
||||
JS_GetArrayBufferViewBuffer(*cx, self.internal.handle(), &mut is_shared));
|
||||
// This buffer is always created unshared
|
||||
debug_assert!(!is_shared);
|
||||
// Detach the ArrayBuffer
|
||||
DetachArrayBuffer(*cx, view_buffer.handle())
|
||||
} else {
|
||||
// If it's not an ArrayBuffer view, Detach the internal buffer directly
|
||||
DetachArrayBuffer(*cx, Handle::from_raw(self.internal.handle()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn copy_data_to(
|
||||
&self,
|
||||
cx: JSContext,
|
||||
dest: &mut [T::Element],
|
||||
source_start: usize,
|
||||
length: usize,
|
||||
) -> Result<(), ()> {
|
||||
assert!(self.is_initialized());
|
||||
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]);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn copy_data_from(
|
||||
&self,
|
||||
cx: JSContext,
|
||||
source: CustomAutoRooterGuard<TypedArray<T, *mut JSObject>>,
|
||||
dest_start: usize,
|
||||
length: usize,
|
||||
) -> Result<(), ()> {
|
||||
assert!(self.is_initialized());
|
||||
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);
|
||||
dest[0..length].copy_from_slice(&source.as_slice()[0..length])
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn is_initialized(&self) -> bool {
|
||||
!self.internal.get().is_null()
|
||||
}
|
||||
|
||||
pub fn get_internal(&self) -> Result<TypedArray<T, *mut JSObject>, ()> {
|
||||
TypedArray::from(self.internal.get())
|
||||
}
|
||||
|
||||
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 {
|
||||
warn!("Internal not initialized.");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_typed_array<T>(
|
||||
cx: JSContext,
|
||||
data: &[T::Element],
|
||||
dest: MutableHandleObject,
|
||||
) -> Result<TypedArray<T, *mut JSObject>, ()>
|
||||
where
|
||||
T: TypedArrayElement + TypedArrayElementCreator,
|
||||
{
|
||||
let res = unsafe { TypedArray::<T, *mut JSObject>::create(*cx, CreateWith::Slice(data), dest) };
|
||||
|
||||
if res.is_err() {
|
||||
Err(())
|
||||
} else {
|
||||
TypedArray::from(dest.get())
|
||||
}
|
||||
}
|
||||
|
||||
fn create_typed_array_with_length<T>(
|
||||
cx: JSContext,
|
||||
len: usize,
|
||||
dest: MutableHandleObject,
|
||||
) -> Result<TypedArray<T, *mut JSObject>, ()>
|
||||
where
|
||||
T: TypedArrayElement + TypedArrayElementCreator,
|
||||
{
|
||||
let res = unsafe { TypedArray::<T, *mut JSObject>::create(*cx, CreateWith::Length(len), dest) };
|
||||
|
||||
if res.is_err() {
|
||||
Err(())
|
||||
} else {
|
||||
TypedArray::from(dest.get())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_new_external_array_buffer<T>(
|
||||
cx: JSContext,
|
||||
mapping: Arc<Mutex<Vec<T::Element>>>,
|
||||
offset: usize,
|
||||
range_size: usize,
|
||||
m_end: usize,
|
||||
) -> HeapTypedArray<T>
|
||||
where
|
||||
T: TypedArrayElement + TypedArrayElementCreator,
|
||||
T::Element: Clone + Copy,
|
||||
{
|
||||
/// `freeFunc()` must be threadsafe, should be safely callable from any thread
|
||||
/// without causing conflicts or unexpected behavior.
|
||||
/// <https://github.com/servo/mozjs/blob/main/mozjs-sys/mozjs/js/public/ArrayBuffer.h#L89>
|
||||
unsafe extern "C" fn free_func(_contents: *mut c_void, free_user_data: *mut c_void) {
|
||||
let _ = Arc::from_raw(free_user_data as _);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let mapping_slice_ptr =
|
||||
mapping.lock().unwrap().borrow_mut()[offset as usize..m_end as usize].as_mut_ptr();
|
||||
|
||||
// rooted! is needed to ensure memory safety and prevent potential garbage collection issues.
|
||||
// https://github.com/mozilla-spidermonkey/spidermonkey-embedding-examples/blob/esr78/docs/GC%20Rooting%20Guide.md#performance-tweaking
|
||||
rooted!(in(*cx) let array_buffer = NewExternalArrayBuffer(
|
||||
*cx,
|
||||
range_size as usize,
|
||||
mapping_slice_ptr as _,
|
||||
Some(free_func),
|
||||
Arc::into_raw(mapping) as _,
|
||||
));
|
||||
|
||||
HeapTypedArray {
|
||||
internal: Heap::boxed(*array_buffer),
|
||||
phantom: PhantomData::default(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,6 +15,7 @@ use js::typedarray::{Float32Array, Float64Array};
|
|||
use style::parser::ParserContext;
|
||||
use url::Url;
|
||||
|
||||
use crate::dom::bindings::buffer_source::create_buffer_source_types;
|
||||
use crate::dom::bindings::cell::{DomRefCell, Ref};
|
||||
use crate::dom::bindings::codegen::Bindings::DOMMatrixBinding::{DOMMatrixInit, DOMMatrixMethods};
|
||||
use crate::dom::bindings::codegen::Bindings::DOMMatrixReadOnlyBinding::DOMMatrixReadOnlyMethods;
|
||||
|
@ -25,7 +26,6 @@ use crate::dom::bindings::error::Fallible;
|
|||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject, Reflector};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::typedarrays::create_typed_array;
|
||||
use crate::dom::dommatrix::DOMMatrix;
|
||||
use crate::dom::dompoint::DOMPoint;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
|
@ -686,14 +686,14 @@ impl DOMMatrixReadOnlyMethods for DOMMatrixReadOnly {
|
|||
.map(|&x| x as f32)
|
||||
.collect();
|
||||
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
|
||||
create_typed_array(cx, &vec, array.handle_mut())
|
||||
create_buffer_source_types(cx, &vec, array.handle_mut())
|
||||
.expect("Converting matrix to float32 array should never fail")
|
||||
}
|
||||
|
||||
// https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-tofloat64array
|
||||
fn ToFloat64Array(&self, cx: JSContext) -> Float64Array {
|
||||
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
|
||||
create_typed_array(cx, &self.matrix.borrow().to_array(), array.handle_mut())
|
||||
create_buffer_source_types(cx, &self.matrix.borrow().to_array(), array.handle_mut())
|
||||
.expect("Converting matrix to float64 array should never fail")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,13 +9,13 @@ use js::jsapi::JSObject;
|
|||
use js::rust::HandleObject;
|
||||
use js::typedarray::{ArrayBuffer, ArrayBufferU8};
|
||||
|
||||
use crate::dom::bindings::buffer_source::create_buffer_source_types;
|
||||
use crate::dom::bindings::codegen::Bindings::BlobBinding::BlobMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::FileReaderSyncBinding::FileReaderSyncMethods;
|
||||
use crate::dom::bindings::error::{Error, Fallible};
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::bindings::typedarrays::create_typed_array;
|
||||
use crate::dom::blob::Blob;
|
||||
use crate::dom::filereader::FileReaderSharedFunctionality;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
|
@ -95,7 +95,7 @@ impl FileReaderSyncMethods for FileReaderSync {
|
|||
// step 2
|
||||
rooted!(in(*cx) let mut array_buffer = ptr::null_mut::<JSObject>());
|
||||
|
||||
create_typed_array::<ArrayBufferU8>(cx, &blob_contents, array_buffer.handle_mut())
|
||||
create_buffer_source_types::<ArrayBufferU8>(cx, &blob_contents, array_buffer.handle_mut())
|
||||
.map_err(|_| Error::JSFailed)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use std::cell::Cell;
|
|||
use dom_struct::dom_struct;
|
||||
use js::typedarray::{Float64, Float64Array};
|
||||
|
||||
use super::bindings::typedarrays::HeapTypedArray;
|
||||
use super::bindings::buffer_source::HeapBufferSource;
|
||||
use crate::dom::bindings::codegen::Bindings::GamepadBinding::{GamepadHand, GamepadMethods};
|
||||
use crate::dom::bindings::codegen::Bindings::GamepadButtonListBinding::GamepadButtonListMethods;
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
|
@ -37,7 +37,7 @@ pub struct Gamepad {
|
|||
timestamp: Cell<f64>,
|
||||
mapping_type: String,
|
||||
#[ignore_malloc_size_of = "mozjs"]
|
||||
axes: HeapTypedArray<Float64>,
|
||||
axes: HeapBufferSource<Float64>,
|
||||
buttons: Dom<GamepadButtonList>,
|
||||
pose: Option<Dom<GamepadPose>>,
|
||||
#[ignore_malloc_size_of = "Defined in rust-webvr"]
|
||||
|
@ -68,7 +68,7 @@ impl Gamepad {
|
|||
connected: Cell::new(connected),
|
||||
timestamp: Cell::new(timestamp),
|
||||
mapping_type: mapping_type,
|
||||
axes: HeapTypedArray::default(),
|
||||
axes: HeapBufferSource::default(),
|
||||
buttons: Dom::from_ref(buttons),
|
||||
pose: pose.map(Dom::from_ref),
|
||||
hand: hand,
|
||||
|
@ -150,9 +150,7 @@ impl GamepadMethods for Gamepad {
|
|||
|
||||
// https://w3c.github.io/gamepad/#dom-gamepad-axes
|
||||
fn Axes(&self, _cx: JSContext) -> Float64Array {
|
||||
self.axes
|
||||
.get_internal()
|
||||
.expect("Failed to get gamepad axes.")
|
||||
self.axes.get_buffer().expect("Failed to get gamepad axes.")
|
||||
}
|
||||
|
||||
// https://w3c.github.io/gamepad/#dom-gamepad-buttons
|
||||
|
@ -232,7 +230,7 @@ impl Gamepad {
|
|||
if normalized_value.is_finite() {
|
||||
let mut axis_vec = self
|
||||
.axes
|
||||
.internal_to_option()
|
||||
.buffer_to_option()
|
||||
.expect("Axes have not been initialized!");
|
||||
unsafe {
|
||||
axis_vec.as_mut_slice()[axis_index] = normalized_value;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
use dom_struct::dom_struct;
|
||||
use js::typedarray::{Float32, Float32Array};
|
||||
|
||||
use super::bindings::typedarrays::HeapTypedArray;
|
||||
use super::bindings::buffer_source::HeapBufferSource;
|
||||
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: HeapTypedArray<Float32>,
|
||||
position: HeapBufferSource<Float32>,
|
||||
#[ignore_malloc_size_of = "mozjs"]
|
||||
orientation: HeapTypedArray<Float32>,
|
||||
orientation: HeapBufferSource<Float32>,
|
||||
#[ignore_malloc_size_of = "mozjs"]
|
||||
linear_vel: HeapTypedArray<Float32>,
|
||||
linear_vel: HeapBufferSource<Float32>,
|
||||
#[ignore_malloc_size_of = "mozjs"]
|
||||
angular_vel: HeapTypedArray<Float32>,
|
||||
angular_vel: HeapBufferSource<Float32>,
|
||||
#[ignore_malloc_size_of = "mozjs"]
|
||||
linear_acc: HeapTypedArray<Float32>,
|
||||
linear_acc: HeapBufferSource<Float32>,
|
||||
#[ignore_malloc_size_of = "mozjs"]
|
||||
angular_acc: HeapTypedArray<Float32>,
|
||||
angular_acc: HeapBufferSource<Float32>,
|
||||
}
|
||||
|
||||
// TODO: support gamepad discovery
|
||||
|
@ -35,12 +35,12 @@ impl GamepadPose {
|
|||
fn new_inherited() -> GamepadPose {
|
||||
GamepadPose {
|
||||
reflector_: Reflector::new(),
|
||||
position: HeapTypedArray::default(),
|
||||
orientation: HeapTypedArray::default(),
|
||||
linear_vel: HeapTypedArray::default(),
|
||||
angular_vel: HeapTypedArray::default(),
|
||||
linear_acc: HeapTypedArray::default(),
|
||||
angular_acc: HeapTypedArray::default(),
|
||||
position: HeapBufferSource::default(),
|
||||
orientation: HeapBufferSource::default(),
|
||||
linear_vel: HeapBufferSource::default(),
|
||||
angular_vel: HeapBufferSource::default(),
|
||||
linear_acc: HeapBufferSource::default(),
|
||||
angular_acc: HeapBufferSource::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ impl GamepadPose {
|
|||
impl GamepadPoseMethods for GamepadPose {
|
||||
// https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-position
|
||||
fn GetPosition(&self, _cx: JSContext) -> Option<Float32Array> {
|
||||
self.position.internal_to_option()
|
||||
self.position.buffer_to_option()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-hasposition
|
||||
|
@ -62,17 +62,17 @@ impl GamepadPoseMethods for GamepadPose {
|
|||
|
||||
// https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-linearvelocity
|
||||
fn GetLinearVelocity(&self, _cx: JSContext) -> Option<Float32Array> {
|
||||
self.linear_vel.internal_to_option()
|
||||
self.linear_vel.buffer_to_option()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-linearacceleration
|
||||
fn GetLinearAcceleration(&self, _cx: JSContext) -> Option<Float32Array> {
|
||||
self.linear_acc.internal_to_option()
|
||||
self.linear_acc.buffer_to_option()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-orientation
|
||||
fn GetOrientation(&self, _cx: JSContext) -> Option<Float32Array> {
|
||||
self.orientation.internal_to_option()
|
||||
self.orientation.buffer_to_option()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-orientation
|
||||
|
@ -82,11 +82,11 @@ impl GamepadPoseMethods for GamepadPose {
|
|||
|
||||
// https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-angularvelocity
|
||||
fn GetAngularVelocity(&self, _cx: JSContext) -> Option<Float32Array> {
|
||||
self.angular_vel.internal_to_option()
|
||||
self.angular_vel.buffer_to_option()
|
||||
}
|
||||
|
||||
// https://w3c.github.io/gamepad/extensions.html#dom-gamepadpose-angularacceleration
|
||||
fn GetAngularAcceleration(&self, _cx: JSContext) -> Option<Float32Array> {
|
||||
self.angular_acc.internal_to_option()
|
||||
self.angular_acc.buffer_to_option()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ use webgpu::identity::WebGPUOpResult;
|
|||
use webgpu::wgpu::device::HostMap;
|
||||
use webgpu::{WebGPU, WebGPUBuffer, WebGPURequest, WebGPUResponse, WebGPUResponseResult};
|
||||
|
||||
use super::bindings::typedarrays::{create_new_external_array_buffer, HeapTypedArray};
|
||||
use super::bindings::buffer_source::{create_new_external_array_buffer, HeapBufferSource};
|
||||
use crate::dom::bindings::cell::DomRefCell;
|
||||
use crate::dom::bindings::codegen::Bindings::WebGPUBinding::{
|
||||
GPUBufferMethods, GPUMapModeConstants, GPUSize64,
|
||||
|
@ -54,7 +54,7 @@ pub struct GPUBufferMapInfo {
|
|||
pub mapping_range: Range<u64>,
|
||||
pub mapped_ranges: Vec<Range<u64>>,
|
||||
#[ignore_malloc_size_of = "defined in mozjs"]
|
||||
pub js_buffers: Vec<HeapTypedArray<ArrayBufferU8>>,
|
||||
pub js_buffers: Vec<HeapBufferSource<ArrayBufferU8>>,
|
||||
pub map_mode: Option<u32>,
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ impl GPUBufferMethods for GPUBuffer {
|
|||
}
|
||||
// Step 3.3
|
||||
m_info.js_buffers.drain(..).for_each(|obj| {
|
||||
obj.detach_internal(cx);
|
||||
obj.detach_buffer(cx);
|
||||
});
|
||||
},
|
||||
// Step 2
|
||||
|
@ -325,7 +325,7 @@ impl GPUBufferMethods for GPUBuffer {
|
|||
m_end as usize,
|
||||
);
|
||||
|
||||
let result = heap_typed_array.get_internal().map_err(|_| Error::JSFailed);
|
||||
let result = heap_typed_array.get_buffer().map_err(|_| Error::JSFailed);
|
||||
|
||||
m_info.mapped_ranges.push(offset..m_end);
|
||||
m_info.js_buffers.push(heap_typed_array);
|
||||
|
|
|
@ -9,12 +9,12 @@ use std::vec::Vec;
|
|||
use dom_struct::dom_struct;
|
||||
use euclid::default::{Rect, Size2D};
|
||||
use ipc_channel::ipc::IpcSharedMemory;
|
||||
use js::jsapi::JSObject;
|
||||
use js::jsapi::{Heap, JSObject};
|
||||
use js::rust::HandleObject;
|
||||
use js::typedarray::{ClampedU8, CreateWith, Uint8ClampedArray};
|
||||
|
||||
use super::bindings::typedarrays::{
|
||||
new_initialized_heap_typed_array, HeapTypedArray, HeapTypedArrayInit,
|
||||
use super::bindings::buffer_source::{
|
||||
new_initialized_heap_buffer_source_types, BufferSource, HeapBufferSource, HeapTypedArrayInit,
|
||||
};
|
||||
use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::ImageDataMethods;
|
||||
use crate::dom::bindings::error::{Error, Fallible};
|
||||
|
@ -29,7 +29,7 @@ pub struct ImageData {
|
|||
width: u32,
|
||||
height: u32,
|
||||
#[ignore_malloc_size_of = "mozjs"]
|
||||
data: HeapTypedArray<ClampedU8>,
|
||||
data: HeapBufferSource<ClampedU8>,
|
||||
}
|
||||
|
||||
impl ImageData {
|
||||
|
@ -63,14 +63,14 @@ impl ImageData {
|
|||
opt_height: Option<u32>,
|
||||
jsobject: *mut JSObject,
|
||||
) -> Fallible<DomRoot<ImageData>> {
|
||||
let heap_typed_array = match new_initialized_heap_typed_array::<ClampedU8>(
|
||||
HeapTypedArrayInit::Object(jsobject),
|
||||
let heap_typed_array = match new_initialized_heap_buffer_source_types::<ClampedU8>(
|
||||
HeapTypedArrayInit::Buffer(BufferSource::Uint8ClampedArray(Heap::boxed(jsobject))),
|
||||
) {
|
||||
Ok(heap_typed_array) => heap_typed_array,
|
||||
Err(_) => return Err(Error::JSFailed),
|
||||
};
|
||||
|
||||
let typed_array = match heap_typed_array.get_internal() {
|
||||
let typed_array = match heap_typed_array.get_buffer() {
|
||||
Ok(array) => array,
|
||||
Err(_) => {
|
||||
return Err(Error::Type(
|
||||
|
@ -117,7 +117,7 @@ impl ImageData {
|
|||
let len = width * height * 4;
|
||||
|
||||
let heap_typed_array =
|
||||
match new_initialized_heap_typed_array::<ClampedU8>(HeapTypedArrayInit::Info {
|
||||
match new_initialized_heap_buffer_source_types::<ClampedU8>(HeapTypedArrayInit::Info {
|
||||
len,
|
||||
cx,
|
||||
}) {
|
||||
|
@ -163,7 +163,7 @@ impl ImageData {
|
|||
assert!(self.data.is_initialized());
|
||||
let internal_data = self
|
||||
.data
|
||||
.get_internal()
|
||||
.get_buffer()
|
||||
.expect("Failed to get Data from ImageData.");
|
||||
// NOTE(nox): This is just as unsafe as `as_slice` itself even though we
|
||||
// are extending the lifetime of the slice, because the data in
|
||||
|
@ -202,6 +202,6 @@ impl ImageDataMethods for ImageData {
|
|||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-imagedata-data>
|
||||
fn GetData(&self, _: JSContext) -> Fallible<Uint8ClampedArray> {
|
||||
self.data.get_internal().map_err(|_| Error::JSFailed)
|
||||
self.data.get_buffer().map_err(|_| Error::JSFailed)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ use script_traits::serializable::BlobImpl;
|
|||
use script_traits::MsDuration;
|
||||
use servo_config::prefs;
|
||||
|
||||
use crate::dom::bindings::buffer_source::create_buffer_source_types;
|
||||
use crate::dom::bindings::callback::ExceptionHandling;
|
||||
use crate::dom::bindings::codegen::Bindings::EventListenerBinding::EventListener;
|
||||
use crate::dom::bindings::codegen::Bindings::FunctionBinding::Function;
|
||||
|
@ -41,7 +42,6 @@ use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, DomObject,
|
|||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::str::{ByteString, DOMString, USVString};
|
||||
use crate::dom::bindings::trace::RootedTraceableBox;
|
||||
use crate::dom::bindings::typedarrays::create_typed_array;
|
||||
use crate::dom::bindings::weakref::MutableWeakRef;
|
||||
use crate::dom::blob::Blob;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
|
@ -214,7 +214,7 @@ impl TestBindingMethods for TestBinding {
|
|||
let data: [u8; 16] = [0; 16];
|
||||
|
||||
rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>());
|
||||
create_typed_array(cx, &data, array.handle_mut())
|
||||
create_buffer_source_types(cx, &data, array.handle_mut())
|
||||
.expect("Creating ClampedU8 array should never fail")
|
||||
}
|
||||
fn AnyAttribute(&self, _: SafeJSContext) -> JSVal {
|
||||
|
|
|
@ -9,12 +9,12 @@ use js::jsapi::JSObject;
|
|||
use js::rust::HandleObject;
|
||||
use js::typedarray::Uint8Array;
|
||||
|
||||
use crate::dom::bindings::buffer_source::create_buffer_source_types;
|
||||
use crate::dom::bindings::codegen::Bindings::TextEncoderBinding::TextEncoderMethods;
|
||||
use crate::dom::bindings::error::Fallible;
|
||||
use crate::dom::bindings::reflector::{reflect_dom_object_with_proto, Reflector};
|
||||
use crate::dom::bindings::root::DomRoot;
|
||||
use crate::dom::bindings::str::{DOMString, USVString};
|
||||
use crate::dom::bindings::typedarrays::create_typed_array;
|
||||
use crate::dom::globalscope::GlobalScope;
|
||||
use crate::script_runtime::JSContext;
|
||||
|
||||
|
@ -55,7 +55,7 @@ impl TextEncoderMethods for TextEncoder {
|
|||
let encoded = input.0.as_bytes();
|
||||
|
||||
rooted!(in(*cx) let mut js_object = ptr::null_mut::<JSObject>());
|
||||
create_typed_array(cx, &encoded, js_object.handle_mut())
|
||||
create_buffer_source_types(cx, &encoded, js_object.handle_mut())
|
||||
.expect("Converting input to uint8 array should never fail")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ use js::rust::HandleObject;
|
|||
use js::typedarray::{Float32, Float32Array};
|
||||
use webxr_api::{ApiSpace, Ray};
|
||||
|
||||
use super::bindings::typedarrays::HeapTypedArray;
|
||||
use super::bindings::buffer_source::HeapBufferSource;
|
||||
use crate::dom::bindings::codegen::Bindings::DOMPointBinding::DOMPointInit;
|
||||
use crate::dom::bindings::codegen::Bindings::XRRayBinding::{XRRayDirectionInit, XRRayMethods};
|
||||
use crate::dom::bindings::error::{Error, Fallible};
|
||||
|
@ -27,7 +27,7 @@ pub struct XRRay {
|
|||
#[no_trace]
|
||||
ray: Ray<ApiSpace>,
|
||||
#[ignore_malloc_size_of = "defined in mozjs"]
|
||||
matrix: HeapTypedArray<Float32>,
|
||||
matrix: HeapBufferSource<Float32>,
|
||||
}
|
||||
|
||||
impl XRRay {
|
||||
|
@ -35,7 +35,7 @@ impl XRRay {
|
|||
XRRay {
|
||||
reflector_: Reflector::new(),
|
||||
ray,
|
||||
matrix: HeapTypedArray::default(),
|
||||
matrix: HeapBufferSource::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -163,7 +163,7 @@ impl XRRayMethods for XRRay {
|
|||
}
|
||||
|
||||
self.matrix
|
||||
.get_internal()
|
||||
.get_buffer()
|
||||
.expect("Failed to get matrix from XRRay.")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use euclid::{RigidTransform3D, Rotation3D, Vector3D};
|
|||
use js::rust::HandleObject;
|
||||
use js::typedarray::{Float32, Float32Array};
|
||||
|
||||
use super::bindings::typedarrays::HeapTypedArray;
|
||||
use super::bindings::buffer_source::HeapBufferSource;
|
||||
use crate::dom::bindings::codegen::Bindings::DOMPointBinding::DOMPointInit;
|
||||
use crate::dom::bindings::codegen::Bindings::XRRigidTransformBinding::XRRigidTransformMethods;
|
||||
use crate::dom::bindings::error::{Error, Fallible};
|
||||
|
@ -29,7 +29,7 @@ pub struct XRRigidTransform {
|
|||
transform: ApiRigidTransform,
|
||||
inverse: MutNullableDom<XRRigidTransform>,
|
||||
#[ignore_malloc_size_of = "defined in mozjs"]
|
||||
matrix: HeapTypedArray<Float32>,
|
||||
matrix: HeapBufferSource<Float32>,
|
||||
}
|
||||
|
||||
impl XRRigidTransform {
|
||||
|
@ -40,7 +40,7 @@ impl XRRigidTransform {
|
|||
orientation: MutNullableDom::default(),
|
||||
transform,
|
||||
inverse: MutNullableDom::default(),
|
||||
matrix: HeapTypedArray::default(),
|
||||
matrix: HeapBufferSource::default(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -140,7 +140,7 @@ impl XRRigidTransformMethods for XRRigidTransform {
|
|||
}
|
||||
|
||||
self.matrix
|
||||
.get_internal()
|
||||
.get_buffer()
|
||||
.expect("Failed to get transform's internal matrix.")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use euclid::RigidTransform3D;
|
|||
use js::typedarray::{Float32, Float32Array};
|
||||
use webxr_api::{ApiSpace, View};
|
||||
|
||||
use super::bindings::typedarrays::HeapTypedArray;
|
||||
use super::bindings::buffer_source::HeapBufferSource;
|
||||
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};
|
||||
|
@ -23,7 +23,7 @@ pub struct XRView {
|
|||
eye: XREye,
|
||||
viewport_index: usize,
|
||||
#[ignore_malloc_size_of = "mozjs"]
|
||||
proj: HeapTypedArray<Float32>,
|
||||
proj: HeapBufferSource<Float32>,
|
||||
#[ignore_malloc_size_of = "defined in rust-webxr"]
|
||||
#[no_trace]
|
||||
view: View<ApiSpace>,
|
||||
|
@ -43,7 +43,7 @@ impl XRView {
|
|||
session: Dom::from_ref(session),
|
||||
eye,
|
||||
viewport_index,
|
||||
proj: HeapTypedArray::default(),
|
||||
proj: HeapBufferSource::default(),
|
||||
view,
|
||||
transform: Dom::from_ref(transform),
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ impl XRViewMethods for XRView {
|
|||
.expect("Failed to set projection matrix.")
|
||||
}
|
||||
self.proj
|
||||
.get_internal()
|
||||
.get_buffer()
|
||||
.expect("Failed to get projection matrix.")
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue