From bdc97b3976786bb744a27e59b0f4f28554a682df Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Wed, 21 Aug 2019 20:42:48 -0400 Subject: [PATCH] Organize dispatch a bit (#2796) Just some clean up reorganization around flatbuffer/minimal dispatch code. This is prep for adding a JSON dispatcher. --- cli/BUILD.gn | 1 + cli/main.rs | 8 +- cli/ops/compiler.rs | 6 +- cli/ops/dispatch_flatbuffers.rs | 216 +++++++++++++ cli/{ => ops}/dispatch_minimal.rs | 76 +---- cli/ops/errors.rs | 5 +- cli/ops/fetch.rs | 4 +- cli/ops/files.rs | 6 +- cli/ops/fs.rs | 8 +- cli/ops/io.rs | 43 +++ cli/ops/metrics.rs | 5 +- cli/ops/mod.rs | 293 ++---------------- cli/ops/net.rs | 13 +- cli/ops/os.rs | 6 +- cli/ops/performance.rs | 5 +- cli/ops/permissions.rs | 6 +- cli/ops/process.rs | 6 +- cli/ops/random.rs | 4 +- cli/ops/repl.rs | 8 +- cli/ops/resources.rs | 6 +- cli/ops/timers.rs | 6 +- cli/ops/utils.rs | 48 +++ cli/ops/workers.rs | 8 +- cli/state.rs | 7 +- cli/worker.rs | 6 +- js/chmod.ts | 8 +- js/chown.ts | 8 +- js/compiler.ts | 4 +- js/copy_file.ts | 8 +- js/dir.ts | 4 +- js/dispatch.ts | 156 +--------- js/dispatch_flatbuffers.ts | 151 +++++++++ js/dispatch_minimal.ts | 13 +- js/error_stack.ts | 6 +- js/errors.ts | 20 +- js/fetch.ts | 4 +- js/files.ts | 22 +- js/format_error.ts | 4 +- js/get_random_values.ts | 6 +- js/link.ts | 8 +- js/make_temp_dir.ts | 8 +- js/metrics.ts | 6 +- js/mkdir.ts | 8 +- js/net.ts | 12 +- js/os.ts | 5 +- js/performance.ts | 4 +- js/permissions.ts | 8 +- js/process.ts | 10 +- js/read_dir.ts | 8 +- js/read_link.ts | 8 +- js/remove.ts | 8 +- js/rename.ts | 8 +- js/repl.ts | 12 +- js/resources.ts | 6 +- js/stat.ts | 12 +- js/symlink.ts | 8 +- js/timers.ts | 4 +- js/truncate.ts | 8 +- js/utime.ts | 8 +- js/workers.ts | 4 +- tests/error_004_missing_module.ts.out | 8 +- tests/error_005_missing_dynamic_import.ts.out | 8 +- tests/error_006_import_ext_failure.ts.out | 8 +- tests/error_011_bad_module_specifier.ts.out | 8 +- ...or_012_bad_dynamic_import_specifier.ts.out | 8 +- 65 files changed, 663 insertions(+), 754 deletions(-) create mode 100644 cli/ops/dispatch_flatbuffers.rs rename cli/{ => ops}/dispatch_minimal.rs (58%) create mode 100644 cli/ops/io.rs create mode 100644 cli/ops/utils.rs create mode 100644 js/dispatch_flatbuffers.ts diff --git a/cli/BUILD.gn b/cli/BUILD.gn index 0a6c9875e7..3a5912471c 100644 --- a/cli/BUILD.gn +++ b/cli/BUILD.gn @@ -82,6 +82,7 @@ ts_sources = [ "../js/diagnostics.ts", "../js/dir.ts", "../js/dispatch.ts", + "../js/dispatch_flatbuffers.ts", "../js/dispatch_minimal.ts", "../js/dom_types.ts", "../js/dom_util.ts", diff --git a/cli/main.rs b/cli/main.rs index 01469e4425..3f8f113b22 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -21,7 +21,6 @@ pub mod deno_dir; pub mod deno_error; pub mod diagnostics; mod disk_cache; -mod dispatch_minimal; mod file_fetcher; pub mod flags; pub mod fmt_errors; @@ -114,10 +113,9 @@ fn create_worker_and_state( } }); // TODO(kevinkassimo): maybe make include_deno_namespace also configurable? - let state = - ThreadSafeState::new(flags, argv, ops::op_selector_std, progress, true) - .map_err(print_err_and_exit) - .unwrap(); + let state = ThreadSafeState::new(flags, argv, progress, true) + .map_err(print_err_and_exit) + .unwrap(); let worker = Worker::new( "main".to_string(), startup_data::deno_isolate_init(), diff --git a/cli/ops/compiler.rs b/cli/ops/compiler.rs index 8d75668c1f..efdcd2c9b1 100644 --- a/cli/ops/compiler.rs +++ b/cli/ops/compiler.rs @@ -1,10 +1,8 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::*; use crate::deno_error; use crate::msg; -use crate::ops::empty_buf; -use crate::ops::ok_buf; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; use crate::state::ThreadSafeState; use crate::tokio_util; use deno::*; diff --git a/cli/ops/dispatch_flatbuffers.rs b/cli/ops/dispatch_flatbuffers.rs new file mode 100644 index 0000000000..2b2e5050df --- /dev/null +++ b/cli/ops/dispatch_flatbuffers.rs @@ -0,0 +1,216 @@ +use super::utils::CliOpResult; +use crate::deno_error::GetErrorKind; +use crate::msg; +use crate::state::ThreadSafeState; +use deno::*; +use flatbuffers::FlatBufferBuilder; +use hyper::rt::Future; + +use super::compiler::{op_cache, op_fetch_source_file}; +use super::errors::{op_apply_source_map, op_format_error}; +use super::fetch::op_fetch; +use super::files::{op_close, op_open, op_read, op_seek, op_write}; +use super::fs::{ + op_chdir, op_chmod, op_chown, op_copy_file, op_cwd, op_link, + op_make_temp_dir, op_mkdir, op_read_dir, op_read_link, op_remove, op_rename, + op_stat, op_symlink, op_truncate, op_utime, +}; +use super::metrics::op_metrics; +use super::net::{op_accept, op_dial, op_listen, op_shutdown}; +use super::os::{ + op_env, op_exec_path, op_exit, op_home_dir, op_is_tty, op_set_env, op_start, +}; +use super::performance::op_now; +use super::permissions::{op_permissions, op_revoke_permission}; +use super::process::{op_kill, op_run, op_run_status}; +use super::random::op_get_random_values; +use super::repl::{op_repl_readline, op_repl_start}; +use super::resources::op_resources; +use super::timers::{op_global_timer, op_global_timer_stop}; +use super::workers::{ + op_create_worker, op_host_get_message, op_host_get_worker_closed, + op_host_post_message, op_worker_get_message, op_worker_post_message, +}; + +type CliDispatchFn = fn( + state: &ThreadSafeState, + base: &msg::Base<'_>, + data: Option, +) -> CliOpResult; + +/// Processes raw messages from JavaScript. +/// This functions invoked every time Deno.core.dispatch() is called. +/// control corresponds to the first argument of Deno.core.dispatch(). +/// data corresponds to the second argument of Deno.core.dispatch(). +pub fn dispatch( + state: &ThreadSafeState, + control: &[u8], + zero_copy: Option, +) -> CoreOp { + let base = msg::get_root_as_base(&control); + let inner_type = base.inner_type(); + let is_sync = base.sync(); + let cmd_id = base.cmd_id(); + + debug!( + "msg_from_js {} sync {}", + msg::enum_name_any(inner_type), + is_sync + ); + + let op_func: CliDispatchFn = match op_selector_std(inner_type) { + Some(v) => v, + None => panic!("Unhandled message {}", msg::enum_name_any(inner_type)), + }; + + let op_result = op_func(state, &base, zero_copy); + + let state = state.clone(); + + match op_result { + Ok(Op::Sync(buf)) => { + state.metrics_op_completed(buf.len()); + Op::Sync(buf) + } + Ok(Op::Async(fut)) => { + let result_fut = Box::new( + fut + .or_else(move |err: ErrBox| -> Result { + debug!("op err {}", err); + // No matter whether we got an Err or Ok, we want a serialized message to + // send back. So transform the DenoError into a Buf. + let builder = &mut FlatBufferBuilder::new(); + let errmsg_offset = builder.create_string(&format!("{}", err)); + Ok(serialize_response( + cmd_id, + builder, + msg::BaseArgs { + error: Some(errmsg_offset), + error_kind: err.kind(), + ..Default::default() + }, + )) + }) + .and_then(move |buf: Buf| -> Result { + // Handle empty responses. For sync responses we just want + // to send null. For async we want to send a small message + // with the cmd_id. + let buf = if buf.len() > 0 { + buf + } else { + let builder = &mut FlatBufferBuilder::new(); + serialize_response( + cmd_id, + builder, + msg::BaseArgs { + ..Default::default() + }, + ) + }; + state.metrics_op_completed(buf.len()); + Ok(buf) + }) + .map_err(|err| panic!("unexpected error {:?}", err)), + ); + Op::Async(result_fut) + } + Err(err) => { + debug!("op err {}", err); + // No matter whether we got an Err or Ok, we want a serialized message to + // send back. So transform the DenoError into a Buf. + let builder = &mut FlatBufferBuilder::new(); + let errmsg_offset = builder.create_string(&format!("{}", err)); + let response_buf = serialize_response( + cmd_id, + builder, + msg::BaseArgs { + error: Some(errmsg_offset), + error_kind: err.kind(), + ..Default::default() + }, + ); + state.metrics_op_completed(response_buf.len()); + Op::Sync(response_buf) + } + } +} + +pub fn serialize_response( + cmd_id: u32, + builder: &mut FlatBufferBuilder<'_>, + mut args: msg::BaseArgs<'_>, +) -> Buf { + args.cmd_id = cmd_id; + let base = msg::Base::create(builder, &args); + msg::finish_base_buffer(builder, base); + let data = builder.finished_data(); + // println!("serialize_response {:x?}", data); + data.into() +} + +/// Standard ops set for most isolates +pub fn op_selector_std(inner_type: msg::Any) -> Option { + match inner_type { + msg::Any::Accept => Some(op_accept), + msg::Any::ApplySourceMap => Some(op_apply_source_map), + msg::Any::Cache => Some(op_cache), + msg::Any::Chdir => Some(op_chdir), + msg::Any::Chmod => Some(op_chmod), + msg::Any::Chown => Some(op_chown), + msg::Any::Close => Some(op_close), + msg::Any::CopyFile => Some(op_copy_file), + msg::Any::CreateWorker => Some(op_create_worker), + msg::Any::Cwd => Some(op_cwd), + msg::Any::Dial => Some(op_dial), + msg::Any::Environ => Some(op_env), + msg::Any::ExecPath => Some(op_exec_path), + msg::Any::Exit => Some(op_exit), + msg::Any::Fetch => Some(op_fetch), + msg::Any::FetchSourceFile => Some(op_fetch_source_file), + msg::Any::FormatError => Some(op_format_error), + msg::Any::GetRandomValues => Some(op_get_random_values), + msg::Any::GlobalTimer => Some(op_global_timer), + msg::Any::GlobalTimerStop => Some(op_global_timer_stop), + msg::Any::HostGetMessage => Some(op_host_get_message), + msg::Any::HostGetWorkerClosed => Some(op_host_get_worker_closed), + msg::Any::HostPostMessage => Some(op_host_post_message), + msg::Any::IsTTY => Some(op_is_tty), + msg::Any::Kill => Some(op_kill), + msg::Any::Link => Some(op_link), + msg::Any::Listen => Some(op_listen), + msg::Any::MakeTempDir => Some(op_make_temp_dir), + msg::Any::Metrics => Some(op_metrics), + msg::Any::Mkdir => Some(op_mkdir), + msg::Any::Now => Some(op_now), + msg::Any::Open => Some(op_open), + msg::Any::PermissionRevoke => Some(op_revoke_permission), + msg::Any::Permissions => Some(op_permissions), + msg::Any::Read => Some(op_read), + msg::Any::ReadDir => Some(op_read_dir), + msg::Any::Readlink => Some(op_read_link), + msg::Any::Remove => Some(op_remove), + msg::Any::Rename => Some(op_rename), + msg::Any::ReplReadline => Some(op_repl_readline), + msg::Any::ReplStart => Some(op_repl_start), + msg::Any::Resources => Some(op_resources), + msg::Any::Run => Some(op_run), + msg::Any::RunStatus => Some(op_run_status), + msg::Any::Seek => Some(op_seek), + msg::Any::SetEnv => Some(op_set_env), + msg::Any::Shutdown => Some(op_shutdown), + msg::Any::Start => Some(op_start), + msg::Any::Stat => Some(op_stat), + msg::Any::Symlink => Some(op_symlink), + msg::Any::Truncate => Some(op_truncate), + msg::Any::HomeDir => Some(op_home_dir), + msg::Any::Utime => Some(op_utime), + msg::Any::Write => Some(op_write), + + // TODO(ry) split these out so that only the appropriate Workers can access + // them. + msg::Any::WorkerGetMessage => Some(op_worker_get_message), + msg::Any::WorkerPostMessage => Some(op_worker_post_message), + + _ => None, + } +} diff --git a/cli/dispatch_minimal.rs b/cli/ops/dispatch_minimal.rs similarity index 58% rename from cli/dispatch_minimal.rs rename to cli/ops/dispatch_minimal.rs index 322094be2d..37ad568132 100644 --- a/cli/dispatch_minimal.rs +++ b/cli/ops/dispatch_minimal.rs @@ -7,13 +7,13 @@ use crate::state::ThreadSafeState; use deno::Buf; use deno::CoreOp; +use deno::ErrBox; use deno::Op; -use deno::OpId; use deno::PinnedBuf; use futures::Future; -const OP_READ: OpId = 1; -const OP_WRITE: OpId = 2; +pub type MinimalOp = dyn Future + Send; +pub type Dispatcher = fn(i32, Option) -> Box; #[derive(Copy, Clone, Debug, PartialEq)] // This corresponds to RecordMinimal on the TS side. @@ -72,21 +72,24 @@ fn test_parse_min_record() { assert_eq!(parse_min_record(&buf), None); } -pub fn dispatch_minimal( +pub fn dispatch( + d: Dispatcher, state: &ThreadSafeState, - op_id: OpId, - mut record: Record, + control: &[u8], zero_copy: Option, ) -> CoreOp { + let mut record = parse_min_record(control).unwrap(); let is_sync = record.promise_id == 0; - let min_op = match op_id { - OP_READ => ops::read(record.arg, zero_copy), - OP_WRITE => ops::write(record.arg, zero_copy), - _ => unimplemented!(), - }; + + // TODO(ry) Currently there aren't any sync minimal ops. This is just a sanity + // check. Remove later. + assert!(!is_sync); let state = state.clone(); + let rid = record.arg; + let min_op = d(rid, zero_copy); + let fut = Box::new(min_op.then(move |result| -> Result { match result { Ok(r) => { @@ -109,54 +112,3 @@ pub fn dispatch_minimal( Op::Async(fut) } } - -mod ops { - use crate::deno_error; - use crate::resources; - use crate::tokio_write; - use deno::ErrBox; - use deno::PinnedBuf; - use futures::Future; - - type MinimalOp = dyn Future + Send; - - pub fn read(rid: i32, zero_copy: Option) -> Box { - debug!("read rid={}", rid); - let zero_copy = match zero_copy { - None => { - return Box::new( - futures::future::err(deno_error::no_buffer_specified()), - ) - } - Some(buf) => buf, - }; - match resources::lookup(rid as u32) { - None => Box::new(futures::future::err(deno_error::bad_resource())), - Some(resource) => Box::new( - tokio::io::read(resource, zero_copy) - .map_err(ErrBox::from) - .and_then(move |(_resource, _buf, nread)| Ok(nread as i32)), - ), - } - } - - pub fn write(rid: i32, zero_copy: Option) -> Box { - debug!("write rid={}", rid); - let zero_copy = match zero_copy { - None => { - return Box::new( - futures::future::err(deno_error::no_buffer_specified()), - ) - } - Some(buf) => buf, - }; - match resources::lookup(rid as u32) { - None => Box::new(futures::future::err(deno_error::bad_resource())), - Some(resource) => Box::new( - tokio_write::write(resource, zero_copy) - .map_err(ErrBox::from) - .and_then(move |(_resource, _buf, nwritten)| Ok(nwritten as i32)), - ), - } - } -} diff --git a/cli/ops/errors.rs b/cli/ops/errors.rs index 16dfc34fd6..a27f3656ee 100644 --- a/cli/ops/errors.rs +++ b/cli/ops/errors.rs @@ -1,10 +1,9 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::*; use crate::deno_error; use crate::fmt_errors::JSError; use crate::msg; -use crate::ops::ok_buf; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; use crate::source_maps::get_orig_position; use crate::source_maps::CachedMaps; use crate::state::ThreadSafeState; diff --git a/cli/ops/fetch.rs b/cli/ops/fetch.rs index e4f57972fe..7661eb6e9d 100644 --- a/cli/ops/fetch.rs +++ b/cli/ops/fetch.rs @@ -1,9 +1,9 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::CliOpResult; use crate::http_util; use crate::msg; use crate::msg_util; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; use crate::resources; use crate::state::ThreadSafeState; use deno::*; diff --git a/cli/ops/files.rs b/cli/ops/files.rs index ce32856235..023bd65f92 100644 --- a/cli/ops/files.rs +++ b/cli/ops/files.rs @@ -1,11 +1,9 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::*; use crate::deno_error; use crate::fs as deno_fs; use crate::msg; -use crate::ops::empty_buf; -use crate::ops::ok_buf; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; use crate::resources; use crate::state::ThreadSafeState; use crate::tokio_write; diff --git a/cli/ops/fs.rs b/cli/ops/fs.rs index 6530e3816e..d46ed91e1c 100644 --- a/cli/ops/fs.rs +++ b/cli/ops/fs.rs @@ -1,18 +1,14 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::*; use crate::deno_error::DenoError; use crate::deno_error::ErrorKind; use crate::fs as deno_fs; use crate::msg; -use crate::ops::blocking; -use crate::ops::empty_buf; -use crate::ops::ok_buf; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; use crate::state::ThreadSafeState; use deno::*; use flatbuffers::FlatBufferBuilder; use remove_dir_all::remove_dir_all; -use std; use std::convert::From; use std::fs; use std::path::PathBuf; diff --git a/cli/ops/io.rs b/cli/ops/io.rs new file mode 100644 index 0000000000..6102389420 --- /dev/null +++ b/cli/ops/io.rs @@ -0,0 +1,43 @@ +use super::dispatch_minimal::MinimalOp; +use crate::deno_error; +use crate::resources; +use crate::tokio_write; +use deno::ErrBox; +use deno::PinnedBuf; +use futures::Future; + +pub fn op_read(rid: i32, zero_copy: Option) -> Box { + debug!("read rid={}", rid); + let zero_copy = match zero_copy { + None => { + return Box::new(futures::future::err(deno_error::no_buffer_specified())) + } + Some(buf) => buf, + }; + match resources::lookup(rid as u32) { + None => Box::new(futures::future::err(deno_error::bad_resource())), + Some(resource) => Box::new( + tokio::io::read(resource, zero_copy) + .map_err(ErrBox::from) + .and_then(move |(_resource, _buf, nread)| Ok(nread as i32)), + ), + } +} + +pub fn op_write(rid: i32, zero_copy: Option) -> Box { + debug!("write rid={}", rid); + let zero_copy = match zero_copy { + None => { + return Box::new(futures::future::err(deno_error::no_buffer_specified())) + } + Some(buf) => buf, + }; + match resources::lookup(rid as u32) { + None => Box::new(futures::future::err(deno_error::bad_resource())), + Some(resource) => Box::new( + tokio_write::write(resource, zero_copy) + .map_err(ErrBox::from) + .and_then(move |(_resource, _buf, nwritten)| Ok(nwritten as i32)), + ), + } +} diff --git a/cli/ops/metrics.rs b/cli/ops/metrics.rs index 7d821f1fa7..76f36c3904 100644 --- a/cli/ops/metrics.rs +++ b/cli/ops/metrics.rs @@ -1,8 +1,7 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::*; use crate::msg; -use crate::ops::ok_buf; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; use crate::state::ThreadSafeState; use deno::*; use flatbuffers::FlatBufferBuilder; diff --git a/cli/ops/mod.rs b/cli/ops/mod.rs index 021c0fa471..92c0f8e62b 100644 --- a/cli/ops/mod.rs +++ b/cli/ops/mod.rs @@ -1,305 +1,52 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -use crate::deno_error::GetErrorKind; -use crate::dispatch_minimal::dispatch_minimal; -use crate::dispatch_minimal::parse_min_record; -use crate::msg; use crate::state::ThreadSafeState; -use crate::tokio_util; use deno::*; -use flatbuffers::FlatBufferBuilder; -use futures; -use futures::Poll; -use hyper; -use hyper::rt::Future; -use tokio_threadpool; mod compiler; -use compiler::{op_cache, op_fetch_source_file}; +mod dispatch_flatbuffers; +mod dispatch_minimal; mod errors; -use errors::{op_apply_source_map, op_format_error}; -mod files; -use files::{op_close, op_open, op_read, op_seek, op_write}; mod fetch; -use fetch::op_fetch; +mod files; mod fs; -use fs::{ - op_chdir, op_chmod, op_chown, op_copy_file, op_cwd, op_link, - op_make_temp_dir, op_mkdir, op_read_dir, op_read_link, op_remove, op_rename, - op_stat, op_symlink, op_truncate, op_utime, -}; +mod io; mod metrics; -use metrics::op_metrics; mod net; -use net::{op_accept, op_dial, op_listen, op_shutdown}; mod os; -use os::{ - op_env, op_exec_path, op_exit, op_home_dir, op_is_tty, op_set_env, op_start, -}; mod performance; -use performance::op_now; mod permissions; -use permissions::{op_permissions, op_revoke_permission}; mod process; -use process::{op_kill, op_run, op_run_status}; mod random; -use random::op_get_random_values; mod repl; -use repl::{op_repl_readline, op_repl_start}; mod resources; -use resources::op_resources; mod timers; -use timers::{op_global_timer, op_global_timer_stop}; +mod utils; mod workers; -use workers::{ - op_create_worker, op_host_get_message, op_host_get_worker_closed, - op_host_post_message, op_worker_get_message, op_worker_post_message, -}; -type CliOpResult = OpResult; +pub const OP_FLATBUFFER: OpId = 44; +pub const OP_READ: OpId = 1; +pub const OP_WRITE: OpId = 2; -type CliDispatchFn = fn( - state: &ThreadSafeState, - base: &msg::Base<'_>, - data: Option, -) -> CliOpResult; - -pub type OpSelector = fn(inner_type: msg::Any) -> Option; - -#[inline] -fn empty_buf() -> Buf { - Box::new([]) -} - -const FLATBUFFER_OP_ID: OpId = 44; - -pub fn dispatch_all( +pub fn dispatch( state: &ThreadSafeState, op_id: OpId, control: &[u8], zero_copy: Option, - op_selector: OpSelector, ) -> CoreOp { let bytes_sent_control = control.len(); let bytes_sent_zero_copy = zero_copy.as_ref().map(|b| b.len()).unwrap_or(0); - let op = if op_id != FLATBUFFER_OP_ID { - let min_record = parse_min_record(control).unwrap(); - dispatch_minimal(state, op_id, min_record, zero_copy) - } else { - dispatch_all_legacy(state, control, zero_copy, op_selector) + + let op = match op_id { + OP_READ => { + dispatch_minimal::dispatch(io::op_read, state, control, zero_copy) + } + OP_WRITE => { + dispatch_minimal::dispatch(io::op_write, state, control, zero_copy) + } + OP_FLATBUFFER => dispatch_flatbuffers::dispatch(state, control, zero_copy), + _ => panic!("bad op_id"), }; + state.metrics_op_dispatched(bytes_sent_control, bytes_sent_zero_copy); op } - -/// Processes raw messages from JavaScript. -/// This functions invoked every time Deno.core.dispatch() is called. -/// control corresponds to the first argument of Deno.core.dispatch(). -/// data corresponds to the second argument of Deno.core.dispatch(). -pub fn dispatch_all_legacy( - state: &ThreadSafeState, - control: &[u8], - zero_copy: Option, - op_selector: OpSelector, -) -> CoreOp { - let base = msg::get_root_as_base(&control); - let inner_type = base.inner_type(); - let is_sync = base.sync(); - let cmd_id = base.cmd_id(); - - debug!( - "msg_from_js {} sync {}", - msg::enum_name_any(inner_type), - is_sync - ); - - let op_func: CliDispatchFn = match op_selector(inner_type) { - Some(v) => v, - None => panic!("Unhandled message {}", msg::enum_name_any(inner_type)), - }; - - let op_result = op_func(state, &base, zero_copy); - - let state = state.clone(); - - match op_result { - Ok(Op::Sync(buf)) => { - state.metrics_op_completed(buf.len()); - Op::Sync(buf) - } - Ok(Op::Async(fut)) => { - let result_fut = Box::new( - fut - .or_else(move |err: ErrBox| -> Result { - debug!("op err {}", err); - // No matter whether we got an Err or Ok, we want a serialized message to - // send back. So transform the DenoError into a Buf. - let builder = &mut FlatBufferBuilder::new(); - let errmsg_offset = builder.create_string(&format!("{}", err)); - Ok(serialize_response( - cmd_id, - builder, - msg::BaseArgs { - error: Some(errmsg_offset), - error_kind: err.kind(), - ..Default::default() - }, - )) - }) - .and_then(move |buf: Buf| -> Result { - // Handle empty responses. For sync responses we just want - // to send null. For async we want to send a small message - // with the cmd_id. - let buf = if buf.len() > 0 { - buf - } else { - let builder = &mut FlatBufferBuilder::new(); - serialize_response( - cmd_id, - builder, - msg::BaseArgs { - ..Default::default() - }, - ) - }; - state.metrics_op_completed(buf.len()); - Ok(buf) - }) - .map_err(|err| panic!("unexpected error {:?}", err)), - ); - Op::Async(result_fut) - } - Err(err) => { - debug!("op err {}", err); - // No matter whether we got an Err or Ok, we want a serialized message to - // send back. So transform the DenoError into a Buf. - let builder = &mut FlatBufferBuilder::new(); - let errmsg_offset = builder.create_string(&format!("{}", err)); - let response_buf = serialize_response( - cmd_id, - builder, - msg::BaseArgs { - error: Some(errmsg_offset), - error_kind: err.kind(), - ..Default::default() - }, - ); - state.metrics_op_completed(response_buf.len()); - Op::Sync(response_buf) - } - } -} - -/// Standard ops set for most isolates -pub fn op_selector_std(inner_type: msg::Any) -> Option { - match inner_type { - msg::Any::Accept => Some(op_accept), - msg::Any::ApplySourceMap => Some(op_apply_source_map), - msg::Any::Cache => Some(op_cache), - msg::Any::Chdir => Some(op_chdir), - msg::Any::Chmod => Some(op_chmod), - msg::Any::Chown => Some(op_chown), - msg::Any::Close => Some(op_close), - msg::Any::CopyFile => Some(op_copy_file), - msg::Any::CreateWorker => Some(op_create_worker), - msg::Any::Cwd => Some(op_cwd), - msg::Any::Dial => Some(op_dial), - msg::Any::Environ => Some(op_env), - msg::Any::ExecPath => Some(op_exec_path), - msg::Any::Exit => Some(op_exit), - msg::Any::Fetch => Some(op_fetch), - msg::Any::FetchSourceFile => Some(op_fetch_source_file), - msg::Any::FormatError => Some(op_format_error), - msg::Any::GetRandomValues => Some(op_get_random_values), - msg::Any::GlobalTimer => Some(op_global_timer), - msg::Any::GlobalTimerStop => Some(op_global_timer_stop), - msg::Any::HostGetMessage => Some(op_host_get_message), - msg::Any::HostGetWorkerClosed => Some(op_host_get_worker_closed), - msg::Any::HostPostMessage => Some(op_host_post_message), - msg::Any::IsTTY => Some(op_is_tty), - msg::Any::Kill => Some(op_kill), - msg::Any::Link => Some(op_link), - msg::Any::Listen => Some(op_listen), - msg::Any::MakeTempDir => Some(op_make_temp_dir), - msg::Any::Metrics => Some(op_metrics), - msg::Any::Mkdir => Some(op_mkdir), - msg::Any::Now => Some(op_now), - msg::Any::Open => Some(op_open), - msg::Any::PermissionRevoke => Some(op_revoke_permission), - msg::Any::Permissions => Some(op_permissions), - msg::Any::Read => Some(op_read), - msg::Any::ReadDir => Some(op_read_dir), - msg::Any::Readlink => Some(op_read_link), - msg::Any::Remove => Some(op_remove), - msg::Any::Rename => Some(op_rename), - msg::Any::ReplReadline => Some(op_repl_readline), - msg::Any::ReplStart => Some(op_repl_start), - msg::Any::Resources => Some(op_resources), - msg::Any::Run => Some(op_run), - msg::Any::RunStatus => Some(op_run_status), - msg::Any::Seek => Some(op_seek), - msg::Any::SetEnv => Some(op_set_env), - msg::Any::Shutdown => Some(op_shutdown), - msg::Any::Start => Some(op_start), - msg::Any::Stat => Some(op_stat), - msg::Any::Symlink => Some(op_symlink), - msg::Any::Truncate => Some(op_truncate), - msg::Any::HomeDir => Some(op_home_dir), - msg::Any::Utime => Some(op_utime), - msg::Any::Write => Some(op_write), - - // TODO(ry) split these out so that only the appropriate Workers can access - // them. - msg::Any::WorkerGetMessage => Some(op_worker_get_message), - msg::Any::WorkerPostMessage => Some(op_worker_post_message), - - _ => None, - } -} - -fn serialize_response( - cmd_id: u32, - builder: &mut FlatBufferBuilder<'_>, - mut args: msg::BaseArgs<'_>, -) -> Buf { - args.cmd_id = cmd_id; - let base = msg::Base::create(builder, &args); - msg::finish_base_buffer(builder, base); - let data = builder.finished_data(); - // println!("serialize_response {:x?}", data); - data.into() -} - -#[inline] -fn ok_buf(buf: Buf) -> CliOpResult { - Ok(Op::Sync(buf)) -} - -// This is just type conversion. Implement From trait? -// See https://github.com/tokio-rs/tokio/blob/ffd73a64e7ec497622b7f939e38017afe7124dc4/tokio-fs/src/lib.rs#L76-L85 -fn convert_blocking(f: F) -> Poll -where - F: FnOnce() -> Result, -{ - use futures::Async::*; - match tokio_threadpool::blocking(f) { - Ok(Ready(Ok(v))) => Ok(v.into()), - Ok(Ready(Err(err))) => Err(err), - Ok(NotReady) => Ok(NotReady), - Err(err) => panic!("blocking error {}", err), - } -} - -fn blocking(is_sync: bool, f: F) -> CliOpResult -where - F: 'static + Send + FnOnce() -> Result, -{ - if is_sync { - let result_buf = f()?; - Ok(Op::Sync(result_buf)) - } else { - Ok(Op::Async(Box::new(futures::sync::oneshot::spawn( - tokio_util::poll_fn(move || convert_blocking(f)), - &tokio_executor::DefaultExecutor::current(), - )))) - } -} diff --git a/cli/ops/net.rs b/cli/ops/net.rs index 16a24872df..5ce5624922 100644 --- a/cli/ops/net.rs +++ b/cli/ops/net.rs @@ -1,10 +1,9 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::*; use crate::deno_error; use crate::msg; -use crate::ops::empty_buf; -use crate::ops::ok_buf; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; +use crate::resolve_addr::resolve_addr; use crate::resources; use crate::resources::Resource; use crate::state::ThreadSafeState; @@ -13,16 +12,12 @@ use deno::*; use flatbuffers::FlatBufferBuilder; use futures::Future; use std; +use std::convert::From; use std::net::Shutdown; use tokio; - -use crate::resolve_addr::resolve_addr; -use std::convert::From; use tokio::net::TcpListener; use tokio::net::TcpStream; -use crate::ops::blocking; - pub fn op_accept( _state: &ThreadSafeState, base: &msg::Base<'_>, diff --git a/cli/ops/os.rs b/cli/ops/os.rs index cd165aa05a..fbf430d7ad 100644 --- a/cli/ops/os.rs +++ b/cli/ops/os.rs @@ -1,12 +1,10 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::*; use crate::ansi; use crate::fs as deno_fs; use crate::msg; use crate::msg_util; -use crate::ops::empty_buf; -use crate::ops::ok_buf; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; use crate::state::ThreadSafeState; use crate::version; use atty; diff --git a/cli/ops/performance.rs b/cli/ops/performance.rs index ae2a0b860e..94f6dbc387 100644 --- a/cli/ops/performance.rs +++ b/cli/ops/performance.rs @@ -1,8 +1,7 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::*; use crate::msg; -use crate::ops::ok_buf; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; use crate::state::ThreadSafeState; use deno::*; use flatbuffers::FlatBufferBuilder; diff --git a/cli/ops/permissions.rs b/cli/ops/permissions.rs index 47a9cf8714..6249581fb0 100644 --- a/cli/ops/permissions.rs +++ b/cli/ops/permissions.rs @@ -1,9 +1,7 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::*; use crate::msg; -use crate::ops::empty_buf; -use crate::ops::ok_buf; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; use crate::state::ThreadSafeState; use deno::*; use flatbuffers::FlatBufferBuilder; diff --git a/cli/ops/process.rs b/cli/ops/process.rs index 914b8ba86c..d7b326d143 100644 --- a/cli/ops/process.rs +++ b/cli/ops/process.rs @@ -1,10 +1,8 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::*; use crate::deno_error; use crate::msg; -use crate::ops::empty_buf; -use crate::ops::ok_buf; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; use crate::resources; use crate::signal::kill; use crate::state::ThreadSafeState; diff --git a/cli/ops/random.rs b/cli/ops/random.rs index 27e120faa6..0c302a0808 100644 --- a/cli/ops/random.rs +++ b/cli/ops/random.rs @@ -1,8 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::utils::*; use crate::msg; -use crate::ops::empty_buf; -use crate::ops::ok_buf; -use crate::ops::CliOpResult; use crate::state::ThreadSafeState; use deno::*; use rand::thread_rng; diff --git a/cli/ops/repl.rs b/cli/ops/repl.rs index 2fff389a17..affe787391 100644 --- a/cli/ops/repl.rs +++ b/cli/ops/repl.rs @@ -1,9 +1,9 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::blocking; +use super::utils::ok_buf; +use super::utils::CliOpResult; use crate::msg; -use crate::ops::blocking; -use crate::ops::ok_buf; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; use crate::repl; use crate::resources; use crate::state::ThreadSafeState; diff --git a/cli/ops/resources.rs b/cli/ops/resources.rs index 410d69c80c..975d94490b 100644 --- a/cli/ops/resources.rs +++ b/cli/ops/resources.rs @@ -1,8 +1,8 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::ok_buf; +use super::utils::CliOpResult; use crate::msg; -use crate::ops::ok_buf; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; use crate::resources::table_entries; use crate::state::ThreadSafeState; use deno::*; diff --git a/cli/ops/timers.rs b/cli/ops/timers.rs index 6c5f6fcaed..550d91f2c4 100644 --- a/cli/ops/timers.rs +++ b/cli/ops/timers.rs @@ -1,9 +1,9 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::empty_buf; +use super::utils::CliOpResult; use crate::deno_error; use crate::msg; -use crate::ops::empty_buf; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; use crate::state::ThreadSafeState; use deno::*; use flatbuffers::FlatBufferBuilder; diff --git a/cli/ops/utils.rs b/cli/ops/utils.rs new file mode 100644 index 0000000000..a9b0b442c5 --- /dev/null +++ b/cli/ops/utils.rs @@ -0,0 +1,48 @@ +use crate::tokio_util; +use deno::Buf; +use deno::ErrBox; +use deno::Op; +use deno::OpResult; +use futures::Poll; + +pub type CliOpResult = OpResult; + +#[inline] +pub fn ok_buf(buf: Buf) -> CliOpResult { + Ok(Op::Sync(buf)) +} + +#[inline] +pub fn empty_buf() -> Buf { + Box::new([]) +} + +// This is just type conversion. Implement From trait? +// See https://github.com/tokio-rs/tokio/blob/ffd73a64e7ec497622b7f939e38017afe7124dc4/tokio-fs/src/lib.rs#L76-L85 +fn convert_blocking(f: F) -> Poll +where + F: FnOnce() -> Result, +{ + use futures::Async::*; + match tokio_threadpool::blocking(f) { + Ok(Ready(Ok(v))) => Ok(v.into()), + Ok(Ready(Err(err))) => Err(err), + Ok(NotReady) => Ok(NotReady), + Err(err) => panic!("blocking error {}", err), + } +} + +pub fn blocking(is_sync: bool, f: F) -> CliOpResult +where + F: 'static + Send + FnOnce() -> Result, +{ + if is_sync { + let result_buf = f()?; + Ok(Op::Sync(result_buf)) + } else { + Ok(Op::Async(Box::new(futures::sync::oneshot::spawn( + tokio_util::poll_fn(move || convert_blocking(f)), + &tokio_executor::DefaultExecutor::current(), + )))) + } +} diff --git a/cli/ops/workers.rs b/cli/ops/workers.rs index d47aab7655..1eb11420fd 100644 --- a/cli/ops/workers.rs +++ b/cli/ops/workers.rs @@ -1,12 +1,11 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use super::dispatch_flatbuffers::serialize_response; +use super::utils::ok_buf; +use super::utils::CliOpResult; use crate::deno_error; use crate::deno_error::DenoError; use crate::deno_error::ErrorKind; use crate::msg; -use crate::ops::ok_buf; -use crate::ops::op_selector_std; -use crate::ops::serialize_response; -use crate::ops::CliOpResult; use crate::resources; use crate::startup_data; use crate::state::ThreadSafeState; @@ -136,7 +135,6 @@ pub fn op_create_worker( let child_state = ThreadSafeState::new( parent_state.flags.clone(), child_argv, - op_selector_std, parent_state.progress.clone(), include_deno_namespace, )?; diff --git a/cli/state.rs b/cli/state.rs index 7773829073..d7c6102048 100644 --- a/cli/state.rs +++ b/cli/state.rs @@ -77,7 +77,6 @@ pub struct State { pub start_time: Instant, /// A reference to this worker's resource. pub resource: resources::Resource, - pub dispatch_selector: ops::OpSelector, /// Reference to global progress bar. pub progress: Progress, pub seeded_rng: Option>, @@ -110,7 +109,7 @@ impl ThreadSafeState { control: &[u8], zero_copy: Option, ) -> CoreOp { - ops::dispatch_all(self, op_id, control, zero_copy, self.dispatch_selector) + ops::dispatch(self, op_id, control, zero_copy) } } @@ -163,7 +162,6 @@ impl ThreadSafeState { pub fn new( flags: flags::DenoFlags, argv_rest: Vec, - dispatch_selector: ops::OpSelector, progress: Progress, include_deno_namespace: bool, ) -> Result { @@ -224,7 +222,6 @@ impl ThreadSafeState { workers: Mutex::new(UserWorkerTable::new()), start_time: Instant::now(), resource, - dispatch_selector, progress, seeded_rng, file_fetcher, @@ -333,7 +330,6 @@ impl ThreadSafeState { ThreadSafeState::new( flags::DenoFlags::default(), argv, - ops::op_selector_std, Progress::new(), true, ) @@ -382,7 +378,6 @@ fn import_map_given_for_repl() { ..flags::DenoFlags::default() }, vec![String::from("./deno")], - ops::op_selector_std, Progress::new(), true, ); diff --git a/cli/worker.rs b/cli/worker.rs index f639c3d6df..cb551453a7 100644 --- a/cli/worker.rs +++ b/cli/worker.rs @@ -123,7 +123,6 @@ impl Future for Worker { mod tests { use super::*; use crate::flags; - use crate::ops::op_selector_std; use crate::progress::Progress; use crate::resources; use crate::startup_data; @@ -140,7 +139,6 @@ mod tests { let state = ThreadSafeState::new( flags::DenoFlags::default(), argv, - op_selector_std, Progress::new(), true, ) @@ -170,7 +168,6 @@ mod tests { let state = ThreadSafeState::new( flags::DenoFlags::default(), argv, - op_selector_std, Progress::new(), true, ) @@ -200,8 +197,7 @@ mod tests { let mut flags = flags::DenoFlags::default(); flags.reload = true; let state = - ThreadSafeState::new(flags, argv, op_selector_std, Progress::new(), true) - .unwrap(); + ThreadSafeState::new(flags, argv, Progress::new(), true).unwrap(); let state_ = state.clone(); tokio_util::run(lazy(move || { let mut worker = Worker::new( diff --git a/js/chmod.ts b/js/chmod.ts index 5abecb5765..2d6a5ed0f7 100644 --- a/js/chmod.ts +++ b/js/chmod.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; function req( path: string, @@ -19,7 +17,7 @@ function req( * Deno.chmodSync("/path/to/file", 0o666); */ export function chmodSync(path: string, mode: number): void { - dispatch.sendSync(...req(path, mode)); + sendSync(...req(path, mode)); } /** Changes the permission of a specific file/directory of specified path. @@ -27,5 +25,5 @@ export function chmodSync(path: string, mode: number): void { * await Deno.chmod("/path/to/file", 0o666); */ export async function chmod(path: string, mode: number): Promise { - await dispatch.sendAsync(...req(path, mode)); + await sendAsync(...req(path, mode)); } diff --git a/js/chown.ts b/js/chown.ts index 5c55fdab04..8787033fca 100644 --- a/js/chown.ts +++ b/js/chown.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as flatbuffers from "./flatbuffers"; -import * as msg from "gen/cli/msg_generated"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; function req( path: string, @@ -21,7 +19,7 @@ function req( * @param gid group id of the new owner */ export function chownSync(path: string, uid: number, gid: number): void { - dispatch.sendSync(...req(path, uid, gid)); + sendSync(...req(path, uid, gid)); } /** @@ -35,5 +33,5 @@ export async function chown( uid: number, gid: number ): Promise { - await dispatch.sendAsync(...req(path, uid, gid)); + await sendAsync(...req(path, uid, gid)); } diff --git a/js/compiler.ts b/js/compiler.ts index 6bda5a1eca..fd6f0ef58a 100644 --- a/js/compiler.ts +++ b/js/compiler.ts @@ -1,5 +1,4 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; import * as ts from "typescript"; import { assetSourceCode } from "./assets"; @@ -8,8 +7,7 @@ import { Console } from "./console"; import { core } from "./core"; import { Diagnostic, fromTypeScriptDiagnostic } from "./diagnostics"; import { cwd } from "./dir"; -import { sendSync } from "./dispatch"; -import * as flatbuffers from "./flatbuffers"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; import * as os from "./os"; import { TextDecoder, TextEncoder } from "./text_encoding"; import { assert, notImplemented } from "./util"; diff --git a/js/copy_file.ts b/js/copy_file.ts index 5cab6d5797..4c62ed1b0a 100644 --- a/js/copy_file.ts +++ b/js/copy_file.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; function req( from: string, @@ -24,7 +22,7 @@ function req( * Deno.copyFileSync("from.txt", "to.txt"); */ export function copyFileSync(from: string, to: string): void { - dispatch.sendSync(...req(from, to)); + sendSync(...req(from, to)); } /** Copies the contents of a file to another by name. @@ -38,5 +36,5 @@ export function copyFileSync(from: string, to: string): void { * await Deno.copyFile("from.txt", "to.txt"); */ export async function copyFile(from: string, to: string): Promise { - await dispatch.sendAsync(...req(from, to)); + await sendAsync(...req(from, to)); } diff --git a/js/dir.ts b/js/dir.ts index cf93451101..824084f4de 100644 --- a/js/dir.ts +++ b/js/dir.ts @@ -1,8 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; import { assert } from "./util"; -import * as flatbuffers from "./flatbuffers"; -import { sendSync } from "./dispatch"; +import { sendSync, flatbuffers, msg } from "./dispatch_flatbuffers"; /** * `cwd()` Return a string representing the current working directory. diff --git a/js/dispatch.ts b/js/dispatch.ts index babea5739d..423469d380 100644 --- a/js/dispatch.ts +++ b/js/dispatch.ts @@ -1,146 +1,22 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { core } from "./core"; -import * as flatbuffers from "./flatbuffers"; -import * as msg from "gen/cli/msg_generated"; -import * as errors from "./errors"; -import * as util from "./util"; -import { - nextPromiseId, - recordFromBufMinimal, - handleAsyncMsgFromRustMinimal -} from "./dispatch_minimal"; +import * as minimal from "./dispatch_minimal"; +import * as flatbuffers from "./dispatch_flatbuffers"; -// TODO(ry) Currently we only use three values for opId: OP_READ, OP_WRITE, -// FLATBUFFER_OP_ID. Later on use opId for actual individual ops, not just -// classes of ops. -const FLATBUFFER_OP_ID = 44; - -const promiseTable = new Map>(); - -interface FlatbufferRecord { - promiseId: number; - base: msg.Base; -} - -function flatbufferRecordFromBuf(buf: Uint8Array): FlatbufferRecord { - const bb = new flatbuffers.ByteBuffer(buf); - const base = msg.Base.getRootAsBase(bb); - return { - promiseId: base.cmdId(), - base - }; -} +// These consts are shared with Rust. Update with care. +export const OP_FLATBUFFER = 44; +export const OP_READ = 1; +export const OP_WRITE = 2; export function handleAsyncMsgFromRust(opId: number, ui8: Uint8Array): void { - const buf32 = new Int32Array(ui8.buffer, ui8.byteOffset, ui8.byteLength / 4); - if (opId !== FLATBUFFER_OP_ID) { - // Fast and new - const recordMin = recordFromBufMinimal(opId, buf32); - handleAsyncMsgFromRustMinimal(ui8, recordMin); - } else { - // Legacy - let { promiseId, base } = flatbufferRecordFromBuf(ui8); - const promise = promiseTable.get(promiseId); - util.assert(promise != null, `Expecting promise in table. ${promiseId}`); - promiseTable.delete(promiseId); - const err = errors.maybeError(base); - if (err != null) { - promise!.reject(err); - } else { - promise!.resolve(base); - } - } -} - -function ui8FromArrayBufferView(abv: ArrayBufferView): Uint8Array { - return new Uint8Array(abv.buffer, abv.byteOffset, abv.byteLength); -} - -function sendInternal( - builder: flatbuffers.Builder, - innerType: msg.Any, - inner: flatbuffers.Offset, - zeroCopy: undefined | ArrayBufferView, - isSync: true -): Uint8Array; -function sendInternal( - builder: flatbuffers.Builder, - innerType: msg.Any, - inner: flatbuffers.Offset, - zeroCopy: undefined | ArrayBufferView, - isSync: false -): Promise; -function sendInternal( - builder: flatbuffers.Builder, - innerType: msg.Any, - inner: flatbuffers.Offset, - zeroCopy: undefined | ArrayBufferView, - isSync: boolean -): Promise | Uint8Array { - const cmdId = nextPromiseId(); - msg.Base.startBase(builder); - msg.Base.addInner(builder, inner); - msg.Base.addInnerType(builder, innerType); - msg.Base.addSync(builder, isSync); - msg.Base.addCmdId(builder, cmdId); - builder.finish(msg.Base.endBase(builder)); - - const control = builder.asUint8Array(); - - const response = core.dispatch( - FLATBUFFER_OP_ID, // TODO(ry) Use actual opId later. - control, - zeroCopy ? ui8FromArrayBufferView(zeroCopy) : undefined - ); - - builder.inUse = false; - - if (response == null) { - util.assert(!isSync); - const promise = util.createResolvable(); - promiseTable.set(cmdId, promise); - return promise; - } else { - if (!isSync) { - // We can easily and correctly allow for sync responses to async calls - // by creating and returning a promise from the sync response. - const bb = new flatbuffers.ByteBuffer(response); - const base = msg.Base.getRootAsBase(bb); - const err = errors.maybeError(base); - if (err != null) { - return Promise.reject(err); - } else { - return Promise.resolve(base); - } - } - return response; - } -} - -// @internal -export function sendAsync( - builder: flatbuffers.Builder, - innerType: msg.Any, - inner: flatbuffers.Offset, - data?: ArrayBufferView -): Promise { - return sendInternal(builder, innerType, inner, data, false); -} - -// @internal -export function sendSync( - builder: flatbuffers.Builder, - innerType: msg.Any, - inner: flatbuffers.Offset, - data?: ArrayBufferView -): null | msg.Base { - const response = sendInternal(builder, innerType, inner, data, true); - if (response!.length === 0) { - return null; - } else { - const bb = new flatbuffers.ByteBuffer(response!); - const baseRes = msg.Base.getRootAsBase(bb); - errors.maybeThrowError(baseRes); - return baseRes; + switch (opId) { + case OP_FLATBUFFER: + flatbuffers.handleAsyncMsgFromRust(opId, ui8); + break; + case OP_WRITE: + case OP_READ: + minimal.handleAsyncMsgFromRust(opId, ui8); + break; + default: + throw Error("bad opId"); } } diff --git a/js/dispatch_flatbuffers.ts b/js/dispatch_flatbuffers.ts new file mode 100644 index 0000000000..87a01037cb --- /dev/null +++ b/js/dispatch_flatbuffers.ts @@ -0,0 +1,151 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +import * as flatbuffers from "./flatbuffers"; +import { DenoError } from "./errors"; +import { core } from "./core"; +import * as msg from "gen/cli/msg_generated"; +import * as util from "./util"; +import { OP_FLATBUFFER } from "./dispatch"; +export { msg, flatbuffers }; + +const promiseTable = new Map>(); +let _nextPromiseId = 1; + +export function nextPromiseId(): number { + return _nextPromiseId++; +} + +interface FlatbufferRecord { + promiseId: number; + base: msg.Base; +} + +export function handleAsyncMsgFromRust(opId: number, ui8: Uint8Array): void { + let { promiseId, base } = flatbufferRecordFromBuf(ui8); + const promise = promiseTable.get(promiseId); + util.assert(promise != null, `Expecting promise in table. ${promiseId}`); + promiseTable.delete(promiseId); + const err = maybeError(base); + if (err != null) { + promise!.reject(err); + } else { + promise!.resolve(base); + } +} + +function flatbufferRecordFromBuf(buf: Uint8Array): FlatbufferRecord { + const bb = new flatbuffers.ByteBuffer(buf); + const base = msg.Base.getRootAsBase(bb); + return { + promiseId: base.cmdId(), + base + }; +} + +function ui8FromArrayBufferView(abv: ArrayBufferView): Uint8Array { + return new Uint8Array(abv.buffer, abv.byteOffset, abv.byteLength); +} + +function sendInternal( + builder: flatbuffers.Builder, + innerType: msg.Any, + inner: flatbuffers.Offset, + zeroCopy: undefined | ArrayBufferView, + isSync: true +): Uint8Array; +function sendInternal( + builder: flatbuffers.Builder, + innerType: msg.Any, + inner: flatbuffers.Offset, + zeroCopy: undefined | ArrayBufferView, + isSync: false +): Promise; +function sendInternal( + builder: flatbuffers.Builder, + innerType: msg.Any, + inner: flatbuffers.Offset, + zeroCopy: undefined | ArrayBufferView, + isSync: boolean +): Promise | Uint8Array { + const cmdId = nextPromiseId(); + msg.Base.startBase(builder); + msg.Base.addInner(builder, inner); + msg.Base.addInnerType(builder, innerType); + msg.Base.addSync(builder, isSync); + msg.Base.addCmdId(builder, cmdId); + builder.finish(msg.Base.endBase(builder)); + + const control = builder.asUint8Array(); + + const response = core.dispatch( + OP_FLATBUFFER, // TODO(ry) Use actual opId later. + control, + zeroCopy ? ui8FromArrayBufferView(zeroCopy) : undefined + ); + + builder.inUse = false; + + if (response == null) { + util.assert(!isSync); + const promise = util.createResolvable(); + promiseTable.set(cmdId, promise); + return promise; + } else { + if (!isSync) { + // We can easily and correctly allow for sync responses to async calls + // by creating and returning a promise from the sync response. + const bb = new flatbuffers.ByteBuffer(response); + const base = msg.Base.getRootAsBase(bb); + const err = maybeError(base); + if (err != null) { + return Promise.reject(err); + } else { + return Promise.resolve(base); + } + } + return response; + } +} + +// @internal +export function sendAsync( + builder: flatbuffers.Builder, + innerType: msg.Any, + inner: flatbuffers.Offset, + data?: ArrayBufferView +): Promise { + return sendInternal(builder, innerType, inner, data, false); +} + +// @internal +export function sendSync( + builder: flatbuffers.Builder, + innerType: msg.Any, + inner: flatbuffers.Offset, + data?: ArrayBufferView +): null | msg.Base { + const response = sendInternal(builder, innerType, inner, data, true); + if (response!.length === 0) { + return null; + } else { + const bb = new flatbuffers.ByteBuffer(response!); + const baseRes = msg.Base.getRootAsBase(bb); + maybeThrowError(baseRes); + return baseRes; + } +} + +function maybeError(base: msg.Base): null | DenoError { + const kind = base.errorKind(); + if (kind === msg.ErrorKind.NoError) { + return null; + } else { + return new DenoError(kind, base.error()!); + } +} + +function maybeThrowError(base: msg.Base): void { + const err = maybeError(base); + if (err != null) { + throw err; + } +} diff --git a/js/dispatch_minimal.ts b/js/dispatch_minimal.ts index df0a290b22..fc3fc61b9d 100644 --- a/js/dispatch_minimal.ts +++ b/js/dispatch_minimal.ts @@ -4,9 +4,9 @@ import * as util from "./util"; import { core } from "./core"; const promiseTableMin = new Map>(); -let _nextPromiseId = 0; +let _nextPromiseId = 1; -export function nextPromiseId(): number { +function nextPromiseId(): number { return _nextPromiseId++; } @@ -40,12 +40,9 @@ const scratchBytes = new Uint8Array( ); util.assert(scratchBytes.byteLength === scratch32.length * 4); -export function handleAsyncMsgFromRustMinimal( - ui8: Uint8Array, - record: RecordMinimal -): void { - // Fast and new - util.log("minimal handleAsyncMsgFromRust ", ui8.length); +export function handleAsyncMsgFromRust(opId: number, ui8: Uint8Array): void { + const buf32 = new Int32Array(ui8.buffer, ui8.byteOffset, ui8.byteLength / 4); + const record = recordFromBufMinimal(opId, buf32); const { promiseId, result } = record; const promise = promiseTableMin.get(promiseId); promiseTableMin.delete(promiseId); diff --git a/js/error_stack.ts b/js/error_stack.ts index e97020687c..003717a72d 100644 --- a/js/error_stack.ts +++ b/js/error_stack.ts @@ -2,9 +2,7 @@ // Some of the code here is adapted directly from V8 and licensed under a BSD // style license available here: https://github.com/v8/v8/blob/24886f2d1c565287d33d71e4109a53bf0b54b75c/LICENSE.v8 -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { assert } from "./util"; export interface Location { @@ -77,7 +75,7 @@ function res(baseRes: msg.Base | null): Location { */ export function applySourceMap(location: Location): Location { const { filename, line, column } = location; - return res(dispatch.sendSync(...req(filename, line, column))); + return res(sendSync(...req(filename, line, column))); } /** Mutate the call site so that it returns the location, instead of its diff --git a/js/errors.ts b/js/errors.ts index 42cff60db8..7170155890 100644 --- a/js/errors.ts +++ b/js/errors.ts @@ -1,5 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { Base, ErrorKind } from "gen/cli/msg_generated"; +import { ErrorKind } from "gen/cli/msg_generated"; export { ErrorKind } from "gen/cli/msg_generated"; /** A Deno specific error. The `kind` property is set to a specific error code @@ -23,21 +23,3 @@ export class DenoError extends Error { this.name = ErrorKind[kind]; } } - -// @internal -export function maybeError(base: Base): null | DenoError { - const kind = base.errorKind(); - if (kind === ErrorKind.NoError) { - return null; - } else { - return new DenoError(kind, base.error()!); - } -} - -// @internal -export function maybeThrowError(base: Base): void { - const err = maybeError(base); - if (err != null) { - throw err; - } -} diff --git a/js/fetch.ts b/js/fetch.ts index 3911c63d00..505da218c3 100644 --- a/js/fetch.ts +++ b/js/fetch.ts @@ -1,8 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import { assert, createResolvable, notImplemented, isTypedArray } from "./util"; -import * as flatbuffers from "./flatbuffers"; -import { sendAsync } from "./dispatch"; -import * as msg from "gen/cli/msg_generated"; +import { sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; import * as domTypes from "./dom_types"; import { TextDecoder, TextEncoder } from "./text_encoding"; import { DenoBlob, bytesSymbol as blobBytesSymbol } from "./blob"; diff --git a/js/files.ts b/js/files.ts index eb899d738d..6f0e523c96 100644 --- a/js/files.ts +++ b/js/files.ts @@ -10,14 +10,10 @@ import { SyncWriter, SyncSeeker } from "./io"; -import * as dispatch from "./dispatch"; import { sendAsyncMinimal } from "./dispatch_minimal"; -import * as msg from "gen/cli/msg_generated"; import { assert } from "./util"; -import * as flatbuffers from "./flatbuffers"; - -const OP_READ = 1; -const OP_WRITE = 2; +import { sendAsync, sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; +import { OP_READ, OP_WRITE } from "./dispatch"; function reqOpen( filename: string, @@ -46,7 +42,7 @@ function resOpen(baseRes: null | msg.Base): File { * const file = Deno.openSync("/foo/bar.txt"); */ export function openSync(filename: string, mode: OpenMode = "r"): File { - return resOpen(dispatch.sendSync(...reqOpen(filename, mode))); + return resOpen(sendSync(...reqOpen(filename, mode))); } /** Open a file and return an instance of the `File` object. @@ -59,7 +55,7 @@ export async function open( filename: string, mode: OpenMode = "r" ): Promise { - return resOpen(await dispatch.sendAsync(...reqOpen(filename, mode))); + return resOpen(await sendAsync(...reqOpen(filename, mode))); } function reqRead( @@ -93,7 +89,7 @@ function resRead(baseRes: null | msg.Base): number | EOF { * */ export function readSync(rid: number, p: Uint8Array): number | EOF { - return resRead(dispatch.sendSync(...reqRead(rid, p))); + return resRead(sendSync(...reqRead(rid, p))); } /** Read from a file ID into an array buffer. @@ -145,7 +141,7 @@ function resWrite(baseRes: null | msg.Base): number { * Deno.writeSync(file.rid, data); */ export function writeSync(rid: number, p: Uint8Array): number { - return resWrite(dispatch.sendSync(...reqWrite(rid, p))); + return resWrite(sendSync(...reqWrite(rid, p))); } /** Write to the file ID the contents of the array buffer. @@ -185,7 +181,7 @@ function reqSeek( * Deno.seekSync(file.rid, 0, 0); */ export function seekSync(rid: number, offset: number, whence: SeekMode): void { - dispatch.sendSync(...reqSeek(rid, offset, whence)); + sendSync(...reqSeek(rid, offset, whence)); } /** Seek a file ID to the given offset under mode given by `whence`. @@ -200,14 +196,14 @@ export async function seek( offset: number, whence: SeekMode ): Promise { - await dispatch.sendAsync(...reqSeek(rid, offset, whence)); + await sendAsync(...reqSeek(rid, offset, whence)); } /** Close the file ID. */ export function close(rid: number): void { const builder = flatbuffers.createBuilder(); const inner = msg.Close.createClose(builder, rid); - dispatch.sendSync(builder, msg.Any.Close, inner); + sendSync(builder, msg.Any.Close, inner); } /** The Deno abstraction for reading and writing files. */ diff --git a/js/format_error.ts b/js/format_error.ts index 1c79f36fc7..6670b05e2c 100644 --- a/js/format_error.ts +++ b/js/format_error.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import { sendSync } from "./dispatch"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { assert } from "./util"; export function formatError(errString: string): string { diff --git a/js/get_random_values.ts b/js/get_random_values.ts index eb46ed0098..d5c0828c55 100644 --- a/js/get_random_values.ts +++ b/js/get_random_values.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { assert } from "./util"; function req( @@ -30,6 +28,6 @@ export function getRandomValues< >(typedArray: T): T { assert(typedArray !== null, "Input must not be null"); assert(typedArray.length <= 65536, "Input must not be longer than 65536"); - dispatch.sendSync(...req(typedArray as ArrayBufferView)); + sendSync(...req(typedArray as ArrayBufferView)); return typedArray; } diff --git a/js/link.ts b/js/link.ts index e6ffde66bb..0d849d289d 100644 --- a/js/link.ts +++ b/js/link.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; function req( oldname: string, @@ -19,7 +17,7 @@ function req( * Deno.linkSync("old/name", "new/name"); */ export function linkSync(oldname: string, newname: string): void { - dispatch.sendSync(...req(oldname, newname)); + sendSync(...req(oldname, newname)); } /** Creates `newname` as a hard link to `oldname`. @@ -27,5 +25,5 @@ export function linkSync(oldname: string, newname: string): void { * await Deno.link("old/name", "new/name"); */ export async function link(oldname: string, newname: string): Promise { - await dispatch.sendAsync(...req(oldname, newname)); + await sendAsync(...req(oldname, newname)); } diff --git a/js/make_temp_dir.ts b/js/make_temp_dir.ts index 8a3098b9e7..f83f7fb60e 100644 --- a/js/make_temp_dir.ts +++ b/js/make_temp_dir.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { assert } from "./util"; export interface MakeTempDirOptions { @@ -44,7 +42,7 @@ function res(baseRes: null | msg.Base): string { * const tempDirName1 = Deno.makeTempDirSync({ prefix: 'my_temp' }); */ export function makeTempDirSync(options: MakeTempDirOptions = {}): string { - return res(dispatch.sendSync(...req(options))); + return res(sendSync(...req(options))); } /** makeTempDir creates a new temporary directory in the directory `dir`, its @@ -61,5 +59,5 @@ export function makeTempDirSync(options: MakeTempDirOptions = {}): string { export async function makeTempDir( options: MakeTempDirOptions = {} ): Promise { - return res(await dispatch.sendAsync(...req(options))); + return res(await sendAsync(...req(options))); } diff --git a/js/metrics.ts b/js/metrics.ts index 92ed5b52e8..e93e9528c7 100644 --- a/js/metrics.ts +++ b/js/metrics.ts @@ -1,8 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; import { assert } from "./util"; -import * as dispatch from "./dispatch"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; export interface Metrics { opsDispatched: number; @@ -47,5 +45,5 @@ function res(baseRes: null | msg.Base): Metrics { * └──────────────────┴────────┘ */ export function metrics(): Metrics { - return res(dispatch.sendSync(...req())); + return res(sendSync(...req())); } diff --git a/js/mkdir.ts b/js/mkdir.ts index bf13c0e283..417c754a91 100644 --- a/js/mkdir.ts +++ b/js/mkdir.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; function req( path: string, @@ -24,7 +22,7 @@ function req( * Deno.mkdirSync("nested/directories", true); */ export function mkdirSync(path: string, recursive = false, mode = 0o777): void { - dispatch.sendSync(...req(path, recursive, mode)); + sendSync(...req(path, recursive, mode)); } /** Creates a new directory with the specified path. @@ -41,5 +39,5 @@ export async function mkdir( recursive = false, mode = 0o777 ): Promise { - await dispatch.sendAsync(...req(path, recursive, mode)); + await sendAsync(...req(path, recursive, mode)); } diff --git a/js/net.ts b/js/net.ts index f1470b86e6..9c3bfbba50 100644 --- a/js/net.ts +++ b/js/net.ts @@ -1,9 +1,7 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import { EOF, Reader, Writer, Closer } from "./io"; -import * as msg from "gen/cli/msg_generated"; import { assert, notImplemented } from "./util"; -import * as dispatch from "./dispatch"; -import * as flatbuffers from "./flatbuffers"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { read, write, close } from "./files"; export type Network = "tcp"; @@ -40,7 +38,7 @@ enum ShutdownMode { function shutdown(rid: number, how: ShutdownMode): void { const builder = flatbuffers.createBuilder(); const inner = msg.Shutdown.createShutdown(builder, rid, how); - const baseRes = dispatch.sendSync(builder, msg.Any.Shutdown, inner); + const baseRes = sendSync(builder, msg.Any.Shutdown, inner); assert(baseRes == null); } @@ -84,7 +82,7 @@ class ListenerImpl implements Listener { async accept(): Promise { const builder = flatbuffers.createBuilder(); const inner = msg.Accept.createAccept(builder, this.rid); - const baseRes = await dispatch.sendAsync(builder, msg.Any.Accept, inner); + const baseRes = await sendAsync(builder, msg.Any.Accept, inner); assert(baseRes != null); assert(msg.Any.NewConn === baseRes!.innerType()); const res = new msg.NewConn(); @@ -149,7 +147,7 @@ export function listen(network: Network, address: string): Listener { const network_ = builder.createString(network); const address_ = builder.createString(address); const inner = msg.Listen.createListen(builder, network_, address_); - const baseRes = dispatch.sendSync(builder, msg.Any.Listen, inner); + const baseRes = sendSync(builder, msg.Any.Listen, inner); assert(baseRes != null); assert(msg.Any.ListenRes === baseRes!.innerType()); const res = new msg.ListenRes(); @@ -189,7 +187,7 @@ export async function dial(network: Network, address: string): Promise { const network_ = builder.createString(network); const address_ = builder.createString(address); const inner = msg.Dial.createDial(builder, network_, address_); - const baseRes = await dispatch.sendAsync(builder, msg.Any.Dial, inner); + const baseRes = await sendAsync(builder, msg.Any.Dial, inner); assert(baseRes != null); assert(msg.Any.NewConn === baseRes!.innerType()); const res = new msg.NewConn(); diff --git a/js/os.ts b/js/os.ts index ff3cd2c2af..59c44145dd 100644 --- a/js/os.ts +++ b/js/os.ts @@ -1,8 +1,7 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; import { core } from "./core"; -import { handleAsyncMsgFromRust, sendSync } from "./dispatch"; -import * as flatbuffers from "./flatbuffers"; +import { handleAsyncMsgFromRust } from "./dispatch"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { assert } from "./util"; import * as util from "./util"; import { window } from "./window"; diff --git a/js/performance.ts b/js/performance.ts index 602c8018f1..7aaa7ae45a 100644 --- a/js/performance.ts +++ b/js/performance.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import { sendSync } from "./dispatch"; -import * as flatbuffers from "./flatbuffers"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { assert } from "./util"; export class Performance { diff --git a/js/permissions.ts b/js/permissions.ts index 13bcf7f906..822ae8cbd3 100644 --- a/js/permissions.ts +++ b/js/permissions.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { assert } from "./util"; /** Permissions as granted by the caller */ @@ -42,7 +40,7 @@ function createPermissions(inner: msg.PermissionsRes): Permissions { * } */ export function permissions(): Permissions { - const baseRes = dispatch.sendSync(...getReq())!; + const baseRes = sendSync(...getReq())!; assert(msg.Any.PermissionsRes === baseRes.innerType()); const res = new msg.PermissionsRes(); assert(baseRes.inner(res) != null); @@ -71,5 +69,5 @@ function revokeReq( * Deno.readFile("example.test"); // -> error or permission prompt */ export function revokePermission(permission: Permission): void { - dispatch.sendSync(...revokeReq(permission)); + sendSync(...revokeReq(permission)); } diff --git a/js/process.ts b/js/process.ts index 0629b26b00..b2b6d47348 100644 --- a/js/process.ts +++ b/js/process.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as dispatch from "./dispatch"; -import * as flatbuffers from "./flatbuffers"; -import * as msg from "gen/cli/msg_generated"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { File, close } from "./files"; import { ReadCloser, WriteCloser } from "./io"; @@ -37,7 +35,7 @@ async function runStatus(rid: number): Promise { const builder = flatbuffers.createBuilder(); const inner = msg.RunStatus.createRunStatus(builder, rid); - const baseRes = await dispatch.sendAsync(builder, msg.Any.RunStatus, inner); + const baseRes = await sendAsync(builder, msg.Any.RunStatus, inner); assert(baseRes != null); assert(msg.Any.RunStatusRes === baseRes!.innerType()); const res = new msg.RunStatusRes(); @@ -60,7 +58,7 @@ async function runStatus(rid: number): Promise { export function kill(pid: number, signo: number): void { const builder = flatbuffers.createBuilder(); const inner = msg.Kill.createKill(builder, pid, signo); - dispatch.sendSync(builder, msg.Any.Kill, inner); + sendSync(builder, msg.Any.Kill, inner); } export class Process { @@ -227,7 +225,7 @@ export function run(opt: RunOptions): Process { stdoutRidOffset, stderrRidOffset ); - const baseRes = dispatch.sendSync(builder, msg.Any.Run, inner); + const baseRes = sendSync(builder, msg.Any.Run, inner); assert(baseRes != null); assert(msg.Any.RunRes === baseRes!.innerType()); const res = new msg.RunRes(); diff --git a/js/read_dir.ts b/js/read_dir.ts index 1394c8514f..13c620916e 100644 --- a/js/read_dir.ts +++ b/js/read_dir.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { FileInfo, FileInfoImpl } from "./file_info"; import { assert } from "./util"; @@ -30,7 +28,7 @@ function res(baseRes: null | msg.Base): FileInfo[] { * const files = Deno.readDirSync("/"); */ export function readDirSync(path: string): FileInfo[] { - return res(dispatch.sendSync(...req(path))); + return res(sendSync(...req(path))); } /** Reads the directory given by path and returns a list of file info. @@ -38,5 +36,5 @@ export function readDirSync(path: string): FileInfo[] { * const files = await Deno.readDir("/"); */ export async function readDir(path: string): Promise { - return res(await dispatch.sendAsync(...req(path))); + return res(await sendAsync(...req(path))); } diff --git a/js/read_link.ts b/js/read_link.ts index 83a4ff1ba4..8cac67dd1e 100644 --- a/js/read_link.ts +++ b/js/read_link.ts @@ -1,8 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; import { assert } from "./util"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; function req(name: string): [flatbuffers.Builder, msg.Any, flatbuffers.Offset] { const builder = flatbuffers.createBuilder(); @@ -26,7 +24,7 @@ function res(baseRes: null | msg.Base): string { * const targetPath = Deno.readlinkSync("symlink/path"); */ export function readlinkSync(name: string): string { - return res(dispatch.sendSync(...req(name))); + return res(sendSync(...req(name))); } /** Returns the destination of the named symbolic link. @@ -34,5 +32,5 @@ export function readlinkSync(name: string): string { * const targetPath = await Deno.readlink("symlink/path"); */ export async function readlink(name: string): Promise { - return res(await dispatch.sendAsync(...req(name))); + return res(await sendAsync(...req(name))); } diff --git a/js/remove.ts b/js/remove.ts index 7abfd18e97..95294e6cfc 100644 --- a/js/remove.ts +++ b/js/remove.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; export interface RemoveOption { recursive?: boolean; @@ -25,7 +23,7 @@ function req( * Deno.removeSync("/path/to/dir/or/file", {recursive: false}); */ export function removeSync(path: string, options: RemoveOption = {}): void { - dispatch.sendSync(...req(path, options)); + sendSync(...req(path, options)); } /** Removes the named file or directory. Would throw error if @@ -39,5 +37,5 @@ export async function remove( path: string, options: RemoveOption = {} ): Promise { - await dispatch.sendAsync(...req(path, options)); + await sendAsync(...req(path, options)); } diff --git a/js/rename.ts b/js/rename.ts index 9099f083ad..31f480d0e4 100644 --- a/js/rename.ts +++ b/js/rename.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; function req( oldpath: string, @@ -22,7 +20,7 @@ function req( * Deno.renameSync("old/path", "new/path"); */ export function renameSync(oldpath: string, newpath: string): void { - dispatch.sendSync(...req(oldpath, newpath)); + sendSync(...req(oldpath, newpath)); } /** Renames (moves) `oldpath` to `newpath`. If `newpath` already exists and is @@ -32,5 +30,5 @@ export function renameSync(oldpath: string, newpath: string): void { * await Deno.rename("old/path", "new/path"); */ export async function rename(oldpath: string, newpath: string): Promise { - await dispatch.sendAsync(...req(oldpath, newpath)); + await sendAsync(...req(oldpath, newpath)); } diff --git a/js/repl.ts b/js/repl.ts index daf4fd154b..c971e44200 100644 --- a/js/repl.ts +++ b/js/repl.ts @@ -1,9 +1,7 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; import { assert } from "./util"; import { close } from "./files"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { exit } from "./os"; import { window } from "./window"; import { core } from "./core"; @@ -49,7 +47,7 @@ function startRepl(historyFile: string): number { const historyFile_ = builder.createString(historyFile); const inner = msg.ReplStart.createReplStart(builder, historyFile_); - const baseRes = dispatch.sendSync(builder, msg.Any.ReplStart, inner); + const baseRes = sendSync(builder, msg.Any.ReplStart, inner); assert(baseRes != null); assert(msg.Any.ReplStartRes === baseRes!.innerType()); const innerRes = new msg.ReplStartRes(); @@ -64,11 +62,7 @@ export async function readline(rid: number, prompt: string): Promise { const prompt_ = builder.createString(prompt); const inner = msg.ReplReadline.createReplReadline(builder, rid, prompt_); - const baseRes = await dispatch.sendAsync( - builder, - msg.Any.ReplReadline, - inner - ); + const baseRes = await sendAsync(builder, msg.Any.ReplReadline, inner); assert(baseRes != null); assert(msg.Any.ReplReadlineRes === baseRes!.innerType()); diff --git a/js/resources.ts b/js/resources.ts index 7ccc79c4d9..49093fab1a 100644 --- a/js/resources.ts +++ b/js/resources.ts @@ -1,8 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; import { assert } from "./util"; -import * as dispatch from "./dispatch"; +import { sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; export interface ResourceMap { [rid: number]: string; @@ -14,7 +12,7 @@ export interface ResourceMap { export function resources(): ResourceMap { const builder = flatbuffers.createBuilder(); const inner = msg.Resource.createResource(builder, 0, 0); - const baseRes = dispatch.sendSync(builder, msg.Any.Resources, inner); + const baseRes = sendSync(builder, msg.Any.Resources, inner); assert(baseRes !== null); assert(msg.Any.ResourcesRes === baseRes!.innerType()); const res = new msg.ResourcesRes(); diff --git a/js/stat.ts b/js/stat.ts index 755753606a..1fcce82afd 100644 --- a/js/stat.ts +++ b/js/stat.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { assert } from "./util"; import { FileInfo, FileInfoImpl } from "./file_info"; @@ -30,7 +28,7 @@ function res(baseRes: null | msg.Base): FileInfo { * assert(fileInfo.isFile()); */ export async function lstat(filename: string): Promise { - return res(await dispatch.sendAsync(...req(filename, true))); + return res(await sendAsync(...req(filename, true))); } /** Queries the file system for information on the path provided synchronously. @@ -41,7 +39,7 @@ export async function lstat(filename: string): Promise { * assert(fileInfo.isFile()); */ export function lstatSync(filename: string): FileInfo { - return res(dispatch.sendSync(...req(filename, true))); + return res(sendSync(...req(filename, true))); } /** Queries the file system for information on the path provided. `stat` Will @@ -51,7 +49,7 @@ export function lstatSync(filename: string): FileInfo { * assert(fileInfo.isFile()); */ export async function stat(filename: string): Promise { - return res(await dispatch.sendAsync(...req(filename, false))); + return res(await sendAsync(...req(filename, false))); } /** Queries the file system for information on the path provided synchronously. @@ -61,5 +59,5 @@ export async function stat(filename: string): Promise { * assert(fileInfo.isFile()); */ export function statSync(filename: string): FileInfo { - return res(dispatch.sendSync(...req(filename, false))); + return res(sendSync(...req(filename, false))); } diff --git a/js/symlink.ts b/js/symlink.ts index 28bf6c859a..40551e9f8e 100644 --- a/js/symlink.ts +++ b/js/symlink.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; import * as util from "./util"; import { platform } from "./build"; @@ -31,7 +29,7 @@ export function symlinkSync( newname: string, type?: string ): void { - dispatch.sendSync(...req(oldname, newname, type)); + sendSync(...req(oldname, newname, type)); } /** Creates `newname` as a symbolic link to `oldname`. The type argument can be @@ -45,5 +43,5 @@ export async function symlink( newname: string, type?: string ): Promise { - await dispatch.sendAsync(...req(oldname, newname, type)); + await sendAsync(...req(oldname, newname, type)); } diff --git a/js/timers.ts b/js/timers.ts index 388827331c..cb0fd531c6 100644 --- a/js/timers.ts +++ b/js/timers.ts @@ -1,8 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import { assert } from "./util"; -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import { sendAsync, sendSync } from "./dispatch"; +import { sendAsync, sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { window } from "./window"; interface Timer { diff --git a/js/truncate.ts b/js/truncate.ts index 0e9a8b9774..259c57da5f 100644 --- a/js/truncate.ts +++ b/js/truncate.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; function req( name: string, @@ -20,7 +18,7 @@ function req( * Deno.truncateSync("hello.txt", 10); */ export function truncateSync(name: string, len?: number): void { - dispatch.sendSync(...req(name, len)); + sendSync(...req(name, len)); } /** @@ -30,5 +28,5 @@ export function truncateSync(name: string, len?: number): void { * await Deno.truncate("hello.txt", 10); */ export async function truncate(name: string, len?: number): Promise { - await dispatch.sendAsync(...req(name, len)); + await sendAsync(...req(name, len)); } diff --git a/js/utime.ts b/js/utime.ts index 02c423d249..89914b4cab 100644 --- a/js/utime.ts +++ b/js/utime.ts @@ -1,7 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; -import * as dispatch from "./dispatch"; +import { sendSync, sendAsync, msg, flatbuffers } from "./dispatch_flatbuffers"; import * as util from "./util"; function req( @@ -34,7 +32,7 @@ export function utimeSync( atime: number | Date, mtime: number | Date ): void { - dispatch.sendSync(...req(filename, atime, mtime)); + sendSync(...req(filename, atime, mtime)); } /** Changes the access and modification times of a file system object @@ -48,5 +46,5 @@ export async function utime( atime: number | Date, mtime: number | Date ): Promise { - await dispatch.sendAsync(...req(filename, atime, mtime)); + await sendAsync(...req(filename, atime, mtime)); } diff --git a/js/workers.ts b/js/workers.ts index f061a0126d..e59e853c50 100644 --- a/js/workers.ts +++ b/js/workers.ts @@ -1,8 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. /* eslint-disable @typescript-eslint/no-explicit-any */ -import { sendAsync, sendSync } from "./dispatch"; -import * as msg from "gen/cli/msg_generated"; -import * as flatbuffers from "./flatbuffers"; +import { sendAsync, sendSync, msg, flatbuffers } from "./dispatch_flatbuffers"; import { assert, log } from "./util"; import { TextDecoder, TextEncoder } from "./text_encoding"; import { window } from "./window"; diff --git a/tests/error_004_missing_module.ts.out b/tests/error_004_missing_module.ts.out index 2f3071cd61..cb0f3bc5a5 100644 --- a/tests/error_004_missing_module.ts.out +++ b/tests/error_004_missing_module.ts.out @@ -1,9 +1,9 @@ [WILDCARD]error: Uncaught NotFound: Cannot resolve module "[WILDCARD]/bad-module.ts" -[WILDCARD] js/errors.ts:[WILDCARD] +[WILDCARD] js/dispatch_flatbuffers.ts:[WILDCARD] at DenoError (js/errors.ts:[WILDCARD]) - at maybeError (js/errors.ts:[WILDCARD]) - at maybeThrowError (js/errors.ts:[WILDCARD]) - at sendSync (js/dispatch.ts:[WILDCARD]) + at maybeError (js/dispatch_flatbuffers.ts:[WILDCARD]) + at maybeThrowError (js/dispatch_flatbuffers.ts:[WILDCARD]) + at sendSync (js/dispatch_flatbuffers.ts:[WILDCARD]) at fetchSourceFile (js/compiler.ts:[WILDCARD]) at _resolveModule (js/compiler.ts:[WILDCARD]) at js/compiler.ts:[WILDCARD] diff --git a/tests/error_005_missing_dynamic_import.ts.out b/tests/error_005_missing_dynamic_import.ts.out index ea2a56762a..fbc25f7010 100644 --- a/tests/error_005_missing_dynamic_import.ts.out +++ b/tests/error_005_missing_dynamic_import.ts.out @@ -1,9 +1,9 @@ [WILDCARD]error: Uncaught NotFound: Cannot resolve module "[WILDCARD]/bad-module.ts" -[WILDCARD] js/errors.ts:[WILDCARD] +[WILDCARD] js/dispatch_flatbuffers.ts:[WILDCARD] at DenoError (js/errors.ts:[WILDCARD]) - at maybeError (js/errors.ts:[WILDCARD]) - at maybeThrowError (js/errors.ts:[WILDCARD]) - at sendSync (js/dispatch.ts:[WILDCARD]) + at maybeError (js/dispatch_flatbuffers.ts:[WILDCARD]) + at maybeThrowError (js/dispatch_flatbuffers.ts:[WILDCARD]) + at sendSync (js/dispatch_flatbuffers.ts:[WILDCARD]) at fetchSourceFile (js/compiler.ts:[WILDCARD]) at _resolveModule (js/compiler.ts:[WILDCARD]) at js/compiler.ts:[WILDCARD] diff --git a/tests/error_006_import_ext_failure.ts.out b/tests/error_006_import_ext_failure.ts.out index 963664e95e..cb7ccee85b 100644 --- a/tests/error_006_import_ext_failure.ts.out +++ b/tests/error_006_import_ext_failure.ts.out @@ -1,9 +1,9 @@ [WILDCARD]error: Uncaught NotFound: Cannot resolve module "[WILDCARD]/non-existent" -[WILDCARD] js/errors.ts:[WILDCARD] +[WILDCARD] js/dispatch_flatbuffers.ts:[WILDCARD] at DenoError (js/errors.ts:[WILDCARD]) - at maybeError (js/errors.ts:[WILDCARD]) - at maybeThrowError (js/errors.ts:[WILDCARD]) - at sendSync (js/dispatch.ts:[WILDCARD]) + at maybeError (js/dispatch_flatbuffers.ts:[WILDCARD]) + at maybeThrowError (js/dispatch_flatbuffers.ts:[WILDCARD]) + at sendSync (js/dispatch_flatbuffers.ts:[WILDCARD]) at fetchSourceFile (js/compiler.ts:[WILDCARD]) at _resolveModule (js/compiler.ts:[WILDCARD]) at js/compiler.ts:[WILDCARD] diff --git a/tests/error_011_bad_module_specifier.ts.out b/tests/error_011_bad_module_specifier.ts.out index fa02d6df50..1590f4e153 100644 --- a/tests/error_011_bad_module_specifier.ts.out +++ b/tests/error_011_bad_module_specifier.ts.out @@ -1,9 +1,9 @@ [WILDCARD]error: Uncaught ImportPrefixMissing: relative import path "bad-module.ts" not prefixed with / or ./ or ../ -[WILDCARD] js/errors.ts:[WILDCARD] +[WILDCARD] js/dispatch_flatbuffers.ts:[WILDCARD] at DenoError (js/errors.ts:[WILDCARD]) - at maybeError (js/errors.ts:[WILDCARD]) - at maybeThrowError (js/errors.ts:[WILDCARD]) - at sendSync (js/dispatch.ts:[WILDCARD]) + at maybeError (js/dispatch_flatbuffers.ts:[WILDCARD]) + at maybeThrowError (js/dispatch_flatbuffers.ts:[WILDCARD]) + at sendSync (js/dispatch_flatbuffers.ts:[WILDCARD]) at fetchSourceFile (js/compiler.ts:[WILDCARD]) at _resolveModule (js/compiler.ts:[WILDCARD]) at js/compiler.ts:[WILDCARD] diff --git a/tests/error_012_bad_dynamic_import_specifier.ts.out b/tests/error_012_bad_dynamic_import_specifier.ts.out index 7417498e6f..ec5cba6f7d 100644 --- a/tests/error_012_bad_dynamic_import_specifier.ts.out +++ b/tests/error_012_bad_dynamic_import_specifier.ts.out @@ -1,9 +1,9 @@ [WILDCARD]error: Uncaught ImportPrefixMissing: relative import path "bad-module.ts" not prefixed with / or ./ or ../ -[WILDCARD] js/errors.ts:[WILDCARD] +[WILDCARD] js/dispatch_flatbuffers.ts:[WILDCARD] at DenoError (js/errors.ts:[WILDCARD]) - at maybeError (js/errors.ts:[WILDCARD]) - at maybeThrowError (js/errors.ts:[WILDCARD]) - at sendSync (js/dispatch.ts:[WILDCARD]) + at maybeError (js/dispatch_flatbuffers.ts:[WILDCARD]) + at maybeThrowError (js/dispatch_flatbuffers.ts:[WILDCARD]) + at sendSync (js/dispatch_flatbuffers.ts:[WILDCARD]) at fetchSourceFile (js/compiler.ts:[WILDCARD]) at _resolveModule (js/compiler.ts:[WILDCARD]) at js/compiler.ts:[WILDCARD]