mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 07:14:47 -05:00
refactor: Make OpDispatcher a trait (#6736)
This commit is contained in:
parent
6af5149ea3
commit
d51972377c
8 changed files with 82 additions and 64 deletions
|
@ -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<u64>,
|
||||
}
|
||||
|
||||
pub fn json_op<D>(
|
||||
d: D,
|
||||
) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
|
||||
pub fn json_op<D>(d: D) -> impl OpDispatcher
|
||||
where
|
||||
D: Fn(
|
||||
&mut CoreIsolateState,
|
||||
|
|
|
@ -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: D,
|
||||
) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
|
||||
pub fn minimal_op<D>(d: D) -> impl OpDispatcher
|
||||
where
|
||||
D: Fn(&mut CoreIsolateState, bool, i32, &mut [ZeroCopyBuf]) -> MinimalOp,
|
||||
{
|
||||
|
|
|
@ -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 {
|
||||
|
|
26
cli/state.rs
26
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<D>(
|
||||
&self,
|
||||
dispatcher: D,
|
||||
) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
|
||||
pub fn stateful_json_op<D>(&self, dispatcher: D) -> impl OpDispatcher
|
||||
where
|
||||
D: Fn(&State, Value, &mut [ZeroCopyBuf]) -> Result<JsonOp, OpError>,
|
||||
{
|
||||
|
@ -73,10 +71,7 @@ impl State {
|
|||
self.core_op(json_op(self.stateful_op(dispatcher)))
|
||||
}
|
||||
|
||||
pub fn stateful_json_op2<D>(
|
||||
&self,
|
||||
dispatcher: D,
|
||||
) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
|
||||
pub fn stateful_json_op2<D>(&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<D>(
|
||||
&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::<usize>() 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<D>(
|
||||
&self,
|
||||
dispatcher: D,
|
||||
) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
|
||||
pub fn stateful_minimal_op2<D>(&self, dispatcher: D) -> impl OpDispatcher
|
||||
where
|
||||
D: Fn(
|
||||
&mut deno_core::CoreIsolateState,
|
||||
|
|
|
@ -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<F>(&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<F>(&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();
|
||||
|
|
|
@ -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;
|
||||
|
|
72
core/ops.rs
72
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<F> 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<Rc<OpDispatcher>>,
|
||||
dispatchers: Vec<Rc<dyn OpDispatcher>>,
|
||||
name_to_id: HashMap<String, OpId>,
|
||||
}
|
||||
|
||||
impl OpRegistry {
|
||||
pub fn new() -> Self {
|
||||
let mut registry = Self::default();
|
||||
let op_id = registry.register("ops", |state, _| {
|
||||
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<F>(&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<Rc<OpDispatcher>> {
|
||||
self.dispatchers.get(op_id as usize).map(Rc::clone)
|
||||
pub fn get(&self, op_id: OpId) -> Option<Rc<dyn OpDispatcher>> {
|
||||
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 |_, _| {
|
||||
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 |_, _| {
|
||||
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 |_, _| {
|
||||
g.register(
|
||||
"test",
|
||||
move |_: &mut CoreIsolateState, _: &mut [ZeroCopyBuf]| {
|
||||
c__.fetch_add(1, atomic::Ordering::SeqCst);
|
||||
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 {
|
||||
|
|
|
@ -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<D>(
|
||||
ts_state: Arc<Mutex<TSState>>,
|
||||
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<S: ::std::hash::BuildHasher>(
|
||||
custom_assets: HashMap<String, PathBuf, S>,
|
||||
) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op {
|
||||
) -> impl OpDispatcher {
|
||||
for (_, path) in custom_assets.iter() {
|
||||
println!("cargo:rerun-if-changed={}", path.display());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue