summaryrefslogtreecommitdiff
path: root/cli
diff options
context:
space:
mode:
Diffstat (limited to 'cli')
-rw-r--r--cli/deno_error.rs17
-rw-r--r--cli/main.rs1
-rw-r--r--cli/msg.fbs333
-rw-r--r--cli/msg.rs14
-rw-r--r--cli/msg_util.rs124
-rw-r--r--cli/ops/compiler.rs90
-rw-r--r--cli/ops/dispatch_flatbuffers.rs56
-rw-r--r--cli/ops/errors.rs98
-rw-r--r--cli/ops/fetch.rs87
-rw-r--r--cli/ops/files.rs98
-rw-r--r--cli/ops/metrics.rs36
-rw-r--r--cli/ops/mod.rs180
-rw-r--r--cli/ops/net.rs167
-rw-r--r--cli/ops/os.rs128
-rw-r--r--cli/ops/performance.rs34
-rw-r--r--cli/ops/permissions.rs62
-rw-r--r--cli/ops/process.rs175
-rw-r--r--cli/ops/random.rs17
-rw-r--r--cli/ops/repl.rs86
-rw-r--r--cli/ops/resources.rs50
-rw-r--r--cli/ops/timers.rs59
-rw-r--r--cli/ops/workers.rs229
22 files changed, 1396 insertions, 745 deletions
diff --git a/cli/deno_error.rs b/cli/deno_error.rs
index 3b7dbcde8..e024a396c 100644
--- a/cli/deno_error.rs
+++ b/cli/deno_error.rs
@@ -205,18 +205,6 @@ impl GetErrorKind for ReadlineError {
}
}
-impl GetErrorKind for serde_json::error::Error {
- fn kind(&self) -> ErrorKind {
- use serde_json::error::*;
- match self.classify() {
- Category::Io => ErrorKind::InvalidInput,
- Category::Syntax => ErrorKind::InvalidInput,
- Category::Data => ErrorKind::InvalidData,
- Category::Eof => ErrorKind::UnexpectedEof,
- }
- }
-}
-
#[cfg(unix)]
mod unix {
use super::{ErrorKind, GetErrorKind};
@@ -263,11 +251,6 @@ impl GetErrorKind for dyn AnyError {
.or_else(|| self.downcast_ref::<uri::InvalidUri>().map(Get::kind))
.or_else(|| self.downcast_ref::<url::ParseError>().map(Get::kind))
.or_else(|| self.downcast_ref::<ReadlineError>().map(Get::kind))
- .or_else(|| {
- self
- .downcast_ref::<serde_json::error::Error>()
- .map(Get::kind)
- })
.or_else(|| unix_error_kind(self))
.unwrap_or_else(|| {
panic!("Can't get ErrorKind for {:?}", self);
diff --git a/cli/main.rs b/cli/main.rs
index a601e68af..2e82b8ee8 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -32,6 +32,7 @@ mod http_body;
mod http_util;
mod import_map;
pub mod msg;
+pub mod msg_util;
pub mod ops;
pub mod permissions;
mod progress;
diff --git a/cli/msg.fbs b/cli/msg.fbs
index a7359c527..3a40b80f5 100644
--- a/cli/msg.fbs
+++ b/cli/msg.fbs
@@ -1,14 +1,48 @@
union Any {
+ Accept,
+ ApplySourceMap,
+ Cache,
Chdir,
Chmod,
Chown,
+ Close,
CopyFile,
+ CreateWorker,
+ CreateWorkerRes,
Cwd,
CwdRes,
+ Dial,
+ Fetch,
+ FetchSourceFile,
+ FetchSourceFileRes,
+ FetchRes,
+ FormatError,
+ FormatErrorRes,
+ GetRandomValues,
+ GlobalTimer,
+ GlobalTimerRes,
+ GlobalTimerStop,
+ HostGetMessage,
+ HostGetMessageRes,
+ HostGetWorkerClosed,
+ HostPostMessage,
+ Kill,
Link,
+ Listen,
+ ListenRes,
MakeTempDir,
MakeTempDirRes,
+ Metrics,
+ MetricsRes,
Mkdir,
+ NewConn,
+ Now,
+ NowRes,
+ Open,
+ OpenRes,
+ PermissionRevoke,
+ Permissions,
+ PermissionsRes,
Read,
ReadDir,
ReadDirRes,
@@ -17,11 +51,30 @@ union Any {
ReadlinkRes,
Remove,
Rename,
+ ReplReadline,
+ ReplReadlineRes,
+ ReplStart,
+ ReplStartRes,
+ Resources,
+ ResourcesRes,
+ Run,
+ RunRes,
+ RunStatus,
+ RunStatusRes,
Seek,
+ SetEnv,
+ Shutdown,
+ Start,
+ StartRes,
Stat,
StatRes,
Symlink,
Truncate,
+ HomeDir,
+ HomeDirRes,
+ WorkerGetMessage,
+ WorkerGetMessageRes,
+ WorkerPostMessage,
Write,
WriteRes,
}
@@ -114,6 +167,25 @@ table Base {
inner: Any;
}
+table Start {
+ unused: int8;
+}
+
+table StartRes {
+ cwd: string;
+ pid: uint32;
+ argv: [string];
+ main_module: string; // Absolute URL.
+ debug_flag: bool;
+ deps_flag: bool;
+ types_flag: bool;
+ version_flag: bool;
+ deno_version: string;
+ v8_version: string;
+ no_color: bool;
+ xeval_delim: string;
+}
+
table FormatError {
error: string;
}
@@ -122,15 +194,138 @@ table FormatErrorRes {
error: string;
}
+// Create worker as host
+table CreateWorker {
+ specifier: string;
+ include_deno_namespace: bool;
+ has_source_code: bool;
+ source_code: string;
+}
+
+table CreateWorkerRes {
+ rid: uint32;
+}
+
+table HostGetWorkerClosed {
+ rid: uint32;
+}
+
+// Get message from guest worker as host
+table HostGetMessage {
+ rid: uint32;
+}
+
+table HostGetMessageRes {
+ data: [ubyte];
+}
+
+// Post message to guest worker as host
+table HostPostMessage {
+ rid: uint32;
+ // data passed thru the zero-copy data parameter.
+}
+
+// Get message from host as guest worker
+table WorkerGetMessage {
+ unused: int8;
+}
+
+table WorkerGetMessageRes {
+ data: [ubyte];
+}
+
+// Post message to host as guest worker
+table WorkerPostMessage {
+ // data passed thru the zero-copy data parameter.
+}
+
+table FetchSourceFile {
+ specifier: string;
+ referrer: string;
+}
+
+table FetchSourceFileRes {
+ // If it's a non-http module, moduleName and filename will be the same.
+ // For http modules, module_name is its resolved http URL, and filename
+ // is the location of the locally downloaded source code.
+ module_name: string;
+ filename: string;
+ media_type: MediaType;
+ data: [ubyte];
+}
+
+table ApplySourceMap {
+ filename: string;
+ line: int;
+ column: int;
+}
+
+table Cache {
+ extension: string;
+ module_id: string;
+ contents: string;
+}
+
table Chdir {
directory: string;
}
+table GlobalTimer {
+ timeout: int;
+}
+
+table GlobalTimerRes { }
+
+table GlobalTimerStop { }
+
+table SetEnv {
+ key: string;
+ value: string;
+}
+
table KeyValue {
key: string;
value: string;
}
+table Permissions {}
+
+table PermissionRevoke {
+ permission: string;
+}
+
+table PermissionsRes {
+ run: bool;
+ read: bool;
+ write: bool;
+ net: bool;
+ env: bool;
+ hrtime: bool;
+}
+
+// Note this represents The WHOLE header of an http message, not just the key
+// value pairs. That means it includes method and url for Requests and status
+// for responses. This is why it is singular "Header" instead of "Headers".
+table HttpHeader {
+ is_request: bool;
+ // Request only:
+ method: string;
+ url: string;
+ // Response only:
+ status: uint16;
+ // Both:
+ fields: [KeyValue];
+}
+
+table Fetch {
+ header: HttpHeader;
+}
+
+table FetchRes {
+ header: HttpHeader;
+ body_rid: uint32;
+}
+
table MakeTempDir {
dir: string;
prefix: string;
@@ -189,6 +384,35 @@ table ReadlinkRes {
path: string;
}
+table ReplStart {
+ history_file: string;
+ // TODO add config
+}
+
+table ReplStartRes {
+ rid: uint32;
+}
+
+table ReplReadline {
+ rid: uint32;
+ prompt: string;
+}
+
+table ReplReadlineRes {
+ line: string;
+}
+
+table Resources {}
+
+table Resource {
+ rid: uint32;
+ repr: string;
+}
+
+table ResourcesRes {
+ resources: [Resource];
+}
+
table Symlink {
oldname: string;
newname: string;
@@ -221,6 +445,22 @@ table Truncate {
len: uint;
}
+table HomeDir {}
+
+table HomeDirRes {
+ path: string;
+}
+
+table Open {
+ filename: string;
+ perm: uint;
+ mode: string;
+}
+
+table OpenRes {
+ rid: uint32;
+}
+
table Read {
rid: uint32;
// (ptr, len) is passed as second parameter to Deno.core.send().
@@ -239,10 +479,103 @@ table WriteRes {
nbyte: uint;
}
+table Close {
+ rid: uint32;
+}
+
+table Kill {
+ pid: int32;
+ signo: int32;
+}
+
+table Shutdown {
+ rid: uint32;
+ how: uint;
+}
+
+table Listen {
+ network: string;
+ address: string;
+}
+
+table ListenRes {
+ rid: uint32;
+}
+
+table Accept {
+ rid: uint32;
+}
+
+table Dial {
+ network: string;
+ address: string;
+}
+
+// Response to Accept and Dial.
+table NewConn {
+ rid: uint32;
+ remote_addr: string;
+ local_addr: string;
+}
+
+table Metrics {}
+
+table MetricsRes {
+ ops_dispatched: uint64;
+ ops_completed: uint64;
+ bytes_sent_control: uint64;
+ bytes_sent_data: uint64;
+ bytes_received: uint64;
+}
+
+enum ProcessStdio: byte { Inherit, Piped, Null }
+
+table Run {
+ args: [string];
+ cwd: string;
+ env: [KeyValue];
+ stdin: ProcessStdio;
+ stdout: ProcessStdio;
+ stderr: ProcessStdio;
+ stdin_rid: uint32;
+ stdout_rid: uint32;
+ stderr_rid: uint32;
+}
+
+table RunRes {
+ rid: uint32;
+ pid: uint32;
+ // The following stdio rids are only valid if "Piped" was specified for the
+ // corresponding stdio stream. The caller MUST issue a close op for all valid
+ // stdio streams.
+ stdin_rid: uint32;
+ stdout_rid: uint32;
+ stderr_rid: uint32;
+}
+
+table RunStatus {
+ rid: uint32;
+}
+
+table RunStatusRes {
+ got_signal: bool;
+ exit_code: int;
+ exit_signal: int;
+}
+
+table Now {}
+
+table NowRes {
+ seconds: uint64;
+ subsec_nanos: uint32;
+}
+
table Seek {
rid: uint32;
offset: int;
whence: uint;
}
+table GetRandomValues {}
+
root_type Base;
diff --git a/cli/msg.rs b/cli/msg.rs
index db4c771f8..51726b572 100644
--- a/cli/msg.rs
+++ b/cli/msg.rs
@@ -1,8 +1,22 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
#![allow(dead_code)]
#![cfg_attr(feature = "cargo-clippy", allow(clippy::all, clippy::pedantic))]
+use crate::state;
use flatbuffers;
+use std::sync::atomic::Ordering;
// GN_OUT_DIR is set either by build.rs (for the Cargo build), or by
// build_extra/rust/run.py (for the GN+Ninja build).
include!(concat!(env!("GN_OUT_DIR"), "/gen/cli/msg_generated.rs"));
+
+impl<'a> From<&'a state::Metrics> for MetricsResArgs {
+ fn from(m: &'a state::Metrics) -> Self {
+ MetricsResArgs {
+ ops_dispatched: m.ops_dispatched.load(Ordering::SeqCst) as u64,
+ ops_completed: m.ops_completed.load(Ordering::SeqCst) as u64,
+ bytes_sent_control: m.bytes_sent_control.load(Ordering::SeqCst) as u64,
+ bytes_sent_data: m.bytes_sent_data.load(Ordering::SeqCst) as u64,
+ bytes_received: m.bytes_received.load(Ordering::SeqCst) as u64,
+ }
+ }
+}
diff --git a/cli/msg_util.rs b/cli/msg_util.rs
new file mode 100644
index 000000000..e37a91f3a
--- /dev/null
+++ b/cli/msg_util.rs
@@ -0,0 +1,124 @@
+// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+// Helpers for serialization.
+use crate::msg;
+use deno::ErrBox;
+use flatbuffers;
+use http::header::HeaderName;
+use http::uri::Uri;
+use http::Method;
+use hyper::header::HeaderMap;
+use hyper::header::HeaderValue;
+use hyper::Body;
+use hyper::Request;
+use hyper::Response;
+use std::str::FromStr;
+
+type Headers = HeaderMap<HeaderValue>;
+
+pub fn serialize_key_value<'bldr>(
+ builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
+ key: &str,
+ value: &str,
+) -> flatbuffers::WIPOffset<msg::KeyValue<'bldr>> {
+ let key = builder.create_string(&key);
+ let value = builder.create_string(&value);
+ msg::KeyValue::create(
+ builder,
+ &msg::KeyValueArgs {
+ key: Some(key),
+ value: Some(value),
+ },
+ )
+}
+
+pub fn serialize_request_header<'bldr>(
+ builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
+ r: &Request<Body>,
+) -> flatbuffers::WIPOffset<msg::HttpHeader<'bldr>> {
+ let method = builder.create_string(r.method().as_str());
+ let url = builder.create_string(r.uri().to_string().as_ref());
+
+ let mut fields = Vec::new();
+ for (key, val) in r.headers().iter() {
+ let kv = serialize_key_value(builder, key.as_ref(), val.to_str().unwrap());
+ fields.push(kv);
+ }
+ let fields = builder.create_vector(fields.as_ref());
+
+ msg::HttpHeader::create(
+ builder,
+ &msg::HttpHeaderArgs {
+ is_request: true,
+ method: Some(method),
+ url: Some(url),
+ fields: Some(fields),
+ ..Default::default()
+ },
+ )
+}
+
+pub fn serialize_fields<'bldr>(
+ builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
+ headers: &Headers,
+) -> flatbuffers::WIPOffset<
+ flatbuffers::Vector<
+ 'bldr,
+ flatbuffers::ForwardsUOffset<msg::KeyValue<'bldr>>,
+ >,
+> {
+ let mut fields = Vec::new();
+ for (key, val) in headers.iter() {
+ let kv = serialize_key_value(builder, key.as_ref(), val.to_str().unwrap());
+ fields.push(kv);
+ }
+ builder.create_vector(fields.as_ref())
+}
+
+// Not to be confused with serialize_response which has nothing to do with HTTP.
+pub fn serialize_http_response<'bldr>(
+ builder: &mut flatbuffers::FlatBufferBuilder<'bldr>,
+ r: &Response<Body>,
+) -> flatbuffers::WIPOffset<msg::HttpHeader<'bldr>> {
+ let status = r.status().as_u16();
+ let fields = serialize_fields(builder, r.headers());
+ msg::HttpHeader::create(
+ builder,
+ &msg::HttpHeaderArgs {
+ is_request: false,
+ status,
+ fields: Some(fields),
+ ..Default::default()
+ },
+ )
+}
+
+pub fn deserialize_request(
+ header_msg: msg::HttpHeader<'_>,
+ body: Body,
+) -> Result<Request<Body>, ErrBox> {
+ let mut r = Request::new(body);
+
+ assert!(header_msg.is_request());
+
+ let u = header_msg.url().unwrap();
+ let u = Uri::from_str(u).map_err(ErrBox::from)?;
+ *r.uri_mut() = u;
+
+ if let Some(method) = header_msg.method() {
+ let method = Method::from_str(method).unwrap();
+ *r.method_mut() = method;
+ }
+
+ if let Some(fields) = header_msg.fields() {
+ let headers = r.headers_mut();
+ for i in 0..fields.len() {
+ let kv = fields.get(i);
+ let key = kv.key().unwrap();
+ let name = HeaderName::from_bytes(key.as_bytes()).unwrap();
+ let value = kv.value().unwrap();
+ let v = HeaderValue::from_str(value).unwrap();
+ headers.insert(name, v);
+ }
+ }
+ Ok(r)
+}
diff --git a/cli/ops/compiler.rs b/cli/ops/compiler.rs
index 39d3a6d7f..efdcd2c9b 100644
--- a/cli/ops/compiler.rs
+++ b/cli/ops/compiler.rs
@@ -1,68 +1,86 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use super::dispatch_json::{Deserialize, JsonOp, Value};
+use super::dispatch_flatbuffers::serialize_response;
+use super::utils::*;
+use crate::deno_error;
+use crate::msg;
use crate::state::ThreadSafeState;
use crate::tokio_util;
use deno::*;
-
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-struct CacheArgs {
- module_id: String,
- contents: String,
- extension: String,
-}
+use flatbuffers::FlatBufferBuilder;
+use futures::Future;
pub fn op_cache(
state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: CacheArgs = serde_json::from_value(args)?;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let inner = base.inner_as_cache().unwrap();
+ let extension = inner.extension().unwrap();
+ // TODO: rename to something with 'url'
+ let module_id = inner.module_id().unwrap();
+ let contents = inner.contents().unwrap();
- let module_specifier = ModuleSpecifier::resolve_url(&args.module_id)
+ let module_specifier = ModuleSpecifier::resolve_url(module_id)
.expect("Should be valid module specifier");
state.ts_compiler.cache_compiler_output(
&module_specifier,
- &args.extension,
- &args.contents,
+ extension,
+ contents,
)?;
- Ok(JsonOp::Sync(json!({})))
-}
-
-#[derive(Deserialize)]
-struct FetchSourceFileArgs {
- specifier: String,
- referrer: String,
+ ok_buf(empty_buf())
}
pub fn op_fetch_source_file(
state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: FetchSourceFileArgs = serde_json::from_value(args)?;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ if !base.sync() {
+ return Err(deno_error::no_async_support());
+ }
+ assert!(data.is_none());
+ let inner = base.inner_as_fetch_source_file().unwrap();
+ let cmd_id = base.cmd_id();
+ let specifier = inner.specifier().unwrap();
+ let referrer = inner.referrer().unwrap();
// TODO(ry) Maybe a security hole. Only the compiler worker should have access
// to this. Need a test to demonstrate the hole.
let is_dyn_import = false;
let resolved_specifier =
- state.resolve(&args.specifier, &args.referrer, false, is_dyn_import)?;
+ state.resolve(specifier, referrer, false, is_dyn_import)?;
let fut = state
.file_fetcher
- .fetch_source_file_async(&resolved_specifier);
+ .fetch_source_file_async(&resolved_specifier)
+ .and_then(move |out| {
+ let builder = &mut FlatBufferBuilder::new();
+ let data_off = builder.create_vector(out.source_code.as_slice());
+ let msg_args = msg::FetchSourceFileResArgs {
+ module_name: Some(builder.create_string(&out.url.to_string())),
+ filename: Some(builder.create_string(&out.filename.to_str().unwrap())),
+ media_type: out.media_type,
+ data: Some(data_off),
+ };
+ let inner = msg::FetchSourceFileRes::create(builder, &msg_args);
+ Ok(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::FetchSourceFileRes,
+ ..Default::default()
+ },
+ ))
+ });
// WARNING: Here we use tokio_util::block_on() which starts a new Tokio
// runtime for executing the future. This is so we don't inadvernently run
// out of threads in the main runtime.
- let out = tokio_util::block_on(fut)?;
- Ok(JsonOp::Sync(json!({
- "moduleName": out.url.to_string(),
- "filename": out.filename.to_str().unwrap(),
- "mediaType": out.media_type as i32,
- "sourceCode": String::from_utf8(out.source_code).unwrap(),
- })))
+ let result_buf = tokio_util::block_on(fut)?;
+ Ok(Op::Sync(result_buf))
}
diff --git a/cli/ops/dispatch_flatbuffers.rs b/cli/ops/dispatch_flatbuffers.rs
index bd0158751..b9dd4d9fa 100644
--- a/cli/ops/dispatch_flatbuffers.rs
+++ b/cli/ops/dispatch_flatbuffers.rs
@@ -6,12 +6,29 @@ use deno::*;
use flatbuffers::FlatBufferBuilder;
use hyper::rt::Future;
-use super::files::{op_read, op_write};
+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,
};
+use super::metrics::op_metrics;
+use super::net::{op_accept, op_dial, op_listen, op_shutdown};
+use super::os::{op_home_dir, 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,
@@ -125,24 +142,61 @@ pub fn serialize_response(
/// 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::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::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::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/ops/errors.rs b/cli/ops/errors.rs
index cd21a3880..a27f3656e 100644
--- a/cli/ops/errors.rs
+++ b/cli/ops/errors.rs
@@ -1,56 +1,88 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use super::dispatch_json::{Deserialize, JsonOp, Value};
+use super::dispatch_flatbuffers::serialize_response;
+use super::utils::*;
+use crate::deno_error;
use crate::fmt_errors::JSError;
+use crate::msg;
use crate::source_maps::get_orig_position;
use crate::source_maps::CachedMaps;
use crate::state::ThreadSafeState;
use deno::*;
+use flatbuffers::FlatBufferBuilder;
use std::collections::HashMap;
-#[derive(Deserialize)]
-struct FormatErrorArgs {
- error: String,
-}
-
pub fn op_format_error(
state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: FormatErrorArgs = serde_json::from_value(args)?;
- let error = JSError::from_json(&args.error, &state.ts_compiler);
-
- Ok(JsonOp::Sync(json!({
- "error": error.to_string(),
- })))
-}
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let inner = base.inner_as_format_error().unwrap();
+ let json_str = inner.error().unwrap();
+ let error = JSError::from_json(json_str, &state.ts_compiler);
+ let error_string = error.to_string();
+
+ let mut builder = FlatBufferBuilder::new();
+ let new_error = builder.create_string(&error_string);
+
+ let inner = msg::FormatErrorRes::create(
+ &mut builder,
+ &msg::FormatErrorResArgs {
+ error: Some(new_error),
+ },
+ );
+
+ let response_buf = serialize_response(
+ base.cmd_id(),
+ &mut builder,
+ msg::BaseArgs {
+ inner_type: msg::Any::FormatErrorRes,
+ inner: Some(inner.as_union_value()),
+ ..Default::default()
+ },
+ );
-#[derive(Deserialize)]
-struct ApplySourceMap {
- filename: String,
- line: i32,
- column: i32,
+ ok_buf(response_buf)
}
pub fn op_apply_source_map(
state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: ApplySourceMap = serde_json::from_value(args)?;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ if !base.sync() {
+ return Err(deno_error::no_async_support());
+ }
+ assert!(data.is_none());
+ let inner = base.inner_as_apply_source_map().unwrap();
+ let cmd_id = base.cmd_id();
+ let filename = inner.filename().unwrap();
+ let line = inner.line();
+ let column = inner.column();
let mut mappings_map: CachedMaps = HashMap::new();
let (orig_filename, orig_line, orig_column) = get_orig_position(
- args.filename,
- args.line.into(),
- args.column.into(),
+ filename.to_owned(),
+ line.into(),
+ column.into(),
&mut mappings_map,
&state.ts_compiler,
);
- Ok(JsonOp::Sync(json!({
- "filename": orig_filename.to_string(),
- "line": orig_line as u32,
- "column": orig_column as u32,
- })))
+ let builder = &mut FlatBufferBuilder::new();
+ let msg_args = msg::ApplySourceMapArgs {
+ filename: Some(builder.create_string(&orig_filename)),
+ line: orig_line as i32,
+ column: orig_column as i32,
+ };
+ let res_inner = msg::ApplySourceMap::create(builder, &msg_args);
+ ok_buf(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(res_inner.as_union_value()),
+ inner_type: msg::Any::ApplySourceMap,
+ ..Default::default()
+ },
+ ))
}
diff --git a/cli/ops/fetch.rs b/cli/ops/fetch.rs
index e2ab81a81..7661eb6e9 100644
--- a/cli/ops/fetch.rs
+++ b/cli/ops/fetch.rs
@@ -1,57 +1,38 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use super::dispatch_json::{Deserialize, JsonOp, Value};
+use super::dispatch_flatbuffers::serialize_response;
+use super::utils::CliOpResult;
use crate::http_util;
+use crate::msg;
+use crate::msg_util;
use crate::resources;
use crate::state::ThreadSafeState;
use deno::*;
-use http::header::HeaderName;
-use http::uri::Uri;
-use http::Method;
+use flatbuffers::FlatBufferBuilder;
use hyper;
-use hyper::header::HeaderValue;
use hyper::rt::Future;
-use hyper::Request;
use std;
use std::convert::From;
-use std::str::FromStr;
-
-#[derive(Deserialize)]
-struct FetchArgs {
- method: Option<String>,
- url: String,
- headers: Vec<(String, String)>,
-}
pub fn op_fetch(
state: &ThreadSafeState,
- args: Value,
+ base: &msg::Base<'_>,
data: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: FetchArgs = serde_json::from_value(args)?;
- let url = args.url;
+) -> CliOpResult {
+ let inner = base.inner_as_fetch().unwrap();
+ let cmd_id = base.cmd_id();
+
+ let header = inner.header().unwrap();
+ assert!(header.is_request());
+ let url = header.url().unwrap();
let body = match data {
None => hyper::Body::empty(),
Some(buf) => hyper::Body::from(Vec::from(&*buf)),
};
- let mut req = Request::new(body);
- let uri = Uri::from_str(&url).map_err(ErrBox::from)?;
- *req.uri_mut() = uri;
-
- if let Some(method) = args.method {
- let method = Method::from_str(&method).unwrap();
- *req.method_mut() = method;
- }
-
- let headers = req.headers_mut();
- for header_pair in args.headers {
- let name = HeaderName::from_bytes(header_pair.0.as_bytes()).unwrap();
- let v = HeaderValue::from_str(&header_pair.1).unwrap();
- headers.insert(name, v);
- }
+ let req = msg_util::deserialize_request(header, body)?;
- let url_ = url::Url::parse(&url).map_err(ErrBox::from)?;
+ let url_ = url::Url::parse(url).map_err(ErrBox::from)?;
state.check_net_url(&url_)?;
let client = http_util::get_client();
@@ -61,22 +42,32 @@ pub fn op_fetch(
.request(req)
.map_err(ErrBox::from)
.and_then(move |res| {
- let status = res.status().as_u16();
- let mut res_headers = Vec::new();
- for (key, val) in res.headers().iter() {
- res_headers.push((key.to_string(), val.to_str().unwrap().to_owned()));
- }
+ let builder = &mut FlatBufferBuilder::new();
+ let header_off = msg_util::serialize_http_response(builder, &res);
let body = res.into_body();
let body_resource = resources::add_hyper_body(body);
+ let inner = msg::FetchRes::create(
+ builder,
+ &msg::FetchResArgs {
+ header: Some(header_off),
+ body_rid: body_resource.rid,
+ },
+ );
- let json_res = json!({
- "bodyRid": body_resource.rid,
- "status": status,
- "headers": res_headers
- });
-
- futures::future::ok(json_res)
+ Ok(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::FetchRes,
+ ..Default::default()
+ },
+ ))
});
-
- Ok(JsonOp::Async(Box::new(future)))
+ if base.sync() {
+ let result_buf = future.wait()?;
+ Ok(Op::Sync(result_buf))
+ } else {
+ Ok(Op::Async(Box::new(future)))
+ }
}
diff --git a/cli/ops/files.rs b/cli/ops/files.rs
index c02a69b9c..023bd65f9 100644
--- a/cli/ops/files.rs
+++ b/cli/ops/files.rs
@@ -1,6 +1,5 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
use super::dispatch_flatbuffers::serialize_response;
-use super::dispatch_json::{Deserialize, JsonOp, Value};
use super::utils::*;
use crate::deno_error;
use crate::fs as deno_fs;
@@ -15,22 +14,17 @@ use std;
use std::convert::From;
use tokio;
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-struct OpenArgs {
- promise_id: Option<u64>,
- filename: String,
- mode: String,
-}
-
pub fn op_open(
state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: OpenArgs = serde_json::from_value(args)?;
- let (filename, filename_) = deno_fs::resolve_from_cwd(&args.filename)?;
- let mode = args.mode.as_ref();
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
+ let inner = base.inner_as_open().unwrap();
+ let (filename, filename_) =
+ deno_fs::resolve_from_cwd(inner.filename().unwrap())?;
+ let mode = inner.mode().unwrap();
let mut open_options = tokio::fs::OpenOptions::new();
@@ -81,39 +75,44 @@ pub fn op_open(
}
}
- let is_sync = args.promise_id.is_none();
let op = open_options.open(filename).map_err(ErrBox::from).and_then(
move |fs_file| {
let resource = resources::add_fs_file(fs_file);
- futures::future::ok(json!(resource.rid))
+ let builder = &mut FlatBufferBuilder::new();
+ let inner =
+ msg::OpenRes::create(builder, &msg::OpenResArgs { rid: resource.rid });
+ Ok(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::OpenRes,
+ ..Default::default()
+ },
+ ))
},
);
-
- if is_sync {
+ if base.sync() {
let buf = op.wait()?;
- Ok(JsonOp::Sync(buf))
+ Ok(Op::Sync(buf))
} else {
- Ok(JsonOp::Async(Box::new(op)))
+ Ok(Op::Async(Box::new(op)))
}
}
-#[derive(Deserialize)]
-struct CloseArgs {
- rid: i32,
-}
-
pub fn op_close(
_state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: CloseArgs = serde_json::from_value(args)?;
-
- match resources::lookup(args.rid as u32) {
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let inner = base.inner_as_close().unwrap();
+ let rid = inner.rid();
+ match resources::lookup(rid) {
None => Err(deno_error::bad_resource()),
Some(resource) => {
resource.close();
- Ok(JsonOp::Sync(json!({})))
+ ok_buf(empty_buf())
}
}
}
@@ -203,32 +202,27 @@ pub fn op_write(
}
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-struct SeekArgs {
- promise_id: Option<u64>,
- rid: i32,
- offset: i32,
- whence: i32,
-}
-
pub fn op_seek(
_state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: SeekArgs = serde_json::from_value(args)?;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let inner = base.inner_as_seek().unwrap();
+ let rid = inner.rid();
+ let offset = inner.offset();
+ let whence = inner.whence();
- match resources::lookup(args.rid as u32) {
+ match resources::lookup(rid) {
None => Err(deno_error::bad_resource()),
Some(resource) => {
- let op = resources::seek(resource, args.offset, args.whence as u32)
- .and_then(move |_| futures::future::ok(json!({})));
- if args.promise_id.is_none() {
+ let op = resources::seek(resource, offset, whence)
+ .and_then(move |_| Ok(empty_buf()));
+ if base.sync() {
let buf = op.wait()?;
- Ok(JsonOp::Sync(buf))
+ Ok(Op::Sync(buf))
} else {
- Ok(JsonOp::Async(Box::new(op)))
+ Ok(Op::Async(Box::new(op)))
}
}
}
diff --git a/cli/ops/metrics.rs b/cli/ops/metrics.rs
index e1a23f6c8..76f36c390 100644
--- a/cli/ops/metrics.rs
+++ b/cli/ops/metrics.rs
@@ -1,21 +1,31 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use super::dispatch_json::{JsonOp, Value};
+use super::dispatch_flatbuffers::serialize_response;
+use super::utils::*;
+use crate::msg;
use crate::state::ThreadSafeState;
use deno::*;
-use std::sync::atomic::Ordering;
+use flatbuffers::FlatBufferBuilder;
pub fn op_metrics(
state: &ThreadSafeState,
- _args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let m = &state.metrics;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
- Ok(JsonOp::Sync(json!({
- "opsDispatched": m.ops_dispatched.load(Ordering::SeqCst) as u64,
- "opsCompleted": m.ops_completed.load(Ordering::SeqCst) as u64,
- "bytesSentControl": m.bytes_sent_control.load(Ordering::SeqCst) as u64,
- "bytesSentData": m.bytes_sent_data.load(Ordering::SeqCst) as u64,
- "bytesReceived": m.bytes_received.load(Ordering::SeqCst) as u64
- })))
+ let builder = &mut FlatBufferBuilder::new();
+ let inner = msg::MetricsRes::create(
+ builder,
+ &msg::MetricsResArgs::from(&state.metrics),
+ );
+ ok_buf(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::MetricsRes,
+ ..Default::default()
+ },
+ ))
}
diff --git a/cli/ops/mod.rs b/cli/ops/mod.rs
index 4636754c9..240132960 100644
--- a/cli/ops/mod.rs
+++ b/cli/ops/mod.rs
@@ -34,40 +34,6 @@ pub const OP_IS_TTY: OpId = 4;
pub const OP_ENV: OpId = 5;
pub const OP_EXEC_PATH: OpId = 6;
pub const OP_UTIME: OpId = 7;
-pub const OP_SET_ENV: OpId = 8;
-pub const OP_HOME_DIR: OpId = 9;
-pub const OP_START: OpId = 10;
-pub const OP_APPLY_SOURCE_MAP: OpId = 11;
-pub const OP_FORMAT_ERROR: OpId = 12;
-pub const OP_CACHE: OpId = 13;
-pub const OP_FETCH_SOURCE_FILE: OpId = 14;
-pub const OP_OPEN: OpId = 15;
-pub const OP_CLOSE: OpId = 16;
-pub const OP_SEEK: OpId = 17;
-pub const OP_FETCH: OpId = 18;
-pub const OP_METRICS: OpId = 19;
-pub const OP_REPL_START: OpId = 20;
-pub const OP_REPL_READLINE: OpId = 21;
-pub const OP_ACCEPT: OpId = 22;
-pub const OP_DIAL: OpId = 23;
-pub const OP_SHUTDOWN: OpId = 24;
-pub const OP_LISTEN: OpId = 25;
-pub const OP_RESOURCES: OpId = 26;
-pub const OP_GET_RANDOM_VALUES: OpId = 27;
-pub const OP_GLOBAL_TIMER_STOP: OpId = 28;
-pub const OP_GLOBAL_TIMER: OpId = 29;
-pub const OP_NOW: OpId = 30;
-pub const OP_PERMISSIONS: OpId = 31;
-pub const OP_REVOKE_PERMISSION: OpId = 32;
-pub const OP_CREATE_WORKER: OpId = 33;
-pub const OP_HOST_GET_WORKER_CLOSED: OpId = 34;
-pub const OP_HOST_POST_MESSAGE: OpId = 35;
-pub const OP_HOST_GET_MESSAGE: OpId = 36;
-pub const OP_WORKER_POST_MESSAGE: OpId = 37;
-pub const OP_WORKER_GET_MESSAGE: OpId = 38;
-pub const OP_RUN: OpId = 39;
-pub const OP_RUN_STATUS: OpId = 40;
-pub const OP_KILL: OpId = 41;
pub fn dispatch(
state: &ThreadSafeState,
@@ -93,155 +59,9 @@ pub fn dispatch(
OP_EXEC_PATH => {
dispatch_json::dispatch(os::op_exec_path, state, control, zero_copy)
}
- OP_HOME_DIR => {
- dispatch_json::dispatch(os::op_home_dir, state, control, zero_copy)
- }
OP_UTIME => {
dispatch_json::dispatch(fs::op_utime, state, control, zero_copy)
}
- OP_SET_ENV => {
- dispatch_json::dispatch(os::op_set_env, state, control, zero_copy)
- }
- OP_START => {
- dispatch_json::dispatch(os::op_start, state, control, zero_copy)
- }
- OP_APPLY_SOURCE_MAP => dispatch_json::dispatch(
- errors::op_apply_source_map,
- state,
- control,
- zero_copy,
- ),
- OP_FORMAT_ERROR => dispatch_json::dispatch(
- errors::op_format_error,
- state,
- control,
- zero_copy,
- ),
- OP_CACHE => {
- dispatch_json::dispatch(compiler::op_cache, state, control, zero_copy)
- }
- OP_FETCH_SOURCE_FILE => dispatch_json::dispatch(
- compiler::op_fetch_source_file,
- state,
- control,
- zero_copy,
- ),
- OP_OPEN => {
- dispatch_json::dispatch(files::op_open, state, control, zero_copy)
- }
- OP_CLOSE => {
- dispatch_json::dispatch(files::op_close, state, control, zero_copy)
- }
- OP_SEEK => {
- dispatch_json::dispatch(files::op_seek, state, control, zero_copy)
- }
- OP_METRICS => {
- dispatch_json::dispatch(metrics::op_metrics, state, control, zero_copy)
- }
- OP_FETCH => {
- dispatch_json::dispatch(fetch::op_fetch, state, control, zero_copy)
- }
- OP_REPL_START => {
- dispatch_json::dispatch(repl::op_repl_start, state, control, zero_copy)
- }
- OP_REPL_READLINE => {
- dispatch_json::dispatch(repl::op_repl_readline, state, control, zero_copy)
- }
- OP_ACCEPT => {
- dispatch_json::dispatch(net::op_accept, state, control, zero_copy)
- }
- OP_DIAL => dispatch_json::dispatch(net::op_dial, state, control, zero_copy),
- OP_SHUTDOWN => {
- dispatch_json::dispatch(net::op_shutdown, state, control, zero_copy)
- }
- OP_LISTEN => {
- dispatch_json::dispatch(net::op_listen, state, control, zero_copy)
- }
- OP_RESOURCES => dispatch_json::dispatch(
- resources::op_resources,
- state,
- control,
- zero_copy,
- ),
- OP_GET_RANDOM_VALUES => dispatch_json::dispatch(
- random::op_get_random_values,
- state,
- control,
- zero_copy,
- ),
- OP_GLOBAL_TIMER_STOP => dispatch_json::dispatch(
- timers::op_global_timer_stop,
- state,
- control,
- zero_copy,
- ),
- OP_GLOBAL_TIMER => dispatch_json::dispatch(
- timers::op_global_timer,
- state,
- control,
- zero_copy,
- ),
- OP_NOW => {
- dispatch_json::dispatch(performance::op_now, state, control, zero_copy)
- }
- OP_PERMISSIONS => dispatch_json::dispatch(
- permissions::op_permissions,
- state,
- control,
- zero_copy,
- ),
- OP_REVOKE_PERMISSION => dispatch_json::dispatch(
- permissions::op_revoke_permission,
- state,
- control,
- zero_copy,
- ),
- OP_CREATE_WORKER => dispatch_json::dispatch(
- workers::op_create_worker,
- state,
- control,
- zero_copy,
- ),
- OP_HOST_GET_WORKER_CLOSED => dispatch_json::dispatch(
- workers::op_host_get_worker_closed,
- state,
- control,
- zero_copy,
- ),
- OP_HOST_POST_MESSAGE => dispatch_json::dispatch(
- workers::op_host_post_message,
- state,
- control,
- zero_copy,
- ),
- OP_HOST_GET_MESSAGE => dispatch_json::dispatch(
- workers::op_host_get_message,
- state,
- control,
- zero_copy,
- ),
- // TODO: make sure these two ops are only accessible to appropriate Workers
- OP_WORKER_POST_MESSAGE => dispatch_json::dispatch(
- workers::op_worker_post_message,
- state,
- control,
- zero_copy,
- ),
- OP_WORKER_GET_MESSAGE => dispatch_json::dispatch(
- workers::op_worker_get_message,
- state,
- control,
- zero_copy,
- ),
- OP_RUN => {
- dispatch_json::dispatch(process::op_run, state, control, zero_copy)
- }
- OP_RUN_STATUS => {
- dispatch_json::dispatch(process::op_run_status, state, control, zero_copy)
- }
- OP_KILL => {
- dispatch_json::dispatch(process::op_kill, state, control, zero_copy)
- }
OP_FLATBUFFER => dispatch_flatbuffers::dispatch(state, control, zero_copy),
_ => panic!("bad op_id"),
};
diff --git a/cli/ops/net.rs b/cli/ops/net.rs
index 650127fad..5ce562492 100644
--- a/cli/ops/net.rs
+++ b/cli/ops/net.rs
@@ -1,12 +1,15 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use super::dispatch_json::{Deserialize, JsonOp, Value};
+use super::dispatch_flatbuffers::serialize_response;
+use super::utils::*;
use crate::deno_error;
+use crate::msg;
use crate::resolve_addr::resolve_addr;
use crate::resources;
use crate::resources::Resource;
use crate::state::ThreadSafeState;
use crate::tokio_util;
use deno::*;
+use flatbuffers::FlatBufferBuilder;
use futures::Future;
use std;
use std::convert::From;
@@ -15,18 +18,15 @@ use tokio;
use tokio::net::TcpListener;
use tokio::net::TcpStream;
-#[derive(Deserialize)]
-struct AcceptArgs {
- rid: i32,
-}
-
pub fn op_accept(
_state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: AcceptArgs = serde_json::from_value(args)?;
- let server_rid = args.rid as u32;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
+ let inner = base.inner_as_accept().unwrap();
+ let server_rid = inner.rid();
match resources::lookup(server_rid) {
None => Err(deno_error::bad_resource()),
@@ -34,65 +34,55 @@ pub fn op_accept(
let op = tokio_util::accept(server_resource)
.map_err(ErrBox::from)
.and_then(move |(tcp_stream, _socket_addr)| {
- let tcp_stream_resource = resources::add_tcp_stream(tcp_stream);
- futures::future::ok(json!({
- "rid": tcp_stream_resource.rid
- }))
+ new_conn(cmd_id, tcp_stream)
});
-
- Ok(JsonOp::Async(Box::new(op)))
+ if base.sync() {
+ let buf = op.wait()?;
+ Ok(Op::Sync(buf))
+ } else {
+ Ok(Op::Async(Box::new(op)))
+ }
}
}
}
-#[derive(Deserialize)]
-struct DialArgs {
- network: String,
- address: String,
-}
-
pub fn op_dial(
state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: DialArgs = serde_json::from_value(args)?;
- let network = args.network;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
+ let inner = base.inner_as_dial().unwrap();
+ let network = inner.network().unwrap();
assert_eq!(network, "tcp"); // TODO Support others.
- let address = args.address;
+ let address = inner.address().unwrap();
state.check_net(&address)?;
- let op = resolve_addr(&address).and_then(move |addr| {
- TcpStream::connect(&addr).map_err(ErrBox::from).and_then(
- move |tcp_stream| {
- let tcp_stream_resource = resources::add_tcp_stream(tcp_stream);
- futures::future::ok(json!({
- "rid": tcp_stream_resource.rid
- }))
- },
- )
+ let op = resolve_addr(address).and_then(move |addr| {
+ TcpStream::connect(&addr)
+ .map_err(ErrBox::from)
+ .and_then(move |tcp_stream| new_conn(cmd_id, tcp_stream))
});
-
- Ok(JsonOp::Async(Box::new(op)))
-}
-
-#[derive(Deserialize)]
-struct ShutdownArgs {
- rid: i32,
- how: i32,
+ if base.sync() {
+ let buf = op.wait()?;
+ Ok(Op::Sync(buf))
+ } else {
+ Ok(Op::Async(Box::new(op)))
+ }
}
pub fn op_shutdown(
_state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: ShutdownArgs = serde_json::from_value(args)?;
-
- let rid = args.rid;
- let how = args.how;
- match resources::lookup(rid as u32) {
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let inner = base.inner_as_shutdown().unwrap();
+ let rid = inner.rid();
+ let how = inner.how();
+ match resources::lookup(rid) {
None => Err(deno_error::bad_resource()),
Some(mut resource) => {
let shutdown_mode = match how {
@@ -100,36 +90,67 @@ pub fn op_shutdown(
1 => Shutdown::Write,
_ => unimplemented!(),
};
-
- // Use UFCS for disambiguation
- Resource::shutdown(&mut resource, shutdown_mode)?;
- Ok(JsonOp::Sync(json!({})))
+ blocking(base.sync(), move || {
+ // Use UFCS for disambiguation
+ Resource::shutdown(&mut resource, shutdown_mode)?;
+ Ok(empty_buf())
+ })
}
}
}
-#[derive(Deserialize)]
-struct ListenArgs {
- network: String,
- address: String,
-}
-
pub fn op_listen(
state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: ListenArgs = serde_json::from_value(args)?;
-
- let network = args.network;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
+ let inner = base.inner_as_listen().unwrap();
+ let network = inner.network().unwrap();
assert_eq!(network, "tcp");
- let address = args.address;
+ let address = inner.address().unwrap();
state.check_net(&address)?;
- let addr = resolve_addr(&address).wait()?;
+ let addr = resolve_addr(address).wait()?;
let listener = TcpListener::bind(&addr)?;
let resource = resources::add_tcp_listener(listener);
- Ok(JsonOp::Sync(json!(resource.rid)))
+ let builder = &mut FlatBufferBuilder::new();
+ let inner =
+ msg::ListenRes::create(builder, &msg::ListenResArgs { rid: resource.rid });
+ let response_buf = serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::ListenRes,
+ ..Default::default()
+ },
+ );
+ ok_buf(response_buf)
+}
+
+fn new_conn(cmd_id: u32, tcp_stream: TcpStream) -> Result<Buf, ErrBox> {
+ let tcp_stream_resource = resources::add_tcp_stream(tcp_stream);
+ // TODO forward socket_addr to client.
+
+ let builder = &mut FlatBufferBuilder::new();
+ let inner = msg::NewConn::create(
+ builder,
+ &msg::NewConnArgs {
+ rid: tcp_stream_resource.rid,
+ ..Default::default()
+ },
+ );
+ Ok(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::NewConn,
+ ..Default::default()
+ },
+ ))
}
diff --git a/cli/ops/os.rs b/cli/ops/os.rs
index afb87539f..53ef63c60 100644
--- a/cli/ops/os.rs
+++ b/cli/ops/os.rs
@@ -1,11 +1,15 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+use super::dispatch_flatbuffers::serialize_response;
use super::dispatch_json::{Deserialize, JsonOp, Value};
+use super::utils::*;
use crate::ansi;
use crate::fs as deno_fs;
+use crate::msg;
use crate::state::ThreadSafeState;
use crate::version;
use atty;
use deno::*;
+use flatbuffers::FlatBufferBuilder;
use log;
use std::collections::HashMap;
use std::env;
@@ -13,38 +17,97 @@ use url::Url;
pub fn op_start(
state: &ThreadSafeState,
- _args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- Ok(JsonOp::Sync(json!({
- "cwd": deno_fs::normalize_path(&env::current_dir().unwrap()),
- "pid": std::process::id(),
- "argv": state.argv,
- "mainModule": state.main_module().map(|x| x.as_str().to_string()),
- "debugFlag": state
- .flags
- .log_level
- .map_or(false, |l| l == log::Level::Debug),
- "versionFlag": state.flags.version,
- "v8Version": version::v8(),
- "denoVersion": version::DENO,
- "noColor": !ansi::use_color(),
- "xevalDelim": state.flags.xeval_delim.clone(),
- })))
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let mut builder = FlatBufferBuilder::new();
+
+ let state = state;
+ let argv = state.argv.iter().map(String::as_str).collect::<Vec<_>>();
+ let argv_off = builder.create_vector_of_strings(argv.as_slice());
+
+ let cwd_path = env::current_dir().unwrap();
+ let cwd_off =
+ builder.create_string(deno_fs::normalize_path(cwd_path.as_ref()).as_ref());
+
+ let v8_version = version::v8();
+ let v8_version_off = builder.create_string(v8_version);
+
+ let deno_version = version::DENO;
+ let deno_version_off = builder.create_string(deno_version);
+
+ let main_module = state
+ .main_module()
+ .map(|m| builder.create_string(&m.to_string()));
+
+ let xeval_delim = state
+ .flags
+ .xeval_delim
+ .clone()
+ .map(|m| builder.create_string(&m));
+
+ let debug_flag = state
+ .flags
+ .log_level
+ .map_or(false, |l| l == log::Level::Debug);
+
+ let inner = msg::StartRes::create(
+ &mut builder,
+ &msg::StartResArgs {
+ cwd: Some(cwd_off),
+ pid: std::process::id(),
+ argv: Some(argv_off),
+ main_module,
+ debug_flag,
+ version_flag: state.flags.version,
+ v8_version: Some(v8_version_off),
+ deno_version: Some(deno_version_off),
+ no_color: !ansi::use_color(),
+ xeval_delim,
+ ..Default::default()
+ },
+ );
+
+ ok_buf(serialize_response(
+ base.cmd_id(),
+ &mut builder,
+ msg::BaseArgs {
+ inner_type: msg::Any::StartRes,
+ inner: Some(inner.as_union_value()),
+ ..Default::default()
+ },
+ ))
}
pub fn op_home_dir(
state: &ThreadSafeState,
- _args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
+
state.check_env()?;
+
+ let builder = &mut FlatBufferBuilder::new();
let path = dirs::home_dir()
.unwrap_or_default()
.into_os_string()
.into_string()
.unwrap_or_default();
- Ok(JsonOp::Sync(json!(path)))
+ let path = Some(builder.create_string(&path));
+ let inner = msg::HomeDirRes::create(builder, &msg::HomeDirResArgs { path });
+
+ ok_buf(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::HomeDirRes,
+ ..Default::default()
+ },
+ ))
}
pub fn op_exec_path(
@@ -61,21 +124,18 @@ pub fn op_exec_path(
Ok(JsonOp::Sync(json!(path)))
}
-#[derive(Deserialize)]
-struct SetEnv {
- key: String,
- value: String,
-}
-
pub fn op_set_env(
state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: SetEnv = serde_json::from_value(args)?;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let inner = base.inner_as_set_env().unwrap();
+ let key = inner.key().unwrap();
+ let value = inner.value().unwrap();
state.check_env()?;
- env::set_var(args.key, args.value);
- Ok(JsonOp::Sync(json!({})))
+ env::set_var(key, value);
+ ok_buf(empty_buf())
}
pub fn op_env(
diff --git a/cli/ops/performance.rs b/cli/ops/performance.rs
index 090fc3323..94f6dbc38 100644
--- a/cli/ops/performance.rs
+++ b/cli/ops/performance.rs
@@ -1,7 +1,10 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use super::dispatch_json::{JsonOp, Value};
+use super::dispatch_flatbuffers::serialize_response;
+use super::utils::*;
+use crate::msg;
use crate::state::ThreadSafeState;
use deno::*;
+use flatbuffers::FlatBufferBuilder;
// Returns a milliseconds and nanoseconds subsec
// since the start time of the deno runtime.
@@ -9,9 +12,10 @@ use deno::*;
// nanoseconds are rounded on 2ms.
pub fn op_now(
state: &ThreadSafeState,
- _args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
let seconds = state.start_time.elapsed().as_secs();
let mut subsec_nanos = state.start_time.elapsed().subsec_nanos();
let reduced_time_precision = 2_000_000; // 2ms in nanoseconds
@@ -23,8 +27,22 @@ pub fn op_now(
subsec_nanos -= subsec_nanos % reduced_time_precision
}
- Ok(JsonOp::Sync(json!({
- "seconds": seconds,
- "subsecNanos": subsec_nanos,
- })))
+ let builder = &mut FlatBufferBuilder::new();
+ let inner = msg::NowRes::create(
+ builder,
+ &msg::NowResArgs {
+ seconds,
+ subsec_nanos,
+ },
+ );
+
+ ok_buf(serialize_response(
+ base.cmd_id(),
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::NowRes,
+ ..Default::default()
+ },
+ ))
}
diff --git a/cli/ops/permissions.rs b/cli/ops/permissions.rs
index 5d14f39be..6249581fb 100644
--- a/cli/ops/permissions.rs
+++ b/cli/ops/permissions.rs
@@ -1,35 +1,50 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use super::dispatch_json::{Deserialize, JsonOp, Value};
+use super::dispatch_flatbuffers::serialize_response;
+use super::utils::*;
+use crate::msg;
use crate::state::ThreadSafeState;
use deno::*;
+use flatbuffers::FlatBufferBuilder;
pub fn op_permissions(
state: &ThreadSafeState,
- _args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- Ok(JsonOp::Sync(json!({
- "run": state.permissions.allows_run(),
- "read": state.permissions.allows_read(),
- "write": state.permissions.allows_write(),
- "net": state.permissions.allows_net(),
- "env": state.permissions.allows_env(),
- "hrtime": state.permissions.allows_hrtime(),
- })))
-}
-
-#[derive(Deserialize)]
-struct RevokePermissionArgs {
- permission: String,
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
+ let builder = &mut FlatBufferBuilder::new();
+ let inner = msg::PermissionsRes::create(
+ builder,
+ &msg::PermissionsResArgs {
+ run: state.permissions.allows_run(),
+ read: state.permissions.allows_read(),
+ write: state.permissions.allows_write(),
+ net: state.permissions.allows_net(),
+ env: state.permissions.allows_env(),
+ hrtime: state.permissions.allows_hrtime(),
+ },
+ );
+ let response_buf = serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::PermissionsRes,
+ ..Default::default()
+ },
+ );
+ ok_buf(response_buf)
}
pub fn op_revoke_permission(
state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: RevokePermissionArgs = serde_json::from_value(args)?;
- let permission = args.permission.as_ref();
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let inner = base.inner_as_permission_revoke().unwrap();
+ let permission = inner.permission().unwrap();
match permission {
"run" => state.permissions.revoke_run(),
"read" => state.permissions.revoke_read(),
@@ -39,6 +54,5 @@ pub fn op_revoke_permission(
"hrtime" => state.permissions.revoke_hrtime(),
_ => Ok(()),
}?;
-
- Ok(JsonOp::Sync(json!({})))
+ ok_buf(empty_buf())
}
diff --git a/cli/ops/process.rs b/cli/ops/process.rs
index 8dff53c6e..d7b326d14 100644
--- a/cli/ops/process.rs
+++ b/cli/ops/process.rs
@@ -1,9 +1,13 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use super::dispatch_json::{Deserialize, JsonOp, Value};
+use super::dispatch_flatbuffers::serialize_response;
+use super::utils::*;
+use crate::deno_error;
+use crate::msg;
use crate::resources;
use crate::signal::kill;
use crate::state::ThreadSafeState;
use deno::*;
+use flatbuffers::FlatBufferBuilder;
use futures;
use futures::Future;
use std;
@@ -14,72 +18,63 @@ use tokio_process::CommandExt;
#[cfg(unix)]
use std::os::unix::process::ExitStatusExt;
-fn subprocess_stdio_map(s: &str) -> std::process::Stdio {
- match s {
- "inherit" => std::process::Stdio::inherit(),
- "piped" => std::process::Stdio::piped(),
- "null" => std::process::Stdio::null(),
- _ => unreachable!(),
+fn subprocess_stdio_map(v: msg::ProcessStdio) -> std::process::Stdio {
+ match v {
+ msg::ProcessStdio::Inherit => std::process::Stdio::inherit(),
+ msg::ProcessStdio::Piped => std::process::Stdio::piped(),
+ msg::ProcessStdio::Null => std::process::Stdio::null(),
}
}
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-struct RunArgs {
- args: Vec<String>,
- cwd: Option<String>,
- env: Vec<(String, String)>,
- stdin: String,
- stdout: String,
- stderr: String,
- stdin_rid: u32,
- stdout_rid: u32,
- stderr_rid: u32,
-}
-
pub fn op_run(
state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let run_args: RunArgs = serde_json::from_value(args)?;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ if !base.sync() {
+ return Err(deno_error::no_async_support());
+ }
+ let cmd_id = base.cmd_id();
state.check_run()?;
- let args = run_args.args;
- let env = run_args.env;
- let cwd = run_args.cwd;
+ assert!(data.is_none());
+ let inner = base.inner_as_run().unwrap();
+ let args = inner.args().unwrap();
+ let env = inner.env().unwrap();
+ let cwd = inner.cwd();
- let mut c = Command::new(args.get(0).unwrap());
+ let mut c = Command::new(args.get(0));
(1..args.len()).for_each(|i| {
- let arg = args.get(i).unwrap();
+ let arg = args.get(i);
c.arg(arg);
});
cwd.map(|d| c.current_dir(d));
- for (key, value) in &env {
- c.env(key, value);
- }
+ (0..env.len()).for_each(|i| {
+ let entry = env.get(i);
+ c.env(entry.key().unwrap(), entry.value().unwrap());
+ });
// TODO: make this work with other resources, eg. sockets
- let stdin_rid = run_args.stdin_rid;
+ let stdin_rid = inner.stdin_rid();
if stdin_rid > 0 {
c.stdin(resources::get_file(stdin_rid)?);
} else {
- c.stdin(subprocess_stdio_map(run_args.stdin.as_ref()));
+ c.stdin(subprocess_stdio_map(inner.stdin()));
}
- let stdout_rid = run_args.stdout_rid;
+ let stdout_rid = inner.stdout_rid();
if stdout_rid > 0 {
c.stdout(resources::get_file(stdout_rid)?);
} else {
- c.stdout(subprocess_stdio_map(run_args.stdout.as_ref()));
+ c.stdout(subprocess_stdio_map(inner.stdout()));
}
- let stderr_rid = run_args.stderr_rid;
+ let stderr_rid = inner.stderr_rid();
if stderr_rid > 0 {
c.stderr(resources::get_file(stderr_rid)?);
} else {
- c.stderr(subprocess_stdio_map(run_args.stderr.as_ref()));
+ c.stderr(subprocess_stdio_map(inner.stderr()));
}
// Spawn the command.
@@ -88,28 +83,44 @@ pub fn op_run(
let pid = child.id();
let resources = resources::add_child(child);
- Ok(JsonOp::Sync(json!({
- "rid": resources.child_rid,
- "pid": pid,
- "stdinRid": resources.stdin_rid,
- "stdoutRid": resources.stdout_rid,
- "stderrRid": resources.stderr_rid,
- })))
-}
+ let mut res_args = msg::RunResArgs {
+ rid: resources.child_rid,
+ pid,
+ ..Default::default()
+ };
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-struct RunStatusArgs {
- rid: i32,
+ if let Some(stdin_rid) = resources.stdin_rid {
+ res_args.stdin_rid = stdin_rid;
+ }
+ if let Some(stdout_rid) = resources.stdout_rid {
+ res_args.stdout_rid = stdout_rid;
+ }
+ if let Some(stderr_rid) = resources.stderr_rid {
+ res_args.stderr_rid = stderr_rid;
+ }
+
+ let builder = &mut FlatBufferBuilder::new();
+ let inner = msg::RunRes::create(builder, &res_args);
+ Ok(Op::Sync(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::RunRes,
+ ..Default::default()
+ },
+ )))
}
pub fn op_run_status(
state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: RunStatusArgs = serde_json::from_value(args)?;
- let rid = args.rid as u32;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
+ let inner = base.inner_as_run_status().unwrap();
+ let rid = inner.rid();
state.check_run()?;
@@ -128,30 +139,44 @@ pub fn op_run_status(
.expect("Should have either an exit code or a signal.");
let got_signal = signal.is_some();
- futures::future::ok(json!({
- "gotSignal": got_signal,
- "exitCode": code.unwrap_or(-1),
- "exitSignal": signal.unwrap_or(-1),
- }))
+ let builder = &mut FlatBufferBuilder::new();
+ let inner = msg::RunStatusRes::create(
+ builder,
+ &msg::RunStatusResArgs {
+ got_signal,
+ exit_code: code.unwrap_or(-1),
+ exit_signal: signal.unwrap_or(-1),
+ },
+ );
+ Ok(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::RunStatusRes,
+ ..Default::default()
+ },
+ ))
});
-
- Ok(JsonOp::Async(Box::new(future)))
-}
-
-#[derive(Deserialize)]
-struct KillArgs {
- pid: i32,
- signo: i32,
+ if base.sync() {
+ let buf = future.wait()?;
+ Ok(Op::Sync(buf))
+ } else {
+ Ok(Op::Async(Box::new(future)))
+ }
}
pub fn op_kill(
state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
state.check_run()?;
- let args: KillArgs = serde_json::from_value(args)?;
- kill(args.pid, args.signo)?;
- Ok(JsonOp::Sync(json!({})))
+ assert!(data.is_none());
+ let inner = base.inner_as_kill().unwrap();
+ let pid = inner.pid();
+ let signo = inner.signo();
+ kill(pid, signo)?;
+ ok_buf(empty_buf())
}
diff --git a/cli/ops/random.rs b/cli/ops/random.rs
index 7470eab40..0c302a080 100644
--- a/cli/ops/random.rs
+++ b/cli/ops/random.rs
@@ -1,5 +1,6 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use super::dispatch_json::{JsonOp, Value};
+use super::utils::*;
+use crate::msg;
use crate::state::ThreadSafeState;
use deno::*;
use rand::thread_rng;
@@ -7,18 +8,16 @@ use rand::Rng;
pub fn op_get_random_values(
state: &ThreadSafeState,
- _args: Value,
- zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- assert!(zero_copy.is_some());
-
+ _base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
if let Some(ref seeded_rng) = state.seeded_rng {
let mut rng = seeded_rng.lock().unwrap();
- rng.fill(&mut zero_copy.unwrap()[..]);
+ rng.fill(&mut data.unwrap()[..]);
} else {
let mut rng = thread_rng();
- rng.fill(&mut zero_copy.unwrap()[..]);
+ rng.fill(&mut data.unwrap()[..]);
}
- Ok(JsonOp::Sync(json!({})))
+ ok_buf(empty_buf())
}
diff --git a/cli/ops/repl.rs b/cli/ops/repl.rs
index 7ab7509de..affe78739 100644
--- a/cli/ops/repl.rs
+++ b/cli/ops/repl.rs
@@ -1,50 +1,78 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use super::dispatch_json::{blocking_json, Deserialize, JsonOp, Value};
+use super::dispatch_flatbuffers::serialize_response;
+use super::utils::blocking;
+use super::utils::ok_buf;
+use super::utils::CliOpResult;
+use crate::msg;
use crate::repl;
use crate::resources;
use crate::state::ThreadSafeState;
use deno::*;
-
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-struct ReplStartArgs {
- history_file: String,
-}
+use flatbuffers::FlatBufferBuilder;
pub fn op_repl_start(
state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: ReplStartArgs = serde_json::from_value(args)?;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let inner = base.inner_as_repl_start().unwrap();
+ let cmd_id = base.cmd_id();
+ let history_file = String::from(inner.history_file().unwrap());
- debug!("op_repl_start {}", args.history_file);
- let history_path = repl::history_path(&state.dir, &args.history_file);
+ debug!("op_repl_start {}", history_file);
+ let history_path = repl::history_path(&state.dir, &history_file);
let repl = repl::Repl::new(history_path);
let resource = resources::add_repl(repl);
- Ok(JsonOp::Sync(json!(resource.rid)))
-}
-
-#[derive(Deserialize)]
-struct ReplReadlineArgs {
- rid: i32,
- prompt: String,
+ let builder = &mut FlatBufferBuilder::new();
+ let inner = msg::ReplStartRes::create(
+ builder,
+ &msg::ReplStartResArgs { rid: resource.rid },
+ );
+ ok_buf(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::ReplStartRes,
+ ..Default::default()
+ },
+ ))
}
pub fn op_repl_readline(
_state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: ReplReadlineArgs = serde_json::from_value(args)?;
- let rid = args.rid;
- let prompt = args.prompt;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let inner = base.inner_as_repl_readline().unwrap();
+ let cmd_id = base.cmd_id();
+ let rid = inner.rid();
+ let prompt = inner.prompt().unwrap().to_owned();
debug!("op_repl_readline {} {}", rid, prompt);
- blocking_json(false, move || {
- let repl = resources::get_repl(rid as u32)?;
+ blocking(base.sync(), move || {
+ let repl = resources::get_repl(rid)?;
let line = repl.lock().unwrap().readline(&prompt)?;
- Ok(json!(line))
+
+ let builder = &mut FlatBufferBuilder::new();
+ let line_off = builder.create_string(&line);
+ let inner = msg::ReplReadlineRes::create(
+ builder,
+ &msg::ReplReadlineResArgs {
+ line: Some(line_off),
+ },
+ );
+ Ok(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::ReplReadlineRes,
+ ..Default::default()
+ },
+ ))
})
}
diff --git a/cli/ops/resources.rs b/cli/ops/resources.rs
index dafd01d08..975d94490 100644
--- a/cli/ops/resources.rs
+++ b/cli/ops/resources.rs
@@ -1,14 +1,54 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use super::dispatch_json::{JsonOp, Value};
+use super::dispatch_flatbuffers::serialize_response;
+use super::utils::ok_buf;
+use super::utils::CliOpResult;
+use crate::msg;
use crate::resources::table_entries;
use crate::state::ThreadSafeState;
use deno::*;
+use flatbuffers::FlatBufferBuilder;
pub fn op_resources(
_state: &ThreadSafeState,
- _args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
+
+ let builder = &mut FlatBufferBuilder::new();
let serialized_resources = table_entries();
- Ok(JsonOp::Sync(json!(serialized_resources)))
+
+ let res: Vec<_> = serialized_resources
+ .iter()
+ .map(|(key, value)| {
+ let repr = builder.create_string(value);
+
+ msg::Resource::create(
+ builder,
+ &msg::ResourceArgs {
+ rid: *key,
+ repr: Some(repr),
+ },
+ )
+ })
+ .collect();
+
+ let resources = builder.create_vector(&res);
+ let inner = msg::ResourcesRes::create(
+ builder,
+ &msg::ResourcesResArgs {
+ resources: Some(resources),
+ },
+ );
+
+ ok_buf(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::ResourcesRes,
+ ..Default::default()
+ },
+ ))
}
diff --git a/cli/ops/timers.rs b/cli/ops/timers.rs
index 46217a188..550d91f2c 100644
--- a/cli/ops/timers.rs
+++ b/cli/ops/timers.rs
@@ -1,7 +1,12 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use super::dispatch_json::{Deserialize, JsonOp, Value};
+use super::dispatch_flatbuffers::serialize_response;
+use super::utils::empty_buf;
+use super::utils::CliOpResult;
+use crate::deno_error;
+use crate::msg;
use crate::state::ThreadSafeState;
use deno::*;
+use flatbuffers::FlatBufferBuilder;
use futures::Future;
use std;
use std::time::Duration;
@@ -9,34 +14,50 @@ use std::time::Instant;
pub fn op_global_timer_stop(
state: &ThreadSafeState,
- _args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ if !base.sync() {
+ return Err(deno_error::no_async_support());
+ }
+ assert!(data.is_none());
let state = state;
let mut t = state.global_timer.lock().unwrap();
t.cancel();
- Ok(JsonOp::Sync(json!({})))
-}
-
-#[derive(Deserialize)]
-struct GlobalTimerArgs {
- timeout: u64,
+ Ok(Op::Sync(empty_buf()))
}
pub fn op_global_timer(
state: &ThreadSafeState,
- args: Value,
- _zero_copy: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: GlobalTimerArgs = serde_json::from_value(args)?;
- let val = args.timeout;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ if base.sync() {
+ return Err(deno_error::no_sync_support());
+ }
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
+ let inner = base.inner_as_global_timer().unwrap();
+ let val = inner.timeout();
+ assert!(val >= 0);
let state = state;
let mut t = state.global_timer.lock().unwrap();
let deadline = Instant::now() + Duration::from_millis(val as u64);
- let f = t
- .new_timeout(deadline)
- .then(move |_| futures::future::ok(json!({})));
+ let f = t.new_timeout(deadline);
- Ok(JsonOp::Async(Box::new(f)))
+ Ok(Op::Async(Box::new(f.then(move |_| {
+ let builder = &mut FlatBufferBuilder::new();
+ let inner =
+ msg::GlobalTimerRes::create(builder, &msg::GlobalTimerResArgs {});
+ Ok(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::GlobalTimerRes,
+ ..Default::default()
+ },
+ ))
+ }))))
}
diff --git a/cli/ops/workers.rs b/cli/ops/workers.rs
index 4eeecd068..1eb11420f 100644
--- a/cli/ops/workers.rs
+++ b/cli/ops/workers.rs
@@ -1,12 +1,17 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-use super::dispatch_json::{Deserialize, JsonOp, Value};
+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::resources;
use crate::startup_data;
use crate::state::ThreadSafeState;
use crate::worker::Worker;
use deno::*;
+use flatbuffers::FlatBufferBuilder;
use futures;
use futures::Async;
use futures::Future;
@@ -34,32 +39,48 @@ impl Future for GetMessageFuture {
/// Get message from host as guest worker
pub fn op_worker_get_message(
state: &ThreadSafeState,
- _args: Value,
- _data: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ if base.sync() {
+ return Err(deno_error::no_sync_support());
+ }
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
+
let op = GetMessageFuture {
state: state.clone(),
};
-
- let op = op
- .map_err(move |_| -> ErrBox { unimplemented!() })
- .and_then(move |maybe_buf| {
- debug!("op_worker_get_message");
-
- futures::future::ok(json!({
- "data": maybe_buf.map(|buf| buf.to_owned())
- }))
- });
-
- Ok(JsonOp::Async(Box::new(op)))
+ let op = op.map_err(move |_| -> ErrBox { unimplemented!() });
+ let op = op.and_then(move |maybe_buf| -> Result<Buf, ErrBox> {
+ debug!("op_worker_get_message");
+ let builder = &mut FlatBufferBuilder::new();
+
+ let data = maybe_buf.as_ref().map(|buf| builder.create_vector(buf));
+ let inner = msg::WorkerGetMessageRes::create(
+ builder,
+ &msg::WorkerGetMessageResArgs { data },
+ );
+ Ok(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(inner.as_union_value()),
+ inner_type: msg::Any::WorkerGetMessageRes,
+ ..Default::default()
+ },
+ ))
+ });
+ Ok(Op::Async(Box::new(op)))
}
/// Post message to host as guest worker
pub fn op_worker_post_message(
state: &ThreadSafeState,
- _args: Value,
+ base: &msg::Base<'_>,
data: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
+) -> CliOpResult {
+ let cmd_id = base.cmd_id();
let d = Vec::from(data.unwrap().as_ref()).into_boxed_slice();
let tx = {
@@ -69,34 +90,33 @@ pub fn op_worker_post_message(
tx.send(d)
.wait()
.map_err(|e| DenoError::new(ErrorKind::Other, e.to_string()))?;
-
- Ok(JsonOp::Sync(json!({})))
-}
-
-#[derive(Deserialize)]
-#[serde(rename_all = "camelCase")]
-struct CreateWorkerArgs {
- specifier: String,
- include_deno_namespace: bool,
- has_source_code: bool,
- source_code: String,
+ let builder = &mut FlatBufferBuilder::new();
+
+ ok_buf(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ ..Default::default()
+ },
+ ))
}
/// Create worker as the host
pub fn op_create_worker(
state: &ThreadSafeState,
- args: Value,
- _data: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: CreateWorkerArgs = serde_json::from_value(args)?;
-
- let specifier = args.specifier.as_ref();
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
+ let inner = base.inner_as_create_worker().unwrap();
+ let specifier = inner.specifier().unwrap();
// Only include deno namespace if requested AND current worker
// has included namespace (to avoid escalation).
let include_deno_namespace =
- args.include_deno_namespace && state.include_deno_namespace;
- let has_source_code = args.has_source_code;
- let source_code = args.source_code;
+ inner.include_deno_namespace() && state.include_deno_namespace;
+ let has_source_code = inner.has_source_code();
+ let source_code = inner.source_code().unwrap();
let parent_state = state.clone();
@@ -130,13 +150,24 @@ pub fn op_create_worker(
let exec_cb = move |worker: Worker| {
let mut workers_tl = parent_state.workers.lock().unwrap();
workers_tl.insert(rid, worker.shared());
- json!(rid)
+ let builder = &mut FlatBufferBuilder::new();
+ let msg_inner =
+ msg::CreateWorkerRes::create(builder, &msg::CreateWorkerResArgs { rid });
+ serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(msg_inner.as_union_value()),
+ inner_type: msg::Any::CreateWorkerRes,
+ ..Default::default()
+ },
+ )
};
// Has provided source code, execute immediately.
if has_source_code {
worker.execute(&source_code).unwrap();
- return Ok(JsonOp::Sync(exec_cb(worker)));
+ return ok_buf(exec_cb(worker));
}
let op = worker
@@ -144,23 +175,22 @@ pub fn op_create_worker(
.and_then(move |()| Ok(exec_cb(worker)));
let result = op.wait()?;
- Ok(JsonOp::Sync(result))
-}
-
-#[derive(Deserialize)]
-struct HostGetWorkerClosedArgs {
- rid: i32,
+ Ok(Op::Sync(result))
}
/// Return when the worker closes
pub fn op_host_get_worker_closed(
state: &ThreadSafeState,
- args: Value,
- _data: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: HostGetWorkerClosedArgs = serde_json::from_value(args)?;
-
- let rid = args.rid as u32;
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ if base.sync() {
+ return Err(deno_error::no_sync_support());
+ }
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
+ let inner = base.inner_as_host_get_worker_closed().unwrap();
+ let rid = inner.rid();
let state = state.clone();
let shared_worker_future = {
@@ -169,58 +199,79 @@ pub fn op_host_get_worker_closed(
worker.clone()
};
- let op = Box::new(
- shared_worker_future.then(move |_result| futures::future::ok(json!({}))),
- );
-
- Ok(JsonOp::Async(Box::new(op)))
-}
-
-#[derive(Deserialize)]
-struct HostGetMessageArgs {
- rid: i32,
+ let op = Box::new(shared_worker_future.then(move |_result| {
+ let builder = &mut FlatBufferBuilder::new();
+
+ Ok(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ ..Default::default()
+ },
+ ))
+ }));
+ Ok(Op::Async(Box::new(op)))
}
/// Get message from guest worker as host
pub fn op_host_get_message(
_state: &ThreadSafeState,
- args: Value,
- _data: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: HostGetMessageArgs = serde_json::from_value(args)?;
-
- let rid = args.rid as u32;
- let op = resources::get_message_from_worker(rid)
- .map_err(move |_| -> ErrBox { unimplemented!() })
- .and_then(move |maybe_buf| {
- futures::future::ok(json!({
- "data": maybe_buf.map(|buf| buf.to_owned())
- }))
- });
-
- Ok(JsonOp::Async(Box::new(op)))
-}
-
-#[derive(Deserialize)]
-struct HostPostMessageArgs {
- rid: i32,
+ base: &msg::Base<'_>,
+ data: Option<PinnedBuf>,
+) -> CliOpResult {
+ if base.sync() {
+ return Err(deno_error::no_sync_support());
+ }
+ assert!(data.is_none());
+ let cmd_id = base.cmd_id();
+ let inner = base.inner_as_host_get_message().unwrap();
+ let rid = inner.rid();
+
+ let op = resources::get_message_from_worker(rid);
+ let op = op.map_err(move |_| -> ErrBox { unimplemented!() });
+ let op = op.and_then(move |maybe_buf| -> Result<Buf, ErrBox> {
+ let builder = &mut FlatBufferBuilder::new();
+
+ let data = maybe_buf.as_ref().map(|buf| builder.create_vector(buf));
+ let msg_inner = msg::HostGetMessageRes::create(
+ builder,
+ &msg::HostGetMessageResArgs { data },
+ );
+ Ok(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ inner: Some(msg_inner.as_union_value()),
+ inner_type: msg::Any::HostGetMessageRes,
+ ..Default::default()
+ },
+ ))
+ });
+ Ok(Op::Async(Box::new(op)))
}
/// Post message to guest worker as host
pub fn op_host_post_message(
_state: &ThreadSafeState,
- args: Value,
+ base: &msg::Base<'_>,
data: Option<PinnedBuf>,
-) -> Result<JsonOp, ErrBox> {
- let args: HostPostMessageArgs = serde_json::from_value(args)?;
-
- let rid = args.rid as u32;
+) -> CliOpResult {
+ let cmd_id = base.cmd_id();
+ let inner = base.inner_as_host_post_message().unwrap();
+ let rid = inner.rid();
let d = Vec::from(data.unwrap().as_ref()).into_boxed_slice();
resources::post_message_to_worker(rid, d)
.wait()
.map_err(|e| DenoError::new(ErrorKind::Other, e.to_string()))?;
-
- Ok(JsonOp::Sync(json!({})))
+ let builder = &mut FlatBufferBuilder::new();
+
+ ok_buf(serialize_response(
+ cmd_id,
+ builder,
+ msg::BaseArgs {
+ ..Default::default()
+ },
+ ))
}