1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-21 15:04:11 -05:00

use Isolate::register_op in deno_cli (#3039)

This commit is contained in:
Bartek Iwańczuk 2019-10-02 00:51:05 +02:00 committed by Ryan Dahl
parent ffbf0c20cc
commit 75eeac03f3
8 changed files with 453 additions and 472 deletions

View file

@ -1,5 +1,4 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
use crate::state::ThreadSafeState;
use crate::tokio_util;
use deno::*;
use futures::Future;
@ -23,12 +22,6 @@ fn json_err(err: ErrBox) -> Value {
})
}
pub type Dispatcher = fn(
state: &ThreadSafeState,
args: Value,
zero_copy: Option<PinnedBuf>,
) -> Result<JsonOp, ErrBox>;
fn serialize_result(
promise_id: Option<u64>,
result: Result<Value, ErrBox>,
@ -50,37 +43,39 @@ struct AsyncArgs {
promise_id: Option<u64>,
}
pub fn dispatch(
d: Dispatcher,
state: &ThreadSafeState,
control: &[u8],
zero_copy: Option<PinnedBuf>,
) -> CoreOp {
let async_args: AsyncArgs = serde_json::from_slice(control).unwrap();
let promise_id = async_args.promise_id;
let is_sync = promise_id.is_none();
pub fn json_op<D>(d: D) -> impl Fn(&[u8], Option<PinnedBuf>) -> CoreOp
where
D: Fn(Value, Option<PinnedBuf>) -> Result<JsonOp, ErrBox>,
{
move |control: &[u8], zero_copy: Option<PinnedBuf>| {
let async_args: AsyncArgs = serde_json::from_slice(control).unwrap();
let promise_id = async_args.promise_id;
let is_sync = promise_id.is_none();
let result = serde_json::from_slice(control)
.map_err(ErrBox::from)
.and_then(move |args| d(state, args, zero_copy));
match result {
Ok(JsonOp::Sync(sync_value)) => {
assert!(promise_id.is_none());
CoreOp::Sync(serialize_result(promise_id, Ok(sync_value)))
}
Ok(JsonOp::Async(fut)) => {
assert!(promise_id.is_some());
let fut2 = Box::new(fut.then(move |result| -> Result<Buf, ()> {
Ok(serialize_result(promise_id, result))
}));
CoreOp::Async(fut2)
}
Err(sync_err) => {
let buf = serialize_result(promise_id, Err(sync_err));
if is_sync {
CoreOp::Sync(buf)
} else {
CoreOp::Async(Box::new(futures::future::ok(buf)))
let result = serde_json::from_slice(control)
.map_err(ErrBox::from)
.and_then(|args| d(args, zero_copy));
// Convert to CoreOp
match result {
Ok(JsonOp::Sync(sync_value)) => {
assert!(promise_id.is_none());
CoreOp::Sync(serialize_result(promise_id, Ok(sync_value)))
}
Ok(JsonOp::Async(fut)) => {
assert!(promise_id.is_some());
let fut2 = Box::new(fut.then(move |result| -> Result<Buf, ()> {
Ok(serialize_result(promise_id, result))
}));
CoreOp::Async(fut2)
}
Err(sync_err) => {
let buf = serialize_result(promise_id, Err(sync_err));
if is_sync {
CoreOp::Sync(buf)
} else {
CoreOp::Async(Box::new(futures::future::ok(buf)))
}
}
}
}

View file

@ -4,7 +4,6 @@
//! alternative to flatbuffers using a very simple list of int32s to lay out
//! messages. The first i32 is used to determine if a message a flatbuffer
//! message or a "minimal" message.
use crate::state::ThreadSafeState;
use deno::Buf;
use deno::CoreOp;
use deno::ErrBox;
@ -72,40 +71,40 @@ fn test_parse_min_record() {
assert_eq!(parse_min_record(&buf), None);
}
pub fn dispatch(
pub fn minimal_op(
d: Dispatcher,
_state: &ThreadSafeState,
control: &[u8],
zero_copy: Option<PinnedBuf>,
) -> CoreOp {
let mut record = parse_min_record(control).unwrap();
let is_sync = record.promise_id == 0;
let rid = record.arg;
let min_op = d(rid, zero_copy);
) -> impl Fn(&[u8], Option<PinnedBuf>) -> CoreOp {
move |control: &[u8], zero_copy: Option<PinnedBuf>| {
let mut record = parse_min_record(control).unwrap();
let is_sync = record.promise_id == 0;
let rid = record.arg;
let min_op = d(rid, zero_copy);
let fut = Box::new(min_op.then(move |result| -> Result<Buf, ()> {
match result {
Ok(r) => {
record.result = r;
}
Err(err) => {
// TODO(ry) The dispatch_minimal doesn't properly pipe errors back to
// the caller.
debug!("swallowed err {}", err);
record.result = -1;
// Convert to CoreOp
let fut = Box::new(min_op.then(move |result| -> Result<Buf, ()> {
match result {
Ok(r) => {
record.result = r;
}
Err(err) => {
// TODO(ry) The dispatch_minimal doesn't properly pipe errors back to
// the caller.
debug!("swallowed err {}", err);
record.result = -1;
}
}
Ok(record.into())
}));
if is_sync {
// Warning! Possible deadlocks can occur if we try to wait for a future
// while in a future. The safe but expensive alternative is to use
// tokio_util::block_on.
// This block is only exercised for readSync and writeSync, which I think
// works since they're simple polling futures.
Op::Sync(fut.wait().unwrap())
} else {
Op::Async(fut)
}
Ok(record.into())
}));
if is_sync {
// Warning! Possible deadlocks can occur if we try to wait for a future
// while in a future. The safe but expensive alternative is to use
// tokio_util::block_on.
// This block is only exercised for readSync and writeSync, which I think
// works since they're simple polling futures.
Op::Sync(fut.wait().unwrap())
} else {
Op::Async(fut)
}
}

View file

@ -1,332 +1,25 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
use crate::state::ThreadSafeState;
use deno::*;
mod compiler;
mod dispatch_json;
mod dispatch_minimal;
mod errors;
mod fetch;
mod files;
mod fs;
mod io;
mod metrics;
mod net;
mod os;
mod performance;
mod permissions;
mod process;
mod random;
mod repl;
mod resources;
mod timers;
mod tls;
mod workers;
// Warning! These values are duplicated in the TypeScript code (js/dispatch.ts),
// update with care.
pub const OP_READ: OpId = 1;
pub const OP_WRITE: OpId = 2;
pub const OP_EXIT: OpId = 3;
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_FILES: 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 const OP_CHDIR: OpId = 42;
pub const OP_MKDIR: OpId = 43;
pub const OP_CHMOD: OpId = 44;
pub const OP_CHOWN: OpId = 45;
pub const OP_REMOVE: OpId = 46;
pub const OP_COPY_FILE: OpId = 47;
pub const OP_STAT: OpId = 48;
pub const OP_READ_DIR: OpId = 49;
pub const OP_RENAME: OpId = 50;
pub const OP_LINK: OpId = 51;
pub const OP_SYMLINK: OpId = 52;
pub const OP_READ_LINK: OpId = 53;
pub const OP_TRUNCATE: OpId = 54;
pub const OP_MAKE_TEMP_DIR: OpId = 55;
pub const OP_CWD: OpId = 56;
pub const OP_FETCH_ASSET: OpId = 57;
pub const OP_DIAL_TLS: OpId = 58;
pub const OP_HOSTNAME: OpId = 59;
pub use dispatch_json::json_op;
pub use dispatch_json::JsonOp;
pub use dispatch_minimal::minimal_op;
pub fn dispatch(
state: &ThreadSafeState,
op_id: OpId,
control: &[u8],
zero_copy: Option<PinnedBuf>,
) -> 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 = 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_EXIT => dispatch_json::dispatch(os::op_exit, state, control, zero_copy),
OP_IS_TTY => {
dispatch_json::dispatch(os::op_is_tty, state, control, zero_copy)
}
OP_ENV => dispatch_json::dispatch(os::op_env, state, control, zero_copy),
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_FILES => dispatch_json::dispatch(
compiler::op_fetch_source_files,
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_CHDIR => {
dispatch_json::dispatch(fs::op_chdir, state, control, zero_copy)
}
OP_MKDIR => {
dispatch_json::dispatch(fs::op_mkdir, state, control, zero_copy)
}
OP_CHMOD => {
dispatch_json::dispatch(fs::op_chmod, state, control, zero_copy)
}
OP_CHOWN => {
dispatch_json::dispatch(fs::op_chown, state, control, zero_copy)
}
OP_REMOVE => {
dispatch_json::dispatch(fs::op_remove, state, control, zero_copy)
}
OP_COPY_FILE => {
dispatch_json::dispatch(fs::op_copy_file, state, control, zero_copy)
}
OP_STAT => dispatch_json::dispatch(fs::op_stat, state, control, zero_copy),
OP_READ_DIR => {
dispatch_json::dispatch(fs::op_read_dir, state, control, zero_copy)
}
OP_RENAME => {
dispatch_json::dispatch(fs::op_rename, state, control, zero_copy)
}
OP_LINK => dispatch_json::dispatch(fs::op_link, state, control, zero_copy),
OP_SYMLINK => {
dispatch_json::dispatch(fs::op_symlink, state, control, zero_copy)
}
OP_READ_LINK => {
dispatch_json::dispatch(fs::op_read_link, state, control, zero_copy)
}
OP_TRUNCATE => {
dispatch_json::dispatch(fs::op_truncate, state, control, zero_copy)
}
OP_MAKE_TEMP_DIR => {
dispatch_json::dispatch(fs::op_make_temp_dir, state, control, zero_copy)
}
OP_CWD => dispatch_json::dispatch(fs::op_cwd, state, control, zero_copy),
OP_FETCH_ASSET => dispatch_json::dispatch(
compiler::op_fetch_asset,
state,
control,
zero_copy,
),
OP_DIAL_TLS => {
dispatch_json::dispatch(tls::op_dial_tls, state, control, zero_copy)
}
OP_HOSTNAME => {
dispatch_json::dispatch(os::op_hostname, state, control, zero_copy)
}
_ => panic!("bad op_id"),
};
state.metrics_op_dispatched(bytes_sent_control, bytes_sent_zero_copy);
match op {
Op::Sync(buf) => {
state.metrics_op_completed(buf.len());
Op::Sync(buf)
}
Op::Async(fut) => {
use crate::futures::Future;
let state = state.clone();
let result_fut = Box::new(fut.map(move |buf: Buf| {
state.clone().metrics_op_completed(buf.len());
buf
}));
Op::Async(result_fut)
}
}
}
pub mod compiler;
pub mod errors;
pub mod fetch;
pub mod files;
pub mod fs;
pub mod io;
pub mod metrics;
pub mod net;
pub mod os;
pub mod performance;
pub mod permissions;
pub mod process;
pub mod random;
pub mod repl;
pub mod resources;
pub mod timers;
pub mod workers;

View file

@ -10,7 +10,7 @@ use crate::flags;
use crate::global_timer::GlobalTimer;
use crate::import_map::ImportMap;
use crate::msg;
use crate::ops;
use crate::ops::JsonOp;
use crate::permissions::DenoPermissions;
use crate::progress::Progress;
use crate::resources;
@ -21,12 +21,13 @@ use deno::CoreOp;
use deno::ErrBox;
use deno::Loader;
use deno::ModuleSpecifier;
use deno::OpId;
use deno::Op;
use deno::PinnedBuf;
use futures::future::Shared;
use futures::Future;
use rand::rngs::StdRng;
use rand::SeedableRng;
use serde_json::Value;
use std;
use std::collections::HashMap;
use std::env;
@ -103,13 +104,59 @@ impl Deref for ThreadSafeState {
}
impl ThreadSafeState {
pub fn dispatch(
// TODO: better name welcome
/// Wrap core `OpDispatcher` to collect metrics.
pub fn cli_op<D>(
&self,
op_id: OpId,
control: &[u8],
zero_copy: Option<PinnedBuf>,
) -> CoreOp {
ops::dispatch(self, op_id, control, zero_copy)
dispatcher: D,
) -> impl Fn(&[u8], Option<PinnedBuf>) -> CoreOp
where
D: Fn(&[u8], Option<PinnedBuf>) -> CoreOp,
{
let state = self.clone();
move |control: &[u8], zero_copy: Option<PinnedBuf>| -> 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 = dispatcher(control, zero_copy);
state.metrics_op_dispatched(bytes_sent_control, bytes_sent_zero_copy);
match op {
Op::Sync(buf) => {
state.metrics_op_completed(buf.len());
Op::Sync(buf)
}
Op::Async(fut) => {
let state = state.clone();
let result_fut = Box::new(fut.map(move |buf: Buf| {
state.clone().metrics_op_completed(buf.len());
buf
}));
Op::Async(result_fut)
}
}
}
}
/// This is a special function that provides `state` argument to dispatcher.
///
/// NOTE: This only works with JSON dispatcher.
/// This is a band-aid for transition to `Isolate.register_op` API as most of our
/// ops require `state` argument.
pub fn stateful_op<D>(
&self,
dispatcher: D,
) -> impl Fn(Value, Option<PinnedBuf>) -> Result<JsonOp, ErrBox>
where
D: Fn(&ThreadSafeState, Value, Option<PinnedBuf>) -> Result<JsonOp, ErrBox>,
{
let state = self.clone();
move |args: Value, zero_copy: Option<PinnedBuf>| -> Result<JsonOp, ErrBox> {
dispatcher(&state, args, zero_copy)
}
}
}

View file

@ -1,5 +1,8 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
use crate::fmt_errors::JSError;
use crate::ops::json_op;
use crate::ops::minimal_op;
use crate::ops::*;
use crate::state::ThreadSafeState;
use crate::tokio_util;
use deno;
@ -31,11 +34,251 @@ impl Worker {
let isolate = Arc::new(Mutex::new(deno::Isolate::new(startup_data, false)));
{
let mut i = isolate.lock().unwrap();
let state_ = state.clone();
i.set_dispatch(move |op_id, control_buf, zero_copy_buf| {
state_.dispatch(op_id, control_buf, zero_copy_buf)
});
i.register_op("read", state_.cli_op(minimal_op(io::op_read)));
i.register_op("write", state_.cli_op(minimal_op(io::op_write)));
i.register_op(
"exit",
state_.cli_op(json_op(state_.stateful_op(os::op_exit))),
);
i.register_op(
"is_tty",
state_.cli_op(json_op(state_.stateful_op(os::op_is_tty))),
);
i.register_op(
"env",
state_.cli_op(json_op(state_.stateful_op(os::op_env))),
);
i.register_op(
"exec_path",
state_.cli_op(json_op(state_.stateful_op(os::op_exec_path))),
);
i.register_op(
"utime",
state_.cli_op(json_op(state_.stateful_op(fs::op_utime))),
);
i.register_op(
"set_env",
state_.cli_op(json_op(state_.stateful_op(os::op_set_env))),
);
i.register_op(
"home_dir",
state_.cli_op(json_op(state_.stateful_op(os::op_home_dir))),
);
i.register_op(
"start",
state_.cli_op(json_op(state_.stateful_op(os::op_start))),
);
i.register_op(
"apply_source_map",
state_.cli_op(json_op(state_.stateful_op(errors::op_apply_source_map))),
);
i.register_op(
"format_error",
state_.cli_op(json_op(state_.stateful_op(errors::op_format_error))),
);
i.register_op(
"cache",
state_.cli_op(json_op(state_.stateful_op(compiler::op_cache))),
);
i.register_op(
"fetch_source_files",
state_
.cli_op(json_op(state_.stateful_op(compiler::op_fetch_source_files))),
);
i.register_op(
"open",
state_.cli_op(json_op(state_.stateful_op(files::op_open))),
);
i.register_op(
"close",
state_.cli_op(json_op(state_.stateful_op(files::op_close))),
);
i.register_op(
"seek",
state_.cli_op(json_op(state_.stateful_op(files::op_seek))),
);
i.register_op(
"fetch",
state_.cli_op(json_op(state_.stateful_op(fetch::op_fetch))),
);
i.register_op(
"metrics",
state_.cli_op(json_op(state_.stateful_op(metrics::op_metrics))),
);
i.register_op(
"repl_start",
state_.cli_op(json_op(state_.stateful_op(repl::op_repl_start))),
);
i.register_op(
"repl_readline",
state_.cli_op(json_op(state_.stateful_op(repl::op_repl_readline))),
);
i.register_op(
"accept",
state_.cli_op(json_op(state_.stateful_op(net::op_accept))),
);
i.register_op(
"dial",
state_.cli_op(json_op(state_.stateful_op(net::op_dial))),
);
i.register_op(
"dial_tls",
state_.cli_op(json_op(state_.stateful_op(net::op_dial))),
);
i.register_op(
"shutdown",
state_.cli_op(json_op(state_.stateful_op(net::op_shutdown))),
);
i.register_op(
"listen",
state_.cli_op(json_op(state_.stateful_op(net::op_listen))),
);
i.register_op(
"resources",
state_.cli_op(json_op(state_.stateful_op(resources::op_resources))),
);
i.register_op(
"get_random_values",
state_
.cli_op(json_op(state_.stateful_op(random::op_get_random_values))),
);
i.register_op(
"global_timer_stop",
state_
.cli_op(json_op(state_.stateful_op(timers::op_global_timer_stop))),
);
i.register_op(
"global_timer",
state_.cli_op(json_op(state_.stateful_op(timers::op_global_timer))),
);
i.register_op(
"now",
state_.cli_op(json_op(state_.stateful_op(performance::op_now))),
);
i.register_op(
"permissions",
state_.cli_op(json_op(state_.stateful_op(permissions::op_permissions))),
);
i.register_op(
"revoke_permission",
state_.cli_op(json_op(
state_.stateful_op(permissions::op_revoke_permission),
)),
);
i.register_op(
"create_worker",
state_.cli_op(json_op(state_.stateful_op(workers::op_create_worker))),
);
i.register_op(
"host_get_worker_closed",
state_.cli_op(json_op(
state_.stateful_op(workers::op_host_get_worker_closed),
)),
);
i.register_op(
"host_post_message",
state_
.cli_op(json_op(state_.stateful_op(workers::op_host_post_message))),
);
i.register_op(
"host_get_message",
state_
.cli_op(json_op(state_.stateful_op(workers::op_host_get_message))),
);
// TODO: make sure these two ops are only accessible to appropriate Worker
i.register_op(
"worker_post_message",
state_
.cli_op(json_op(state_.stateful_op(workers::op_worker_post_message))),
);
i.register_op(
"worker_get_message",
state_
.cli_op(json_op(state_.stateful_op(workers::op_worker_get_message))),
);
i.register_op(
"run",
state_.cli_op(json_op(state_.stateful_op(process::op_run))),
);
i.register_op(
"run_status",
state_.cli_op(json_op(state_.stateful_op(process::op_run_status))),
);
i.register_op(
"kill",
state_.cli_op(json_op(state_.stateful_op(process::op_kill))),
);
i.register_op(
"chdir",
state_.cli_op(json_op(state_.stateful_op(fs::op_chdir))),
);
i.register_op(
"mkdir",
state_.cli_op(json_op(state_.stateful_op(fs::op_mkdir))),
);
i.register_op(
"chmod",
state_.cli_op(json_op(state_.stateful_op(fs::op_chmod))),
);
i.register_op(
"chown",
state_.cli_op(json_op(state_.stateful_op(fs::op_chown))),
);
i.register_op(
"remove",
state_.cli_op(json_op(state_.stateful_op(fs::op_remove))),
);
i.register_op(
"copy_file",
state_.cli_op(json_op(state_.stateful_op(fs::op_copy_file))),
);
i.register_op(
"stat",
state_.cli_op(json_op(state_.stateful_op(fs::op_stat))),
);
i.register_op(
"read_dir",
state_.cli_op(json_op(state_.stateful_op(fs::op_read_dir))),
);
i.register_op(
"rename",
state_.cli_op(json_op(state_.stateful_op(fs::op_rename))),
);
i.register_op(
"link",
state_.cli_op(json_op(state_.stateful_op(fs::op_link))),
);
i.register_op(
"symlink",
state_.cli_op(json_op(state_.stateful_op(fs::op_symlink))),
);
i.register_op(
"read_link",
state_.cli_op(json_op(state_.stateful_op(fs::op_read_link))),
);
i.register_op(
"truncate",
state_.cli_op(json_op(state_.stateful_op(fs::op_truncate))),
);
i.register_op(
"make_temp_dir",
state_.cli_op(json_op(state_.stateful_op(fs::op_make_temp_dir))),
);
i.register_op(
"cwd",
state_.cli_op(json_op(state_.stateful_op(fs::op_cwd))),
);
i.register_op(
"fetch_asset",
state_.cli_op(json_op(state_.stateful_op(compiler::op_fetch_asset))),
);
i.register_op(
"hostname",
state_.cli_op(json_op(state_.stateful_op(os::op_hostname))),
);
let state_ = state.clone();
i.set_dyn_import(move |id, specifier, referrer| {

View file

@ -37,10 +37,7 @@ declare interface DenoCore {
shift(): Uint8Array | null;
};
ops: {
init(): void;
get(name: string): number;
};
ops(): Record<string, number>;
recv(cb: MessageCallback): void;

View file

@ -3,65 +3,65 @@ import * as minimal from "./dispatch_minimal.ts";
import * as json from "./dispatch_json.ts";
// These consts are shared with Rust. Update with care.
export const OP_READ = 1;
export const OP_WRITE = 2;
export const OP_EXIT = 3;
export const OP_IS_TTY = 4;
export const OP_ENV = 5;
export const OP_EXEC_PATH = 6;
export const OP_UTIME = 7;
export const OP_SET_ENV = 8;
export const OP_HOME_DIR = 9;
export const OP_START = 10;
export const OP_APPLY_SOURCE_MAP = 11;
export const OP_FORMAT_ERROR = 12;
export const OP_CACHE = 13;
export const OP_FETCH_SOURCE_FILES = 14;
export const OP_OPEN = 15;
export const OP_CLOSE = 16;
export const OP_SEEK = 17;
export const OP_FETCH = 18;
export const OP_METRICS = 19;
export const OP_REPL_START = 20;
export const OP_REPL_READLINE = 21;
export const OP_ACCEPT = 22;
export const OP_DIAL = 23;
export const OP_SHUTDOWN = 24;
export const OP_LISTEN = 25;
export const OP_RESOURCES = 26;
export const OP_GET_RANDOM_VALUES = 27;
export const OP_GLOBAL_TIMER_STOP = 28;
export const OP_GLOBAL_TIMER = 29;
export const OP_NOW = 30;
export const OP_PERMISSIONS = 31;
export const OP_REVOKE_PERMISSION = 32;
export const OP_CREATE_WORKER = 33;
export const OP_HOST_GET_WORKER_CLOSED = 34;
export const OP_HOST_POST_MESSAGE = 35;
export const OP_HOST_GET_MESSAGE = 36;
export const OP_WORKER_POST_MESSAGE = 37;
export const OP_WORKER_GET_MESSAGE = 38;
export const OP_RUN = 39;
export const OP_RUN_STATUS = 40;
export const OP_KILL = 41;
export const OP_CHDIR = 42;
export const OP_MKDIR = 43;
export const OP_CHMOD = 44;
export const OP_CHOWN = 45;
export const OP_REMOVE = 46;
export const OP_COPY_FILE = 47;
export const OP_STAT = 48;
export const OP_READ_DIR = 49;
export const OP_RENAME = 50;
export const OP_LINK = 51;
export const OP_SYMLINK = 52;
export const OP_READ_LINK = 53;
export const OP_TRUNCATE = 54;
export const OP_MAKE_TEMP_DIR = 55;
export const OP_CWD = 56;
export const OP_FETCH_ASSET = 57;
export const OP_DIAL_TLS = 58;
export const OP_HOSTNAME = 59;
export let OP_READ: number;
export let OP_WRITE: number;
export let OP_EXIT: number;
export let OP_IS_TTY: number;
export let OP_ENV: number;
export let OP_EXEC_PATH: number;
export let OP_UTIME: number;
export let OP_SET_ENV: number;
export let OP_HOME_DIR: number;
export let OP_START: number;
export let OP_APPLY_SOURCE_MAP: number;
export let OP_FORMAT_ERROR: number;
export let OP_CACHE: number;
export let OP_FETCH_SOURCE_FILES: number;
export let OP_OPEN: number;
export let OP_CLOSE: number;
export let OP_SEEK: number;
export let OP_FETCH: number;
export let OP_METRICS: number;
export let OP_REPL_START: number;
export let OP_REPL_READLINE: number;
export let OP_ACCEPT: number;
export let OP_DIAL: number;
export let OP_SHUTDOWN: number;
export let OP_LISTEN: number;
export let OP_RESOURCES: number;
export let OP_GET_RANDOM_VALUES: number;
export let OP_GLOBAL_TIMER_STOP: number;
export let OP_GLOBAL_TIMER: number;
export let OP_NOW: number;
export let OP_PERMISSIONS: number;
export let OP_REVOKE_PERMISSION: number;
export let OP_CREATE_WORKER: number;
export let OP_HOST_GET_WORKER_CLOSED: number;
export let OP_HOST_POST_MESSAGE: number;
export let OP_HOST_GET_MESSAGE: number;
export let OP_WORKER_POST_MESSAGE: number;
export let OP_WORKER_GET_MESSAGE: number;
export let OP_RUN: number;
export let OP_RUN_STATUS: number;
export let OP_KILL: number;
export let OP_CHDIR: number;
export let OP_MKDIR: number;
export let OP_CHMOD: number;
export let OP_CHOWN: number;
export let OP_REMOVE: number;
export let OP_COPY_FILE: number;
export let OP_STAT: number;
export let OP_READ_DIR: number;
export let OP_RENAME: number;
export let OP_LINK: number;
export let OP_SYMLINK: number;
export let OP_READ_LINK: number;
export let OP_TRUNCATE: number;
export let OP_MAKE_TEMP_DIR: number;
export let OP_CWD: number;
export let OP_FETCH_ASSET: number;
export let OP_DIAL_TLS: number;
export let OP_HOSTNAME: number;
export function asyncMsgFromRust(opId: number, ui8: Uint8Array): void {
switch (opId) {

View file

@ -81,7 +81,14 @@ interface Start {
// @internal
export function start(preserveDenoNamespace = true, source?: string): Start {
core.setAsyncHandler(dispatch.asyncMsgFromRust);
const ops = core.ops();
// TODO(bartlomieju): this is a prototype, we should come up with
// something a bit more sophisticated
for (const [name, opId] of Object.entries(ops)) {
const opName = `OP_${name.toUpperCase()}`;
// Assign op ids to actual variables
dispatch[opName] = opId;
}
// First we send an empty `Start` message to let the privileged side know we
// are ready. The response should be a `StartRes` message containing the CLI
// args and other info.