Skip to content

Commit

Permalink
RecursiveLoad shouldn't own the Isolate (#2453)
Browse files Browse the repository at this point in the history
This patch makes it so that RecursiveLoad doesn't own the Isolate, so
Worker::execute_mod_async does not consume itself.

Previously Worker implemented Loader, but now ThreadSafeState does.

This is necessary preparation work for dynamic import (#1789) and import
maps (#1921)
  • Loading branch information
ry authored Jun 5, 2019
1 parent 6fa4d2e commit e152dae
Show file tree
Hide file tree
Showing 5 changed files with 251 additions and 249 deletions.
14 changes: 7 additions & 7 deletions cli/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -193,15 +193,15 @@ 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);
}
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);
}
Expand Down Expand Up @@ -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);
}
Expand Down
8 changes: 3 additions & 5 deletions cli/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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),
}
}()))
}
Expand Down
85 changes: 85 additions & 0 deletions cli/state.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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,
Expand Down
Loading

0 comments on commit e152dae

Please sign in to comment.