diff options
Diffstat (limited to 'cli/ops')
-rw-r--r-- | cli/ops/compiler.rs | 32 | ||||
-rw-r--r-- | cli/ops/dispatch_minimal.rs | 134 | ||||
-rw-r--r-- | cli/ops/errors.rs | 16 | ||||
-rw-r--r-- | cli/ops/fetch.rs | 29 | ||||
-rw-r--r-- | cli/ops/fs.rs | 440 | ||||
-rw-r--r-- | cli/ops/fs_events.rs | 26 | ||||
-rw-r--r-- | cli/ops/idna.rs | 9 | ||||
-rw-r--r-- | cli/ops/io.rs | 40 | ||||
-rw-r--r-- | cli/ops/mod.rs | 40 | ||||
-rw-r--r-- | cli/ops/net.rs | 117 | ||||
-rw-r--r-- | cli/ops/net_unix.rs | 52 | ||||
-rw-r--r-- | cli/ops/os.rs | 81 | ||||
-rw-r--r-- | cli/ops/permissions.rs | 27 | ||||
-rw-r--r-- | cli/ops/plugin.rs | 65 | ||||
-rw-r--r-- | cli/ops/process.rs | 46 | ||||
-rw-r--r-- | cli/ops/random.rs | 14 | ||||
-rw-r--r-- | cli/ops/repl.rs | 39 | ||||
-rw-r--r-- | cli/ops/resources.rs | 18 | ||||
-rw-r--r-- | cli/ops/runtime.rs | 28 | ||||
-rw-r--r-- | cli/ops/runtime_compiler.rs | 28 | ||||
-rw-r--r-- | cli/ops/signal.rs | 42 | ||||
-rw-r--r-- | cli/ops/timers.rs | 40 | ||||
-rw-r--r-- | cli/ops/tls.rs | 107 | ||||
-rw-r--r-- | cli/ops/tty.rs | 33 | ||||
-rw-r--r-- | cli/ops/web_worker.rs | 15 | ||||
-rw-r--r-- | cli/ops/websocket.rs | 48 | ||||
-rw-r--r-- | cli/ops/worker_host.rs | 89 |
27 files changed, 910 insertions, 745 deletions
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(¤t_dir()?, "CWD")?; + cli_state.check_read_blind(¤t_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(¤t_dir()?, "CWD")?; + cli_state.check_read_blind(¤t_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(¤t_exe, "exec_path")?; + let cli_state = super::cli_state(state); + cli_state.check_read_blind(¤t_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!({})) |