Make Rc/Arc wrapper around State/GlobalState visible (#7104)

This commit is contained in:
Bert Belder 2020-08-18 18:30:13 +02:00
parent de1007fc6a
commit 27f4aeb924
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
33 changed files with 368 additions and 430 deletions

View file

@ -121,7 +121,7 @@ impl SourceFileFetcher {
cache_blocklist: Vec<String>,
no_remote: bool,
cached_only: bool,
ca_file: Option<String>,
ca_file: Option<&str>,
) -> Result<Self, ErrBox> {
let file_fetcher = Self {
http_cache,

View file

@ -17,20 +17,15 @@ use crate::tsc::TsCompiler;
use deno_core::ErrBox;
use deno_core::ModuleSpecifier;
use std::env;
use std::ops::Deref;
use std::sync::atomic::AtomicUsize;
use std::sync::Arc;
use std::sync::Mutex;
use tokio::sync::Mutex as AsyncMutex;
/// Holds state of the program and can be accessed by V8 isolate.
#[derive(Clone)]
pub struct GlobalState(Arc<GlobalStateInner>);
/// This structure represents state of single "deno" program.
///
/// It is shared by all created workers (thus V8 isolates).
pub struct GlobalStateInner {
pub struct GlobalState {
/// Flags parsed from `argv` contents.
pub flags: flags::Flags,
/// Permissions parsed from `flags`.
@ -44,23 +39,13 @@ pub struct GlobalStateInner {
compile_lock: AsyncMutex<()>,
}
impl Deref for GlobalState {
type Target = GlobalStateInner;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl GlobalState {
pub fn new(flags: flags::Flags) -> Result<Self, ErrBox> {
pub fn new(flags: flags::Flags) -> Result<Arc<Self>, ErrBox> {
let custom_root = env::var("DENO_DIR").map(String::into).ok();
let dir = deno_dir::DenoDir::new(custom_root)?;
let deps_cache_location = dir.root.join("deps");
let http_cache = http_cache::HttpCache::new(&deps_cache_location);
let ca_file = flags
.ca_file
.clone()
.or_else(|| env::var("DENO_CERT").map(String::into).ok());
let ca_file = flags.ca_file.clone().or_else(|| env::var("DENO_CERT").ok());
let file_fetcher = SourceFileFetcher::new(
http_cache,
@ -68,7 +53,7 @@ impl GlobalState {
flags.cache_blocklist.clone(),
flags.no_remote,
flags.cached_only,
ca_file,
ca_file.as_deref(),
)?;
let ts_compiler = TsCompiler::new(
@ -95,7 +80,7 @@ impl GlobalState {
}
};
let inner = GlobalStateInner {
let global_state = GlobalState {
dir,
permissions: Permissions::from_flags(&flags),
flags,
@ -106,7 +91,7 @@ impl GlobalState {
compiler_starts: AtomicUsize::new(0),
compile_lock: AsyncMutex::new(()),
};
Ok(GlobalState(Arc::new(inner)))
Ok(Arc::new(global_state))
}
/// This function is called when new module load is
@ -114,7 +99,7 @@ impl GlobalState {
/// all dependencies and if it is required then also perform TS typecheck
/// and traspilation.
pub async fn prepare_module_load(
&self,
self: &Arc<Self>,
module_specifier: ModuleSpecifier,
maybe_referrer: Option<ModuleSpecifier>,
target_lib: TargetLib,
@ -178,14 +163,7 @@ impl GlobalState {
} else {
self
.ts_compiler
.compile(
self.clone(),
&out,
target_lib,
permissions,
module_graph,
allow_js,
)
.compile(self, &out, target_lib, permissions, module_graph, allow_js)
.await?;
}
}
@ -210,7 +188,6 @@ impl GlobalState {
module_specifier: ModuleSpecifier,
_maybe_referrer: Option<ModuleSpecifier>,
) -> Result<CompiledModule, ErrBox> {
let state1 = self.clone();
let module_specifier = module_specifier.clone();
let out = self
@ -232,7 +209,7 @@ impl GlobalState {
};
let compiled_module = if was_compiled {
match state1.ts_compiler.get_compiled_module(&out.url) {
match self.ts_compiler.get_compiled_module(&out.url) {
Ok(module) => module,
Err(e) => {
let msg = format!(
@ -264,16 +241,12 @@ impl GlobalState {
pub fn mock(
argv: Vec<String>,
maybe_flags: Option<flags::Flags>,
) -> GlobalState {
if let Some(in_flags) = maybe_flags {
GlobalState::new(flags::Flags { argv, ..in_flags }).unwrap()
} else {
GlobalState::new(flags::Flags {
argv,
..flags::Flags::default()
})
.unwrap()
}
) -> Arc<GlobalState> {
GlobalState::new(flags::Flags {
argv,
..maybe_flags.unwrap_or_default()
})
.unwrap()
}
}

View file

@ -26,7 +26,7 @@ use url::Url;
/// Create new instance of async reqwest::Client. This client supports
/// proxies and doesn't follow redirects.
pub fn create_http_client(ca_file: Option<String>) -> Result<Client, ErrBox> {
pub fn create_http_client(ca_file: Option<&str>) -> Result<Client, ErrBox> {
let mut headers = HeaderMap::new();
headers.insert(
USER_AGENT,
@ -397,12 +397,12 @@ mod tests {
let url =
Url::parse("https://localhost:5545/cli/tests/fixture.json").unwrap();
let client = create_http_client(Some(String::from(
let client = create_http_client(Some(
test_util::root_path()
.join("std/http/testdata/tls/RootCA.pem")
.to_str()
.unwrap(),
)))
))
.unwrap();
let result = fetch_once(client, &url, None).await;
if let Ok(FetchOnceResult::Code(body, headers)) = result {
@ -423,12 +423,12 @@ mod tests {
"https://localhost:5545/cli/tests/053_import_compression/gziped",
)
.unwrap();
let client = create_http_client(Some(String::from(
let client = create_http_client(Some(
test_util::root_path()
.join("std/http/testdata/tls/RootCA.pem")
.to_str()
.unwrap(),
)))
))
.unwrap();
let result = fetch_once(client, &url, None).await;
if let Ok(FetchOnceResult::Code(body, headers)) = result {
@ -448,12 +448,12 @@ mod tests {
async fn test_fetch_with_cafile_with_etag() {
let _http_server_guard = test_util::http_server();
let url = Url::parse("https://localhost:5545/etag_script.ts").unwrap();
let client = create_http_client(Some(String::from(
let client = create_http_client(Some(
test_util::root_path()
.join("std/http/testdata/tls/RootCA.pem")
.to_str()
.unwrap(),
)))
))
.unwrap();
let result = fetch_once(client.clone(), &url, None).await;
if let Ok(FetchOnceResult::Code(body, headers)) = result {
@ -482,12 +482,12 @@ mod tests {
"https://localhost:5545/cli/tests/053_import_compression/brotli",
)
.unwrap();
let client = create_http_client(Some(String::from(
let client = create_http_client(Some(
test_util::root_path()
.join("std/http/testdata/tls/RootCA.pem")
.to_str()
.unwrap(),
)))
))
.unwrap();
let result = fetch_once(client, &url, None).await;
if let Ok(FetchOnceResult::Code(body, headers)) = result {

View file

@ -99,6 +99,7 @@ use std::io::Write;
use std::iter::once;
use std::path::PathBuf;
use std::pin::Pin;
use std::sync::Arc;
use upgrade::upgrade_command;
use url::Url;
@ -151,7 +152,10 @@ where
serde_json::to_writer_pretty(writer, value).map_err(ErrBox::from)
}
fn print_cache_info(state: &GlobalState, json: bool) -> Result<(), ErrBox> {
fn print_cache_info(
state: &Arc<GlobalState>,
json: bool,
) -> Result<(), ErrBox> {
let deno_dir = &state.dir.root;
let modules_cache = &state.file_fetcher.http_cache.location;
let typescript_cache = &state.dir.gen_cache.location;
@ -193,7 +197,7 @@ async fn print_file_info(
module_specifier: ModuleSpecifier,
json: bool,
) -> Result<(), ErrBox> {
let global_state = worker.state.borrow().global_state.clone();
let global_state = worker.state.global_state.clone();
let out = global_state
.file_fetcher
@ -316,7 +320,7 @@ async fn info_command(
print_cache_info(&global_state, json)
} else {
let main_module = ModuleSpecifier::resolve_url_or_path(&file.unwrap())?;
let mut worker = MainWorker::create(global_state, main_module.clone())?;
let mut worker = MainWorker::create(&global_state, main_module.clone())?;
worker.preload_module(&main_module).await?;
print_file_info(&worker, main_module.clone(), json).await
}
@ -335,7 +339,7 @@ async fn install_command(
fetch_flags.reload = true;
let global_state = GlobalState::new(fetch_flags)?;
let main_module = ModuleSpecifier::resolve_url_or_path(&module_url)?;
let mut worker = MainWorker::create(global_state, main_module.clone())?;
let mut worker = MainWorker::create(&global_state, main_module.clone())?;
worker.preload_module(&main_module).await?;
installer::install(flags, &module_url, args, name, root, force)
.map_err(ErrBox::from)
@ -364,8 +368,7 @@ async fn cache_command(flags: Flags, files: Vec<String>) -> Result<(), ErrBox> {
let main_module =
ModuleSpecifier::resolve_url_or_path("./__$deno$fetch.ts").unwrap();
let global_state = GlobalState::new(flags)?;
let mut worker =
MainWorker::create(global_state.clone(), main_module.clone())?;
let mut worker = MainWorker::create(&global_state, main_module.clone())?;
for file in files {
let specifier = ModuleSpecifier::resolve_url_or_path(&file)?;
@ -385,8 +388,7 @@ async fn eval_command(
let main_module =
ModuleSpecifier::resolve_url_or_path("./__$deno$eval.ts").unwrap();
let global_state = GlobalState::new(flags)?;
let mut worker =
MainWorker::create(global_state.clone(), main_module.clone())?;
let mut worker = MainWorker::create(&global_state, main_module.clone())?;
let main_module_url = main_module.as_url().to_owned();
// Create a dummy source file.
let source_code = if print {
@ -438,7 +440,7 @@ async fn bundle_command(
let output = global_state
.ts_compiler
.bundle(global_state.clone(), module_specifier)
.bundle(&global_state, module_specifier)
.await?;
debug!(">>>>> bundle END");
@ -566,7 +568,7 @@ async fn run_repl(flags: Flags) -> Result<(), ErrBox> {
let main_module =
ModuleSpecifier::resolve_url_or_path("./__$deno$repl.ts").unwrap();
let global_state = GlobalState::new(flags)?;
let mut worker = MainWorker::create(global_state, main_module)?;
let mut worker = MainWorker::create(&global_state, main_module)?;
loop {
(&mut *worker).await?;
}
@ -580,7 +582,7 @@ async fn run_command(flags: Flags, script: String) -> Result<(), ErrBox> {
ModuleSpecifier::resolve_url_or_path("./__$deno$stdin.ts").unwrap()
};
let mut worker =
MainWorker::create(global_state.clone(), main_module.clone())?;
MainWorker::create(&global_state.clone(), main_module.clone())?;
if script == "-" {
let mut source = Vec::new();
std::io::stdin().read_to_end(&mut source)?;
@ -636,8 +638,7 @@ async fn test_command(
test_runner::render_test_file(test_modules, fail_fast, quiet, filter);
let main_module =
ModuleSpecifier::resolve_url(&test_file_url.to_string()).unwrap();
let mut worker =
MainWorker::create(global_state.clone(), main_module.clone())?;
let mut worker = MainWorker::create(&global_state, main_module.clone())?;
// Create a dummy source file.
let source_file = SourceFile {
filename: test_file_url.to_file_path().unwrap(),

View file

@ -582,7 +582,7 @@ impl ModuleGraphLoader {
#[cfg(test)]
mod tests {
use super::*;
use crate::GlobalState;
use crate::global_state::GlobalState;
async fn build_graph(
module_specifier: &ModuleSpecifier,

View file

@ -6,12 +6,13 @@ use crate::state::State;
use deno_core::CoreIsolate;
use deno_core::CoreIsolateState;
use deno_core::ZeroCopyBuf;
use std::rc::Rc;
use std::sync::Arc;
use std::sync::Mutex;
pub fn init(
i: &mut CoreIsolate,
_s: &State,
_s: &Rc<State>,
response: Arc<Mutex<Option<String>>>,
) {
let custom_assets = std::collections::HashMap::new();

View file

@ -8,8 +8,9 @@ use crate::state::State;
use deno_core::CoreIsolate;
use deno_core::ZeroCopyBuf;
use std::collections::HashMap;
use std::rc::Rc;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op(
"op_apply_source_map",
s.stateful_json_op(op_apply_source_map),
@ -29,7 +30,7 @@ struct ApplySourceMap {
}
fn op_apply_source_map(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -42,7 +43,7 @@ fn op_apply_source_map(
args.line_number.into(),
args.column_number.into(),
&mut mappings_map,
&state.borrow().global_state.ts_compiler,
&state.global_state.ts_compiler,
);
Ok(JsonOp::Sync(json!({
@ -53,7 +54,7 @@ fn op_apply_source_map(
}
fn op_format_diagnostic(
_state: &State,
_state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {

View file

@ -14,8 +14,9 @@ use http::Method;
use reqwest::Client;
use std::convert::From;
use std::path::PathBuf;
use std::rc::Rc;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_fetch", s.stateful_json_op2(op_fetch));
i.register_op(
"op_create_http_client",
@ -34,22 +35,23 @@ struct FetchArgs {
pub fn op_fetch(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
data: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
let args: FetchArgs = serde_json::from_value(args)?;
let url = args.url;
let resource_table_ = isolate_state.resource_table.borrow();
let state_ = state.borrow();
let mut client_ref_mut;
let client = if let Some(rid) = args.client_rid {
let r = resource_table_
.get::<HttpClientResource>(rid)
.ok_or_else(OpError::bad_resource_id)?;
&r.client
} else {
&state_.http_client
client_ref_mut = state.http_client.borrow_mut();
&mut *client_ref_mut
};
let method = match args.method {
@ -137,7 +139,7 @@ struct CreateHttpClientOptions {
fn op_create_http_client(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -148,7 +150,7 @@ fn op_create_http_client(
state.check_read(&PathBuf::from(ca_file))?;
}
let client = create_http_client(args.ca_file).unwrap();
let client = create_http_client(args.ca_file.as_deref()).unwrap();
let rid =
resource_table.add("httpClient", Box::new(HttpClientResource::new(client)));

View file

@ -23,7 +23,7 @@ use std::time::UNIX_EPOCH;
use rand::{thread_rng, Rng};
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
let t = &CoreIsolate::state(i).borrow().resource_table.clone();
i.register_op("op_open_sync", s.stateful_json_op_sync(t, op_open_sync));
@ -140,7 +140,7 @@ fn op_open_sync(
}
async fn op_open_async(
state: State,
state: Rc<State>,
resource_table: Rc<RefCell<ResourceTable>>,
args: Value,
_zero_copy: BufVec,
@ -170,7 +170,7 @@ struct SeekArgs {
fn op_seek(
isolate_state: &mut CoreIsolateState,
_state: &State,
_state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -230,7 +230,7 @@ struct FdatasyncArgs {
fn op_fdatasync(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -274,7 +274,7 @@ struct FsyncArgs {
fn op_fsync(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -318,7 +318,7 @@ struct FstatArgs {
fn op_fstat(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -360,7 +360,7 @@ struct UmaskArgs {
}
fn op_umask(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -398,7 +398,7 @@ struct ChdirArgs {
}
fn op_chdir(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -419,7 +419,7 @@ struct MkdirArgs {
}
fn op_mkdir(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -453,7 +453,7 @@ struct ChmodArgs {
}
fn op_chmod(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -493,7 +493,7 @@ struct ChownArgs {
}
fn op_chown(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -530,7 +530,7 @@ struct RemoveArgs {
}
fn op_remove(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -584,7 +584,7 @@ struct CopyFileArgs {
}
fn op_copy_file(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -678,7 +678,7 @@ struct StatArgs {
}
fn op_stat(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -708,7 +708,7 @@ struct RealpathArgs {
}
fn op_realpath(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -743,7 +743,7 @@ struct ReadDirArgs {
}
fn op_read_dir(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -786,7 +786,7 @@ struct RenameArgs {
}
fn op_rename(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -815,7 +815,7 @@ struct LinkArgs {
}
fn op_link(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -853,7 +853,7 @@ struct SymlinkOptions {
}
fn op_symlink(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -913,7 +913,7 @@ struct ReadLinkArgs {
}
fn op_read_link(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -941,7 +941,7 @@ struct FtruncateArgs {
fn op_ftruncate(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -986,7 +986,7 @@ struct TruncateArgs {
}
fn op_truncate(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -1060,7 +1060,7 @@ struct MakeTempArgs {
}
fn op_make_temp_dir(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -1091,7 +1091,7 @@ fn op_make_temp_dir(
}
fn op_make_temp_file(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -1131,7 +1131,7 @@ struct UtimeArgs {
}
fn op_utime(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -1151,7 +1151,7 @@ fn op_utime(
}
fn op_cwd(
state: &State,
state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {

View file

@ -17,9 +17,10 @@ use notify::Watcher;
use serde::Serialize;
use std::convert::From;
use std::path::PathBuf;
use std::rc::Rc;
use tokio::sync::mpsc;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_fs_events_open", s.stateful_json_op2(op_fs_events_open));
i.register_op("op_fs_events_poll", s.stateful_json_op2(op_fs_events_poll));
}
@ -64,7 +65,7 @@ impl From<NotifyEvent> for FsEvent {
pub fn op_fs_events_open(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -102,7 +103,7 @@ pub fn op_fs_events_open(
pub fn op_fs_events_poll(
isolate_state: &mut CoreIsolateState,
_state: &State,
_state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {

View file

@ -8,8 +8,9 @@ use crate::state::State;
use deno_core::CoreIsolate;
use deno_core::ZeroCopyBuf;
use idna::{domain_to_ascii, domain_to_ascii_strict};
use std::rc::Rc;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_domain_to_ascii", s.stateful_json_op(op_domain_to_ascii));
}
@ -21,7 +22,7 @@ struct DomainToAscii {
}
fn op_domain_to_ascii(
_state: &State,
_state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {

View file

@ -11,6 +11,7 @@ use futures::future::FutureExt;
use futures::ready;
use std::collections::HashMap;
use std::pin::Pin;
use std::rc::Rc;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::task::Context;
use std::task::Poll;
@ -84,7 +85,7 @@ lazy_static! {
};
}
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_read", s.stateful_minimal_op2(op_read));
i.register_op("op_write", s.stateful_minimal_op2(op_write));
}
@ -236,7 +237,7 @@ impl DenoAsyncRead for StreamResource {
pub fn op_read(
isolate_state: &mut CoreIsolateState,
_state: &State,
_state: &Rc<State>,
is_sync: bool,
rid: i32,
zero_copy: &mut [ZeroCopyBuf],
@ -361,7 +362,7 @@ impl DenoAsyncWrite for StreamResource {
pub fn op_write(
isolate_state: &mut CoreIsolateState,
_state: &State,
_state: &Rc<State>,
is_sync: bool,
rid: i32,
zero_copy: &mut [ZeroCopyBuf],

View file

@ -13,6 +13,7 @@ use futures::future::FutureExt;
use std::convert::From;
use std::net::Shutdown;
use std::net::SocketAddr;
use std::rc::Rc;
use std::task::Context;
use std::task::Poll;
use tokio::net::TcpListener;
@ -22,7 +23,7 @@ use tokio::net::UdpSocket;
#[cfg(unix)]
use super::net_unix;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_accept", s.stateful_json_op2(op_accept));
i.register_op("op_connect", s.stateful_json_op2(op_connect));
i.register_op("op_shutdown", s.stateful_json_op2(op_shutdown));
@ -102,7 +103,7 @@ fn accept_tcp(
fn op_accept(
isolate_state: &mut CoreIsolateState,
_state: &State,
_state: &Rc<State>,
args: Value,
zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -126,7 +127,7 @@ struct ReceiveArgs {
fn receive_udp(
isolate_state: &mut CoreIsolateState,
_state: &State,
_state: &Rc<State>,
args: ReceiveArgs,
zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -166,7 +167,7 @@ fn receive_udp(
fn op_datagram_receive(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -196,7 +197,7 @@ struct SendArgs {
fn op_datagram_send(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -266,7 +267,7 @@ struct ConnectArgs {
fn op_connect(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -352,7 +353,7 @@ struct ShutdownArgs {
fn op_shutdown(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -494,7 +495,7 @@ fn listen_udp(
fn op_listen(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {

View file

@ -6,9 +6,10 @@ use deno_core::CoreIsolate;
use deno_core::ZeroCopyBuf;
use std::collections::HashMap;
use std::env;
use std::rc::Rc;
use url::Url;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_exit", s.stateful_json_op(op_exit));
i.register_op("op_env", s.stateful_json_op(op_env));
i.register_op("op_exec_path", s.stateful_json_op(op_exec_path));
@ -21,7 +22,7 @@ pub fn init(i: &mut CoreIsolate, s: &State) {
}
fn op_exec_path(
state: &State,
state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -41,7 +42,7 @@ struct SetEnv {
}
fn op_set_env(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -52,7 +53,7 @@ fn op_set_env(
}
fn op_env(
state: &State,
state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -67,7 +68,7 @@ struct GetEnv {
}
fn op_get_env(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -86,7 +87,7 @@ struct DeleteEnv {
}
fn op_delete_env(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -102,7 +103,7 @@ struct Exit {
}
fn op_exit(
_s: &State,
_s: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -111,7 +112,7 @@ fn op_exit(
}
fn op_loadavg(
state: &State,
state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -128,7 +129,7 @@ fn op_loadavg(
}
fn op_hostname(
state: &State,
state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -139,7 +140,7 @@ fn op_hostname(
}
fn op_os_release(
state: &State,
state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {

View file

@ -5,8 +5,9 @@ use crate::state::State;
use deno_core::CoreIsolate;
use deno_core::ZeroCopyBuf;
use std::path::Path;
use std::rc::Rc;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op(
"op_query_permission",
s.stateful_json_op(op_query_permission),
@ -29,13 +30,12 @@ struct PermissionArgs {
}
pub fn op_query_permission(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
let args: PermissionArgs = serde_json::from_value(args)?;
let state = state.borrow();
let permissions = &state.permissions;
let permissions = state.permissions.borrow();
let path = args.path.as_deref();
let perm = match args.name.as_ref() {
"read" => permissions.query_read(&path.as_deref().map(Path::new)),
@ -51,13 +51,12 @@ pub fn op_query_permission(
}
pub fn op_revoke_permission(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
let args: PermissionArgs = serde_json::from_value(args)?;
let mut state = state.borrow_mut();
let permissions = &mut state.permissions;
let mut permissions = state.permissions.borrow_mut();
let path = args.path.as_deref();
let perm = match args.name.as_ref() {
"read" => permissions.revoke_read(&path.as_deref().map(Path::new)),
@ -73,13 +72,12 @@ pub fn op_revoke_permission(
}
pub fn op_request_permission(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
let args: PermissionArgs = serde_json::from_value(args)?;
let mut state = state.borrow_mut();
let permissions = &mut state.permissions;
let permissions = &mut state.permissions.borrow_mut();
let path = args.path.as_deref();
let perm = match args.name.as_ref() {
"read" => permissions.request_read(&path.as_deref().map(Path::new)),

View file

@ -20,7 +20,7 @@ use std::rc::Rc;
use std::task::Context;
use std::task::Poll;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op(
"op_open_plugin",
s.core_op(json_op(s.stateful_op2(op_open_plugin))),
@ -35,7 +35,7 @@ struct OpenPluginArgs {
pub fn op_open_plugin(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {

View file

@ -12,12 +12,13 @@ use futures::future::poll_fn;
use futures::future::FutureExt;
use futures::TryFutureExt;
use std::convert::From;
use std::rc::Rc;
use tokio::process::Command;
#[cfg(unix)]
use std::os::unix::process::ExitStatusExt;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_run", s.stateful_json_op2(op_run));
i.register_op("op_run_status", s.stateful_json_op2(op_run_status));
i.register_op("op_kill", s.stateful_json_op(op_kill));
@ -62,7 +63,7 @@ struct ChildResource {
fn op_run(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -173,7 +174,7 @@ struct RunStatusArgs {
fn op_run_status(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -223,7 +224,7 @@ struct KillArgs {
}
fn op_kill(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {

View file

@ -6,8 +6,9 @@ use deno_core::CoreIsolate;
use deno_core::ZeroCopyBuf;
use rand::thread_rng;
use rand::Rng;
use std::rc::Rc;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op(
"op_get_random_values",
s.stateful_json_op(op_get_random_values),
@ -15,14 +16,14 @@ pub fn init(i: &mut CoreIsolate, s: &State) {
}
fn op_get_random_values(
state: &State,
state: &Rc<State>,
_args: Value,
zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
assert_eq!(zero_copy.len(), 1);
if let Some(ref mut seeded_rng) = state.borrow_mut().seeded_rng {
seeded_rng.fill(&mut *zero_copy[0]);
if let Some(seeded_rng) = &state.seeded_rng {
seeded_rng.borrow_mut().fill(&mut *zero_copy[0]);
} else {
let mut rng = thread_rng();
rng.fill(&mut *zero_copy[0]);

View file

@ -7,10 +7,11 @@ use crate::state::State;
use deno_core::CoreIsolate;
use deno_core::CoreIsolateState;
use deno_core::ZeroCopyBuf;
use std::rc::Rc;
use std::sync::Arc;
use std::sync::Mutex;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_repl_start", s.stateful_json_op2(op_repl_start));
i.register_op("op_repl_readline", s.stateful_json_op2(op_repl_readline));
}
@ -25,14 +26,14 @@ struct ReplStartArgs {
fn op_repl_start(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
let args: ReplStartArgs = serde_json::from_value(args)?;
debug!("op_repl_start {}", args.history_file);
let history_path =
repl::history_path(&state.borrow().global_state.dir, &args.history_file);
repl::history_path(&state.global_state.dir, &args.history_file);
let repl = repl::Repl::new(history_path);
let resource = ReplResource(Arc::new(Mutex::new(repl)));
let mut resource_table = isolate_state.resource_table.borrow_mut();
@ -48,7 +49,7 @@ struct ReplReadlineArgs {
fn op_repl_readline(
isolate_state: &mut CoreIsolateState,
_state: &State,
_state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {

View file

@ -5,15 +5,16 @@ use crate::state::State;
use deno_core::CoreIsolate;
use deno_core::CoreIsolateState;
use deno_core::ZeroCopyBuf;
use std::rc::Rc;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_resources", s.stateful_json_op2(op_resources));
i.register_op("op_close", s.stateful_json_op2(op_close));
}
fn op_resources(
isolate_state: &mut CoreIsolateState,
_state: &State,
_state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -24,7 +25,7 @@ fn op_resources(
/// op_close removes a resource from the resource table.
fn op_close(
isolate_state: &mut CoreIsolateState,
_state: &State,
_state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {

View file

@ -9,19 +9,19 @@ use deno_core::CoreIsolate;
use deno_core::ModuleSpecifier;
use deno_core::ZeroCopyBuf;
use std::env;
use std::rc::Rc;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_start", s.stateful_json_op(op_start));
i.register_op("op_main_module", s.stateful_json_op(op_main_module));
i.register_op("op_metrics", s.stateful_json_op(op_metrics));
}
fn op_start(
state: &State,
state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
let state = state.borrow();
let gs = &state.global_state;
Ok(JsonOp::Sync(json!({
@ -43,11 +43,11 @@ fn op_start(
}
fn op_main_module(
state: &State,
state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
let main = &state.borrow().main_module.to_string();
let main = &state.main_module.to_string();
let main_url = ModuleSpecifier::resolve_url_or_path(&main)?;
if main_url.as_url().scheme() == "file" {
let main_path = std::env::current_dir().unwrap().join(main_url.to_string());
@ -57,12 +57,11 @@ fn op_main_module(
}
fn op_metrics(
state: &State,
state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
let state = state.borrow();
let m = &state.metrics;
let m = &state.metrics.borrow();
Ok(JsonOp::Sync(json!({
"opsDispatched": m.ops_dispatched,

View file

@ -9,8 +9,9 @@ use crate::tsc::runtime_transpile;
use deno_core::CoreIsolate;
use deno_core::ZeroCopyBuf;
use std::collections::HashMap;
use std::rc::Rc;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_compile", s.stateful_json_op(op_compile));
i.register_op("op_transpile", s.stateful_json_op(op_transpile));
}
@ -25,19 +26,18 @@ struct CompileArgs {
}
fn op_compile(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
state.check_unstable("Deno.compile");
let args: CompileArgs = serde_json::from_value(args)?;
let s = state.borrow();
let global_state = s.global_state.clone();
let permissions = s.permissions.clone();
let global_state = state.global_state.clone();
let permissions = state.permissions.borrow().clone();
let fut = async move {
let fut = if args.bundle {
runtime_bundle(
global_state,
&global_state,
permissions,
&args.root_name,
&args.sources,
@ -46,7 +46,7 @@ fn op_compile(
.boxed_local()
} else {
runtime_compile(
global_state,
&global_state,
permissions,
&args.root_name,
&args.sources,
@ -68,17 +68,16 @@ struct TranspileArgs {
}
fn op_transpile(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
state.check_unstable("Deno.transpile");
let args: TranspileArgs = serde_json::from_value(args)?;
let s = state.borrow();
let global_state = s.global_state.clone();
let permissions = s.permissions.clone();
let global_state = state.global_state.clone();
let permissions = state.permissions.borrow().clone();
let fut = async move {
runtime_transpile(global_state, permissions, &args.sources, &args.options)
runtime_transpile(&global_state, permissions, &args.sources, &args.options)
.await
}
.boxed_local();

View file

@ -5,6 +5,7 @@ use crate::state::State;
use deno_core::CoreIsolate;
use deno_core::CoreIsolateState;
use deno_core::ZeroCopyBuf;
use std::rc::Rc;
#[cfg(unix)]
use super::dispatch_json::Deserialize;
@ -15,7 +16,7 @@ use std::task::Waker;
#[cfg(unix)]
use tokio::signal::unix::{signal, Signal, SignalKind};
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_signal_bind", s.stateful_json_op2(op_signal_bind));
i.register_op("op_signal_unbind", s.stateful_json_op2(op_signal_unbind));
i.register_op("op_signal_poll", s.stateful_json_op2(op_signal_poll));
@ -41,7 +42,7 @@ struct SignalArgs {
#[cfg(unix)]
fn op_signal_bind(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -63,7 +64,7 @@ fn op_signal_bind(
#[cfg(unix)]
fn op_signal_poll(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -90,7 +91,7 @@ fn op_signal_poll(
#[cfg(unix)]
pub fn op_signal_unbind(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -115,7 +116,7 @@ pub fn op_signal_unbind(
#[cfg(not(unix))]
pub fn op_signal_bind(
_isolate_state: &mut CoreIsolateState,
_state: &State,
_state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -125,7 +126,7 @@ pub fn op_signal_bind(
#[cfg(not(unix))]
fn op_signal_unbind(
_isolate_state: &mut CoreIsolateState,
_state: &State,
_state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -135,7 +136,7 @@ fn op_signal_unbind(
#[cfg(not(unix))]
fn op_signal_poll(
_isolate_state: &mut CoreIsolateState,
_state: &State,
_state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {

View file

@ -5,10 +5,11 @@ use crate::state::State;
use deno_core::CoreIsolate;
use deno_core::ZeroCopyBuf;
use futures::future::FutureExt;
use std::rc::Rc;
use std::time::Duration;
use std::time::Instant;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op(
"op_global_timer_stop",
s.stateful_json_op(op_global_timer_stop),
@ -18,12 +19,11 @@ pub fn init(i: &mut CoreIsolate, s: &State) {
}
fn op_global_timer_stop(
state: &State,
state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
let mut state = state.borrow_mut();
state.global_timer.cancel();
state.global_timer.borrow_mut().cancel();
Ok(JsonOp::Sync(json!({})))
}
@ -33,17 +33,17 @@ struct GlobalTimerArgs {
}
fn op_global_timer(
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
let args: GlobalTimerArgs = serde_json::from_value(args)?;
let val = args.timeout;
let mut state = state.borrow_mut();
let deadline = Instant::now() + Duration::from_millis(val);
let f = state
.global_timer
.borrow_mut()
.new_timeout(deadline)
.then(move |_| futures::future::ok(json!({})));
@ -55,13 +55,12 @@ fn op_global_timer(
// If the High precision flag is not set, the
// nanoseconds are rounded on 2ms.
fn op_now(
state: &State,
state: &Rc<State>,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
let inner_state = state.borrow();
let seconds = inner_state.start_time.elapsed().as_secs();
let mut subsec_nanos = inner_state.start_time.elapsed().subsec_nanos();
let seconds = state.start_time.elapsed().as_secs();
let mut subsec_nanos = state.start_time.elapsed().subsec_nanos();
let reduced_time_precision = 2_000_000; // 2ms in nanoseconds
// If the permission is not enabled

View file

@ -14,6 +14,7 @@ use std::fs::File;
use std::io::BufReader;
use std::net::SocketAddr;
use std::path::Path;
use std::rc::Rc;
use std::sync::Arc;
use std::task::Context;
use std::task::Poll;
@ -29,7 +30,7 @@ use tokio_rustls::{
};
use webpki::DNSNameRef;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_start_tls", s.stateful_json_op2(op_start_tls));
i.register_op("op_connect_tls", s.stateful_json_op2(op_connect_tls));
i.register_op("op_listen_tls", s.stateful_json_op2(op_listen_tls));
@ -55,7 +56,7 @@ struct StartTLSArgs {
pub fn op_start_tls(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -134,7 +135,7 @@ pub fn op_start_tls(
pub fn op_connect_tls(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -308,7 +309,7 @@ struct ListenTlsArgs {
fn op_listen_tls(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -358,7 +359,7 @@ struct AcceptTlsArgs {
fn op_accept_tls(
isolate_state: &mut CoreIsolateState,
_state: &State,
_state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {

View file

@ -10,6 +10,7 @@ use deno_core::ZeroCopyBuf;
use nix::sys::termios;
use serde_derive::{Deserialize, Serialize};
use serde_json::Value;
use std::rc::Rc;
#[cfg(windows)]
use winapi::shared::minwindef::DWORD;
@ -35,7 +36,7 @@ fn get_windows_handle(
Ok(handle)
}
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_set_raw", s.stateful_json_op2(op_set_raw));
i.register_op("op_isatty", s.stateful_json_op2(op_isatty));
i.register_op("op_console_size", s.stateful_json_op2(op_console_size));
@ -49,7 +50,7 @@ struct SetRawArgs {
pub fn op_set_raw(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -218,7 +219,7 @@ struct IsattyArgs {
pub fn op_isatty(
isolate_state: &mut CoreIsolateState,
_state: &State,
_state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -265,7 +266,7 @@ struct ConsoleSize {
pub fn op_console_size(
isolate_state: &mut CoreIsolateState,
state: &State,
state: &Rc<State>,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {

View file

@ -10,6 +10,7 @@ use deno_core::CoreIsolateState;
use deno_core::ZeroCopyBuf;
use futures::channel::mpsc;
use std::convert::From;
use std::rc::Rc;
pub fn web_worker_op<D>(
sender: mpsc::Sender<WorkerEvent>,
@ -59,7 +60,7 @@ where
pub fn init(
i: &mut CoreIsolate,
s: &State,
s: &Rc<State>,
sender: &mpsc::Sender<WorkerEvent>,
handle: WebWorkerHandle,
) {

View file

@ -17,9 +17,11 @@ use deno_core::ModuleSpecifier;
use deno_core::ZeroCopyBuf;
use futures::future::FutureExt;
use std::convert::From;
use std::rc::Rc;
use std::sync::Arc;
use std::thread::JoinHandle;
pub fn init(i: &mut CoreIsolate, s: &State) {
pub fn init(i: &mut CoreIsolate, s: &Rc<State>) {
i.register_op("op_create_worker", s.stateful_json_op(op_create_worker));
i.register_op(
"op_host_terminate_worker",
@ -38,7 +40,7 @@ pub fn init(i: &mut CoreIsolate, s: &State) {
fn create_web_worker(
worker_id: u32,
name: String,
global_state: GlobalState,
global_state: &Arc<GlobalState>,
permissions: Permissions,
specifier: ModuleSpecifier,
has_deno_namespace: bool,
@ -49,7 +51,7 @@ fn create_web_worker(
let mut worker = WebWorker::new(
name.clone(),
startup_data::deno_isolate_init(),
state,
&state,
has_deno_namespace,
);
@ -84,12 +86,13 @@ fn create_web_worker(
fn run_worker_thread(
worker_id: u32,
name: String,
global_state: GlobalState,
global_state: &Arc<GlobalState>,
permissions: Permissions,
specifier: ModuleSpecifier,
has_deno_namespace: bool,
maybe_source_code: Option<String>,
) -> Result<(JoinHandle<()>, WebWorkerHandle), ErrBox> {
let global_state = global_state.clone();
let (handle_sender, handle_receiver) =
std::sync::mpsc::sync_channel::<Result<WebWorkerHandle, ErrBox>>(1);
@ -103,7 +106,7 @@ fn run_worker_thread(
let result = create_web_worker(
worker_id,
name,
global_state,
&global_state,
permissions,
specifier.clone(),
has_deno_namespace,
@ -178,7 +181,7 @@ struct CreateWorkerArgs {
/// Create worker as the host
fn op_create_worker(
state: &State,
state: &Rc<State>,
args: Value,
_data: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -196,12 +199,10 @@ fn op_create_worker(
state.check_unstable("Worker.deno");
}
let parent_state = state.clone();
let mut state = state.borrow_mut();
let global_state = state.global_state.clone();
let permissions = state.permissions.clone();
let worker_id = state.next_worker_id;
state.next_worker_id += 1;
drop(state);
let permissions = state.permissions.borrow().clone();
let worker_id = state.next_worker_id.get();
state.next_worker_id.set(worker_id + 1);
let module_specifier = ModuleSpecifier::resolve_url(&specifier)?;
let worker_name = args_name.unwrap_or_else(|| "".to_string());
@ -209,7 +210,7 @@ fn op_create_worker(
let (join_handle, worker_handle) = run_worker_thread(
worker_id,
worker_name,
global_state,
&global_state,
permissions,
module_specifier,
use_deno_namespace,
@ -218,9 +219,9 @@ fn op_create_worker(
.map_err(|e| OpError::other(e.to_string()))?;
// At this point all interactions with worker happen using thread
// safe handler returned from previous function call
let mut parent_state = parent_state.borrow_mut();
parent_state
.workers
.borrow_mut()
.insert(worker_id, (join_handle, worker_handle));
Ok(JsonOp::Sync(json!({ "id": worker_id })))
@ -232,15 +233,17 @@ struct WorkerArgs {
}
fn op_host_terminate_worker(
state: &State,
state: &Rc<State>,
args: Value,
_data: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
let args: WorkerArgs = serde_json::from_value(args)?;
let id = args.id as u32;
let mut state = state.borrow_mut();
let (join_handle, worker_handle) =
state.workers.remove(&id).expect("No worker handle found");
let (join_handle, worker_handle) = state
.workers
.borrow_mut()
.remove(&id)
.expect("No worker handle found");
worker_handle.terminate();
join_handle.join().expect("Panic in worker thread");
Ok(JsonOp::Sync(json!({})))
@ -298,27 +301,21 @@ fn serialize_worker_event(event: WorkerEvent) -> Value {
/// Get message from guest worker as host
fn op_host_get_message(
state: &State,
state: &Rc<State>,
args: Value,
_data: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
let args: WorkerArgs = serde_json::from_value(args)?;
let id = args.id as u32;
let worker_handle = {
let state_ = state.borrow();
let (_join_handle, worker_handle) =
state_.workers.get(&id).expect("No worker handle found");
worker_handle.clone()
};
let state_ = state.clone();
let state = state.clone();
let worker_handle = state.workers.borrow()[&id].1.clone();
let op = async move {
let response = match worker_handle.get_event().await? {
Some(event) => {
// Terminal error means that worker should be removed from worker table.
if let WorkerEvent::TerminalError(_) = &event {
let mut state_ = state_.borrow_mut();
if let Some((join_handle, mut worker_handle)) =
state_.workers.remove(&id)
state.workers.borrow_mut().remove(&id)
{
worker_handle.sender.close_channel();
join_handle.join().expect("Worker thread panicked");
@ -328,12 +325,10 @@ fn op_host_get_message(
}
None => {
// Worker shuts down
let mut state_ = state_.borrow_mut();
let mut workers = state.workers.borrow_mut();
// Try to remove worker from workers table - NOTE: `Worker.terminate()` might have been called
// already meaning that we won't find worker in table - in that case ignore.
if let Some((join_handle, mut worker_handle)) =
state_.workers.remove(&id)
{
if let Some((join_handle, mut worker_handle)) = workers.remove(&id) {
worker_handle.sender.close_channel();
join_handle.join().expect("Worker thread panicked");
}
@ -347,7 +342,7 @@ fn op_host_get_message(
/// Post message to guest worker as host
fn op_host_post_message(
state: &State,
state: &Rc<State>,
args: Value,
data: &mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError> {
@ -357,9 +352,8 @@ fn op_host_post_message(
let msg = Vec::from(&*data[0]).into_boxed_slice();
debug!("post message to worker {}", id);
let state = state.borrow();
let (_, worker_handle) =
state.workers.get(&id).expect("No worker handle found");
let workers = state.workers.borrow();
let worker_handle = workers[&id].1.clone();
worker_handle
.post_message(msg)
.map_err(|e| OpError::other(e.to_string()))?;

View file

@ -27,60 +27,51 @@ use futures::Future;
use rand::rngs::StdRng;
use rand::SeedableRng;
use serde_json::Value;
use std::cell::Cell;
use std::cell::RefCell;
use std::collections::HashMap;
use std::ops::Deref;
use std::path::Path;
use std::pin::Pin;
use std::rc::Rc;
use std::str;
use std::sync::Arc;
use std::thread::JoinHandle;
use std::time::Instant;
#[derive(Clone)]
pub struct State(Rc<RefCell<StateInner>>);
impl Deref for State {
type Target = Rc<RefCell<StateInner>>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[cfg_attr(feature = "cargo-clippy", allow(stutter))]
pub struct StateInner {
pub global_state: GlobalState,
pub permissions: Permissions,
pub struct State {
pub global_state: Arc<GlobalState>,
pub permissions: RefCell<Permissions>,
pub main_module: ModuleSpecifier,
/// When flags contains a `.import_map_path` option, the content of the
/// import map file will be resolved and set.
pub import_map: Option<ImportMap>,
pub metrics: Metrics,
pub global_timer: GlobalTimer,
pub workers: HashMap<u32, (JoinHandle<()>, WebWorkerHandle)>,
pub next_worker_id: u32,
pub metrics: RefCell<Metrics>,
pub global_timer: RefCell<GlobalTimer>,
pub workers: RefCell<HashMap<u32, (JoinHandle<()>, WebWorkerHandle)>>,
pub next_worker_id: Cell<u32>,
pub start_time: Instant,
pub seeded_rng: Option<StdRng>,
pub seeded_rng: Option<RefCell<StdRng>>,
pub target_lib: TargetLib,
pub is_main: bool,
pub is_internal: bool,
pub http_client: reqwest::Client,
pub http_client: RefCell<reqwest::Client>,
}
impl State {
pub fn stateful_json_op<D>(
&self,
self: &Rc<Self>,
dispatcher: D,
) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
where
D: Fn(&State, Value, &mut [ZeroCopyBuf]) -> Result<JsonOp, OpError>,
D: Fn(&Rc<State>, Value, &mut [ZeroCopyBuf]) -> Result<JsonOp, OpError>,
{
use crate::ops::json_op;
self.core_op(json_op(self.stateful_op(dispatcher)))
}
pub fn stateful_json_op_sync<D>(
&self,
self: &Rc<Self>,
resource_table: &Rc<RefCell<ResourceTable>>,
dispatcher: D,
) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
@ -117,12 +108,13 @@ impl State {
}
pub fn stateful_json_op_async<D, F>(
&self,
self: &Rc<Self>,
resource_table: &Rc<RefCell<ResourceTable>>,
dispatcher: D,
) -> impl Fn(&mut CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
where
D: FnOnce(State, Rc<RefCell<ResourceTable>>, Value, BufVec) -> F + Clone,
D:
FnOnce(Rc<State>, Rc<RefCell<ResourceTable>>, Value, BufVec) -> F + Clone,
F: Future<Output = Result<Value, OpError>> + 'static,
{
let state = self.clone();
@ -167,13 +159,13 @@ impl State {
}
pub fn stateful_json_op2<D>(
&self,
self: &Rc<Self>,
dispatcher: D,
) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
where
D: Fn(
&mut deno_core::CoreIsolateState,
&State,
&Rc<State>,
Value,
&mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError>,
@ -186,7 +178,7 @@ impl State {
// TODO(ry) this should be private. Is called by stateful_json_op or
// stateful_minimal_op
pub fn core_op<D>(
&self,
self: &Rc<Self>,
dispatcher: D,
) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
where
@ -206,8 +198,7 @@ impl State {
match op {
Op::Sync(buf) => {
let mut state_ = state.borrow_mut();
state_.metrics.op_sync(
state.metrics.borrow_mut().op_sync(
bytes_sent_control,
bytes_sent_zero_copy,
buf.len() as u64,
@ -215,28 +206,31 @@ impl State {
Op::Sync(buf)
}
Op::Async(fut) => {
let mut state_ = state.borrow_mut();
state_
state
.metrics
.borrow_mut()
.op_dispatched_async(bytes_sent_control, bytes_sent_zero_copy);
let state = state.clone();
let result_fut = fut.map(move |buf: Buf| {
let mut state_ = state.borrow_mut();
state_.metrics.op_completed_async(buf.len() as u64);
state
.metrics
.borrow_mut()
.op_completed_async(buf.len() as u64);
buf
});
Op::Async(result_fut.boxed_local())
}
Op::AsyncUnref(fut) => {
let mut state_ = state.borrow_mut();
state_.metrics.op_dispatched_async_unref(
state.metrics.borrow_mut().op_dispatched_async_unref(
bytes_sent_control,
bytes_sent_zero_copy,
);
let state = state.clone();
let result_fut = fut.map(move |buf: Buf| {
let mut state_ = state.borrow_mut();
state_.metrics.op_completed_async_unref(buf.len() as u64);
state
.metrics
.borrow_mut()
.op_completed_async_unref(buf.len() as u64);
buf
});
Op::AsyncUnref(result_fut.boxed_local())
@ -246,13 +240,13 @@ impl State {
}
pub fn stateful_minimal_op2<D>(
&self,
self: &Rc<Self>,
dispatcher: D,
) -> impl Fn(&mut deno_core::CoreIsolateState, &mut [ZeroCopyBuf]) -> Op
where
D: Fn(
&mut deno_core::CoreIsolateState,
&State,
&Rc<State>,
bool,
i32,
&mut [ZeroCopyBuf],
@ -276,7 +270,7 @@ impl State {
/// This is a band-aid for transition to `CoreIsolate.register_op` API as most of our
/// ops require `state` argument.
pub fn stateful_op<D>(
&self,
self: &Rc<Self>,
dispatcher: D,
) -> impl Fn(
&mut deno_core::CoreIsolateState,
@ -284,7 +278,7 @@ impl State {
&mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError>
where
D: Fn(&State, Value, &mut [ZeroCopyBuf]) -> Result<JsonOp, OpError>,
D: Fn(&Rc<State>, Value, &mut [ZeroCopyBuf]) -> Result<JsonOp, OpError>,
{
let state = self.clone();
move |_isolate_state: &mut deno_core::CoreIsolateState,
@ -294,7 +288,7 @@ impl State {
}
pub fn stateful_op2<D>(
&self,
self: &Rc<Self>,
dispatcher: D,
) -> impl Fn(
&mut deno_core::CoreIsolateState,
@ -304,7 +298,7 @@ impl State {
where
D: Fn(
&mut deno_core::CoreIsolateState,
&State,
&Rc<State>,
Value,
&mut [ZeroCopyBuf],
) -> Result<JsonOp, OpError>,
@ -322,11 +316,10 @@ impl State {
///
/// This is intentionally a non-recoverable check so that people cannot probe
/// for unstable APIs from stable programs.
pub fn check_unstable(&self, api_name: &str) {
pub fn check_unstable(self: &Rc<Self>, api_name: &str) {
// TODO(ry) Maybe use IsolateHandle::terminate_execution here to provide a
// stack trace in JS.
let s = self.0.borrow();
if !s.global_state.flags.unstable {
if !self.global_state.flags.unstable {
exit_unstable(api_name);
}
}
@ -348,7 +341,7 @@ impl ModuleLoader for State {
is_main: bool,
) -> Result<ModuleSpecifier, ErrBox> {
if !is_main {
if let Some(import_map) = &self.borrow().import_map {
if let Some(import_map) = &self.import_map {
let result = import_map.resolve(specifier, referrer)?;
if let Some(r) = result {
return Ok(r);
@ -368,11 +361,10 @@ impl ModuleLoader for State {
_is_dyn_import: bool,
) -> Pin<Box<deno_core::ModuleSourceFuture>> {
let module_specifier = module_specifier.to_owned();
let mut state = self.borrow_mut();
// TODO(bartlomieju): incrementing resolve_count here has no sense...
state.metrics.resolve_count += 1;
self.metrics.borrow_mut().resolve_count += 1;
let module_url_specified = module_specifier.to_string();
let global_state = state.global_state.clone();
let global_state = self.global_state.clone();
// TODO(bartlomieju): `fetch_compiled_module` should take `load_id` param
let fut = async move {
@ -399,18 +391,17 @@ impl ModuleLoader for State {
is_dyn_import: bool,
) -> Pin<Box<dyn Future<Output = Result<(), ErrBox>>>> {
let module_specifier = module_specifier.clone();
let state = self.borrow();
let target_lib = state.target_lib.clone();
let maybe_import_map = state.import_map.clone();
let target_lib = self.target_lib.clone();
let maybe_import_map = self.import_map.clone();
// Only "main" module is loaded without permission check,
// ie. module that is associated with "is_main" state
// and is not a dynamic import.
let permissions = if state.is_main && !is_dyn_import {
let permissions = if self.is_main && !is_dyn_import {
Permissions::allow_all()
} else {
state.permissions.clone()
self.permissions.borrow().clone()
};
let global_state = state.global_state.clone();
let global_state = self.global_state.clone();
// TODO(bartlomieju): I'm not sure if it's correct to ignore
// bad referrer - this is the case for `Deno.core.evalContext()` where
// `ref_str` is `<unknown>`.
@ -419,7 +410,6 @@ impl ModuleLoader for State {
} else {
None
};
drop(state);
// TODO(bartlomieju): `prepare_module_load` should take `load_id` param
async move {
@ -441,87 +431,65 @@ impl ModuleLoader for State {
impl State {
/// If `shared_permission` is None then permissions from globa state are used.
pub fn new(
global_state: GlobalState,
global_state: &Arc<GlobalState>,
shared_permissions: Option<Permissions>,
main_module: ModuleSpecifier,
maybe_import_map: Option<ImportMap>,
is_internal: bool,
) -> Result<Self, ErrBox> {
let seeded_rng = match global_state.flags.seed {
Some(seed) => Some(StdRng::seed_from_u64(seed)),
None => None,
};
let permissions = if let Some(perm) = shared_permissions {
perm
} else {
global_state.permissions.clone()
};
let http_client = create_http_client(global_state.flags.ca_file.clone())?;
let state = Rc::new(RefCell::new(StateInner {
global_state,
) -> Result<Rc<Self>, ErrBox> {
let fl = &global_state.flags;
let state = State {
global_state: global_state.clone(),
main_module,
permissions,
permissions: shared_permissions
.unwrap_or_else(|| global_state.permissions.clone())
.into(),
import_map: maybe_import_map,
metrics: Metrics::default(),
global_timer: GlobalTimer::new(),
workers: HashMap::new(),
next_worker_id: 0,
metrics: Default::default(),
global_timer: Default::default(),
workers: Default::default(),
next_worker_id: Default::default(),
start_time: Instant::now(),
seeded_rng,
seeded_rng: fl.seed.map(|v| StdRng::seed_from_u64(v).into()),
target_lib: TargetLib::Main,
is_main: true,
is_internal,
http_client,
}));
Ok(Self(state))
http_client: create_http_client(fl.ca_file.as_deref())?.into(),
};
Ok(Rc::new(state))
}
/// If `shared_permission` is None then permissions from globa state are used.
pub fn new_for_worker(
global_state: GlobalState,
global_state: &Arc<GlobalState>,
shared_permissions: Option<Permissions>,
main_module: ModuleSpecifier,
) -> Result<Self, ErrBox> {
let seeded_rng = match global_state.flags.seed {
Some(seed) => Some(StdRng::seed_from_u64(seed)),
None => None,
};
let permissions = if let Some(perm) = shared_permissions {
perm
} else {
global_state.permissions.clone()
};
let http_client = create_http_client(global_state.flags.ca_file.clone())?;
let state = Rc::new(RefCell::new(StateInner {
global_state,
) -> Result<Rc<Self>, ErrBox> {
let fl = &global_state.flags;
let state = State {
global_state: global_state.clone(),
main_module,
permissions,
permissions: shared_permissions
.unwrap_or_else(|| global_state.permissions.clone())
.into(),
import_map: None,
metrics: Metrics::default(),
global_timer: GlobalTimer::new(),
workers: HashMap::new(),
next_worker_id: 0,
metrics: Default::default(),
global_timer: Default::default(),
workers: Default::default(),
next_worker_id: Default::default(),
start_time: Instant::now(),
seeded_rng,
seeded_rng: fl.seed.map(|v| StdRng::seed_from_u64(v).into()),
target_lib: TargetLib::Worker,
is_main: false,
is_internal: false,
http_client,
}));
Ok(Self(state))
http_client: create_http_client(fl.ca_file.as_deref())?.into(),
};
Ok(Rc::new(state))
}
#[inline]
pub fn check_read(&self, path: &Path) -> Result<(), OpError> {
self.borrow().permissions.check_read(path)
self.permissions.borrow().check_read(path)
}
/// As `check_read()`, but permission error messages will anonymize the path
@ -532,42 +500,42 @@ impl State {
path: &Path,
display: &str,
) -> Result<(), OpError> {
self.borrow().permissions.check_read_blind(path, display)
self.permissions.borrow().check_read_blind(path, display)
}
#[inline]
pub fn check_write(&self, path: &Path) -> Result<(), OpError> {
self.borrow().permissions.check_write(path)
self.permissions.borrow().check_write(path)
}
#[inline]
pub fn check_env(&self) -> Result<(), OpError> {
self.borrow().permissions.check_env()
self.permissions.borrow().check_env()
}
#[inline]
pub fn check_net(&self, hostname: &str, port: u16) -> Result<(), OpError> {
self.borrow().permissions.check_net(hostname, port)
self.permissions.borrow().check_net(hostname, port)
}
#[inline]
pub fn check_net_url(&self, url: &url::Url) -> Result<(), OpError> {
self.borrow().permissions.check_net_url(url)
self.permissions.borrow().check_net_url(url)
}
#[inline]
pub fn check_run(&self) -> Result<(), OpError> {
self.borrow().permissions.check_run()
self.permissions.borrow().check_run()
}
#[inline]
pub fn check_hrtime(&self) -> Result<(), OpError> {
self.borrow().permissions.check_hrtime()
self.permissions.borrow().check_hrtime()
}
#[inline]
pub fn check_plugin(&self, filename: &Path) -> Result<(), OpError> {
self.borrow().permissions.check_plugin(filename)
self.permissions.borrow().check_plugin(filename)
}
pub fn check_dyn_import(
@ -599,11 +567,11 @@ impl State {
}
#[cfg(test)]
pub fn mock(main_module: &str) -> State {
pub fn mock(main_module: &str) -> Rc<State> {
let module_specifier = ModuleSpecifier::resolve_url_or_path(main_module)
.expect("Invalid entry module");
State::new(
GlobalState::mock(vec!["deno".to_string()], None),
&GlobalState::mock(vec!["deno".to_string()], None),
None,
module_specifier,
None,

View file

@ -12,7 +12,7 @@ pub fn create_basic_runtime() -> tokio::runtime::Runtime {
// TODO(ry) rename to run_local ?
pub fn run_basic<F, R>(future: F) -> R
where
F: std::future::Future<Output = R> + 'static,
F: std::future::Future<Output = R>,
{
let mut rt = create_basic_runtime();
rt.block_on(future)

View file

@ -46,6 +46,7 @@ use std::ops::Deref;
use std::ops::DerefMut;
use std::path::PathBuf;
use std::pin::Pin;
use std::rc::Rc;
use std::str;
use std::sync::atomic::Ordering;
use std::sync::Arc;
@ -131,9 +132,12 @@ pub struct CompilerWorker {
}
impl CompilerWorker {
pub fn new(name: String, startup_data: StartupData, state: State) -> Self {
let state_ = state.clone();
let mut worker = Worker::new(name, startup_data, state_);
pub fn new(
name: String,
startup_data: StartupData,
state: &Rc<State>,
) -> Self {
let mut worker = Worker::new(name, startup_data, state);
let response = Arc::new(Mutex::new(None));
{
let isolate = &mut worker.isolate;
@ -199,21 +203,16 @@ lazy_static! {
/// Create a new worker with snapshot of TS compiler and setup compiler's
/// runtime.
fn create_compiler_worker(
global_state: GlobalState,
global_state: &Arc<GlobalState>,
permissions: Permissions,
) -> CompilerWorker {
// TODO(bartlomieju): these $deno$ specifiers should be unified for all subcommands
// like 'eval', 'repl'
let entry_point =
ModuleSpecifier::resolve_url_or_path("./__$deno$ts_compiler.ts").unwrap();
let worker_state = State::new(
global_state.clone(),
Some(permissions),
entry_point,
None,
true,
)
.expect("Unable to create worker state");
let worker_state =
State::new(&global_state, Some(permissions), entry_point, None, true)
.expect("Unable to create worker state");
// TODO(bartlomieju): this metric is never used anywhere
// Count how many times we start the compiler worker.
@ -222,7 +221,7 @@ fn create_compiler_worker(
let mut worker = CompilerWorker::new(
"TS".to_string(),
startup_data::compiler_isolate_init(),
worker_state,
&worker_state,
);
worker
.execute("globalThis.bootstrapCompilerRuntime()")
@ -545,7 +544,7 @@ impl TsCompiler {
/// compiler.
pub async fn compile(
&self,
global_state: GlobalState,
global_state: &Arc<GlobalState>,
source_file: &SourceFile,
target: TargetLib,
permissions: Permissions,
@ -635,7 +634,7 @@ impl TsCompiler {
/// all the dependencies for that module.
pub async fn bundle(
&self,
global_state: GlobalState,
global_state: &Arc<GlobalState>,
module_specifier: ModuleSpecifier,
) -> Result<String, ErrBox> {
debug!(
@ -1055,11 +1054,11 @@ impl TsCompiler {
}
async fn execute_in_same_thread(
global_state: GlobalState,
global_state: &Arc<GlobalState>,
permissions: Permissions,
req: String,
) -> Result<String, ErrBox> {
let mut worker = create_compiler_worker(global_state.clone(), permissions);
let mut worker = create_compiler_worker(&global_state, permissions);
let script = format!("globalThis.tsCompilerOnMessage({{ data: {} }});", req);
worker.execute2("<compiler>", &script)?;
(&mut *worker).await?;
@ -1067,7 +1066,7 @@ async fn execute_in_same_thread(
}
async fn create_runtime_module_graph(
global_state: GlobalState,
global_state: &Arc<GlobalState>,
permissions: Permissions,
root_name: &str,
sources: &Option<HashMap<String, String>>,
@ -1131,14 +1130,14 @@ fn js_error_to_op_error(error: ErrBox) -> OpError {
/// This function is used by `Deno.compile()` API.
pub async fn runtime_compile(
global_state: GlobalState,
global_state: &Arc<GlobalState>,
permissions: Permissions,
root_name: &str,
sources: &Option<HashMap<String, String>>,
maybe_options: &Option<String>,
) -> Result<Value, OpError> {
let (root_names, module_graph) = create_runtime_module_graph(
global_state.clone(),
&global_state,
permissions.clone(),
root_name,
sources,
@ -1178,14 +1177,14 @@ pub async fn runtime_compile(
/// This function is used by `Deno.bundle()` API.
pub async fn runtime_bundle(
global_state: GlobalState,
global_state: &Arc<GlobalState>,
permissions: Permissions,
root_name: &str,
sources: &Option<HashMap<String, String>>,
maybe_options: &Option<String>,
) -> Result<Value, OpError> {
let (root_names, module_graph) = create_runtime_module_graph(
global_state.clone(),
&global_state,
permissions.clone(),
root_name,
sources,
@ -1217,7 +1216,7 @@ pub async fn runtime_bundle(
/// This function is used by `Deno.transpileOnly()` API.
pub async fn runtime_transpile(
global_state: GlobalState,
global_state: &Arc<GlobalState>,
permissions: Permissions,
sources: &HashMap<String, String>,
options: &Option<String>,
@ -1495,6 +1494,7 @@ mod tests {
use super::*;
use crate::deno_dir;
use crate::fs as deno_fs;
use crate::global_state::GlobalState;
use crate::http_cache;
use deno_core::ModuleSpecifier;
use std::path::PathBuf;
@ -1607,7 +1607,7 @@ mod tests {
let result = ts_compiler
.compile(
mock_state.clone(),
&mock_state,
&out,
TargetLib::Main,
Permissions::allow_all(),
@ -1716,7 +1716,7 @@ mod tests {
let result = mock_state
.ts_compiler
.bundle(mock_state.clone(), module_name)
.bundle(&mock_state, module_name)
.await;
assert!(result.is_ok());

View file

@ -14,6 +14,7 @@ use std::future::Future;
use std::ops::Deref;
use std::ops::DerefMut;
use std::pin::Pin;
use std::rc::Rc;
use std::sync::atomic::AtomicBool;
use std::sync::atomic::Ordering;
use std::sync::Arc;
@ -84,11 +85,10 @@ impl WebWorker {
pub fn new(
name: String,
startup_data: StartupData,
state: State,
state: &Rc<State>,
has_deno_namespace: bool,
) -> Self {
let state_ = state.clone();
let mut worker = Worker::new(name, startup_data, state_);
let mut worker = Worker::new(name, startup_data, &state);
let terminated = Arc::new(AtomicBool::new(false));
let isolate_handle = worker.isolate.thread_safe_handle();
@ -254,7 +254,7 @@ mod tests {
let mut worker = WebWorker::new(
"TEST".to_string(),
startup_data::deno_isolate_init(),
state,
&state,
false,
);
worker

View file

@ -92,19 +92,23 @@ pub struct Worker {
pub name: String,
pub isolate: deno_core::EsIsolate,
pub inspector: Option<Box<DenoInspector>>,
pub state: State,
pub state: Rc<State>,
pub waker: AtomicWaker,
pub(crate) internal_channels: WorkerChannelsInternal,
external_channels: WorkerHandle,
}
impl Worker {
pub fn new(name: String, startup_data: StartupData, state: State) -> Self {
let loader = Rc::new(state.clone());
let mut isolate = deno_core::EsIsolate::new(loader, startup_data, false);
pub fn new(
name: String,
startup_data: StartupData,
state: &Rc<State>,
) -> Self {
let mut isolate =
deno_core::EsIsolate::new(state.clone(), startup_data, false);
{
let global_state = state.borrow().global_state.clone();
let global_state = state.global_state.clone();
let core_state_rc = CoreIsolate::state(&isolate);
let mut core_state = core_state_rc.borrow_mut();
core_state.set_js_error_create_fn(move |core_js_error| {
@ -113,7 +117,6 @@ impl Worker {
}
let inspector = {
let state = state.borrow();
let global_state = &state.global_state;
global_state
.flags
@ -129,7 +132,7 @@ impl Worker {
name,
isolate,
inspector,
state,
state: state.clone(),
waker: AtomicWaker::new(),
internal_channels,
external_channels,
@ -193,8 +196,7 @@ impl Worker {
fn wait_for_inspector_session(&mut self) {
let should_break_on_first_statement = self.inspector.is_some() && {
let state = self.state.borrow();
state.is_main && state.global_state.flags.inspect_brk.is_some()
self.state.is_main && self.state.global_state.flags.inspect_brk.is_some()
};
if should_break_on_first_statement {
self
@ -250,9 +252,8 @@ pub struct MainWorker(Worker);
impl MainWorker {
// TODO(ry) combine MainWorker::new and MainWorker::create.
fn new(name: String, startup_data: StartupData, state: State) -> Self {
let state_ = state.clone();
let mut worker = Worker::new(name, startup_data, state_);
fn new(name: String, startup_data: StartupData, state: &Rc<State>) -> Self {
let mut worker = Worker::new(name, startup_data, state);
{
let isolate = &mut worker.isolate;
ops::runtime::init(isolate, &state);
@ -281,11 +282,11 @@ impl MainWorker {
}
pub fn create(
global_state: GlobalState,
global_state: &Arc<GlobalState>,
main_module: ModuleSpecifier,
) -> Result<MainWorker, ErrBox> {
let state = State::new(
global_state.clone(),
&global_state,
None,
main_module,
global_state.maybe_import_map.clone(),
@ -294,7 +295,7 @@ impl MainWorker {
let mut worker = MainWorker::new(
"main".to_string(),
startup_data::deno_isolate_init(),
state,
&state,
);
{
let (stdin, stdout, stderr) = get_stdio();
@ -335,7 +336,6 @@ mod tests {
use crate::flags;
use crate::global_state::GlobalState;
use crate::startup_data;
use crate::state::State;
use crate::tokio_util;
use std::sync::atomic::Ordering;
@ -349,12 +349,11 @@ mod tests {
ModuleSpecifier::resolve_url_or_path(&p.to_string_lossy()).unwrap();
let global_state = GlobalState::new(flags::Flags::default()).unwrap();
let state =
State::new(global_state, None, module_specifier.clone(), None, false)
State::new(&global_state, None, module_specifier.clone(), None, false)
.unwrap();
let state_ = state.clone();
tokio_util::run_basic(async move {
tokio_util::run_basic(async {
let mut worker =
MainWorker::new("TEST".to_string(), StartupData::None, state);
MainWorker::new("TEST".to_string(), StartupData::None, &state);
let result = worker.execute_module(&module_specifier).await;
if let Err(err) = result {
eprintln!("execute_mod err {:?}", err);
@ -363,8 +362,7 @@ mod tests {
panic!("Future got unexpected error: {:?}", e);
}
});
let state = state_.borrow();
assert_eq!(state.metrics.resolve_count, 2);
assert_eq!(state.metrics.borrow().resolve_count, 2);
// Check that we didn't start the compiler.
assert_eq!(state.global_state.compiler_starts.load(Ordering::SeqCst), 0);
}
@ -379,12 +377,11 @@ mod tests {
ModuleSpecifier::resolve_url_or_path(&p.to_string_lossy()).unwrap();
let global_state = GlobalState::new(flags::Flags::default()).unwrap();
let state =
State::new(global_state, None, module_specifier.clone(), None, false)
State::new(&global_state, None, module_specifier.clone(), None, false)
.unwrap();
let state_ = state.clone();
tokio_util::run_basic(async move {
tokio_util::run_basic(async {
let mut worker =
MainWorker::new("TEST".to_string(), StartupData::None, state);
MainWorker::new("TEST".to_string(), StartupData::None, &state);
let result = worker.execute_module(&module_specifier).await;
if let Err(err) = result {
eprintln!("execute_mod err {:?}", err);
@ -394,7 +391,6 @@ mod tests {
}
});
let state = state_.borrow();
// Check that we didn't start the compiler.
assert_eq!(state.global_state.compiler_starts.load(Ordering::SeqCst), 0);
}
@ -416,18 +412,13 @@ mod tests {
..flags::Flags::default()
};
let global_state = GlobalState::new(flags).unwrap();
let state = State::new(
global_state.clone(),
None,
module_specifier.clone(),
None,
false,
)
.unwrap();
let state =
State::new(&global_state, None, module_specifier.clone(), None, false)
.unwrap();
let mut worker = MainWorker::new(
"TEST".to_string(),
startup_data::deno_isolate_init(),
state.clone(),
&state,
);
worker.execute("bootstrap.mainRuntime()").unwrap();
let result = worker.execute_module(&module_specifier).await;
@ -437,8 +428,7 @@ mod tests {
if let Err(e) = (&mut *worker).await {
panic!("Future got unexpected error: {:?}", e);
}
let state = state.borrow();
assert_eq!(state.metrics.resolve_count, 3);
assert_eq!(state.metrics.borrow().resolve_count, 3);
// Check that we've only invoked the compiler once.
assert_eq!(state.global_state.compiler_starts.load(Ordering::SeqCst), 1);
}
@ -448,7 +438,7 @@ mod tests {
let mut worker = MainWorker::new(
"TEST".to_string(),
startup_data::deno_isolate_init(),
state,
&state,
);
worker.execute("bootstrap.mainRuntime()").unwrap();
worker