mirror of
https://github.com/denoland/rusty_v8.git
synced 2025-02-01 20:24:56 -05:00
add v8::SharedArrayBuffer (#134)
This commit is contained in:
parent
5284abdab0
commit
00d592cd4d
5 changed files with 142 additions and 2 deletions
|
@ -28,6 +28,7 @@ extern "C" {
|
|||
isolate: *mut Isolate,
|
||||
byte_length: usize,
|
||||
) -> *mut 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;
|
||||
fn v8__BackingStore__DELETE(self_: &mut BackingStore);
|
||||
|
@ -98,11 +99,21 @@ impl Delete for Allocator {
|
|||
pub struct BackingStore([usize; 6]);
|
||||
|
||||
impl BackingStore {
|
||||
/// Returns a rust u8 slice with a lifetime equal to the lifetime of the BackingStore.
|
||||
pub fn data_bytes<'a>(&'a mut self) -> &'a mut [u8] {
|
||||
unsafe {
|
||||
std::slice::from_raw_parts_mut::<'a, u8>(
|
||||
v8__BackingStore__Data(self) as *mut u8,
|
||||
self.byte_length(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a pointer to the beginning of the memory block for this backing
|
||||
/// store. The pointer is only valid as long as this backing store object
|
||||
/// lives.
|
||||
pub fn data(&self) -> std::ffi::c_void {
|
||||
unimplemented!()
|
||||
pub fn data(&mut self) -> &mut std::ffi::c_void {
|
||||
unsafe { &mut *v8__BackingStore__Data(self) }
|
||||
}
|
||||
|
||||
/// The length (in bytes) of this backing store.
|
||||
|
|
|
@ -335,6 +335,10 @@ two_pointers_t v8__ArrayBuffer__GetBackingStore(v8::ArrayBuffer& self) {
|
|||
return make_pod<two_pointers_t>(self.GetBackingStore());
|
||||
}
|
||||
|
||||
void* v8__BackingStore__Data(v8::BackingStore& self) {
|
||||
return self.Data();
|
||||
}
|
||||
|
||||
size_t v8__BackingStore__ByteLength(v8::BackingStore& self) {
|
||||
return self.ByteLength();
|
||||
}
|
||||
|
@ -682,6 +686,18 @@ v8::PrimitiveArray* v8__ScriptOrModule__GetHostDefinedOptions(
|
|||
return local_to_ptr(self.GetHostDefinedOptions());
|
||||
}
|
||||
|
||||
v8::SharedArrayBuffer* v8__SharedArrayBuffer__New(v8::Isolate* isolate, size_t byte_length) {
|
||||
return local_to_ptr(v8::SharedArrayBuffer::New(isolate, byte_length));
|
||||
}
|
||||
|
||||
size_t v8__SharedArrayBuffer__ByteLength(v8::SharedArrayBuffer& self) {
|
||||
return self.ByteLength();
|
||||
}
|
||||
|
||||
two_pointers_t v8__SharedArrayBuffer__GetBackingStore(v8::SharedArrayBuffer& self) {
|
||||
return make_pod<two_pointers_t>(self.GetBackingStore());
|
||||
}
|
||||
|
||||
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));
|
||||
|
|
|
@ -61,6 +61,7 @@ mod promise;
|
|||
mod property;
|
||||
mod script;
|
||||
mod script_or_module;
|
||||
mod shared_array_buffer;
|
||||
mod snapshot;
|
||||
mod string;
|
||||
mod support;
|
||||
|
@ -104,6 +105,7 @@ pub use promise::{
|
|||
pub use property::PropertyCallbackInfo;
|
||||
pub use script::{Script, ScriptOrigin};
|
||||
pub use script_or_module::ScriptOrModule;
|
||||
pub use shared_array_buffer::SharedArrayBuffer;
|
||||
pub use snapshot::{FunctionCodeHandling, SnapshotCreator, StartupData};
|
||||
pub use string::NewStringType;
|
||||
pub use string::String;
|
||||
|
|
62
src/shared_array_buffer.rs
Normal file
62
src/shared_array_buffer.rs
Normal file
|
@ -0,0 +1,62 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use crate::support::Opaque;
|
||||
use crate::support::SharedRef;
|
||||
use crate::BackingStore;
|
||||
use crate::Isolate;
|
||||
use crate::Local;
|
||||
use crate::ToLocal;
|
||||
use crate::Value;
|
||||
|
||||
extern "C" {
|
||||
fn v8__SharedArrayBuffer__New(
|
||||
isolate: *mut Isolate,
|
||||
byte_length: usize,
|
||||
) -> *mut SharedArrayBuffer;
|
||||
fn v8__SharedArrayBuffer__ByteLength(
|
||||
self_: *const SharedArrayBuffer,
|
||||
) -> usize;
|
||||
fn v8__SharedArrayBuffer__GetBackingStore(
|
||||
self_: *const SharedArrayBuffer,
|
||||
) -> SharedRef<BackingStore>;
|
||||
}
|
||||
|
||||
/// An instance of the built-in SharedArrayBuffer constructor.
|
||||
/// This API is experimental and may change significantly.
|
||||
#[repr(C)]
|
||||
pub struct SharedArrayBuffer(Opaque);
|
||||
|
||||
impl SharedArrayBuffer {
|
||||
/// Create a new SharedArrayBuffer. Allocate |byte_length| bytes.
|
||||
/// Allocated memory will be owned by a created SharedArrayBuffer and
|
||||
/// will be deallocated when it is garbage-collected,
|
||||
/// unless the object is externalized.
|
||||
pub fn new<'sc>(
|
||||
scope: &mut impl ToLocal<'sc>,
|
||||
byte_length: usize,
|
||||
) -> Option<Local<'sc, SharedArrayBuffer>> {
|
||||
unsafe {
|
||||
Local::from_raw(v8__SharedArrayBuffer__New(scope.isolate(), byte_length))
|
||||
}
|
||||
}
|
||||
|
||||
/// Data length in bytes.
|
||||
pub fn byte_length(&self) -> usize {
|
||||
unsafe { v8__SharedArrayBuffer__ByteLength(self) }
|
||||
}
|
||||
|
||||
/// Get a shared pointer to the backing store of this array buffer. This
|
||||
/// pointer coordinates the lifetime management of the internal storage
|
||||
/// with any live ArrayBuffers on the heap, even across isolates. The embedder
|
||||
/// should not attempt to manage lifetime of the storage through other means.
|
||||
pub fn get_backing_store(&self) -> SharedRef<BackingStore> {
|
||||
unsafe { v8__SharedArrayBuffer__GetBackingStore(self) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for SharedArrayBuffer {
|
||||
type Target = Value;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
unsafe { &*(self as *const _ as *const Value) }
|
||||
}
|
||||
}
|
|
@ -1491,3 +1491,52 @@ fn dynamic_import() {
|
|||
isolate.exit();
|
||||
drop(g);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shared_array_buffer() {
|
||||
let g = setup();
|
||||
let mut params = v8::Isolate::create_params();
|
||||
params.set_array_buffer_allocator(v8::new_default_allocator());
|
||||
let mut isolate = v8::Isolate::new(params);
|
||||
isolate.enter();
|
||||
let mut locker = v8::Locker::new(&isolate);
|
||||
{
|
||||
let mut hs = v8::HandleScope::new(&mut locker);
|
||||
let s = hs.enter();
|
||||
let mut context = v8::Context::new(s);
|
||||
context.enter();
|
||||
let maybe_sab = v8::SharedArrayBuffer::new(s, 16);
|
||||
assert!(maybe_sab.is_some());
|
||||
let sab = maybe_sab.unwrap();
|
||||
let mut backing_store = sab.get_backing_store();
|
||||
let shared_buf = backing_store.data_bytes();
|
||||
shared_buf[5] = 12;
|
||||
shared_buf[12] = 52;
|
||||
let global = context.global(s);
|
||||
assert_eq!(
|
||||
global.create_data_property(
|
||||
context,
|
||||
cast(v8_str(s, "shared")),
|
||||
cast(sab)
|
||||
),
|
||||
v8::MaybeBool::JustTrue
|
||||
);
|
||||
let source = v8::String::new(
|
||||
s,
|
||||
"sharedBytes = new Uint8Array(shared); sharedBytes[2] = 16; sharedBytes[14] = 62; sharedBytes[5] + sharedBytes[12]",
|
||||
)
|
||||
.unwrap();
|
||||
let mut script = v8::Script::compile(s, context, source, None).unwrap();
|
||||
source.to_rust_string_lossy(s);
|
||||
let result = script.run(s, context).unwrap();
|
||||
// TODO: safer casts.
|
||||
let result: v8::Local<v8::Integer> = cast(result);
|
||||
assert_eq!(result.value(), 64);
|
||||
assert_eq!(shared_buf[2], 16);
|
||||
assert_eq!(shared_buf[14], 62);
|
||||
context.exit();
|
||||
}
|
||||
drop(locker);
|
||||
isolate.exit();
|
||||
drop(g);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue