From 6143a64256b299f6ff8fa846e2e26d11c8c2c71d Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Mon, 17 Sep 2018 17:41:13 -0700 Subject: [PATCH] Rename Deno to Isolate and move to own file. --- src/handlers.rs | 88 ++++++++++++++++++++-------------------- src/isolate.rs | 97 ++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 104 +++++------------------------------------------- 3 files changed, 153 insertions(+), 136 deletions(-) create mode 100644 src/isolate.rs diff --git a/src/handlers.rs b/src/handlers.rs index 9c218827ff..cf0d1a3159 100644 --- a/src/handlers.rs +++ b/src/handlers.rs @@ -2,13 +2,13 @@ use errors::DenoError; use errors::DenoResult; use flatbuffers::FlatBufferBuilder; -use from_c; use fs as deno_fs; use futures; use futures::sync::oneshot; use hyper; use hyper::rt::{Future, Stream}; use hyper::Client; +use isolate::from_c; use libdeno; use libdeno::{deno_buf, DenoC}; use msg; @@ -83,7 +83,7 @@ pub extern "C" fn msg_from_js(d: *const DenoC, buf: deno_buf) { )) }); - let deno = from_c(d); + let isolate = from_c(d); if base.sync() { // Execute future synchronously. // println!("sync handler {}", msg::enum_name_any(msg_type)); @@ -92,7 +92,7 @@ pub extern "C" fn msg_from_js(d: *const DenoC, buf: deno_buf) { None => {} Some(box_u8) => { let buf = deno_buf_from(box_u8); - // Set the synchronous response, the value returned from deno.send(). + // Set the synchronous response, the value returned from isolate.send(). unsafe { libdeno::deno_set_response(d, buf) } } } @@ -120,7 +120,7 @@ pub extern "C" fn msg_from_js(d: *const DenoC, buf: deno_buf) { unsafe { libdeno::deno_send(d, buf) }; Ok(()) }); - deno.rt.spawn(future); + isolate.rt.spawn(future); } } @@ -148,10 +148,10 @@ fn handle_exit(_d: *const DenoC, base: &msg::Base) -> Box { } fn handle_start(d: *const DenoC, base: &msg::Base) -> Box { - let deno = from_c(d); + let isolate = from_c(d); let mut builder = FlatBufferBuilder::new(); - let argv = deno.argv.iter().map(|s| s.as_str()).collect::>(); + let argv = isolate.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(); @@ -163,7 +163,7 @@ fn handle_start(d: *const DenoC, base: &msg::Base) -> Box { &msg::StartResArgs { cwd: Some(cwd_off), argv: Some(argv_off), - debug_flag: deno.flags.log_debug, + debug_flag: isolate.flags.log_debug, ..Default::default() }, ); @@ -202,19 +202,23 @@ fn odd_future(err: DenoError) -> Box { Box::new(futures::future::err(err)) } -// https://github.com/denoland/deno/blob/golang/os.go#L100-L154 +// https://github.com/denoland/isolate/blob/golang/os.go#L100-L154 fn handle_code_fetch(d: *const DenoC, base: &msg::Base) -> Box { let msg = base.msg_as_code_fetch().unwrap(); let cmd_id = base.cmd_id(); let module_specifier = msg.module_specifier().unwrap(); let containing_file = msg.containing_file().unwrap(); - let deno = from_c(d); + let isolate = from_c(d); - assert_eq!(deno.dir.root.join("gen"), deno.dir.gen, "Sanity check"); + assert_eq!( + isolate.dir.root.join("gen"), + isolate.dir.gen, + "Sanity check" + ); Box::new(futures::future::result(|| -> OpResult { let builder = &mut FlatBufferBuilder::new(); - let out = deno.dir.code_fetch(module_specifier, containing_file)?; + let out = isolate.dir.code_fetch(module_specifier, containing_file)?; let mut msg_args = msg::CodeFetchResArgs { module_name: Some(builder.create_string(&out.module_name)), filename: Some(builder.create_string(&out.filename)), @@ -240,15 +244,15 @@ fn handle_code_fetch(d: *const DenoC, base: &msg::Base) -> Box { }())) } -// https://github.com/denoland/deno/blob/golang/os.go#L156-L169 +// https://github.com/denoland/isolate/blob/golang/os.go#L156-L169 fn handle_code_cache(d: *const DenoC, base: &msg::Base) -> Box { let msg = base.msg_as_code_cache().unwrap(); let filename = msg.filename().unwrap(); let source_code = msg.source_code().unwrap(); let output_code = msg.output_code().unwrap(); Box::new(futures::future::result(|| -> OpResult { - let deno = from_c(d); - deno.dir.code_cache(filename, source_code, output_code)?; + let isolate = from_c(d); + isolate.dir.code_cache(filename, source_code, output_code)?; Ok(None) }())) } @@ -258,8 +262,8 @@ fn handle_set_env(d: *const DenoC, base: &msg::Base) -> Box { let key = msg.key().unwrap(); let value = msg.value().unwrap(); - let deno = from_c(d); - if !deno.flags.allow_env { + let isolate = from_c(d); + if !isolate.flags.allow_env { return odd_future(permission_denied()); } @@ -268,9 +272,9 @@ fn handle_set_env(d: *const DenoC, base: &msg::Base) -> Box { } fn handle_env(d: *const DenoC, base: &msg::Base) -> Box { - let deno = from_c(d); + let isolate = from_c(d); let cmd_id = base.cmd_id(); - if !deno.flags.allow_env { + if !isolate.flags.allow_env { return odd_future(permission_denied()); } @@ -288,8 +292,7 @@ fn handle_env(d: *const DenoC, base: &msg::Base) -> Box { ..Default::default() }, ) - }) - .collect(); + }).collect(); let tables = builder.create_vector(&vars); let msg = msg::EnvironRes::create( builder, @@ -314,9 +317,9 @@ fn handle_fetch_req(d: *const DenoC, base: &msg::Base) -> Box { let cmd_id = base.cmd_id(); let id = msg.id(); let url = msg.url().unwrap(); - let deno = from_c(d); + let isolate = from_c(d); - if !deno.flags.allow_net { + if !isolate.flags.allow_net { return odd_future(permission_denied()); } @@ -402,8 +405,7 @@ where .and_then(|_| { cb(); Ok(()) - }) - .select(cancel_rx) + }).select(cancel_rx) .map(|_| ()) .map_err(|_| ()); @@ -418,14 +420,14 @@ fn handle_make_temp_dir(d: *const DenoC, base: &msg::Base) -> Box { let prefix = msg.prefix(); let suffix = msg.suffix(); - let deno = from_c(d); - if !deno.flags.allow_write { + let isolate = from_c(d); + if !isolate.flags.allow_write { return odd_future(permission_denied()); } // TODO Use blocking() here. Box::new(futures::future::result(|| -> OpResult { // TODO(piscisaureus): use byte vector for paths, not a string. - // See https://github.com/denoland/deno/issues/627. + // See https://github.com/denoland/isolate/issues/627. // We can't assume that paths are always valid utf8 strings. let path = deno_fs::make_temp_dir(dir.map(Path::new), prefix, suffix)?; let builder = &mut FlatBufferBuilder::new(); @@ -453,8 +455,8 @@ fn handle_mkdir(d: *const DenoC, base: &msg::Base) -> Box { let msg = base.msg_as_mkdir().unwrap(); let mode = msg.mode(); let path = msg.path().unwrap(); - let deno = from_c(d); - if !deno.flags.allow_write { + let isolate = from_c(d); + if !isolate.flags.allow_write { return odd_future(permission_denied()); } // TODO Use tokio_threadpool. @@ -469,8 +471,8 @@ fn handle_remove(d: *const DenoC, base: &msg::Base) -> Box { let msg = base.msg_as_remove().unwrap(); let path = msg.path().unwrap(); let recursive = msg.recursive(); - let deno = from_c(d); - if !deno.flags.allow_write { + let isolate = from_c(d); + if !isolate.flags.allow_write { return odd_future(permission_denied()); } // TODO Use tokio_threadpool. @@ -491,7 +493,7 @@ fn handle_remove(d: *const DenoC, base: &msg::Base) -> Box { }())) } -// Prototype https://github.com/denoland/deno/blob/golang/os.go#L171-L184 +// Prototype https://github.com/denoland/isolate/blob/golang/os.go#L171-L184 fn handle_read_file(_d: *const DenoC, base: &msg::Base) -> Box { let msg = base.msg_as_read_file().unwrap(); let cmd_id = base.cmd_id(); @@ -591,8 +593,8 @@ fn handle_write_file(d: *const DenoC, base: &msg::Base) -> Box { let data = msg.data().unwrap(); let perm = msg.perm(); - let deno = from_c(d); - if !deno.flags.allow_write { + let isolate = from_c(d); + if !isolate.flags.allow_write { return odd_future(permission_denied()); } Box::new(futures::future::result(|| -> OpResult { @@ -602,20 +604,20 @@ fn handle_write_file(d: *const DenoC, base: &msg::Base) -> Box { }())) } -// TODO(ry) Use Deno instead of DenoC as first arg. +// TODO(ry) Use Isolate instead of DenoC as first arg. fn remove_timer(d: *const DenoC, timer_id: u32) { - let deno = from_c(d); - deno.timers.remove(&timer_id); + let isolate = from_c(d); + isolate.timers.remove(&timer_id); } -// Prototype: https://github.com/ry/deno/blob/golang/timers.go#L25-L39 +// Prototype: https://github.com/ry/isolate/blob/golang/timers.go#L25-L39 fn handle_timer_start(d: *const DenoC, base: &msg::Base) -> Box { debug!("handle_timer_start"); let msg = base.msg_as_timer_start().unwrap(); let cmd_id = base.cmd_id(); let timer_id = msg.id(); let delay = msg.delay(); - let deno = from_c(d); + let isolate = from_c(d); let future = { let (delay_task, cancel_delay) = set_timeout( @@ -624,7 +626,7 @@ fn handle_timer_start(d: *const DenoC, base: &msg::Base) -> Box { }, delay, ); - deno.timers.insert(timer_id, cancel_delay); + isolate.timers.insert(timer_id, cancel_delay); delay_task }; Box::new(future.then(move |result| { @@ -649,7 +651,7 @@ fn handle_timer_start(d: *const DenoC, base: &msg::Base) -> Box { })) } -// Prototype: https://github.com/ry/deno/blob/golang/timers.go#L40-L43 +// Prototype: https://github.com/ry/isolate/blob/golang/timers.go#L40-L43 fn handle_timer_clear(d: *const DenoC, base: &msg::Base) -> Box { let msg = base.msg_as_timer_clear().unwrap(); debug!("handle_timer_clear"); @@ -658,8 +660,8 @@ fn handle_timer_clear(d: *const DenoC, base: &msg::Base) -> Box { } fn handle_rename(d: *const DenoC, base: &msg::Base) -> Box { - let deno = from_c(d); - if !deno.flags.allow_write { + let isolate = from_c(d); + if !isolate.flags.allow_write { return odd_future(permission_denied()); }; let msg = base.msg_as_rename().unwrap(); diff --git a/src/isolate.rs b/src/isolate.rs new file mode 100644 index 0000000000..71a633abd3 --- /dev/null +++ b/src/isolate.rs @@ -0,0 +1,97 @@ +// Copyright 2018 the Deno authors. All rights reserved. MIT license. +use deno_dir; +use flags; +use futures; +use handlers; +use libc::c_void; +use libdeno; +use std; +use std::collections::HashMap; +use std::ffi::CStr; +use std::ffi::CString; +use tokio; + +type DenoException<'a> = &'a str; + +pub struct Isolate { + pub ptr: *const libdeno::DenoC, + pub dir: deno_dir::DenoDir, + pub rt: tokio::runtime::current_thread::Runtime, + pub timers: HashMap>, + pub argv: Vec, + pub flags: flags::DenoFlags, +} + +static DENO_INIT: std::sync::Once = std::sync::ONCE_INIT; + +impl Isolate { + pub fn new(argv: Vec) -> Box { + DENO_INIT.call_once(|| { + unsafe { libdeno::deno_init() }; + }); + + let (flags, argv_rest) = flags::set_flags(argv); + + let mut deno_box = Box::new(Isolate { + ptr: 0 as *const libdeno::DenoC, + dir: deno_dir::DenoDir::new(flags.reload, None).unwrap(), + rt: tokio::runtime::current_thread::Runtime::new().unwrap(), + timers: HashMap::new(), + argv: argv_rest, + flags, + }); + + (*deno_box).ptr = unsafe { + libdeno::deno_new( + deno_box.as_ref() as *const _ as *const c_void, + handlers::msg_from_js, + ) + }; + + deno_box + } + + pub fn execute( + &mut self, + js_filename: &str, + js_source: &str, + ) -> Result<(), DenoException> { + let filename = CString::new(js_filename).unwrap(); + let source = CString::new(js_source).unwrap(); + let r = unsafe { + libdeno::deno_execute(self.ptr, filename.as_ptr(), source.as_ptr()) + }; + if r == 0 { + let ptr = unsafe { libdeno::deno_last_exception(self.ptr) }; + let cstr = unsafe { CStr::from_ptr(ptr) }; + return Err(cstr.to_str().unwrap()); + } + Ok(()) + } +} + +impl Drop for Isolate { + fn drop(&mut self) { + unsafe { libdeno::deno_delete(self.ptr) } + } +} + +pub fn from_c<'a>(d: *const libdeno::DenoC) -> &'a mut Isolate { + let ptr = unsafe { libdeno::deno_get_data(d) }; + let ptr = ptr as *mut Isolate; + let isolate_box = unsafe { Box::from_raw(ptr) }; + Box::leak(isolate_box) +} + +#[test] +fn test_c_to_rust() { + let argv = vec![String::from("./deno"), String::from("hello.js")]; + let isolate = Isolate::new(argv); + let isolate2 = from_c(isolate.ptr); + assert_eq!(isolate.ptr, isolate2.ptr); + assert_eq!( + isolate.dir.root.join("gen"), + isolate.dir.gen, + "Sanity check" + ); +} diff --git a/src/main.rs b/src/main.rs index 72bbe54fae..764f5a0c60 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +// Copyright 2018 the Deno authors. All rights reserved. MIT license. extern crate flatbuffers; extern crate futures; extern crate hyper; @@ -19,96 +20,13 @@ mod errors; mod flags; mod fs; pub mod handlers; +mod isolate; mod libdeno; mod net; mod version; -use libc::c_void; -use std::collections::HashMap; +use isolate::Isolate; use std::env; -use std::ffi::CStr; -use std::ffi::CString; - -type DenoException<'a> = &'a str; - -pub struct Deno { - ptr: *const libdeno::DenoC, - dir: deno_dir::DenoDir, - rt: tokio::runtime::current_thread::Runtime, - timers: HashMap>, - argv: Vec, - flags: flags::DenoFlags, -} - -static DENO_INIT: std::sync::Once = std::sync::ONCE_INIT; - -impl Deno { - fn new(argv: Vec) -> Box { - DENO_INIT.call_once(|| { - unsafe { libdeno::deno_init() }; - }); - - let (flags, argv_rest) = flags::set_flags(argv); - - let mut deno_box = Box::new(Deno { - ptr: 0 as *const libdeno::DenoC, - dir: deno_dir::DenoDir::new(flags.reload, None).unwrap(), - rt: tokio::runtime::current_thread::Runtime::new().unwrap(), - timers: HashMap::new(), - argv: argv_rest, - flags, - }); - - (*deno_box).ptr = unsafe { - libdeno::deno_new( - deno_box.as_ref() as *const _ as *const c_void, - handlers::msg_from_js, - ) - }; - - deno_box - } - - fn execute( - &mut self, - js_filename: &str, - js_source: &str, - ) -> Result<(), DenoException> { - let filename = CString::new(js_filename).unwrap(); - let source = CString::new(js_source).unwrap(); - let r = unsafe { - libdeno::deno_execute(self.ptr, filename.as_ptr(), source.as_ptr()) - }; - if r == 0 { - let ptr = unsafe { libdeno::deno_last_exception(self.ptr) }; - let cstr = unsafe { CStr::from_ptr(ptr) }; - return Err(cstr.to_str().unwrap()); - } - Ok(()) - } -} - -impl Drop for Deno { - fn drop(&mut self) { - unsafe { libdeno::deno_delete(self.ptr) } - } -} - -pub fn from_c<'a>(d: *const libdeno::DenoC) -> &'a mut Deno { - let ptr = unsafe { libdeno::deno_get_data(d) }; - let deno_ptr = ptr as *mut Deno; - let deno_box = unsafe { Box::from_raw(deno_ptr) }; - Box::leak(deno_box) -} - -#[test] -fn test_c_to_rust() { - let argv = vec![String::from("./deno"), String::from("hello.js")]; - let d = Deno::new(argv); - let d2 = from_c(d.ptr); - assert!(d.ptr == d2.ptr); - assert!(d.dir.root.join("gen") == d.dir.gen, "Sanity check"); -} static LOGGER: Logger = Logger; @@ -132,31 +50,31 @@ fn main() { let js_args = flags::v8_set_flags(env::args().collect()); - let mut d = Deno::new(js_args); - let mut log_level = log::LevelFilter::Info; + let mut isolate = Isolate::new(js_args); - if d.flags.help { + if isolate.flags.help { flags::print_usage(); std::process::exit(0); } - if d.flags.version { + if isolate.flags.version { version::print_version(); std::process::exit(0); } - if d.flags.log_debug { + let mut log_level = log::LevelFilter::Info; + if isolate.flags.log_debug { log_level = log::LevelFilter::Debug; } - log::set_max_level(log_level); - d.execute("deno_main.js", "denoMain();") + isolate + .execute("deno_main.js", "denoMain();") .unwrap_or_else(|err| { error!("{}", err); std::process::exit(1); }); // Start the Tokio event loop - d.rt.run().expect("err"); + isolate.rt.run().expect("err"); }