summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/main.rs14
-rw-r--r--cli/ops.rs8
-rw-r--r--cli/state.rs85
-rw-r--r--cli/worker.rs203
4 files changed, 150 insertions, 160 deletions
diff --git a/cli/main.rs b/cli/main.rs
index 953e01943..891f18f39 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -92,10 +92,9 @@ where
}
}
-// TODO(ry) Move this to main.rs
pub fn print_file_info(worker: &Worker, url: &str) {
let maybe_out =
- worker::fetch_module_meta_data_and_maybe_compile(&worker.state, url, ".");
+ state::fetch_module_meta_data_and_maybe_compile(&worker.state, url, ".");
if let Err(err) = maybe_out {
println!("{}", err);
return;
@@ -126,7 +125,8 @@ pub fn print_file_info(worker: &Worker, url: &str) {
);
}
- if let Some(deps) = worker.modules.deps(&out.module_name) {
+ let modules = worker.modules.lock().unwrap();
+ if let Some(deps) = modules.deps(&out.module_name) {
println!("{}{}", ansi::bold("deps:\n".to_string()), deps.name);
if let Some(ref depsdeps) = deps.deps {
for d in depsdeps {
@@ -193,7 +193,7 @@ fn fetch_or_info_command(
worker
.execute_mod_async(&main_url, true)
- .and_then(move |worker| {
+ .and_then(move |()| {
if print_info {
print_file_info(&worker, &main_module);
}
@@ -201,7 +201,7 @@ fn fetch_or_info_command(
js_check(result);
Ok(())
})
- }).map_err(|(err, _worker)| print_err_and_exit(err))
+ }).map_err(print_err_and_exit)
});
tokio_util::run(main_future);
}
@@ -289,12 +289,12 @@ fn run_script(flags: DenoFlags, argv: Vec<String>) {
worker
.execute_mod_async(&main_url, false)
- .and_then(move |worker| {
+ .and_then(move |()| {
worker.then(|result| {
js_check(result);
Ok(())
})
- }).map_err(|(err, _worker)| print_err_and_exit(err))
+ }).map_err(print_err_and_exit)
});
tokio_util::run(main_future);
}
diff --git a/cli/ops.rs b/cli/ops.rs
index e41c9caa2..0e41eacc0 100644
--- a/cli/ops.rs
+++ b/cli/ops.rs
@@ -2067,7 +2067,7 @@ fn op_create_worker(
// TODO(ry) Use execute_mod_async here.
let result = worker.execute_mod(&specifier_url, false);
match result {
- Ok(worker) => {
+ Ok(()) => {
let mut workers_tl = parent_state.workers.lock().unwrap();
workers_tl.insert(rid, worker.shared());
let builder = &mut FlatBufferBuilder::new();
@@ -2085,10 +2085,8 @@ fn op_create_worker(
},
))
}
- Err((errors::RustOrJsError::Js(_), _worker)) => {
- Err(errors::worker_init_failed())
- }
- Err((errors::RustOrJsError::Rust(err), _worker)) => Err(err),
+ Err(errors::RustOrJsError::Js(_)) => Err(errors::worker_init_failed()),
+ Err(errors::RustOrJsError::Rust(err)) => Err(err),
}
}()))
}
diff --git a/cli/state.rs b/cli/state.rs
index dffd1202f..cc3edec87 100644
--- a/cli/state.rs
+++ b/cli/state.rs
@@ -1,18 +1,27 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+use crate::compiler::compile_async;
+use crate::compiler::ModuleMetaData;
use crate::deno_dir;
+use crate::errors::DenoError;
use crate::errors::DenoResult;
use crate::flags;
use crate::global_timer::GlobalTimer;
+use crate::msg;
use crate::ops;
use crate::permissions::DenoPermissions;
use crate::progress::Progress;
use crate::resources;
use crate::resources::ResourceId;
+use crate::tokio_util;
+use crate::worker::resolve_module_spec;
use crate::worker::Worker;
use deno::Buf;
+use deno::Loader;
use deno::Op;
use deno::PinnedBuf;
+use futures::future::Either;
use futures::future::Shared;
+use futures::Future;
use std;
use std::collections::HashMap;
use std::collections::HashSet;
@@ -94,6 +103,82 @@ impl ThreadSafeState {
}
}
+fn fetch_module_meta_data_and_maybe_compile_async(
+ state: &ThreadSafeState,
+ specifier: &str,
+ referrer: &str,
+) -> impl Future<Item = ModuleMetaData, Error = DenoError> {
+ let state_ = state.clone();
+ let specifier = specifier.to_string();
+ let referrer = referrer.to_string();
+
+ let f =
+ futures::future::result(ThreadSafeState::resolve(&specifier, &referrer));
+ f.and_then(move |module_id| {
+ let use_cache = !state_.flags.reload || state_.has_compiled(&module_id);
+ let no_fetch = state_.flags.no_fetch;
+
+ state_
+ .dir
+ .fetch_module_meta_data_async(&specifier, &referrer, use_cache, no_fetch)
+ .and_then(move |out| {
+ if out.media_type == msg::MediaType::TypeScript
+ && !out.has_output_code_and_source_map()
+ {
+ debug!(">>>>> compile_sync START");
+ Either::A(
+ compile_async(state_.clone(), &specifier, &referrer, &out)
+ .map_err(|e| {
+ debug!("compiler error exiting!");
+ eprintln!("\n{}", e.to_string());
+ std::process::exit(1);
+ }).and_then(move |out| {
+ debug!(">>>>> compile_sync END");
+ Ok(out)
+ }),
+ )
+ } else {
+ Either::B(futures::future::ok(out))
+ }
+ })
+ })
+}
+
+pub fn fetch_module_meta_data_and_maybe_compile(
+ state: &ThreadSafeState,
+ specifier: &str,
+ referrer: &str,
+) -> Result<ModuleMetaData, DenoError> {
+ tokio_util::block_on(fetch_module_meta_data_and_maybe_compile_async(
+ state, specifier, referrer,
+ ))
+}
+
+impl Loader for ThreadSafeState {
+ type Error = DenoError;
+
+ fn resolve(specifier: &str, referrer: &str) -> Result<String, Self::Error> {
+ resolve_module_spec(specifier, referrer).map_err(DenoError::from)
+ }
+
+ /// Given an absolute url, load its source code.
+ fn load(&self, url: &str) -> Box<deno::SourceCodeInfoFuture<Self::Error>> {
+ self.metrics.resolve_count.fetch_add(1, Ordering::SeqCst);
+ Box::new(
+ fetch_module_meta_data_and_maybe_compile_async(self, url, ".")
+ .map_err(|err| {
+ eprintln!("{}", err);
+ err
+ }).map(|module_meta_data| deno::SourceCodeInfo {
+ // Real module name, might be different from initial URL
+ // due to redirections.
+ code: module_meta_data.js_source(),
+ module_name: module_meta_data.module_name,
+ }),
+ )
+ }
+}
+
impl ThreadSafeState {
pub fn new(
flags: flags::DenoFlags,
diff --git a/cli/worker.rs b/cli/worker.rs
index c08a43385..f95826674 100644
--- a/cli/worker.rs
+++ b/cli/worker.rs
@@ -1,28 +1,25 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use crate::compiler::compile_async;
-use crate::compiler::ModuleMetaData;
use crate::errors::DenoError;
use crate::errors::RustOrJsError;
use crate::js_errors;
-use crate::msg;
use crate::state::ThreadSafeState;
use crate::tokio_util;
use deno;
use deno::Config;
use deno::JSError;
-use deno::Loader;
use deno::StartupData;
-use futures::future::Either;
use futures::Async;
use futures::Future;
-use std::sync::atomic::Ordering;
+use std::sync::Arc;
+use std::sync::Mutex;
use url::Url;
/// Wraps deno::Isolate to provide source maps, ops for the CLI, and
/// high-level module loading
+#[derive(Clone)]
pub struct Worker {
- inner: deno::Isolate,
- pub modules: deno::Modules,
+ inner: Arc<Mutex<deno::Isolate>>,
+ pub modules: Arc<Mutex<deno::Modules>>,
pub state: ThreadSafeState,
}
@@ -38,8 +35,8 @@ impl Worker {
state_.dispatch(control_buf, zero_copy_buf)
});
Self {
- inner: deno::Isolate::new(startup_data, config),
- modules: deno::Modules::new(),
+ inner: Arc::new(Mutex::new(deno::Isolate::new(startup_data, config))),
+ modules: Arc::new(Mutex::new(deno::Modules::new())),
state,
}
}
@@ -56,48 +53,55 @@ impl Worker {
js_filename: &str,
js_source: &str,
) -> Result<(), JSError> {
- self.inner.execute(js_filename, js_source)
+ let mut isolate = self.inner.lock().unwrap();
+ isolate.execute(js_filename, js_source)
}
/// Consumes worker. Executes the provided JavaScript module.
pub fn execute_mod_async(
- self,
+ &mut self,
js_url: &Url,
is_prefetch: bool,
- ) -> impl Future<Item = Self, Error = (RustOrJsError, Self)> {
- let recursive_load = deno::RecursiveLoad::new(js_url.as_str(), self);
- recursive_load.and_then(
- move |(id, mut self_)| -> Result<Self, (deno::JSErrorOr<DenoError>, Self)> {
- self_.state.progress.done();
+ ) -> impl Future<Item = (), Error = RustOrJsError> {
+ let worker = self.clone();
+ let worker_ = worker.clone();
+ let loader = self.state.clone();
+ let isolate = self.inner.clone();
+ let modules = self.modules.clone();
+ let recursive_load =
+ deno::RecursiveLoad::new(js_url.as_str(), loader, isolate, modules);
+ recursive_load
+ .and_then(move |id| -> Result<(), deno::JSErrorOr<DenoError>> {
+ worker.state.progress.done();
if is_prefetch {
- Ok(self_)
+ Ok(())
} else {
- let result = self_.inner.mod_evaluate(id);
+ let mut isolate = worker.inner.lock().unwrap();
+ let result = isolate.mod_evaluate(id);
if let Err(err) = result {
- Err((deno::JSErrorOr::JSError(err), self_))
+ Err(deno::JSErrorOr::JSError(err))
} else {
- Ok(self_)
+ Ok(())
}
}
- },
- )
- .map_err(|(err, self_)| {
- self_.state.progress.done();
- // Convert to RustOrJsError AND apply_source_map.
- let err = match err {
- deno::JSErrorOr::JSError(err) => RustOrJsError::Js(self_.apply_source_map(err)),
- deno::JSErrorOr::Other(err) => RustOrJsError::Rust(err),
- };
- (err, self_)
- })
+ }).map_err(move |err| {
+ worker_.state.progress.done();
+ // Convert to RustOrJsError AND apply_source_map.
+ match err {
+ deno::JSErrorOr::JSError(err) => {
+ RustOrJsError::Js(worker_.apply_source_map(err))
+ }
+ deno::JSErrorOr::Other(err) => RustOrJsError::Rust(err),
+ }
+ })
}
/// Consumes worker. Executes the provided JavaScript module.
pub fn execute_mod(
- self,
+ &mut self,
js_url: &Url,
is_prefetch: bool,
- ) -> Result<Self, (RustOrJsError, Self)> {
+ ) -> Result<(), RustOrJsError> {
tokio_util::block_on(self.execute_mod_async(js_url, is_prefetch))
}
@@ -159,103 +163,16 @@ pub fn root_specifier_to_url(
}
}
-impl Loader for Worker {
- type Error = DenoError;
-
- fn resolve(specifier: &str, referrer: &str) -> Result<String, Self::Error> {
- resolve_module_spec(specifier, referrer).map_err(DenoError::from)
- }
-
- /// Given an absolute url, load its source code.
- fn load(
- &mut self,
- url: &str,
- ) -> Box<deno::SourceCodeInfoFuture<Self::Error>> {
- self
- .state
- .metrics
- .resolve_count
- .fetch_add(1, Ordering::SeqCst);
- Box::new(
- fetch_module_meta_data_and_maybe_compile_async(&self.state, url, ".")
- .map_err(|err| {
- eprintln!("{}", err);
- err
- }).map(|module_meta_data| deno::SourceCodeInfo {
- // Real module name, might be different from initial URL
- // due to redirections.
- code: module_meta_data.js_source(),
- module_name: module_meta_data.module_name,
- }),
- )
- }
-
- fn isolate_and_modules<'a: 'b + 'c, 'b, 'c>(
- &'a mut self,
- ) -> (&'b mut deno::Isolate, &'c mut deno::Modules) {
- (&mut self.inner, &mut self.modules)
- }
-}
-
impl Future for Worker {
type Item = ();
type Error = JSError;
fn poll(&mut self) -> Result<Async<()>, Self::Error> {
- self.inner.poll().map_err(|err| self.apply_source_map(err))
+ let mut isolate = self.inner.lock().unwrap();
+ isolate.poll().map_err(|err| self.apply_source_map(err))
}
}
-fn fetch_module_meta_data_and_maybe_compile_async(
- state: &ThreadSafeState,
- specifier: &str,
- referrer: &str,
-) -> impl Future<Item = ModuleMetaData, Error = DenoError> {
- let state_ = state.clone();
- let specifier = specifier.to_string();
- let referrer = referrer.to_string();
-
- let f = futures::future::result(Worker::resolve(&specifier, &referrer));
- f.and_then(move |module_id| {
- let use_cache = !state_.flags.reload || state_.has_compiled(&module_id);
- let no_fetch = state_.flags.no_fetch;
-
- state_
- .dir
- .fetch_module_meta_data_async(&specifier, &referrer, use_cache, no_fetch)
- .and_then(move |out| {
- if out.media_type == msg::MediaType::TypeScript
- && !out.has_output_code_and_source_map()
- {
- debug!(">>>>> compile_sync START");
- Either::A(
- compile_async(state_.clone(), &specifier, &referrer, &out)
- .map_err(|e| {
- debug!("compiler error exiting!");
- eprintln!("\n{}", e.to_string());
- std::process::exit(1);
- }).and_then(move |out| {
- debug!(">>>>> compile_sync END");
- Ok(out)
- }),
- )
- } else {
- Either::B(futures::future::ok(out))
- }
- })
- })
-}
-
-pub fn fetch_module_meta_data_and_maybe_compile(
- state: &ThreadSafeState,
- specifier: &str,
- referrer: &str,
-) -> Result<ModuleMetaData, DenoError> {
- tokio_util::block_on(fetch_module_meta_data_and_maybe_compile_async(
- state, specifier, referrer,
- ))
-}
-
#[cfg(test)]
mod tests {
use super::*;
@@ -286,15 +203,12 @@ mod tests {
);
let state_ = state.clone();
tokio_util::run(lazy(move || {
- let worker = Worker::new("TEST".to_string(), StartupData::None, state);
+ let mut worker =
+ Worker::new("TEST".to_string(), StartupData::None, state);
let result = worker.execute_mod(&js_url, false);
- let worker = match result {
- Err((err, worker)) => {
- eprintln!("execute_mod err {:?}", err);
- worker
- }
- Ok(worker) => worker,
- };
+ if let Err(err) = result {
+ eprintln!("execute_mod err {:?}", err);
+ }
tokio_util::panic_on_error(worker)
}));
@@ -318,15 +232,12 @@ mod tests {
);
let state_ = state.clone();
tokio_util::run(lazy(move || {
- let worker = Worker::new("TEST".to_string(), StartupData::None, state);
+ let mut worker =
+ Worker::new("TEST".to_string(), StartupData::None, state);
let result = worker.execute_mod(&js_url, false);
- let worker = match result {
- Err((err, worker)) => {
- eprintln!("execute_mod err {:?}", err);
- worker
- }
- Ok(worker) => worker,
- };
+ if let Err(err) = result {
+ eprintln!("execute_mod err {:?}", err);
+ }
tokio_util::panic_on_error(worker)
}));
@@ -356,13 +267,9 @@ mod tests {
);
js_check(worker.execute("denoMain()"));
let result = worker.execute_mod(&js_url, false);
- let worker = match result {
- Err((err, worker)) => {
- eprintln!("execute_mod err {:?}", err);
- worker
- }
- Ok(worker) => worker,
- };
+ if let Err(err) = result {
+ eprintln!("execute_mod err {:?}", err);
+ }
tokio_util::panic_on_error(worker)
}));
@@ -470,7 +377,7 @@ mod tests {
fn execute_mod_resolve_error() {
tokio_util::init(|| {
// "foo" is not a vailid module specifier so this should return an error.
- let worker = create_test_worker();
+ let mut worker = create_test_worker();
let js_url = root_specifier_to_url("does-not-exist").unwrap();
let result = worker.execute_mod_async(&js_url, false).wait();
assert!(result.is_err());
@@ -482,7 +389,7 @@ mod tests {
tokio_util::init(|| {
// This assumes cwd is project root (an assumption made throughout the
// tests).
- let worker = create_test_worker();
+ let mut worker = create_test_worker();
let js_url = root_specifier_to_url("./tests/002_hello.ts").unwrap();
let result = worker.execute_mod_async(&js_url, false).wait();
assert!(result.is_ok());