0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2024-11-21 15:04:33 -05:00

ArrayBuffer::new_backing_store_from_boxed_slice (#202)

This commit is contained in:
Bartek Iwańczuk 2020-01-17 14:41:12 +01:00 committed by Bert Belder
parent 52b8bbaf82
commit bc927c7477
4 changed files with 126 additions and 31 deletions

View file

@ -29,6 +29,12 @@ extern "C" {
isolate: *mut Isolate,
byte_length: usize,
) -> *mut BackingStore;
fn v8__ArrayBuffer__NewBackingStore_FromRaw(
data: *mut std::ffi::c_void,
byte_length: usize,
deleter: BackingStoreDeleterCallback,
) -> SharedRef<BackingStore>;
fn v8__BackingStore__Data(self_: &mut BackingStore) -> *mut std::ffi::c_void;
fn v8__BackingStore__ByteLength(self_: &BackingStore) -> usize;
fn v8__BackingStore__IsShared(self_: &BackingStore) -> bool;
@ -85,6 +91,21 @@ impl Delete for Allocator {
}
}
pub type BackingStoreDeleterCallback = unsafe extern "C" fn(
data: *mut std::ffi::c_void,
byte_length: usize,
deleter_data: *mut std::ffi::c_void,
);
pub unsafe extern "C" fn backing_store_deleter_callback(
data: *mut std::ffi::c_void,
_byte_length: usize,
_deleter_data: *mut std::ffi::c_void,
) {
let b = Box::from_raw(data);
drop(b)
}
/// 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.
///
@ -201,4 +222,23 @@ impl ArrayBuffer {
))
}
}
/// Returns a new standalone BackingStore that takes over the ownership of
/// the given buffer.
///
/// The destructor of the BackingStore frees owned buffer memory.
///
/// The result can be later passed to ArrayBuffer::New. The raw pointer
/// to the buffer must not be passed again to any V8 API function.
pub unsafe fn new_backing_store_from_boxed_slice(
data: Box<[u8]>,
) -> SharedRef<BackingStore> {
let byte_length = data.len();
let data_ptr = Box::into_raw(data) as *mut std::ffi::c_void;
v8__ArrayBuffer__NewBackingStore_FromRaw(
data_ptr,
byte_length,
backing_store_deleter_callback,
)
}
}

View file

@ -568,6 +568,14 @@ v8::BackingStore* v8__ArrayBuffer__NewBackingStore(v8::Isolate* isolate,
return u.release();
}
two_pointers_t v8__ArrayBuffer__NewBackingStore_FromRaw(
void* data, size_t length, v8::BackingStoreDeleterCallback deleter) {
std::unique_ptr<v8::BackingStore> u =
v8::ArrayBuffer::NewBackingStore(data, length, deleter, nullptr);
const std::shared_ptr<v8::BackingStore> bs = std::move(u);
return make_pod<two_pointers_t>(bs);
}
two_pointers_t v8__ArrayBuffer__GetBackingStore(v8::ArrayBuffer& self) {
return make_pod<two_pointers_t>(self.GetBackingStore());
}
@ -1047,14 +1055,6 @@ v8::SharedArrayBuffer* v8__SharedArrayBuffer__New(v8::Isolate* isolate,
return local_to_ptr(v8::SharedArrayBuffer::New(isolate, byte_length));
}
v8::SharedArrayBuffer* v8__SharedArrayBuffer__New__DEPRECATED(
v8::Isolate* isolate, void* data_ptr, size_t data_length) {
auto ab =
v8::SharedArrayBuffer::New(isolate, data_ptr, data_length,
v8::ArrayBufferCreationMode::kExternalized);
return local_to_ptr(ab);
}
size_t v8__SharedArrayBuffer__ByteLength(v8::SharedArrayBuffer& self) {
return self.ByteLength();
}
@ -1064,6 +1064,19 @@ two_pointers_t v8__SharedArrayBuffer__GetBackingStore(
return make_pod<two_pointers_t>(self.GetBackingStore());
}
two_pointers_t v8__SharedArrayBuffer__NewBackingStore_FromRaw(
void* data, size_t length, v8::BackingStoreDeleterCallback deleter) {
std::unique_ptr<v8::BackingStore> u =
v8::SharedArrayBuffer::NewBackingStore(data, length, deleter, nullptr);
const std::shared_ptr<v8::BackingStore> bs = std::move(u);
return make_pod<two_pointers_t>(bs);
}
v8::SharedArrayBuffer* v8__SharedArrayBuffer__New__backing_store(
v8::Isolate* isolate, std::shared_ptr<v8::BackingStore>& backing_store) {
return local_to_ptr(v8::SharedArrayBuffer::New(isolate, backing_store));
}
v8::Value* v8__JSON__Parse(v8::Local<v8::Context> context,
v8::Local<v8::String> json_string) {
return maybe_local_to_ptr(v8::JSON::Parse(context, json_string));

View file

@ -1,5 +1,7 @@
use crate::array_buffer::backing_store_deleter_callback;
use crate::support::SharedRef;
use crate::BackingStore;
use crate::BackingStoreDeleterCallback;
use crate::Isolate;
use crate::Local;
use crate::SharedArrayBuffer;
@ -21,6 +23,15 @@ extern "C" {
fn v8__SharedArrayBuffer__GetBackingStore(
self_: *const SharedArrayBuffer,
) -> SharedRef<BackingStore>;
fn v8__SharedArrayBuffer__NewBackingStore_FromRaw(
data: *mut std::ffi::c_void,
byte_length: usize,
deleter: BackingStoreDeleterCallback,
) -> SharedRef<BackingStore>;
fn v8__SharedArrayBuffer__New__backing_store(
isolate: *mut Isolate,
backing_store: *mut SharedRef<BackingStore>,
) -> *mut SharedArrayBuffer;
}
impl SharedArrayBuffer {
@ -37,29 +48,6 @@ impl SharedArrayBuffer {
}
}
/// DEPRECATED
/// Use the version that takes a BackingStore.
/// See http://crbug.com/v8/9908.
///
///
/// Create a new SharedArrayBuffer over an existing memory block. The created
/// array buffer is immediately in externalized state unless otherwise
/// specified. The memory block will not be reclaimed when a created
/// SharedArrayBuffer is garbage-collected.
#[allow(non_snake_case)]
pub unsafe fn new_DEPRECATED<'sc>(
scope: &mut impl ToLocal<'sc>,
data_ptr: *mut std::ffi::c_void,
data_length: usize,
) -> Local<'sc, SharedArrayBuffer> {
Local::from_raw(v8__SharedArrayBuffer__New__DEPRECATED(
scope.isolate(),
data_ptr,
data_length,
))
.unwrap()
}
/// Data length in bytes.
pub fn byte_length(&self) -> usize {
unsafe { v8__SharedArrayBuffer__ByteLength(self) }
@ -72,4 +60,34 @@ impl SharedArrayBuffer {
pub fn get_backing_store(&self) -> SharedRef<BackingStore> {
unsafe { v8__SharedArrayBuffer__GetBackingStore(self) }
}
pub fn new_with_backing_store<'sc>(
scope: &mut impl ToLocal<'sc>,
backing_store: &mut SharedRef<BackingStore>,
) -> Local<'sc, SharedArrayBuffer> {
let isolate = scope.isolate();
let ptr = unsafe {
v8__SharedArrayBuffer__New__backing_store(isolate, &mut *backing_store)
};
unsafe { scope.to_local(ptr) }.unwrap()
}
/// Returns a new standalone BackingStore that takes over the ownership of
/// the given buffer.
///
/// The destructor of the BackingStore frees owned buffer memory.
///
/// The result can be later passed to SharedArrayBuffer::New. The raw pointer
/// to the buffer must not be passed again to any V8 API function.
pub unsafe fn new_backing_store_from_boxed_slice(
data: Box<[u8]>,
) -> SharedRef<BackingStore> {
let byte_length = data.len();
let data_ptr = Box::into_raw(data) as *mut std::ffi::c_void;
v8__SharedArrayBuffer__NewBackingStore_FromRaw(
data_ptr,
byte_length,
backing_store_deleter_callback,
)
}
}

View file

@ -252,6 +252,17 @@ fn array_buffer() {
assert_eq!(84, bs.byte_length());
assert_eq!(false, bs.is_shared());
let data: Box<[u8]> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9].into_boxed_slice();
let mut bs =
unsafe { v8::ArrayBuffer::new_backing_store_from_boxed_slice(data) };
assert_eq!(10, bs.byte_length());
assert_eq!(false, bs.is_shared());
let ab = v8::ArrayBuffer::new_with_backing_store(scope, &mut bs);
let mut bs = ab.get_backing_store();
assert_eq!(10, ab.byte_length());
let data = bs.data_bytes();
assert_eq!(data[0], 0);
assert_eq!(data[9], 9);
context.exit();
}
}
@ -1758,6 +1769,19 @@ fn shared_array_buffer() {
assert_eq!(result.value(), 64);
assert_eq!(shared_buf[2], 16);
assert_eq!(shared_buf[14], 62);
let data: Box<[u8]> = vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9].into_boxed_slice();
let mut bs = unsafe {
v8::SharedArrayBuffer::new_backing_store_from_boxed_slice(data)
};
assert_eq!(10, bs.byte_length());
assert_eq!(true, bs.is_shared());
let ab = v8::SharedArrayBuffer::new_with_backing_store(s, &mut bs);
let mut bs = ab.get_backing_store();
assert_eq!(10, ab.byte_length());
let data = bs.data_bytes();
assert_eq!(data[0], 0);
assert_eq!(data[9], 9);
context.exit();
}
}