mirror of
https://github.com/servo/servo.git
synced 2025-08-09 15:35:34 +01:00
WebIDL: Use ArrayBuffer
instead of raw JSObject
in bindings (#31202)
* WebIDL: Use ArrayBuffer instead of raw JSObject in bindings Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com> * Convert GPUBufferMapInfo mapping to Arc<Mutex> * Remove #[allow(unsafe_code)] from GPUBuffer * Add doc comments * Implement trace for Arc<Mutex<Vec<T>>> Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com> * Use #[no_trace] for GPUBufferMapInfo.mapping * Make create_new_external_array_buffer generic Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com> * Address review comments * Remove HeapTypedArray::new and avoid cloning Arc Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com> * Use expect for GetMappedRange and ReadAsArrayBuffer Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com> * Use doc comments for FileReaderSyncMethods Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com> * Return for Error::JsFailed GetMappedRange and ReadAsArrayBuffer Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com> * Fix detached_internal implementation and comments Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com> * format code Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com> * Update expectations --------- Signed-off-by: Bentaimia Haddadi <haddadi.taym@gmail.com> Co-authored-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
parent
e6baa26ff8
commit
9be989146d
7 changed files with 121 additions and 75 deletions
|
@ -128,6 +128,7 @@ builtinNames = {
|
|||
IDLType.Tags.uint32array: 'Uint32Array',
|
||||
IDLType.Tags.float32array: 'Float32Array',
|
||||
IDLType.Tags.float64array: 'Float64Array',
|
||||
IDLType.Tags.arrayBuffer: 'ArrayBuffer',
|
||||
}
|
||||
|
||||
numericTags = [
|
||||
|
@ -1481,7 +1482,7 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
|
|||
return CGGeneric("()")
|
||||
if returnType.isPrimitive() and returnType.tag() in builtinNames:
|
||||
return builtin_return_type(returnType)
|
||||
if returnType.isTypedArray() and returnType.tag() in builtinNames:
|
||||
if is_typed_array(returnType) and returnType.tag() in builtinNames:
|
||||
return builtin_return_type(returnType)
|
||||
if returnType.isDOMString():
|
||||
result = CGGeneric("DOMString")
|
||||
|
@ -6516,6 +6517,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
|
|||
'js::typedarray::Uint32Array',
|
||||
'js::typedarray::Float32Array',
|
||||
'js::typedarray::Float64Array',
|
||||
'js::typedarray::ArrayBuffer',
|
||||
'crate::dom',
|
||||
'crate::dom::bindings',
|
||||
'crate::dom::bindings::codegen::InterfaceObjectMap',
|
||||
|
|
|
@ -4,12 +4,17 @@
|
|||
|
||||
#![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};
|
||||
use js::jsapi::{
|
||||
Heap, JSObject, JS_GetArrayBufferViewBuffer, JS_IsArrayBufferViewObject, NewExternalArrayBuffer,
|
||||
};
|
||||
use js::rust::wrappers::DetachArrayBuffer;
|
||||
use js::rust::{CustomAutoRooterGuard, MutableHandleObject};
|
||||
use js::rust::{CustomAutoRooterGuard, Handle, MutableHandleObject};
|
||||
use js::typedarray::{CreateWith, TypedArray, TypedArrayElement, TypedArrayElementCreator};
|
||||
|
||||
use crate::script_runtime::JSContext;
|
||||
|
@ -52,14 +57,7 @@ where
|
|||
array as Result<CustomAutoRooterGuard<'_, TypedArray<T, *mut JSObject>>, &mut ()>
|
||||
{
|
||||
let data = array.to_vec();
|
||||
let mut is_shared = false;
|
||||
unsafe {
|
||||
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);
|
||||
let _ = DetachArrayBuffer(*cx, view_buffer.handle());
|
||||
}
|
||||
let _ = self.detach_internal(cx);
|
||||
Ok(data)
|
||||
} else {
|
||||
Err(())
|
||||
|
@ -68,6 +66,26 @@ where
|
|||
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,
|
||||
|
@ -142,3 +160,40 @@ where
|
|||
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();
|
||||
|
||||
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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue