mirror of
https://github.com/denoland/deno.git
synced 2024-11-21 15:04:11 -05:00
BREAKING(core): Remove control slice from ops (#6048)
This commit is contained in:
parent
cbbd944359
commit
be7e0f2d49
18 changed files with 120 additions and 160 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -441,6 +441,7 @@ dependencies = [
|
||||||
"log 0.4.8",
|
"log 0.4.8",
|
||||||
"rusty_v8",
|
"rusty_v8",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"smallvec 1.4.0",
|
||||||
"tokio",
|
"tokio",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
|
@ -77,14 +77,9 @@ declare global {
|
||||||
|
|
||||||
interface DenoCore {
|
interface DenoCore {
|
||||||
print(s: string, isErr?: boolean): void;
|
print(s: string, isErr?: boolean): void;
|
||||||
dispatch(
|
dispatch(opId: number, ...zeroCopy: ArrayBufferView[]): Uint8Array | null;
|
||||||
opId: number,
|
|
||||||
control: Uint8Array,
|
|
||||||
...zeroCopy: ArrayBufferView[]
|
|
||||||
): Uint8Array | null;
|
|
||||||
dispatchByName(
|
dispatchByName(
|
||||||
opName: string,
|
opName: string,
|
||||||
control: Uint8Array,
|
|
||||||
...zeroCopy: ArrayBufferView[]
|
...zeroCopy: ArrayBufferView[]
|
||||||
): Uint8Array | null;
|
): Uint8Array | null;
|
||||||
setAsyncHandler(opId: number, cb: (msg: Uint8Array) => void): void;
|
setAsyncHandler(opId: number, cb: (msg: Uint8Array) => void): void;
|
||||||
|
@ -101,11 +96,7 @@ declare global {
|
||||||
|
|
||||||
recv(cb: (opId: number, msg: Uint8Array) => void): void;
|
recv(cb: (opId: number, msg: Uint8Array) => void): void;
|
||||||
|
|
||||||
send(
|
send(opId: number, ...data: ArrayBufferView[]): null | Uint8Array;
|
||||||
opId: number,
|
|
||||||
control: null | ArrayBufferView,
|
|
||||||
...data: ArrayBufferView[]
|
|
||||||
): null | Uint8Array;
|
|
||||||
|
|
||||||
setMacrotaskCallback(cb: () => boolean): void;
|
setMacrotaskCallback(cb: () => boolean): void;
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ struct AsyncArgs {
|
||||||
|
|
||||||
pub fn json_op<D>(
|
pub fn json_op<D>(
|
||||||
d: D,
|
d: D,
|
||||||
) -> impl Fn(&mut CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op
|
) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
|
||||||
where
|
where
|
||||||
D: Fn(
|
D: Fn(
|
||||||
&mut CoreIsolateState,
|
&mut CoreIsolateState,
|
||||||
|
@ -54,10 +54,9 @@ where
|
||||||
&mut [ZeroCopyBuf],
|
&mut [ZeroCopyBuf],
|
||||||
) -> Result<JsonOp, OpError>,
|
) -> Result<JsonOp, OpError>,
|
||||||
{
|
{
|
||||||
move |isolate_state: &mut CoreIsolateState,
|
move |isolate_state: &mut CoreIsolateState, zero_copy: &mut [ZeroCopyBuf]| {
|
||||||
control: &[u8],
|
assert!(!zero_copy.is_empty(), "Expected JSON string at position 0");
|
||||||
zero_copy: &mut [ZeroCopyBuf]| {
|
let async_args: AsyncArgs = match serde_json::from_slice(&zero_copy[0]) {
|
||||||
let async_args: AsyncArgs = match serde_json::from_slice(control) {
|
|
||||||
Ok(args) => args,
|
Ok(args) => args,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
let buf = serialize_result(None, Err(OpError::from(e)));
|
let buf = serialize_result(None, Err(OpError::from(e)));
|
||||||
|
@ -67,9 +66,9 @@ where
|
||||||
let promise_id = async_args.promise_id;
|
let promise_id = async_args.promise_id;
|
||||||
let is_sync = promise_id.is_none();
|
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)
|
.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
|
// Convert to Op
|
||||||
match result {
|
match result {
|
||||||
|
|
|
@ -116,14 +116,13 @@ fn test_parse_min_record() {
|
||||||
|
|
||||||
pub fn minimal_op<D>(
|
pub fn minimal_op<D>(
|
||||||
d: D,
|
d: D,
|
||||||
) -> impl Fn(&mut CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op
|
) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
|
||||||
where
|
where
|
||||||
D: Fn(&mut CoreIsolateState, bool, i32, &mut [ZeroCopyBuf]) -> MinimalOp,
|
D: Fn(&mut CoreIsolateState, bool, i32, &mut [ZeroCopyBuf]) -> MinimalOp,
|
||||||
{
|
{
|
||||||
move |isolate_state: &mut CoreIsolateState,
|
move |isolate_state: &mut CoreIsolateState, zero_copy: &mut [ZeroCopyBuf]| {
|
||||||
control: &[u8],
|
assert!(!zero_copy.is_empty(), "Expected record at position 0");
|
||||||
zero_copy: &mut [ZeroCopyBuf]| {
|
let mut record = match parse_min_record(&zero_copy[0]) {
|
||||||
let mut record = match parse_min_record(control) {
|
|
||||||
Some(r) => r,
|
Some(r) => r,
|
||||||
None => {
|
None => {
|
||||||
let e = OpError::type_error("Unparsable control buffer".to_string());
|
let e = OpError::type_error("Unparsable control buffer".to_string());
|
||||||
|
@ -138,7 +137,7 @@ where
|
||||||
};
|
};
|
||||||
let is_sync = record.promise_id == 0;
|
let is_sync = record.promise_id == 0;
|
||||||
let rid = record.arg;
|
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 {
|
match min_op {
|
||||||
MinimalOp::Sync(sync_result) => Op::Sync(match sync_result {
|
MinimalOp::Sync(sync_result) => Op::Sync(match sync_result {
|
||||||
|
|
|
@ -110,9 +110,9 @@ impl<'a> plugin_api::Interface for PluginInterface<'a> {
|
||||||
let plugin_lib = self.plugin_lib.clone();
|
let plugin_lib = self.plugin_lib.clone();
|
||||||
self.isolate_state.op_registry.register(
|
self.isolate_state.op_registry.register(
|
||||||
name,
|
name,
|
||||||
move |isolate_state, control, zero_copy| {
|
move |isolate_state, zero_copy| {
|
||||||
let mut interface = PluginInterface::new(isolate_state, &plugin_lib);
|
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 {
|
match op {
|
||||||
sync_op @ Op::Sync(..) => sync_op,
|
sync_op @ Op::Sync(..) => sync_op,
|
||||||
Op::Async(fut) => {
|
Op::Async(fut) => {
|
||||||
|
|
18
cli/state.rs
18
cli/state.rs
|
@ -65,7 +65,7 @@ impl State {
|
||||||
pub fn stateful_json_op<D>(
|
pub fn stateful_json_op<D>(
|
||||||
&self,
|
&self,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
) -> impl Fn(&mut deno_core::CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op
|
) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
|
||||||
where
|
where
|
||||||
D: Fn(&State, Value, &mut [ZeroCopyBuf]) -> Result<JsonOp, OpError>,
|
D: Fn(&State, Value, &mut [ZeroCopyBuf]) -> Result<JsonOp, OpError>,
|
||||||
{
|
{
|
||||||
|
@ -76,7 +76,7 @@ impl State {
|
||||||
pub fn stateful_json_op2<D>(
|
pub fn stateful_json_op2<D>(
|
||||||
&self,
|
&self,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
) -> impl Fn(&mut deno_core::CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op
|
) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
|
||||||
where
|
where
|
||||||
D: Fn(
|
D: Fn(
|
||||||
&mut deno_core::CoreIsolateState,
|
&mut deno_core::CoreIsolateState,
|
||||||
|
@ -95,21 +95,21 @@ impl State {
|
||||||
pub fn core_op<D>(
|
pub fn core_op<D>(
|
||||||
&self,
|
&self,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
) -> impl Fn(&mut deno_core::CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op
|
) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
|
||||||
where
|
where
|
||||||
D: Fn(&mut deno_core::CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op,
|
D: Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op,
|
||||||
{
|
{
|
||||||
let state = self.clone();
|
let state = self.clone();
|
||||||
|
|
||||||
move |isolate_state: &mut deno_core::CoreIsolateState,
|
move |isolate_state: &mut deno_core::CoreIsolateState,
|
||||||
control: &[u8],
|
|
||||||
zero_copy: &mut [ZeroCopyBuf]|
|
zero_copy: &mut [ZeroCopyBuf]|
|
||||||
-> Op {
|
-> 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 =
|
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 {
|
match op {
|
||||||
Op::Sync(buf) => {
|
Op::Sync(buf) => {
|
||||||
|
@ -155,7 +155,7 @@ impl State {
|
||||||
pub fn stateful_minimal_op2<D>(
|
pub fn stateful_minimal_op2<D>(
|
||||||
&self,
|
&self,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
) -> impl Fn(&mut deno_core::CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op
|
) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
|
||||||
where
|
where
|
||||||
D: Fn(
|
D: Fn(
|
||||||
&mut deno_core::CoreIsolateState,
|
&mut deno_core::CoreIsolateState,
|
||||||
|
|
|
@ -21,6 +21,7 @@ libc = "0.2.71"
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
rusty_v8 = "0.6.0"
|
rusty_v8 = "0.6.0"
|
||||||
serde_json = "1.0.55"
|
serde_json = "1.0.55"
|
||||||
|
smallvec = "1.4.0"
|
||||||
url = "2.1.1"
|
url = "2.1.1"
|
||||||
|
|
||||||
[[example]]
|
[[example]]
|
||||||
|
|
|
@ -8,6 +8,7 @@ use crate::ZeroCopyBuf;
|
||||||
use rusty_v8 as v8;
|
use rusty_v8 as v8;
|
||||||
use v8::MapFnTo;
|
use v8::MapFnTo;
|
||||||
|
|
||||||
|
use smallvec::SmallVec;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::option::Option;
|
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 state_rc = CoreIsolate::state(scope);
|
||||||
let mut state = state_rc.borrow_mut();
|
let mut state = state_rc.borrow_mut();
|
||||||
assert!(!state.global_context.is_empty());
|
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))
|
v8::Local::<v8::ArrayBufferView>::try_from(args.get(idx))
|
||||||
.map(|view| ZeroCopyBuf::new(scope, view))
|
.map(|view| ZeroCopyBuf::new(scope, view))
|
||||||
.map_err(|err| {
|
.map_err(|err| {
|
||||||
|
@ -415,36 +403,15 @@ fn send(
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut buf_one: ZeroCopyBuf;
|
// If response is empty then it's either async op or exception was thrown.
|
||||||
let mut buf_vec: Vec<ZeroCopyBuf>;
|
let maybe_response =
|
||||||
|
match buf_iter.collect::<Result<SmallVec<[ZeroCopyBuf; 2]>, _>>() {
|
||||||
// Collect all ArrayBufferView's
|
Ok(mut bufs) => state.dispatch_op(scope, op_id, &mut bufs),
|
||||||
let buf_iter_result = match buf_iter.len() {
|
Err(exc) => {
|
||||||
0 => Ok(&mut [][..]),
|
scope.throw_exception(exc);
|
||||||
1 => match buf_iter.next().unwrap() {
|
return;
|
||||||
Ok(buf) => {
|
|
||||||
buf_one = buf;
|
|
||||||
Ok(std::slice::from_mut(&mut buf_one))
|
|
||||||
}
|
}
|
||||||
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 {
|
if let Some(response) = maybe_response {
|
||||||
// Synchronous response.
|
// Synchronous response.
|
||||||
|
|
|
@ -350,7 +350,7 @@ impl CoreIsolate {
|
||||||
/// Requires runtime to explicitly ask for op ids before using any of the ops.
|
/// 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
|
pub fn register_op<F>(&mut self, name: &str, op: F) -> OpId
|
||||||
where
|
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 state_rc = Self::state(self);
|
||||||
let mut state = state_rc.borrow_mut();
|
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.
|
/// 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
|
pub fn register_op<F>(&mut self, name: &str, op: F) -> OpId
|
||||||
where
|
where
|
||||||
F: Fn(&mut CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op + 'static,
|
F: Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op + 'static,
|
||||||
{
|
{
|
||||||
self.op_registry.register(name, op)
|
self.op_registry.register(name, op)
|
||||||
}
|
}
|
||||||
|
@ -485,11 +485,10 @@ impl CoreIsolateState {
|
||||||
&mut self,
|
&mut self,
|
||||||
scope: &mut v8::HandleScope<'s>,
|
scope: &mut v8::HandleScope<'s>,
|
||||||
op_id: OpId,
|
op_id: OpId,
|
||||||
control_buf: &[u8],
|
|
||||||
zero_copy_bufs: &mut [ZeroCopyBuf],
|
zero_copy_bufs: &mut [ZeroCopyBuf],
|
||||||
) -> Option<(OpId, Box<[u8]>)> {
|
) -> Option<(OpId, Box<[u8]>)> {
|
||||||
let op = if let Some(dispatcher) = self.op_registry.get(op_id) {
|
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 {
|
} else {
|
||||||
let message =
|
let message =
|
||||||
v8::String::new(scope, &format!("Unknown op id: {}", op_id)).unwrap();
|
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 mut isolate = CoreIsolate::new(StartupData::None, false);
|
||||||
|
|
||||||
let dispatcher = move |_state: &mut CoreIsolateState,
|
let dispatcher = move |_state: &mut CoreIsolateState,
|
||||||
control: &[u8],
|
|
||||||
zero_copy: &mut [ZeroCopyBuf]|
|
zero_copy: &mut [ZeroCopyBuf]|
|
||||||
-> Op {
|
-> Op {
|
||||||
dispatch_count_.fetch_add(1, Ordering::Relaxed);
|
dispatch_count_.fetch_add(1, Ordering::Relaxed);
|
||||||
match mode {
|
match mode {
|
||||||
Mode::Async => {
|
Mode::Async => {
|
||||||
assert_eq!(control.len(), 1);
|
assert_eq!(zero_copy.len(), 1);
|
||||||
assert_eq!(control[0], 42);
|
assert_eq!(zero_copy[0].len(), 1);
|
||||||
|
assert_eq!(zero_copy[0][0], 42);
|
||||||
let buf = vec![43u8].into_boxed_slice();
|
let buf = vec![43u8].into_boxed_slice();
|
||||||
Op::Async(futures::future::ready(buf).boxed())
|
Op::Async(futures::future::ready(buf).boxed())
|
||||||
}
|
}
|
||||||
Mode::AsyncUnref => {
|
Mode::AsyncUnref => {
|
||||||
assert_eq!(control.len(), 1);
|
assert_eq!(zero_copy.len(), 1);
|
||||||
assert_eq!(control[0], 42);
|
assert_eq!(zero_copy[0].len(), 1);
|
||||||
|
assert_eq!(zero_copy[0][0], 42);
|
||||||
let fut = async {
|
let fut = async {
|
||||||
// This future never finish.
|
// This future never finish.
|
||||||
futures::future::pending::<()>().await;
|
futures::future::pending::<()>().await;
|
||||||
|
@ -726,8 +726,6 @@ pub mod tests {
|
||||||
Op::AsyncUnref(fut.boxed())
|
Op::AsyncUnref(fut.boxed())
|
||||||
}
|
}
|
||||||
Mode::AsyncZeroCopy(count) => {
|
Mode::AsyncZeroCopy(count) => {
|
||||||
assert_eq!(control.len(), 1);
|
|
||||||
assert_eq!(control[0], 24);
|
|
||||||
assert_eq!(zero_copy.len(), count as usize);
|
assert_eq!(zero_copy.len(), count as usize);
|
||||||
zero_copy.iter().enumerate().for_each(|(idx, buf)| {
|
zero_copy.iter().enumerate().for_each(|(idx, buf)| {
|
||||||
assert_eq!(buf.len(), 1);
|
assert_eq!(buf.len(), 1);
|
||||||
|
@ -738,13 +736,15 @@ pub mod tests {
|
||||||
Op::Async(futures::future::ready(buf).boxed())
|
Op::Async(futures::future::ready(buf).boxed())
|
||||||
}
|
}
|
||||||
Mode::OverflowReqSync => {
|
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();
|
let buf = vec![43u8].into_boxed_slice();
|
||||||
Op::Sync(buf)
|
Op::Sync(buf)
|
||||||
}
|
}
|
||||||
Mode::OverflowResSync => {
|
Mode::OverflowResSync => {
|
||||||
assert_eq!(control.len(), 1);
|
assert_eq!(zero_copy.len(), 1);
|
||||||
assert_eq!(control[0], 42);
|
assert_eq!(zero_copy[0].len(), 1);
|
||||||
|
assert_eq!(zero_copy[0][0], 42);
|
||||||
let mut vec = Vec::<u8>::new();
|
let mut vec = Vec::<u8>::new();
|
||||||
vec.resize(100 * 1024 * 1024, 0);
|
vec.resize(100 * 1024 * 1024, 0);
|
||||||
vec[0] = 99;
|
vec[0] = 99;
|
||||||
|
@ -752,13 +752,15 @@ pub mod tests {
|
||||||
Op::Sync(buf)
|
Op::Sync(buf)
|
||||||
}
|
}
|
||||||
Mode::OverflowReqAsync => {
|
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();
|
let buf = vec![43u8].into_boxed_slice();
|
||||||
Op::Async(futures::future::ready(buf).boxed())
|
Op::Async(futures::future::ready(buf).boxed())
|
||||||
}
|
}
|
||||||
Mode::OverflowResAsync => {
|
Mode::OverflowResAsync => {
|
||||||
assert_eq!(control.len(), 1);
|
assert_eq!(zero_copy.len(), 1);
|
||||||
assert_eq!(control[0], 42);
|
assert_eq!(zero_copy[0].len(), 1);
|
||||||
|
assert_eq!(zero_copy[0][0], 42);
|
||||||
let mut vec = Vec::<u8>::new();
|
let mut vec = Vec::<u8>::new();
|
||||||
vec.resize(100 * 1024 * 1024, 0);
|
vec.resize(100 * 1024 * 1024, 0);
|
||||||
vec[0] = 4;
|
vec[0] = 4;
|
||||||
|
@ -807,37 +809,38 @@ pub mod tests {
|
||||||
js_check(isolate.execute(
|
js_check(isolate.execute(
|
||||||
"filename.js",
|
"filename.js",
|
||||||
r#"
|
r#"
|
||||||
let control = new Uint8Array([24]);
|
Deno.core.send(1);
|
||||||
Deno.core.send(1, control);
|
|
||||||
"#,
|
"#,
|
||||||
));
|
));
|
||||||
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_dispatch_one_zero_copy_buf() {
|
fn test_dispatch_stack_zero_copy_bufs() {
|
||||||
let (mut isolate, dispatch_count) = setup(Mode::AsyncZeroCopy(1));
|
|
||||||
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);
|
|
||||||
"#,
|
|
||||||
));
|
|
||||||
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));
|
let (mut isolate, dispatch_count) = setup(Mode::AsyncZeroCopy(2));
|
||||||
js_check(isolate.execute(
|
js_check(isolate.execute(
|
||||||
"filename.js",
|
"filename.js",
|
||||||
r#"
|
r#"
|
||||||
let control = new Uint8Array([24]);
|
|
||||||
let zero_copy_a = new Uint8Array([0]);
|
let zero_copy_a = new Uint8Array([0]);
|
||||||
let zero_copy_b = new Uint8Array([1]);
|
let zero_copy_b = new Uint8Array([1]);
|
||||||
Deno.core.send(1, control, zero_copy_a, zero_copy_b);
|
Deno.core.send(1, zero_copy_a, zero_copy_b);
|
||||||
|
"#,
|
||||||
|
));
|
||||||
|
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_dispatch_heap_zero_copy_bufs() {
|
||||||
|
let (mut isolate, dispatch_count) = setup(Mode::AsyncZeroCopy(5));
|
||||||
|
js_check(isolate.execute(
|
||||||
|
"filename.js",
|
||||||
|
r#"
|
||||||
|
let zero_copy_a = new Uint8Array([0]);
|
||||||
|
let zero_copy_b = new Uint8Array([1]);
|
||||||
|
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);
|
assert_eq!(dispatch_count.load(Ordering::Relaxed), 1);
|
||||||
|
@ -1120,7 +1123,7 @@ pub mod tests {
|
||||||
r#"
|
r#"
|
||||||
let thrown;
|
let thrown;
|
||||||
try {
|
try {
|
||||||
Deno.core.dispatch(100, []);
|
Deno.core.dispatch(100);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
thrown = e;
|
thrown = e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -708,12 +708,12 @@ pub mod tests {
|
||||||
let mut isolate = EsIsolate::new(loader, StartupData::None, false);
|
let mut isolate = EsIsolate::new(loader, StartupData::None, false);
|
||||||
|
|
||||||
let dispatcher = move |_state: &mut CoreIsolateState,
|
let dispatcher = move |_state: &mut CoreIsolateState,
|
||||||
control: &[u8],
|
zero_copy: &mut [ZeroCopyBuf]|
|
||||||
_zero_copy: &mut [ZeroCopyBuf]|
|
|
||||||
-> Op {
|
-> Op {
|
||||||
dispatch_count_.fetch_add(1, Ordering::Relaxed);
|
dispatch_count_.fetch_add(1, Ordering::Relaxed);
|
||||||
assert_eq!(control.len(), 1);
|
assert_eq!(zero_copy.len(), 1);
|
||||||
assert_eq!(control[0], 42);
|
assert_eq!(zero_copy[0].len(), 1);
|
||||||
|
assert_eq!(zero_copy[0][0], 42);
|
||||||
let buf = vec![43u8, 0, 0, 0].into_boxed_slice();
|
let buf = vec![43u8, 0, 0, 0].into_boxed_slice();
|
||||||
Op::Async(futures::future::ready(buf).boxed())
|
Op::Async(futures::future::ready(buf).boxed())
|
||||||
};
|
};
|
||||||
|
|
|
@ -117,18 +117,19 @@ impl Isolate {
|
||||||
{
|
{
|
||||||
let state = self.state.clone();
|
let state = self.state.clone();
|
||||||
let core_handler = move |_isolate_state: &mut CoreIsolateState,
|
let core_handler = move |_isolate_state: &mut CoreIsolateState,
|
||||||
control_buf: &[u8],
|
|
||||||
zero_copy_bufs: &mut [ZeroCopyBuf]|
|
zero_copy_bufs: &mut [ZeroCopyBuf]|
|
||||||
-> Op {
|
-> Op {
|
||||||
|
assert!(!zero_copy_bufs.is_empty());
|
||||||
let state = state.clone();
|
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;
|
let is_sync = record.promise_id == 0;
|
||||||
assert!(is_sync);
|
assert!(is_sync);
|
||||||
|
|
||||||
let result: i32 = match handler(state, record.rid, zero_copy_bufs) {
|
let result: i32 =
|
||||||
Ok(r) => r as i32,
|
match handler(state, record.rid, &mut zero_copy_bufs[1..]) {
|
||||||
Err(_) => -1,
|
Ok(r) => r as i32,
|
||||||
};
|
Err(_) => -1,
|
||||||
|
};
|
||||||
let buf = RecordBuf::from(Record { result, ..record })[..].into();
|
let buf = RecordBuf::from(Record { result, ..record })[..].into();
|
||||||
Op::Sync(buf)
|
Op::Sync(buf)
|
||||||
};
|
};
|
||||||
|
@ -147,15 +148,15 @@ impl Isolate {
|
||||||
{
|
{
|
||||||
let state = self.state.clone();
|
let state = self.state.clone();
|
||||||
let core_handler = move |_isolate_state: &mut CoreIsolateState,
|
let core_handler = move |_isolate_state: &mut CoreIsolateState,
|
||||||
control_buf: &[u8],
|
|
||||||
zero_copy_bufs: &mut [ZeroCopyBuf]|
|
zero_copy_bufs: &mut [ZeroCopyBuf]|
|
||||||
-> Op {
|
-> Op {
|
||||||
|
assert!(!zero_copy_bufs.is_empty());
|
||||||
let state = state.clone();
|
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;
|
let is_sync = record.promise_id == 0;
|
||||||
assert!(!is_sync);
|
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 fut = async move {
|
||||||
let op = handler(state, record.rid, &mut zero_copy);
|
let op = handler(state, record.rid, &mut zero_copy);
|
||||||
let result = op
|
let result = op
|
||||||
|
|
18
core/ops.rs
18
core/ops.rs
|
@ -22,7 +22,7 @@ pub enum Op {
|
||||||
|
|
||||||
/// Main type describing op
|
/// Main type describing op
|
||||||
pub type OpDispatcher =
|
pub type OpDispatcher =
|
||||||
dyn Fn(&mut CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op + 'static;
|
dyn Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op + 'static;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct OpRegistry {
|
pub struct OpRegistry {
|
||||||
|
@ -33,7 +33,7 @@ pub struct OpRegistry {
|
||||||
impl OpRegistry {
|
impl OpRegistry {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let mut registry = Self::default();
|
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();
|
let buf = state.op_registry.json_map();
|
||||||
Op::Sync(buf)
|
Op::Sync(buf)
|
||||||
});
|
});
|
||||||
|
@ -43,7 +43,7 @@ impl OpRegistry {
|
||||||
|
|
||||||
pub fn register<F>(&mut self, name: &str, op: F) -> OpId
|
pub fn register<F>(&mut self, name: &str, op: F) -> OpId
|
||||||
where
|
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;
|
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 = Arc::new(atomic::AtomicUsize::new(0));
|
||||||
let c_ = c.clone();
|
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);
|
c_.fetch_add(1, atomic::Ordering::SeqCst);
|
||||||
Op::Sync(Box::new([]))
|
Op::Sync(Box::new([]))
|
||||||
});
|
});
|
||||||
|
@ -97,7 +97,7 @@ fn test_op_registry() {
|
||||||
let dispatch = op_registry.get(test_id).unwrap();
|
let dispatch = op_registry.get(test_id).unwrap();
|
||||||
let state_rc = CoreIsolate::state(&isolate);
|
let state_rc = CoreIsolate::state(&isolate);
|
||||||
let mut state = state_rc.borrow_mut();
|
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 {
|
if let Op::Sync(buf) = res {
|
||||||
assert_eq!(buf.len(), 0);
|
assert_eq!(buf.len(), 0);
|
||||||
} else {
|
} else {
|
||||||
|
@ -127,10 +127,10 @@ fn register_op_during_call() {
|
||||||
|
|
||||||
let test_id = {
|
let test_id = {
|
||||||
let mut g = op_registry.lock().unwrap();
|
let mut g = op_registry.lock().unwrap();
|
||||||
g.register("dynamic_register_op", move |_, _, _| {
|
g.register("dynamic_register_op", move |_, _| {
|
||||||
let c__ = c_.clone();
|
let c__ = c_.clone();
|
||||||
let mut g = op_registry_.lock().unwrap();
|
let mut g = op_registry_.lock().unwrap();
|
||||||
g.register("test", move |_, _, _| {
|
g.register("test", move |_, _| {
|
||||||
c__.fetch_add(1, atomic::Ordering::SeqCst);
|
c__.fetch_add(1, atomic::Ordering::SeqCst);
|
||||||
Op::Sync(Box::new([]))
|
Op::Sync(Box::new([]))
|
||||||
});
|
});
|
||||||
|
@ -148,7 +148,7 @@ fn register_op_during_call() {
|
||||||
{
|
{
|
||||||
let state_rc = CoreIsolate::state(&isolate);
|
let state_rc = CoreIsolate::state(&isolate);
|
||||||
let mut state = state_rc.borrow_mut();
|
let mut state = state_rc.borrow_mut();
|
||||||
dispatcher1(&mut state, &[], &mut []);
|
dispatcher1(&mut state, &mut []);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut expected = HashMap::new();
|
let mut expected = HashMap::new();
|
||||||
|
@ -166,7 +166,7 @@ fn register_op_during_call() {
|
||||||
};
|
};
|
||||||
let state_rc = CoreIsolate::state(&isolate);
|
let state_rc = CoreIsolate::state(&isolate);
|
||||||
let mut state = state_rc.borrow_mut();
|
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 {
|
if let Op::Sync(buf) = res {
|
||||||
assert_eq!(buf.len(), 0);
|
assert_eq!(buf.len(), 0);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub use crate::ZeroCopyBuf;
|
||||||
|
|
||||||
pub type InitFn = fn(&mut dyn Interface);
|
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 {
|
pub trait Interface {
|
||||||
fn register_op(&mut self, name: &str, dispatcher: DispatchOpFn) -> OpId;
|
fn register_op(&mut self, name: &str, dispatcher: DispatchOpFn) -> OpId;
|
||||||
|
|
|
@ -6,8 +6,14 @@ use std::ops::DerefMut;
|
||||||
/// A ZeroCopyBuf encapsulates a slice that's been borrowed from a JavaScript
|
/// A ZeroCopyBuf encapsulates a slice that's been borrowed from a JavaScript
|
||||||
/// ArrayBuffer object. JavaScript objects can normally be garbage collected,
|
/// ArrayBuffer object. JavaScript objects can normally be garbage collected,
|
||||||
/// but the existence of a ZeroCopyBuf inhibits this until it is dropped. It
|
/// 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
|
/// behaves much like an Arc<[u8]>.
|
||||||
/// cloned.
|
///
|
||||||
|
/// # 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)]
|
#[derive(Clone)]
|
||||||
pub struct ZeroCopyBuf {
|
pub struct ZeroCopyBuf {
|
||||||
backing_store: v8::SharedRef<v8::BackingStore>,
|
backing_store: v8::SharedRef<v8::BackingStore>,
|
||||||
|
|
|
@ -50,17 +50,16 @@ pub struct TSState {
|
||||||
fn compiler_op<D>(
|
fn compiler_op<D>(
|
||||||
ts_state: Arc<Mutex<TSState>>,
|
ts_state: Arc<Mutex<TSState>>,
|
||||||
dispatcher: D,
|
dispatcher: D,
|
||||||
) -> impl Fn(&mut CoreIsolateState, &[u8], &mut [ZeroCopyBuf]) -> Op
|
) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
|
||||||
where
|
where
|
||||||
D: Fn(&mut TSState, &[u8]) -> Op,
|
D: Fn(&mut TSState, &[u8]) -> Op,
|
||||||
{
|
{
|
||||||
move |_state: &mut CoreIsolateState,
|
move |_state: &mut CoreIsolateState,
|
||||||
control: &[u8],
|
|
||||||
zero_copy_bufs: &mut [ZeroCopyBuf]|
|
zero_copy_bufs: &mut [ZeroCopyBuf]|
|
||||||
-> Op {
|
-> 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();
|
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.
|
/// CoreIsolate.
|
||||||
pub fn op_fetch_asset<S: ::std::hash::BuildHasher>(
|
pub fn op_fetch_asset<S: ::std::hash::BuildHasher>(
|
||||||
custom_assets: HashMap<String, PathBuf, S>,
|
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() {
|
for (_, path) in custom_assets.iter() {
|
||||||
println!("cargo:rerun-if-changed={}", path.display());
|
println!("cargo:rerun-if-changed={}", path.display());
|
||||||
}
|
}
|
||||||
move |_state: &mut CoreIsolateState,
|
move |_state: &mut CoreIsolateState,
|
||||||
control: &[u8],
|
|
||||||
zero_copy_bufs: &mut [ZeroCopyBuf]|
|
zero_copy_bufs: &mut [ZeroCopyBuf]|
|
||||||
-> Op {
|
-> Op {
|
||||||
assert!(zero_copy_bufs.is_empty()); // zero_copy_bufs unused in this op.
|
assert_eq!(zero_copy_bufs.len(), 1, "Invalid number of arguments");
|
||||||
let name = std::str::from_utf8(control).unwrap();
|
let name = std::str::from_utf8(&zero_copy_bufs[0]).unwrap();
|
||||||
|
|
||||||
let asset_code = if let Some(source_code) = get_asset(name) {
|
let asset_code = if let Some(source_code) = get_asset(name) {
|
||||||
source_code.to_string()
|
source_code.to_string()
|
||||||
|
|
|
@ -12,14 +12,12 @@ pub fn deno_plugin_init(interface: &mut dyn Interface) {
|
||||||
|
|
||||||
fn op_test_sync(
|
fn op_test_sync(
|
||||||
_interface: &mut dyn Interface,
|
_interface: &mut dyn Interface,
|
||||||
data: &[u8],
|
|
||||||
zero_copy: &mut [ZeroCopyBuf],
|
zero_copy: &mut [ZeroCopyBuf],
|
||||||
) -> Op {
|
) -> Op {
|
||||||
let data_str = std::str::from_utf8(&data[..]).unwrap();
|
|
||||||
let zero_copy = zero_copy.to_vec();
|
|
||||||
if !zero_copy.is_empty() {
|
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() {
|
for (idx, buf) in zero_copy.iter().enumerate() {
|
||||||
let buf_str = std::str::from_utf8(&buf[..]).unwrap();
|
let buf_str = std::str::from_utf8(&buf[..]).unwrap();
|
||||||
println!("zero_copy[{}]: {}", idx, buf_str);
|
println!("zero_copy[{}]: {}", idx, buf_str);
|
||||||
|
@ -31,14 +29,12 @@ fn op_test_sync(
|
||||||
|
|
||||||
fn op_test_async(
|
fn op_test_async(
|
||||||
_interface: &mut dyn Interface,
|
_interface: &mut dyn Interface,
|
||||||
data: &[u8],
|
|
||||||
zero_copy: &mut [ZeroCopyBuf],
|
zero_copy: &mut [ZeroCopyBuf],
|
||||||
) -> Op {
|
) -> Op {
|
||||||
let zero_copy = zero_copy.to_vec();
|
|
||||||
if !zero_copy.is_empty() {
|
if !zero_copy.is_empty() {
|
||||||
let data_str = std::str::from_utf8(&data[..]).unwrap().to_string();
|
println!("Hello from plugin.");
|
||||||
println!("Hello from plugin. data: {}", data_str);
|
|
||||||
}
|
}
|
||||||
|
let zero_copy = zero_copy.to_vec();
|
||||||
let fut = async move {
|
let fut = async move {
|
||||||
for (idx, buf) in zero_copy.iter().enumerate() {
|
for (idx, buf) in zero_copy.iter().enumerate() {
|
||||||
let buf_str = std::str::from_utf8(&buf[..]).unwrap();
|
let buf_str = std::str::from_utf8(&buf[..]).unwrap();
|
||||||
|
|
|
@ -36,7 +36,7 @@ fn basic() {
|
||||||
println!("stderr {}", stderr);
|
println!("stderr {}", stderr);
|
||||||
}
|
}
|
||||||
assert!(output.status.success());
|
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!(stdout, expected);
|
||||||
assert_eq!(stderr, "");
|
assert_eq!(stderr, "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@ function runTestSync() {
|
||||||
const response = Deno.core.dispatch(
|
const response = Deno.core.dispatch(
|
||||||
testSync,
|
testSync,
|
||||||
new Uint8Array([116, 101, 115, 116]),
|
new Uint8Array([116, 101, 115, 116]),
|
||||||
new Uint8Array([116, 101, 115, 116]),
|
|
||||||
new Uint8Array([49, 50, 51]),
|
new Uint8Array([49, 50, 51]),
|
||||||
new Uint8Array([99, 98, 97])
|
new Uint8Array([99, 98, 97])
|
||||||
);
|
);
|
||||||
|
@ -49,7 +48,6 @@ function runTestAsync() {
|
||||||
const response = Deno.core.dispatch(
|
const response = Deno.core.dispatch(
|
||||||
testAsync,
|
testAsync,
|
||||||
new Uint8Array([116, 101, 115, 116]),
|
new Uint8Array([116, 101, 115, 116]),
|
||||||
new Uint8Array([116, 101, 115, 116]),
|
|
||||||
new Uint8Array([49, 50, 51])
|
new Uint8Array([49, 50, 51])
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -61,7 +59,7 @@ function runTestAsync() {
|
||||||
function runTestOpCount() {
|
function runTestOpCount() {
|
||||||
const start = Deno.metrics();
|
const start = Deno.metrics();
|
||||||
|
|
||||||
Deno.core.dispatch(testSync, new Uint8Array([116, 101, 115, 116]));
|
Deno.core.dispatch(testSync);
|
||||||
|
|
||||||
const end = Deno.metrics();
|
const end = Deno.metrics();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue