summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2020-09-10 09:57:45 -0400
committerGitHub <noreply@github.com>2020-09-10 09:57:45 -0400
commit7c2e7c660804afca823d60e6496aa853f75db16c (patch)
treeb7746b181c1564c6b1abd2e906662f9e6b008417
parent6f70e6e72ba2d5c1de7495adac37c1e4f4e86b24 (diff)
Use gotham-like state for ops (#7385)
Provides a concrete state type that can be dynamically added. This is necessary for op crates. * renames BasicState to OpState * async ops take `Rc<RefCell<OpState>>` * sync ops take `&mut OpState` * removes `OpRegistry`, `OpRouter` traits * `get_error_class_fn` moved to OpState * ResourceTable moved to OpState
-rw-r--r--cli/build.rs11
-rw-r--r--cli/js.rs2
-rw-r--r--cli/metrics.rs57
-rw-r--r--cli/ops/compiler.rs32
-rw-r--r--cli/ops/dispatch_minimal.rs134
-rw-r--r--cli/ops/errors.rs16
-rw-r--r--cli/ops/fetch.rs29
-rw-r--r--cli/ops/fs.rs440
-rw-r--r--cli/ops/fs_events.rs26
-rw-r--r--cli/ops/idna.rs9
-rw-r--r--cli/ops/io.rs40
-rw-r--r--cli/ops/mod.rs40
-rw-r--r--cli/ops/net.rs117
-rw-r--r--cli/ops/net_unix.rs52
-rw-r--r--cli/ops/os.rs81
-rw-r--r--cli/ops/permissions.rs27
-rw-r--r--cli/ops/plugin.rs65
-rw-r--r--cli/ops/process.rs46
-rw-r--r--cli/ops/random.rs14
-rw-r--r--cli/ops/repl.rs39
-rw-r--r--cli/ops/resources.rs18
-rw-r--r--cli/ops/runtime.rs28
-rw-r--r--cli/ops/runtime_compiler.rs28
-rw-r--r--cli/ops/signal.rs42
-rw-r--r--cli/ops/timers.rs40
-rw-r--r--cli/ops/tls.rs107
-rw-r--r--cli/ops/tty.rs33
-rw-r--r--cli/ops/web_worker.rs15
-rw-r--r--cli/ops/websocket.rs48
-rw-r--r--cli/ops/worker_host.rs89
-rw-r--r--cli/state.rs90
-rw-r--r--cli/tsc.rs13
-rw-r--r--cli/web_worker.rs54
-rw-r--r--cli/worker.rs76
-rw-r--r--core/basic_state.rs91
-rw-r--r--core/bindings.rs4
-rw-r--r--core/examples/http_bench_bin_ops.rs84
-rw-r--r--core/examples/http_bench_json_ops.rs46
-rw-r--r--core/gotham_state.rs167
-rw-r--r--core/lib.rs8
-rw-r--r--core/modules.rs49
-rw-r--r--core/ops.rs256
-rw-r--r--core/runtime.rs251
-rw-r--r--op_crates/web/lib.rs4
44 files changed, 1573 insertions, 1345 deletions
diff --git a/cli/build.rs b/cli/build.rs
index 422bc1759..f2abb9529 100644
--- a/cli/build.rs
+++ b/cli/build.rs
@@ -3,9 +3,7 @@
mod op_fetch_asset;
use deno_core::js_check;
-use deno_core::BasicState;
use deno_core::JsRuntime;
-use deno_core::OpRegistry;
use deno_core::StartupData;
use std::collections::HashMap;
use std::env;
@@ -39,8 +37,7 @@ fn create_snapshot(
}
fn create_runtime_snapshot(snapshot_path: &Path, files: Vec<PathBuf>) {
- let state = BasicState::new();
- let isolate = JsRuntime::new(state, StartupData::None, true);
+ let isolate = JsRuntime::new(StartupData::None, true);
create_snapshot(isolate, snapshot_path, files);
}
@@ -73,13 +70,11 @@ fn create_compiler_snapshot(
cwd.join("dts/lib.deno.unstable.d.ts"),
);
- let state = BasicState::new();
- state.register_op(
+ let mut isolate = JsRuntime::new(StartupData::None, true);
+ isolate.register_op(
"op_fetch_asset",
op_fetch_asset::op_fetch_asset(custom_libs),
);
-
- let isolate = JsRuntime::new(state, StartupData::None, true);
create_snapshot(isolate, snapshot_path, files);
}
diff --git a/cli/js.rs b/cli/js.rs
index 6e6767873..2dc56710d 100644
--- a/cli/js.rs
+++ b/cli/js.rs
@@ -14,7 +14,6 @@ pub static UNSTABLE_NS_LIB: &str = include_str!("dts/lib.deno.unstable.d.ts");
#[test]
fn cli_snapshot() {
let mut isolate = deno_core::JsRuntime::new(
- deno_core::BasicState::new(),
deno_core::StartupData::Snapshot(deno_core::Snapshot::Static(CLI_SNAPSHOT)),
false,
);
@@ -32,7 +31,6 @@ fn cli_snapshot() {
#[test]
fn compiler_snapshot() {
let mut isolate = deno_core::JsRuntime::new(
- deno_core::BasicState::new(),
deno_core::StartupData::Snapshot(deno_core::Snapshot::Static(
COMPILER_SNAPSHOT,
)),
diff --git a/cli/metrics.rs b/cli/metrics.rs
index 43f11cd36..227c10f60 100644
--- a/cli/metrics.rs
+++ b/cli/metrics.rs
@@ -71,3 +71,60 @@ impl Metrics {
self.op_completed(bytes_received);
}
}
+
+use deno_core::BufVec;
+use deno_core::Op;
+use deno_core::OpFn;
+use deno_core::OpState;
+use std::cell::RefCell;
+use std::rc::Rc;
+
+pub fn metrics_op(op_fn: Box<OpFn>) -> Box<OpFn> {
+ Box::new(move |op_state: Rc<RefCell<OpState>>, bufs: BufVec| -> Op {
+ // TODOs:
+ // * The 'bytes' metrics seem pretty useless, especially now that the
+ // distinction between 'control' and 'data' buffers has become blurry.
+ // * Tracking completion of async ops currently makes us put the boxed
+ // future into _another_ box. Keeping some counters may not be expensive
+ // in itself, but adding a heap allocation for every metric seems bad.
+ let mut buf_len_iter = bufs.iter().map(|buf| buf.len());
+ let bytes_sent_control = buf_len_iter.next().unwrap_or(0);
+ let bytes_sent_data = buf_len_iter.sum();
+
+ let op = (op_fn)(op_state.clone(), bufs);
+
+ let cli_state = crate::ops::cli_state2(&op_state);
+ let cli_state_ = cli_state.clone();
+ let mut metrics = cli_state.metrics.borrow_mut();
+
+ use futures::future::FutureExt;
+
+ match op {
+ Op::Sync(buf) => {
+ metrics.op_sync(bytes_sent_control, bytes_sent_data, buf.len());
+ Op::Sync(buf)
+ }
+ Op::Async(fut) => {
+ metrics.op_dispatched_async(bytes_sent_control, bytes_sent_data);
+ let fut = fut
+ .inspect(move |buf| {
+ let mut metrics = cli_state_.metrics.borrow_mut();
+ metrics.op_completed_async(buf.len());
+ })
+ .boxed_local();
+ Op::Async(fut)
+ }
+ Op::AsyncUnref(fut) => {
+ metrics.op_dispatched_async_unref(bytes_sent_control, bytes_sent_data);
+ let fut = fut
+ .inspect(move |buf| {
+ let mut metrics = cli_state_.metrics.borrow_mut();
+ metrics.op_completed_async_unref(buf.len());
+ })
+ .boxed_local();
+ Op::AsyncUnref(fut)
+ }
+ other => other,
+ }
+ })
+}
diff --git a/cli/ops/compiler.rs b/cli/ops/compiler.rs
index 0b8379fa3..618851daa 100644
--- a/cli/ops/compiler.rs
+++ b/cli/ops/compiler.rs
@@ -1,27 +1,31 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::state::State;
-use deno_core::OpRegistry;
-use std::rc::Rc;
use std::sync::Arc;
use std::sync::Mutex;
-pub fn init(s: &Rc<State>, response: Arc<Mutex<Option<String>>>) {
+pub fn init(
+ rt: &mut deno_core::JsRuntime,
+ response: Arc<Mutex<Option<String>>>,
+) {
let custom_assets = std::collections::HashMap::new();
// TODO(ry) use None.
// TODO(bartlomieju): is this op even required?
- s.register_op(
+ rt.register_op(
"op_fetch_asset",
crate::op_fetch_asset::op_fetch_asset(custom_assets),
);
- s.register_op_json_sync("op_compiler_respond", move |_state, args, _bufs| {
- let mut response_slot = response.lock().unwrap();
- let replaced_value = response_slot.replace(args.to_string());
- assert!(
- replaced_value.is_none(),
- "op_compiler_respond found unexpected existing compiler output",
- );
- Ok(json!({}))
- });
+ super::reg_json_sync(
+ rt,
+ "op_compiler_respond",
+ move |_state, args, _bufs| {
+ let mut response_slot = response.lock().unwrap();
+ let replaced_value = response_slot.replace(args.to_string());
+ assert!(
+ replaced_value.is_none(),
+ "op_compiler_respond found unexpected existing compiler output",
+ );
+ Ok(json!({}))
+ },
+ );
}
diff --git a/cli/ops/dispatch_minimal.rs b/cli/ops/dispatch_minimal.rs
index 9d941682d..0429e7f7b 100644
--- a/cli/ops/dispatch_minimal.rs
+++ b/cli/ops/dispatch_minimal.rs
@@ -1,12 +1,12 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::state::State;
use deno_core::BufVec;
use deno_core::ErrBox;
use deno_core::Op;
-use deno_core::OpId;
-use deno_core::OpRegistry;
+use deno_core::OpFn;
+use deno_core::OpState;
use futures::future::FutureExt;
+use std::cell::RefCell;
use std::future::Future;
use std::iter::repeat;
use std::mem::size_of_val;
@@ -132,78 +132,74 @@ fn test_parse_min_record() {
assert_eq!(parse_min_record(&buf), None);
}
-impl State {
- pub fn register_op_minimal<F>(self: &Rc<Self>, name: &str, op_fn: F) -> OpId
- where
- F: Fn(Rc<Self>, bool, i32, BufVec) -> MinimalOp + 'static,
- {
- let base_op_fn = move |state: Rc<Self>, bufs: BufVec| {
- let mut bufs_iter = bufs.into_iter();
- let record_buf = bufs_iter.next().expect("Expected record at position 0");
- let zero_copy = bufs_iter.collect::<BufVec>();
-
- let mut record = match parse_min_record(&record_buf) {
- Some(r) => r,
- None => {
- let error = ErrBox::type_error("Unparsable control buffer");
- let error_class = state.get_error_class_name(&error);
+pub fn minimal_op<F>(op_fn: F) -> Box<OpFn>
+where
+ F: Fn(Rc<RefCell<OpState>>, bool, i32, BufVec) -> MinimalOp + 'static,
+{
+ Box::new(move |state: Rc<RefCell<OpState>>, bufs: BufVec| {
+ let mut bufs_iter = bufs.into_iter();
+ let record_buf = bufs_iter.next().expect("Expected record at position 0");
+ let zero_copy = bufs_iter.collect::<BufVec>();
+
+ let mut record = match parse_min_record(&record_buf) {
+ Some(r) => r,
+ None => {
+ let error = ErrBox::type_error("Unparsable control buffer");
+ let error_class = (state.borrow().get_error_class_fn)(&error);
+ let error_record = ErrorRecord {
+ promise_id: 0,
+ arg: -1,
+ error_len: error_class.len() as i32,
+ error_class: error_class.as_bytes(),
+ error_message: error.to_string().as_bytes().to_owned(),
+ };
+ return Op::Sync(error_record.into());
+ }
+ };
+ let is_sync = record.promise_id == 0;
+ let rid = record.arg;
+ let min_op = op_fn(state.clone(), is_sync, rid, zero_copy);
+
+ match min_op {
+ MinimalOp::Sync(sync_result) => Op::Sync(match sync_result {
+ Ok(r) => {
+ record.result = r;
+ record.into()
+ }
+ Err(err) => {
+ let error_class = (state.borrow().get_error_class_fn)(&err);
let error_record = ErrorRecord {
- promise_id: 0,
+ promise_id: record.promise_id,
arg: -1,
error_len: error_class.len() as i32,
error_class: error_class.as_bytes(),
- error_message: error.to_string().as_bytes().to_owned(),
+ error_message: err.to_string().as_bytes().to_owned(),
};
- return Op::Sync(error_record.into());
+ error_record.into()
}
- };
- let is_sync = record.promise_id == 0;
- let rid = record.arg;
- let min_op = op_fn(state.clone(), is_sync, rid, zero_copy);
-
- match min_op {
- MinimalOp::Sync(sync_result) => Op::Sync(match sync_result {
- Ok(r) => {
- record.result = r;
- record.into()
- }
- Err(err) => {
- let error_class = state.get_error_class_name(&err);
- let error_record = ErrorRecord {
- promise_id: record.promise_id,
- arg: -1,
- error_len: error_class.len() as i32,
- error_class: error_class.as_bytes(),
- error_message: err.to_string().as_bytes().to_owned(),
- };
- error_record.into()
- }
- }),
- MinimalOp::Async(min_fut) => {
- let fut = async move {
- match min_fut.await {
- Ok(r) => {
- record.result = r;
- record.into()
- }
- Err(err) => {
- let error_class = state.get_error_class_name(&err);
- let error_record = ErrorRecord {
- promise_id: record.promise_id,
- arg: -1,
- error_len: error_class.len() as i32,
- error_class: error_class.as_bytes(),
- error_message: err.to_string().as_bytes().to_owned(),
- };
- error_record.into()
- }
+ }),
+ MinimalOp::Async(min_fut) => {
+ let fut = async move {
+ match min_fut.await {
+ Ok(r) => {
+ record.result = r;
+ record.into()
}
- };
- Op::Async(fut.boxed_local())
- }
+ Err(err) => {
+ let error_class = (state.borrow().get_error_class_fn)(&err);
+ let error_record = ErrorRecord {
+ promise_id: record.promise_id,
+ arg: -1,
+ error_len: error_class.len() as i32,
+ error_class: error_class.as_bytes(),
+ error_message: err.to_string().as_bytes().to_owned(),
+ };
+ error_record.into()
+ }
+ }
+ };
+ Op::Async(fut.boxed_local())
}
- };
-
- self.register_op(name, base_op_fn)
- }
+ }
+ })
}
diff --git a/cli/ops/errors.rs b/cli/ops/errors.rs
index a4f4665e2..40ec1da30 100644
--- a/cli/ops/errors.rs
+++ b/cli/ops/errors.rs
@@ -3,18 +3,16 @@
use crate::diagnostics::Diagnostic;
use crate::source_maps::get_orig_position;
use crate::source_maps::CachedMaps;
-use crate::state::State;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use serde_derive::Deserialize;
use serde_json::Value;
use std::collections::HashMap;
-use std::rc::Rc;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_apply_source_map", op_apply_source_map);
- s.register_op_json_sync("op_format_diagnostic", op_format_diagnostic);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_apply_source_map", op_apply_source_map);
+ super::reg_json_sync(rt, "op_format_diagnostic", op_format_diagnostic);
}
#[derive(Deserialize)]
@@ -26,7 +24,7 @@ struct ApplySourceMap {
}
fn op_apply_source_map(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -39,7 +37,7 @@ fn op_apply_source_map(
args.line_number.into(),
args.column_number.into(),
&mut mappings_map,
- &state.global_state.ts_compiler,
+ &super::cli_state(state).global_state.ts_compiler,
);
Ok(json!({
@@ -50,7 +48,7 @@ fn op_apply_source_map(
}
fn op_format_diagnostic(
- _state: &State,
+ _state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
diff --git a/cli/ops/fetch.rs b/cli/ops/fetch.rs
index 690cbc592..44031e2ac 100644
--- a/cli/ops/fetch.rs
+++ b/cli/ops/fetch.rs
@@ -2,10 +2,9 @@
use super::io::{StreamResource, StreamResourceHolder};
use crate::http_util::{create_http_client, HttpBody};
-use crate::state::State;
use deno_core::BufVec;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use http::header::HeaderName;
use http::header::HeaderValue;
@@ -13,13 +12,14 @@ use http::Method;
use reqwest::Client;
use serde_derive::Deserialize;
use serde_json::Value;
+use std::cell::RefCell;
use std::convert::From;
use std::path::PathBuf;
use std::rc::Rc;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_async("op_fetch", op_fetch);
- s.register_op_json_sync("op_create_http_client", op_create_http_client);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_async(rt, "op_fetch", op_fetch);
+ super::reg_json_sync(rt, "op_create_http_client", op_create_http_client);
}
#[derive(Deserialize)]
@@ -32,7 +32,7 @@ struct FetchArgs {
}
async fn op_fetch(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
data: BufVec,
) -> Result<Value, ErrBox> {
@@ -40,13 +40,15 @@ async fn op_fetch(
let url = args.url;
let client = if let Some(rid) = args.client_rid {
- let resource_table_ = state.resource_table.borrow();
- let r = resource_table_
+ let state = state.borrow();
+ let r = state
+ .resource_table
.get::<HttpClientResource>(rid)
.ok_or_else(ErrBox::bad_resource_id)?;
r.client.clone()
} else {
- let client_ref = state.http_client.borrow_mut();
+ let cli_state = super::cli_state2(&state);
+ let client_ref = cli_state.http_client.borrow();
client_ref.clone()
};
@@ -66,7 +68,7 @@ async fn op_fetch(
)));
}
- state.check_net_url(&url_)?;
+ super::cli_state2(&state).check_net_url(&url_)?;
let mut request = client.request(method, url_);
@@ -93,7 +95,7 @@ async fn op_fetch(
}
let body = HttpBody::from(res);
- let rid = state.resource_table.borrow_mut().add(
+ let rid = state.borrow_mut().resource_table.add(
"httpBody",
Box::new(StreamResourceHolder::new(StreamResource::HttpBody(
Box::new(body),
@@ -128,21 +130,20 @@ struct CreateHttpClientOptions {
}
fn op_create_http_client(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: CreateHttpClientOptions = serde_json::from_value(args)?;
if let Some(ca_file) = args.ca_file.clone() {
- state.check_read(&PathBuf::from(ca_file))?;
+ super::cli_state(state).check_read(&PathBuf::from(ca_file))?;
}
let client = create_http_client(args.ca_file.as_deref()).unwrap();
let rid = state
.resource_table
- .borrow_mut()
.add("httpClient", Box::new(HttpClientResource::new(client)));
Ok(json!(rid))
}
diff --git a/cli/ops/fs.rs b/cli/ops/fs.rs
index e281f947e..7f9443efb 100644
--- a/cli/ops/fs.rs
+++ b/cli/ops/fs.rs
@@ -2,15 +2,15 @@
// Some deserializer fields are only used on Unix and Windows build fails without it
use super::io::std_file_resource;
use super::io::{FileMetadata, StreamResource, StreamResourceHolder};
-use crate::state::State;
use deno_core::BufVec;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use rand::thread_rng;
use rand::Rng;
use serde_derive::Deserialize;
use serde_json::Value;
+use std::cell::RefCell;
use std::convert::From;
use std::env::{current_dir, set_current_dir, temp_dir};
use std::io;
@@ -20,80 +20,80 @@ use std::rc::Rc;
use std::time::SystemTime;
use std::time::UNIX_EPOCH;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_open_sync", op_open_sync);
- s.register_op_json_async("op_open_async", op_open_async);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_open_sync", op_open_sync);
+ super::reg_json_async(rt, "op_open_async", op_open_async);
- s.register_op_json_sync("op_seek_sync", op_seek_sync);
- s.register_op_json_async("op_seek_async", op_seek_async);
+ super::reg_json_sync(rt, "op_seek_sync", op_seek_sync);
+ super::reg_json_async(rt, "op_seek_async", op_seek_async);
- s.register_op_json_sync("op_fdatasync_sync", op_fdatasync_sync);
- s.register_op_json_async("op_fdatasync_async", op_fdatasync_async);
+ super::reg_json_sync(rt, "op_fdatasync_sync", op_fdatasync_sync);
+ super::reg_json_async(rt, "op_fdatasync_async", op_fdatasync_async);
- s.register_op_json_sync("op_fsync_sync", op_fsync_sync);
- s.register_op_json_async("op_fsync_async", op_fsync_async);
+ super::reg_json_sync(rt, "op_fsync_sync", op_fsync_sync);
+ super::reg_json_async(rt, "op_fsync_async", op_fsync_async);
- s.register_op_json_sync("op_fstat_sync", op_fstat_sync);
- s.register_op_json_async("op_fstat_async", op_fstat_async);
+ super::reg_json_sync(rt, "op_fstat_sync", op_fstat_sync);
+ super::reg_json_async(rt, "op_fstat_async", op_fstat_async);
- s.register_op_json_sync("op_umask", op_umask);
- s.register_op_json_sync("op_chdir", op_chdir);
+ super::reg_json_sync(rt, "op_umask", op_umask);
+ super::reg_json_sync(rt, "op_chdir", op_chdir);
- s.register_op_json_sync("op_mkdir_sync", op_mkdir_sync);
- s.register_op_json_async("op_mkdir_async", op_mkdir_async);
+ super::reg_json_sync(rt, "op_mkdir_sync", op_mkdir_sync);
+ super::reg_json_async(rt, "op_mkdir_async", op_mkdir_async);
- s.register_op_json_sync("op_chmod_sync", op_chmod_sync);
- s.register_op_json_async("op_chmod_async", op_chmod_async);
+ super::reg_json_sync(rt, "op_chmod_sync", op_chmod_sync);
+ super::reg_json_async(rt, "op_chmod_async", op_chmod_async);
- s.register_op_json_sync("op_chown_sync", op_chown_sync);
- s.register_op_json_async("op_chown_async", op_chown_async);
+ super::reg_json_sync(rt, "op_chown_sync", op_chown_sync);
+ super::reg_json_async(rt, "op_chown_async", op_chown_async);
- s.register_op_json_sync("op_remove_sync", op_remove_sync);
- s.register_op_json_async("op_remove_async", op_remove_async);
+ super::reg_json_sync(rt, "op_remove_sync", op_remove_sync);
+ super::reg_json_async(rt, "op_remove_async", op_remove_async);
- s.register_op_json_sync("op_copy_file_sync", op_copy_file_sync);
- s.register_op_json_async("op_copy_file_async", op_copy_file_async);
+ super::reg_json_sync(rt, "op_copy_file_sync", op_copy_file_sync);
+ super::reg_json_async(rt, "op_copy_file_async", op_copy_file_async);
- s.register_op_json_sync("op_stat_sync", op_stat_sync);
- s.register_op_json_async("op_stat_async", op_stat_async);
+ super::reg_json_sync(rt, "op_stat_sync", op_stat_sync);
+ super::reg_json_async(rt, "op_stat_async", op_stat_async);
- s.register_op_json_sync("op_realpath_sync", op_realpath_sync);
- s.register_op_json_async("op_realpath_async", op_realpath_async);
+ super::reg_json_sync(rt, "op_realpath_sync", op_realpath_sync);
+ super::reg_json_async(rt, "op_realpath_async", op_realpath_async);
- s.register_op_json_sync("op_read_dir_sync", op_read_dir_sync);
- s.register_op_json_async("op_read_dir_async", op_read_dir_async);
+ super::reg_json_sync(rt, "op_read_dir_sync", op_read_dir_sync);
+ super::reg_json_async(rt, "op_read_dir_async", op_read_dir_async);
- s.register_op_json_sync("op_rename_sync", op_rename_sync);
- s.register_op_json_async("op_rename_async", op_rename_async);
+ super::reg_json_sync(rt, "op_rename_sync", op_rename_sync);
+ super::reg_json_async(rt, "op_rename_async", op_rename_async);
- s.register_op_json_sync("op_link_sync", op_link_sync);
- s.register_op_json_async("op_link_async", op_link_async);
+ super::reg_json_sync(rt, "op_link_sync", op_link_sync);
+ super::reg_json_async(rt, "op_link_async", op_link_async);
- s.register_op_json_sync("op_symlink_sync", op_symlink_sync);
- s.register_op_json_async("op_symlink_async", op_symlink_async);
+ super::reg_json_sync(rt, "op_symlink_sync", op_symlink_sync);
+ super::reg_json_async(rt, "op_symlink_async", op_symlink_async);
- s.register_op_json_sync("op_read_link_sync", op_read_link_sync);
- s.register_op_json_async("op_read_link_async", op_read_link_async);
+ super::reg_json_sync(rt, "op_read_link_sync", op_read_link_sync);
+ super::reg_json_async(rt, "op_read_link_async", op_read_link_async);
- s.register_op_json_sync("op_ftruncate_sync", op_ftruncate_sync);
- s.register_op_json_async("op_ftruncate_async", op_ftruncate_async);
+ super::reg_json_sync(rt, "op_ftruncate_sync", op_ftruncate_sync);
+ super::reg_json_async(rt, "op_ftruncate_async", op_ftruncate_async);
- s.register_op_json_sync("op_truncate_sync", op_truncate_sync);
- s.register_op_json_async("op_truncate_async", op_truncate_async);
+ super::reg_json_sync(rt, "op_truncate_sync", op_truncate_sync);
+ super::reg_json_async(rt, "op_truncate_async", op_truncate_async);
- s.register_op_json_sync("op_make_temp_dir_sync", op_make_temp_dir_sync);
- s.register_op_json_async("op_make_temp_dir_async", op_make_temp_dir_async);
+ super::reg_json_sync(rt, "op_make_temp_dir_sync", op_make_temp_dir_sync);
+ super::reg_json_async(rt, "op_make_temp_dir_async", op_make_temp_dir_async);
- s.register_op_json_sync("op_make_temp_file_sync", op_make_temp_file_sync);
- s.register_op_json_async("op_make_temp_file_async", op_make_temp_file_async);
+ super::reg_json_sync(rt, "op_make_temp_file_sync", op_make_temp_file_sync);
+ super::reg_json_async(rt, "op_make_temp_file_async", op_make_temp_file_async);
- s.register_op_json_sync("op_cwd", op_cwd);
+ super::reg_json_sync(rt, "op_cwd", op_cwd);
- s.register_op_json_sync("op_futime_sync", op_futime_sync);
- s.register_op_json_async("op_futime_async", op_futime_async);
+ super::reg_json_sync(rt, "op_futime_sync", op_futime_sync);
+ super::reg_json_async(rt, "op_futime_async", op_futime_async);
- s.register_op_json_sync("op_utime_sync", op_utime_sync);
- s.register_op_json_async("op_utime_async", op_utime_async);
+ super::reg_json_sync(rt, "op_utime_sync", op_utime_sync);
+ super::reg_json_async(rt, "op_utime_async", op_utime_async);
}
fn into_string(s: std::ffi::OsString) -> Result<String, ErrBox> {
@@ -124,7 +124,7 @@ struct OpenOptions {
}
fn open_helper(
- state: &State,
+ state: &mut OpState,
args: Value,
) -> Result<(PathBuf, std::fs::OpenOptions), ErrBox> {
let args: OpenArgs = serde_json::from_value(args)?;
@@ -146,11 +146,13 @@ fn open_helper(
let options = args.options;
if options.read {
- state.check_read(&path)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_read(&path)?;
}
if options.write || options.append {
- state.check_write(&path)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_write(&path)?;
}
open_options
@@ -165,14 +167,14 @@ fn open_helper(
}
fn op_open_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let (path, open_options) = open_helper(state, args)?;
let std_file = open_options.open(path)?;
let tokio_file = tokio::fs::File::from_std(std_file);
- let rid = state.resource_table.borrow_mut().add(
+ let rid = state.resource_table.add(
"fsFile",
Box::new(StreamResourceHolder::new(StreamResource::FsFile(Some((
tokio_file,
@@ -183,15 +185,15 @@ fn op_open_sync(
}
async fn op_open_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
- let (path, open_options) = open_helper(&state, args)?;
+ let (path, open_options) = open_helper(&mut state.borrow_mut(), args)?;
let tokio_file = tokio::fs::OpenOptions::from(open_options)
.open(path)
.await?;
- let rid = state.resource_table.borrow_mut().add(
+ let rid = state.borrow_mut().resource_table.add(
"fsFile",
Box::new(StreamResourceHolder::new(StreamResource::FsFile(Some((
tokio_file,
@@ -228,7 +230,7 @@ fn seek_helper(args: Value) -> Result<(u32, SeekFrom), ErrBox> {
}
fn op_seek_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -243,14 +245,14 @@ fn op_seek_sync(
}
async fn op_seek_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
let (rid, seek_from) = seek_helper(args)?;
// TODO(ry) This is a fake async op. We need to use poll_fn,
// tokio::fs::File::start_seek and tokio::fs::File::poll_complete
- let pos = std_file_resource(&state, rid, |r| match r {
+ let pos = std_file_resource(&mut state.borrow_mut(), rid, |r| match r {
Ok(std_file) => std_file.seek(seek_from).map_err(ErrBox::from),
Err(_) => Err(ErrBox::type_error(
"cannot seek on this type of resource".to_string(),
@@ -266,11 +268,14 @@ struct FdatasyncArgs {
}
fn op_fdatasync_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.fdatasync");
+ {
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.fdatasync");
+ }
let args: FdatasyncArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
std_file_resource(state, rid, |r| match r {
@@ -283,14 +288,15 @@ fn op_fdatasync_sync(
}
async fn op_fdatasync_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.fdatasync");
+ super::cli_state2(&state).check_unstable("Deno.fdatasync");
+
let args: FdatasyncArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
- std_file_resource(&state, rid, |r| match r {
+ std_file_resource(&mut state.borrow_mut(), rid, |r| match r {
Ok(std_file) => std_file.sync_data().map_err(ErrBox::from),
Err(_) => Err(ErrBox::type_error(
"cannot sync this type of resource".to_string(),
@@ -306,11 +312,14 @@ struct FsyncArgs {
}
fn op_fsync_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.fsync");
+ {
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.fsync");
+ }
let args: FsyncArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
std_file_resource(state, rid, |r| match r {
@@ -323,14 +332,15 @@ fn op_fsync_sync(
}
async fn op_fsync_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.fsync");
+ super::cli_state2(&state).check_unstable("Deno.fsync");
+
let args: FsyncArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
- std_file_resource(&state, rid, |r| match r {
+ std_file_resource(&mut state.borrow_mut(), rid, |r| match r {
Ok(std_file) => std_file.sync_all().map_err(ErrBox::from),
Err(_) => Err(ErrBox::type_error(
"cannot sync this type of resource".to_string(),
@@ -346,11 +356,14 @@ struct FstatArgs {
}
fn op_fstat_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.fstat");
+ {
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.fstat");
+ }
let args: FstatArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let metadata = std_file_resource(state, rid, |r| match r {
@@ -363,19 +376,21 @@ fn op_fstat_sync(
}
async fn op_fstat_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.fstat");
+ super::cli_state2(&state).check_unstable("Deno.fstat");
+
let args: FstatArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
- let metadata = std_file_resource(&state, rid, |r| match r {
- Ok(std_file) => std_file.metadata().map_err(ErrBox::from),
- Err(_) => Err(ErrBox::type_error(
- "cannot stat this type of resource".to_string(),
- )),
- })?;
+ let metadata =
+ std_file_resource(&mut state.borrow_mut(), rid, |r| match r {
+ Ok(std_file) => std_file.metadata().map_err(ErrBox::from),
+ Err(_) => Err(ErrBox::type_error(
+ "cannot stat this type of resource".to_string(),
+ )),
+ })?;
Ok(get_stat_json(metadata).unwrap())
}
@@ -385,11 +400,14 @@ struct UmaskArgs {
}
fn op_umask(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.umask");
+ {
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.umask");
+ }
let args: UmaskArgs = serde_json::from_value(args)?;
// TODO implement umask for Windows
// see https://github.com/nodejs/node/blob/master/src/node_process_methods.cc
@@ -423,13 +441,14 @@ struct ChdirArgs {
}
fn op_chdir(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: ChdirArgs = serde_json::from_value(args)?;
let d = PathBuf::from(&args.directory);
- state.check_read(&d)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_read(&d)?;
set_current_dir(&d)?;
Ok(json!({}))
}
@@ -443,14 +462,15 @@ struct MkdirArgs {
}
fn op_mkdir_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: MkdirArgs = serde_json::from_value(args)?;
let path = Path::new(&args.path).to_path_buf();
let mode = args.mode.unwrap_or(0o777) & 0o777;
- state.check_write(&path)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_write(&path)?;
debug!("op_mkdir {} {:o} {}", path.display(), mode, args.recursive);
let mut builder = std::fs::DirBuilder::new();
builder.recursive(args.recursive);
@@ -464,14 +484,16 @@ fn op_mkdir_sync(
}
async fn op_mkdir_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
let args: MkdirArgs = serde_json::from_value(args)?;
let path = Path::new(&args.path).to_path_buf();
let mode = args.mode.unwrap_or(0o777) & 0o777;
- state.check_write(&path)?;
+
+ super::cli_state2(&state).check_write(&path)?;
+
tokio::task::spawn_blocking(move || {
debug!("op_mkdir {} {:o} {}", path.display(), mode, args.recursive);
let mut builder = std::fs::DirBuilder::new();
@@ -496,7 +518,7 @@ struct ChmodArgs {
}
fn op_chmod_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -504,7 +526,8 @@ fn op_chmod_sync(
let path = Path::new(&args.path).to_path_buf();
let mode = args.mode & 0o777;
- state.check_write(&path)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_write(&path)?;
debug!("op_chmod_sync {} {:o}", path.display(), mode);
#[cfg(unix)]
{
@@ -523,14 +546,16 @@ fn op_chmod_sync(
}
async fn op_chmod_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
let args: ChmodArgs = serde_json::from_value(args)?;
let path = Path::new(&args.path).to_path_buf();
let mode = args.mode & 0o777;
- state.check_write(&path)?;
+
+ super::cli_state2(&state).check_write(&path)?;
+
tokio::task::spawn_blocking(move || {
debug!("op_chmod_async {} {:o}", path.display(), mode);
#[cfg(unix)]
@@ -561,13 +586,14 @@ struct ChownArgs {
}
fn op_chown_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: ChownArgs = serde_json::from_value(args)?;
let path = Path::new(&args.path).to_path_buf();
- state.check_write(&path)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_write(&path)?;
debug!(
"op_chown_sync {} {:?} {:?}",
path.display(),
@@ -590,13 +616,15 @@ fn op_chown_sync(
}
async fn op_chown_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
let args: ChownArgs = serde_json::from_value(args)?;
let path = Path::new(&args.path).to_path_buf();
- state.check_write(&path)?;
+
+ super::cli_state2(&state).check_write(&path)?;
+
tokio::task::spawn_blocking(move || {
debug!(
"op_chown_async {} {:?} {:?}",
@@ -628,7 +656,7 @@ struct RemoveArgs {
}
fn op_remove_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -636,7 +664,8 @@ fn op_remove_sync(
let path = PathBuf::from(&args.path);
let recursive = args.recursive;
- state.check_write(&path)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_write(&path)?;
#[cfg(not(unix))]
use std::os::windows::prelude::MetadataExt;
@@ -671,7 +700,7 @@ fn op_remove_sync(
}
async fn op_remove_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
@@ -679,7 +708,7 @@ async fn op_remove_async(
let path = PathBuf::from(&args.path);
let recursive = args.recursive;
- state.check_write(&path)?;
+ super::cli_state2(&state).check_write(&path)?;
tokio::task::spawn_blocking(move || {
#[cfg(not(unix))]
@@ -725,7 +754,7 @@ struct CopyFileArgs {
}
fn op_copy_file_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -733,8 +762,9 @@ fn op_copy_file_sync(
let from = PathBuf::from(&args.from);
let to = PathBuf::from(&args.to);
- state.check_read(&from)?;
- state.check_write(&to)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_read(&from)?;
+ cli_state.check_write(&to)?;
debug!("op_copy_file_sync {} {}", from.display(), to.display());
// On *nix, Rust reports non-existent `from` as ErrorKind::InvalidInput
@@ -750,7 +780,7 @@ fn op_copy_file_sync(
}
async fn op_copy_file_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
@@ -758,8 +788,9 @@ async fn op_copy_file_async(
let from = PathBuf::from(&args.from);
let to = PathBuf::from(&args.to);
- state.check_read(&from)?;
- state.check_write(&to)?;
+ let cli_state = super::cli_state2(&state);
+ cli_state.check_read(&from)?;
+ cli_state.check_write(&to)?;
debug!("op_copy_file_async {} {}", from.display(), to.display());
tokio::task::spawn_blocking(move || {
@@ -844,14 +875,15 @@ struct StatArgs {
}
fn op_stat_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: StatArgs = serde_json::from_value(args)?;
let path = PathBuf::from(&args.path);
let lstat = args.lstat;
- state.check_read(&path)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_read(&path)?;
debug!("op_stat_sync {} {}", path.display(), lstat);
let metadata = if lstat {
std::fs::symlink_metadata(&path)?
@@ -862,7 +894,7 @@ fn op_stat_sync(
}
async fn op_stat_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
@@ -870,7 +902,7 @@ async fn op_stat_async(
let path = PathBuf::from(&args.path);
let lstat = args.lstat;
- state.check_read(&path)?;
+ super::cli_state2(&state).check_read(&path)?;
tokio::task::spawn_blocking(move || {
debug!("op_stat_async {} {}", path.display(), lstat);
@@ -892,16 +924,17 @@ struct RealpathArgs {
}
fn op_realpath_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: RealpathArgs = serde_json::from_value(args)?;
let path = PathBuf::from(&args.path);
- state.check_read(&path)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_read(&path)?;
if path.is_relative() {
- state.check_read_blind(&current_dir()?, "CWD")?;
+ cli_state.check_read_blind(&current_dir()?, "CWD")?;
}
debug!("op_realpath_sync {}", path.display());
@@ -917,16 +950,17 @@ fn op_realpath_sync(
}
async fn op_realpath_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
let args: RealpathArgs = serde_json::from_value(args)?;
let path = PathBuf::from(&args.path);
- state.check_read(&path)?;
+ let cli_state = super::cli_state2(&state);
+ cli_state.check_read(&path)?;
if path.is_relative() {
- state.check_read_blind(&current_dir()?, "CWD")?;
+ cli_state.check_read_blind(&current_dir()?, "CWD")?;
}
tokio::task::spawn_blocking(move || {
@@ -952,14 +986,15 @@ struct ReadDirArgs {
}
fn op_read_dir_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: ReadDirArgs = serde_json::from_value(args)?;
let path = PathBuf::from(&args.path);
- state.check_read(&path)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_read(&path)?;
debug!("op_read_dir_sync {}", path.display());
let entries: Vec<_> = std::fs::read_dir(path)?
@@ -984,15 +1019,13 @@ fn op_read_dir_sync(
}
async fn op_read_dir_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
let args: ReadDirArgs = serde_json::from_value(args)?;
let path = PathBuf::from(&args.path);
-
- state.check_read(&path)?;
-
+ super::cli_state2(&state).check_read(&path)?;
tokio::task::spawn_blocking(move || {
debug!("op_read_dir_async {}", path.display());
let entries: Vec<_> = std::fs::read_dir(path)?
@@ -1027,7 +1060,7 @@ struct RenameArgs {
}
fn op_rename_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -1035,27 +1068,29 @@ fn op_rename_sync(
let oldpath = PathBuf::from(&args.oldpath);
let newpath = PathBuf::from(&args.newpath);
- state.check_read(&oldpath)?;
- state.check_write(&oldpath)?;
- state.check_write(&newpath)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_read(&oldpath)?;
+ cli_state.check_write(&oldpath)?;
+ cli_state.check_write(&newpath)?;
debug!("op_rename_sync {} {}", oldpath.display(), newpath.display());
std::fs::rename(&oldpath, &newpath)?;
Ok(json!({}))
}
async fn op_rename_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
let args: RenameArgs = serde_json::from_value(args)?;
let oldpath = PathBuf::from(&args.oldpath);
let newpath = PathBuf::from(&args.newpath);
-
- state.check_read(&oldpath)?;
- state.check_write(&oldpath)?;
- state.check_write(&newpath)?;
-
+ {
+ let cli_state = super::cli_state2(&state);
+ cli_state.check_read(&oldpath)?;
+ cli_state.check_write(&oldpath)?;
+ cli_state.check_write(&newpath)?;
+ }
tokio::task::spawn_blocking(move || {
debug!(
"op_rename_async {} {}",
@@ -1077,17 +1112,18 @@ struct LinkArgs {
}
fn op_link_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.link");
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.link");
let args: LinkArgs = serde_json::from_value(args)?;
let oldpath = PathBuf::from(&args.oldpath);
let newpath = PathBuf::from(&args.newpath);
- state.check_read(&oldpath)?;
- state.check_write(&newpath)?;
+ cli_state.check_read(&oldpath)?;
+ cli_state.check_write(&newpath)?;
debug!("op_link_sync {} {}", oldpath.display(), newpath.display());
std::fs::hard_link(&oldpath, &newpath)?;
@@ -1095,17 +1131,19 @@ fn op_link_sync(
}
async fn op_link_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.link");
+ let cli_state = super::cli_state2(&state);
+ cli_state.check_unstable("Deno.link");
+
let args: LinkArgs = serde_json::from_value(args)?;
let oldpath = PathBuf::from(&args.oldpath);
let newpath = PathBuf::from(&args.newpath);
- state.check_read(&oldpath)?;
- state.check_write(&newpath)?;
+ cli_state.check_read(&oldpath)?;
+ cli_state.check_write(&newpath)?;
tokio::task::spawn_blocking(move || {
debug!("op_link_async {} {}", oldpath.display(), newpath.display());
@@ -1133,16 +1171,17 @@ struct SymlinkOptions {
}
fn op_symlink_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.symlink");
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.symlink");
let args: SymlinkArgs = serde_json::from_value(args)?;
let oldpath = PathBuf::from(&args.oldpath);
let newpath = PathBuf::from(&args.newpath);
- state.check_write(&newpath)?;
+ cli_state.check_write(&newpath)?;
debug!(
"op_symlink_sync {} {}",
@@ -1184,16 +1223,18 @@ fn op_symlink_sync(
}
async fn op_symlink_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.symlink");
+ let cli_state = super::cli_state2(&state);
+ cli_state.check_unstable("Deno.symlink");
+
let args: SymlinkArgs = serde_json::from_value(args)?;
let oldpath = PathBuf::from(&args.oldpath);
let newpath = PathBuf::from(&args.newpath);
- state.check_write(&newpath)?;
+ cli_state.check_write(&newpath)?;
tokio::task::spawn_blocking(move || {
debug!("op_symlink_async {} {}", oldpath.display(), newpath.display());
@@ -1241,14 +1282,15 @@ struct ReadLinkArgs {
}
fn op_read_link_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: ReadLinkArgs = serde_json::from_value(args)?;
let path = PathBuf::from(&args.path);
- state.check_read(&path)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_read(&path)?;
debug!("op_read_link_value {}", path.display());
let target = std::fs::read_link(&path)?.into_os_string();
@@ -1257,15 +1299,13 @@ fn op_read_link_sync(
}
async fn op_read_link_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
let args: ReadLinkArgs = serde_json::from_value(args)?;
let path = PathBuf::from(&args.path);
-
- state.check_read(&path)?;
-
+ super::cli_state2(&state).check_read(&path)?;
tokio::task::spawn_blocking(move || {
debug!("op_read_link_async {}", path.display());
let target = std::fs::read_link(&path)?.into_os_string();
@@ -1284,11 +1324,14 @@ struct FtruncateArgs {
}
fn op_ftruncate_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.ftruncate");
+ {
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.ftruncate");
+ }
let args: FtruncateArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let len = args.len as u64;
@@ -1300,15 +1343,15 @@ fn op_ftruncate_sync(
}
async fn op_ftruncate_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.ftruncate");
+ super::cli_state2(&state).check_unstable("Deno.ftruncate");
let args: FtruncateArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let len = args.len as u64;
- std_file_resource(&state, rid, |r| match r {
+ std_file_resource(&mut state.borrow_mut(), rid, |r| match r {
Ok(std_file) => std_file.set_len(len).map_err(ErrBox::from),
Err(_) => Err(ErrBox::type_error("cannot truncate this type of resource")),
})?;
@@ -1323,7 +1366,7 @@ struct TruncateArgs {
}
fn op_truncate_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -1331,7 +1374,8 @@ fn op_truncate_sync(
let path = PathBuf::from(&args.path);
let len = args.len;
- state.check_write(&path)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_write(&path)?;
debug!("op_truncate_sync {} {}", path.display(), len);
let f = std::fs::OpenOptions::new().write(true).open(&path)?;
@@ -1340,16 +1384,14 @@ fn op_truncate_sync(
}
async fn op_truncate_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
let args: TruncateArgs = serde_json::from_value(args)?;
let path = PathBuf::from(&args.path);
let len = args.len;
-
- state.check_write(&path)?;
-
+ super::cli_state2(&state).check_write(&path)?;
tokio::task::spawn_blocking(move || {
debug!("op_truncate_async {} {}", path.display(), len);
let f = std::fs::OpenOptions::new().write(true).open(&path)?;
@@ -1414,7 +1456,7 @@ struct MakeTempArgs {
}
fn op_make_temp_dir_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -1424,7 +1466,8 @@ fn op_make_temp_dir_sync(
let prefix = args.prefix.map(String::from);
let suffix = args.suffix.map(String::from);
- state.check_write(dir.clone().unwrap_or_else(temp_dir).as_path())?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_write(dir.clone().unwrap_or_else(temp_dir).as_path())?;
// TODO(piscisaureus): use byte vector for paths, not a string.
// See https://github.com/denoland/deno/issues/627.
@@ -1442,7 +1485,7 @@ fn op_make_temp_dir_sync(
}
async fn op_make_temp_dir_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
@@ -1451,9 +1494,10 @@ async fn op_make_temp_dir_async(
let dir = args.dir.map(|s| PathBuf::from(&s));
let prefix = args.prefix.map(String::from);
let suffix = args.suffix.map(String::from);
-
- state.check_write(dir.clone().unwrap_or_else(temp_dir).as_path())?;
-
+ {
+ let cli_state = super::cli_state2(&state);
+ cli_state.check_write(dir.clone().unwrap_or_else(temp_dir).as_path())?;
+ }
tokio::task::spawn_blocking(move || {
// TODO(piscisaureus): use byte vector for paths, not a string.
// See https://github.com/denoland/deno/issues/627.
@@ -1474,7 +1518,7 @@ async fn op_make_temp_dir_async(
}
fn op_make_temp_file_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -1484,7 +1528,8 @@ fn op_make_temp_file_sync(
let prefix = args.prefix.map(String::from);
let suffix = args.suffix.map(String::from);
- state.check_write(dir.clone().unwrap_or_else(temp_dir).as_path())?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_write(dir.clone().unwrap_or_else(temp_dir).as_path())?;
// TODO(piscisaureus): use byte vector for paths, not a string.
// See https://github.com/denoland/deno/issues/627.
@@ -1502,7 +1547,7 @@ fn op_make_temp_file_sync(
}
async fn op_make_temp_file_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
@@ -1511,9 +1556,11 @@ async fn op_make_temp_file_async(
let dir = args.dir.map(|s| PathBuf::from(&s));
let prefix = args.prefix.map(String::from);
let suffix = args.suffix.map(String::from);
-
- state.check_write(dir.clone().unwrap_or_else(temp_dir).as_path())?;
-
+ {
+ let state = state.borrow();
+ let cli_state = super::cli_state(&state);
+ cli_state.check_write(dir.clone().unwrap_or_else(temp_dir).as_path())?;
+ }
tokio::task::spawn_blocking(move || {
// TODO(piscisaureus): use byte vector for paths, not a string.
// See https://github.com/denoland/deno/issues/627.
@@ -1542,11 +1589,14 @@ struct FutimeArgs {
}
fn op_futime_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.futimeSync");
+ {
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.futimeSync");
+ }
let args: FutimeArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let atime = filetime::FileTime::from_unix_time(args.atime.0, args.atime.1);
@@ -1566,17 +1616,19 @@ fn op_futime_sync(
}
async fn op_futime_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.futime");
+ let mut state = state.borrow_mut();
+ let cli_state = super::cli_state(&state);
+ cli_state.check_unstable("Deno.futime");
let args: FutimeArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let atime = filetime::FileTime::from_unix_time(args.atime.0, args.atime.1);
let mtime = filetime::FileTime::from_unix_time(args.mtime.0, args.mtime.1);
-
- std_file_resource(&state, rid, |r| match r {
+ // TODO Not actually async! https://github.com/denoland/deno/issues/7400
+ std_file_resource(&mut state, rid, |r| match r {
Ok(std_file) => {
filetime::set_file_handle_times(std_file, Some(atime), Some(mtime))
.map_err(ErrBox::from)
@@ -1598,35 +1650,38 @@ struct UtimeArgs {
}
fn op_utime_sync(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.utime");
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.utime");
let args: UtimeArgs = serde_json::from_value(args)?;
let path = PathBuf::from(&args.path);
let atime = filetime::FileTime::from_unix_time(args.atime.0, args.atime.1);
let mtime = filetime::FileTime::from_unix_time(args.mtime.0, args.mtime.1);
- state.check_write(&path)?;
+ cli_state.check_write(&path)?;
filetime::set_file_times(path, atime, mtime)?;
Ok(json!({}))
}
async fn op_utime_async(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.utime");
+ let state = state.borrow();
+ let cli_state = super::cli_state(&state);
+ cli_state.check_unstable("Deno.utime");
let args: UtimeArgs = serde_json::from_value(args)?;
let path = PathBuf::from(&args.path);
let atime = filetime::FileTime::from_unix_time(args.atime.0, args.atime.1);
let mtime = filetime::FileTime::from_unix_time(args.mtime.0, args.mtime.1);
- state.check_write(&path)?;
+ cli_state.check_write(&path)?;
tokio::task::spawn_blocking(move || {
filetime::set_file_times(path, atime, mtime)?;
@@ -1637,12 +1692,13 @@ async fn op_utime_async(
}
fn op_cwd(
- state: &State,
+ state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let path = current_dir()?;
- state.check_read_blind(&path, "CWD")?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_read_blind(&path, "CWD")?;
let path_str = into_string(path.into_os_string())?;
Ok(json!(path_str))
}
diff --git a/cli/ops/fs_events.rs b/cli/ops/fs_events.rs
index 142aa3ccf..3468169b0 100644
--- a/cli/ops/fs_events.rs
+++ b/cli/ops/fs_events.rs
@@ -1,9 +1,8 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::state::State;
use deno_core::BufVec;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use futures::future::poll_fn;
use notify::event::Event as NotifyEvent;
@@ -15,14 +14,15 @@ use notify::Watcher;
use serde::Serialize;
use serde_derive::Deserialize;
use serde_json::Value;
+use std::cell::RefCell;
use std::convert::From;
use std::path::PathBuf;
use std::rc::Rc;
use tokio::sync::mpsc;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_fs_events_open", op_fs_events_open);
- s.register_op_json_async("op_fs_events_poll", op_fs_events_poll);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_fs_events_open", op_fs_events_open);
+ super::reg_json_async(rt, "op_fs_events_poll", op_fs_events_poll);
}
struct FsEventsResource {
@@ -64,7 +64,7 @@ impl From<NotifyEvent> for FsEvent {
}
fn op_fs_events_open(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -90,19 +90,16 @@ fn op_fs_events_open(
RecursiveMode::NonRecursive
};
for path in &args.paths {
- state.check_read(&PathBuf::from(path))?;
+ super::cli_state(state).check_read(&PathBuf::from(path))?;
watcher.watch(path, recursive_mode)?;
}
let resource = FsEventsResource { watcher, receiver };
- let rid = state
- .resource_table
- .borrow_mut()
- .add("fsEvents", Box::new(resource));
+ let rid = state.resource_table.add("fsEvents", Box::new(resource));
Ok(json!(rid))
}
async fn op_fs_events_poll(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
@@ -112,8 +109,9 @@ async fn op_fs_events_poll(
}
let PollArgs { rid } = serde_json::from_value(args)?;
poll_fn(move |cx| {
- let mut resource_table = state.resource_table.borrow_mut();
- let watcher = resource_table
+ let mut state = state.borrow_mut();
+ let watcher = state
+ .resource_table
.get_mut::<FsEventsResource>(rid)
.ok_or_else(ErrBox::bad_resource_id)?;
watcher
diff --git a/cli/ops/idna.rs b/cli/ops/idna.rs
index 8e83a03ba..7a83f169d 100644
--- a/cli/ops/idna.rs
+++ b/cli/ops/idna.rs
@@ -2,18 +2,15 @@
//! https://url.spec.whatwg.org/#idna
-use crate::state::State;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
use deno_core::ZeroCopyBuf;
use idna::domain_to_ascii;
use idna::domain_to_ascii_strict;
use serde_derive::Deserialize;
use serde_json::Value;
-use std::rc::Rc;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_domain_to_ascii", op_domain_to_ascii);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_domain_to_ascii", op_domain_to_ascii);
}
#[derive(Deserialize)]
@@ -24,7 +21,7 @@ struct DomainToAscii {
}
fn op_domain_to_ascii(
- _state: &State,
+ _state: &mut deno_core::OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
diff --git a/cli/ops/io.rs b/cli/ops/io.rs
index 4a8f6d96d..be59ac863 100644
--- a/cli/ops/io.rs
+++ b/cli/ops/io.rs
@@ -1,11 +1,15 @@
+use super::dispatch_minimal::minimal_op;
use super::dispatch_minimal::MinimalOp;
use crate::http_util::HttpBody;
-use crate::state::State;
+use crate::metrics::metrics_op;
use deno_core::BufVec;
use deno_core::ErrBox;
+use deno_core::JsRuntime;
+use deno_core::OpState;
use futures::future::poll_fn;
use futures::future::FutureExt;
use futures::ready;
+use std::cell::RefCell;
use std::collections::HashMap;
use std::pin::Pin;
use std::rc::Rc;
@@ -82,9 +86,9 @@ lazy_static! {
};
}
-pub fn init(s: &Rc<State>) {
- s.register_op_minimal("op_read", op_read);
- s.register_op_minimal("op_write", op_write);
+pub fn init(rt: &mut JsRuntime) {
+ rt.register_op("op_read", metrics_op(minimal_op(op_read)));
+ rt.register_op("op_write", metrics_op(minimal_op(op_write)));
}
pub fn get_stdio() -> (
@@ -233,7 +237,7 @@ impl DenoAsyncRead for StreamResource {
}
pub fn op_read(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
is_sync: bool,
rid: i32,
mut zero_copy: BufVec,
@@ -248,7 +252,7 @@ pub fn op_read(
if is_sync {
MinimalOp::Sync({
// First we look up the rid in the resource table.
- std_file_resource(&state, rid as u32, move |r| match r {
+ std_file_resource(&mut state.borrow_mut(), rid as u32, move |r| match r {
Ok(std_file) => {
use std::io::Read;
std_file
@@ -265,8 +269,9 @@ pub fn op_read(
let mut zero_copy = zero_copy[0].clone();
MinimalOp::Async(
poll_fn(move |cx| {
- let mut resource_table = state.resource_table.borrow_mut();
- let resource_holder = resource_table
+ let mut state = state.borrow_mut();
+ let resource_holder = state
+ .resource_table
.get_mut::<StreamResourceHolder>(rid as u32)
.ok_or_else(ErrBox::bad_resource_id)?;
@@ -352,7 +357,7 @@ impl DenoAsyncWrite for StreamResource {
}
pub fn op_write(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
is_sync: bool,
rid: i32,
zero_copy: BufVec,
@@ -367,7 +372,7 @@ pub fn op_write(
if is_sync {
MinimalOp::Sync({
// First we look up the rid in the resource table.
- std_file_resource(&state, rid as u32, move |r| match r {
+ std_file_resource(&mut state.borrow_mut(), rid as u32, move |r| match r {
Ok(std_file) => {
use std::io::Write;
std_file
@@ -385,8 +390,9 @@ pub fn op_write(
MinimalOp::Async(
async move {
let nwritten = poll_fn(|cx| {
- let mut resource_table = state.resource_table.borrow_mut();
- let resource_holder = resource_table
+ let mut state = state.borrow_mut();
+ let resource_holder = state
+ .resource_table
.get_mut::<StreamResourceHolder>(rid as u32)
.ok_or_else(ErrBox::bad_resource_id)?;
resource_holder.resource.poll_write(cx, &zero_copy)
@@ -398,8 +404,9 @@ pub fn op_write(
// Figure out why it's needed and preferably remove it.
// https://github.com/denoland/deno/issues/3565
poll_fn(|cx| {
- let mut resource_table = state.resource_table.borrow_mut();
- let resource_holder = resource_table
+ let mut state = state.borrow_mut();
+ let resource_holder = state
+ .resource_table
.get_mut::<StreamResourceHolder>(rid as u32)
.ok_or_else(ErrBox::bad_resource_id)?;
resource_holder.resource.poll_flush(cx)
@@ -421,7 +428,7 @@ pub fn op_write(
///
/// Returns ErrorKind::Busy if the resource is being used by another op.
pub fn std_file_resource<F, T>(
- state: &State,
+ state: &mut OpState,
rid: u32,
mut f: F,
) -> Result<T, ErrBox>
@@ -430,8 +437,7 @@ where
FnMut(Result<&mut std::fs::File, &mut StreamResource>) -> Result<T, ErrBox>,
{
// First we look up the rid in the resource table.
- let mut resource_table = state.resource_table.borrow_mut();
- let mut r = resource_table.get_mut::<StreamResourceHolder>(rid);
+ let mut r = state.resource_table.get_mut::<StreamResourceHolder>(rid);
if let Some(ref mut resource_holder) = r {
// Sync write only works for FsFile. It doesn't make sense to do this
// for non-blocking sockets. So we error out if not FsFile.
diff --git a/cli/ops/mod.rs b/cli/ops/mod.rs
index 06a55bade..3858400a3 100644
--- a/cli/ops/mod.rs
+++ b/cli/ops/mod.rs
@@ -29,3 +29,43 @@ pub mod tty;
pub mod web_worker;
pub mod websocket;
pub mod worker_host;
+
+use crate::metrics::metrics_op;
+use deno_core::json_op_async;
+use deno_core::json_op_sync;
+use deno_core::BufVec;
+use deno_core::ErrBox;
+use deno_core::JsRuntime;
+use deno_core::OpState;
+use deno_core::ZeroCopyBuf;
+use serde_json::Value;
+use std::cell::RefCell;
+use std::future::Future;
+use std::rc::Rc;
+
+pub fn reg_json_async<F, R>(rt: &mut JsRuntime, name: &'static str, op_fn: F)
+where
+ F: Fn(Rc<RefCell<OpState>>, Value, BufVec) -> R + 'static,
+ R: Future<Output = Result<Value, ErrBox>> + 'static,
+{
+ rt.register_op(name, metrics_op(json_op_async(op_fn)));
+}
+
+pub fn reg_json_sync<F>(rt: &mut JsRuntime, name: &'static str, op_fn: F)
+where
+ F: Fn(&mut OpState, Value, &mut [ZeroCopyBuf]) -> Result<Value, ErrBox>
+ + 'static,
+{
+ rt.register_op(name, metrics_op(json_op_sync(op_fn)));
+}
+
+/// Helper for extracting the commonly used state. Used for sync ops.
+pub fn cli_state(state: &OpState) -> Rc<crate::state::State> {
+ state.borrow::<Rc<crate::state::State>>().clone()
+}
+
+/// Helper for extracting the commonly used state. Used for async ops.
+pub fn cli_state2(state: &Rc<RefCell<OpState>>) -> Rc<crate::state::State> {
+ let state = state.borrow();
+ state.borrow::<Rc<crate::state::State>>().clone()
+}
diff --git a/cli/ops/net.rs b/cli/ops/net.rs
index 91a9079d4..67a201460 100644
--- a/cli/ops/net.rs
+++ b/cli/ops/net.rs
@@ -2,14 +2,14 @@
use crate::ops::io::{StreamResource, StreamResourceHolder};
use crate::resolve_addr::resolve_addr;
-use crate::state::State;
use deno_core::BufVec;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use futures::future::poll_fn;
use serde_derive::Deserialize;
use serde_json::Value;
+use std::cell::RefCell;
use std::net::Shutdown;
use std::net::SocketAddr;
use std::rc::Rc;
@@ -22,13 +22,13 @@ use tokio::net::UdpSocket;
#[cfg(unix)]
use super::net_unix;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_async("op_accept", op_accept);
- s.register_op_json_async("op_connect", op_connect);
- s.register_op_json_sync("op_shutdown", op_shutdown);
- s.register_op_json_sync("op_listen", op_listen);
- s.register_op_json_async("op_datagram_receive", op_datagram_receive);
- s.register_op_json_async("op_datagram_send", op_datagram_send);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_async(rt, "op_accept", op_accept);
+ super::reg_json_async(rt, "op_connect", op_connect);
+ super::reg_json_sync(rt, "op_shutdown", op_shutdown);
+ super::reg_json_sync(rt, "op_listen", op_listen);
+ super::reg_json_async(rt, "op_datagram_receive", op_datagram_receive);
+ super::reg_json_async(rt, "op_datagram_send", op_datagram_send);
}
#[derive(Deserialize)]
@@ -38,15 +38,16 @@ pub(crate) struct AcceptArgs {
}
async fn accept_tcp(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: AcceptArgs,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
let rid = args.rid as u32;
let accept_fut = poll_fn(|cx| {
- let mut resource_table = state.resource_table.borrow_mut();
- let listener_resource = resource_table
+ let mut state = state.borrow_mut();
+ let listener_resource = state
+ .resource_table
.get_mut::<TcpListenerResource>(rid)
.ok_or_else(|| ErrBox::bad_resource("Listener has been closed"))?;
let listener = &mut listener_resource.listener;
@@ -68,7 +69,9 @@ async fn accept_tcp(
let (tcp_stream, _socket_addr) = accept_fut.await?;
let local_addr = tcp_stream.local_addr()?;
let remote_addr = tcp_stream.peer_addr()?;
- let rid = state.resource_table.borrow_mut().add(
+
+ let mut state = state.borrow_mut();
+ let rid = state.resource_table.add(
"tcpStream",
Box::new(StreamResourceHolder::new(StreamResource::TcpStream(Some(
tcp_stream,
@@ -90,7 +93,7 @@ async fn accept_tcp(
}
async fn op_accept(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
bufs: BufVec,
) -> Result<Value, ErrBox> {
@@ -113,7 +116,7 @@ pub(crate) struct ReceiveArgs {
}
async fn receive_udp(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: ReceiveArgs,
zero_copy: BufVec,
) -> Result<Value, ErrBox> {
@@ -123,8 +126,9 @@ async fn receive_udp(
let rid = args.rid as u32;
let receive_fut = poll_fn(|cx| {
- let mut resource_table = state.resource_table.borrow_mut();
- let resource = resource_table
+ let mut state = state.borrow_mut();
+ let resource = state
+ .resource_table
.get_mut::<UdpSocketResource>(rid)
.ok_or_else(|| ErrBox::bad_resource("Socket has been closed"))?;
let socket = &mut resource.socket;
@@ -144,7 +148,7 @@ async fn receive_udp(
}
async fn op_datagram_receive(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
zero_copy: BufVec,
) -> Result<Value, ErrBox> {
@@ -171,12 +175,13 @@ struct SendArgs {
}
async fn op_datagram_send(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
zero_copy: BufVec,
) -> Result<Value, ErrBox> {
assert_eq!(zero_copy.len(), 1, "Invalid number of arguments");
let zero_copy = zero_copy[0].clone();
+ let cli_state = super::cli_state2(&state);
match serde_json::from_value(args)? {
SendArgs {
@@ -184,11 +189,12 @@ async fn op_datagram_send(
transport,
transport_args: ArgsEnum::Ip(args),
} if transport == "udp" => {
- state.check_net(&args.hostname, args.port)?;
+ cli_state.check_net(&args.hostname, args.port)?;
let addr = resolve_addr(&args.hostname, args.port)?;
poll_fn(move |cx| {
- let mut resource_table = state.resource_table.borrow_mut();
- let resource = resource_table
+ let mut state = state.borrow_mut();
+ let resource = state
+ .resource_table
.get_mut::<UdpSocketResource>(rid as u32)
.ok_or_else(|| ErrBox::bad_resource("Socket has been closed"))?;
resource
@@ -206,9 +212,10 @@ async fn op_datagram_send(
transport_args: ArgsEnum::Unix(args),
} if transport == "unixpacket" => {
let address_path = net_unix::Path::new(&args.path);
- state.check_read(&address_path)?;
- let mut resource_table = state.resource_table.borrow_mut();
- let resource = resource_table
+ cli_state.check_read(&address_path)?;
+ let mut state = state.borrow_mut();
+ let resource = state
+ .resource_table
.get_mut::<net_unix::UnixDatagramResource>(rid as u32)
.ok_or_else(|| ErrBox::new("NotConnected", "Socket has been closed"))?;
let socket = &mut resource.socket;
@@ -230,21 +237,24 @@ struct ConnectArgs {
}
async fn op_connect(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
+ let cli_state = super::cli_state2(&state);
match serde_json::from_value(args)? {
ConnectArgs {
transport,
transport_args: ArgsEnum::Ip(args),
} if transport == "tcp" => {
- state.check_net(&args.hostname, args.port)?;
+ cli_state.check_net(&args.hostname, args.port)?;
let addr = resolve_addr(&args.hostname, args.port)?;
let tcp_stream = TcpStream::connect(&addr).await?;
let local_addr = tcp_stream.local_addr()?;
let remote_addr = tcp_stream.peer_addr()?;
- let rid = state.resource_table.borrow_mut().add(
+
+ let mut state_ = state.borrow_mut();
+ let rid = state_.resource_table.add(
"tcpStream",
Box::new(StreamResourceHolder::new(StreamResource::TcpStream(Some(
tcp_stream,
@@ -270,14 +280,16 @@ async fn op_connect(
transport_args: ArgsEnum::Unix(args),
} if transport == "unix" => {
let address_path = net_unix::Path::new(&args.path);
- state.check_unstable("Deno.connect");
- state.check_read(&address_path)?;
+ cli_state.check_unstable("Deno.connect");
+ cli_state.check_read(&address_path)?;
let path = args.path;
let unix_stream =
net_unix::UnixStream::connect(net_unix::Path::new(&path)).await?;
let local_addr = unix_stream.local_addr()?;
let remote_addr = unix_stream.peer_addr()?;
- let rid = state.resource_table.borrow_mut().add(
+
+ let mut state_ = state.borrow_mut();
+ let rid = state_.resource_table.add(
"unixStream",
Box::new(StreamResourceHolder::new(StreamResource::UnixStream(
unix_stream,
@@ -306,11 +318,11 @@ struct ShutdownArgs {
}
fn op_shutdown(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.shutdown");
+ super::cli_state(state).check_unstable("Deno.shutdown");
let args: ShutdownArgs = serde_json::from_value(args)?;
@@ -323,8 +335,8 @@ fn op_shutdown(
_ => unimplemented!(),
};
- let mut resource_table = state.resource_table.borrow_mut();
- let resource_holder = resource_table
+ let resource_holder = state
+ .resource_table
.get_mut::<StreamResourceHolder>(rid)
.ok_or_else(ErrBox::bad_resource_id)?;
match resource_holder.resource {
@@ -416,7 +428,7 @@ struct ListenArgs {
}
fn listen_tcp(
- state: &State,
+ state: &mut OpState,
addr: SocketAddr,
) -> Result<(u32, SocketAddr), ErrBox> {
let std_listener = std::net::TcpListener::bind(&addr)?;
@@ -429,14 +441,13 @@ fn listen_tcp(
};
let rid = state
.resource_table
- .borrow_mut()
.add("tcpListener", Box::new(listener_resource));
Ok((rid, local_addr))
}
fn listen_udp(
- state: &State,
+ state: &mut OpState,
addr: SocketAddr,
) -> Result<(u32, SocketAddr), ErrBox> {
let std_socket = std::net::UdpSocket::bind(&addr)?;
@@ -445,26 +456,28 @@ fn listen_udp(
let socket_resource = UdpSocketResource { socket };
let rid = state
.resource_table
- .borrow_mut()
.add("udpSocket", Box::new(socket_resource));
Ok((rid, local_addr))
}
fn op_listen(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
+ let cli_state = super::cli_state(state);
match serde_json::from_value(args)? {
ListenArgs {
transport,
transport_args: ArgsEnum::Ip(args),
} => {
- if transport == "udp" {
- state.check_unstable("Deno.listenDatagram");
+ {
+ if transport == "udp" {
+ cli_state.check_unstable("Deno.listenDatagram");
+ }
+ cli_state.check_net(&args.hostname, args.port)?;
}
- state.check_net(&args.hostname, args.port)?;
let addr = resolve_addr(&args.hostname, args.port)?;
let (rid, local_addr) = if transport == "tcp" {
listen_tcp(state, addr)?
@@ -491,15 +504,17 @@ fn op_listen(
transport,
transport_args: ArgsEnum::Unix(args),
} if transport == "unix" || transport == "unixpacket" => {
- if transport == "unix" {
- state.check_unstable("Deno.listen");
- }
- if transport == "unixpacket" {
- state.check_unstable("Deno.listenDatagram");
- }
let address_path = net_unix::Path::new(&args.path);
- state.check_read(&address_path)?;
- state.check_write(&address_path)?;
+ {
+ if transport == "unix" {
+ cli_state.check_unstable("Deno.listen");
+ }
+ if transport == "unixpacket" {
+ cli_state.check_unstable("Deno.listenDatagram");
+ }
+ cli_state.check_read(&address_path)?;
+ cli_state.check_write(&address_path)?;
+ }
let (rid, local_addr) = if transport == "unix" {
net_unix::listen_unix(state, &address_path)?
} else {
diff --git a/cli/ops/net_unix.rs b/cli/ops/net_unix.rs
index a73db89b2..5cdb451dc 100644
--- a/cli/ops/net_unix.rs
+++ b/cli/ops/net_unix.rs
@@ -2,15 +2,18 @@ use crate::ops::io::StreamResource;
use crate::ops::io::StreamResourceHolder;
use crate::ops::net::AcceptArgs;
use crate::ops::net::ReceiveArgs;
-use crate::state::State;
use deno_core::BufVec;
use deno_core::ErrBox;
+use deno_core::OpState;
+use futures::future::poll_fn;
use serde_derive::Deserialize;
use serde_json::Value;
+use std::cell::RefCell;
use std::fs::remove_file;
use std::os::unix;
pub use std::path::Path;
use std::rc::Rc;
+use std::task::Poll;
use tokio::net::UnixDatagram;
use tokio::net::UnixListener;
pub use tokio::net::UnixStream;
@@ -30,25 +33,39 @@ pub struct UnixListenArgs {
}
pub(crate) async fn accept_unix(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: AcceptArgs,
_bufs: BufVec,
) -> Result<Value, ErrBox> {
let rid = args.rid as u32;
- let mut resource_table_ = state.resource_table.borrow_mut();
- let listener_resource = {
- resource_table_
+ let accept_fut = poll_fn(|cx| {
+ let mut state = state.borrow_mut();
+ let listener_resource = state
+ .resource_table
.get_mut::<UnixListenerResource>(rid)
- .ok_or_else(|| ErrBox::bad_resource("Listener has been closed"))?
- };
- let (unix_stream, _socket_addr) = listener_resource.listener.accept().await?;
- drop(resource_table_);
+ .ok_or_else(|| ErrBox::bad_resource("Listener has been closed"))?;
+ let listener = &mut listener_resource.listener;
+ use futures::StreamExt;
+ match listener.poll_next_unpin(cx) {
+ Poll::Ready(Some(stream)) => {
+ //listener_resource.untrack_task();
+ Poll::Ready(stream)
+ }
+ Poll::Ready(None) => todo!(),
+ Poll::Pending => {
+ //listener_resource.track_task(cx)?;
+ Poll::Pending
+ }
+ }
+ .map_err(ErrBox::from)
+ });
+ let unix_stream = accept_fut.await?;
let local_addr = unix_stream.local_addr()?;
let remote_addr = unix_stream.peer_addr()?;
- let mut resource_table_ = state.resource_table.borrow_mut();
- let rid = resource_table_.add(
+ let mut state = state.borrow_mut();
+ let rid = state.resource_table.add(
"unixStream",
Box::new(StreamResourceHolder::new(StreamResource::UnixStream(
unix_stream,
@@ -68,7 +85,7 @@ pub(crate) async fn accept_unix(
}
pub(crate) async fn receive_unix_packet(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: ReceiveArgs,
bufs: BufVec,
) -> Result<Value, ErrBox> {
@@ -77,8 +94,9 @@ pub(crate) async fn receive_unix_packet(
let rid = args.rid as u32;
let mut buf = bufs.into_iter().next().unwrap();
- let mut resource_table_ = state.resource_table.borrow_mut();
- let resource = resource_table_
+ let mut state = state.borrow_mut();
+ let resource = state
+ .resource_table
.get_mut::<UnixDatagramResource>(rid)
.ok_or_else(|| ErrBox::bad_resource("Socket has been closed"))?;
let (size, remote_addr) = resource.socket.recv_from(&mut buf).await?;
@@ -92,7 +110,7 @@ pub(crate) async fn receive_unix_packet(
}
pub fn listen_unix(
- state: &State,
+ state: &mut OpState,
addr: &Path,
) -> Result<(u32, unix::net::SocketAddr), ErrBox> {
if addr.exists() {
@@ -103,14 +121,13 @@ pub fn listen_unix(
let listener_resource = UnixListenerResource { listener };
let rid = state
.resource_table
- .borrow_mut()
.add("unixListener", Box::new(listener_resource));
Ok((rid, local_addr))
}
pub fn listen_unix_packet(
- state: &State,
+ state: &mut OpState,
addr: &Path,
) -> Result<(u32, unix::net::SocketAddr), ErrBox> {
if addr.exists() {
@@ -124,7 +141,6 @@ pub fn listen_unix_packet(
};
let rid = state
.resource_table
- .borrow_mut()
.add("unixDatagram", Box::new(datagram_resource));
Ok((rid, local_addr))
diff --git a/cli/ops/os.rs b/cli/ops/os.rs
index a38b5b08a..9860018a0 100644
--- a/cli/ops/os.rs
+++ b/cli/ops/os.rs
@@ -1,36 +1,35 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::state::State;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use serde_derive::Deserialize;
use serde_json::Value;
use std::collections::HashMap;
use std::env;
-use std::rc::Rc;
use url::Url;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_exit", op_exit);
- s.register_op_json_sync("op_env", op_env);
- s.register_op_json_sync("op_exec_path", op_exec_path);
- s.register_op_json_sync("op_set_env", op_set_env);
- s.register_op_json_sync("op_get_env", op_get_env);
- s.register_op_json_sync("op_delete_env", op_delete_env);
- s.register_op_json_sync("op_hostname", op_hostname);
- s.register_op_json_sync("op_loadavg", op_loadavg);
- s.register_op_json_sync("op_os_release", op_os_release);
- s.register_op_json_sync("op_system_memory_info", op_system_memory_info);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_exit", op_exit);
+ super::reg_json_sync(rt, "op_env", op_env);
+ super::reg_json_sync(rt, "op_exec_path", op_exec_path);
+ super::reg_json_sync(rt, "op_set_env", op_set_env);
+ super::reg_json_sync(rt, "op_get_env", op_get_env);
+ super::reg_json_sync(rt, "op_delete_env", op_delete_env);
+ super::reg_json_sync(rt, "op_hostname", op_hostname);
+ super::reg_json_sync(rt, "op_loadavg", op_loadavg);
+ super::reg_json_sync(rt, "op_os_release", op_os_release);
+ super::reg_json_sync(rt, "op_system_memory_info", op_system_memory_info);
}
fn op_exec_path(
- state: &State,
+ state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let current_exe = env::current_exe().unwrap();
- state.check_read_blind(&current_exe, "exec_path")?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_read_blind(&current_exe, "exec_path")?;
// Now apply URL parser to current exe to get fully resolved path, otherwise
// we might get `./` and `../` bits in `exec_path`
let exe_url = Url::from_file_path(current_exe).unwrap();
@@ -45,22 +44,24 @@ struct SetEnv {
}
fn op_set_env(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: SetEnv = serde_json::from_value(args)?;
- state.check_env()?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_env()?;
env::set_var(args.key, args.value);
Ok(json!({}))
}
fn op_env(
- state: &State,
+ state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_env()?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_env()?;
let v = env::vars().collect::<HashMap<String, String>>();
Ok(json!(v))
}
@@ -71,12 +72,13 @@ struct GetEnv {
}
fn op_get_env(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: GetEnv = serde_json::from_value(args)?;
- state.check_env()?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_env()?;
let r = match env::var(args.key) {
Err(env::VarError::NotPresent) => json!([]),
v => json!([v?]),
@@ -90,12 +92,13 @@ struct DeleteEnv {
}
fn op_delete_env(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: DeleteEnv = serde_json::from_value(args)?;
- state.check_env()?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_env()?;
env::remove_var(args.key);
Ok(json!({}))
}
@@ -106,7 +109,7 @@ struct Exit {
}
fn op_exit(
- _state: &State,
+ _state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -115,12 +118,13 @@ fn op_exit(
}
fn op_loadavg(
- state: &State,
+ state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.loadavg");
- state.check_env()?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.loadavg");
+ cli_state.check_env()?;
match sys_info::loadavg() {
Ok(loadavg) => Ok(json!([loadavg.one, loadavg.five, loadavg.fifteen])),
Err(_) => Ok(json!([0f64, 0f64, 0f64])),
@@ -128,34 +132,37 @@ fn op_loadavg(
}
fn op_hostname(
- state: &State,
+ state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.hostname");
- state.check_env()?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.hostname");
+ cli_state.check_env()?;
let hostname = sys_info::hostname().unwrap_or_else(|_| "".to_string());
Ok(json!(hostname))
}
fn op_os_release(
- state: &State,
+ state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.osRelease");
- state.check_env()?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.osRelease");
+ cli_state.check_env()?;
let release = sys_info::os_release().unwrap_or_else(|_| "".to_string());
Ok(json!(release))
}
fn op_system_memory_info(
- state: &State,
+ state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.systemMemoryInfo");
- state.check_env()?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.systemMemoryInfo");
+ cli_state.check_env()?;
match sys_info::mem_info() {
Ok(info) => Ok(json!({
"total": info.total,
diff --git a/cli/ops/permissions.rs b/cli/ops/permissions.rs
index 90d21a726..76d105ba7 100644
--- a/cli/ops/permissions.rs
+++ b/cli/ops/permissions.rs
@@ -1,18 +1,16 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::state::State;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use serde_derive::Deserialize;
use serde_json::Value;
use std::path::Path;
-use std::rc::Rc;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_query_permission", op_query_permission);
- s.register_op_json_sync("op_revoke_permission", op_revoke_permission);
- s.register_op_json_sync("op_request_permission", op_request_permission);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_query_permission", op_query_permission);
+ super::reg_json_sync(rt, "op_revoke_permission", op_revoke_permission);
+ super::reg_json_sync(rt, "op_request_permission", op_request_permission);
}
#[derive(Deserialize)]
@@ -23,12 +21,13 @@ struct PermissionArgs {
}
pub fn op_query_permission(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: PermissionArgs = serde_json::from_value(args)?;
- let permissions = state.permissions.borrow();
+ let cli_state = super::cli_state(state);
+ let permissions = cli_state.permissions.borrow();
let path = args.path.as_deref();
let perm = match args.name.as_ref() {
"read" => permissions.query_read(&path.as_deref().map(Path::new)),
@@ -49,12 +48,13 @@ pub fn op_query_permission(
}
pub fn op_revoke_permission(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: PermissionArgs = serde_json::from_value(args)?;
- let mut permissions = state.permissions.borrow_mut();
+ let cli_state = super::cli_state(state);
+ let mut permissions = cli_state.permissions.borrow_mut();
let path = args.path.as_deref();
let perm = match args.name.as_ref() {
"read" => permissions.revoke_read(&path.as_deref().map(Path::new)),
@@ -75,12 +75,13 @@ pub fn op_revoke_permission(
}
pub fn op_request_permission(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: PermissionArgs = serde_json::from_value(args)?;
- let permissions = &mut state.permissions.borrow_mut();
+ let cli_state = super::cli_state(state);
+ let permissions = &mut cli_state.permissions.borrow_mut();
let path = args.path.as_deref();
let perm = match args.name.as_ref() {
"read" => permissions.request_read(&path.as_deref().map(Path::new)),
diff --git a/cli/ops/plugin.rs b/cli/ops/plugin.rs
index 9cab05011..fc3d5201d 100644
--- a/cli/ops/plugin.rs
+++ b/cli/ops/plugin.rs
@@ -1,26 +1,28 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::state::State;
+use crate::metrics::metrics_op;
use deno_core::plugin_api;
use deno_core::BufVec;
use deno_core::ErrBox;
+use deno_core::JsRuntime;
use deno_core::Op;
use deno_core::OpAsyncFuture;
use deno_core::OpId;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use dlopen::symbor::Library;
use futures::prelude::*;
use serde_derive::Deserialize;
use serde_json::Value;
+use std::cell::RefCell;
use std::path::PathBuf;
use std::pin::Pin;
use std::rc::Rc;
use std::task::Context;
use std::task::Poll;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_open_plugin", op_open_plugin);
+pub fn init(rt: &mut JsRuntime) {
+ super::reg_json_sync(rt, "op_open_plugin", op_open_plugin);
}
#[derive(Deserialize)]
@@ -30,16 +32,16 @@ struct OpenPluginArgs {
}
pub fn op_open_plugin(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.openPlugin");
-
- let args: OpenPluginArgs = serde_json::from_value(args).unwrap();
+ let args: OpenPluginArgs = serde_json::from_value(args)?;
let filename = PathBuf::from(&args.filename);
- state.check_plugin(&filename)?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.openPlugin");
+ cli_state.check_plugin(&filename)?;
debug!("Loading Plugin: {:#?}", filename);
let plugin_lib = Library::open(filename).map(Rc::new)?;
@@ -48,10 +50,12 @@ pub fn op_open_plugin(
let rid;
let deno_plugin_init;
{
- let mut resource_table = state.resource_table.borrow_mut();
- rid = resource_table.add("plugin", Box::new(plugin_resource));
+ rid = state
+ .resource_table
+ .add("plugin", Box::new(plugin_resource));
deno_plugin_init = *unsafe {
- resource_table
+ state
+ .resource_table
.get::<PluginResource>(rid)
.unwrap()
.lib
@@ -77,12 +81,12 @@ impl PluginResource {
}
struct PluginInterface<'a> {
- state: &'a State,
+ state: &'a mut OpState,
plugin_lib: &'a Rc<Library>,
}
impl<'a> PluginInterface<'a> {
- fn new(state: &'a State, plugin_lib: &'a Rc<Library>) -> Self {
+ fn new(state: &'a mut OpState, plugin_lib: &'a Rc<Library>) -> Self {
Self { state, plugin_lib }
}
}
@@ -99,23 +103,24 @@ impl<'a> plugin_api::Interface for PluginInterface<'a> {
dispatch_op_fn: plugin_api::DispatchOpFn,
) -> OpId {
let plugin_lib = self.plugin_lib.clone();
- self.state.register_op(
- name,
- move |state: Rc<State>, mut zero_copy: BufVec| {
- let mut interface = PluginInterface::new(&state, &plugin_lib);
- let op = dispatch_op_fn(&mut interface, &mut zero_copy);
- match op {
- sync_op @ Op::Sync(..) => sync_op,
- Op::Async(fut) => {
- Op::Async(PluginOpAsyncFuture::new(&plugin_lib, fut))
- }
- Op::AsyncUnref(fut) => {
- Op::AsyncUnref(PluginOpAsyncFuture::new(&plugin_lib, fut))
- }
- _ => unreachable!(),
+ let plugin_op_fn = move |state_rc: Rc<RefCell<OpState>>,
+ mut zero_copy: BufVec| {
+ let mut state = state_rc.borrow_mut();
+ let mut interface = PluginInterface::new(&mut state, &plugin_lib);
+ let op = dispatch_op_fn(&mut interface, &mut zero_copy);
+ match op {
+ sync_op @ Op::Sync(..) => sync_op,
+ Op::Async(fut) => Op::Async(PluginOpAsyncFuture::new(&plugin_lib, fut)),
+ Op::AsyncUnref(fut) => {
+ Op::AsyncUnref(PluginOpAsyncFuture::new(&plugin_lib, fut))
}
- },
- )
+ _ => unreachable!(),
+ }
+ };
+ self
+ .state
+ .op_table
+ .register_op(name, metrics_op(Box::new(plugin_op_fn)))
}
}
diff --git a/cli/ops/process.rs b/cli/ops/process.rs
index fb8675db9..6a7e05ebf 100644
--- a/cli/ops/process.rs
+++ b/cli/ops/process.rs
@@ -2,28 +2,28 @@
use super::io::{std_file_resource, StreamResource, StreamResourceHolder};
use crate::signal::kill;
-use crate::state::State;
use deno_core::BufVec;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use futures::future::poll_fn;
use futures::future::FutureExt;
use serde_derive::Deserialize;
use serde_json::Value;
+use std::cell::RefCell;
use std::rc::Rc;
use tokio::process::Command;
#[cfg(unix)]
use std::os::unix::process::ExitStatusExt;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_run", op_run);
- s.register_op_json_async("op_run_status", op_run_status);
- s.register_op_json_sync("op_kill", op_kill);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_run", op_run);
+ super::reg_json_async(rt, "op_run_status", op_run_status);
+ super::reg_json_sync(rt, "op_kill", op_kill);
}
-fn clone_file(state: &State, rid: u32) -> Result<std::fs::File, ErrBox> {
+fn clone_file(state: &mut OpState, rid: u32) -> Result<std::fs::File, ErrBox> {
std_file_resource(state, rid, move |r| match r {
Ok(std_file) => std_file.try_clone().map_err(ErrBox::from),
Err(_) => Err(ErrBox::bad_resource_id()),
@@ -58,13 +58,12 @@ struct ChildResource {
}
fn op_run(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let run_args: RunArgs = serde_json::from_value(args)?;
-
- state.check_run()?;
+ super::cli_state(state).check_run()?;
let args = run_args.cmd;
let env = run_args.env;
@@ -111,7 +110,7 @@ fn op_run(
let stdin_rid = match child.stdin.take() {
Some(child_stdin) => {
- let rid = state.resource_table.borrow_mut().add(
+ let rid = state.resource_table.add(
"childStdin",
Box::new(StreamResourceHolder::new(StreamResource::ChildStdin(
child_stdin,
@@ -124,7 +123,7 @@ fn op_run(
let stdout_rid = match child.stdout.take() {
Some(child_stdout) => {
- let rid = state.resource_table.borrow_mut().add(
+ let rid = state.resource_table.add(
"childStdout",
Box::new(StreamResourceHolder::new(StreamResource::ChildStdout(
child_stdout,
@@ -137,7 +136,7 @@ fn op_run(
let stderr_rid = match child.stderr.take() {
Some(child_stderr) => {
- let rid = state.resource_table.borrow_mut().add(
+ let rid = state.resource_table.add(
"childStderr",
Box::new(StreamResourceHolder::new(StreamResource::ChildStderr(
child_stderr,
@@ -149,10 +148,7 @@ fn op_run(
};
let child_resource = ChildResource { child };
- let child_rid = state
- .resource_table
- .borrow_mut()
- .add("child", Box::new(child_resource));
+ let child_rid = state.resource_table.add("child", Box::new(child_resource));
Ok(json!({
"rid": child_rid,
@@ -170,18 +166,19 @@ struct RunStatusArgs {
}
async fn op_run_status(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
let args: RunStatusArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
- state.check_run()?;
+ super::cli_state2(&state).check_run()?;
let run_status = poll_fn(|cx| {
- let mut resource_table = state.resource_table.borrow_mut();
- let child_resource = resource_table
+ let mut state = state.borrow_mut();
+ let child_resource = state
+ .resource_table
.get_mut::<ChildResource>(rid)
.ok_or_else(ErrBox::bad_resource_id)?;
let child = &mut child_resource.child;
@@ -215,12 +212,13 @@ struct KillArgs {
}
fn op_kill(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.kill");
- state.check_run()?;
+ let cli_state = super::cli_state(state);
+ cli_state.check_unstable("Deno.kill");
+ cli_state.check_run()?;
let args: KillArgs = serde_json::from_value(args)?;
kill(args.pid, args.signo)?;
diff --git a/cli/ops/random.rs b/cli/ops/random.rs
index 4ce1411b8..1ef0c2645 100644
--- a/cli/ops/random.rs
+++ b/cli/ops/random.rs
@@ -1,26 +1,24 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::state::State;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use rand::thread_rng;
use rand::Rng;
use serde_json::Value;
-use std::rc::Rc;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_get_random_values", op_get_random_values);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_get_random_values", op_get_random_values);
}
fn op_get_random_values(
- state: &State,
+ state: &mut OpState,
_args: Value,
zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
assert_eq!(zero_copy.len(), 1);
-
- if let Some(seeded_rng) = &state.seeded_rng {
+ let cli_state = super::cli_state(state);
+ if let Some(seeded_rng) = &cli_state.seeded_rng {
seeded_rng.borrow_mut().fill(&mut *zero_copy[0]);
} else {
let mut rng = thread_rng();
diff --git a/cli/ops/repl.rs b/cli/ops/repl.rs
index 300432832..e2cfe21cd 100644
--- a/cli/ops/repl.rs
+++ b/cli/ops/repl.rs
@@ -2,20 +2,20 @@
use crate::repl;
use crate::repl::Repl;
-use crate::state::State;
use deno_core::BufVec;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use serde_derive::Deserialize;
use serde_json::Value;
+use std::cell::RefCell;
use std::rc::Rc;
use std::sync::Arc;
use std::sync::Mutex;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_repl_start", op_repl_start);
- s.register_op_json_async("op_repl_readline", op_repl_readline);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_repl_start", op_repl_start);
+ super::reg_json_async(rt, "op_repl_readline", op_repl_readline);
}
struct ReplResource(Arc<Mutex<Repl>>);
@@ -27,20 +27,19 @@ struct ReplStartArgs {
}
fn op_repl_start(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: ReplStartArgs = serde_json::from_value(args)?;
debug!("op_repl_start {}", args.history_file);
- let history_path =
- repl::history_path(&state.global_state.dir, &args.history_file);
+ let history_path = {
+ let cli_state = super::cli_state(state);
+ repl::history_path(&cli_state.global_state.dir, &args.history_file)
+ };
let repl = repl::Repl::new(history_path);
let resource = ReplResource(Arc::new(Mutex::new(repl)));
- let rid = state
- .resource_table
- .borrow_mut()
- .add("repl", Box::new(resource));
+ let rid = state.resource_table.add("repl", Box::new(resource));
Ok(json!(rid))
}
@@ -51,7 +50,7 @@ struct ReplReadlineArgs {
}
async fn op_repl_readline(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
@@ -59,12 +58,14 @@ async fn op_repl_readline(
let rid = args.rid as u32;
let prompt = args.prompt;
debug!("op_repl_readline {} {}", rid, prompt);
- let resource_table = state.resource_table.borrow();
- let resource = resource_table
- .get::<ReplResource>(rid)
- .ok_or_else(ErrBox::bad_resource_id)?;
- let repl = resource.0.clone();
- drop(resource_table);
+ let repl = {
+ let state = state.borrow();
+ let resource = state
+ .resource_table
+ .get::<ReplResource>(rid)
+ .ok_or_else(ErrBox::bad_resource_id)?;
+ resource.0.clone()
+ };
tokio::task::spawn_blocking(move || {
let line = repl.lock().unwrap().readline(&prompt)?;
Ok(json!(line))
diff --git a/cli/ops/resources.rs b/cli/ops/resources.rs
index d7c2fd142..78e35828e 100644
--- a/cli/ops/resources.rs
+++ b/cli/ops/resources.rs
@@ -1,31 +1,28 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::state::State;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use serde_derive::Deserialize;
use serde_json::Value;
-use std::rc::Rc;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_resources", op_resources);
- s.register_op_json_sync("op_close", op_close);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_resources", op_resources);
+ super::reg_json_sync(rt, "op_close", op_close);
}
fn op_resources(
- state: &State,
+ state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- let resource_table = state.resource_table.borrow();
- let serialized_resources = resource_table.entries();
+ let serialized_resources = state.resource_table.entries();
Ok(json!(serialized_resources))
}
/// op_close removes a resource from the resource table.
fn op_close(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -36,7 +33,6 @@ fn op_close(
let args: CloseArgs = serde_json::from_value(args)?;
state
.resource_table
- .borrow_mut()
.close(args.rid as u32)
.ok_or_else(ErrBox::bad_resource_id)?;
Ok(json!({}))
diff --git a/cli/ops/runtime.rs b/cli/ops/runtime.rs
index 10aac11fa..396a6951c 100644
--- a/cli/ops/runtime.rs
+++ b/cli/ops/runtime.rs
@@ -1,29 +1,27 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::colors;
-use crate::state::State;
use crate::version;
use crate::DenoSubcommand;
use deno_core::ErrBox;
use deno_core::ModuleSpecifier;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use serde_json::Value;
use std::env;
-use std::rc::Rc;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_start", op_start);
- s.register_op_json_sync("op_main_module", op_main_module);
- s.register_op_json_sync("op_metrics", op_metrics);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_start", op_start);
+ super::reg_json_sync(rt, "op_main_module", op_main_module);
+ super::reg_json_sync(rt, "op_metrics", op_metrics);
}
fn op_start(
- state: &State,
+ state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- let gs = &state.global_state;
+ let gs = &super::cli_state(state).global_state;
Ok(json!({
// TODO(bartlomieju): `cwd` field is not used in JS, remove?
@@ -44,25 +42,27 @@ fn op_start(
}
fn op_main_module(
- state: &State,
+ state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- let main = &state.main_module.to_string();
+ let cli_state = super::cli_state(state);
+ let main = &cli_state.main_module.to_string();
let main_url = ModuleSpecifier::resolve_url_or_path(&main)?;
if main_url.as_url().scheme() == "file" {
let main_path = std::env::current_dir().unwrap().join(main_url.to_string());
- state.check_read_blind(&main_path, "main_module")?;
+ cli_state.check_read_blind(&main_path, "main_module")?;
}
Ok(json!(&main))
}
fn op_metrics(
- state: &State,
+ state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- let m = &state.metrics.borrow();
+ let cli_state = super::cli_state(state);
+ let m = &cli_state.metrics.borrow();
Ok(json!({
"opsDispatched": m.ops_dispatched,
diff --git a/cli/ops/runtime_compiler.rs b/cli/ops/runtime_compiler.rs
index 71974e6da..d806b0133 100644
--- a/cli/ops/runtime_compiler.rs
+++ b/cli/ops/runtime_compiler.rs
@@ -1,21 +1,21 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
use crate::futures::FutureExt;
-use crate::state::State;
use crate::tsc::runtime_bundle;
use crate::tsc::runtime_compile;
use crate::tsc::runtime_transpile;
use deno_core::BufVec;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use serde_derive::Deserialize;
use serde_json::Value;
+use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_async("op_compile", op_compile);
- s.register_op_json_async("op_transpile", op_transpile);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_async(rt, "op_compile", op_compile);
+ super::reg_json_async(rt, "op_transpile", op_transpile);
}
#[derive(Deserialize, Debug)]
@@ -28,14 +28,15 @@ struct CompileArgs {
}
async fn op_compile(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_data: BufVec,
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.compile");
+ let cli_state = super::cli_state2(&state);
+ cli_state.check_unstable("Deno.compile");
let args: CompileArgs = serde_json::from_value(args)?;
- let global_state = state.global_state.clone();
- let permissions = state.permissions.borrow().clone();
+ let global_state = cli_state.global_state.clone();
+ let permissions = cli_state.permissions.borrow().clone();
let fut = if args.bundle {
runtime_bundle(
&global_state,
@@ -66,14 +67,15 @@ struct TranspileArgs {
}
async fn op_transpile(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_data: BufVec,
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.transpile");
+ let cli_state = super::cli_state2(&state);
+ cli_state.check_unstable("Deno.transpile");
let args: TranspileArgs = serde_json::from_value(args)?;
- let global_state = state.global_state.clone();
- let permissions = state.permissions.borrow().clone();
+ let global_state = cli_state.global_state.clone();
+ let permissions = cli_state.permissions.borrow().clone();
let result =
runtime_transpile(&global_state, permissions, &args.sources, &args.options)
.await?;
diff --git a/cli/ops/signal.rs b/cli/ops/signal.rs
index c0b1220e0..37d1ca914 100644
--- a/cli/ops/signal.rs
+++ b/cli/ops/signal.rs
@@ -1,11 +1,11 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::state::State;
use deno_core::BufVec;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use serde_json::Value;
+use std::cell::RefCell;
use std::rc::Rc;
#[cfg(unix)]
@@ -17,10 +17,10 @@ use std::task::Waker;
#[cfg(unix)]
use tokio::signal::unix::{signal, Signal, SignalKind};
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_signal_bind", op_signal_bind);
- s.register_op_json_sync("op_signal_unbind", op_signal_unbind);
- s.register_op_json_async("op_signal_poll", op_signal_poll);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_signal_bind", op_signal_bind);
+ super::reg_json_sync(rt, "op_signal_unbind", op_signal_unbind);
+ super::reg_json_async(rt, "op_signal_poll", op_signal_poll);
}
#[cfg(unix)]
@@ -42,13 +42,13 @@ struct SignalArgs {
#[cfg(unix)]
fn op_signal_bind(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.signal");
+ super::cli_state(state).check_unstable("Deno.signal");
let args: BindSignalArgs = serde_json::from_value(args)?;
- let rid = state.resource_table.borrow_mut().add(
+ let rid = state.resource_table.add(
"signal",
Box::new(SignalStreamResource(
signal(SignalKind::from_raw(args.signo)).expect(""),
@@ -62,18 +62,18 @@ fn op_signal_bind(
#[cfg(unix)]
async fn op_signal_poll(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.signal");
+ super::cli_state2(&state).check_unstable("Deno.signal");
let args: SignalArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let future = poll_fn(move |cx| {
- let mut resource_table = state.resource_table.borrow_mut();
+ let mut state = state.borrow_mut();
if let Some(mut signal) =
- resource_table.get_mut::<SignalStreamResource>(rid)
+ state.resource_table.get_mut::<SignalStreamResource>(rid)
{
signal.1 = Some(cx.waker().clone());
return signal.0.poll_recv(cx);
@@ -86,15 +86,14 @@ async fn op_signal_poll(
#[cfg(unix)]
pub fn op_signal_unbind(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.signal");
- let mut resource_table = state.resource_table.borrow_mut();
+ super::cli_state(state).check_unstable("Deno.signal");
let args: SignalArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
- let resource = resource_table.get_mut::<SignalStreamResource>(rid);
+ let resource = state.resource_table.get_mut::<SignalStreamResource>(rid);
if let Some(signal) = resource {
if let Some(waker) = &signal.1 {
// Wakes up the pending poll if exists.
@@ -102,7 +101,8 @@ pub fn op_signal_unbind(
waker.clone().wake();
}
}
- resource_table
+ state
+ .resource_table
.close(rid)
.ok_or_else(ErrBox::bad_resource_id)?;
Ok(json!({}))
@@ -110,7 +110,7 @@ pub fn op_signal_unbind(
#[cfg(not(unix))]
pub fn op_signal_bind(
- _state: &State,
+ _state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -119,7 +119,7 @@ pub fn op_signal_bind(
#[cfg(not(unix))]
fn op_signal_unbind(
- _state: &State,
+ _state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -128,7 +128,7 @@ fn op_signal_unbind(
#[cfg(not(unix))]
async fn op_signal_poll(
- _state: Rc<State>,
+ _state: Rc<RefCell<OpState>>,
_args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
diff --git a/cli/ops/timers.rs b/cli/ops/timers.rs
index 36d617a85..3ce2b5633 100644
--- a/cli/ops/timers.rs
+++ b/cli/ops/timers.rs
@@ -1,29 +1,30 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::state::State;
use deno_core::BufVec;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use futures::future::FutureExt;
use serde_derive::Deserialize;
use serde_json::Value;
+use std::cell::RefCell;
use std::rc::Rc;
use std::time::Duration;
use std::time::Instant;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_global_timer_stop", op_global_timer_stop);
- s.register_op_json_async("op_global_timer", op_global_timer);
- s.register_op_json_sync("op_now", op_now);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_global_timer_stop", op_global_timer_stop);
+ super::reg_json_async(rt, "op_global_timer", op_global_timer);
+ super::reg_json_sync(rt, "op_now", op_now);
}
fn op_global_timer_stop(
- state: &State,
+ state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.global_timer.borrow_mut().cancel();
+ let cli_state = super::cli_state(state);
+ cli_state.global_timer.borrow_mut().cancel();
Ok(json!({}))
}
@@ -33,7 +34,7 @@ struct GlobalTimerArgs {
}
async fn op_global_timer(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
@@ -41,11 +42,13 @@ async fn op_global_timer(
let val = args.timeout;
let deadline = Instant::now() + Duration::from_millis(val);
- let timer_fut = state
- .global_timer
- .borrow_mut()
- .new_timeout(deadline)
- .boxed_local();
+ let timer_fut = {
+ super::cli_state2(&state)
+ .global_timer
+ .borrow_mut()
+ .new_timeout(deadline)
+ .boxed_local()
+ };
let _ = timer_fut.await;
Ok(json!({}))
}
@@ -55,18 +58,19 @@ async fn op_global_timer(
// If the High precision flag is not set, the
// nanoseconds are rounded on 2ms.
fn op_now(
- state: &State,
+ state: &mut OpState,
_args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- let seconds = state.start_time.elapsed().as_secs();
- let mut subsec_nanos = state.start_time.elapsed().subsec_nanos();
+ let cli_state = super::cli_state(state);
+ let seconds = cli_state.start_time.elapsed().as_secs();
+ let mut subsec_nanos = cli_state.start_time.elapsed().subsec_nanos();
let reduced_time_precision = 2_000_000; // 2ms in nanoseconds
// If the permission is not enabled
// Round the nano result on 2 milliseconds
// see: https://developer.mozilla.org/en-US/docs/Web/API/DOMHighResTimeStamp#Reduced_time_precision
- if state.check_hrtime().is_err() {
+ if cli_state.check_hrtime().is_err() {
subsec_nanos -= subsec_nanos % reduced_time_precision;
}
diff --git a/cli/ops/tls.rs b/cli/ops/tls.rs
index 3a478c3ad..43364df1b 100644
--- a/cli/ops/tls.rs
+++ b/cli/ops/tls.rs
@@ -2,14 +2,14 @@
use super::io::{StreamResource, StreamResourceHolder};
use crate::resolve_addr::resolve_addr;
-use crate::state::State;
use deno_core::BufVec;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use futures::future::poll_fn;
use serde_derive::Deserialize;
use serde_json::Value;
+use std::cell::RefCell;
use std::convert::From;
use std::fs::File;
use std::io::BufReader;
@@ -31,11 +31,11 @@ use tokio_rustls::{
};
use webpki::DNSNameRef;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_async("op_start_tls", op_start_tls);
- s.register_op_json_async("op_connect_tls", op_connect_tls);
- s.register_op_json_sync("op_listen_tls", op_listen_tls);
- s.register_op_json_async("op_accept_tls", op_accept_tls);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_async(rt, "op_start_tls", op_start_tls);
+ super::reg_json_async(rt, "op_connect_tls", op_connect_tls);
+ super::reg_json_sync(rt, "op_listen_tls", op_listen_tls);
+ super::reg_json_async(rt, "op_accept_tls", op_accept_tls);
}
#[derive(Deserialize)]
@@ -56,11 +56,10 @@ struct StartTLSArgs {
}
async fn op_start_tls(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.startTls");
let args: StartTLSArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let cert_file = args.cert_file.clone();
@@ -69,15 +68,17 @@ async fn op_start_tls(
if domain.is_empty() {
domain.push_str("localhost");
}
-
- state.check_net(&domain, 0)?;
- if let Some(path) = cert_file.clone() {
- state.check_read(Path::new(&path))?;
+ {
+ let cli_state = super::cli_state2(&state);
+ cli_state.check_unstable("Deno.startTls");
+ cli_state.check_net(&domain, 0)?;
+ if let Some(path) = cert_file.clone() {
+ cli_state.check_read(Path::new(&path))?;
+ }
}
-
let mut resource_holder = {
- let mut resource_table = state.resource_table.borrow_mut();
- match resource_table.remove::<StreamResourceHolder>(rid) {
+ let mut state_ = state.borrow_mut();
+ match state_.resource_table.remove::<StreamResourceHolder>(rid) {
Some(resource) => *resource,
None => return Err(ErrBox::bad_resource_id()),
}
@@ -104,13 +105,15 @@ async fn op_start_tls(
DNSNameRef::try_from_ascii_str(&domain).expect("Invalid DNS lookup");
let tls_stream = tls_connector.connect(dnsname, tcp_stream).await?;
- let mut resource_table = state.resource_table.borrow_mut();
- let rid = resource_table.add(
- "clientTlsStream",
- Box::new(StreamResourceHolder::new(StreamResource::ClientTlsStream(
- Box::new(tls_stream),
- ))),
- );
+ let rid = {
+ let mut state_ = state.borrow_mut();
+ state_.resource_table.add(
+ "clientTlsStream",
+ Box::new(StreamResourceHolder::new(StreamResource::ClientTlsStream(
+ Box::new(tls_stream),
+ ))),
+ )
+ };
Ok(json!({
"rid": rid,
"localAddr": {
@@ -130,17 +133,19 @@ async fn op_start_tls(
}
async fn op_connect_tls(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
let args: ConnectTLSArgs = serde_json::from_value(args)?;
let cert_file = args.cert_file.clone();
- state.check_net(&args.hostname, args.port)?;
- if let Some(path) = cert_file.clone() {
- state.check_read(Path::new(&path))?;
+ {
+ let cli_state = super::cli_state2(&state);
+ cli_state.check_net(&args.hostname, args.port)?;
+ if let Some(path) = cert_file.clone() {
+ cli_state.check_read(Path::new(&path))?;
+ }
}
-
let mut domain = args.hostname.clone();
if domain.is_empty() {
domain.push_str("localhost");
@@ -163,13 +168,15 @@ async fn op_connect_tls(
let dnsname =
DNSNameRef::try_from_ascii_str(&domain).expect("Invalid DNS lookup");
let tls_stream = tls_connector.connect(dnsname, tcp_stream).await?;
- let mut resource_table = state.resource_table.borrow_mut();
- let rid = resource_table.add(
- "clientTlsStream",
- Box::new(StreamResourceHolder::new(StreamResource::ClientTlsStream(
- Box::new(tls_stream),
- ))),
- );
+ let rid = {
+ let mut state_ = state.borrow_mut();
+ state_.resource_table.add(
+ "clientTlsStream",
+ Box::new(StreamResourceHolder::new(StreamResource::ClientTlsStream(
+ Box::new(tls_stream),
+ ))),
+ )
+ };
Ok(json!({
"rid": rid,
"localAddr": {
@@ -298,7 +305,7 @@ struct ListenTlsArgs {
}
fn op_listen_tls(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -307,11 +314,12 @@ fn op_listen_tls(
let cert_file = args.cert_file;
let key_file = args.key_file;
-
- state.check_net(&args.hostname, args.port)?;
- state.check_read(Path::new(&cert_file))?;
- state.check_read(Path::new(&key_file))?;
-
+ {
+ let cli_state = super::cli_state(state);
+ cli_state.check_net(&args.hostname, args.port)?;
+ cli_state.check_read(Path::new(&cert_file))?;
+ cli_state.check_read(Path::new(&key_file))?;
+ }
let mut config = ServerConfig::new(NoClientAuth::new());
config
.set_single_cert(load_certs(&cert_file)?, load_keys(&key_file)?.remove(0))
@@ -330,7 +338,6 @@ fn op_listen_tls(
let rid = state
.resource_table
- .borrow_mut()
.add("tlsListener", Box::new(tls_listener_resource));
Ok(json!({
@@ -349,15 +356,16 @@ struct AcceptTlsArgs {
}
async fn op_accept_tls(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
let args: AcceptTlsArgs = serde_json::from_value(args)?;
let rid = args.rid as u32;
let accept_fut = poll_fn(|cx| {
- let mut resource_table = state.resource_table.borrow_mut();
- let listener_resource = resource_table
+ let mut state = state.borrow_mut();
+ let listener_resource = state
+ .resource_table
.get_mut::<TlsListenerResource>(rid)
.ok_or_else(|| ErrBox::bad_resource("Listener has been closed"))?;
let listener = &mut listener_resource.listener;
@@ -380,8 +388,9 @@ async fn op_accept_tls(
let local_addr = tcp_stream.local_addr()?;
let remote_addr = tcp_stream.peer_addr()?;
let tls_acceptor = {
- let resource_table = state.resource_table.borrow();
- let resource = resource_table
+ let state_ = state.borrow();
+ let resource = state_
+ .resource_table
.get::<TlsListenerResource>(rid)
.ok_or_else(ErrBox::bad_resource_id)
.expect("Can't find tls listener");
@@ -389,8 +398,8 @@ async fn op_accept_tls(
};
let tls_stream = tls_acceptor.accept(tcp_stream).await?;
let rid = {
- let mut resource_table = state.resource_table.borrow_mut();
- resource_table.add(
+ let mut state_ = state.borrow_mut();
+ state_.resource_table.add(
"serverTlsStream",
Box::new(StreamResourceHolder::new(StreamResource::ServerTlsStream(
Box::new(tls_stream),
diff --git a/cli/ops/tty.rs b/cli/ops/tty.rs
index 9079ca57e..84443c0bc 100644
--- a/cli/ops/tty.rs
+++ b/cli/ops/tty.rs
@@ -2,15 +2,13 @@
use super::io::std_file_resource;
use super::io::{StreamResource, StreamResourceHolder};
-use crate::state::State;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
#[cfg(unix)]
use nix::sys::termios;
use serde_derive::{Deserialize, Serialize};
use serde_json::Value;
-use std::rc::Rc;
#[cfg(windows)]
use winapi::shared::minwindef::DWORD;
@@ -20,6 +18,7 @@ use winapi::um::wincon;
const RAW_MODE_MASK: DWORD = wincon::ENABLE_LINE_INPUT
| wincon::ENABLE_ECHO_INPUT
| wincon::ENABLE_PROCESSED_INPUT;
+
#[cfg(windows)]
fn get_windows_handle(
f: &std::fs::File,
@@ -36,10 +35,10 @@ fn get_windows_handle(
Ok(handle)
}
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_set_raw", op_set_raw);
- s.register_op_json_sync("op_isatty", op_isatty);
- s.register_op_json_sync("op_console_size", op_console_size);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_set_raw", op_set_raw);
+ super::reg_json_sync(rt, "op_isatty", op_isatty);
+ super::reg_json_sync(rt, "op_console_size", op_console_size);
}
#[derive(Deserialize)]
@@ -49,11 +48,12 @@ struct SetRawArgs {
}
fn op_set_raw(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.setRaw");
+ super::cli_state(state).check_unstable("Deno.setRaw");
+
let args: SetRawArgs = serde_json::from_value(args)?;
let rid = args.rid;
let is_raw = args.mode;
@@ -69,8 +69,8 @@ fn op_set_raw(
use winapi::shared::minwindef::FALSE;
use winapi::um::{consoleapi, handleapi};
- let mut resource_table = state.resource_table.borrow_mut();
- let resource_holder = resource_table.get_mut::<StreamResourceHolder>(rid);
+ let resource_holder =
+ state.resource_table.get_mut::<StreamResourceHolder>(rid);
if resource_holder.is_none() {
return Err(ErrBox::bad_resource_id());
}
@@ -135,8 +135,8 @@ fn op_set_raw(
{
use std::os::unix::io::AsRawFd;
- let mut resource_table = state.resource_table.borrow_mut();
- let resource_holder = resource_table.get_mut::<StreamResourceHolder>(rid);
+ let resource_holder =
+ state.resource_table.get_mut::<StreamResourceHolder>(rid);
if resource_holder.is_none() {
return Err(ErrBox::bad_resource_id());
}
@@ -217,7 +217,7 @@ struct IsattyArgs {
}
fn op_isatty(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -261,11 +261,12 @@ struct ConsoleSize {
}
fn op_console_size(
- state: &State,
+ state: &mut OpState,
args: Value,
_zero_copy: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
- state.check_unstable("Deno.consoleSize");
+ super::cli_state(state).check_unstable("Deno.consoleSize");
+
let args: ConsoleSizeArgs = serde_json::from_value(args)?;
let rid = args.rid;
diff --git a/cli/ops/web_worker.rs b/cli/ops/web_worker.rs
index 9d8140d7b..fad0b9df7 100644
--- a/cli/ops/web_worker.rs
+++ b/cli/ops/web_worker.rs
@@ -1,20 +1,18 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::state::State;
use crate::web_worker::WebWorkerHandle;
use crate::worker::WorkerEvent;
-use deno_core::OpRegistry;
use futures::channel::mpsc;
-use std::rc::Rc;
pub fn init(
- s: &Rc<State>,
- sender: &mpsc::Sender<WorkerEvent>,
+ rt: &mut deno_core::JsRuntime,
+ sender: mpsc::Sender<WorkerEvent>,
handle: WebWorkerHandle,
) {
// Post message to host as guest worker.
let sender_ = sender.clone();
- s.register_op_json_sync(
+ super::reg_json_sync(
+ rt,
"op_worker_post_message",
move |_state, _args, bufs| {
assert_eq!(bufs.len(), 1, "Invalid number of arguments");
@@ -28,10 +26,9 @@ pub fn init(
);
// Notify host that guest worker closes.
- let sender_ = sender.clone();
- s.register_op_json_sync("op_worker_close", move |_state, _args, _bufs| {
+ super::reg_json_sync(rt, "op_worker_close", move |_state, _args, _bufs| {
// Notify parent that we're finished
- sender_.clone().close_channel();
+ sender.clone().close_channel();
// Terminate execution of current worker
handle.terminate();
Ok(json!({}))
diff --git a/cli/ops/websocket.rs b/cli/ops/websocket.rs
index 131c52179..4a5b83b88 100644
--- a/cli/ops/websocket.rs
+++ b/cli/ops/websocket.rs
@@ -1,10 +1,9 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::state::State;
use core::task::Poll;
use deno_core::BufVec;
use deno_core::ErrBox;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use futures::future::poll_fn;
use futures::StreamExt;
use futures::{ready, SinkExt};
@@ -12,6 +11,7 @@ use http::{Method, Request, Uri};
use serde_derive::Deserialize;
use serde_json::Value;
use std::borrow::Cow;
+use std::cell::RefCell;
use std::fs::File;
use std::io::BufReader;
use std::rc::Rc;
@@ -26,11 +26,11 @@ use tokio_tungstenite::tungstenite::{
use tokio_tungstenite::{client_async, WebSocketStream};
use webpki::DNSNameRef;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_async("op_ws_create", op_ws_create);
- s.register_op_json_async("op_ws_send", op_ws_send);
- s.register_op_json_async("op_ws_close", op_ws_close);
- s.register_op_json_async("op_ws_next_event", op_ws_next_event);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_async(rt, "op_ws_create", op_ws_create);
+ super::reg_json_async(rt, "op_ws_send", op_ws_send);
+ super::reg_json_async(rt, "op_ws_close", op_ws_close);
+ super::reg_json_async(rt, "op_ws_next_event", op_ws_next_event);
}
type MaybeTlsStream =
@@ -46,13 +46,16 @@ struct CreateArgs {
}
pub async fn op_ws_create(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_bufs: BufVec,
) -> Result<Value, ErrBox> {
let args: CreateArgs = serde_json::from_value(args)?;
- state.check_net_url(&url::Url::parse(&args.url)?)?;
- let ca_file = state.global_state.flags.ca_file.clone();
+ let ca_file = {
+ let cli_state = super::cli_state2(&state);
+ cli_state.check_net_url(&url::Url::parse(&args.url)?)?;
+ cli_state.global_state.flags.ca_file.clone()
+ };
let uri: Uri = args.url.parse().unwrap();
let request = Request::builder()
.method(Method::GET)
@@ -99,9 +102,9 @@ pub async fn op_ws_create(
let (stream, response): (WsStream, Response) =
client_async(request, socket).await.unwrap();
+ let mut state = state.borrow_mut();
let rid = state
.resource_table
- .borrow_mut()
.add("webSocketStream", Box::new(stream));
let protocol = match response.headers().get("Sec-WebSocket-Protocol") {
@@ -130,7 +133,7 @@ struct SendArgs {
}
pub async fn op_ws_send(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
bufs: BufVec,
) -> Result<Value, ErrBox> {
@@ -143,8 +146,9 @@ pub async fn op_ws_send(
let rid = args.rid;
poll_fn(move |cx| {
- let mut resource_table = state.resource_table.borrow_mut();
- let stream = resource_table
+ let mut state = state.borrow_mut();
+ let stream = state
+ .resource_table
.get_mut::<WsStream>(rid)
.ok_or_else(ErrBox::bad_resource_id)?;
@@ -171,7 +175,7 @@ struct CloseArgs {
}
pub async fn op_ws_close(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_bufs: BufVec,
) -> Result<Value, ErrBox> {
@@ -186,8 +190,9 @@ pub async fn op_ws_close(
})));
poll_fn(move |cx| {
- let mut resource_table = state.resource_table.borrow_mut();
- let stream = resource_table
+ let mut state = state.borrow_mut();
+ let stream = state
+ .resource_table
.get_mut::<WsStream>(rid)
.ok_or_else(ErrBox::bad_resource_id)?;
@@ -213,14 +218,15 @@ struct NextEventArgs {
}
pub async fn op_ws_next_event(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_bufs: BufVec,
) -> Result<Value, ErrBox> {
let args: NextEventArgs = serde_json::from_value(args)?;
poll_fn(move |cx| {
- let mut resource_table = state.resource_table.borrow_mut();
- let stream = resource_table
+ let mut state = state.borrow_mut();
+ let stream = state
+ .resource_table
.get_mut::<WsStream>(args.rid)
.ok_or_else(ErrBox::bad_resource_id)?;
stream
@@ -248,7 +254,7 @@ pub async fn op_ws_next_event(
Some(Ok(Message::Pong(_))) => json!({"type": "pong"}),
Some(Err(_)) => json!({"type": "error"}),
None => {
- resource_table.close(args.rid).unwrap();
+ state.resource_table.close(args.rid).unwrap();
json!({"type": "closed"})
}
}
diff --git a/cli/ops/worker_host.rs b/cli/ops/worker_host.rs
index 83f84064b..158865abc 100644
--- a/cli/ops/worker_host.rs
+++ b/cli/ops/worker_host.rs
@@ -5,7 +5,6 @@ use crate::global_state::GlobalState;
use crate::ops::io::get_stdio;
use crate::permissions::Permissions;
use crate::startup_data;
-use crate::state::State;
use crate::tokio_util::create_basic_runtime;
use crate::web_worker::WebWorker;
use crate::web_worker::WebWorkerHandle;
@@ -13,21 +12,26 @@ use crate::worker::WorkerEvent;
use deno_core::BufVec;
use deno_core::ErrBox;
use deno_core::ModuleSpecifier;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::ZeroCopyBuf;
use futures::future::FutureExt;
use serde_derive::Deserialize;
use serde_json::Value;
+use std::cell::RefCell;
use std::convert::From;
use std::rc::Rc;
use std::sync::Arc;
use std::thread::JoinHandle;
-pub fn init(s: &Rc<State>) {
- s.register_op_json_sync("op_create_worker", op_create_worker);
- s.register_op_json_sync("op_host_terminate_worker", op_host_terminate_worker);
- s.register_op_json_sync("op_host_post_message", op_host_post_message);
- s.register_op_json_async("op_host_get_message", op_host_get_message);
+pub fn init(rt: &mut deno_core::JsRuntime) {
+ super::reg_json_sync(rt, "op_create_worker", op_create_worker);
+ super::reg_json_sync(
+ rt,
+ "op_host_terminate_worker",
+ op_host_terminate_worker,
+ );
+ super::reg_json_sync(rt, "op_host_post_message", op_host_post_message);
+ super::reg_json_async(rt, "op_host_get_message", op_host_get_message);
}
fn create_web_worker(
@@ -38,27 +42,31 @@ fn create_web_worker(
specifier: ModuleSpecifier,
has_deno_namespace: bool,
) -> Result<WebWorker, ErrBox> {
- let state =
- State::new_for_worker(global_state, Some(permissions), specifier)?;
+ let cli_state = crate::state::State::new_for_worker(
+ global_state,
+ Some(permissions),
+ specifier,
+ )?;
let mut worker = WebWorker::new(
name.clone(),
startup_data::deno_isolate_init(),
- &state,
+ &cli_state,
has_deno_namespace,
);
if has_deno_namespace {
- let mut resource_table = state.resource_table.borrow_mut();
+ let state = worker.isolate.op_state();
+ let mut state = state.borrow_mut();
let (stdin, stdout, stderr) = get_stdio();
if let Some(stream) = stdin {
- resource_table.add("stdin", Box::new(stream));
+ state.resource_table.add("stdin", Box::new(stream));
}
if let Some(stream) = stdout {
- resource_table.add("stdout", Box::new(stream));
+ state.resource_table.add("stdout", Box::new(stream));
}
if let Some(stream) = stderr {
- resource_table.add("stderr", Box::new(stream));
+ state.resource_table.add("stderr", Box::new(stream));
}
}
@@ -172,10 +180,11 @@ struct CreateWorkerArgs {
/// Create worker as the host
fn op_create_worker(
- state: &State,
+ state: &mut OpState,
args: Value,
_data: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
+ let cli_state = super::cli_state(state);
let args: CreateWorkerArgs = serde_json::from_value(args)?;
let specifier = args.specifier.clone();
@@ -187,12 +196,12 @@ fn op_create_worker(
let args_name = args.name;
let use_deno_namespace = args.use_deno_namespace;
if use_deno_namespace {
- state.check_unstable("Worker.deno");
+ cli_state.check_unstable("Worker.deno");
}
- let global_state = state.global_state.clone();
- let permissions = state.permissions.borrow().clone();
- let worker_id = state.next_worker_id.get();
- state.next_worker_id.set(worker_id + 1);
+ let global_state = cli_state.global_state.clone();
+ let permissions = cli_state.permissions.borrow().clone();
+ let worker_id = cli_state.next_worker_id.get();
+ cli_state.next_worker_id.set(worker_id + 1);
let module_specifier = ModuleSpecifier::resolve_url(&specifier)?;
let worker_name = args_name.unwrap_or_else(|| "".to_string());
@@ -208,7 +217,8 @@ fn op_create_worker(
)?;
// At this point all interactions with worker happen using thread
// safe handler returned from previous function call
- state
+ let cli_state = super::cli_state(state);
+ cli_state
.workers
.borrow_mut()
.insert(worker_id, (join_handle, worker_handle));
@@ -222,13 +232,14 @@ struct WorkerArgs {
}
fn op_host_terminate_worker(
- state: &State,
+ state: &mut OpState,
args: Value,
_data: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
let args: WorkerArgs = serde_json::from_value(args)?;
let id = args.id as u32;
- let (join_handle, worker_handle) = state
+ let cli_state = super::cli_state(state);
+ let (join_handle, worker_handle) = cli_state
.workers
.borrow_mut()
.remove(&id)
@@ -290,40 +301,41 @@ fn serialize_worker_event(event: WorkerEvent) -> Value {
/// Get message from guest worker as host
async fn op_host_get_message(
- state: Rc<State>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_zero_copy: BufVec,
) -> Result<Value, ErrBox> {
let args: WorkerArgs = serde_json::from_value(args)?;
let id = args.id as u32;
- let state = state.clone();
+ let cli_state = super::cli_state2(&state);
- let workers_table = state.workers.borrow();
- let maybe_handle = workers_table.get(&id);
- let worker_handle = if let Some(handle) = maybe_handle {
- handle.1.clone()
- } else {
- // If handle was not found it means worker has already shutdown
- return Ok(json!({ "type": "close" }));
+ let worker_handle = {
+ let workers_table = cli_state.workers.borrow();
+ let maybe_handle = workers_table.get(&id);
+ if let Some(handle) = maybe_handle {
+ handle.1.clone()
+ } else {
+ // If handle was not found it means worker has already shutdown
+ return Ok(json!({ "type": "close" }));
+ }
};
- drop(workers_table);
let response = match worker_handle.get_event().await? {
Some(event) => {
// Terminal error means that worker should be removed from worker table.
if let WorkerEvent::TerminalError(_) = &event {
if let Some((join_handle, mut worker_handle)) =
- state.workers.borrow_mut().remove(&id)
+ cli_state.workers.borrow_mut().remove(&id)
{
worker_handle.sender.close_channel();
join_handle.join().expect("Worker thread panicked");
- }
+ };
}
serialize_worker_event(event)
}
None => {
// Worker shuts down
- let mut workers = state.workers.borrow_mut();
+ let mut workers = cli_state.workers.borrow_mut();
// Try to remove worker from workers table - NOTE: `Worker.terminate()` might have been called
// already meaning that we won't find worker in table - in that case ignore.
if let Some((join_handle, mut worker_handle)) = workers.remove(&id) {
@@ -338,7 +350,7 @@ async fn op_host_get_message(
/// Post message to guest worker as host
fn op_host_post_message(
- state: &State,
+ state: &mut OpState,
args: Value,
data: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -348,7 +360,8 @@ fn op_host_post_message(
let msg = Vec::from(&*data[0]).into_boxed_slice();
debug!("post message to worker {}", id);
- let workers = state.workers.borrow();
+ let cli_state = super::cli_state(state);
+ let workers = cli_state.workers.borrow();
let worker_handle = workers[&id].1.clone();
worker_handle.post_message(msg)?;
Ok(json!({}))
diff --git a/cli/state.rs b/cli/state.rs
index c85701bac..3df4ffb3b 100644
--- a/cli/state.rs
+++ b/cli/state.rs
@@ -1,6 +1,5 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-use crate::errors::get_error_class_name;
use crate::file_fetcher::SourceFileFetcher;
use crate::global_state::GlobalState;
use crate::global_timer::GlobalTimer;
@@ -10,17 +9,10 @@ use crate::metrics::Metrics;
use crate::permissions::Permissions;
use crate::tsc::TargetLib;
use crate::web_worker::WebWorkerHandle;
-use deno_core::BufVec;
use deno_core::ErrBox;
use deno_core::ModuleLoadId;
use deno_core::ModuleLoader;
use deno_core::ModuleSpecifier;
-use deno_core::Op;
-use deno_core::OpId;
-use deno_core::OpRegistry;
-use deno_core::OpRouter;
-use deno_core::OpTable;
-use deno_core::ResourceTable;
use futures::future::FutureExt;
use futures::Future;
use rand::rngs::StdRng;
@@ -36,6 +28,7 @@ use std::sync::Arc;
use std::thread::JoinHandle;
use std::time::Instant;
+// TODO(ry) Rename to CliState to avoid confusion with other states.
#[cfg_attr(feature = "cargo-clippy", allow(stutter))]
pub struct State {
pub global_state: Arc<GlobalState>,
@@ -54,8 +47,6 @@ pub struct State {
pub is_main: bool,
pub is_internal: bool,
pub http_client: RefCell<reqwest::Client>,
- pub resource_table: RefCell<ResourceTable>,
- pub op_table: RefCell<OpTable<Self>>,
}
impl State {
@@ -202,8 +193,6 @@ impl State {
is_main: true,
is_internal,
http_client: create_http_client(fl.ca_file.as_deref())?.into(),
- resource_table: Default::default(),
- op_table: Default::default(),
};
Ok(Rc::new(state))
}
@@ -232,8 +221,6 @@ impl State {
is_main: false,
is_internal: false,
http_client: create_http_client(fl.ca_file.as_deref())?.into(),
- resource_table: Default::default(),
- op_table: Default::default(),
};
Ok(Rc::new(state))
}
@@ -331,78 +318,3 @@ impl State {
.unwrap()
}
}
-
-impl OpRouter for State {
- fn route_op(self: Rc<Self>, op_id: OpId, bufs: BufVec) -> Op {
- // TODOs:
- // * The 'bytes' metrics seem pretty useless, especially now that the
- // distinction between 'control' and 'data' buffers has become blurry.
- // * Tracking completion of async ops currently makes us put the boxed
- // future into _another_ box. Keeping some counters may not be expensive
- // in itself, but adding a heap allocation for every metric seems bad.
- let mut buf_len_iter = bufs.iter().map(|buf| buf.len());
- let bytes_sent_control = buf_len_iter.next().unwrap_or(0);
- let bytes_sent_data = buf_len_iter.sum();
-
- let op_fn = self
- .op_table
- .borrow()
- .get_index(op_id)
- .map(|(_, op_fn)| op_fn.clone())
- .unwrap();
-
- let self_ = self.clone();
- let op = (op_fn)(self_, bufs);
-
- let self_ = self.clone();
- let mut metrics = self_.metrics.borrow_mut();
- match op {
- Op::Sync(buf) => {
- metrics.op_sync(bytes_sent_control, bytes_sent_data, buf.len());
- Op::Sync(buf)
- }
- Op::Async(fut) => {
- metrics.op_dispatched_async(bytes_sent_control, bytes_sent_data);
- let fut = fut
- .inspect(move |buf| {
- self.metrics.borrow_mut().op_completed_async(buf.len());
- })
- .boxed_local();
- Op::Async(fut)
- }
- Op::AsyncUnref(fut) => {
- metrics.op_dispatched_async_unref(bytes_sent_control, bytes_sent_data);
- let fut = fut
- .inspect(move |buf| {
- self
- .metrics
- .borrow_mut()
- .op_completed_async_unref(buf.len());
- })
- .boxed_local();
- Op::AsyncUnref(fut)
- }
- other => other,
- }
- }
-}
-
-impl OpRegistry for State {
- fn get_op_catalog(self: Rc<Self>) -> HashMap<String, OpId> {
- self.op_table.borrow().get_op_catalog()
- }
-
- fn register_op<F>(&self, name: &str, op_fn: F) -> OpId
- where
- F: Fn(Rc<Self>, BufVec) -> Op + 'static,
- {
- let mut op_table = self.op_table.borrow_mut();
- let (op_id, prev) = op_table.insert_full(name.to_owned(), Rc::new(op_fn));
- assert!(prev.is_none());
- op_id
- }
-
- fn get_error_class_name(&self, err: &ErrBox) -> &'static str {
- get_error_class_name(err)
- }
-}
diff --git a/cli/tsc.rs b/cli/tsc.rs
index 36a7cf054..77b855dd1 100644
--- a/cli/tsc.rs
+++ b/cli/tsc.rs
@@ -139,15 +139,12 @@ impl CompilerWorker {
startup_data: StartupData,
state: &Rc<State>,
) -> Self {
- let worker = Worker::new(name, startup_data, state);
+ let mut worker = Worker::new(name, startup_data, state);
let response = Arc::new(Mutex::new(None));
- {
- ops::runtime::init(&state);
- ops::errors::init(&state);
- ops::timers::init(&state);
- ops::compiler::init(&state, response.clone());
- }
-
+ ops::runtime::init(&mut worker);
+ ops::errors::init(&mut worker);
+ ops::timers::init(&mut worker);
+ ops::compiler::init(&mut worker, response.clone());
Self { worker, response }
}
diff --git a/cli/web_worker.rs b/cli/web_worker.rs
index 095d5b376..ebf8fa698 100644
--- a/cli/web_worker.rs
+++ b/cli/web_worker.rs
@@ -102,7 +102,7 @@ impl WebWorker {
terminate_tx,
};
- let web_worker = Self {
+ let mut web_worker = Self {
worker,
event_loop_idle: false,
terminate_rx,
@@ -110,37 +110,33 @@ impl WebWorker {
has_deno_namespace,
};
- let handle = web_worker.thread_safe_handle();
-
{
- ops::runtime::init(&state);
- ops::web_worker::init(
- &state,
- &web_worker.worker.internal_channels.sender,
- handle,
- );
- ops::worker_host::init(&state);
- ops::idna::init(&state);
- ops::io::init(&state);
- ops::resources::init(&state);
- ops::errors::init(&state);
- ops::timers::init(&state);
- ops::fetch::init(&state);
- ops::websocket::init(&state);
+ ops::runtime::init(&mut web_worker.worker);
+ let sender = web_worker.worker.internal_channels.sender.clone();
+ let handle = web_worker.thread_safe_handle();
+ ops::web_worker::init(&mut web_worker.worker, sender, handle);
+ ops::worker_host::init(&mut web_worker.worker);
+ ops::idna::init(&mut web_worker.worker);
+ ops::io::init(&mut web_worker.worker);
+ ops::resources::init(&mut web_worker.worker);
+ ops::errors::init(&mut web_worker.worker);
+ ops::timers::init(&mut web_worker.worker);
+ ops::fetch::init(&mut web_worker.worker);
+ ops::websocket::init(&mut web_worker.worker);
if has_deno_namespace {
- ops::runtime_compiler::init(&state);
- ops::fs::init(&state);
- ops::fs_events::init(&state);
- ops::plugin::init(&state);
- ops::net::init(&state);
- ops::tls::init(&state);
- ops::os::init(&state);
- ops::permissions::init(&state);
- ops::process::init(&state);
- ops::random::init(&state);
- ops::signal::init(&state);
- ops::tty::init(&state);
+ ops::runtime_compiler::init(&mut web_worker.worker);
+ ops::fs::init(&mut web_worker.worker);
+ ops::fs_events::init(&mut web_worker.worker);
+ ops::plugin::init(&mut web_worker.worker);
+ ops::net::init(&mut web_worker.worker);
+ ops::tls::init(&mut web_worker.worker);
+ ops::os::init(&mut web_worker.worker);
+ ops::permissions::init(&mut web_worker.worker);
+ ops::process::init(&mut web_worker.worker);
+ ops::random::init(&mut web_worker.worker);
+ ops::signal::init(&mut web_worker.worker);
+ ops::tty::init(&mut web_worker.worker);
}
}
diff --git a/cli/worker.rs b/cli/worker.rs
index 9ac3bbead..baab81ff6 100644
--- a/cli/worker.rs
+++ b/cli/worker.rs
@@ -91,7 +91,7 @@ fn create_channels() -> (WorkerChannelsInternal, WorkerHandle) {
/// - `WebWorker`
pub struct Worker {
pub name: String,
- pub isolate: deno_core::JsRuntime,
+ pub isolate: JsRuntime,
pub inspector: Option<Box<DenoInspector>>,
pub state: Rc<State>,
pub waker: AtomicWaker,
@@ -105,22 +105,22 @@ impl Worker {
startup_data: StartupData,
state: &Rc<State>,
) -> Self {
- let mut isolate = deno_core::JsRuntime::new_with_loader(
- state.clone(),
- state.clone(),
- startup_data,
- false,
- );
-
+ let mut isolate =
+ JsRuntime::new_with_loader(state.clone(), startup_data, false);
{
let global_state = state.global_state.clone();
- let core_state_rc = JsRuntime::state(&isolate);
- let mut core_state = core_state_rc.borrow_mut();
- core_state.set_js_error_create_fn(move |core_js_error| {
+ let js_runtime_state = JsRuntime::state(&isolate);
+ let mut js_runtime_state = js_runtime_state.borrow_mut();
+ js_runtime_state.set_js_error_create_fn(move |core_js_error| {
JsError::create(core_js_error, &global_state.ts_compiler)
});
}
-
+ {
+ let op_state = isolate.op_state();
+ let mut op_state = op_state.borrow_mut();
+ op_state.get_error_class_fn = &crate::errors::get_error_class_name;
+ op_state.put(state.clone());
+ }
let inspector = {
let global_state = &state.global_state;
global_state
@@ -235,7 +235,7 @@ impl Future for Worker {
}
impl Deref for Worker {
- type Target = deno_core::JsRuntime;
+ type Target = JsRuntime;
fn deref(&self) -> &Self::Target {
&self.isolate
}
@@ -258,30 +258,30 @@ pub struct MainWorker(Worker);
impl MainWorker {
// TODO(ry) combine MainWorker::new and MainWorker::create.
fn new(name: String, startup_data: StartupData, state: &Rc<State>) -> Self {
- let worker = Worker::new(name, startup_data, state);
+ let mut worker = Worker::new(name, startup_data, state);
{
- ops::runtime::init(&state);
- ops::runtime_compiler::init(&state);
- ops::errors::init(&state);
- ops::fetch::init(&state);
- ops::websocket::init(&state);
- ops::fs::init(&state);
- ops::fs_events::init(&state);
- ops::idna::init(&state);
- ops::io::init(&state);
- ops::plugin::init(&state);
- ops::net::init(&state);
- ops::tls::init(&state);
- ops::os::init(&state);
- ops::permissions::init(&state);
- ops::process::init(&state);
- ops::random::init(&state);
- ops::repl::init(&state);
- ops::resources::init(&state);
- ops::signal::init(&state);
- ops::timers::init(&state);
- ops::tty::init(&state);
- ops::worker_host::init(&state);
+ ops::runtime::init(&mut worker);
+ ops::runtime_compiler::init(&mut worker);
+ ops::errors::init(&mut worker);
+ ops::fetch::init(&mut worker);
+ ops::websocket::init(&mut worker);
+ ops::fs::init(&mut worker);
+ ops::fs_events::init(&mut worker);
+ ops::idna::init(&mut worker);
+ ops::io::init(&mut worker);
+ ops::plugin::init(&mut worker);
+ ops::net::init(&mut worker);
+ ops::tls::init(&mut worker);
+ ops::os::init(&mut worker);
+ ops::permissions::init(&mut worker);
+ ops::process::init(&mut worker);
+ ops::random::init(&mut worker);
+ ops::repl::init(&mut worker);
+ ops::resources::init(&mut worker);
+ ops::signal::init(&mut worker);
+ ops::timers::init(&mut worker);
+ ops::tty::init(&mut worker);
+ ops::worker_host::init(&mut worker);
}
Self(worker)
}
@@ -303,7 +303,9 @@ impl MainWorker {
&state,
);
{
- let mut t = state.resource_table.borrow_mut();
+ let op_state = worker.op_state();
+ let mut op_state = op_state.borrow_mut();
+ let t = &mut op_state.resource_table;
let (stdin, stdout, stderr) = get_stdio();
if let Some(stream) = stdin {
t.add("stdin", Box::new(stream));
diff --git a/core/basic_state.rs b/core/basic_state.rs
deleted file mode 100644
index 54b9ee132..000000000
--- a/core/basic_state.rs
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
-
-use crate::BufVec;
-use crate::Op;
-use crate::OpId;
-use crate::OpRegistry;
-use crate::OpRouter;
-use crate::OpTable;
-use crate::ResourceTable;
-use std::cell::RefCell;
-use std::collections::HashMap;
-use std::rc::Rc;
-
-/// A minimal state struct for use by tests, examples etc. It contains
-/// an OpTable and ResourceTable, and implements the relevant traits
-/// for working with ops in the most straightforward way possible.
-#[derive(Default)]
-pub struct BasicState {
- pub op_table: RefCell<OpTable<Self>>,
- pub resource_table: RefCell<ResourceTable>,
-}
-
-impl BasicState {
- pub fn new() -> Rc<Self> {
- Default::default()
- }
-}
-
-impl OpRegistry for BasicState {
- fn get_op_catalog(self: Rc<Self>) -> HashMap<String, OpId> {
- self.op_table.borrow().get_op_catalog()
- }
-
- fn register_op<F>(&self, name: &str, op_fn: F) -> OpId
- where
- F: Fn(Rc<Self>, BufVec) -> Op + 'static,
- {
- let mut op_table = self.op_table.borrow_mut();
- let (op_id, prev) = op_table.insert_full(name.to_owned(), Rc::new(op_fn));
- assert!(prev.is_none());
- op_id
- }
-}
-
-impl OpRouter for BasicState {
- fn route_op(self: Rc<Self>, op_id: OpId, bufs: BufVec) -> Op {
- let op_fn = self
- .op_table
- .borrow()
- .get_index(op_id)
- .map(|(_, op_fn)| op_fn.clone())
- .unwrap();
- (op_fn)(self, bufs)
- }
-}
-
-#[test]
-fn test_basic_state_ops() {
- let state = BasicState::new();
-
- let foo_id = state.register_op("foo", |_, _| Op::Sync(b"oof!"[..].into()));
- assert_eq!(foo_id, 1);
-
- let bar_id = state.register_op("bar", |_, _| Op::Sync(b"rab!"[..].into()));
- assert_eq!(bar_id, 2);
-
- let state_ = state.clone();
- let foo_res = state_.route_op(foo_id, Default::default());
- assert!(matches!(foo_res, Op::Sync(buf) if &*buf == b"oof!"));
-
- let state_ = state.clone();
- let bar_res = state_.route_op(bar_id, Default::default());
- assert!(matches!(bar_res, Op::Sync(buf) if &*buf == b"rab!"));
-
- let catalog_res = state.route_op(0, Default::default());
- let mut catalog_entries = match catalog_res {
- Op::Sync(buf) => serde_json::from_slice::<HashMap<String, OpId>>(&buf)
- .map(|map| map.into_iter().collect::<Vec<_>>())
- .unwrap(),
- _ => panic!("unexpected `Op` variant"),
- };
- catalog_entries.sort_by(|(_, id1), (_, id2)| id1.partial_cmp(id2).unwrap());
- assert_eq!(
- catalog_entries,
- vec![
- ("ops".to_owned(), 0),
- ("foo".to_owned(), 1),
- ("bar".to_owned(), 2)
- ]
- )
-}
diff --git a/core/bindings.rs b/core/bindings.rs
index d0d916bdc..265906990 100644
--- a/core/bindings.rs
+++ b/core/bindings.rs
@@ -6,6 +6,7 @@ use crate::JsRuntime;
use crate::JsRuntimeState;
use crate::Op;
use crate::OpId;
+use crate::OpTable;
use crate::ZeroCopyBuf;
use futures::future::FutureExt;
use rusty_v8 as v8;
@@ -426,8 +427,7 @@ fn send<'s>(
}
};
- let op_router = state.op_router.clone();
- let op = op_router.route_op(op_id, bufs);
+ let op = OpTable::route_op(op_id, state.op_state.clone(), bufs);
assert_eq!(state.shared.size(), 0);
match op {
Op::Sync(buf) if !buf.is_empty() => {
diff --git a/core/examples/http_bench_bin_ops.rs b/core/examples/http_bench_bin_ops.rs
index 00eb95f44..b29af8b9d 100644
--- a/core/examples/http_bench_bin_ops.rs
+++ b/core/examples/http_bench_bin_ops.rs
@@ -2,11 +2,10 @@
extern crate log;
use deno_core::js_check;
-use deno_core::BasicState;
use deno_core::BufVec;
use deno_core::JsRuntime;
use deno_core::Op;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::Script;
use deno_core::StartupData;
use deno_core::ZeroCopyBuf;
@@ -14,6 +13,7 @@ use futures::future::poll_fn;
use futures::future::FutureExt;
use futures::future::TryFuture;
use futures::future::TryFutureExt;
+use std::cell::RefCell;
use std::convert::TryInto;
use std::env;
use std::fmt::Debug;
@@ -78,23 +78,22 @@ impl From<Record> for RecordBuf {
}
fn create_isolate() -> JsRuntime {
- let state = BasicState::new();
- register_op_bin_sync(&state, "listen", op_listen);
- register_op_bin_sync(&state, "close", op_close);
- register_op_bin_async(&state, "accept", op_accept);
- register_op_bin_async(&state, "read", op_read);
- register_op_bin_async(&state, "write", op_write);
-
let startup_data = StartupData::Script(Script {
source: include_str!("http_bench_bin_ops.js"),
filename: "http_bench_bin_ops.js",
});
- JsRuntime::new(state, startup_data, false)
+ let mut isolate = JsRuntime::new(startup_data, false);
+ register_op_bin_sync(&mut isolate, "listen", op_listen);
+ register_op_bin_sync(&mut isolate, "close", op_close);
+ register_op_bin_async(&mut isolate, "accept", op_accept);
+ register_op_bin_async(&mut isolate, "read", op_read);
+ register_op_bin_async(&mut isolate, "write", op_write);
+ isolate
}
fn op_listen(
- state: &BasicState,
+ state: &mut OpState,
_rid: u32,
_bufs: &mut [ZeroCopyBuf],
) -> Result<u32, Error> {
@@ -102,36 +101,33 @@ fn op_listen(
let addr = "127.0.0.1:4544".parse::<SocketAddr>().unwrap();
let std_listener = std::net::TcpListener::bind(&addr)?;
let listener = TcpListener::from_std(std_listener)?;
- let rid = state
- .resource_table
- .borrow_mut()
- .add("tcpListener", Box::new(listener));
+ let rid = state.resource_table.add("tcpListener", Box::new(listener));
Ok(rid)
}
fn op_close(
- state: &BasicState,
+ state: &mut OpState,
rid: u32,
_bufs: &mut [ZeroCopyBuf],
) -> Result<u32, Error> {
debug!("close rid={}", rid);
state
.resource_table
- .borrow_mut()
.close(rid)
.map(|_| 0)
.ok_or_else(bad_resource_id)
}
-fn op_accept(
- state: Rc<BasicState>,
+async fn op_accept(
+ state: Rc<RefCell<OpState>>,
rid: u32,
_bufs: BufVec,
-) -> impl TryFuture<Ok = u32, Error = Error> {
+) -> Result<u32, Error> {
debug!("accept rid={}", rid);
poll_fn(move |cx| {
- let resource_table = &mut state.resource_table.borrow_mut();
+ let resource_table = &mut state.borrow_mut().resource_table;
+
let listener = resource_table
.get_mut::<TcpListener>(rid)
.ok_or_else(bad_resource_id)?;
@@ -139,10 +135,11 @@ fn op_accept(
resource_table.add("tcpStream", Box::new(stream))
})
})
+ .await
}
fn op_read(
- state: Rc<BasicState>,
+ state: Rc<RefCell<OpState>>,
rid: u32,
bufs: BufVec,
) -> impl TryFuture<Ok = usize, Error = Error> {
@@ -152,7 +149,8 @@ fn op_read(
debug!("read rid={}", rid);
poll_fn(move |cx| {
- let resource_table = &mut state.resource_table.borrow_mut();
+ let resource_table = &mut state.borrow_mut().resource_table;
+
let stream = resource_table
.get_mut::<TcpStream>(rid)
.ok_or_else(bad_resource_id)?;
@@ -161,7 +159,7 @@ fn op_read(
}
fn op_write(
- state: Rc<BasicState>,
+ state: Rc<RefCell<OpState>>,
rid: u32,
bufs: BufVec,
) -> impl TryFuture<Ok = usize, Error = Error> {
@@ -170,7 +168,8 @@ fn op_write(
debug!("write rid={}", rid);
poll_fn(move |cx| {
- let resource_table = &mut state.resource_table.borrow_mut();
+ let resource_table = &mut state.borrow_mut().resource_table;
+
let stream = resource_table
.get_mut::<TcpStream>(rid)
.ok_or_else(bad_resource_id)?;
@@ -178,35 +177,42 @@ fn op_write(
})
}
-fn register_op_bin_sync<F>(state: &BasicState, name: &'static str, op_fn: F)
-where
- F: Fn(&BasicState, u32, &mut [ZeroCopyBuf]) -> Result<u32, Error> + 'static,
+fn register_op_bin_sync<F>(
+ isolate: &mut JsRuntime,
+ name: &'static str,
+ op_fn: F,
+) where
+ F: Fn(&mut OpState, u32, &mut [ZeroCopyBuf]) -> Result<u32, Error> + 'static,
{
- let base_op_fn = move |state: Rc<BasicState>, mut bufs: BufVec| -> Op {
+ let base_op_fn = move |state: Rc<RefCell<OpState>>, mut bufs: BufVec| -> Op {
let record = Record::from(bufs[0].as_ref());
let is_sync = record.promise_id == 0;
assert!(is_sync);
let zero_copy_bufs = &mut bufs[1..];
- let result: i32 = match op_fn(&state, record.rid, zero_copy_bufs) {
- Ok(r) => r as i32,
- Err(_) => -1,
- };
+ let result: i32 =
+ match op_fn(&mut state.borrow_mut(), record.rid, zero_copy_bufs) {
+ Ok(r) => r as i32,
+ Err(_) => -1,
+ };
let buf = RecordBuf::from(Record { result, ..record })[..].into();
Op::Sync(buf)
};
- state.register_op(name, base_op_fn);
+ isolate.register_op(name, base_op_fn);
}
-fn register_op_bin_async<F, R>(state: &BasicState, name: &'static str, op_fn: F)
-where
- F: Fn(Rc<BasicState>, u32, BufVec) -> R + Copy + 'static,
+fn register_op_bin_async<F, R>(
+ isolate: &mut JsRuntime,
+ name: &'static str,
+ op_fn: F,
+) where
+ F: Fn(Rc<RefCell<OpState>>, u32, BufVec) -> R + Copy + 'static,
R: TryFuture,
R::Ok: TryInto<i32>,
<R::Ok as TryInto<i32>>::Error: Debug,
{
- let base_op_fn = move |state: Rc<BasicState>, bufs: BufVec| -> Op {
+ let base_op_fn = move |state: Rc<RefCell<OpState>>, bufs: BufVec| -> Op {
let mut bufs_iter = bufs.into_iter();
let record_buf = bufs_iter.next().unwrap();
let zero_copy_bufs = bufs_iter.collect::<BufVec>();
@@ -227,7 +233,7 @@ where
Op::Async(fut.boxed_local())
};
- state.register_op(name, base_op_fn);
+ isolate.register_op(name, base_op_fn);
}
fn bad_resource_id() -> Error {
diff --git a/core/examples/http_bench_json_ops.rs b/core/examples/http_bench_json_ops.rs
index de467b8ad..dc0c837e2 100644
--- a/core/examples/http_bench_json_ops.rs
+++ b/core/examples/http_bench_json_ops.rs
@@ -2,17 +2,17 @@
extern crate log;
use deno_core::js_check;
-use deno_core::BasicState;
use deno_core::BufVec;
use deno_core::ErrBox;
use deno_core::JsRuntime;
-use deno_core::OpRegistry;
+use deno_core::OpState;
use deno_core::Script;
use deno_core::StartupData;
use deno_core::ZeroCopyBuf;
use futures::future::poll_fn;
use futures::future::Future;
use serde_json::Value;
+use std::cell::RefCell;
use std::convert::TryInto;
use std::env;
use std::net::SocketAddr;
@@ -42,23 +42,21 @@ impl log::Log for Logger {
}
fn create_isolate() -> JsRuntime {
- let state = BasicState::new();
- state.register_op_json_sync("listen", op_listen);
- state.register_op_json_sync("close", op_close);
- state.register_op_json_async("accept", op_accept);
- state.register_op_json_async("read", op_read);
- state.register_op_json_async("write", op_write);
-
let startup_data = StartupData::Script(Script {
source: include_str!("http_bench_json_ops.js"),
filename: "http_bench_json_ops.js",
});
-
- JsRuntime::new(state, startup_data, false)
+ let mut runtime = JsRuntime::new(startup_data, false);
+ runtime.register_op("listen", deno_core::json_op_sync(op_listen));
+ runtime.register_op("close", deno_core::json_op_sync(op_close));
+ runtime.register_op("accept", deno_core::json_op_async(op_accept));
+ runtime.register_op("read", deno_core::json_op_async(op_read));
+ runtime.register_op("write", deno_core::json_op_async(op_write));
+ runtime
}
fn op_listen(
- state: &BasicState,
+ state: &mut OpState,
_args: Value,
_bufs: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -66,15 +64,12 @@ fn op_listen(
let addr = "127.0.0.1:4544".parse::<SocketAddr>().unwrap();
let std_listener = std::net::TcpListener::bind(&addr)?;
let listener = TcpListener::from_std(std_listener)?;
- let rid = state
- .resource_table
- .borrow_mut()
- .add("tcpListener", Box::new(listener));
+ let rid = state.resource_table.add("tcpListener", Box::new(listener));
Ok(serde_json::json!({ "rid": rid }))
}
fn op_close(
- state: &BasicState,
+ state: &mut OpState,
args: Value,
_buf: &mut [ZeroCopyBuf],
) -> Result<Value, ErrBox> {
@@ -86,17 +81,15 @@ fn op_close(
.try_into()
.unwrap();
debug!("close rid={}", rid);
-
state
.resource_table
- .borrow_mut()
.close(rid)
.map(|_| serde_json::json!(()))
.ok_or_else(ErrBox::bad_resource_id)
}
fn op_accept(
- state: Rc<BasicState>,
+ state: Rc<RefCell<OpState>>,
args: Value,
_bufs: BufVec,
) -> impl Future<Output = Result<Value, ErrBox>> {
@@ -110,7 +103,8 @@ fn op_accept(
debug!("accept rid={}", rid);
poll_fn(move |cx| {
- let resource_table = &mut state.resource_table.borrow_mut();
+ let resource_table = &mut state.borrow_mut().resource_table;
+
let listener = resource_table
.get_mut::<TcpListener>(rid)
.ok_or_else(ErrBox::bad_resource_id)?;
@@ -122,7 +116,7 @@ fn op_accept(
}
fn op_read(
- state: Rc<BasicState>,
+ state: Rc<RefCell<OpState>>,
args: Value,
mut bufs: BufVec,
) -> impl Future<Output = Result<Value, ErrBox>> {
@@ -138,7 +132,8 @@ fn op_read(
debug!("read rid={}", rid);
poll_fn(move |cx| -> Poll<Result<Value, ErrBox>> {
- let resource_table = &mut state.resource_table.borrow_mut();
+ let resource_table = &mut state.borrow_mut().resource_table;
+
let stream = resource_table
.get_mut::<TcpStream>(rid)
.ok_or_else(ErrBox::bad_resource_id)?;
@@ -149,7 +144,7 @@ fn op_read(
}
fn op_write(
- state: Rc<BasicState>,
+ state: Rc<RefCell<OpState>>,
args: Value,
bufs: BufVec,
) -> impl Future<Output = Result<Value, ErrBox>> {
@@ -165,7 +160,8 @@ fn op_write(
debug!("write rid={}", rid);
poll_fn(move |cx| {
- let resource_table = &mut state.resource_table.borrow_mut();
+ let resource_table = &mut state.borrow_mut().resource_table;
+
let stream = resource_table
.get_mut::<TcpStream>(rid)
.ok_or_else(ErrBox::bad_resource_id)?;
diff --git a/core/gotham_state.rs b/core/gotham_state.rs
new file mode 100644
index 000000000..94a2d67d4
--- /dev/null
+++ b/core/gotham_state.rs
@@ -0,0 +1,167 @@
+// Forked from Gotham:
+// https://github.com/gotham-rs/gotham/blob/bcbbf8923789e341b7a0e62c59909428ca4e22e2/gotham/src/state/mod.rs
+// Copyright 2017 Gotham Project Developers. MIT license.
+
+use std::any::Any;
+use std::any::TypeId;
+use std::collections::HashMap;
+
+#[derive(Default)]
+pub struct GothamState {
+ data: HashMap<TypeId, Box<dyn Any>>,
+}
+
+impl GothamState {
+ /// Puts a value into the `GothamState` storage. One value of each type is retained.
+ /// Successive calls to `put` will overwrite the existing value of the same
+ /// type.
+ pub fn put<T: 'static>(&mut self, t: T) {
+ let type_id = TypeId::of::<T>();
+ trace!(" inserting record to state for type_id `{:?}`", type_id);
+ self.data.insert(type_id, Box::new(t));
+ }
+
+ /// Determines if the current value exists in `GothamState` storage.
+ pub fn has<T: 'static>(&self) -> bool {
+ let type_id = TypeId::of::<T>();
+ self.data.get(&type_id).is_some()
+ }
+
+ /// Tries to borrow a value from the `GothamState` storage.
+ pub fn try_borrow<T: 'static>(&self) -> Option<&T> {
+ let type_id = TypeId::of::<T>();
+ trace!(" borrowing state data for type_id `{:?}`", type_id);
+ self.data.get(&type_id).and_then(|b| b.downcast_ref())
+ }
+
+ /// Borrows a value from the `GothamState` storage.
+ pub fn borrow<T: 'static>(&self) -> &T {
+ self
+ .try_borrow()
+ .expect("required type is not present in GothamState container")
+ }
+
+ /// Tries to mutably borrow a value from the `GothamState` storage.
+ pub fn try_borrow_mut<T: 'static>(&mut self) -> Option<&mut T> {
+ let type_id = TypeId::of::<T>();
+ trace!(" mutably borrowing state data for type_id `{:?}`", type_id);
+ self.data.get_mut(&type_id).and_then(|b| b.downcast_mut())
+ }
+
+ /// Mutably borrows a value from the `GothamState` storage.
+ pub fn borrow_mut<T: 'static>(&mut self) -> &mut T {
+ self
+ .try_borrow_mut()
+ .expect("required type is not present in GothamState container")
+ }
+
+ /// Tries to move a value out of the `GothamState` storage and return ownership.
+ pub fn try_take<T: 'static>(&mut self) -> Option<T> {
+ let type_id = TypeId::of::<T>();
+ trace!(
+ " taking ownership from state data for type_id `{:?}`",
+ type_id
+ );
+ self
+ .data
+ .remove(&type_id)
+ .and_then(|b| b.downcast().ok())
+ .map(|b| *b)
+ }
+
+ /// Moves a value out of the `GothamState` storage and returns ownership.
+ ///
+ /// # Panics
+ ///
+ /// If a value of type `T` is not present in `GothamState`.
+ pub fn take<T: 'static>(&mut self) -> T {
+ self
+ .try_take()
+ .expect("required type is not present in GothamState container")
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::GothamState;
+
+ struct MyStruct {
+ value: i32,
+ }
+
+ struct AnotherStruct {
+ value: &'static str,
+ }
+
+ #[test]
+ fn put_borrow1() {
+ let mut state = GothamState::default();
+ state.put(MyStruct { value: 1 });
+ assert_eq!(state.borrow::<MyStruct>().value, 1);
+ }
+
+ #[test]
+ fn put_borrow2() {
+ let mut state = GothamState::default();
+ assert!(!state.has::<AnotherStruct>());
+ state.put(AnotherStruct { value: "a string" });
+ assert!(state.has::<AnotherStruct>());
+ assert!(!state.has::<MyStruct>());
+ state.put(MyStruct { value: 100 });
+ assert!(state.has::<MyStruct>());
+ assert_eq!(state.borrow::<MyStruct>().value, 100);
+ assert_eq!(state.borrow::<AnotherStruct>().value, "a string");
+ }
+
+ #[test]
+ fn try_borrow() {
+ let mut state = GothamState::default();
+ state.put(MyStruct { value: 100 });
+ assert!(state.try_borrow::<MyStruct>().is_some());
+ assert_eq!(state.try_borrow::<MyStruct>().unwrap().value, 100);
+ assert!(state.try_borrow::<AnotherStruct>().is_none());
+ }
+
+ #[test]
+ fn try_borrow_mut() {
+ let mut state = GothamState::default();
+ state.put(MyStruct { value: 100 });
+ if let Some(a) = state.try_borrow_mut::<MyStruct>() {
+ a.value += 10;
+ }
+ assert_eq!(state.borrow::<MyStruct>().value, 110);
+ }
+
+ #[test]
+ fn borrow_mut() {
+ let mut state = GothamState::default();
+ state.put(MyStruct { value: 100 });
+ {
+ let a = state.borrow_mut::<MyStruct>();
+ a.value += 10;
+ }
+ assert_eq!(state.borrow::<MyStruct>().value, 110);
+ assert!(state.try_borrow_mut::<AnotherStruct>().is_none());
+ }
+
+ #[test]
+ fn try_take() {
+ let mut state = GothamState::default();
+ state.put(MyStruct { value: 100 });
+ assert_eq!(state.try_take::<MyStruct>().unwrap().value, 100);
+ assert!(state.try_take::<MyStruct>().is_none());
+ assert!(state.try_borrow_mut::<MyStruct>().is_none());
+ assert!(state.try_borrow::<MyStruct>().is_none());
+ assert!(state.try_take::<AnotherStruct>().is_none());
+ }
+
+ #[test]
+ fn take() {
+ let mut state = GothamState::default();
+ state.put(MyStruct { value: 110 });
+ assert_eq!(state.take::<MyStruct>().value, 110);
+ assert!(state.try_take::<MyStruct>().is_none());
+ assert!(state.try_borrow_mut::<MyStruct>().is_none());
+ assert!(state.try_borrow::<MyStruct>().is_none());
+ }
+}
diff --git a/core/lib.rs b/core/lib.rs
index b27419ff5..450b7378a 100644
--- a/core/lib.rs
+++ b/core/lib.rs
@@ -8,10 +8,10 @@ extern crate lazy_static;
#[macro_use]
extern crate log;
-mod basic_state;
mod bindings;
mod errors;
mod flags;
+mod gotham_state;
mod module_specifier;
mod modules;
mod normalize_path;
@@ -24,7 +24,6 @@ mod zero_copy_buf;
pub use rusty_v8 as v8;
-pub use crate::basic_state::BasicState;
pub use crate::errors::AnyError;
pub use crate::errors::ErrBox;
pub use crate::errors::JsError;
@@ -38,12 +37,13 @@ pub use crate::modules::ModuleSource;
pub use crate::modules::ModuleSourceFuture;
pub use crate::modules::RecursiveModuleLoad;
pub use crate::normalize_path::normalize_path;
+pub use crate::ops::json_op_async;
+pub use crate::ops::json_op_sync;
pub use crate::ops::Op;
pub use crate::ops::OpAsyncFuture;
pub use crate::ops::OpFn;
pub use crate::ops::OpId;
-pub use crate::ops::OpRegistry;
-pub use crate::ops::OpRouter;
+pub use crate::ops::OpState;
pub use crate::ops::OpTable;
pub use crate::resources::ResourceTable;
pub use crate::runtime::js_check;
diff --git a/core/modules.rs b/core/modules.rs
index 3caeab7b1..57068528d 100644
--- a/core/modules.rs
+++ b/core/modules.rs
@@ -441,7 +441,6 @@ impl Modules {
mod tests {
use super::*;
use crate::js_check;
- use crate::BasicState;
use crate::JsRuntime;
use crate::StartupData;
use futures::future::FutureExt;
@@ -620,12 +619,8 @@ mod tests {
fn test_recursive_load() {
let loader = MockLoader::new();
let loads = loader.loads.clone();
- let mut runtime = JsRuntime::new_with_loader(
- loader,
- BasicState::new(),
- StartupData::None,
- false,
- );
+ let mut runtime =
+ JsRuntime::new_with_loader(loader, StartupData::None, false);
let spec = ModuleSpecifier::resolve_url("file:///a.js").unwrap();
let a_id_fut = runtime.load_module(&spec, None);
let a_id = futures::executor::block_on(a_id_fut).expect("Failed to load");
@@ -687,12 +682,8 @@ mod tests {
fn test_circular_load() {
let loader = MockLoader::new();
let loads = loader.loads.clone();
- let mut runtime = JsRuntime::new_with_loader(
- loader,
- BasicState::new(),
- StartupData::None,
- false,
- );
+ let mut runtime =
+ JsRuntime::new_with_loader(loader, StartupData::None, false);
let fut = async move {
let spec = ModuleSpecifier::resolve_url("file:///circular1.js").unwrap();
@@ -765,12 +756,8 @@ mod tests {
fn test_redirect_load() {
let loader = MockLoader::new();
let loads = loader.loads.clone();
- let mut runtime = JsRuntime::new_with_loader(
- loader,
- BasicState::new(),
- StartupData::None,
- false,
- );
+ let mut runtime =
+ JsRuntime::new_with_loader(loader, StartupData::None, false);
let fut = async move {
let spec = ModuleSpecifier::resolve_url("file:///redirect1.js").unwrap();
@@ -834,12 +821,8 @@ mod tests {
run_in_task(|mut cx| {
let loader = MockLoader::new();
let loads = loader.loads.clone();
- let mut runtime = JsRuntime::new_with_loader(
- loader,
- BasicState::new(),
- StartupData::None,
- false,
- );
+ let mut runtime =
+ JsRuntime::new_with_loader(loader, StartupData::None, false);
let spec = ModuleSpecifier::resolve_url("file:///main.js").unwrap();
let mut recursive_load = runtime.load_module(&spec, None).boxed_local();
@@ -884,12 +867,8 @@ mod tests {
fn loader_disappears_after_error() {
run_in_task(|mut cx| {
let loader = MockLoader::new();
- let mut runtime = JsRuntime::new_with_loader(
- loader,
- BasicState::new(),
- StartupData::None,
- false,
- );
+ let mut runtime =
+ JsRuntime::new_with_loader(loader, StartupData::None, false);
let spec = ModuleSpecifier::resolve_url("file:///bad_import.js").unwrap();
let mut load_fut = runtime.load_module(&spec, None).boxed_local();
let result = load_fut.poll_unpin(&mut cx);
@@ -917,12 +896,8 @@ mod tests {
fn recursive_load_main_with_code() {
let loader = MockLoader::new();
let loads = loader.loads.clone();
- let mut runtime = JsRuntime::new_with_loader(
- loader,
- BasicState::new(),
- StartupData::None,
- false,
- );
+ let mut runtime =
+ JsRuntime::new_with_loader(loader, StartupData::None, false);
// In default resolution code should be empty.
// Instead we explicitly pass in our own code.
// The behavior should be very similar to /a.js.
diff --git a/core/ops.rs b/core/ops.rs
index 838596dc0..7af4949a1 100644
--- a/core/ops.rs
+++ b/core/ops.rs
@@ -1,13 +1,13 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
+use crate::gotham_state::GothamState;
use crate::BufVec;
use crate::ErrBox;
use crate::ZeroCopyBuf;
use futures::Future;
-use futures::FutureExt;
use indexmap::IndexMap;
-use serde_json::json;
use serde_json::Value;
+use std::cell::RefCell;
use std::collections::HashMap;
use std::iter::once;
use std::ops::Deref;
@@ -16,7 +16,7 @@ use std::pin::Pin;
use std::rc::Rc;
pub type OpAsyncFuture = Pin<Box<dyn Future<Output = Box<[u8]>>>>;
-pub type OpFn<S> = dyn Fn(Rc<S>, BufVec) -> Op + 'static;
+pub type OpFn = dyn Fn(Rc<RefCell<OpState>>, BufVec) -> Op + 'static;
pub type OpId = usize;
pub enum Op {
@@ -28,119 +28,191 @@ pub enum Op {
NotFound,
}
-pub trait OpRouter {
- fn route_op(self: Rc<Self>, op_id: OpId, bufs: BufVec) -> Op;
+pub struct OpState {
+ pub resource_table: crate::ResourceTable,
+ pub op_table: OpTable,
+ pub get_error_class_fn: crate::runtime::GetErrorClassFn,
+ gotham_state: GothamState,
}
-pub trait OpRegistry: OpRouter + 'static {
- fn get_op_catalog(self: Rc<Self>) -> HashMap<String, OpId>;
-
- fn register_op<F>(&self, name: &str, op_fn: F) -> OpId
- where
- F: Fn(Rc<Self>, BufVec) -> Op + 'static;
-
- fn register_op_json_sync<F>(self: &Rc<Self>, name: &str, op_fn: F) -> OpId
- where
- F: Fn(&Self, Value, &mut [ZeroCopyBuf]) -> Result<Value, ErrBox> + 'static,
- {
- let base_op_fn = move |state: Rc<Self>, mut bufs: BufVec| -> Op {
- let result = serde_json::from_slice(&bufs[0])
- .map_err(ErrBox::from)
- .and_then(|args| op_fn(&state, args, &mut bufs[1..]));
- let buf = state.json_serialize_op_result(None, result);
- Op::Sync(buf)
- };
-
- self.register_op(name, base_op_fn)
+impl Default for OpState {
+ // TODO(ry) Only deno_core should be able to construct an OpState. But I don't
+ // know how to make default private. Maybe rename to
+ // pub(crate) fn new() -> OpState
+ fn default() -> OpState {
+ OpState {
+ resource_table: crate::ResourceTable::default(),
+ op_table: OpTable::default(),
+ get_error_class_fn: &|_| "Error",
+ gotham_state: GothamState::default(),
+ }
}
+}
- fn register_op_json_async<F, R>(self: &Rc<Self>, name: &str, op_fn: F) -> OpId
- where
- F: Fn(Rc<Self>, Value, BufVec) -> R + 'static,
- R: Future<Output = Result<Value, ErrBox>> + 'static,
- {
- let try_dispatch_op = move |state: Rc<Self>,
- bufs: BufVec|
- -> Result<Op, ErrBox> {
- let args: Value = serde_json::from_slice(&bufs[0])?;
- let promise_id = args
- .get("promiseId")
- .and_then(Value::as_u64)
- .ok_or_else(|| ErrBox::type_error("missing or invalid `promiseId`"))?;
- let bufs = bufs[1..].into();
- let fut = op_fn(state.clone(), args, bufs).map(move |result| {
- state.json_serialize_op_result(Some(promise_id), result)
- });
- Ok(Op::Async(Box::pin(fut)))
- };
-
- let base_op_fn = move |state: Rc<Self>, bufs: BufVec| -> Op {
- match try_dispatch_op(state.clone(), bufs) {
- Ok(op) => op,
- Err(err) => Op::Sync(state.json_serialize_op_result(None, Err(err))),
- }
- };
-
- self.register_op(name, base_op_fn)
- }
+impl Deref for OpState {
+ type Target = GothamState;
- fn json_serialize_op_result(
- &self,
- promise_id: Option<u64>,
- result: Result<Value, ErrBox>,
- ) -> Box<[u8]> {
- let value = match result {
- Ok(v) => json!({ "ok": v, "promiseId": promise_id }),
- Err(err) => json!({
- "promiseId": promise_id ,
- "err": {
- "className": self.get_error_class_name(&err),
- "message": err.to_string(),
- }
- }),
- };
- serde_json::to_vec(&value).unwrap().into_boxed_slice()
+ fn deref(&self) -> &Self::Target {
+ &self.gotham_state
}
+}
- fn get_error_class_name(&self, _err: &ErrBox) -> &'static str {
- "Error"
+impl DerefMut for OpState {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.gotham_state
}
}
/// Collection for storing registered ops. The special 'get_op_catalog'
/// op with OpId `0` is automatically added when the OpTable is created.
-pub struct OpTable<S>(IndexMap<String, Rc<OpFn<S>>>);
+pub struct OpTable(IndexMap<String, Rc<OpFn>>);
-impl<S: OpRegistry> OpTable<S> {
- pub fn get_op_catalog(&self) -> HashMap<String, OpId> {
- self.keys().cloned().zip(0..).collect()
+impl OpTable {
+ pub fn register_op<F>(&mut self, name: &str, op_fn: F) -> OpId
+ where
+ F: Fn(Rc<RefCell<OpState>>, BufVec) -> Op + 'static,
+ {
+ let (op_id, prev) = self.0.insert_full(name.to_owned(), Rc::new(op_fn));
+ assert!(prev.is_none());
+ op_id
}
- fn op_get_op_catalog(state: Rc<S>, _bufs: BufVec) -> Op {
- let ops = state.get_op_catalog();
- let buf = serde_json::to_vec(&ops).map(Into::into).unwrap();
- Op::Sync(buf)
+ pub fn route_op(
+ op_id: OpId,
+ state: Rc<RefCell<OpState>>,
+ bufs: BufVec,
+ ) -> Op {
+ if op_id == 0 {
+ let ops: HashMap<String, OpId> =
+ state.borrow().op_table.0.keys().cloned().zip(0..).collect();
+ let buf = serde_json::to_vec(&ops).map(Into::into).unwrap();
+ Op::Sync(buf)
+ } else {
+ let op_fn = state
+ .borrow()
+ .op_table
+ .0
+ .get_index(op_id)
+ .map(|(_, op_fn)| op_fn.clone());
+ match op_fn {
+ Some(f) => (f)(state, bufs),
+ None => Op::NotFound,
+ }
+ }
}
}
-impl<S: OpRegistry> Default for OpTable<S> {
+impl Default for OpTable {
fn default() -> Self {
- Self(
- once(("ops".to_owned(), Rc::new(Self::op_get_op_catalog) as _)).collect(),
- )
+ fn dummy(_state: Rc<RefCell<OpState>>, _bufs: BufVec) -> Op {
+ unreachable!()
+ }
+ Self(once(("ops".to_owned(), Rc::new(dummy) as _)).collect())
}
}
-impl<S> Deref for OpTable<S> {
- type Target = IndexMap<String, Rc<OpFn<S>>>;
+#[test]
+fn op_table() {
+ let state = Rc::new(RefCell::new(OpState::default()));
- fn deref(&self) -> &Self::Target {
- &self.0
+ let foo_id;
+ let bar_id;
+ {
+ let op_table = &mut state.borrow_mut().op_table;
+ foo_id = op_table.register_op("foo", |_, _| Op::Sync(b"oof!"[..].into()));
+ assert_eq!(foo_id, 1);
+ bar_id = op_table.register_op("bar", |_, _| Op::Sync(b"rab!"[..].into()));
+ assert_eq!(bar_id, 2);
}
+
+ let foo_res = OpTable::route_op(foo_id, state.clone(), Default::default());
+ assert!(matches!(foo_res, Op::Sync(buf) if &*buf == b"oof!"));
+ let bar_res = OpTable::route_op(bar_id, state.clone(), Default::default());
+ assert!(matches!(bar_res, Op::Sync(buf) if &*buf == b"rab!"));
+
+ let catalog_res = OpTable::route_op(0, state, Default::default());
+ let mut catalog_entries = match catalog_res {
+ Op::Sync(buf) => serde_json::from_slice::<HashMap<String, OpId>>(&buf)
+ .map(|map| map.into_iter().collect::<Vec<_>>())
+ .unwrap(),
+ _ => panic!("unexpected `Op` variant"),
+ };
+ catalog_entries.sort_by(|(_, id1), (_, id2)| id1.partial_cmp(id2).unwrap());
+ assert_eq!(
+ catalog_entries,
+ vec![
+ ("ops".to_owned(), 0),
+ ("foo".to_owned(), 1),
+ ("bar".to_owned(), 2)
+ ]
+ )
}
-impl<S> DerefMut for OpTable<S> {
- fn deref_mut(&mut self) -> &mut Self::Target {
- &mut self.0
- }
+pub fn json_op_sync<F>(op_fn: F) -> Box<OpFn>
+where
+ F: Fn(&mut OpState, Value, &mut [ZeroCopyBuf]) -> Result<Value, ErrBox>
+ + 'static,
+{
+ Box::new(move |state: Rc<RefCell<OpState>>, mut bufs: BufVec| -> Op {
+ let result = serde_json::from_slice(&bufs[0])
+ .map_err(crate::ErrBox::from)
+ .and_then(|args| op_fn(&mut state.borrow_mut(), args, &mut bufs[1..]));
+ let buf =
+ json_serialize_op_result(None, result, state.borrow().get_error_class_fn);
+ Op::Sync(buf)
+ })
+}
+
+pub fn json_op_async<F, R>(op_fn: F) -> Box<OpFn>
+where
+ F: Fn(Rc<RefCell<OpState>>, Value, BufVec) -> R + 'static,
+ R: Future<Output = Result<Value, ErrBox>> + 'static,
+{
+ let try_dispatch_op =
+ move |state: Rc<RefCell<OpState>>, bufs: BufVec| -> Result<Op, ErrBox> {
+ let args: Value = serde_json::from_slice(&bufs[0])?;
+ let promise_id = args
+ .get("promiseId")
+ .and_then(Value::as_u64)
+ .ok_or_else(|| ErrBox::type_error("missing or invalid `promiseId`"))?;
+ let bufs = bufs[1..].into();
+ use crate::futures::FutureExt;
+ let fut = op_fn(state.clone(), args, bufs).map(move |result| {
+ json_serialize_op_result(
+ Some(promise_id),
+ result,
+ state.borrow().get_error_class_fn,
+ )
+ });
+ Ok(Op::Async(Box::pin(fut)))
+ };
+
+ Box::new(move |state: Rc<RefCell<OpState>>, bufs: BufVec| -> Op {
+ match try_dispatch_op(state.clone(), bufs) {
+ Ok(op) => op,
+ Err(err) => Op::Sync(json_serialize_op_result(
+ None,
+ Err(err),
+ state.borrow().get_error_class_fn,
+ )),
+ }
+ })
+}
+
+fn json_serialize_op_result(
+ promise_id: Option<u64>,
+ result: Result<serde_json::Value, crate::ErrBox>,
+ get_error_class_fn: crate::runtime::GetErrorClassFn,
+) -> Box<[u8]> {
+ let value = match result {
+ Ok(v) => serde_json::json!({ "ok": v, "promiseId": promise_id }),
+ Err(err) => serde_json::json!({
+ "promiseId": promise_id ,
+ "err": {
+ "className": (get_error_class_fn)(&err),
+ "message": err.to_string(),
+ }
+ }),
+ };
+ serde_json::to_vec(&value).unwrap().into_boxed_slice()
}
diff --git a/core/runtime.rs b/core/runtime.rs
index 2f574b195..e6fc23084 100644
--- a/core/runtime.rs
+++ b/core/runtime.rs
@@ -19,9 +19,10 @@ use crate::modules::RecursiveModuleLoad;
use crate::ops::*;
use crate::shared_queue::SharedQueue;
use crate::shared_queue::RECOMMENDED_SIZE;
+use crate::BufVec;
use crate::ErrBox;
use crate::JsError;
-use crate::OpRouter;
+use crate::OpState;
use futures::stream::FuturesUnordered;
use futures::stream::StreamExt;
use futures::stream::StreamFuture;
@@ -94,7 +95,7 @@ impl StartupData<'_> {
type JsErrorCreateFn = dyn Fn(JsError) -> ErrBox;
-pub type GetErrorClassFn = dyn for<'e> Fn(&'e ErrBox) -> &'static str;
+pub type GetErrorClassFn = &'static dyn for<'e> Fn(&'e ErrBox) -> &'static str;
/// Objects that need to live as long as the isolate
#[derive(Default)]
@@ -137,7 +138,8 @@ pub struct JsRuntimeState {
pub(crate) pending_ops: FuturesUnordered<PendingOpFuture>,
pub(crate) pending_unref_ops: FuturesUnordered<PendingOpFuture>,
pub(crate) have_unpolled_ops: Cell<bool>,
- pub(crate) op_router: Rc<dyn OpRouter>,
+ //pub(crate) op_table: OpTable,
+ pub(crate) op_state: Rc<RefCell<OpState>>,
loader: Rc<dyn ModuleLoader>,
pub modules: Modules,
pub(crate) dyn_import_map:
@@ -219,7 +221,6 @@ pub struct HeapLimits {
pub(crate) struct IsolateOptions {
loader: Rc<dyn ModuleLoader>,
- op_router: Rc<dyn OpRouter>,
startup_script: Option<OwnedScript>,
startup_snapshot: Option<Snapshot>,
will_snapshot: bool,
@@ -229,15 +230,10 @@ pub(crate) struct IsolateOptions {
impl JsRuntime {
/// startup_data defines the snapshot or script used at startup to initialize
/// the isolate.
- pub fn new(
- op_router: Rc<dyn OpRouter>,
- startup_data: StartupData,
- will_snapshot: bool,
- ) -> Self {
+ pub fn new(startup_data: StartupData, will_snapshot: bool) -> Self {
let (startup_script, startup_snapshot) = startup_data.into_options();
let options = IsolateOptions {
loader: Rc::new(NoopModuleLoader),
- op_router,
startup_script,
startup_snapshot,
will_snapshot,
@@ -251,14 +247,12 @@ impl JsRuntime {
/// Create new isolate that can load and execute ESModules.
pub fn new_with_loader(
loader: Rc<dyn ModuleLoader>,
- op_router: Rc<dyn OpRouter>,
startup_data: StartupData,
will_snapshot: bool,
) -> Self {
let (startup_script, startup_snapshot) = startup_data.into_options();
let options = IsolateOptions {
loader,
- op_router,
startup_script,
startup_snapshot,
will_snapshot,
@@ -275,14 +269,12 @@ impl JsRuntime {
/// Make sure to use [`add_near_heap_limit_callback`](#method.add_near_heap_limit_callback)
/// to prevent v8 from crashing when reaching the upper limit.
pub fn with_heap_limits(
- op_router: Rc<dyn OpRouter>,
startup_data: StartupData,
heap_limits: HeapLimits,
) -> Self {
let (startup_script, startup_snapshot) = startup_data.into_options();
let options = IsolateOptions {
loader: Rc::new(NoopModuleLoader),
- op_router,
startup_script,
startup_snapshot,
will_snapshot: false,
@@ -347,6 +339,8 @@ impl JsRuntime {
(isolate, None)
};
+ let op_state = OpState::default();
+
isolate.set_slot(Rc::new(RefCell::new(JsRuntimeState {
global_context: Some(global_context),
pending_promise_exceptions: HashMap::new(),
@@ -357,8 +351,8 @@ impl JsRuntime {
shared: SharedQueue::new(RECOMMENDED_SIZE),
pending_ops: FuturesUnordered::new(),
pending_unref_ops: FuturesUnordered::new(),
+ op_state: Rc::new(RefCell::new(op_state)),
have_unpolled_ops: Cell::new(false),
- op_router: options.op_router,
modules: Modules::new(),
loader: options.loader,
dyn_import_map: HashMap::new(),
@@ -406,6 +400,12 @@ impl JsRuntime {
}
}
+ pub fn op_state(&mut self) -> Rc<RefCell<OpState>> {
+ let state_rc = Self::state(self);
+ let state = state_rc.borrow();
+ state.op_state.clone()
+ }
+
/// Executes traditional JavaScript code (traditional = not ES modules)
///
/// ErrBox can be downcast to a type that exposes additional information about
@@ -477,6 +477,18 @@ impl JsRuntime {
snapshot
}
+ pub fn register_op<F>(&mut self, name: &str, op_fn: F) -> OpId
+ where
+ F: Fn(Rc<RefCell<OpState>>, BufVec) -> Op + 'static,
+ {
+ Self::state(self)
+ .borrow_mut()
+ .op_state
+ .borrow_mut()
+ .op_table
+ .register_op(name, op_fn)
+ }
+
/// Registers a callback on the isolate when the memory limits are approached.
/// Use this to prevent V8 from crashing the process when reaching the limit.
///
@@ -1283,8 +1295,6 @@ impl JsRuntime {
pub mod tests {
use super::*;
use crate::modules::ModuleSourceFuture;
- use crate::ops::*;
- use crate::BasicState;
use crate::BufVec;
use futures::future::lazy;
use futures::FutureExt;
@@ -1328,89 +1338,89 @@ pub mod tests {
OverflowResAsync,
}
- struct TestOpRouter {
+ struct TestState {
mode: Mode,
dispatch_count: Arc<AtomicUsize>,
}
- impl OpRouter for TestOpRouter {
- fn route_op(self: Rc<Self>, op_id: OpId, bufs: BufVec) -> Op {
- if op_id != 1 {
- return Op::NotFound;
+ fn dispatch(op_state: Rc<RefCell<OpState>>, bufs: BufVec) -> Op {
+ let op_state_ = op_state.borrow();
+ let test_state = op_state_.borrow::<TestState>();
+ test_state.dispatch_count.fetch_add(1, Ordering::Relaxed);
+ match test_state.mode {
+ Mode::Async => {
+ assert_eq!(bufs.len(), 1);
+ assert_eq!(bufs[0].len(), 1);
+ assert_eq!(bufs[0][0], 42);
+ let buf = vec![43u8].into_boxed_slice();
+ Op::Async(futures::future::ready(buf).boxed())
}
- self.dispatch_count.fetch_add(1, Ordering::Relaxed);
- match self.mode {
- Mode::Async => {
- assert_eq!(bufs.len(), 1);
- assert_eq!(bufs[0].len(), 1);
- assert_eq!(bufs[0][0], 42);
- let buf = vec![43u8].into_boxed_slice();
- Op::Async(futures::future::ready(buf).boxed())
- }
- Mode::AsyncUnref => {
- assert_eq!(bufs.len(), 1);
- assert_eq!(bufs[0].len(), 1);
- assert_eq!(bufs[0][0], 42);
- let fut = async {
- // This future never finish.
- futures::future::pending::<()>().await;
- vec![43u8].into_boxed_slice()
- };
- Op::AsyncUnref(fut.boxed())
- }
- Mode::AsyncZeroCopy(count) => {
- assert_eq!(bufs.len(), count as usize);
- bufs.iter().enumerate().for_each(|(idx, buf)| {
- assert_eq!(buf.len(), 1);
- assert_eq!(idx, buf[0] as usize);
- });
-
- let buf = vec![43u8].into_boxed_slice();
- Op::Async(futures::future::ready(buf).boxed())
- }
- Mode::OverflowReqSync => {
- assert_eq!(bufs.len(), 1);
- assert_eq!(bufs[0].len(), 100 * 1024 * 1024);
- let buf = vec![43u8].into_boxed_slice();
- Op::Sync(buf)
- }
- Mode::OverflowResSync => {
- assert_eq!(bufs.len(), 1);
- assert_eq!(bufs[0].len(), 1);
- assert_eq!(bufs[0][0], 42);
- let mut vec = Vec::<u8>::new();
- vec.resize(100 * 1024 * 1024, 0);
- vec[0] = 99;
- let buf = vec.into_boxed_slice();
- Op::Sync(buf)
- }
- Mode::OverflowReqAsync => {
- assert_eq!(bufs.len(), 1);
- assert_eq!(bufs[0].len(), 100 * 1024 * 1024);
- let buf = vec![43u8].into_boxed_slice();
- Op::Async(futures::future::ready(buf).boxed())
- }
- Mode::OverflowResAsync => {
- assert_eq!(bufs.len(), 1);
- assert_eq!(bufs[0].len(), 1);
- assert_eq!(bufs[0][0], 42);
- let mut vec = Vec::<u8>::new();
- vec.resize(100 * 1024 * 1024, 0);
- vec[0] = 4;
- let buf = vec.into_boxed_slice();
- Op::Async(futures::future::ready(buf).boxed())
- }
+ Mode::AsyncUnref => {
+ assert_eq!(bufs.len(), 1);
+ assert_eq!(bufs[0].len(), 1);
+ assert_eq!(bufs[0][0], 42);
+ let fut = async {
+ // This future never finish.
+ futures::future::pending::<()>().await;
+ vec![43u8].into_boxed_slice()
+ };
+ Op::AsyncUnref(fut.boxed())
+ }
+ Mode::AsyncZeroCopy(count) => {
+ assert_eq!(bufs.len(), count as usize);
+ bufs.iter().enumerate().for_each(|(idx, buf)| {
+ assert_eq!(buf.len(), 1);
+ assert_eq!(idx, buf[0] as usize);
+ });
+
+ let buf = vec![43u8].into_boxed_slice();
+ Op::Async(futures::future::ready(buf).boxed())
+ }
+ Mode::OverflowReqSync => {
+ assert_eq!(bufs.len(), 1);
+ assert_eq!(bufs[0].len(), 100 * 1024 * 1024);
+ let buf = vec![43u8].into_boxed_slice();
+ Op::Sync(buf)
+ }
+ Mode::OverflowResSync => {
+ assert_eq!(bufs.len(), 1);
+ assert_eq!(bufs[0].len(), 1);
+ assert_eq!(bufs[0][0], 42);
+ let mut vec = Vec::<u8>::new();
+ vec.resize(100 * 1024 * 1024, 0);
+ vec[0] = 99;
+ let buf = vec.into_boxed_slice();
+ Op::Sync(buf)
+ }
+ Mode::OverflowReqAsync => {
+ assert_eq!(bufs.len(), 1);
+ assert_eq!(bufs[0].len(), 100 * 1024 * 1024);
+ let buf = vec![43u8].into_boxed_slice();
+ Op::Async(futures::future::ready(buf).boxed())
+ }
+ Mode::OverflowResAsync => {
+ assert_eq!(bufs.len(), 1);
+ assert_eq!(bufs[0].len(), 1);
+ assert_eq!(bufs[0][0], 42);
+ let mut vec = Vec::<u8>::new();
+ vec.resize(100 * 1024 * 1024, 0);
+ vec[0] = 4;
+ let buf = vec.into_boxed_slice();
+ Op::Async(futures::future::ready(buf).boxed())
}
}
}
fn setup(mode: Mode) -> (JsRuntime, Arc<AtomicUsize>) {
let dispatch_count = Arc::new(AtomicUsize::new(0));
- let test_state = Rc::new(TestOpRouter {
+ let mut runtime = JsRuntime::new(StartupData::None, false);
+ let op_state = runtime.op_state();
+ op_state.borrow_mut().put(TestState {
mode,
dispatch_count: dispatch_count.clone(),
});
- let mut runtime = JsRuntime::new(test_state, StartupData::None, false);
+
+ runtime.register_op("test", dispatch);
js_check(runtime.execute(
"setup.js",
@@ -1774,8 +1784,7 @@ pub mod tests {
#[test]
fn syntax_error() {
- let mut runtime =
- JsRuntime::new(BasicState::new(), StartupData::None, false);
+ let mut runtime = JsRuntime::new(StartupData::None, false);
let src = "hocuspocus(";
let r = runtime.execute("i.js", src);
let e = r.unwrap_err();
@@ -1800,29 +1809,27 @@ pub mod tests {
#[test]
fn will_snapshot() {
let snapshot = {
- let mut runtime =
- JsRuntime::new(BasicState::new(), StartupData::None, true);
+ let mut runtime = JsRuntime::new(StartupData::None, true);
js_check(runtime.execute("a.js", "a = 1 + 2"));
runtime.snapshot()
};
let startup_data = StartupData::Snapshot(Snapshot::JustCreated(snapshot));
- let mut runtime2 = JsRuntime::new(BasicState::new(), startup_data, false);
+ let mut runtime2 = JsRuntime::new(startup_data, false);
js_check(runtime2.execute("check.js", "if (a != 3) throw Error('x')"));
}
#[test]
fn test_from_boxed_snapshot() {
let snapshot = {
- let mut runtime =
- JsRuntime::new(BasicState::new(), StartupData::None, true);
+ let mut runtime = JsRuntime::new(StartupData::None, true);
js_check(runtime.execute("a.js", "a = 1 + 2"));
let snap: &[u8] = &*runtime.snapshot();
Vec::from(snap).into_boxed_slice()
};
let startup_data = StartupData::Snapshot(Snapshot::Boxed(snapshot));
- let mut runtime2 = JsRuntime::new(BasicState::new(), startup_data, false);
+ let mut runtime2 = JsRuntime::new(startup_data, false);
js_check(runtime2.execute("check.js", "if (a != 3) throw Error('x')"));
}
@@ -1832,11 +1839,8 @@ pub mod tests {
initial: 0,
max: 20 * 1024, // 20 kB
};
- let mut runtime = JsRuntime::with_heap_limits(
- BasicState::new(),
- StartupData::None,
- heap_limits,
- );
+ let mut runtime =
+ JsRuntime::with_heap_limits(StartupData::None, heap_limits);
let cb_handle = runtime.thread_safe_handle();
let callback_invoke_count = Rc::new(AtomicUsize::default());
@@ -1864,8 +1868,7 @@ pub mod tests {
#[test]
fn test_heap_limit_cb_remove() {
- let mut runtime =
- JsRuntime::new(BasicState::new(), StartupData::None, false);
+ let mut runtime = JsRuntime::new(StartupData::None, false);
runtime.add_near_heap_limit_callback(|current_limit, _initial_limit| {
current_limit * 2
@@ -1880,11 +1883,8 @@ pub mod tests {
initial: 0,
max: 20 * 1024, // 20 kB
};
- let mut runtime = JsRuntime::with_heap_limits(
- BasicState::new(),
- StartupData::None,
- heap_limits,
- );
+ let mut runtime =
+ JsRuntime::with_heap_limits(StartupData::None, heap_limits);
let cb_handle = runtime.thread_safe_handle();
let callback_invoke_count_first = Rc::new(AtomicUsize::default());
@@ -1952,13 +1952,12 @@ pub mod tests {
}
let loader = Rc::new(ModsLoader::default());
- let state = BasicState::new();
let resolve_count = loader.count.clone();
let dispatch_count = Arc::new(AtomicUsize::new(0));
let dispatch_count_ = dispatch_count.clone();
- let dispatcher = move |_state: Rc<BasicState>, bufs: BufVec| -> Op {
+ let dispatcher = move |_state: Rc<RefCell<OpState>>, bufs: BufVec| -> Op {
dispatch_count_.fetch_add(1, Ordering::Relaxed);
assert_eq!(bufs.len(), 1);
assert_eq!(bufs[0].len(), 1);
@@ -1966,10 +1965,10 @@ pub mod tests {
let buf = [43u8, 0, 0, 0][..].into();
Op::Async(futures::future::ready(buf).boxed())
};
- state.register_op("test", dispatcher);
let mut runtime =
- JsRuntime::new_with_loader(loader, state, StartupData::None, false);
+ JsRuntime::new_with_loader(loader, StartupData::None, false);
+ runtime.register_op("test", dispatcher);
js_check(runtime.execute(
"setup.js",
@@ -2063,12 +2062,8 @@ pub mod tests {
run_in_task(|cx| {
let loader = Rc::new(DynImportErrLoader::default());
let count = loader.count.clone();
- let mut runtime = JsRuntime::new_with_loader(
- loader,
- BasicState::new(),
- StartupData::None,
- false,
- );
+ let mut runtime =
+ JsRuntime::new_with_loader(loader, StartupData::None, false);
js_check(runtime.execute(
"file:///dyn_import2.js",
@@ -2145,12 +2140,8 @@ pub mod tests {
let prepare_load_count = loader.prepare_load_count.clone();
let resolve_count = loader.resolve_count.clone();
let load_count = loader.load_count.clone();
- let mut runtime = JsRuntime::new_with_loader(
- loader,
- BasicState::new(),
- StartupData::None,
- false,
- );
+ let mut runtime =
+ JsRuntime::new_with_loader(loader, StartupData::None, false);
// Dynamically import mod_b
js_check(runtime.execute(
@@ -2190,12 +2181,8 @@ pub mod tests {
run_in_task(|cx| {
let loader = Rc::new(DynImportOkLoader::default());
let prepare_load_count = loader.prepare_load_count.clone();
- let mut runtime = JsRuntime::new_with_loader(
- loader,
- BasicState::new(),
- StartupData::None,
- false,
- );
+ let mut runtime =
+ JsRuntime::new_with_loader(loader, StartupData::None, false);
js_check(runtime.execute(
"file:///dyn_import3.js",
r#"
@@ -2246,12 +2233,8 @@ pub mod tests {
}
let loader = std::rc::Rc::new(ModsLoader::default());
- let mut runtime = JsRuntime::new_with_loader(
- loader,
- BasicState::new(),
- StartupData::None,
- true,
- );
+ let mut runtime =
+ JsRuntime::new_with_loader(loader, StartupData::None, true);
let specifier = ModuleSpecifier::resolve_url("file:///main.js").unwrap();
let source_code = "Deno.core.print('hello\\n')".to_string();
diff --git a/op_crates/web/lib.rs b/op_crates/web/lib.rs
index f98dfe7c4..03107524a 100644
--- a/op_crates/web/lib.rs
+++ b/op_crates/web/lib.rs
@@ -33,7 +33,6 @@ pub fn get_declaration() -> PathBuf {
#[cfg(test)]
mod tests {
use deno_core::js_check;
- use deno_core::BasicState;
use deno_core::JsRuntime;
use deno_core::StartupData;
use futures::future::lazy;
@@ -49,8 +48,7 @@ mod tests {
}
fn setup() -> JsRuntime {
- let mut isolate =
- JsRuntime::new(BasicState::new(), StartupData::None, false);
+ let mut isolate = JsRuntime::new(StartupData::None, false);
crate::init(&mut isolate);
isolate
}