diff --git a/cli/ops/dispatch_json.rs b/cli/ops/dispatch_json.rs index 26ffc7d33a..30a3a44333 100644 --- a/cli/ops/dispatch_json.rs +++ b/cli/ops/dispatch_json.rs @@ -3,6 +3,7 @@ use crate::op_error::OpError; use deno_core::Buf; use deno_core::CoreIsolateState; use deno_core::Op; +use deno_core::OpDispatcher; use deno_core::ZeroCopyBuf; use futures::future::FutureExt; pub use serde_derive::Deserialize; @@ -44,9 +45,7 @@ struct AsyncArgs { promise_id: Option, } -pub fn json_op( - d: D, -) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op +pub fn json_op(d: D) -> impl OpDispatcher where D: Fn( &mut CoreIsolateState, diff --git a/cli/ops/dispatch_minimal.rs b/cli/ops/dispatch_minimal.rs index 45b90ef81c..c37e57e45f 100644 --- a/cli/ops/dispatch_minimal.rs +++ b/cli/ops/dispatch_minimal.rs @@ -9,6 +9,7 @@ use byteorder::{LittleEndian, WriteBytesExt}; use deno_core::Buf; use deno_core::CoreIsolateState; use deno_core::Op; +use deno_core::OpDispatcher; use deno_core::ZeroCopyBuf; use futures::future::FutureExt; use std::future::Future; @@ -114,9 +115,7 @@ fn test_parse_min_record() { assert_eq!(parse_min_record(&buf), None); } -pub fn minimal_op( - d: D, -) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op +pub fn minimal_op(d: D) -> impl OpDispatcher where D: Fn(&mut CoreIsolateState, bool, i32, &mut [ZeroCopyBuf]) -> MinimalOp, { diff --git a/cli/ops/plugin.rs b/cli/ops/plugin.rs index 16debac50a..ba105cff8f 100644 --- a/cli/ops/plugin.rs +++ b/cli/ops/plugin.rs @@ -110,7 +110,8 @@ impl<'a> plugin_api::Interface for PluginInterface<'a> { let plugin_lib = self.plugin_lib.clone(); self.isolate_state.op_registry.register( name, - move |isolate_state, zero_copy| { + move |isolate_state: &mut CoreIsolateState, + zero_copy: &mut [ZeroCopyBuf]| { let mut interface = PluginInterface::new(isolate_state, &plugin_lib); let op = dispatch_op_fn(&mut interface, zero_copy); match op { diff --git a/cli/state.rs b/cli/state.rs index 5f3873510f..2d871d74d0 100644 --- a/cli/state.rs +++ b/cli/state.rs @@ -16,6 +16,7 @@ use deno_core::ModuleLoadId; use deno_core::ModuleLoader; use deno_core::ModuleSpecifier; use deno_core::Op; +use deno_core::OpDispatcher; use deno_core::ZeroCopyBuf; use futures::future::FutureExt; use futures::Future; @@ -62,10 +63,7 @@ pub struct StateInner { } impl State { - pub fn stateful_json_op( - &self, - dispatcher: D, - ) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op + pub fn stateful_json_op(&self, dispatcher: D) -> impl OpDispatcher where D: Fn(&State, Value, &mut [ZeroCopyBuf]) -> Result, { @@ -73,10 +71,7 @@ impl State { self.core_op(json_op(self.stateful_op(dispatcher))) } - pub fn stateful_json_op2( - &self, - dispatcher: D, - ) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op + pub fn stateful_json_op2(&self, dispatcher: D) -> impl OpDispatcher where D: Fn( &mut deno_core::CoreIsolateState, @@ -92,13 +87,7 @@ impl State { /// Wrap core `OpDispatcher` to collect metrics. // TODO(ry) this should be private. Is called by stateful_json_op or // stateful_minimal_op - pub fn core_op( - &self, - dispatcher: D, - ) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op - where - D: Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op, - { + pub fn core_op(&self, dispatcher: impl OpDispatcher) -> impl OpDispatcher { let state = self.clone(); move |isolate_state: &mut deno_core::CoreIsolateState, @@ -109,7 +98,7 @@ impl State { let bytes_sent_zero_copy = zero_copy[1..].iter().map(|b| b.len()).sum::() as u64; - let op = dispatcher(isolate_state, zero_copy); + let op = dispatcher.dispatch(isolate_state, zero_copy); match op { Op::Sync(buf) => { @@ -152,10 +141,7 @@ impl State { } } - pub fn stateful_minimal_op2( - &self, - dispatcher: D, - ) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op + pub fn stateful_minimal_op2(&self, dispatcher: D) -> impl OpDispatcher where D: Fn( &mut deno_core::CoreIsolateState, diff --git a/core/core_isolate.rs b/core/core_isolate.rs index ffe75c00c5..c9e718d2db 100644 --- a/core/core_isolate.rs +++ b/core/core_isolate.rs @@ -348,10 +348,11 @@ impl CoreIsolate { /// corresponds to the second argument of Deno.core.dispatch(). /// /// Requires runtime to explicitly ask for op ids before using any of the ops. - pub fn register_op(&mut self, name: &str, op: F) -> OpId - where - F: Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op + 'static, - { + pub fn register_op( + &mut self, + name: &str, + op: impl OpDispatcher + 'static, + ) -> OpId { let state_rc = Self::state(self); let mut state = state_rc.borrow_mut(); state.op_registry.register(name, op) @@ -466,7 +467,7 @@ impl CoreIsolateState { /// Requires runtime to explicitly ask for op ids before using any of the ops. pub fn register_op(&mut self, name: &str, op: F) -> OpId where - F: Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op + 'static, + F: OpDispatcher + 'static, { self.op_registry.register(name, op) } @@ -488,7 +489,7 @@ impl CoreIsolateState { zero_copy_bufs: &mut [ZeroCopyBuf], ) -> Option<(OpId, Box<[u8]>)> { let op = if let Some(dispatcher) = self.op_registry.get(op_id) { - dispatcher(self, zero_copy_bufs) + dispatcher.dispatch(self, zero_copy_bufs) } else { let message = v8::String::new(scope, &format!("Unknown op id: {}", op_id)).unwrap(); diff --git a/core/lib.rs b/core/lib.rs index 7358af1c43..f348ed6cf4 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -46,6 +46,7 @@ pub use crate::modules::RecursiveModuleLoad; pub use crate::ops::Buf; pub use crate::ops::Op; pub use crate::ops::OpAsyncFuture; +pub use crate::ops::OpDispatcher; pub use crate::ops::OpId; pub use crate::resources::ResourceTable; pub use crate::zero_copy_buf::ZeroCopyBuf; diff --git a/core/ops.rs b/core/ops.rs index 65a0f325b1..8aa13936b4 100644 --- a/core/ops.rs +++ b/core/ops.rs @@ -20,31 +20,52 @@ pub enum Op { AsyncUnref(OpAsyncFuture), } -/// Main type describing op -pub type OpDispatcher = - dyn Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op + 'static; +pub trait OpDispatcher { + fn dispatch( + &self, + isolate: &mut CoreIsolateState, + buf: &mut [ZeroCopyBuf], + ) -> Op; +} + +impl OpDispatcher for F +where + F: Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op, +{ + fn dispatch( + &self, + isolate: &mut CoreIsolateState, + buf: &mut [ZeroCopyBuf], + ) -> Op { + self(isolate, buf) + } +} #[derive(Default)] pub struct OpRegistry { - dispatchers: Vec>, + dispatchers: Vec>, name_to_id: HashMap, } impl OpRegistry { pub fn new() -> Self { let mut registry = Self::default(); - let op_id = registry.register("ops", |state, _| { - let buf = state.op_registry.json_map(); - Op::Sync(buf) - }); + let op_id = registry.register( + "ops", + |state: &mut CoreIsolateState, _: &mut [ZeroCopyBuf]| { + let buf = state.op_registry.json_map(); + Op::Sync(buf) + }, + ); assert_eq!(op_id, 0); registry } - pub fn register(&mut self, name: &str, op: F) -> OpId - where - F: Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op + 'static, - { + pub fn register( + &mut self, + name: &str, + op: impl OpDispatcher + 'static, + ) -> OpId { let op_id = self.dispatchers.len() as u32; let existing = self.name_to_id.insert(name.to_string(), op_id); @@ -61,8 +82,8 @@ impl OpRegistry { op_map_json.as_bytes().to_owned().into_boxed_slice() } - pub fn get(&self, op_id: OpId) -> Option> { - self.dispatchers.get(op_id as usize).map(Rc::clone) + pub fn get(&self, op_id: OpId) -> Option> { + self.dispatchers.get(op_id as usize).cloned() } pub fn unregister_op(&mut self, name: &str) { @@ -81,10 +102,13 @@ fn test_op_registry() { let c = Arc::new(atomic::AtomicUsize::new(0)); let c_ = c.clone(); - let test_id = op_registry.register("test", move |_, _| { - c_.fetch_add(1, atomic::Ordering::SeqCst); - Op::Sync(Box::new([])) - }); + let test_id = op_registry.register( + "test", + move |_: &mut CoreIsolateState, _: &mut [ZeroCopyBuf]| { + c_.fetch_add(1, atomic::Ordering::SeqCst); + Op::Sync(Box::new([])) + }, + ); assert!(test_id != 0); let mut expected = HashMap::new(); @@ -97,7 +121,7 @@ fn test_op_registry() { let dispatch = op_registry.get(test_id).unwrap(); let state_rc = CoreIsolate::state(&isolate); let mut state = state_rc.borrow_mut(); - let res = dispatch(&mut state, &mut []); + let res = dispatch.dispatch(&mut state, &mut []); if let Op::Sync(buf) = res { assert_eq!(buf.len(), 0); } else { @@ -127,15 +151,21 @@ fn register_op_during_call() { let test_id = { let mut g = op_registry.lock().unwrap(); - g.register("dynamic_register_op", move |_, _| { - let c__ = c_.clone(); - let mut g = op_registry_.lock().unwrap(); - g.register("test", move |_, _| { - c__.fetch_add(1, atomic::Ordering::SeqCst); + g.register( + "dynamic_register_op", + move |_: &mut CoreIsolateState, _: &mut [ZeroCopyBuf]| { + let c__ = c_.clone(); + let mut g = op_registry_.lock().unwrap(); + g.register( + "test", + move |_: &mut CoreIsolateState, _: &mut [ZeroCopyBuf]| { + c__.fetch_add(1, atomic::Ordering::SeqCst); + Op::Sync(Box::new([])) + }, + ); Op::Sync(Box::new([])) - }); - Op::Sync(Box::new([])) - }) + }, + ) }; assert!(test_id != 0); @@ -148,7 +178,7 @@ fn register_op_during_call() { { let state_rc = CoreIsolate::state(&isolate); let mut state = state_rc.borrow_mut(); - dispatcher1(&mut state, &mut []); + dispatcher1.dispatch(&mut state, &mut []); } let mut expected = HashMap::new(); @@ -166,7 +196,7 @@ fn register_op_during_call() { }; let state_rc = CoreIsolate::state(&isolate); let mut state = state_rc.borrow_mut(); - let res = dispatcher2(&mut state, &mut []); + let res = dispatcher2.dispatch(&mut state, &mut []); if let Op::Sync(buf) = res { assert_eq!(buf.len(), 0); } else { diff --git a/deno_typescript/lib.rs b/deno_typescript/lib.rs index 70d6d42d0b..f64959e0d7 100644 --- a/deno_typescript/lib.rs +++ b/deno_typescript/lib.rs @@ -13,6 +13,7 @@ use deno_core::CoreIsolateState; use deno_core::ErrBox; use deno_core::ModuleSpecifier; use deno_core::Op; +use deno_core::OpDispatcher; use deno_core::StartupData; use deno_core::ZeroCopyBuf; pub use ops::EmitResult; @@ -50,7 +51,7 @@ pub struct TSState { fn compiler_op( ts_state: Arc>, dispatcher: D, -) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op +) -> impl OpDispatcher where D: Fn(&mut TSState, &[u8]) -> Op, { @@ -337,7 +338,7 @@ pub fn trace_serializer() { /// CoreIsolate. pub fn op_fetch_asset( custom_assets: HashMap, -) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op { +) -> impl OpDispatcher { for (_, path) in custom_assets.iter() { println!("cargo:rerun-if-changed={}", path.display()); }