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