diff options
author | Valentin Anger <syrupthinker@gryphno.de> | 2020-07-08 17:23:50 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-08 11:23:50 -0400 |
commit | be7e0f2d490ca480aaa154845c4c5c6dccbd7546 (patch) | |
tree | b2a2d284c490a2a1cd8ec3b6175ea5d4077cc65e | |
parent | cbbd9443592f79f6abf9e5019840de4e01ff8580 (diff) |
BREAKING(core): Remove control slice from ops (#6048)
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | cli/js/globals.ts | 13 | ||||
-rw-r--r-- | cli/ops/dispatch_json.rs | 13 | ||||
-rw-r--r-- | cli/ops/dispatch_minimal.rs | 11 | ||||
-rw-r--r-- | cli/ops/plugin.rs | 4 | ||||
-rw-r--r-- | cli/state.rs | 18 | ||||
-rw-r--r-- | core/Cargo.toml | 1 | ||||
-rw-r--r-- | core/bindings.rs | 53 | ||||
-rw-r--r-- | core/core_isolate.rs | 61 | ||||
-rw-r--r-- | core/es_isolate.rs | 8 | ||||
-rw-r--r-- | core/examples/http_bench.rs | 19 | ||||
-rw-r--r-- | core/ops.rs | 18 | ||||
-rw-r--r-- | core/plugin_api.rs | 2 | ||||
-rw-r--r-- | core/zero_copy_buf.rs | 10 | ||||
-rw-r--r-- | deno_typescript/lib.rs | 14 | ||||
-rw-r--r-- | test_plugin/src/lib.rs | 12 | ||||
-rw-r--r-- | test_plugin/tests/integration_tests.rs | 2 | ||||
-rw-r--r-- | test_plugin/tests/test.js | 4 |
18 files changed, 112 insertions, 152 deletions
diff --git a/Cargo.lock b/Cargo.lock index 59c9adce7..5c5998cf2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -441,6 +441,7 @@ dependencies = [ "log 0.4.8", "rusty_v8", "serde_json", + "smallvec 1.4.0", "tokio", "url", ] diff --git a/cli/js/globals.ts b/cli/js/globals.ts index c73a2a6ab..4548c8304 100644 --- a/cli/js/globals.ts +++ b/cli/js/globals.ts @@ -77,14 +77,9 @@ declare global { interface DenoCore { print(s: string, isErr?: boolean): void; - dispatch( - opId: number, - control: Uint8Array, - ...zeroCopy: ArrayBufferView[] - ): Uint8Array | null; + dispatch(opId: number, ...zeroCopy: ArrayBufferView[]): Uint8Array | null; dispatchByName( opName: string, - control: Uint8Array, ...zeroCopy: ArrayBufferView[] ): Uint8Array | null; setAsyncHandler(opId: number, cb: (msg: Uint8Array) => void): void; @@ -101,11 +96,7 @@ declare global { recv(cb: (opId: number, msg: Uint8Array) => void): void; - send( - opId: number, - control: null | ArrayBufferView, - ...data: ArrayBufferView[] - ): null | Uint8Array; + send(opId: number, ...data: ArrayBufferView[]): null | Uint8Array; setMacrotaskCallback(cb: () => boolean): void; diff --git a/cli/ops/dispatch_json.rs b/cli/ops/dispatch_json.rs index 97a02991f..26ffc7d33 100644 --- a/cli/ops/dispatch_json.rs +++ b/cli/ops/dispatch_json.rs @@ -46,7 +46,7 @@ struct AsyncArgs { pub fn json_op<D>( d: D, -) -> impl Fn(&mut CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op +) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op where D: Fn( &mut CoreIsolateState, @@ -54,10 +54,9 @@ where &mut [ZeroCopyBuf], ) -> Result<JsonOp, OpError>, { - move |isolate_state: &mut CoreIsolateState, - control: &[u8], - zero_copy: &mut [ZeroCopyBuf]| { - let async_args: AsyncArgs = match serde_json::from_slice(control) { + move |isolate_state: &mut CoreIsolateState, zero_copy: &mut [ZeroCopyBuf]| { + assert!(!zero_copy.is_empty(), "Expected JSON string at position 0"); + let async_args: AsyncArgs = match serde_json::from_slice(&zero_copy[0]) { Ok(args) => args, Err(e) => { let buf = serialize_result(None, Err(OpError::from(e))); @@ -67,9 +66,9 @@ where let promise_id = async_args.promise_id; let is_sync = promise_id.is_none(); - let result = serde_json::from_slice(control) + let result = serde_json::from_slice(&zero_copy[0]) .map_err(OpError::from) - .and_then(|args| d(isolate_state, args, zero_copy)); + .and_then(|args| d(isolate_state, args, &mut zero_copy[1..])); // Convert to Op match result { diff --git a/cli/ops/dispatch_minimal.rs b/cli/ops/dispatch_minimal.rs index eac5ad055..45b90ef81 100644 --- a/cli/ops/dispatch_minimal.rs +++ b/cli/ops/dispatch_minimal.rs @@ -116,14 +116,13 @@ fn test_parse_min_record() { pub fn minimal_op<D>( d: D, -) -> impl Fn(&mut CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op +) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op where D: Fn(&mut CoreIsolateState, bool, i32, &mut [ZeroCopyBuf]) -> MinimalOp, { - move |isolate_state: &mut CoreIsolateState, - control: &[u8], - zero_copy: &mut [ZeroCopyBuf]| { - let mut record = match parse_min_record(control) { + move |isolate_state: &mut CoreIsolateState, zero_copy: &mut [ZeroCopyBuf]| { + assert!(!zero_copy.is_empty(), "Expected record at position 0"); + let mut record = match parse_min_record(&zero_copy[0]) { Some(r) => r, None => { let e = OpError::type_error("Unparsable control buffer".to_string()); @@ -138,7 +137,7 @@ where }; let is_sync = record.promise_id == 0; let rid = record.arg; - let min_op = d(isolate_state, is_sync, rid, zero_copy); + let min_op = d(isolate_state, is_sync, rid, &mut zero_copy[1..]); match min_op { MinimalOp::Sync(sync_result) => Op::Sync(match sync_result { diff --git a/cli/ops/plugin.rs b/cli/ops/plugin.rs index 775178f1e..16debac50 100644 --- a/cli/ops/plugin.rs +++ b/cli/ops/plugin.rs @@ -110,9 +110,9 @@ 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, control, zero_copy| { + move |isolate_state, zero_copy| { let mut interface = PluginInterface::new(isolate_state, &plugin_lib); - let op = dispatch_op_fn(&mut interface, control, zero_copy); + let op = dispatch_op_fn(&mut interface, zero_copy); match op { sync_op @ Op::Sync(..) => sync_op, Op::Async(fut) => { diff --git a/cli/state.rs b/cli/state.rs index 39bd8a565..5f3873510 100644 --- a/cli/state.rs +++ b/cli/state.rs @@ -65,7 +65,7 @@ impl State { pub fn stateful_json_op<D>( &self, dispatcher: D, - ) -> impl Fn(&mut deno_core::CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op + ) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op where D: Fn(&State, Value, &mut [ZeroCopyBuf]) -> Result<JsonOp, OpError>, { @@ -76,7 +76,7 @@ impl State { pub fn stateful_json_op2<D>( &self, dispatcher: D, - ) -> impl Fn(&mut deno_core::CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op + ) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op where D: Fn( &mut deno_core::CoreIsolateState, @@ -95,21 +95,21 @@ impl State { pub fn core_op<D>( &self, dispatcher: D, - ) -> impl Fn(&mut deno_core::CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op + ) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op where - D: Fn(&mut deno_core::CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op, + D: Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op, { let state = self.clone(); move |isolate_state: &mut deno_core::CoreIsolateState, - control: &[u8], zero_copy: &mut [ZeroCopyBuf]| -> Op { - let bytes_sent_control = control.len() as u64; + let bytes_sent_control = + zero_copy.get(0).map(|s| s.len()).unwrap_or(0) as u64; let bytes_sent_zero_copy = - zero_copy.iter().map(|b| b.len()).sum::<usize>() as u64; + zero_copy[1..].iter().map(|b| b.len()).sum::<usize>() as u64; - let op = dispatcher(isolate_state, control, zero_copy); + let op = dispatcher(isolate_state, zero_copy); match op { Op::Sync(buf) => { @@ -155,7 +155,7 @@ impl State { pub fn stateful_minimal_op2<D>( &self, dispatcher: D, - ) -> impl Fn(&mut deno_core::CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op + ) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op where D: Fn( &mut deno_core::CoreIsolateState, diff --git a/core/Cargo.toml b/core/Cargo.toml index 6b73cc02a..038b81580 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -21,6 +21,7 @@ libc = "0.2.71" log = "0.4.8" rusty_v8 = "0.6.0" serde_json = "1.0.55" +smallvec = "1.4.0" url = "2.1.1" [[example]] diff --git a/core/bindings.rs b/core/bindings.rs index 6407cb555..0d0a633a5 100644 --- a/core/bindings.rs +++ b/core/bindings.rs @@ -8,6 +8,7 @@ use crate::ZeroCopyBuf; use rusty_v8 as v8; use v8::MapFnTo; +use smallvec::SmallVec; use std::cell::Cell; use std::convert::TryFrom; use std::option::Option; @@ -388,24 +389,11 @@ fn send( } }; - let control_backing_store: v8::SharedRef<v8::BackingStore>; - let control = match v8::Local::<v8::ArrayBufferView>::try_from(args.get(1)) { - Ok(view) => unsafe { - control_backing_store = view.buffer(scope).unwrap().get_backing_store(); - get_backing_store_slice( - &control_backing_store, - view.byte_offset(), - view.byte_length(), - ) - }, - Err(_) => &[], - }; - let state_rc = CoreIsolate::state(scope); let mut state = state_rc.borrow_mut(); assert!(!state.global_context.is_empty()); - let mut buf_iter = (2..args.length()).map(|idx| { + let buf_iter = (1..args.length()).map(|idx| { v8::Local::<v8::ArrayBufferView>::try_from(args.get(idx)) .map(|view| ZeroCopyBuf::new(scope, view)) .map_err(|err| { @@ -415,36 +403,15 @@ fn send( }) }); - let mut buf_one: ZeroCopyBuf; - let mut buf_vec: Vec<ZeroCopyBuf>; - - // Collect all ArrayBufferView's - let buf_iter_result = match buf_iter.len() { - 0 => Ok(&mut [][..]), - 1 => match buf_iter.next().unwrap() { - Ok(buf) => { - buf_one = buf; - Ok(std::slice::from_mut(&mut buf_one)) + // If response is empty then it's either async op or exception was thrown. + let maybe_response = + match buf_iter.collect::<Result<SmallVec<[ZeroCopyBuf; 2]>, _>>() { + Ok(mut bufs) => state.dispatch_op(scope, op_id, &mut bufs), + Err(exc) => { + scope.throw_exception(exc); + return; } - Err(err) => Err(err), - }, - _ => match buf_iter.collect::<Result<Vec<_>, _>>() { - Ok(v) => { - buf_vec = v; - Ok(&mut buf_vec[..]) - } - Err(err) => Err(err), - }, - }; - - // If response is empty then it's either async op or exception was thrown - let maybe_response = match buf_iter_result { - Ok(bufs) => state.dispatch_op(scope, op_id, control, bufs), - Err(exc) => { - scope.throw_exception(exc); - return; - } - }; + }; if let Some(response) = maybe_response { // Synchronous response. diff --git a/core/core_isolate.rs b/core/core_isolate.rs index bb1807f62..ffe75c00c 100644 --- a/core/core_isolate.rs +++ b/core/core_isolate.rs @@ -350,7 +350,7 @@ impl CoreIsolate { /// 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, &[u8], &mut [ZeroCopyBuf]) -> Op + 'static, + F: Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op + 'static, { let state_rc = Self::state(self); let mut state = state_rc.borrow_mut(); @@ -466,7 +466,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, &[u8], &mut [ZeroCopyBuf]) -> Op + 'static, + F: Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op + 'static, { self.op_registry.register(name, op) } @@ -485,11 +485,10 @@ impl CoreIsolateState { &mut self, scope: &mut v8::HandleScope<'s>, op_id: OpId, - control_buf: &[u8], zero_copy_bufs: &mut [ZeroCopyBuf], ) -> Option<(OpId, Box<[u8]>)> { let op = if let Some(dispatcher) = self.op_registry.get(op_id) { - dispatcher(self, control_buf, zero_copy_bufs) + dispatcher(self, zero_copy_bufs) } else { let message = v8::String::new(scope, &format!("Unknown op id: {}", op_id)).unwrap(); @@ -704,20 +703,21 @@ pub mod tests { let mut isolate = CoreIsolate::new(StartupData::None, false); let dispatcher = move |_state: &mut CoreIsolateState, - control: &[u8], zero_copy: &mut [ZeroCopyBuf]| -> Op { dispatch_count_.fetch_add(1, Ordering::Relaxed); match mode { Mode::Async => { - assert_eq!(control.len(), 1); - assert_eq!(control[0], 42); + assert_eq!(zero_copy.len(), 1); + assert_eq!(zero_copy[0].len(), 1); + assert_eq!(zero_copy[0][0], 42); let buf = vec![43u8].into_boxed_slice(); Op::Async(futures::future::ready(buf).boxed()) } Mode::AsyncUnref => { - assert_eq!(control.len(), 1); - assert_eq!(control[0], 42); + assert_eq!(zero_copy.len(), 1); + assert_eq!(zero_copy[0].len(), 1); + assert_eq!(zero_copy[0][0], 42); let fut = async { // This future never finish. futures::future::pending::<()>().await; @@ -726,8 +726,6 @@ pub mod tests { Op::AsyncUnref(fut.boxed()) } Mode::AsyncZeroCopy(count) => { - assert_eq!(control.len(), 1); - assert_eq!(control[0], 24); assert_eq!(zero_copy.len(), count as usize); zero_copy.iter().enumerate().for_each(|(idx, buf)| { assert_eq!(buf.len(), 1); @@ -738,13 +736,15 @@ pub mod tests { Op::Async(futures::future::ready(buf).boxed()) } Mode::OverflowReqSync => { - assert_eq!(control.len(), 100 * 1024 * 1024); + assert_eq!(zero_copy.len(), 1); + assert_eq!(zero_copy[0].len(), 100 * 1024 * 1024); let buf = vec![43u8].into_boxed_slice(); Op::Sync(buf) } Mode::OverflowResSync => { - assert_eq!(control.len(), 1); - assert_eq!(control[0], 42); + assert_eq!(zero_copy.len(), 1); + assert_eq!(zero_copy[0].len(), 1); + assert_eq!(zero_copy[0][0], 42); let mut vec = Vec::<u8>::new(); vec.resize(100 * 1024 * 1024, 0); vec[0] = 99; @@ -752,13 +752,15 @@ pub mod tests { Op::Sync(buf) } Mode::OverflowReqAsync => { - assert_eq!(control.len(), 100 * 1024 * 1024); + assert_eq!(zero_copy.len(), 1); + assert_eq!(zero_copy[0].len(), 100 * 1024 * 1024); let buf = vec![43u8].into_boxed_slice(); Op::Async(futures::future::ready(buf).boxed()) } Mode::OverflowResAsync => { - assert_eq!(control.len(), 1); - assert_eq!(control[0], 42); + assert_eq!(zero_copy.len(), 1); + assert_eq!(zero_copy[0].len(), 1); + assert_eq!(zero_copy[0][0], 42); let mut vec = Vec::<u8>::new(); vec.resize(100 * 1024 * 1024, 0); vec[0] = 4; @@ -807,37 +809,38 @@ pub mod tests { js_check(isolate.execute( "filename.js", r#" - let control = new Uint8Array([24]); - Deno.core.send(1, control); + Deno.core.send(1); "#, )); assert_eq!(dispatch_count.load(Ordering::Relaxed), 1); } #[test] - fn test_dispatch_one_zero_copy_buf() { - let (mut isolate, dispatch_count) = setup(Mode::AsyncZeroCopy(1)); + fn test_dispatch_stack_zero_copy_bufs() { + let (mut isolate, dispatch_count) = setup(Mode::AsyncZeroCopy(2)); js_check(isolate.execute( "filename.js", r#" - let control = new Uint8Array([24]); - let zero_copy = new Uint8Array([0]); - Deno.core.send(1, control, zero_copy); + let zero_copy_a = new Uint8Array([0]); + let zero_copy_b = new Uint8Array([1]); + Deno.core.send(1, zero_copy_a, zero_copy_b); "#, )); assert_eq!(dispatch_count.load(Ordering::Relaxed), 1); } #[test] - fn test_dispatch_two_zero_copy_bufs() { - let (mut isolate, dispatch_count) = setup(Mode::AsyncZeroCopy(2)); + fn test_dispatch_heap_zero_copy_bufs() { + let (mut isolate, dispatch_count) = setup(Mode::AsyncZeroCopy(5)); js_check(isolate.execute( "filename.js", r#" - let control = new Uint8Array([24]); let zero_copy_a = new Uint8Array([0]); let zero_copy_b = new Uint8Array([1]); - Deno.core.send(1, control, zero_copy_a, zero_copy_b); + let zero_copy_c = new Uint8Array([2]); + let zero_copy_d = new Uint8Array([3]); + let zero_copy_e = new Uint8Array([4]); + Deno.core.send(1, zero_copy_a, zero_copy_b, zero_copy_c, zero_copy_d, zero_copy_e); "#, )); assert_eq!(dispatch_count.load(Ordering::Relaxed), 1); @@ -1120,7 +1123,7 @@ pub mod tests { r#" let thrown; try { - Deno.core.dispatch(100, []); + Deno.core.dispatch(100); } catch (e) { thrown = e; } diff --git a/core/es_isolate.rs b/core/es_isolate.rs index 5bb1a55c0..a59ba7e92 100644 --- a/core/es_isolate.rs +++ b/core/es_isolate.rs @@ -708,12 +708,12 @@ pub mod tests { let mut isolate = EsIsolate::new(loader, StartupData::None, false); let dispatcher = move |_state: &mut CoreIsolateState, - control: &[u8], - _zero_copy: &mut [ZeroCopyBuf]| + zero_copy: &mut [ZeroCopyBuf]| -> Op { dispatch_count_.fetch_add(1, Ordering::Relaxed); - assert_eq!(control.len(), 1); - assert_eq!(control[0], 42); + assert_eq!(zero_copy.len(), 1); + assert_eq!(zero_copy[0].len(), 1); + assert_eq!(zero_copy[0][0], 42); let buf = vec![43u8, 0, 0, 0].into_boxed_slice(); Op::Async(futures::future::ready(buf).boxed()) }; diff --git a/core/examples/http_bench.rs b/core/examples/http_bench.rs index 233864fac..92e69d215 100644 --- a/core/examples/http_bench.rs +++ b/core/examples/http_bench.rs @@ -117,18 +117,19 @@ impl Isolate { { let state = self.state.clone(); let core_handler = move |_isolate_state: &mut CoreIsolateState, - control_buf: &[u8], zero_copy_bufs: &mut [ZeroCopyBuf]| -> Op { + assert!(!zero_copy_bufs.is_empty()); let state = state.clone(); - let record = Record::from(control_buf); + let record = Record::from(zero_copy_bufs[0].as_ref()); let is_sync = record.promise_id == 0; assert!(is_sync); - let result: i32 = match handler(state, record.rid, zero_copy_bufs) { - Ok(r) => r as i32, - Err(_) => -1, - }; + let result: i32 = + match handler(state, record.rid, &mut zero_copy_bufs[1..]) { + Ok(r) => r as i32, + Err(_) => -1, + }; let buf = RecordBuf::from(Record { result, ..record })[..].into(); Op::Sync(buf) }; @@ -147,15 +148,15 @@ impl Isolate { { let state = self.state.clone(); let core_handler = move |_isolate_state: &mut CoreIsolateState, - control_buf: &[u8], zero_copy_bufs: &mut [ZeroCopyBuf]| -> Op { + assert!(!zero_copy_bufs.is_empty()); let state = state.clone(); - let record = Record::from(control_buf); + let record = Record::from(zero_copy_bufs[0].as_ref()); let is_sync = record.promise_id == 0; assert!(!is_sync); - let mut zero_copy = zero_copy_bufs.to_vec(); + let mut zero_copy = zero_copy_bufs[1..].to_vec(); let fut = async move { let op = handler(state, record.rid, &mut zero_copy); let result = op diff --git a/core/ops.rs b/core/ops.rs index eb995df6e..65a0f325b 100644 --- a/core/ops.rs +++ b/core/ops.rs @@ -22,7 +22,7 @@ pub enum Op { /// Main type describing op pub type OpDispatcher = - dyn Fn(&mut CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op + 'static; + dyn Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op + 'static; #[derive(Default)] pub struct OpRegistry { @@ -33,7 +33,7 @@ pub struct OpRegistry { 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, _| { let buf = state.op_registry.json_map(); Op::Sync(buf) }); @@ -43,7 +43,7 @@ impl OpRegistry { pub fn register<F>(&mut self, name: &str, op: F) -> OpId where - F: Fn(&mut CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op + 'static, + F: Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op + 'static, { let op_id = self.dispatchers.len() as u32; @@ -81,7 +81,7 @@ 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 |_, _| { c_.fetch_add(1, atomic::Ordering::SeqCst); Op::Sync(Box::new([])) }); @@ -97,7 +97,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(&mut state, &mut []); if let Op::Sync(buf) = res { assert_eq!(buf.len(), 0); } else { @@ -127,10 +127,10 @@ 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 |_, _| { let c__ = c_.clone(); let mut g = op_registry_.lock().unwrap(); - g.register("test", move |_, _, _| { + g.register("test", move |_, _| { c__.fetch_add(1, atomic::Ordering::SeqCst); Op::Sync(Box::new([])) }); @@ -148,7 +148,7 @@ fn register_op_during_call() { { let state_rc = CoreIsolate::state(&isolate); let mut state = state_rc.borrow_mut(); - dispatcher1(&mut state, &[], &mut []); + dispatcher1(&mut state, &mut []); } let mut expected = HashMap::new(); @@ -166,7 +166,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(&mut state, &mut []); if let Op::Sync(buf) = res { assert_eq!(buf.len(), 0); } else { diff --git a/core/plugin_api.rs b/core/plugin_api.rs index 16f5d4a36..0cb9acaeb 100644 --- a/core/plugin_api.rs +++ b/core/plugin_api.rs @@ -15,7 +15,7 @@ pub use crate::ZeroCopyBuf; pub type InitFn = fn(&mut dyn Interface); -pub type DispatchOpFn = fn(&mut dyn Interface, &[u8], &mut [ZeroCopyBuf]) -> Op; +pub type DispatchOpFn = fn(&mut dyn Interface, &mut [ZeroCopyBuf]) -> Op; pub trait Interface { fn register_op(&mut self, name: &str, dispatcher: DispatchOpFn) -> OpId; diff --git a/core/zero_copy_buf.rs b/core/zero_copy_buf.rs index a458e12ff..a2625b8aa 100644 --- a/core/zero_copy_buf.rs +++ b/core/zero_copy_buf.rs @@ -6,8 +6,14 @@ use std::ops::DerefMut; /// A ZeroCopyBuf encapsulates a slice that's been borrowed from a JavaScript /// ArrayBuffer object. JavaScript objects can normally be garbage collected, /// but the existence of a ZeroCopyBuf inhibits this until it is dropped. It -/// behaves much like an Arc<[u8]>, although a ZeroCopyBuf currently can't be -/// cloned. +/// behaves much like an Arc<[u8]>. +/// +/// # Cloning +/// Cloning a ZeroCopyBuf does not clone the contents of the buffer, +/// it creates a new reference to that buffer. +/// +/// To actually clone the contents of the buffer do +/// `let copy = Vec::from(&*zero_copy_buf);` #[derive(Clone)] pub struct ZeroCopyBuf { backing_store: v8::SharedRef<v8::BackingStore>, diff --git a/deno_typescript/lib.rs b/deno_typescript/lib.rs index 54d9b1d3b..70d6d42d0 100644 --- a/deno_typescript/lib.rs +++ b/deno_typescript/lib.rs @@ -50,17 +50,16 @@ pub struct TSState { fn compiler_op<D>( ts_state: Arc<Mutex<TSState>>, dispatcher: D, -) -> impl Fn(&mut CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op +) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op where D: Fn(&mut TSState, &[u8]) -> Op, { move |_state: &mut CoreIsolateState, - control: &[u8], zero_copy_bufs: &mut [ZeroCopyBuf]| -> Op { - assert!(zero_copy_bufs.is_empty()); // zero_copy_bufs unused in compiler. + assert_eq!(zero_copy_bufs.len(), 1, "Invalid number of arguments"); let mut s = ts_state.lock().unwrap(); - dispatcher(&mut s, control) + dispatcher(&mut s, &zero_copy_bufs[0]) } } @@ -338,16 +337,15 @@ pub fn trace_serializer() { /// CoreIsolate. pub fn op_fetch_asset<S: ::std::hash::BuildHasher>( custom_assets: HashMap<String, PathBuf, S>, -) -> impl Fn(&mut CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op { +) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op { for (_, path) in custom_assets.iter() { println!("cargo:rerun-if-changed={}", path.display()); } move |_state: &mut CoreIsolateState, - control: &[u8], zero_copy_bufs: &mut [ZeroCopyBuf]| -> Op { - assert!(zero_copy_bufs.is_empty()); // zero_copy_bufs unused in this op. - let name = std::str::from_utf8(control).unwrap(); + assert_eq!(zero_copy_bufs.len(), 1, "Invalid number of arguments"); + let name = std::str::from_utf8(&zero_copy_bufs[0]).unwrap(); let asset_code = if let Some(source_code) = get_asset(name) { source_code.to_string() diff --git a/test_plugin/src/lib.rs b/test_plugin/src/lib.rs index 781bc4259..bb4c4d8ff 100644 --- a/test_plugin/src/lib.rs +++ b/test_plugin/src/lib.rs @@ -12,14 +12,12 @@ pub fn deno_plugin_init(interface: &mut dyn Interface) { fn op_test_sync( _interface: &mut dyn Interface, - data: &[u8], zero_copy: &mut [ZeroCopyBuf], ) -> Op { - let data_str = std::str::from_utf8(&data[..]).unwrap(); - let zero_copy = zero_copy.to_vec(); if !zero_copy.is_empty() { - println!("Hello from plugin. data: {}", data_str); + println!("Hello from plugin."); } + let zero_copy = zero_copy.to_vec(); for (idx, buf) in zero_copy.iter().enumerate() { let buf_str = std::str::from_utf8(&buf[..]).unwrap(); println!("zero_copy[{}]: {}", idx, buf_str); @@ -31,14 +29,12 @@ fn op_test_sync( fn op_test_async( _interface: &mut dyn Interface, - data: &[u8], zero_copy: &mut [ZeroCopyBuf], ) -> Op { - let zero_copy = zero_copy.to_vec(); if !zero_copy.is_empty() { - let data_str = std::str::from_utf8(&data[..]).unwrap().to_string(); - println!("Hello from plugin. data: {}", data_str); + println!("Hello from plugin."); } + let zero_copy = zero_copy.to_vec(); let fut = async move { for (idx, buf) in zero_copy.iter().enumerate() { let buf_str = std::str::from_utf8(&buf[..]).unwrap(); diff --git a/test_plugin/tests/integration_tests.rs b/test_plugin/tests/integration_tests.rs index 53d1c2441..85374c217 100644 --- a/test_plugin/tests/integration_tests.rs +++ b/test_plugin/tests/integration_tests.rs @@ -36,7 +36,7 @@ fn basic() { println!("stderr {}", stderr); } assert!(output.status.success()); - let expected = "Hello from plugin. data: test\nzero_copy[0]: test\nzero_copy[1]: 123\nzero_copy[2]: cba\nPlugin Sync Response: test\nHello from plugin. data: test\nzero_copy[0]: test\nzero_copy[1]: 123\nPlugin Async Response: test\n"; + let expected = "Hello from plugin.\nzero_copy[0]: test\nzero_copy[1]: 123\nzero_copy[2]: cba\nPlugin Sync Response: test\nHello from plugin.\nzero_copy[0]: test\nzero_copy[1]: 123\nPlugin Async Response: test\n"; assert_eq!(stdout, expected); assert_eq!(stderr, ""); } diff --git a/test_plugin/tests/test.js b/test_plugin/tests/test.js index fbe58aeb8..d48394b4b 100644 --- a/test_plugin/tests/test.js +++ b/test_plugin/tests/test.js @@ -33,7 +33,6 @@ function runTestSync() { const response = Deno.core.dispatch( testSync, new Uint8Array([116, 101, 115, 116]), - new Uint8Array([116, 101, 115, 116]), new Uint8Array([49, 50, 51]), new Uint8Array([99, 98, 97]) ); @@ -49,7 +48,6 @@ function runTestAsync() { const response = Deno.core.dispatch( testAsync, new Uint8Array([116, 101, 115, 116]), - new Uint8Array([116, 101, 115, 116]), new Uint8Array([49, 50, 51]) ); @@ -61,7 +59,7 @@ function runTestAsync() { function runTestOpCount() { const start = Deno.metrics(); - Deno.core.dispatch(testSync, new Uint8Array([116, 101, 115, 116])); + Deno.core.dispatch(testSync); const end = Deno.metrics(); |