mirror of
https://github.com/denoland/rusty_v8.git
synced 2025-01-21 05:02:11 -05:00
implement Rawable for all TypedArray types (#1679)
This commit is contained in:
parent
8020991257
commit
c8f3a6d853
3 changed files with 64 additions and 46 deletions
|
@ -253,26 +253,66 @@ pub type BackingStoreDeleterCallback = unsafe extern "C" fn(
|
||||||
);
|
);
|
||||||
|
|
||||||
pub(crate) mod sealed {
|
pub(crate) mod sealed {
|
||||||
pub trait Rawable<T: ?Sized> {
|
pub trait Rawable {
|
||||||
|
fn byte_len(&mut self) -> usize;
|
||||||
fn into_raw(self) -> (*const (), *const u8);
|
fn into_raw(self) -> (*const (), *const u8);
|
||||||
unsafe fn drop_raw(ptr: *const (), size: usize);
|
unsafe fn drop_raw(ptr: *const (), size: usize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl sealed::Rawable<[u8]> for Vec<u8> {
|
macro_rules! rawable {
|
||||||
unsafe fn drop_raw(ptr: *const (), size: usize) {
|
($ty:ty) => {
|
||||||
<Box<[u8]> as sealed::Rawable<[u8]>>::drop_raw(ptr, size);
|
impl sealed::Rawable for Box<[$ty]> {
|
||||||
}
|
fn byte_len(&mut self) -> usize {
|
||||||
|
self.as_mut().len() * std::mem::size_of::<$ty>()
|
||||||
|
}
|
||||||
|
|
||||||
fn into_raw(self) -> (*const (), *const u8) {
|
fn into_raw(mut self) -> (*const (), *const u8) {
|
||||||
self.into_boxed_slice().into_raw()
|
// Thin the fat pointer
|
||||||
}
|
let ptr = self.as_mut_ptr();
|
||||||
|
std::mem::forget(self);
|
||||||
|
(ptr as _, ptr as _)
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn drop_raw(ptr: *const (), len: usize) {
|
||||||
|
// Fatten the thin pointer
|
||||||
|
_ = Self::from_raw(std::ptr::slice_from_raw_parts_mut(ptr as _, len));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sealed::Rawable for Vec<$ty> {
|
||||||
|
fn byte_len(&mut self) -> usize {
|
||||||
|
Vec::<$ty>::len(self) * std::mem::size_of::<$ty>()
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn drop_raw(ptr: *const (), size: usize) {
|
||||||
|
<Box<[$ty]> as sealed::Rawable>::drop_raw(ptr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_raw(self) -> (*const (), *const u8) {
|
||||||
|
self.into_boxed_slice().into_raw()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Sized> sealed::Rawable<T> for Box<T>
|
rawable!(u8);
|
||||||
|
rawable!(u16);
|
||||||
|
rawable!(u32);
|
||||||
|
rawable!(u64);
|
||||||
|
rawable!(i8);
|
||||||
|
rawable!(i16);
|
||||||
|
rawable!(i32);
|
||||||
|
rawable!(i64);
|
||||||
|
|
||||||
|
impl<T: Sized> sealed::Rawable for Box<T>
|
||||||
where
|
where
|
||||||
T: AsMut<[u8]>,
|
T: AsMut<[u8]>,
|
||||||
{
|
{
|
||||||
|
fn byte_len(&mut self) -> usize {
|
||||||
|
self.as_mut().as_mut().len()
|
||||||
|
}
|
||||||
|
|
||||||
fn into_raw(mut self) -> (*const (), *const u8) {
|
fn into_raw(mut self) -> (*const (), *const u8) {
|
||||||
let data = self.as_mut().as_mut().as_mut_ptr();
|
let data = self.as_mut().as_mut().as_mut_ptr();
|
||||||
let ptr = Self::into_raw(self);
|
let ptr = Self::into_raw(self);
|
||||||
|
@ -284,20 +324,6 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl sealed::Rawable<[u8]> for Box<[u8]> {
|
|
||||||
fn into_raw(mut self) -> (*const (), *const u8) {
|
|
||||||
// Thin the fat pointer
|
|
||||||
let ptr = self.as_mut_ptr();
|
|
||||||
std::mem::forget(self);
|
|
||||||
(ptr as _, ptr)
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn drop_raw(ptr: *const (), len: usize) {
|
|
||||||
// Fatten the thin pointer
|
|
||||||
_ = Self::from_raw(std::ptr::slice_from_raw_parts_mut(ptr as _, len));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A wrapper around the backing store (i.e. the raw memory) of an array buffer.
|
/// A wrapper around the backing store (i.e. the raw memory) of an array buffer.
|
||||||
/// See a document linked in http://crbug.com/v8/9908 for more information.
|
/// See a document linked in http://crbug.com/v8/9908 for more information.
|
||||||
///
|
///
|
||||||
|
@ -565,16 +591,13 @@ impl ArrayBuffer {
|
||||||
/// let backing_store = v8::ArrayBuffer::new_backing_store_from_bytes(Box::new(bytes::BytesMut::new()));
|
/// let backing_store = v8::ArrayBuffer::new_backing_store_from_bytes(Box::new(bytes::BytesMut::new()));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new_backing_store_from_bytes<T, U>(
|
pub fn new_backing_store_from_bytes<T>(
|
||||||
mut bytes: T,
|
mut bytes: T,
|
||||||
) -> UniqueRef<BackingStore>
|
) -> UniqueRef<BackingStore>
|
||||||
where
|
where
|
||||||
U: ?Sized,
|
T: sealed::Rawable,
|
||||||
U: AsMut<[u8]>,
|
|
||||||
T: AsMut<U>,
|
|
||||||
T: sealed::Rawable<U>,
|
|
||||||
{
|
{
|
||||||
let len = bytes.as_mut().as_mut().len();
|
let len = bytes.byte_len();
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
return unsafe {
|
return unsafe {
|
||||||
UniqueRef::from_raw(v8__BackingStore__EmptyBackingStore(false))
|
UniqueRef::from_raw(v8__BackingStore__EmptyBackingStore(false))
|
||||||
|
@ -583,13 +606,13 @@ impl ArrayBuffer {
|
||||||
|
|
||||||
let (ptr, slice) = T::into_raw(bytes);
|
let (ptr, slice) = T::into_raw(bytes);
|
||||||
|
|
||||||
extern "C" fn drop_rawable<T: sealed::Rawable<U>, U: ?Sized>(
|
extern "C" fn drop_rawable<T: sealed::Rawable>(
|
||||||
_ptr: *mut c_void,
|
_ptr: *mut c_void,
|
||||||
len: usize,
|
len: usize,
|
||||||
data: *mut c_void,
|
data: *mut c_void,
|
||||||
) {
|
) {
|
||||||
// SAFETY: We know that data is a raw T from above
|
// SAFETY: We know that data is a raw T from above
|
||||||
unsafe { <T as sealed::Rawable<U>>::drop_raw(data as _, len) }
|
unsafe { T::drop_raw(data as _, len) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAFETY: We are extending the lifetime of a slice, but we're locking away the box that we
|
// SAFETY: We are extending the lifetime of a slice, but we're locking away the box that we
|
||||||
|
@ -598,7 +621,7 @@ impl ArrayBuffer {
|
||||||
Self::new_backing_store_from_ptr(
|
Self::new_backing_store_from_ptr(
|
||||||
slice as _,
|
slice as _,
|
||||||
len,
|
len,
|
||||||
drop_rawable::<T, U>,
|
drop_rawable::<T>,
|
||||||
ptr as _,
|
ptr as _,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -166,16 +166,13 @@ impl SharedArrayBuffer {
|
||||||
/// let backing_store = v8::ArrayBuffer::new_backing_store_from_bytes(Box::new(bytes::BytesMut::new()));
|
/// let backing_store = v8::ArrayBuffer::new_backing_store_from_bytes(Box::new(bytes::BytesMut::new()));
|
||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn new_backing_store_from_bytes<T, U>(
|
pub fn new_backing_store_from_bytes<T>(
|
||||||
mut bytes: T,
|
mut bytes: T,
|
||||||
) -> UniqueRef<BackingStore>
|
) -> UniqueRef<BackingStore>
|
||||||
where
|
where
|
||||||
U: ?Sized,
|
T: crate::array_buffer::sealed::Rawable,
|
||||||
U: AsMut<[u8]>,
|
|
||||||
T: AsMut<U>,
|
|
||||||
T: crate::array_buffer::sealed::Rawable<U>,
|
|
||||||
{
|
{
|
||||||
let len = bytes.as_mut().as_mut().len();
|
let len = bytes.byte_len();
|
||||||
if len == 0 {
|
if len == 0 {
|
||||||
return unsafe {
|
return unsafe {
|
||||||
UniqueRef::from_raw(v8__BackingStore__EmptyBackingStore(false))
|
UniqueRef::from_raw(v8__BackingStore__EmptyBackingStore(false))
|
||||||
|
@ -184,17 +181,14 @@ impl SharedArrayBuffer {
|
||||||
|
|
||||||
let (ptr, slice) = T::into_raw(bytes);
|
let (ptr, slice) = T::into_raw(bytes);
|
||||||
|
|
||||||
extern "C" fn drop_rawable<
|
extern "C" fn drop_rawable<T: crate::array_buffer::sealed::Rawable>(
|
||||||
T: crate::array_buffer::sealed::Rawable<U>,
|
|
||||||
U: ?Sized,
|
|
||||||
>(
|
|
||||||
_ptr: *mut c_void,
|
_ptr: *mut c_void,
|
||||||
len: usize,
|
len: usize,
|
||||||
data: *mut c_void,
|
data: *mut c_void,
|
||||||
) {
|
) {
|
||||||
// SAFETY: We know that data is a raw T from above
|
// SAFETY: We know that data is a raw T from above
|
||||||
unsafe {
|
unsafe {
|
||||||
<T as crate::array_buffer::sealed::Rawable<U>>::drop_raw(data as _, len)
|
<T as crate::array_buffer::sealed::Rawable>::drop_raw(data as _, len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +198,7 @@ impl SharedArrayBuffer {
|
||||||
Self::new_backing_store_from_ptr(
|
Self::new_backing_store_from_ptr(
|
||||||
slice as _,
|
slice as _,
|
||||||
len,
|
len,
|
||||||
drop_rawable::<T, U>,
|
drop_rawable::<T>,
|
||||||
ptr as _,
|
ptr as _,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -862,13 +862,14 @@ fn array_buffer() {
|
||||||
// Empty but from vec
|
// Empty but from vec
|
||||||
let ab = v8::ArrayBuffer::with_backing_store(
|
let ab = v8::ArrayBuffer::with_backing_store(
|
||||||
scope,
|
scope,
|
||||||
&v8::ArrayBuffer::new_backing_store_from_bytes(vec![]).make_shared(),
|
&v8::ArrayBuffer::new_backing_store_from_bytes(Vec::<u8>::new())
|
||||||
|
.make_shared(),
|
||||||
);
|
);
|
||||||
assert_eq!(0, ab.byte_length());
|
assert_eq!(0, ab.byte_length());
|
||||||
assert!(!ab.get_backing_store().is_shared());
|
assert!(!ab.get_backing_store().is_shared());
|
||||||
|
|
||||||
// Empty but from vec with a huge capacity
|
// Empty but from vec with a huge capacity
|
||||||
let mut v = Vec::with_capacity(10_000_000);
|
let mut v: Vec<u8> = Vec::with_capacity(10_000_000);
|
||||||
v.extend_from_slice(&[1, 2, 3, 4]);
|
v.extend_from_slice(&[1, 2, 3, 4]);
|
||||||
let ab = v8::ArrayBuffer::with_backing_store(
|
let ab = v8::ArrayBuffer::with_backing_store(
|
||||||
scope,
|
scope,
|
||||||
|
|
Loading…
Add table
Reference in a new issue