diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/bindings.rs | 36 | ||||
-rw-r--r-- | core/lib.rs | 1 | ||||
-rw-r--r-- | core/runtime.rs | 40 |
3 files changed, 77 insertions, 0 deletions
diff --git a/core/bindings.rs b/core/bindings.rs index 143ccda9b..d8337322d 100644 --- a/core/bindings.rs +++ b/core/bindings.rs @@ -22,7 +22,10 @@ use std::convert::TryInto; use std::option::Option; use std::rc::Rc; use url::Url; +use v8::HandleScope; +use v8::Local; use v8::MapFnTo; +use v8::SharedArrayBuffer; lazy_static::lazy_static! { pub static ref EXTERNAL_REFERENCES: v8::ExternalReferences = @@ -713,6 +716,22 @@ impl<'a> v8::ValueSerializerImpl for SerializeDeserialize<'a> { scope.throw_exception(error); } + fn get_shared_array_buffer_id<'s>( + &mut self, + scope: &mut HandleScope<'s>, + shared_array_buffer: Local<'s, SharedArrayBuffer>, + ) -> Option<u32> { + let state_rc = JsRuntime::state(scope); + let state = state_rc.borrow_mut(); + if let Some(shared_array_buffer_store) = &state.shared_array_buffer_store { + let backing_store = shared_array_buffer.get_backing_store(); + let id = shared_array_buffer_store.insert(backing_store); + Some(id) + } else { + None + } + } + fn write_host_object<'s>( &mut self, scope: &mut v8::HandleScope<'s>, @@ -735,6 +754,23 @@ impl<'a> v8::ValueSerializerImpl for SerializeDeserialize<'a> { } impl<'a> v8::ValueDeserializerImpl for SerializeDeserialize<'a> { + fn get_shared_array_buffer_from_id<'s>( + &mut self, + scope: &mut HandleScope<'s>, + transfer_id: u32, + ) -> Option<Local<'s, SharedArrayBuffer>> { + let state_rc = JsRuntime::state(scope); + let state = state_rc.borrow_mut(); + if let Some(shared_array_buffer_store) = &state.shared_array_buffer_store { + let backing_store = shared_array_buffer_store.take(transfer_id)?; + let shared_array_buffer = + v8::SharedArrayBuffer::with_backing_store(scope, &backing_store); + Some(shared_array_buffer) + } else { + None + } + } + fn read_host_object<'s>( &mut self, scope: &mut v8::HandleScope<'s>, diff --git a/core/lib.rs b/core/lib.rs index 4a9a213f4..8c8861c79 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -57,6 +57,7 @@ pub use crate::modules::ModuleLoader; pub use crate::modules::ModuleSource; pub use crate::modules::ModuleSourceFuture; pub use crate::modules::NoopModuleLoader; +pub use crate::runtime::SharedArrayBufferStore; // TODO(bartlomieju): this struct should be implementation // detail nad not be public pub use crate::modules::RecursiveModuleLoad; diff --git a/core/runtime.rs b/core/runtime.rs index 48003c811..cf43c2adc 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -38,6 +38,8 @@ use std::mem::forget; use std::option::Option; use std::pin::Pin; use std::rc::Rc; +use std::sync::Arc; +use std::sync::Mutex; use std::sync::Once; use std::task::Context; use std::task::Poll; @@ -97,6 +99,36 @@ struct ModEvaluate { sender: mpsc::Sender<Result<(), AnyError>>, } +#[derive(Default, Clone)] +pub struct SharedArrayBufferStore(Arc<Mutex<SharedArrayBufferStoreInner>>); + +#[derive(Default)] +pub struct SharedArrayBufferStoreInner { + buffers: HashMap<u32, v8::SharedRef<v8::BackingStore>>, + last_id: u32, +} + +impl SharedArrayBufferStore { + pub(crate) fn insert( + &self, + backing_store: v8::SharedRef<v8::BackingStore>, + ) -> u32 { + let mut buffers = self.0.lock().unwrap(); + let last_id = buffers.last_id; + buffers.buffers.insert(last_id, backing_store); + buffers.last_id += 1; + last_id + } + + pub(crate) fn take( + &self, + id: u32, + ) -> Option<v8::SharedRef<v8::BackingStore>> { + let mut buffers = self.0.lock().unwrap(); + buffers.buffers.remove(&id) + } +} + /// Internal state for JsRuntime which is stored in one of v8::Isolate's /// embedder slots. pub(crate) struct JsRuntimeState { @@ -116,6 +148,7 @@ pub(crate) struct JsRuntimeState { pub(crate) pending_unref_ops: FuturesUnordered<PendingOpFuture>, pub(crate) have_unpolled_ops: bool, pub(crate) op_state: Rc<RefCell<OpState>>, + pub(crate) shared_array_buffer_store: Option<SharedArrayBufferStore>, waker: AtomicWaker, } @@ -204,6 +237,12 @@ pub struct RuntimeOptions { /// V8 platform instance to use. Used when Deno initializes V8 /// (which it only does once), otherwise it's silenty dropped. pub v8_platform: Option<v8::SharedRef<v8::Platform>>, + + /// The buffer to use for transferring SharedArrayBuffers between isolates. + /// If multiple isolates should have the possibility of sharing + /// SharedArrayBuffers, they should use the same SharedArrayBufferStore. If no + /// SharedArrayBufferStore is specified, SharedArrayBuffer can not be serialized. + pub shared_array_buffer_store: Option<SharedArrayBufferStore>, } impl JsRuntime { @@ -294,6 +333,7 @@ impl JsRuntime { js_error_create_fn, pending_ops: FuturesUnordered::new(), pending_unref_ops: FuturesUnordered::new(), + shared_array_buffer_store: options.shared_array_buffer_store, op_state: op_state.clone(), have_unpolled_ops: false, waker: AtomicWaker::new(), |