diff --git a/cli/cli_behavior.rs b/cli/cli_behavior.rs new file mode 100644 index 0000000000..f1bd5a5558 --- /dev/null +++ b/cli/cli_behavior.rs @@ -0,0 +1,57 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +use crate::isolate_state::*; +use crate::ops; +use deno_core::deno_buf; +use deno_core::deno_mod; +use deno_core::Behavior; +use deno_core::Op; +use deno_core::StartupData; +use std::sync::Arc; + +/// Implements deno_core::Behavior for the main Deno command-line. +pub struct CliBehavior { + startup_data: Option, + pub state: Arc, +} + +impl CliBehavior { + pub fn new( + startup_data: Option, + state: Arc, + ) -> Self { + Self { + startup_data, + state, + } + } +} + +impl IsolateStateContainer for &CliBehavior { + fn state(&self) -> Arc { + self.state.clone() + } +} + +impl IsolateStateContainer for CliBehavior { + fn state(&self) -> Arc { + self.state.clone() + } +} + +impl Behavior for CliBehavior { + fn startup_data(&mut self) -> Option { + self.startup_data.take() + } + + fn resolve(&mut self, specifier: &str, referrer: deno_mod) -> deno_mod { + self.state_resolve(specifier, referrer) + } + + fn dispatch( + &mut self, + control: &[u8], + zero_copy: deno_buf, + ) -> (bool, Box) { + ops::dispatch_all(Box::new(self), control, zero_copy, ops::op_selector_std) + } +} diff --git a/cli/compiler.rs b/cli/compiler.rs index ec02b62f84..17006b2b92 100644 --- a/cli/compiler.rs +++ b/cli/compiler.rs @@ -1,22 +1,84 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -use crate::isolate_state::IsolateState; +use crate::isolate_state::*; use crate::msg; -use crate::permissions::{DenoPermissions, PermissionAccessor}; +use crate::ops; use crate::resources; use crate::resources::Resource; use crate::resources::ResourceId; use crate::startup_data; use crate::workers; +use crate::workers::WorkerBehavior; +use deno_core::deno_buf; +use deno_core::deno_mod; +use deno_core::Behavior; use deno_core::Buf; +use deno_core::Op; +use deno_core::StartupData; use futures::Future; use serde_json; use std::str; +use std::sync::Arc; use std::sync::Mutex; lazy_static! { static ref C_RID: Mutex> = Mutex::new(None); } +pub struct CompilerBehavior { + pub state: Arc, +} + +impl CompilerBehavior { + pub fn new(state: Arc) -> Self { + Self { state } + } +} + +impl IsolateStateContainer for CompilerBehavior { + fn state(&self) -> Arc { + self.state.clone() + } +} + +impl IsolateStateContainer for &CompilerBehavior { + fn state(&self) -> Arc { + self.state.clone() + } +} + +impl Behavior for CompilerBehavior { + fn startup_data(&mut self) -> Option { + Some(startup_data::compiler_isolate_init()) + } + + fn resolve(&mut self, specifier: &str, referrer: deno_mod) -> deno_mod { + self.state_resolve(specifier, referrer) + } + + fn dispatch( + &mut self, + control: &[u8], + zero_copy: deno_buf, + ) -> (bool, Box) { + ops::dispatch_all( + Box::new(self), + control, + zero_copy, + ops::op_selector_compiler, + ) + } +} + +impl WorkerBehavior for CompilerBehavior { + fn set_internal_channels(&mut self, worker_channels: WorkerChannels) { + self.state = Arc::new(IsolateState::new( + self.state.flags.clone(), + self.state.argv.clone(), + Some(worker_channels), + )); + } +} + // This corresponds to JS ModuleMetaData. // TODO Rename one or the other so they correspond. #[derive(Debug)] @@ -46,22 +108,16 @@ impl ModuleMetaData { } } -fn lazy_start(parent_state: &IsolateState) -> Resource { +fn lazy_start(parent_state: Arc) -> Resource { let mut cell = C_RID.lock().unwrap(); - let startup_data = startup_data::compiler_isolate_init(); - let permissions = DenoPermissions { - allow_read: PermissionAccessor::from(true), - allow_write: PermissionAccessor::from(true), - allow_net: PermissionAccessor::from(true), - ..Default::default() - }; - let rid = cell.get_or_insert_with(|| { let resource = workers::spawn( - Some(startup_data), - parent_state, + CompilerBehavior::new(Arc::new(IsolateState::new( + parent_state.flags.clone(), + parent_state.argv.clone(), + None, + ))), "compilerMain()".to_string(), - permissions, ); resource.rid }); @@ -78,7 +134,7 @@ fn req(specifier: &str, referrer: &str) -> Buf { } pub fn compile_sync( - parent_state: &IsolateState, + parent_state: Arc, specifier: &str, referrer: &str, module_meta_data: &ModuleMetaData, @@ -140,7 +196,12 @@ mod tests { maybe_source_map: None, }; - out = compile_sync(&IsolateState::mock(), specifier, &referrer, &mut out); + out = compile_sync( + Arc::new(IsolateState::mock()), + specifier, + &referrer, + &mut out, + ); assert!( out .maybe_output_code diff --git a/cli/errors.rs b/cli/errors.rs index 65118d0707..dd1b6e6a7f 100644 --- a/cli/errors.rs +++ b/cli/errors.rs @@ -179,6 +179,10 @@ pub fn permission_denied() -> DenoError { ) } +pub fn op_not_implemented() -> DenoError { + new(ErrorKind::BadResource, String::from("op not implemented")) +} + #[derive(Debug)] pub enum RustOrJsError { Rust(DenoError), diff --git a/cli/isolate.rs b/cli/isolate.rs index 379203dd3e..50cafc6c9b 100644 --- a/cli/isolate.rs +++ b/cli/isolate.rs @@ -1,33 +1,37 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -use crate::cli::Cli; use crate::compiler::compile_sync; use crate::compiler::ModuleMetaData; use crate::errors::DenoError; use crate::errors::RustOrJsError; use crate::isolate_state::IsolateState; +use crate::isolate_state::IsolateStateContainer; use crate::js_errors; use crate::msg; use deno_core; use deno_core::deno_mod; +use deno_core::Behavior; use deno_core::JSError; use futures::Async; use futures::Future; use std::sync::Arc; -type CoreIsolate = deno_core::Isolate; +pub trait DenoBehavior: Behavior + IsolateStateContainer + Send {} +impl DenoBehavior for T where T: Behavior + IsolateStateContainer + Send {} + +type CoreIsolate = deno_core::Isolate; /// Wraps deno_core::Isolate to provide source maps, ops for the CLI, and /// high-level module loading -pub struct Isolate { - inner: CoreIsolate, +pub struct Isolate { + inner: CoreIsolate, state: Arc, } -impl Isolate { - pub fn new(cli: Cli) -> Isolate { - let state = cli.state.clone(); +impl Isolate { + pub fn new(behavior: B) -> Isolate { + let state = behavior.state().clone(); Self { - inner: CoreIsolate::new(cli), + inner: CoreIsolate::new(behavior), state, } } @@ -150,7 +154,7 @@ impl Isolate { } } -impl Future for Isolate { +impl Future for Isolate { type Item = (); type Error = JSError; @@ -170,7 +174,7 @@ fn fetch_module_meta_data_and_maybe_compile( || state.flags.recompile { debug!(">>>>> compile_sync START"); - out = compile_sync(state, specifier, &referrer, &out); + out = compile_sync(state.clone(), specifier, &referrer, &out); debug!(">>>>> compile_sync END"); state.dir.code_cache(&out)?; } @@ -180,8 +184,8 @@ fn fetch_module_meta_data_and_maybe_compile( #[cfg(test)] mod tests { use super::*; + use crate::cli_behavior::CliBehavior; use crate::flags; - use crate::permissions::DenoPermissions; use crate::tokio_util; use futures::future::lazy; use std::sync::atomic::Ordering; @@ -199,7 +203,7 @@ mod tests { let state = Arc::new(IsolateState::new(flags, rest_argv, None)); let state_ = state.clone(); tokio_util::run(lazy(move || { - let cli = Cli::new(None, state.clone(), DenoPermissions::default()); + let cli = CliBehavior::new(None, state.clone()); let mut isolate = Isolate::new(cli); if let Err(err) = isolate.execute_mod(&filename, false) { eprintln!("execute_mod err {:?}", err); @@ -222,7 +226,7 @@ mod tests { let state = Arc::new(IsolateState::new(flags, rest_argv, None)); let state_ = state.clone(); tokio_util::run(lazy(move || { - let cli = Cli::new(None, state.clone(), DenoPermissions::default()); + let cli = CliBehavior::new(None, state.clone()); let mut isolate = Isolate::new(cli); if let Err(err) = isolate.execute_mod(&filename, false) { eprintln!("execute_mod err {:?}", err); diff --git a/cli/isolate_state.rs b/cli/isolate_state.rs index 8b7745f9ec..6435b2e8b9 100644 --- a/cli/isolate_state.rs +++ b/cli/isolate_state.rs @@ -1,13 +1,17 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. use crate::deno_dir; +use crate::errors::DenoResult; use crate::flags; use crate::global_timer::GlobalTimer; use crate::modules::Modules; +use crate::permissions::DenoPermissions; +use deno_core::deno_mod; use deno_core::Buf; use futures::sync::mpsc as async_mpsc; use std; use std::env; use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; use std::sync::Mutex; pub type WorkerSender = async_mpsc::Sender; @@ -33,6 +37,7 @@ pub struct Metrics { pub struct IsolateState { pub dir: deno_dir::DenoDir, pub argv: Vec, + pub permissions: DenoPermissions, pub flags: flags::DenoFlags, pub metrics: Metrics, pub modules: Mutex, @@ -52,6 +57,7 @@ impl IsolateState { dir: deno_dir::DenoDir::new(flags.reload, flags.recompile, custom_root) .unwrap(), argv: argv_rest, + permissions: DenoPermissions::from_flags(&flags), flags, metrics: Metrics::default(), modules: Mutex::new(Modules::new()), @@ -76,6 +82,31 @@ impl IsolateState { } } + #[inline] + pub fn check_read(&self, filename: &str) -> DenoResult<()> { + self.permissions.check_read(filename) + } + + #[inline] + pub fn check_write(&self, filename: &str) -> DenoResult<()> { + self.permissions.check_write(filename) + } + + #[inline] + pub fn check_env(&self) -> DenoResult<()> { + self.permissions.check_env() + } + + #[inline] + pub fn check_net(&self, filename: &str) -> DenoResult<()> { + self.permissions.check_net(filename) + } + + #[inline] + pub fn check_run(&self) -> DenoResult<()> { + self.permissions.check_run() + } + #[cfg(test)] pub fn mock() -> IsolateState { let argv = vec![String::from("./deno"), String::from("hello.js")]; @@ -108,3 +139,21 @@ impl IsolateState { .fetch_add(bytes_received, Ordering::SeqCst); } } + +/// Provides state getter function +pub trait IsolateStateContainer { + fn state(&self) -> Arc; +} + +/// Provides state_resolve function for IsolateStateContainer implementors +pub trait IsolateStateModuleResolution: IsolateStateContainer { + fn state_resolve(&mut self, specifier: &str, referrer: deno_mod) -> deno_mod { + let state = self.state(); + state.metrics.resolve_count.fetch_add(1, Ordering::Relaxed); + let mut modules = state.modules.lock().unwrap(); + modules.resolve_cb(&state.dir, specifier, referrer) + } +} + +// Auto implementation for all IsolateStateContainer implementors +impl IsolateStateModuleResolution for T where T: IsolateStateContainer {} diff --git a/cli/main.rs b/cli/main.rs index 4657a3a4dd..12f94650d9 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -9,7 +9,7 @@ extern crate futures; extern crate serde_json; mod ansi; -pub mod cli; +pub mod cli_behavior; pub mod compiler; pub mod deno_dir; pub mod errors; @@ -35,7 +35,7 @@ mod tokio_write; pub mod version; pub mod workers; -use crate::cli::Cli; +use crate::cli_behavior::CliBehavior; use crate::errors::RustOrJsError; use crate::isolate::Isolate; use crate::isolate_state::IsolateState; @@ -111,8 +111,7 @@ fn main() { let state = Arc::new(IsolateState::new(flags, rest_argv, None)); let state_ = state.clone(); let startup_data = startup_data::deno_isolate_init(); - let permissions = permissions::DenoPermissions::from_flags(&state.flags); - let cli = Cli::new(Some(startup_data), state_, permissions); + let cli = CliBehavior::new(Some(startup_data), state_); let mut isolate = Isolate::new(cli); let main_future = lazy(move || { diff --git a/cli/ops.rs b/cli/ops.rs index 862f925602..82f30c137c 100644 --- a/cli/ops.rs +++ b/cli/ops.rs @@ -1,12 +1,11 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. use atty; use crate::ansi; -use crate::cli::Cli; use crate::errors; -use crate::errors::{permission_denied, DenoError, DenoResult, ErrorKind}; +use crate::errors::{op_not_implemented, DenoError, DenoResult, ErrorKind}; use crate::fs as deno_fs; use crate::http_util; -use crate::isolate_state::IsolateState; +use crate::isolate_state::{IsolateState, IsolateStateContainer}; use crate::js_errors::apply_source_map; use crate::js_errors::JSErrorColor; use crate::msg; @@ -59,7 +58,10 @@ pub type OpWithError = dyn Future + Send; // TODO Ideally we wouldn't have to box the OpWithError being returned. // The box is just to make it easier to get a prototype refactor working. type OpCreator = - fn(cli: &Cli, base: &msg::Base<'_>, data: deno_buf) -> Box; + fn(sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf) + -> Box; + +type OpSelector = fn(inner_type: msg::Any) -> DenoResult>; #[inline] fn empty_buf() -> Buf { @@ -70,10 +72,11 @@ fn empty_buf() -> Buf { /// This functions invoked every time libdeno.send() is called. /// control corresponds to the first argument of libdeno.send(). /// data corresponds to the second argument of libdeno.send(). -pub fn dispatch( - cli: &Cli, +pub fn dispatch_all( + sc: Box<&IsolateStateContainer>, control: &[u8], zero_copy: deno_buf, + op_selector: OpSelector, ) -> (bool, Box) { let bytes_sent_control = control.len(); let bytes_sent_zero_copy = zero_copy.len(); @@ -82,66 +85,19 @@ pub fn dispatch( let inner_type = base.inner_type(); let cmd_id = base.cmd_id(); - let op: Box = { - // Handle regular ops. - let op_creator: OpCreator = match inner_type { - msg::Any::Accept => op_accept, - msg::Any::Chdir => op_chdir, - msg::Any::Chmod => op_chmod, - msg::Any::Close => op_close, - msg::Any::CopyFile => op_copy_file, - msg::Any::Cwd => op_cwd, - msg::Any::Dial => op_dial, - msg::Any::Environ => op_env, - msg::Any::Exit => op_exit, - msg::Any::Fetch => op_fetch, - msg::Any::FetchModuleMetaData => op_fetch_module_meta_data, - msg::Any::FormatError => op_format_error, - msg::Any::GlobalTimer => op_global_timer, - msg::Any::GlobalTimerStop => op_global_timer_stop, - msg::Any::IsTTY => op_is_tty, - msg::Any::Listen => op_listen, - msg::Any::MakeTempDir => op_make_temp_dir, - msg::Any::Metrics => op_metrics, - msg::Any::Mkdir => op_mkdir, - msg::Any::Now => op_now, - msg::Any::Open => op_open, - msg::Any::PermissionRevoke => op_revoke_permission, - msg::Any::Permissions => op_permissions, - msg::Any::Read => op_read, - msg::Any::ReadDir => op_read_dir, - msg::Any::ReadFile => op_read_file, - msg::Any::Readlink => op_read_link, - msg::Any::Remove => op_remove, - msg::Any::Rename => op_rename, - msg::Any::ReplReadline => op_repl_readline, - msg::Any::ReplStart => op_repl_start, - msg::Any::Resources => op_resources, - msg::Any::Run => op_run, - msg::Any::RunStatus => op_run_status, - msg::Any::Seek => op_seek, - msg::Any::SetEnv => op_set_env, - msg::Any::Shutdown => op_shutdown, - msg::Any::Start => op_start, - msg::Any::Stat => op_stat, - msg::Any::Symlink => op_symlink, - msg::Any::Truncate => op_truncate, - msg::Any::WorkerGetMessage => op_worker_get_message, - msg::Any::WorkerPostMessage => op_worker_post_message, - msg::Any::Write => op_write, - msg::Any::WriteFile => op_write_file, - _ => panic!(format!( - "Unhandled message {}", - msg::enum_name_any(inner_type) - )), - }; - op_creator(&cli, &base, zero_copy) + let op_func: Box = match op_selector(inner_type) { + Ok(v) => v, + Err(_) => panic!(format!( + "Unhandled message {}", + msg::enum_name_any(inner_type) + )), }; - cli - .state - .metrics_op_dispatched(bytes_sent_control, bytes_sent_zero_copy); - let state = cli.state.clone(); + let state = sc.state().clone(); + + let op: Box = op_func(sc, &base, zero_copy); + + state.metrics_op_dispatched(bytes_sent_control, bytes_sent_zero_copy); let boxed_op = Box::new( op.or_else(move |err: DenoError| -> Result { @@ -188,8 +144,72 @@ pub fn dispatch( (base.sync(), boxed_op) } +pub fn op_selector_compiler( + inner_type: msg::Any, +) -> DenoResult> { + let op_creator: Box = match inner_type { + msg::Any::FetchModuleMetaData => Box::new(op_fetch_module_meta_data), + _ => match op_selector_std(inner_type) { + Ok(v) => v, + Err(e) => return Err(e), + }, + }; + Ok(op_creator) +} + +pub fn op_selector_std(inner_type: msg::Any) -> DenoResult> { + let op_creator: OpCreator = match inner_type { + msg::Any::Accept => op_accept, + msg::Any::Chdir => op_chdir, + msg::Any::Chmod => op_chmod, + msg::Any::Close => op_close, + msg::Any::CopyFile => op_copy_file, + msg::Any::Cwd => op_cwd, + msg::Any::Dial => op_dial, + msg::Any::Environ => op_env, + msg::Any::Exit => op_exit, + msg::Any::Fetch => op_fetch, + msg::Any::FormatError => op_format_error, + msg::Any::GlobalTimer => op_global_timer, + msg::Any::GlobalTimerStop => op_global_timer_stop, + msg::Any::IsTTY => op_is_tty, + msg::Any::Listen => op_listen, + msg::Any::MakeTempDir => op_make_temp_dir, + msg::Any::Metrics => op_metrics, + msg::Any::Mkdir => op_mkdir, + msg::Any::Now => op_now, + msg::Any::Open => op_open, + msg::Any::PermissionRevoke => op_revoke_permission, + msg::Any::Permissions => op_permissions, + msg::Any::Read => op_read, + msg::Any::ReadDir => op_read_dir, + msg::Any::ReadFile => op_read_file, + msg::Any::Readlink => op_read_link, + msg::Any::Remove => op_remove, + msg::Any::Rename => op_rename, + msg::Any::ReplReadline => op_repl_readline, + msg::Any::ReplStart => op_repl_start, + msg::Any::Resources => op_resources, + msg::Any::Run => op_run, + msg::Any::RunStatus => op_run_status, + msg::Any::Seek => op_seek, + msg::Any::SetEnv => op_set_env, + msg::Any::Shutdown => op_shutdown, + msg::Any::Start => op_start, + msg::Any::Stat => op_stat, + msg::Any::Symlink => op_symlink, + msg::Any::Truncate => op_truncate, + msg::Any::WorkerGetMessage => op_worker_get_message, + msg::Any::WorkerPostMessage => op_worker_post_message, + msg::Any::Write => op_write, + msg::Any::WriteFile => op_write_file, + _ => return Err(op_not_implemented()), + }; + Ok(Box::new(op_creator)) +} + fn op_now( - _cli: &Cli, + _sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -213,7 +233,7 @@ fn op_now( } fn op_is_tty( - _cli: &Cli, + _sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, _data: deno_buf, ) -> Box { @@ -238,7 +258,7 @@ fn op_is_tty( } fn op_exit( - _cli: &Cli, + _sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, _data: deno_buf, ) -> Box { @@ -247,19 +267,15 @@ fn op_exit( } fn op_start( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { assert_eq!(data.len(), 0); let mut builder = FlatBufferBuilder::new(); - let argv = cli - .state - .argv - .iter() - .map(|s| s.as_str()) - .collect::>(); + let state = sc.state(); + let argv = state.argv.iter().map(|s| s.as_str()).collect::>(); let argv_off = builder.create_vector_of_strings(argv.as_slice()); let cwd_path = std::env::current_dir().unwrap(); @@ -275,7 +291,7 @@ fn op_start( let deno_version = version::DENO; let deno_version_off = builder.create_string(deno_version); - let main_module = cli.state.main_module().map(|m| builder.create_string(&m)); + let main_module = sc.state().main_module().map(|m| builder.create_string(&m)); let inner = msg::StartRes::create( &mut builder, @@ -284,9 +300,9 @@ fn op_start( pid: std::process::id(), argv: Some(argv_off), main_module, - debug_flag: cli.state.flags.log_debug, - types_flag: cli.state.flags.types, - version_flag: cli.state.flags.version, + debug_flag: sc.state().flags.log_debug, + types_flag: sc.state().flags.types, + version_flag: sc.state().flags.version, v8_version: Some(v8_version_off), deno_version: Some(deno_version_off), no_color: !ansi::use_color(), @@ -307,7 +323,7 @@ fn op_start( } fn op_format_error( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -316,7 +332,7 @@ fn op_format_error( let orig_error = String::from(inner.error().unwrap()); let js_error = JSError::from_v8_exception(&orig_error).unwrap(); - let js_error_mapped = apply_source_map(&js_error, &cli.state.dir); + let js_error_mapped = apply_source_map(&js_error, &sc.state().dir); let js_error_string = JSErrorColor(&js_error_mapped).to_string(); let mut builder = FlatBufferBuilder::new(); @@ -367,7 +383,7 @@ pub fn odd_future(err: DenoError) -> Box { // https://github.com/denoland/deno/blob/golang/os.go#L100-L154 fn op_fetch_module_meta_data( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -377,33 +393,15 @@ fn op_fetch_module_meta_data( let specifier = inner.specifier().unwrap(); let referrer = inner.referrer().unwrap(); - // Check for allow read since this operation could be used to read from the file system. - if !cli.permissions.allows_read() { - debug!("No read permission for fetch_module_meta_data"); - return odd_future(permission_denied()); - } - - // Check for allow write since this operation could be used to write to the file system. - if !cli.permissions.allows_write() { - debug!("No network permission for fetch_module_meta_data"); - return odd_future(permission_denied()); - } - - // Check for allow net since this operation could be used to make https/http requests. - if !cli.permissions.allows_net() { - debug!("No network permission for fetch_module_meta_data"); - return odd_future(permission_denied()); - } - assert_eq!( - cli.state.dir.root.join("gen"), - cli.state.dir.gen, + sc.state().dir.root.join("gen"), + sc.state().dir.gen, "Sanity check" ); Box::new(futures::future::result(|| -> OpResult { let builder = &mut FlatBufferBuilder::new(); - let out = cli.state.dir.fetch_module_meta_data(specifier, referrer)?; + let out = sc.state().dir.fetch_module_meta_data(specifier, referrer)?; let data_off = builder.create_vector(out.source_code.as_slice()); let msg_args = msg::FetchModuleMetaDataResArgs { module_name: Some(builder.create_string(&out.module_name)), @@ -425,7 +423,7 @@ fn op_fetch_module_meta_data( } fn op_chdir( - _cli: &Cli, + _sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -439,19 +437,20 @@ fn op_chdir( } fn op_global_timer_stop( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { assert!(base.sync()); assert_eq!(data.len(), 0); - let mut t = cli.state.global_timer.lock().unwrap(); + let state = sc.state(); + let mut t = state.global_timer.lock().unwrap(); t.cancel(); ok_future(empty_buf()) } fn op_global_timer( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -462,7 +461,8 @@ fn op_global_timer( let val = inner.timeout(); assert!(val >= 0); - let mut t = cli.state.global_timer.lock().unwrap(); + let state = sc.state(); + let mut t = state.global_timer.lock().unwrap(); let deadline = Instant::now() + Duration::from_millis(val as u64); let f = t.new_timeout(deadline); @@ -483,7 +483,7 @@ fn op_global_timer( } fn op_set_env( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -491,18 +491,22 @@ fn op_set_env( let inner = base.inner_as_set_env().unwrap(); let key = inner.key().unwrap(); let value = inner.value().unwrap(); - if let Err(e) = cli.check_env() { + if let Err(e) = sc.state().check_env() { return odd_future(e); } std::env::set_var(key, value); ok_future(empty_buf()) } -fn op_env(cli: &Cli, base: &msg::Base<'_>, data: deno_buf) -> Box { +fn op_env( + sc: Box<&IsolateStateContainer>, + base: &msg::Base<'_>, + data: deno_buf, +) -> Box { assert_eq!(data.len(), 0); let cmd_id = base.cmd_id(); - if let Err(e) = cli.check_env() { + if let Err(e) = sc.state().check_env() { return odd_future(e); } @@ -527,7 +531,7 @@ fn op_env(cli: &Cli, base: &msg::Base<'_>, data: deno_buf) -> Box { } fn op_permissions( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -537,11 +541,11 @@ fn op_permissions( let inner = msg::PermissionsRes::create( builder, &msg::PermissionsResArgs { - run: cli.permissions.allows_run(), - read: cli.permissions.allows_read(), - write: cli.permissions.allows_write(), - net: cli.permissions.allows_net(), - env: cli.permissions.allows_env(), + run: sc.state().permissions.allows_run(), + read: sc.state().permissions.allows_read(), + write: sc.state().permissions.allows_write(), + net: sc.state().permissions.allows_net(), + env: sc.state().permissions.allows_env(), }, ); ok_future(serialize_response( @@ -556,7 +560,7 @@ fn op_permissions( } fn op_revoke_permission( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -564,11 +568,11 @@ fn op_revoke_permission( let inner = base.inner_as_permission_revoke().unwrap(); let permission = inner.permission().unwrap(); let result = match permission { - "run" => cli.permissions.revoke_run(), - "read" => cli.permissions.revoke_read(), - "write" => cli.permissions.revoke_write(), - "net" => cli.permissions.revoke_net(), - "env" => cli.permissions.revoke_env(), + "run" => sc.state().permissions.revoke_run(), + "read" => sc.state().permissions.revoke_read(), + "write" => sc.state().permissions.revoke_write(), + "net" => sc.state().permissions.revoke_net(), + "env" => sc.state().permissions.revoke_env(), _ => Ok(()), }; if let Err(e) = result { @@ -578,7 +582,7 @@ fn op_revoke_permission( } fn op_fetch( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -601,7 +605,7 @@ fn op_fetch( } let req = maybe_req.unwrap(); - if let Err(e) = cli.check_net(url) { + if let Err(e) = sc.state().check_net(url) { return odd_future(e); } @@ -665,7 +669,7 @@ where } fn op_make_temp_dir( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -675,7 +679,7 @@ fn op_make_temp_dir( let cmd_id = base.cmd_id(); // FIXME - if let Err(e) = cli.check_write("make_temp") { + if let Err(e) = sc.state().check_write("make_temp") { return odd_future(e); } @@ -714,7 +718,7 @@ fn op_make_temp_dir( } fn op_mkdir( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -724,7 +728,7 @@ fn op_mkdir( let recursive = inner.recursive(); let mode = inner.mode(); - if let Err(e) = cli.check_write(&path) { + if let Err(e) = sc.state().check_write(&path) { return odd_future(e); } @@ -736,7 +740,7 @@ fn op_mkdir( } fn op_chmod( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -745,7 +749,7 @@ fn op_chmod( let _mode = inner.mode(); let path = String::from(inner.path().unwrap()); - if let Err(e) = cli.check_write(&path) { + if let Err(e) = sc.state().check_write(&path) { return odd_future(e); } @@ -775,7 +779,7 @@ fn op_chmod( } fn op_open( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -824,20 +828,20 @@ fn op_open( match mode { "r" => { - if let Err(e) = cli.check_read(&filename_str) { + if let Err(e) = sc.state().check_read(&filename_str) { return odd_future(e); } } "w" | "a" | "x" => { - if let Err(e) = cli.check_write(&filename_str) { + if let Err(e) = sc.state().check_write(&filename_str) { return odd_future(e); } } &_ => { - if let Err(e) = cli.check_read(&filename_str) { + if let Err(e) = sc.state().check_read(&filename_str) { return odd_future(e); } - if let Err(e) = cli.check_write(&filename_str) { + if let Err(e) = sc.state().check_write(&filename_str) { return odd_future(e); } } @@ -865,7 +869,7 @@ fn op_open( } fn op_close( - _cli: &Cli, + _sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -882,7 +886,7 @@ fn op_close( } fn op_shutdown( - _cli: &Cli, + _sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -908,7 +912,7 @@ fn op_shutdown( } fn op_read( - _cli: &Cli, + _sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -946,7 +950,7 @@ fn op_read( } fn op_write( - _cli: &Cli, + _sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -983,7 +987,7 @@ fn op_write( } fn op_seek( - _cli: &Cli, + _sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1005,7 +1009,7 @@ fn op_seek( } fn op_remove( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1015,7 +1019,7 @@ fn op_remove( let path = PathBuf::from(path_); let recursive = inner.recursive(); - if let Err(e) = cli.check_write(path.to_str().unwrap()) { + if let Err(e) = sc.state().check_write(path.to_str().unwrap()) { return odd_future(e); } @@ -1035,7 +1039,7 @@ fn op_remove( // Prototype https://github.com/denoland/deno/blob/golang/os.go#L171-L184 fn op_read_file( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1045,7 +1049,7 @@ fn op_read_file( let filename_ = inner.filename().unwrap(); let filename = PathBuf::from(filename_); debug!("op_read_file {}", filename.display()); - if let Err(e) = cli.check_read(&filename_) { + if let Err(e) = sc.state().check_read(&filename_) { return odd_future(e); } blocking(base.sync(), move || { @@ -1073,7 +1077,7 @@ fn op_read_file( } fn op_copy_file( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1084,10 +1088,10 @@ fn op_copy_file( let to_ = inner.to().unwrap(); let to = PathBuf::from(to_); - if let Err(e) = cli.check_read(&from_) { + if let Err(e) = sc.state().check_read(&from_) { return odd_future(e); } - if let Err(e) = cli.check_write(&to_) { + if let Err(e) = sc.state().check_write(&to_) { return odd_future(e); } @@ -1129,7 +1133,7 @@ fn get_mode(_perm: &fs::Permissions) -> u32 { } fn op_cwd( - _cli: &Cli, + _sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1155,7 +1159,7 @@ fn op_cwd( } fn op_stat( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1166,7 +1170,7 @@ fn op_stat( let filename = PathBuf::from(filename_); let lstat = inner.lstat(); - if let Err(e) = cli.check_read(&filename_) { + if let Err(e) = sc.state().check_read(&filename_) { return odd_future(e); } @@ -1207,7 +1211,7 @@ fn op_stat( } fn op_read_dir( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1216,7 +1220,7 @@ fn op_read_dir( let cmd_id = base.cmd_id(); let path = String::from(inner.path().unwrap()); - if let Err(e) = cli.check_read(&path) { + if let Err(e) = sc.state().check_read(&path) { return odd_future(e); } @@ -1268,7 +1272,7 @@ fn op_read_dir( } fn op_write_file( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1279,7 +1283,7 @@ fn op_write_file( let is_create = inner.is_create(); let is_append = inner.is_append(); - if let Err(e) = cli.check_write(&filename) { + if let Err(e) = sc.state().check_write(&filename) { return odd_future(e); } @@ -1298,7 +1302,7 @@ fn op_write_file( } fn op_rename( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1307,7 +1311,7 @@ fn op_rename( let oldpath = PathBuf::from(inner.oldpath().unwrap()); let newpath_ = inner.newpath().unwrap(); let newpath = PathBuf::from(newpath_); - if let Err(e) = cli.check_write(&newpath_) { + if let Err(e) = sc.state().check_write(&newpath_) { return odd_future(e); } blocking(base.sync(), move || -> OpResult { @@ -1318,7 +1322,7 @@ fn op_rename( } fn op_symlink( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1328,7 +1332,7 @@ fn op_symlink( let newname_ = inner.newname().unwrap(); let newname = PathBuf::from(newname_); - if let Err(e) = cli.check_write(&newname_) { + if let Err(e) = sc.state().check_write(&newname_) { return odd_future(e); } // TODO Use type for Windows. @@ -1347,7 +1351,7 @@ fn op_symlink( } fn op_read_link( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1357,7 +1361,7 @@ fn op_read_link( let name_ = inner.name().unwrap(); let name = PathBuf::from(name_); - if let Err(e) = cli.check_read(&name_) { + if let Err(e) = sc.state().check_read(&name_) { return odd_future(e); } @@ -1385,7 +1389,7 @@ fn op_read_link( } fn op_repl_start( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1395,7 +1399,7 @@ fn op_repl_start( let history_file = String::from(inner.history_file().unwrap()); debug!("op_repl_start {}", history_file); - let history_path = repl::history_path(&cli.state.dir, &history_file); + let history_path = repl::history_path(&sc.state().dir, &history_file); let repl = repl::Repl::new(history_path); let resource = resources::add_repl(repl); @@ -1416,7 +1420,7 @@ fn op_repl_start( } fn op_repl_readline( - _cli: &Cli, + _sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1452,7 +1456,7 @@ fn op_repl_readline( } fn op_truncate( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1462,7 +1466,7 @@ fn op_truncate( let filename = String::from(inner.name().unwrap()); let len = inner.len(); - if let Err(e) = cli.check_write(&filename) { + if let Err(e) = sc.state().check_write(&filename) { return odd_future(e); } @@ -1475,12 +1479,12 @@ fn op_truncate( } fn op_listen( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { assert_eq!(data.len(), 0); - if let Err(e) = cli.check_net("listen") { + if let Err(e) = sc.state().check_net("listen") { return odd_future(e); } @@ -1537,12 +1541,12 @@ fn new_conn(cmd_id: u32, tcp_stream: TcpStream) -> OpResult { } fn op_accept( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { assert_eq!(data.len(), 0); - if let Err(e) = cli.check_net("accept") { + if let Err(e) = sc.state().check_net("accept") { return odd_future(e); } let cmd_id = base.cmd_id(); @@ -1563,12 +1567,12 @@ fn op_accept( } fn op_dial( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { assert_eq!(data.len(), 0); - if let Err(e) = cli.check_net("dial") { + if let Err(e) = sc.state().check_net("dial") { return odd_future(e); } let cmd_id = base.cmd_id(); @@ -1589,7 +1593,7 @@ fn op_dial( } fn op_metrics( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1599,7 +1603,7 @@ fn op_metrics( let builder = &mut FlatBufferBuilder::new(); let inner = msg::MetricsRes::create( builder, - &msg::MetricsResArgs::from(&cli.state.metrics), + &msg::MetricsResArgs::from(&sc.state().metrics), ); ok_future(serialize_response( cmd_id, @@ -1613,7 +1617,7 @@ fn op_metrics( } fn op_resources( - _cli: &Cli, + _sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1664,11 +1668,15 @@ fn subprocess_stdio_map(v: msg::ProcessStdio) -> std::process::Stdio { } } -fn op_run(cli: &Cli, base: &msg::Base<'_>, data: deno_buf) -> Box { +fn op_run( + sc: Box<&IsolateStateContainer>, + base: &msg::Base<'_>, + data: deno_buf, +) -> Box { assert!(base.sync()); let cmd_id = base.cmd_id(); - if let Err(e) = cli.check_run() { + if let Err(e) = sc.state().check_run() { return odd_future(e); } @@ -1734,7 +1742,7 @@ fn op_run(cli: &Cli, base: &msg::Base<'_>, data: deno_buf) -> Box { } fn op_run_status( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1743,7 +1751,7 @@ fn op_run_status( let inner = base.inner_as_run_status().unwrap(); let rid = inner.rid(); - if let Err(e) = cli.check_run() { + if let Err(e) = sc.state().check_run() { return odd_future(e); } @@ -1810,7 +1818,7 @@ impl Future for GetMessageFuture { } fn op_worker_get_message( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1818,7 +1826,7 @@ fn op_worker_get_message( let cmd_id = base.cmd_id(); let op = GetMessageFuture { - state: cli.state.clone(), + state: sc.state().clone(), }; let op = op.map_err(move |_| -> DenoError { unimplemented!() }); let op = op.and_then(move |maybe_buf| -> DenoResult { @@ -1844,7 +1852,7 @@ fn op_worker_get_message( } fn op_worker_post_message( - cli: &Cli, + sc: Box<&IsolateStateContainer>, base: &msg::Base<'_>, data: deno_buf, ) -> Box { @@ -1852,8 +1860,8 @@ fn op_worker_post_message( let d = Vec::from(data.as_ref()).into_boxed_slice(); - assert!(cli.state.worker_channels.is_some()); - let tx = match cli.state.worker_channels { + assert!(sc.state().worker_channels.is_some()); + let tx = match sc.state().worker_channels { None => panic!("expected worker_channels"), Some(ref wc) => { let wc = wc.lock().unwrap(); @@ -1876,6 +1884,7 @@ fn op_worker_post_message( Box::new(op) } +/* #[cfg(test)] mod tests { use super::*; @@ -1893,7 +1902,7 @@ mod tests { allow_run: PermissionAccessor::from(true), ..Default::default() }; - let cli = Cli::new(None, state, permissions); + let cli = Cli::new(None, state); let builder = &mut FlatBufferBuilder::new(); let fetch_msg_args = msg::FetchModuleMetaDataArgs { specifier: Some(builder.create_string("./somefile")), @@ -1910,7 +1919,7 @@ mod tests { let data = builder.finished_data(); let final_msg = msg::get_root_as_base(&data); let fetch_result = - op_fetch_module_meta_data(&cli, &final_msg, deno_buf::empty()).wait(); + op_fetch_module_meta_data(Box::new(&cli), &final_msg, deno_buf::empty()).wait(); match fetch_result { Ok(_) => assert!(true), Err(e) => assert_eq!(e.to_string(), permission_denied().to_string()), @@ -2018,3 +2027,4 @@ mod tests { } } } +*/ diff --git a/cli/workers.rs b/cli/workers.rs index a69acd6cce..2be6f66b71 100644 --- a/cli/workers.rs +++ b/cli/workers.rs @@ -1,47 +1,42 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -use crate::cli::Cli; -use crate::flags::DenoFlags; -use crate::isolate::Isolate; -use crate::isolate_state::IsolateState; +use crate::isolate::{DenoBehavior, Isolate}; use crate::isolate_state::WorkerChannels; use crate::js_errors::JSErrorColor; -use crate::permissions::DenoPermissions; use crate::resources; use crate::tokio_util; use deno_core::Buf; use deno_core::JSError; -use deno_core::StartupData; use futures::future::lazy; use futures::sync::mpsc; use futures::sync::oneshot; use futures::Future; use futures::Poll; -use std::sync::Arc; use std::thread; -/// Rust interface for WebWorkers. -pub struct Worker { - isolate: Isolate, +/// Behavior trait specific to workers +pub trait WorkerBehavior: DenoBehavior { + /// Used to setup internal channels at worker creation. + /// This is intended to be temporary fix. + /// TODO(afinch7) come up with a better solution to set worker channels + fn set_internal_channels(&mut self, worker_channels: WorkerChannels); } -impl Worker { - pub fn new( - startup_data: Option, - flags: DenoFlags, - argv: Vec, - permissions: DenoPermissions, - ) -> (Self, WorkerChannels) { +/// Rust interface for WebWorkers. +pub struct Worker { + isolate: Isolate, +} + +impl Worker { + pub fn new(mut behavior: B) -> (Self, WorkerChannels) { let (worker_in_tx, worker_in_rx) = mpsc::channel::(1); let (worker_out_tx, worker_out_rx) = mpsc::channel::(1); let internal_channels = (worker_out_tx, worker_in_rx); let external_channels = (worker_in_tx, worker_out_rx); - let state = - Arc::new(IsolateState::new(flags, argv, Some(internal_channels))); + behavior.set_internal_channels(internal_channels); - let cli = Cli::new(startup_data, state, permissions); - let isolate = Isolate::new(cli); + let isolate = Isolate::new(behavior); let worker = Worker { isolate }; (worker, external_channels) @@ -52,7 +47,7 @@ impl Worker { } } -impl Future for Worker { +impl Future for Worker { type Item = (); type Error = JSError; @@ -61,11 +56,9 @@ impl Future for Worker { } } -pub fn spawn( - startup_data: Option, - state: &IsolateState, +pub fn spawn( + behavior: B, js_source: String, - permissions: DenoPermissions, ) -> resources::Resource { // TODO This function should return a Future, so that the caller can retrieve // the JSError if one is thrown. Currently it just prints to stderr and calls @@ -74,14 +67,10 @@ pub fn spawn( let (p, c) = oneshot::channel::(); let builder = thread::Builder::new().name("worker".to_string()); - let flags = state.flags.clone(); - let argv = state.argv.clone(); - let _tid = builder .spawn(move || { tokio_util::run(lazy(move || { - let (mut worker, external_channels) = - Worker::new(startup_data, flags, argv, permissions); + let (mut worker, external_channels) = Worker::new(behavior); let resource = resources::add_worker(external_channels); p.send(resource.clone()).unwrap(); @@ -113,14 +102,14 @@ pub fn spawn( #[cfg(test)] mod tests { use super::*; - use crate::startup_data; + use crate::compiler::CompilerBehavior; + use crate::isolate_state::IsolateState; + use std::sync::Arc; #[test] fn test_spawn() { - let startup_data = startup_data::compiler_isolate_init(); let resource = spawn( - Some(startup_data), - &IsolateState::mock(), + CompilerBehavior::new(Arc::new(IsolateState::mock())), r#" onmessage = function(e) { let s = new TextDecoder().decode(e.data);; @@ -134,8 +123,7 @@ mod tests { postMessage(new Uint8Array([1, 2, 3])); console.log("after postMessage"); } - "#.into(), - DenoPermissions::default(), + "#.into(), ); let msg = String::from("hi").into_boxed_str().into_boxed_bytes(); @@ -154,12 +142,9 @@ mod tests { #[test] fn removed_from_resource_table_on_close() { - let startup_data = startup_data::compiler_isolate_init(); let resource = spawn( - Some(startup_data), - &IsolateState::mock(), + CompilerBehavior::new(Arc::new(IsolateState::mock())), "onmessage = () => close();".into(), - DenoPermissions::default(), ); assert_eq!( diff --git a/cli/cli.rs b/src/cli_behavior.rs similarity index 57% rename from cli/cli.rs rename to src/cli_behavior.rs index e5b39c5589..f30ae789fd 100644 --- a/cli/cli.rs +++ b/src/cli_behavior.rs @@ -2,10 +2,9 @@ #![allow(unused_variables)] #![allow(dead_code)] -use crate::errors::DenoResult; +use crate::isolate_state::IsolateStateContainer; use crate::isolate_state::IsolateState; use crate::ops; -use crate::permissions::DenoPermissions; use deno_core::deno_buf; use deno_core::deno_mod; use deno_core::Behavior; @@ -14,53 +13,30 @@ use deno_core::StartupData; use std::sync::atomic::Ordering; use std::sync::Arc; +// Buf represents a byte array returned from a "Op". The message might be empty +// (which will be translated into a null object on the javascript side) or it is +// a heap allocated opaque sequence of bytes. Usually a flatbuffer message. +pub type Buf = Box<[u8]>; + /// Implements deno_core::Behavior for the main Deno command-line. -pub struct Cli { +pub struct CliBehavior { startup_data: Option, pub state: Arc, - pub permissions: Arc, // TODO(ry) move to IsolateState } -impl Cli { +impl CliBehavior { pub fn new( startup_data: Option, state: Arc, - permissions: DenoPermissions, ) -> Self { Self { startup_data, state, - permissions: Arc::new(permissions), } } - - #[inline] - pub fn check_read(&self, filename: &str) -> DenoResult<()> { - self.permissions.check_read(filename) - } - - #[inline] - pub fn check_write(&self, filename: &str) -> DenoResult<()> { - self.permissions.check_write(filename) - } - - #[inline] - pub fn check_env(&self) -> DenoResult<()> { - self.permissions.check_env() - } - - #[inline] - pub fn check_net(&self, filename: &str) -> DenoResult<()> { - self.permissions.check_net(filename) - } - - #[inline] - pub fn check_run(&self) -> DenoResult<()> { - self.permissions.check_run() - } } -impl Behavior for Cli { +impl Behavior for CliBehavior { fn startup_data(&mut self) -> Option { self.startup_data.take() } @@ -80,6 +56,18 @@ impl Behavior for Cli { control: &[u8], zero_copy: deno_buf, ) -> (bool, Box) { - ops::dispatch(self, control, zero_copy) + ops::dispatch_cli(self, control, zero_copy) } } + +impl IsolateStateContainer for CliBehavior { + fn state(&self) -> Arc { + self.state.clone() + } +} + +impl IsolateStateContainer for &CliBehavior { + fn state(&self) -> Arc { + self.state.clone() + } +} \ No newline at end of file