-
Notifications
You must be signed in to change notification settings - Fork 5.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Just some clean up reorganization around flatbuffer/minimal dispatch code. This is prep for adding a JSON dispatcher.
- Loading branch information
Showing
65 changed files
with
662 additions
and
753 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<PinnedBuf>, | ||
) -> 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<PinnedBuf>, | ||
) -> 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<Buf, ()> { | ||
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<Buf, ()> { | ||
// 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<CliDispatchFn> { | ||
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, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.