mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-11-22 15:07:00 -05:00
ArrayBuffer::new_backing_store_from_boxed_slice (#202)
This commit is contained in:
parent
52b8bbaf82
commit
bc927c7477
4 changed files with 126 additions and 31 deletions
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue