From ffbf0c20ccc4e70281958f18ed117f40bdd91397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Mon, 30 Sep 2019 20:59:44 +0200 Subject: feat: op registration in core (#3002) --- core/isolate.rs | 52 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 20 deletions(-) (limited to 'core/isolate.rs') diff --git a/core/isolate.rs b/core/isolate.rs index bad79b579..6795f25f0 100644 --- a/core/isolate.rs +++ b/core/isolate.rs @@ -13,10 +13,10 @@ use crate::libdeno::deno_buf; use crate::libdeno::deno_dyn_import_id; use crate::libdeno::deno_mod; use crate::libdeno::deno_pinned_buf; -use crate::libdeno::OpId; use crate::libdeno::PinnedBuf; use crate::libdeno::Snapshot1; use crate::libdeno::Snapshot2; +use crate::ops::*; use crate::shared_queue::SharedQueue; use crate::shared_queue::RECOMMENDED_SIZE; use futures::stream::FuturesUnordered; @@ -34,24 +34,6 @@ use std::fmt; use std::ptr::null; use std::sync::{Arc, Mutex, Once}; -pub type Buf = Box<[u8]>; - -pub type OpAsyncFuture = Box + Send>; - -type PendingOpFuture = - Box + Send>; - -pub enum Op { - Sync(Buf), - Async(OpAsyncFuture), -} - -pub type CoreError = (); - -pub type CoreOp = Op; - -pub type OpResult = Result, E>; - /// Args: op_id, control_buf, zero_copy_buf type CoreDispatchFn = dyn Fn(OpId, &[u8], Option) -> CoreOp; @@ -179,6 +161,7 @@ pub struct Isolate { pending_dyn_imports: FuturesUnordered>, have_unpolled_ops: bool, startup_script: Option, + op_registry: OpRegistry, } unsafe impl Send for Isolate {} @@ -244,12 +227,17 @@ impl Isolate { have_unpolled_ops: false, pending_dyn_imports: FuturesUnordered::new(), startup_script, + op_registry: OpRegistry::new(), } } /// Defines the how Deno.core.dispatch() acts. /// Called whenever Deno.core.dispatch() is called in JavaScript. zero_copy_buf /// corresponds to the second argument of Deno.core.dispatch(). + /// + /// If this method is used then ops registered using `op_register` function are + /// ignored and all dispatching must be handled manually in provided callback. + // TODO: we want to deprecate and remove this API and move to `register_op` API pub fn set_dispatch(&mut self, f: F) where F: Fn(OpId, &[u8], Option) -> CoreOp + Send + Sync + 'static, @@ -257,6 +245,22 @@ impl Isolate { self.dispatch = Some(Arc::new(f)); } + /// New dispatch mechanism. Requires runtime to explicitly ask for op ids + /// before using any of the ops. + /// + /// Ops added using this method are only usable if `dispatch` is not set + /// (using `set_dispatch` method). + pub fn register_op(&mut self, name: &str, op: F) -> OpId + where + F: Fn(&[u8], Option) -> CoreOp + Send + Sync + 'static, + { + assert!( + self.dispatch.is_none(), + "set_dispatch should not be used in conjunction with register_op" + ); + self.op_registry.register(name, op) + } + pub fn set_dyn_import(&mut self, f: F) where F: Fn(deno_dyn_import_id, &str, &str) -> DynImportStream @@ -329,9 +333,17 @@ impl Isolate { let isolate = unsafe { Isolate::from_raw_ptr(user_data) }; let op = if let Some(ref f) = isolate.dispatch { + assert!( + op_id != 0, + "op_id 0 is a special value that shouldn't be used with dispatch" + ); f(op_id, control_buf.as_ref(), PinnedBuf::new(zero_copy_buf)) } else { - panic!("isolate.dispatch not set") + isolate.op_registry.call( + op_id, + control_buf.as_ref(), + PinnedBuf::new(zero_copy_buf), + ) }; debug_assert_eq!(isolate.shared.size(), 0); -- cgit v1.2.3