mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
core: Rename Behavior to Dispatch (#2082)
And rename IsolateState to ThreadSafeState. Also make ThreadSafeState directly implement Dispatch. This is simpler.
This commit is contained in:
parent
e43da28b28
commit
d2579f4564
12 changed files with 206 additions and 214 deletions
|
@ -1,28 +0,0 @@
|
|||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||
use crate::isolate_state::*;
|
||||
use crate::ops;
|
||||
use deno::deno_buf;
|
||||
use deno::Behavior;
|
||||
use deno::Op;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Implements deno::Behavior for the main Deno command-line.
|
||||
pub struct CliBehavior {
|
||||
pub state: Arc<IsolateState>,
|
||||
}
|
||||
|
||||
impl CliBehavior {
|
||||
pub fn new(state: Arc<IsolateState>) -> Self {
|
||||
Self { state }
|
||||
}
|
||||
}
|
||||
|
||||
impl Behavior for CliBehavior {
|
||||
fn dispatch(
|
||||
&mut self,
|
||||
control: &[u8],
|
||||
zero_copy: deno_buf,
|
||||
) -> (bool, Box<Op>) {
|
||||
ops::dispatch_all(&self.state, control, zero_copy, ops::op_selector_std)
|
||||
}
|
||||
}
|
|
@ -1,12 +1,11 @@
|
|||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||
use crate::cli_behavior::CliBehavior;
|
||||
use crate::isolate_state::*;
|
||||
use crate::js_errors;
|
||||
use crate::js_errors::JSErrorColor;
|
||||
use crate::msg;
|
||||
use crate::resources;
|
||||
use crate::resources::ResourceId;
|
||||
use crate::startup_data;
|
||||
use crate::state::*;
|
||||
use crate::tokio_util;
|
||||
use crate::worker::Worker;
|
||||
use deno::js_check;
|
||||
|
@ -21,7 +20,6 @@ use std::collections::HashMap;
|
|||
use std::str;
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
|
@ -88,22 +86,21 @@ fn parse_cmd_id(res_json: &str) -> CmdId {
|
|||
}
|
||||
}
|
||||
|
||||
fn lazy_start(parent_state: Arc<IsolateState>) -> ResourceId {
|
||||
fn lazy_start(parent_state: ThreadSafeState) -> ResourceId {
|
||||
let mut cell = C_RID.lock().unwrap();
|
||||
cell
|
||||
.get_or_insert_with(|| {
|
||||
let child_state = Arc::new(IsolateState::new(
|
||||
let child_state = ThreadSafeState::new(
|
||||
parent_state.flags.clone(),
|
||||
parent_state.argv.clone(),
|
||||
));
|
||||
);
|
||||
let rid = child_state.resource.rid;
|
||||
let resource = child_state.resource.clone();
|
||||
let behavior = CliBehavior::new(child_state);
|
||||
|
||||
let mut worker = Worker::new(
|
||||
"TS".to_string(),
|
||||
startup_data::compiler_isolate_init(),
|
||||
behavior,
|
||||
child_state,
|
||||
);
|
||||
|
||||
js_check(worker.execute("denoMain()"));
|
||||
|
@ -160,7 +157,7 @@ fn req(specifier: &str, referrer: &str, cmd_id: u32) -> Buf {
|
|||
}
|
||||
|
||||
pub fn compile_async(
|
||||
parent_state: Arc<IsolateState>,
|
||||
parent_state: ThreadSafeState,
|
||||
specifier: &str,
|
||||
referrer: &str,
|
||||
module_meta_data: &ModuleMetaData,
|
||||
|
@ -248,7 +245,7 @@ pub fn compile_async(
|
|||
}
|
||||
|
||||
pub fn compile_sync(
|
||||
parent_state: Arc<IsolateState>,
|
||||
parent_state: ThreadSafeState,
|
||||
specifier: &str,
|
||||
referrer: &str,
|
||||
module_meta_data: &ModuleMetaData,
|
||||
|
@ -286,12 +283,8 @@ mod tests {
|
|||
maybe_source_map: None,
|
||||
};
|
||||
|
||||
out = compile_sync(
|
||||
Arc::new(IsolateState::mock()),
|
||||
specifier,
|
||||
&referrer,
|
||||
&out,
|
||||
).unwrap();
|
||||
out = compile_sync(ThreadSafeState::mock(), specifier, &referrer, &out)
|
||||
.unwrap();
|
||||
assert!(
|
||||
out
|
||||
.maybe_output_code
|
||||
|
|
18
cli/main.rs
18
cli/main.rs
|
@ -11,7 +11,6 @@ extern crate clap;
|
|||
extern crate deno;
|
||||
|
||||
mod ansi;
|
||||
pub mod cli_behavior;
|
||||
pub mod compiler;
|
||||
pub mod deno_dir;
|
||||
pub mod errors;
|
||||
|
@ -20,7 +19,6 @@ mod fs;
|
|||
mod global_timer;
|
||||
mod http_body;
|
||||
mod http_util;
|
||||
pub mod isolate_state;
|
||||
pub mod js_errors;
|
||||
pub mod modules;
|
||||
pub mod msg;
|
||||
|
@ -31,20 +29,19 @@ mod repl;
|
|||
pub mod resolve_addr;
|
||||
pub mod resources;
|
||||
mod startup_data;
|
||||
pub mod state;
|
||||
mod tokio_util;
|
||||
mod tokio_write;
|
||||
pub mod version;
|
||||
pub mod worker;
|
||||
|
||||
use crate::cli_behavior::CliBehavior;
|
||||
use crate::errors::RustOrJsError;
|
||||
use crate::isolate_state::IsolateState;
|
||||
use crate::state::ThreadSafeState;
|
||||
use crate::worker::Worker;
|
||||
use futures::lazy;
|
||||
use futures::Future;
|
||||
use log::{LevelFilter, Metadata, Record};
|
||||
use std::env;
|
||||
use std::sync::Arc;
|
||||
|
||||
static LOGGER: Logger = Logger;
|
||||
|
||||
|
@ -104,11 +101,12 @@ fn main() {
|
|||
let should_prefetch = flags.prefetch || flags.info;
|
||||
let should_display_info = flags.info;
|
||||
|
||||
let state = Arc::new(IsolateState::new(flags, rest_argv));
|
||||
let state_ = state.clone();
|
||||
let cli = CliBehavior::new(state_);
|
||||
let mut main_worker =
|
||||
Worker::new("main".to_string(), startup_data::deno_isolate_init(), cli);
|
||||
let state = ThreadSafeState::new(flags, rest_argv);
|
||||
let mut main_worker = Worker::new(
|
||||
"main".to_string(),
|
||||
startup_data::deno_isolate_init(),
|
||||
state.clone(),
|
||||
);
|
||||
|
||||
let main_future = lazy(move || {
|
||||
// Setup runtime.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
feature = "cargo-clippy",
|
||||
allow(clippy::all, clippy::pedantic)
|
||||
)]
|
||||
use crate::isolate_state;
|
||||
use crate::state;
|
||||
use flatbuffers;
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
|
@ -13,8 +13,8 @@ use std::sync::atomic::Ordering;
|
|||
// build_extra/rust/run.py (for the GN+Ninja build).
|
||||
include!(concat!(env!("GN_OUT_DIR"), "/gen/cli/msg_generated.rs"));
|
||||
|
||||
impl<'a> From<&'a isolate_state::Metrics> for MetricsResArgs {
|
||||
fn from(m: &'a isolate_state::Metrics) -> Self {
|
||||
impl<'a> From<&'a state::Metrics> for MetricsResArgs {
|
||||
fn from(m: &'a state::Metrics) -> Self {
|
||||
MetricsResArgs {
|
||||
ops_dispatched: m.ops_dispatched.load(Ordering::SeqCst) as u64,
|
||||
ops_completed: m.ops_completed.load(Ordering::SeqCst) as u64,
|
||||
|
|
113
cli/ops.rs
113
cli/ops.rs
|
@ -1,12 +1,10 @@
|
|||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||
use atty;
|
||||
use crate::ansi;
|
||||
use crate::cli_behavior::CliBehavior;
|
||||
use crate::errors;
|
||||
use crate::errors::{DenoError, DenoResult, ErrorKind};
|
||||
use crate::fs as deno_fs;
|
||||
use crate::http_util;
|
||||
use crate::isolate_state::IsolateState;
|
||||
use crate::js_errors::apply_source_map;
|
||||
use crate::js_errors::JSErrorColor;
|
||||
use crate::msg;
|
||||
|
@ -17,6 +15,7 @@ use crate::resources;
|
|||
use crate::resources::table_entries;
|
||||
use crate::resources::Resource;
|
||||
use crate::startup_data;
|
||||
use crate::state::ThreadSafeState;
|
||||
use crate::tokio_util;
|
||||
use crate::tokio_write;
|
||||
use crate::version;
|
||||
|
@ -42,7 +41,6 @@ use std::net::Shutdown;
|
|||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::sync::Arc;
|
||||
use std::time::{Duration, Instant, UNIX_EPOCH};
|
||||
use tokio;
|
||||
use tokio::net::TcpListener;
|
||||
|
@ -62,7 +60,7 @@ pub type OpWithError = dyn Future<Item = Buf, Error = DenoError> + Send;
|
|||
// TODO Ideally we wouldn't have to box the OpWithError being returned.
|
||||
// The box is just to make it easier to get a prototype refactor working.
|
||||
type OpCreator =
|
||||
fn(state: &Arc<IsolateState>, base: &msg::Base<'_>, data: deno_buf)
|
||||
fn(state: &ThreadSafeState, base: &msg::Base<'_>, data: deno_buf)
|
||||
-> Box<OpWithError>;
|
||||
|
||||
type OpSelector = fn(inner_type: msg::Any) -> Option<OpCreator>;
|
||||
|
@ -77,7 +75,7 @@ fn empty_buf() -> Buf {
|
|||
/// control corresponds to the first argument of Deno.core.dispatch().
|
||||
/// data corresponds to the second argument of Deno.core.dispatch().
|
||||
pub fn dispatch_all(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
control: &[u8],
|
||||
zero_copy: deno_buf,
|
||||
op_selector: OpSelector,
|
||||
|
@ -209,7 +207,7 @@ pub fn op_selector_std(inner_type: msg::Any) -> Option<OpCreator> {
|
|||
// If the High precision flag is not set, the
|
||||
// nanoseconds are rounded on 2ms.
|
||||
fn op_now(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -245,7 +243,7 @@ fn op_now(
|
|||
}
|
||||
|
||||
fn op_is_tty(
|
||||
_state: &Arc<IsolateState>,
|
||||
_state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
_data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -270,7 +268,7 @@ fn op_is_tty(
|
|||
}
|
||||
|
||||
fn op_exit(
|
||||
_state: &Arc<IsolateState>,
|
||||
_state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
_data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -279,7 +277,7 @@ fn op_exit(
|
|||
}
|
||||
|
||||
fn op_start(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -335,7 +333,7 @@ fn op_start(
|
|||
}
|
||||
|
||||
fn op_format_error(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -394,7 +392,7 @@ pub fn odd_future(err: DenoError) -> Box<OpWithError> {
|
|||
|
||||
// https://github.com/denoland/deno/blob/golang/os.go#L100-L154
|
||||
fn op_fetch_module_meta_data(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -435,7 +433,7 @@ fn op_fetch_module_meta_data(
|
|||
}
|
||||
|
||||
fn op_chdir(
|
||||
_state: &Arc<IsolateState>,
|
||||
_state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -449,7 +447,7 @@ fn op_chdir(
|
|||
}
|
||||
|
||||
fn op_global_timer_stop(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -462,7 +460,7 @@ fn op_global_timer_stop(
|
|||
}
|
||||
|
||||
fn op_global_timer(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -495,7 +493,7 @@ fn op_global_timer(
|
|||
}
|
||||
|
||||
fn op_set_env(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -511,7 +509,7 @@ fn op_set_env(
|
|||
}
|
||||
|
||||
fn op_env(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -543,7 +541,7 @@ fn op_env(
|
|||
}
|
||||
|
||||
fn op_permissions(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -573,7 +571,7 @@ fn op_permissions(
|
|||
}
|
||||
|
||||
fn op_revoke_permission(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -596,7 +594,7 @@ fn op_revoke_permission(
|
|||
}
|
||||
|
||||
fn op_fetch(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -683,7 +681,7 @@ where
|
|||
}
|
||||
|
||||
fn op_make_temp_dir(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -732,7 +730,7 @@ fn op_make_temp_dir(
|
|||
}
|
||||
|
||||
fn op_mkdir(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -754,7 +752,7 @@ fn op_mkdir(
|
|||
}
|
||||
|
||||
fn op_chmod(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -793,7 +791,7 @@ fn op_chmod(
|
|||
}
|
||||
|
||||
fn op_open(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -883,7 +881,7 @@ fn op_open(
|
|||
}
|
||||
|
||||
fn op_close(
|
||||
_state: &Arc<IsolateState>,
|
||||
_state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -900,7 +898,7 @@ fn op_close(
|
|||
}
|
||||
|
||||
fn op_shutdown(
|
||||
_state: &Arc<IsolateState>,
|
||||
_state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -926,7 +924,7 @@ fn op_shutdown(
|
|||
}
|
||||
|
||||
fn op_read(
|
||||
_state: &Arc<IsolateState>,
|
||||
_state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -964,7 +962,7 @@ fn op_read(
|
|||
}
|
||||
|
||||
fn op_write(
|
||||
_state: &Arc<IsolateState>,
|
||||
_state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1001,7 +999,7 @@ fn op_write(
|
|||
}
|
||||
|
||||
fn op_seek(
|
||||
_state: &Arc<IsolateState>,
|
||||
_state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1023,7 +1021,7 @@ fn op_seek(
|
|||
}
|
||||
|
||||
fn op_remove(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1052,7 +1050,7 @@ fn op_remove(
|
|||
}
|
||||
|
||||
fn op_copy_file(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1108,7 +1106,7 @@ fn get_mode(_perm: &fs::Permissions) -> u32 {
|
|||
}
|
||||
|
||||
fn op_cwd(
|
||||
_state: &Arc<IsolateState>,
|
||||
_state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1134,7 +1132,7 @@ fn op_cwd(
|
|||
}
|
||||
|
||||
fn op_stat(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1186,7 +1184,7 @@ fn op_stat(
|
|||
}
|
||||
|
||||
fn op_read_dir(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1247,7 +1245,7 @@ fn op_read_dir(
|
|||
}
|
||||
|
||||
fn op_rename(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1267,7 +1265,7 @@ fn op_rename(
|
|||
}
|
||||
|
||||
fn op_link(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1289,7 +1287,7 @@ fn op_link(
|
|||
}
|
||||
|
||||
fn op_symlink(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1318,7 +1316,7 @@ fn op_symlink(
|
|||
}
|
||||
|
||||
fn op_read_link(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1356,7 +1354,7 @@ fn op_read_link(
|
|||
}
|
||||
|
||||
fn op_repl_start(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1387,7 +1385,7 @@ fn op_repl_start(
|
|||
}
|
||||
|
||||
fn op_repl_readline(
|
||||
_state: &Arc<IsolateState>,
|
||||
_state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1423,7 +1421,7 @@ fn op_repl_readline(
|
|||
}
|
||||
|
||||
fn op_truncate(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1446,7 +1444,7 @@ fn op_truncate(
|
|||
}
|
||||
|
||||
fn op_listen(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1508,7 +1506,7 @@ fn new_conn(cmd_id: u32, tcp_stream: TcpStream) -> OpResult {
|
|||
}
|
||||
|
||||
fn op_accept(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1534,7 +1532,7 @@ fn op_accept(
|
|||
}
|
||||
|
||||
fn op_dial(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1560,7 +1558,7 @@ fn op_dial(
|
|||
}
|
||||
|
||||
fn op_metrics(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1584,7 +1582,7 @@ fn op_metrics(
|
|||
}
|
||||
|
||||
fn op_resources(
|
||||
_state: &Arc<IsolateState>,
|
||||
_state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1636,7 +1634,7 @@ fn subprocess_stdio_map(v: msg::ProcessStdio) -> std::process::Stdio {
|
|||
}
|
||||
|
||||
fn op_run(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1709,7 +1707,7 @@ fn op_run(
|
|||
}
|
||||
|
||||
fn op_run_status(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1765,7 +1763,7 @@ fn op_run_status(
|
|||
}
|
||||
|
||||
struct GetMessageFuture {
|
||||
pub state: Arc<IsolateState>,
|
||||
pub state: ThreadSafeState,
|
||||
}
|
||||
|
||||
impl Future for GetMessageFuture {
|
||||
|
@ -1782,7 +1780,7 @@ impl Future for GetMessageFuture {
|
|||
|
||||
/// Get message from host as guest worker
|
||||
fn op_worker_get_message(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1817,7 +1815,7 @@ fn op_worker_get_message(
|
|||
|
||||
/// Post message to host as guest worker
|
||||
fn op_worker_post_message(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1847,7 +1845,7 @@ fn op_worker_post_message(
|
|||
|
||||
/// Create worker as the host
|
||||
fn op_create_worker(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1859,16 +1857,15 @@ fn op_create_worker(
|
|||
Box::new(futures::future::result(move || -> OpResult {
|
||||
let parent_state = state.clone();
|
||||
|
||||
let child_state = Arc::new(IsolateState::new(
|
||||
let child_state = ThreadSafeState::new(
|
||||
parent_state.flags.clone(),
|
||||
parent_state.argv.clone(),
|
||||
));
|
||||
);
|
||||
let rid = child_state.resource.rid;
|
||||
let behavior = CliBehavior::new(child_state);
|
||||
let name = format!("USER-WORKER-{}", specifier);
|
||||
|
||||
let mut worker =
|
||||
Worker::new(name, startup_data::deno_isolate_init(), behavior);
|
||||
Worker::new(name, startup_data::deno_isolate_init(), child_state);
|
||||
js_check(worker.execute("denoMain()"));
|
||||
js_check(worker.execute("workerMain()"));
|
||||
let result = worker.execute_mod(specifier, false);
|
||||
|
@ -1899,7 +1896,7 @@ fn op_create_worker(
|
|||
|
||||
/// Return when the worker closes
|
||||
fn op_host_get_worker_closed(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1930,7 +1927,7 @@ fn op_host_get_worker_closed(
|
|||
|
||||
/// Get message from guest worker as host
|
||||
fn op_host_get_message(
|
||||
_state: &Arc<IsolateState>,
|
||||
_state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
@ -1964,7 +1961,7 @@ fn op_host_get_message(
|
|||
|
||||
/// Post message to guest worker as host
|
||||
fn op_host_post_message(
|
||||
_state: &Arc<IsolateState>,
|
||||
_state: &ThreadSafeState,
|
||||
base: &msg::Base<'_>,
|
||||
data: deno_buf,
|
||||
) -> Box<OpWithError> {
|
||||
|
|
|
@ -13,8 +13,8 @@ use crate::errors::bad_resource;
|
|||
use crate::errors::DenoError;
|
||||
use crate::errors::DenoResult;
|
||||
use crate::http_body::HttpBody;
|
||||
use crate::isolate_state::WorkerChannels;
|
||||
use crate::repl::Repl;
|
||||
use crate::state::WorkerChannels;
|
||||
|
||||
use deno::Buf;
|
||||
|
||||
|
|
|
@ -4,16 +4,22 @@ use crate::errors::DenoResult;
|
|||
use crate::flags;
|
||||
use crate::global_timer::GlobalTimer;
|
||||
use crate::modules::Modules;
|
||||
use crate::ops;
|
||||
use crate::permissions::DenoPermissions;
|
||||
use crate::resources;
|
||||
use crate::resources::ResourceId;
|
||||
use crate::worker::Worker;
|
||||
use deno::deno_buf;
|
||||
use deno::Buf;
|
||||
use deno::Dispatch;
|
||||
use deno::Op;
|
||||
use futures::future::Shared;
|
||||
use std;
|
||||
use std::collections::HashMap;
|
||||
use std::env;
|
||||
use std::ops::Deref;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use std::time::Instant;
|
||||
use tokio::sync::mpsc as async_mpsc;
|
||||
|
@ -34,12 +40,15 @@ pub struct Metrics {
|
|||
pub resolve_count: AtomicUsize,
|
||||
}
|
||||
|
||||
// Isolate cannot be passed between threads but IsolateState can.
|
||||
// IsolateState satisfies Send and Sync.
|
||||
// Wrap State so that it can implement Dispatch.
|
||||
pub struct ThreadSafeState(Arc<State>);
|
||||
|
||||
// Isolate cannot be passed between threads but ThreadSafeState can.
|
||||
// ThreadSafeState satisfies Send and Sync.
|
||||
// So any state that needs to be accessed outside the main V8 thread should be
|
||||
// inside IsolateState.
|
||||
// inside ThreadSafeState.
|
||||
#[cfg_attr(feature = "cargo-clippy", allow(stutter))]
|
||||
pub struct IsolateState {
|
||||
pub struct State {
|
||||
pub dir: deno_dir::DenoDir,
|
||||
pub argv: Vec<String>,
|
||||
pub permissions: DenoPermissions,
|
||||
|
@ -53,7 +62,30 @@ pub struct IsolateState {
|
|||
pub resource: resources::Resource,
|
||||
}
|
||||
|
||||
impl IsolateState {
|
||||
impl Clone for ThreadSafeState {
|
||||
fn clone(&self) -> Self {
|
||||
ThreadSafeState(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for ThreadSafeState {
|
||||
type Target = Arc<State>;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Dispatch for ThreadSafeState {
|
||||
fn dispatch(
|
||||
&mut self,
|
||||
control: &[u8],
|
||||
zero_copy: deno_buf,
|
||||
) -> (bool, Box<Op>) {
|
||||
ops::dispatch_all(self, control, zero_copy, ops::op_selector_std)
|
||||
}
|
||||
}
|
||||
|
||||
impl ThreadSafeState {
|
||||
pub fn new(flags: flags::DenoFlags, argv_rest: Vec<String>) -> Self {
|
||||
let custom_root = env::var("DENO_DIR").map(|s| s.into()).ok();
|
||||
|
||||
|
@ -63,7 +95,7 @@ impl IsolateState {
|
|||
let external_channels = (worker_in_tx, worker_out_rx);
|
||||
let resource = resources::add_worker(external_channels);
|
||||
|
||||
Self {
|
||||
ThreadSafeState(Arc::new(State {
|
||||
dir: deno_dir::DenoDir::new(custom_root).unwrap(),
|
||||
argv: argv_rest,
|
||||
permissions: DenoPermissions::from_flags(&flags),
|
||||
|
@ -75,7 +107,7 @@ impl IsolateState {
|
|||
workers: Mutex::new(UserWorkerTable::new()),
|
||||
start_time: Instant::now(),
|
||||
resource,
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
/// Read main module from argv
|
||||
|
@ -121,11 +153,11 @@ impl IsolateState {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn mock() -> IsolateState {
|
||||
pub fn mock() -> ThreadSafeState {
|
||||
let argv = vec![String::from("./deno"), String::from("hello.js")];
|
||||
// For debugging: argv.push_back(String::from("-D"));
|
||||
let (flags, rest_argv) = flags::set_flags(argv).unwrap();
|
||||
IsolateState::new(flags, rest_argv)
|
||||
ThreadSafeState::new(flags, rest_argv)
|
||||
}
|
||||
|
||||
pub fn metrics_op_dispatched(
|
||||
|
@ -152,3 +184,9 @@ impl IsolateState {
|
|||
.fetch_add(bytes_received, Ordering::SeqCst);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn thread_safe() {
|
||||
fn f<S: Send + Sync>(_: S) {}
|
||||
f(ThreadSafeState::mock());
|
||||
}
|
|
@ -1,13 +1,12 @@
|
|||
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
|
||||
use crate::cli_behavior::CliBehavior;
|
||||
use crate::compiler::compile_async;
|
||||
use crate::compiler::ModuleMetaData;
|
||||
use crate::errors::DenoError;
|
||||
use crate::errors::RustOrJsError;
|
||||
use crate::isolate_state::IsolateState;
|
||||
use crate::js_errors;
|
||||
use crate::js_errors::JSErrorColor;
|
||||
use crate::msg;
|
||||
use crate::state::ThreadSafeState;
|
||||
use crate::tokio_util;
|
||||
use deno;
|
||||
use deno::deno_mod;
|
||||
|
@ -17,24 +16,23 @@ use futures::future::Either;
|
|||
use futures::Async;
|
||||
use futures::Future;
|
||||
use std::sync::atomic::Ordering;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Wraps deno::Isolate to provide source maps, ops for the CLI, and
|
||||
/// high-level module loading
|
||||
pub struct Worker {
|
||||
inner: deno::Isolate<CliBehavior>,
|
||||
state: Arc<IsolateState>,
|
||||
inner: deno::Isolate<ThreadSafeState>,
|
||||
state: ThreadSafeState,
|
||||
}
|
||||
|
||||
impl Worker {
|
||||
pub fn new(
|
||||
_name: String,
|
||||
startup_data: StartupData,
|
||||
behavior: CliBehavior,
|
||||
state: ThreadSafeState,
|
||||
) -> Worker {
|
||||
let state = behavior.state.clone();
|
||||
let state_ = state.clone();
|
||||
Self {
|
||||
inner: deno::Isolate::new(startup_data, behavior),
|
||||
inner: deno::Isolate::new(startup_data, state_),
|
||||
state,
|
||||
}
|
||||
}
|
||||
|
@ -107,7 +105,7 @@ impl Worker {
|
|||
js_filename: &str,
|
||||
is_prefetch: bool,
|
||||
) -> Result<(), RustOrJsError> {
|
||||
// TODO move isolate_state::execute_mod impl here.
|
||||
// TODO move state::execute_mod impl here.
|
||||
self
|
||||
.execute_mod_inner(js_filename, is_prefetch)
|
||||
.map_err(|err| match err {
|
||||
|
@ -204,7 +202,7 @@ impl Future for Worker {
|
|||
}
|
||||
|
||||
fn fetch_module_meta_data_and_maybe_compile_async(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
specifier: &str,
|
||||
referrer: &str,
|
||||
) -> impl Future<Item = ModuleMetaData, Error = DenoError> {
|
||||
|
@ -239,7 +237,7 @@ fn fetch_module_meta_data_and_maybe_compile_async(
|
|||
}
|
||||
|
||||
fn fetch_module_meta_data_and_maybe_compile(
|
||||
state: &Arc<IsolateState>,
|
||||
state: &ThreadSafeState,
|
||||
specifier: &str,
|
||||
referrer: &str,
|
||||
) -> Result<ModuleMetaData, DenoError> {
|
||||
|
@ -251,11 +249,10 @@ fn fetch_module_meta_data_and_maybe_compile(
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::cli_behavior::CliBehavior;
|
||||
use crate::flags;
|
||||
use crate::isolate_state::IsolateState;
|
||||
use crate::resources;
|
||||
use crate::startup_data;
|
||||
use crate::state::ThreadSafeState;
|
||||
use crate::tokio_util;
|
||||
use deno::js_check;
|
||||
use futures::future::lazy;
|
||||
|
@ -272,11 +269,11 @@ mod tests {
|
|||
let argv = vec![String::from("./deno"), filename.clone()];
|
||||
let (flags, rest_argv) = flags::set_flags(argv).unwrap();
|
||||
|
||||
let state = Arc::new(IsolateState::new(flags, rest_argv));
|
||||
let state = ThreadSafeState::new(flags, rest_argv);
|
||||
let state_ = state.clone();
|
||||
tokio_util::run(lazy(move || {
|
||||
let cli = CliBehavior::new(state.clone());
|
||||
let mut worker = Worker::new("TEST".to_string(), StartupData::None, cli);
|
||||
let mut worker =
|
||||
Worker::new("TEST".to_string(), StartupData::None, state);
|
||||
if let Err(err) = worker.execute_mod(&filename, false) {
|
||||
eprintln!("execute_mod err {:?}", err);
|
||||
}
|
||||
|
@ -295,11 +292,11 @@ mod tests {
|
|||
let argv = vec![String::from("./deno"), filename.clone()];
|
||||
let (flags, rest_argv) = flags::set_flags(argv).unwrap();
|
||||
|
||||
let state = Arc::new(IsolateState::new(flags, rest_argv));
|
||||
let state = ThreadSafeState::new(flags, rest_argv);
|
||||
let state_ = state.clone();
|
||||
tokio_util::run(lazy(move || {
|
||||
let cli = CliBehavior::new(state.clone());
|
||||
let mut worker = Worker::new("TEST".to_string(), StartupData::None, cli);
|
||||
let mut worker =
|
||||
Worker::new("TEST".to_string(), StartupData::None, state);
|
||||
if let Err(err) = worker.execute_mod(&filename, false) {
|
||||
eprintln!("execute_mod err {:?}", err);
|
||||
}
|
||||
|
@ -311,10 +308,9 @@ mod tests {
|
|||
}
|
||||
|
||||
fn create_test_worker() -> Worker {
|
||||
let state = Arc::new(IsolateState::mock());
|
||||
let cli = CliBehavior::new(state.clone());
|
||||
let state = ThreadSafeState::mock();
|
||||
let mut worker =
|
||||
Worker::new("TEST".to_string(), startup_data::deno_isolate_init(), cli);
|
||||
Worker::new("TEST".to_string(), startup_data::deno_isolate_init(), state);
|
||||
js_check(worker.execute("denoMain()"));
|
||||
js_check(worker.execute("workerMain()"));
|
||||
worker
|
||||
|
|
|
@ -4,7 +4,7 @@ This Rust crate contains the essential V8 bindings for Deno's command-line
|
|||
interface (Deno CLI). The main abstraction here is the Isolate which proivdes a
|
||||
way to execute JavaScript. The Isolate is modeled as a
|
||||
`Future<Item=(), Error=JSError>` which completes once all of its ops have
|
||||
completed. The user must define what an Op is by implementing the `Behavior`
|
||||
completed. The user must define what an Op is by implementing the `Dispatch`
|
||||
trait, and by doing so define any "built-in" functionality that would be
|
||||
provided by the VM. Ops are triggered by `Deno.core.dispatch()`.
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ pub type HttpBenchOp = dyn Future<Item = i32, Error = std::io::Error> + Send;
|
|||
|
||||
struct HttpBench();
|
||||
|
||||
impl Behavior for HttpBench {
|
||||
impl Dispatch for HttpBench {
|
||||
fn dispatch(
|
||||
&mut self,
|
||||
control: &[u8],
|
||||
|
|
114
core/isolate.rs
114
core/isolate.rs
|
@ -66,10 +66,8 @@ pub enum StartupData<'a> {
|
|||
None,
|
||||
}
|
||||
|
||||
/// Defines the behavior of an Isolate.
|
||||
// TODO(ry) Now that Behavior only has the dispatch method, it should be renamed
|
||||
// to Dispatcher.
|
||||
pub trait Behavior {
|
||||
/// Defines the how Deno.core.dispatch() acts.
|
||||
pub trait Dispatch {
|
||||
/// Called whenever Deno.core.dispatch() is called in JavaScript. zero_copy_buf
|
||||
/// corresponds to the second argument of Deno.core.dispatch().
|
||||
fn dispatch(
|
||||
|
@ -85,21 +83,21 @@ pub trait Behavior {
|
|||
/// pending ops have completed.
|
||||
///
|
||||
/// Ops are created in JavaScript by calling Deno.core.dispatch(), and in Rust
|
||||
/// by implementing deno::Behavior::dispatch. An Op corresponds exactly to a
|
||||
/// by implementing deno::Dispatch::dispatch. An Op corresponds exactly to a
|
||||
/// Promise in JavaScript.
|
||||
pub struct Isolate<B: Behavior> {
|
||||
pub struct Isolate<B: Dispatch> {
|
||||
libdeno_isolate: *const libdeno::isolate,
|
||||
shared_libdeno_isolate: Arc<Mutex<Option<*const libdeno::isolate>>>,
|
||||
behavior: B,
|
||||
dispatcher: B,
|
||||
needs_init: bool,
|
||||
shared: SharedQueue,
|
||||
pending_ops: VecDeque<PendingOp>,
|
||||
polled_recently: bool,
|
||||
}
|
||||
|
||||
unsafe impl<B: Behavior> Send for Isolate<B> {}
|
||||
unsafe impl<B: Dispatch> Send for Isolate<B> {}
|
||||
|
||||
impl<B: Behavior> Drop for Isolate<B> {
|
||||
impl<B: Dispatch> Drop for Isolate<B> {
|
||||
fn drop(&mut self) {
|
||||
// remove shared_libdeno_isolate reference
|
||||
*self.shared_libdeno_isolate.lock().unwrap() = None;
|
||||
|
@ -110,10 +108,10 @@ impl<B: Behavior> Drop for Isolate<B> {
|
|||
|
||||
static DENO_INIT: Once = ONCE_INIT;
|
||||
|
||||
impl<B: Behavior> Isolate<B> {
|
||||
impl<B: Dispatch> Isolate<B> {
|
||||
/// startup_data defines the snapshot or script used at startup to initalize
|
||||
/// the isolate.
|
||||
pub fn new(startup_data: StartupData, behavior: B) -> Self {
|
||||
pub fn new(startup_data: StartupData, dispatcher: B) -> Self {
|
||||
DENO_INIT.call_once(|| {
|
||||
unsafe { libdeno::deno_init() };
|
||||
});
|
||||
|
@ -141,7 +139,7 @@ impl<B: Behavior> Isolate<B> {
|
|||
let mut core_isolate = Self {
|
||||
libdeno_isolate,
|
||||
shared_libdeno_isolate: Arc::new(Mutex::new(Some(libdeno_isolate))),
|
||||
behavior,
|
||||
dispatcher,
|
||||
shared,
|
||||
needs_init,
|
||||
pending_ops: VecDeque::new(),
|
||||
|
@ -186,11 +184,11 @@ impl<B: Behavior> Isolate<B> {
|
|||
let (is_sync, op) = if control_argv0.len() > 0 {
|
||||
// The user called Deno.core.send(control)
|
||||
isolate
|
||||
.behavior
|
||||
.dispatcher
|
||||
.dispatch(control_argv0.as_ref(), zero_copy_buf)
|
||||
} else if let Some(c) = control_shared {
|
||||
// The user called Deno.sharedQueue.push(control)
|
||||
isolate.behavior.dispatch(&c, zero_copy_buf)
|
||||
isolate.dispatcher.dispatch(&c, zero_copy_buf)
|
||||
} else {
|
||||
// The sharedQueue is empty. The shouldn't happen usually, but it's also
|
||||
// not technically a failure.
|
||||
|
@ -366,7 +364,7 @@ impl<'a> ResolveContext<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<B: Behavior> Isolate<B> {
|
||||
impl<B: Dispatch> Isolate<B> {
|
||||
pub fn mod_instantiate(
|
||||
&mut self,
|
||||
id: deno_mod,
|
||||
|
@ -432,7 +430,7 @@ impl Drop for LockerScope {
|
|||
}
|
||||
}
|
||||
|
||||
impl<B: Behavior> Future for Isolate<B> {
|
||||
impl<B: Dispatch> Future for Isolate<B> {
|
||||
type Item = ();
|
||||
type Error = JSError;
|
||||
|
||||
|
@ -540,7 +538,7 @@ pub mod tests {
|
|||
use super::*;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
pub enum TestBehaviorMode {
|
||||
pub enum TestDispatchMode {
|
||||
AsyncImmediate,
|
||||
OverflowReqSync,
|
||||
OverflowResSync,
|
||||
|
@ -548,16 +546,16 @@ pub mod tests {
|
|||
OverflowResAsync,
|
||||
}
|
||||
|
||||
pub struct TestBehavior {
|
||||
pub struct TestDispatch {
|
||||
pub dispatch_count: usize,
|
||||
mode: TestBehaviorMode,
|
||||
mode: TestDispatchMode,
|
||||
}
|
||||
|
||||
impl TestBehavior {
|
||||
pub fn setup(mode: TestBehaviorMode) -> Isolate<Self> {
|
||||
impl TestDispatch {
|
||||
pub fn setup(mode: TestDispatchMode) -> Isolate<Self> {
|
||||
let mut isolate = Isolate::new(
|
||||
StartupData::None,
|
||||
TestBehavior {
|
||||
TestDispatch {
|
||||
dispatch_count: 0,
|
||||
mode,
|
||||
},
|
||||
|
@ -572,12 +570,12 @@ pub mod tests {
|
|||
}
|
||||
"#,
|
||||
));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 0);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 0);
|
||||
isolate
|
||||
}
|
||||
}
|
||||
|
||||
impl Behavior for TestBehavior {
|
||||
impl Dispatch for TestDispatch {
|
||||
fn dispatch(
|
||||
&mut self,
|
||||
control: &[u8],
|
||||
|
@ -585,18 +583,18 @@ pub mod tests {
|
|||
) -> (bool, Box<Op>) {
|
||||
self.dispatch_count += 1;
|
||||
match self.mode {
|
||||
TestBehaviorMode::AsyncImmediate => {
|
||||
TestDispatchMode::AsyncImmediate => {
|
||||
assert_eq!(control.len(), 1);
|
||||
assert_eq!(control[0], 42);
|
||||
let buf = vec![43u8].into_boxed_slice();
|
||||
(false, Box::new(futures::future::ok(buf)))
|
||||
}
|
||||
TestBehaviorMode::OverflowReqSync => {
|
||||
TestDispatchMode::OverflowReqSync => {
|
||||
assert_eq!(control.len(), 100 * 1024 * 1024);
|
||||
let buf = vec![43u8].into_boxed_slice();
|
||||
(true, Box::new(futures::future::ok(buf)))
|
||||
}
|
||||
TestBehaviorMode::OverflowResSync => {
|
||||
TestDispatchMode::OverflowResSync => {
|
||||
assert_eq!(control.len(), 1);
|
||||
assert_eq!(control[0], 42);
|
||||
let mut vec = Vec::<u8>::new();
|
||||
|
@ -605,12 +603,12 @@ pub mod tests {
|
|||
let buf = vec.into_boxed_slice();
|
||||
(true, Box::new(futures::future::ok(buf)))
|
||||
}
|
||||
TestBehaviorMode::OverflowReqAsync => {
|
||||
TestDispatchMode::OverflowReqAsync => {
|
||||
assert_eq!(control.len(), 100 * 1024 * 1024);
|
||||
let buf = vec![43u8].into_boxed_slice();
|
||||
(false, Box::new(futures::future::ok(buf)))
|
||||
}
|
||||
TestBehaviorMode::OverflowResAsync => {
|
||||
TestDispatchMode::OverflowResAsync => {
|
||||
assert_eq!(control.len(), 1);
|
||||
assert_eq!(control[0], 42);
|
||||
let mut vec = Vec::<u8>::new();
|
||||
|
@ -625,7 +623,7 @@ pub mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_dispatch() {
|
||||
let mut isolate = TestBehavior::setup(TestBehaviorMode::AsyncImmediate);
|
||||
let mut isolate = TestDispatch::setup(TestDispatchMode::AsyncImmediate);
|
||||
js_check(isolate.execute(
|
||||
"filename.js",
|
||||
r#"
|
||||
|
@ -637,12 +635,12 @@ pub mod tests {
|
|||
main();
|
||||
"#,
|
||||
));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 2);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_mods() {
|
||||
let mut isolate = TestBehavior::setup(TestBehaviorMode::AsyncImmediate);
|
||||
let mut isolate = TestDispatch::setup(TestDispatchMode::AsyncImmediate);
|
||||
let mod_a = isolate
|
||||
.mod_new(
|
||||
true,
|
||||
|
@ -654,7 +652,7 @@ pub mod tests {
|
|||
Deno.core.send(control);
|
||||
"#,
|
||||
).unwrap();
|
||||
assert_eq!(isolate.behavior.dispatch_count, 0);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 0);
|
||||
|
||||
let imports = isolate.mod_get_imports(mod_a);
|
||||
assert_eq!(imports, vec!["b.js".to_string()]);
|
||||
|
@ -675,21 +673,21 @@ pub mod tests {
|
|||
};
|
||||
|
||||
js_check(isolate.mod_instantiate(mod_b, &mut resolve));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 0);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 0);
|
||||
assert_eq!(resolve_count.load(Ordering::SeqCst), 0);
|
||||
|
||||
js_check(isolate.mod_instantiate(mod_a, &mut resolve));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 0);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 0);
|
||||
assert_eq!(resolve_count.load(Ordering::SeqCst), 1);
|
||||
|
||||
js_check(isolate.mod_evaluate(mod_a));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 1);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 1);
|
||||
assert_eq!(resolve_count.load(Ordering::SeqCst), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_poll_async_immediate_ops() {
|
||||
let mut isolate = TestBehavior::setup(TestBehaviorMode::AsyncImmediate);
|
||||
let mut isolate = TestDispatch::setup(TestDispatchMode::AsyncImmediate);
|
||||
|
||||
js_check(isolate.execute(
|
||||
"setup2.js",
|
||||
|
@ -700,7 +698,7 @@ pub mod tests {
|
|||
});
|
||||
"#,
|
||||
));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 0);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 0);
|
||||
js_check(isolate.execute(
|
||||
"check1.js",
|
||||
r#"
|
||||
|
@ -710,9 +708,9 @@ pub mod tests {
|
|||
assert(nrecv == 0);
|
||||
"#,
|
||||
));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 1);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 1);
|
||||
assert_eq!(Ok(Async::Ready(())), isolate.poll());
|
||||
assert_eq!(isolate.behavior.dispatch_count, 1);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 1);
|
||||
js_check(isolate.execute(
|
||||
"check2.js",
|
||||
r#"
|
||||
|
@ -721,17 +719,17 @@ pub mod tests {
|
|||
assert(nrecv == 1);
|
||||
"#,
|
||||
));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 2);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 2);
|
||||
assert_eq!(Ok(Async::Ready(())), isolate.poll());
|
||||
js_check(isolate.execute("check3.js", "assert(nrecv == 2)"));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 2);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 2);
|
||||
// We are idle, so the next poll should be the last.
|
||||
assert_eq!(Ok(Async::Ready(())), isolate.poll());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_shared() {
|
||||
let mut isolate = TestBehavior::setup(TestBehaviorMode::AsyncImmediate);
|
||||
let mut isolate = TestDispatch::setup(TestDispatchMode::AsyncImmediate);
|
||||
|
||||
js_check(isolate.execute(
|
||||
"setup2.js",
|
||||
|
@ -744,7 +742,7 @@ pub mod tests {
|
|||
});
|
||||
"#,
|
||||
));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 0);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 0);
|
||||
|
||||
js_check(isolate.execute(
|
||||
"send1.js",
|
||||
|
@ -759,7 +757,7 @@ pub mod tests {
|
|||
assert(nrecv === 0);
|
||||
"#,
|
||||
));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 2);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 2);
|
||||
assert_eq!(Ok(Async::Ready(())), isolate.poll());
|
||||
|
||||
js_check(isolate.execute("send1.js", "assert(nrecv === 2);"));
|
||||
|
@ -770,7 +768,7 @@ pub mod tests {
|
|||
let (tx, rx) = std::sync::mpsc::channel::<bool>();
|
||||
let tx_clone = tx.clone();
|
||||
|
||||
let mut isolate = TestBehavior::setup(TestBehaviorMode::AsyncImmediate);
|
||||
let mut isolate = TestDispatch::setup(TestDispatchMode::AsyncImmediate);
|
||||
let shared = isolate.shared_isolate_handle();
|
||||
|
||||
let t1 = std::thread::spawn(move || {
|
||||
|
@ -827,7 +825,7 @@ pub mod tests {
|
|||
fn dangling_shared_isolate() {
|
||||
let shared = {
|
||||
// isolate is dropped at the end of this block
|
||||
let mut isolate = TestBehavior::setup(TestBehaviorMode::AsyncImmediate);
|
||||
let mut isolate = TestDispatch::setup(TestDispatchMode::AsyncImmediate);
|
||||
isolate.shared_isolate_handle()
|
||||
};
|
||||
|
||||
|
@ -837,7 +835,7 @@ pub mod tests {
|
|||
|
||||
#[test]
|
||||
fn overflow_req_sync() {
|
||||
let mut isolate = TestBehavior::setup(TestBehaviorMode::OverflowReqSync);
|
||||
let mut isolate = TestDispatch::setup(TestDispatchMode::OverflowReqSync);
|
||||
js_check(isolate.execute(
|
||||
"overflow_req_sync.js",
|
||||
r#"
|
||||
|
@ -852,14 +850,14 @@ pub mod tests {
|
|||
assert(asyncRecv == 0);
|
||||
"#,
|
||||
));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 1);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overflow_res_sync() {
|
||||
// TODO(ry) This test is quite slow due to memcpy-ing 100MB into JS. We
|
||||
// should optimize this.
|
||||
let mut isolate = TestBehavior::setup(TestBehaviorMode::OverflowResSync);
|
||||
let mut isolate = TestDispatch::setup(TestDispatchMode::OverflowResSync);
|
||||
js_check(isolate.execute(
|
||||
"overflow_res_sync.js",
|
||||
r#"
|
||||
|
@ -874,12 +872,12 @@ pub mod tests {
|
|||
assert(asyncRecv == 0);
|
||||
"#,
|
||||
));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 1);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn overflow_req_async() {
|
||||
let mut isolate = TestBehavior::setup(TestBehaviorMode::OverflowReqAsync);
|
||||
let mut isolate = TestDispatch::setup(TestDispatchMode::OverflowReqAsync);
|
||||
js_check(isolate.execute(
|
||||
"overflow_req_async.js",
|
||||
r#"
|
||||
|
@ -897,7 +895,7 @@ pub mod tests {
|
|||
assert(asyncRecv == 0);
|
||||
"#,
|
||||
));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 1);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 1);
|
||||
assert_eq!(Ok(Async::Ready(())), isolate.poll());
|
||||
js_check(isolate.execute("check.js", "assert(asyncRecv == 1);"));
|
||||
}
|
||||
|
@ -906,7 +904,7 @@ pub mod tests {
|
|||
fn overflow_res_async() {
|
||||
// TODO(ry) This test is quite slow due to memcpy-ing 100MB into JS. We
|
||||
// should optimize this.
|
||||
let mut isolate = TestBehavior::setup(TestBehaviorMode::OverflowResAsync);
|
||||
let mut isolate = TestDispatch::setup(TestDispatchMode::OverflowResAsync);
|
||||
js_check(isolate.execute(
|
||||
"overflow_res_async.js",
|
||||
r#"
|
||||
|
@ -923,7 +921,7 @@ pub mod tests {
|
|||
assert(asyncRecv == 0);
|
||||
"#,
|
||||
));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 1);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 1);
|
||||
assert_eq!(Ok(Async::Ready(())), isolate.poll());
|
||||
js_check(isolate.execute("check.js", "assert(asyncRecv == 1);"));
|
||||
}
|
||||
|
@ -932,7 +930,7 @@ pub mod tests {
|
|||
fn overflow_res_multiple_dispatch_async() {
|
||||
// TODO(ry) This test is quite slow due to memcpy-ing 100MB into JS. We
|
||||
// should optimize this.
|
||||
let mut isolate = TestBehavior::setup(TestBehaviorMode::OverflowResAsync);
|
||||
let mut isolate = TestDispatch::setup(TestDispatchMode::OverflowResAsync);
|
||||
js_check(isolate.execute(
|
||||
"overflow_res_multiple_dispatch_async.js",
|
||||
r#"
|
||||
|
@ -952,14 +950,14 @@ pub mod tests {
|
|||
Deno.core.dispatch(control);
|
||||
"#,
|
||||
));
|
||||
assert_eq!(isolate.behavior.dispatch_count, 2);
|
||||
assert_eq!(isolate.dispatcher.dispatch_count, 2);
|
||||
assert_eq!(Ok(Async::Ready(())), isolate.poll());
|
||||
js_check(isolate.execute("check.js", "assert(asyncRecv == 2);"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_js() {
|
||||
let mut isolate = TestBehavior::setup(TestBehaviorMode::AsyncImmediate);
|
||||
let mut isolate = TestDispatch::setup(TestDispatchMode::AsyncImmediate);
|
||||
js_check(
|
||||
isolate
|
||||
.execute("shared_queue_test.js", include_str!("shared_queue_test.js")),
|
||||
|
|
|
@ -18,7 +18,7 @@ use std::collections::HashMap;
|
|||
pub type SourceCodeFuture<E> = dyn Future<Item = String, Error = E> + Send;
|
||||
|
||||
pub trait Loader {
|
||||
type Behavior: crate::isolate::Behavior;
|
||||
type Dispatch: crate::isolate::Dispatch;
|
||||
type Error: std::error::Error + 'static;
|
||||
|
||||
/// Returns an absolute URL.
|
||||
|
@ -32,9 +32,9 @@ pub trait Loader {
|
|||
|
||||
fn isolate_and_modules<'a: 'b + 'c, 'b, 'c>(
|
||||
&'a mut self,
|
||||
) -> (&'b mut Isolate<Self::Behavior>, &'c mut Modules);
|
||||
) -> (&'b mut Isolate<Self::Dispatch>, &'c mut Modules);
|
||||
|
||||
fn isolate<'a: 'b, 'b>(&'a mut self) -> &'b mut Isolate<Self::Behavior> {
|
||||
fn isolate<'a: 'b, 'b>(&'a mut self) -> &'b mut Isolate<Self::Dispatch> {
|
||||
let (isolate, _) = self.isolate_and_modules();
|
||||
isolate
|
||||
}
|
||||
|
@ -262,14 +262,14 @@ mod tests {
|
|||
|
||||
struct MockLoader {
|
||||
pub loads: Vec<String>,
|
||||
pub isolate: Isolate<TestBehavior>,
|
||||
pub isolate: Isolate<TestDispatch>,
|
||||
pub modules: Modules,
|
||||
}
|
||||
|
||||
impl MockLoader {
|
||||
fn new() -> Self {
|
||||
let modules = Modules::new();
|
||||
let isolate = TestBehavior::setup(TestBehaviorMode::AsyncImmediate);
|
||||
let isolate = TestDispatch::setup(TestDispatchMode::AsyncImmediate);
|
||||
Self {
|
||||
loads: Vec::new(),
|
||||
isolate,
|
||||
|
@ -279,7 +279,7 @@ mod tests {
|
|||
}
|
||||
|
||||
impl Loader for MockLoader {
|
||||
type Behavior = TestBehavior;
|
||||
type Dispatch = TestDispatch;
|
||||
type Error = std::io::Error;
|
||||
|
||||
fn resolve(specifier: &str, _referrer: &str) -> String {
|
||||
|
@ -304,7 +304,7 @@ mod tests {
|
|||
|
||||
fn isolate_and_modules<'a: 'b + 'c, 'b, 'c>(
|
||||
&'a mut self,
|
||||
) -> (&'b mut Isolate<Self::Behavior>, &'c mut Modules) {
|
||||
) -> (&'b mut Isolate<Self::Dispatch>, &'c mut Modules) {
|
||||
(&mut self.isolate, &mut self.modules)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue