From d3aa444755f7498fe710b64a3ed3a132446b61cd Mon Sep 17 00:00:00 2001 From: Aaron O'Mullan Date: Sat, 2 Apr 2022 00:10:42 +0200 Subject: [PATCH] cleanup(serde_v8): simpler ZeroCopyBuf (#14095) --- serde_v8/magic/zero_copy_buf.rs | 81 ++++++++++----------------------- 1 file changed, 25 insertions(+), 56 deletions(-) diff --git a/serde_v8/magic/zero_copy_buf.rs b/serde_v8/magic/zero_copy_buf.rs index c63d4ba668..dcd969aea0 100644 --- a/serde_v8/magic/zero_copy_buf.rs +++ b/serde_v8/magic/zero_copy_buf.rs @@ -1,8 +1,8 @@ // Copyright 2018-2022 the Deno authors. All rights reserved. MIT license. -use std::cell::Cell; use std::ops::Deref; use std::ops::DerefMut; +use std::ops::Range; use super::transl8::FromV8; @@ -19,9 +19,8 @@ use super::transl8::FromV8; /// `let copy = Vec::from(&*zero_copy_buf);` #[derive(Clone)] pub struct ZeroCopyBuf { - backing_store: v8::SharedRef, - byte_offset: usize, - byte_length: usize, + store: v8::SharedRef, + range: Range, } unsafe impl Send for ZeroCopyBuf {} @@ -29,21 +28,16 @@ unsafe impl Send for ZeroCopyBuf {} impl ZeroCopyBuf { pub fn from_buffer( buffer: v8::Local, - byte_offset: usize, - byte_length: usize, + range: Range, ) -> Result { - let backing_store = buffer.get_backing_store(); - match backing_store.is_shared() { - true => Err(v8::DataError::BadType { + let store = buffer.get_backing_store(); + if store.is_shared() { + return Err(v8::DataError::BadType { actual: "shared ArrayBufferView", expected: "non-shared ArrayBufferView", - }), - false => Ok(Self { - backing_store, - byte_offset, - byte_length, - }), + }); } + Ok(Self { store, range }) } pub fn from_view( @@ -53,7 +47,17 @@ impl ZeroCopyBuf { let buffer = view.buffer(scope).ok_or(v8::DataError::NoData { expected: "view to have a buffer", })?; - Self::from_buffer(buffer, view.byte_offset(), view.byte_length()) + let (offset, len) = (view.byte_offset(), view.byte_length()); + Self::from_buffer(buffer, offset..offset + len) + } + + fn as_slice(&self) -> &[u8] { + unsafe { &*(&self.store[self.range.clone()] as *const _ as *const [u8]) } + } + + #[allow(clippy::cast_ref_to_mut)] + fn as_slice_mut(&mut self) -> &mut [u8] { + unsafe { &mut *(&self.store[self.range.clone()] as *const _ as *mut [u8]) } } } @@ -65,7 +69,7 @@ impl FromV8 for ZeroCopyBuf { if value.is_array_buffer() { value .try_into() - .and_then(|b| Self::from_buffer(b, 0, b.byte_length())) + .and_then(|b| Self::from_buffer(b, 0..b.byte_length())) } else { value .try_into() @@ -78,59 +82,24 @@ impl FromV8 for ZeroCopyBuf { impl Deref for ZeroCopyBuf { type Target = [u8]; fn deref(&self) -> &[u8] { - unsafe { - get_backing_store_slice( - &self.backing_store, - self.byte_offset, - self.byte_length, - ) - } + self.as_slice() } } impl DerefMut for ZeroCopyBuf { fn deref_mut(&mut self) -> &mut [u8] { - unsafe { - get_backing_store_slice_mut( - &self.backing_store, - self.byte_offset, - self.byte_length, - ) - } + self.as_slice_mut() } } impl AsRef<[u8]> for ZeroCopyBuf { fn as_ref(&self) -> &[u8] { - &*self + self.as_slice() } } impl AsMut<[u8]> for ZeroCopyBuf { fn as_mut(&mut self) -> &mut [u8] { - &mut *self + self.as_slice_mut() } } - -unsafe fn get_backing_store_slice( - backing_store: &v8::SharedRef, - byte_offset: usize, - byte_length: usize, -) -> &[u8] { - let cells: *const [Cell] = - &backing_store[byte_offset..byte_offset + byte_length]; - let bytes = cells as *const [u8]; - &*bytes -} - -#[allow(clippy::mut_from_ref)] -unsafe fn get_backing_store_slice_mut( - backing_store: &v8::SharedRef, - byte_offset: usize, - byte_length: usize, -) -> &mut [u8] { - let cells: *const [Cell] = - &backing_store[byte_offset..byte_offset + byte_length]; - let bytes = cells as *const _ as *mut [u8]; - &mut *bytes -}