Rename Deno to Isolate and move to own file.

This commit is contained in:
Ryan Dahl 2018-09-17 17:41:13 -07:00
parent e3d634eb21
commit 6143a64256
3 changed files with 153 additions and 136 deletions

View file

@ -2,13 +2,13 @@
use errors::DenoError; use errors::DenoError;
use errors::DenoResult; use errors::DenoResult;
use flatbuffers::FlatBufferBuilder; use flatbuffers::FlatBufferBuilder;
use from_c;
use fs as deno_fs; use fs as deno_fs;
use futures; use futures;
use futures::sync::oneshot; use futures::sync::oneshot;
use hyper; use hyper;
use hyper::rt::{Future, Stream}; use hyper::rt::{Future, Stream};
use hyper::Client; use hyper::Client;
use isolate::from_c;
use libdeno; use libdeno;
use libdeno::{deno_buf, DenoC}; use libdeno::{deno_buf, DenoC};
use msg; 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() { if base.sync() {
// Execute future synchronously. // Execute future synchronously.
// println!("sync handler {}", msg::enum_name_any(msg_type)); // 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 => {} None => {}
Some(box_u8) => { Some(box_u8) => {
let buf = deno_buf_from(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) } 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) }; unsafe { libdeno::deno_send(d, buf) };
Ok(()) Ok(())
}); });
deno.rt.spawn(future); isolate.rt.spawn(future);
} }
} }
@ -148,10 +148,10 @@ fn handle_exit(_d: *const DenoC, base: &msg::Base) -> Box<Op> {
} }
fn handle_start(d: *const DenoC, base: &msg::Base) -> Box<Op> { fn handle_start(d: *const DenoC, base: &msg::Base) -> Box<Op> {
let deno = from_c(d); let isolate = from_c(d);
let mut builder = FlatBufferBuilder::new(); let mut builder = FlatBufferBuilder::new();
let argv = deno.argv.iter().map(|s| s.as_str()).collect::<Vec<_>>(); let argv = isolate.argv.iter().map(|s| s.as_str()).collect::<Vec<_>>();
let argv_off = builder.create_vector_of_strings(argv.as_slice()); let argv_off = builder.create_vector_of_strings(argv.as_slice());
let cwd_path = std::env::current_dir().unwrap(); let cwd_path = std::env::current_dir().unwrap();
@ -163,7 +163,7 @@ fn handle_start(d: *const DenoC, base: &msg::Base) -> Box<Op> {
&msg::StartResArgs { &msg::StartResArgs {
cwd: Some(cwd_off), cwd: Some(cwd_off),
argv: Some(argv_off), argv: Some(argv_off),
debug_flag: deno.flags.log_debug, debug_flag: isolate.flags.log_debug,
..Default::default() ..Default::default()
}, },
); );
@ -202,19 +202,23 @@ fn odd_future(err: DenoError) -> Box<Op> {
Box::new(futures::future::err(err)) 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<Op> { fn handle_code_fetch(d: *const DenoC, base: &msg::Base) -> Box<Op> {
let msg = base.msg_as_code_fetch().unwrap(); let msg = base.msg_as_code_fetch().unwrap();
let cmd_id = base.cmd_id(); let cmd_id = base.cmd_id();
let module_specifier = msg.module_specifier().unwrap(); let module_specifier = msg.module_specifier().unwrap();
let containing_file = msg.containing_file().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 { Box::new(futures::future::result(|| -> OpResult {
let builder = &mut FlatBufferBuilder::new(); 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 { let mut msg_args = msg::CodeFetchResArgs {
module_name: Some(builder.create_string(&out.module_name)), module_name: Some(builder.create_string(&out.module_name)),
filename: Some(builder.create_string(&out.filename)), filename: Some(builder.create_string(&out.filename)),
@ -240,15 +244,15 @@ fn handle_code_fetch(d: *const DenoC, base: &msg::Base) -> Box<Op> {
}())) }()))
} }
// 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<Op> { fn handle_code_cache(d: *const DenoC, base: &msg::Base) -> Box<Op> {
let msg = base.msg_as_code_cache().unwrap(); let msg = base.msg_as_code_cache().unwrap();
let filename = msg.filename().unwrap(); let filename = msg.filename().unwrap();
let source_code = msg.source_code().unwrap(); let source_code = msg.source_code().unwrap();
let output_code = msg.output_code().unwrap(); let output_code = msg.output_code().unwrap();
Box::new(futures::future::result(|| -> OpResult { Box::new(futures::future::result(|| -> OpResult {
let deno = from_c(d); let isolate = from_c(d);
deno.dir.code_cache(filename, source_code, output_code)?; isolate.dir.code_cache(filename, source_code, output_code)?;
Ok(None) Ok(None)
}())) }()))
} }
@ -258,8 +262,8 @@ fn handle_set_env(d: *const DenoC, base: &msg::Base) -> Box<Op> {
let key = msg.key().unwrap(); let key = msg.key().unwrap();
let value = msg.value().unwrap(); let value = msg.value().unwrap();
let deno = from_c(d); let isolate = from_c(d);
if !deno.flags.allow_env { if !isolate.flags.allow_env {
return odd_future(permission_denied()); return odd_future(permission_denied());
} }
@ -268,9 +272,9 @@ fn handle_set_env(d: *const DenoC, base: &msg::Base) -> Box<Op> {
} }
fn handle_env(d: *const DenoC, base: &msg::Base) -> Box<Op> { fn handle_env(d: *const DenoC, base: &msg::Base) -> Box<Op> {
let deno = from_c(d); let isolate = from_c(d);
let cmd_id = base.cmd_id(); let cmd_id = base.cmd_id();
if !deno.flags.allow_env { if !isolate.flags.allow_env {
return odd_future(permission_denied()); return odd_future(permission_denied());
} }
@ -288,8 +292,7 @@ fn handle_env(d: *const DenoC, base: &msg::Base) -> Box<Op> {
..Default::default() ..Default::default()
}, },
) )
}) }).collect();
.collect();
let tables = builder.create_vector(&vars); let tables = builder.create_vector(&vars);
let msg = msg::EnvironRes::create( let msg = msg::EnvironRes::create(
builder, builder,
@ -314,9 +317,9 @@ fn handle_fetch_req(d: *const DenoC, base: &msg::Base) -> Box<Op> {
let cmd_id = base.cmd_id(); let cmd_id = base.cmd_id();
let id = msg.id(); let id = msg.id();
let url = msg.url().unwrap(); 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()); return odd_future(permission_denied());
} }
@ -402,8 +405,7 @@ where
.and_then(|_| { .and_then(|_| {
cb(); cb();
Ok(()) Ok(())
}) }).select(cancel_rx)
.select(cancel_rx)
.map(|_| ()) .map(|_| ())
.map_err(|_| ()); .map_err(|_| ());
@ -418,14 +420,14 @@ fn handle_make_temp_dir(d: *const DenoC, base: &msg::Base) -> Box<Op> {
let prefix = msg.prefix(); let prefix = msg.prefix();
let suffix = msg.suffix(); let suffix = msg.suffix();
let deno = from_c(d); let isolate = from_c(d);
if !deno.flags.allow_write { if !isolate.flags.allow_write {
return odd_future(permission_denied()); return odd_future(permission_denied());
} }
// TODO Use blocking() here. // TODO Use blocking() here.
Box::new(futures::future::result(|| -> OpResult { Box::new(futures::future::result(|| -> OpResult {
// TODO(piscisaureus): use byte vector for paths, not a string. // 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. // 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 path = deno_fs::make_temp_dir(dir.map(Path::new), prefix, suffix)?;
let builder = &mut FlatBufferBuilder::new(); let builder = &mut FlatBufferBuilder::new();
@ -453,8 +455,8 @@ fn handle_mkdir(d: *const DenoC, base: &msg::Base) -> Box<Op> {
let msg = base.msg_as_mkdir().unwrap(); let msg = base.msg_as_mkdir().unwrap();
let mode = msg.mode(); let mode = msg.mode();
let path = msg.path().unwrap(); let path = msg.path().unwrap();
let deno = from_c(d); let isolate = from_c(d);
if !deno.flags.allow_write { if !isolate.flags.allow_write {
return odd_future(permission_denied()); return odd_future(permission_denied());
} }
// TODO Use tokio_threadpool. // TODO Use tokio_threadpool.
@ -469,8 +471,8 @@ fn handle_remove(d: *const DenoC, base: &msg::Base) -> Box<Op> {
let msg = base.msg_as_remove().unwrap(); let msg = base.msg_as_remove().unwrap();
let path = msg.path().unwrap(); let path = msg.path().unwrap();
let recursive = msg.recursive(); let recursive = msg.recursive();
let deno = from_c(d); let isolate = from_c(d);
if !deno.flags.allow_write { if !isolate.flags.allow_write {
return odd_future(permission_denied()); return odd_future(permission_denied());
} }
// TODO Use tokio_threadpool. // TODO Use tokio_threadpool.
@ -491,7 +493,7 @@ fn handle_remove(d: *const DenoC, base: &msg::Base) -> Box<Op> {
}())) }()))
} }
// 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<Op> { fn handle_read_file(_d: *const DenoC, base: &msg::Base) -> Box<Op> {
let msg = base.msg_as_read_file().unwrap(); let msg = base.msg_as_read_file().unwrap();
let cmd_id = base.cmd_id(); let cmd_id = base.cmd_id();
@ -591,8 +593,8 @@ fn handle_write_file(d: *const DenoC, base: &msg::Base) -> Box<Op> {
let data = msg.data().unwrap(); let data = msg.data().unwrap();
let perm = msg.perm(); let perm = msg.perm();
let deno = from_c(d); let isolate = from_c(d);
if !deno.flags.allow_write { if !isolate.flags.allow_write {
return odd_future(permission_denied()); return odd_future(permission_denied());
} }
Box::new(futures::future::result(|| -> OpResult { Box::new(futures::future::result(|| -> OpResult {
@ -602,20 +604,20 @@ fn handle_write_file(d: *const DenoC, base: &msg::Base) -> Box<Op> {
}())) }()))
} }
// 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) { fn remove_timer(d: *const DenoC, timer_id: u32) {
let deno = from_c(d); let isolate = from_c(d);
deno.timers.remove(&timer_id); 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<Op> { fn handle_timer_start(d: *const DenoC, base: &msg::Base) -> Box<Op> {
debug!("handle_timer_start"); debug!("handle_timer_start");
let msg = base.msg_as_timer_start().unwrap(); let msg = base.msg_as_timer_start().unwrap();
let cmd_id = base.cmd_id(); let cmd_id = base.cmd_id();
let timer_id = msg.id(); let timer_id = msg.id();
let delay = msg.delay(); let delay = msg.delay();
let deno = from_c(d); let isolate = from_c(d);
let future = { let future = {
let (delay_task, cancel_delay) = set_timeout( let (delay_task, cancel_delay) = set_timeout(
@ -624,7 +626,7 @@ fn handle_timer_start(d: *const DenoC, base: &msg::Base) -> Box<Op> {
}, },
delay, delay,
); );
deno.timers.insert(timer_id, cancel_delay); isolate.timers.insert(timer_id, cancel_delay);
delay_task delay_task
}; };
Box::new(future.then(move |result| { Box::new(future.then(move |result| {
@ -649,7 +651,7 @@ fn handle_timer_start(d: *const DenoC, base: &msg::Base) -> Box<Op> {
})) }))
} }
// 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<Op> { fn handle_timer_clear(d: *const DenoC, base: &msg::Base) -> Box<Op> {
let msg = base.msg_as_timer_clear().unwrap(); let msg = base.msg_as_timer_clear().unwrap();
debug!("handle_timer_clear"); debug!("handle_timer_clear");
@ -658,8 +660,8 @@ fn handle_timer_clear(d: *const DenoC, base: &msg::Base) -> Box<Op> {
} }
fn handle_rename(d: *const DenoC, base: &msg::Base) -> Box<Op> { fn handle_rename(d: *const DenoC, base: &msg::Base) -> Box<Op> {
let deno = from_c(d); let isolate = from_c(d);
if !deno.flags.allow_write { if !isolate.flags.allow_write {
return odd_future(permission_denied()); return odd_future(permission_denied());
}; };
let msg = base.msg_as_rename().unwrap(); let msg = base.msg_as_rename().unwrap();

97
src/isolate.rs Normal file
View file

@ -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<u32, futures::sync::oneshot::Sender<()>>,
pub argv: Vec<String>,
pub flags: flags::DenoFlags,
}
static DENO_INIT: std::sync::Once = std::sync::ONCE_INIT;
impl Isolate {
pub fn new(argv: Vec<String>) -> Box<Isolate> {
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"
);
}

View file

@ -1,3 +1,4 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
extern crate flatbuffers; extern crate flatbuffers;
extern crate futures; extern crate futures;
extern crate hyper; extern crate hyper;
@ -19,96 +20,13 @@ mod errors;
mod flags; mod flags;
mod fs; mod fs;
pub mod handlers; pub mod handlers;
mod isolate;
mod libdeno; mod libdeno;
mod net; mod net;
mod version; mod version;
use libc::c_void; use isolate::Isolate;
use std::collections::HashMap;
use std::env; 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<u32, futures::sync::oneshot::Sender<()>>,
argv: Vec<String>,
flags: flags::DenoFlags,
}
static DENO_INIT: std::sync::Once = std::sync::ONCE_INIT;
impl Deno {
fn new(argv: Vec<String>) -> Box<Deno> {
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; static LOGGER: Logger = Logger;
@ -132,31 +50,31 @@ fn main() {
let js_args = flags::v8_set_flags(env::args().collect()); let js_args = flags::v8_set_flags(env::args().collect());
let mut d = Deno::new(js_args); let mut isolate = Isolate::new(js_args);
let mut log_level = log::LevelFilter::Info;
if d.flags.help { if isolate.flags.help {
flags::print_usage(); flags::print_usage();
std::process::exit(0); std::process::exit(0);
} }
if d.flags.version { if isolate.flags.version {
version::print_version(); version::print_version();
std::process::exit(0); 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_level = log::LevelFilter::Debug;
} }
log::set_max_level(log_level); log::set_max_level(log_level);
d.execute("deno_main.js", "denoMain();") isolate
.execute("deno_main.js", "denoMain();")
.unwrap_or_else(|err| { .unwrap_or_else(|err| {
error!("{}", err); error!("{}", err);
std::process::exit(1); std::process::exit(1);
}); });
// Start the Tokio event loop // Start the Tokio event loop
d.rt.run().expect("err"); isolate.rt.run().expect("err");
} }