diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/examples/http_bench_bin_ops.rs | 23 | ||||
-rw-r--r-- | core/examples/http_bench_json_ops.rs | 22 | ||||
-rw-r--r-- | core/lib.rs | 3 | ||||
-rw-r--r-- | core/modules.rs | 38 | ||||
-rw-r--r-- | core/runtime.rs | 202 |
5 files changed, 127 insertions, 161 deletions
diff --git a/core/examples/http_bench_bin_ops.rs b/core/examples/http_bench_bin_ops.rs index b29af8b9d..2748705ea 100644 --- a/core/examples/http_bench_bin_ops.rs +++ b/core/examples/http_bench_bin_ops.rs @@ -6,8 +6,6 @@ use deno_core::BufVec; use deno_core::JsRuntime; use deno_core::Op; use deno_core::OpState; -use deno_core::Script; -use deno_core::StartupData; use deno_core::ZeroCopyBuf; use futures::future::poll_fn; use futures::future::FutureExt; @@ -78,12 +76,7 @@ impl From<Record> for RecordBuf { } fn create_isolate() -> JsRuntime { - let startup_data = StartupData::Script(Script { - source: include_str!("http_bench_bin_ops.js"), - filename: "http_bench_bin_ops.js", - }); - - let mut isolate = JsRuntime::new(startup_data, false); + let mut isolate = JsRuntime::new(Default::default()); register_op_bin_sync(&mut isolate, "listen", op_listen); register_op_bin_sync(&mut isolate, "close", op_close); register_op_bin_async(&mut isolate, "accept", op_accept); @@ -252,13 +245,23 @@ fn main() { // NOTE: `--help` arg will display V8 help and exit deno_core::v8_set_flags(env::args().collect()); - let isolate = create_isolate(); + let mut isolate = create_isolate(); let mut runtime = runtime::Builder::new() .basic_scheduler() .enable_all() .build() .unwrap(); - js_check(runtime.block_on(isolate)); + + let future = async move { + isolate + .execute( + "http_bench_bin_ops.js", + include_str!("http_bench_bin_ops.js"), + ) + .unwrap(); + isolate.await + }; + js_check(runtime.block_on(future)); } #[test] diff --git a/core/examples/http_bench_json_ops.rs b/core/examples/http_bench_json_ops.rs index dc0c837e2..a7db450e4 100644 --- a/core/examples/http_bench_json_ops.rs +++ b/core/examples/http_bench_json_ops.rs @@ -6,8 +6,6 @@ use deno_core::BufVec; use deno_core::ErrBox; use deno_core::JsRuntime; use deno_core::OpState; -use deno_core::Script; -use deno_core::StartupData; use deno_core::ZeroCopyBuf; use futures::future::poll_fn; use futures::future::Future; @@ -42,11 +40,7 @@ impl log::Log for Logger { } fn create_isolate() -> JsRuntime { - let startup_data = StartupData::Script(Script { - source: include_str!("http_bench_json_ops.js"), - filename: "http_bench_json_ops.js", - }); - let mut runtime = JsRuntime::new(startup_data, false); + let mut runtime = JsRuntime::new(Default::default()); runtime.register_op("listen", deno_core::json_op_sync(op_listen)); runtime.register_op("close", deno_core::json_op_sync(op_close)); runtime.register_op("accept", deno_core::json_op_async(op_accept)); @@ -183,11 +177,21 @@ fn main() { // NOTE: `--help` arg will display V8 help and exit deno_core::v8_set_flags(env::args().collect()); - let isolate = create_isolate(); + let mut isolate = create_isolate(); let mut runtime = runtime::Builder::new() .basic_scheduler() .enable_all() .build() .unwrap(); - js_check(runtime.block_on(isolate)); + + let future = async move { + isolate + .execute( + "http_bench_json_ops.js", + include_str!("http_bench_json_ops.js"), + ) + .unwrap(); + isolate.await + }; + js_check(runtime.block_on(future)); } diff --git a/core/lib.rs b/core/lib.rs index 450b7378a..bb54f5133 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -51,9 +51,8 @@ pub use crate::runtime::GetErrorClassFn; pub use crate::runtime::HeapLimits; pub use crate::runtime::JsRuntime; pub use crate::runtime::JsRuntimeState; -pub use crate::runtime::Script; +pub use crate::runtime::RuntimeOptions; pub use crate::runtime::Snapshot; -pub use crate::runtime::StartupData; pub use crate::zero_copy_buf::BufVec; pub use crate::zero_copy_buf::ZeroCopyBuf; pub use serde_json; diff --git a/core/modules.rs b/core/modules.rs index 57068528d..eae2a8d9f 100644 --- a/core/modules.rs +++ b/core/modules.rs @@ -442,7 +442,7 @@ mod tests { use super::*; use crate::js_check; use crate::JsRuntime; - use crate::StartupData; + use crate::RuntimeOptions; use futures::future::FutureExt; use std::error::Error; use std::fmt; @@ -619,8 +619,10 @@ mod tests { fn test_recursive_load() { let loader = MockLoader::new(); let loads = loader.loads.clone(); - let mut runtime = - JsRuntime::new_with_loader(loader, StartupData::None, false); + let mut runtime = JsRuntime::new(RuntimeOptions { + module_loader: Some(loader), + ..Default::default() + }); let spec = ModuleSpecifier::resolve_url("file:///a.js").unwrap(); let a_id_fut = runtime.load_module(&spec, None); let a_id = futures::executor::block_on(a_id_fut).expect("Failed to load"); @@ -682,8 +684,10 @@ mod tests { fn test_circular_load() { let loader = MockLoader::new(); let loads = loader.loads.clone(); - let mut runtime = - JsRuntime::new_with_loader(loader, StartupData::None, false); + let mut runtime = JsRuntime::new(RuntimeOptions { + module_loader: Some(loader), + ..Default::default() + }); let fut = async move { let spec = ModuleSpecifier::resolve_url("file:///circular1.js").unwrap(); @@ -756,8 +760,10 @@ mod tests { fn test_redirect_load() { let loader = MockLoader::new(); let loads = loader.loads.clone(); - let mut runtime = - JsRuntime::new_with_loader(loader, StartupData::None, false); + let mut runtime = JsRuntime::new(RuntimeOptions { + module_loader: Some(loader), + ..Default::default() + }); let fut = async move { let spec = ModuleSpecifier::resolve_url("file:///redirect1.js").unwrap(); @@ -821,8 +827,10 @@ mod tests { run_in_task(|mut cx| { let loader = MockLoader::new(); let loads = loader.loads.clone(); - let mut runtime = - JsRuntime::new_with_loader(loader, StartupData::None, false); + let mut runtime = JsRuntime::new(RuntimeOptions { + module_loader: Some(loader), + ..Default::default() + }); let spec = ModuleSpecifier::resolve_url("file:///main.js").unwrap(); let mut recursive_load = runtime.load_module(&spec, None).boxed_local(); @@ -867,8 +875,10 @@ mod tests { fn loader_disappears_after_error() { run_in_task(|mut cx| { let loader = MockLoader::new(); - let mut runtime = - JsRuntime::new_with_loader(loader, StartupData::None, false); + let mut runtime = JsRuntime::new(RuntimeOptions { + module_loader: Some(loader), + ..Default::default() + }); let spec = ModuleSpecifier::resolve_url("file:///bad_import.js").unwrap(); let mut load_fut = runtime.load_module(&spec, None).boxed_local(); let result = load_fut.poll_unpin(&mut cx); @@ -896,8 +906,10 @@ mod tests { fn recursive_load_main_with_code() { let loader = MockLoader::new(); let loads = loader.loads.clone(); - let mut runtime = - JsRuntime::new_with_loader(loader, StartupData::None, false); + let mut runtime = JsRuntime::new(RuntimeOptions { + module_loader: Some(loader), + ..Default::default() + }); // In default resolution code should be empty. // Instead we explicitly pass in our own code. // The behavior should be very similar to /a.js. diff --git a/core/runtime.rs b/core/runtime.rs index e6fc23084..045613224 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -32,7 +32,6 @@ use std::any::Any; use std::cell::Cell; use std::cell::RefCell; use std::collections::HashMap; -use std::convert::From; use std::convert::TryFrom; use std::ffi::c_void; use std::mem::forget; @@ -47,52 +46,12 @@ use std::task::Poll; type PendingOpFuture = Pin<Box<dyn Future<Output = (OpId, Box<[u8]>)>>>; -/// Stores a script used to initialize a Isolate -pub struct Script<'a> { - pub source: &'a str, - pub filename: &'a str, -} - -// TODO(ry) It's ugly that we have both Script and OwnedScript. Ideally we -// wouldn't expose such twiddly complexity. -struct OwnedScript { - pub source: String, - pub filename: String, -} - -impl From<Script<'_>> for OwnedScript { - fn from(s: Script) -> OwnedScript { - OwnedScript { - source: s.source.to_string(), - filename: s.filename.to_string(), - } - } -} - pub enum Snapshot { Static(&'static [u8]), JustCreated(v8::StartupData), Boxed(Box<[u8]>), } -/// Represents data used to initialize an isolate at startup, either -/// in the form of a binary snapshot or a JavaScript source file. -pub enum StartupData<'a> { - Script(Script<'a>), - Snapshot(Snapshot), - None, -} - -impl StartupData<'_> { - fn into_options(self) -> (Option<OwnedScript>, Option<Snapshot>) { - match self { - Self::Script(script) => (Some(script.into()), None), - Self::Snapshot(snapshot) => (None, Some(snapshot)), - Self::None => (None, None), - } - } -} - type JsErrorCreateFn = dyn Fn(JsError) -> ErrBox; pub type GetErrorClassFn = &'static dyn for<'e> Fn(&'e ErrBox) -> &'static str; @@ -121,7 +80,6 @@ pub struct JsRuntime { snapshot_creator: Option<v8::SnapshotCreator>, has_snapshotted: bool, needs_init: bool, - startup_script: Option<OwnedScript>, allocations: IsolateAllocations, } @@ -219,48 +177,24 @@ pub struct HeapLimits { pub max: usize, } -pub(crate) struct IsolateOptions { - loader: Rc<dyn ModuleLoader>, - startup_script: Option<OwnedScript>, - startup_snapshot: Option<Snapshot>, - will_snapshot: bool, - heap_limits: Option<HeapLimits>, -} - -impl JsRuntime { - /// startup_data defines the snapshot or script used at startup to initialize - /// the isolate. - pub fn new(startup_data: StartupData, will_snapshot: bool) -> Self { - let (startup_script, startup_snapshot) = startup_data.into_options(); - let options = IsolateOptions { - loader: Rc::new(NoopModuleLoader), - startup_script, - startup_snapshot, - will_snapshot, - heap_limits: None, - }; - - Self::from_options(options) - } +#[derive(Default)] +pub struct RuntimeOptions { + /// Implementation of `ModuleLoader` which will be + /// called when V8 requests to load ES modules. + /// + /// If not provided runtime will error if code being + /// executed tries to load modules. + pub module_loader: Option<Rc<dyn ModuleLoader>>, - // TODO(bartlomieju): add `new_with_loader_and_heap_limits` function? - /// Create new isolate that can load and execute ESModules. - pub fn new_with_loader( - loader: Rc<dyn ModuleLoader>, - startup_data: StartupData, - will_snapshot: bool, - ) -> Self { - let (startup_script, startup_snapshot) = startup_data.into_options(); - let options = IsolateOptions { - loader, - startup_script, - startup_snapshot, - will_snapshot, - heap_limits: None, - }; + /// V8 snapshot that should be loaded on startup. + /// + /// Currently can't be used with `will_snapshot`. + pub startup_snapshot: Option<Snapshot>, - Self::from_options(options) - } + /// Prepare runtime to take snapshot of loaded code. + /// + /// Currently can't be used with `startup_snapshot`. + pub will_snapshot: bool, /// This is useful for controlling memory usage of scripts. /// @@ -268,23 +202,11 @@ impl JsRuntime { /// /// Make sure to use [`add_near_heap_limit_callback`](#method.add_near_heap_limit_callback) /// to prevent v8 from crashing when reaching the upper limit. - pub fn with_heap_limits( - startup_data: StartupData, - heap_limits: HeapLimits, - ) -> Self { - let (startup_script, startup_snapshot) = startup_data.into_options(); - let options = IsolateOptions { - loader: Rc::new(NoopModuleLoader), - startup_script, - startup_snapshot, - will_snapshot: false, - heap_limits: Some(heap_limits), - }; - - Self::from_options(options) - } + pub heap_limits: Option<HeapLimits>, +} - fn from_options(options: IsolateOptions) -> Self { +impl JsRuntime { + pub fn new(options: RuntimeOptions) -> Self { static DENO_INIT: Once = Once::new(); DENO_INIT.call_once(|| { unsafe { v8_init() }; @@ -339,6 +261,10 @@ impl JsRuntime { (isolate, None) }; + let loader = options + .module_loader + .unwrap_or_else(|| Rc::new(NoopModuleLoader)); + let op_state = OpState::default(); isolate.set_slot(Rc::new(RefCell::new(JsRuntimeState { @@ -354,7 +280,7 @@ impl JsRuntime { op_state: Rc::new(RefCell::new(op_state)), have_unpolled_ops: Cell::new(false), modules: Modules::new(), - loader: options.loader, + loader, dyn_import_map: HashMap::new(), preparing_dyn_imports: FuturesUnordered::new(), pending_dyn_imports: FuturesUnordered::new(), @@ -366,7 +292,6 @@ impl JsRuntime { snapshot_creator: maybe_snapshot_creator, has_snapshotted: false, needs_init: true, - startup_script: options.startup_script, allocations: IsolateAllocations::default(), } } @@ -393,10 +318,6 @@ impl JsRuntime { if self.needs_init { self.needs_init = false; js_check(self.execute("core.js", include_str!("core.js"))); - // Maybe execute the startup script. - if let Some(s) = self.startup_script.take() { - self.execute(&s.filename, &s.source).unwrap() - } } } @@ -1413,7 +1334,7 @@ pub mod tests { fn setup(mode: Mode) -> (JsRuntime, Arc<AtomicUsize>) { let dispatch_count = Arc::new(AtomicUsize::new(0)); - let mut runtime = JsRuntime::new(StartupData::None, false); + let mut runtime = JsRuntime::new(Default::default()); let op_state = runtime.op_state(); op_state.borrow_mut().put(TestState { mode, @@ -1784,7 +1705,7 @@ pub mod tests { #[test] fn syntax_error() { - let mut runtime = JsRuntime::new(StartupData::None, false); + let mut runtime = JsRuntime::new(Default::default()); let src = "hocuspocus("; let r = runtime.execute("i.js", src); let e = r.unwrap_err(); @@ -1809,27 +1730,39 @@ pub mod tests { #[test] fn will_snapshot() { let snapshot = { - let mut runtime = JsRuntime::new(StartupData::None, true); + let mut runtime = JsRuntime::new(RuntimeOptions { + will_snapshot: true, + ..Default::default() + }); js_check(runtime.execute("a.js", "a = 1 + 2")); runtime.snapshot() }; - let startup_data = StartupData::Snapshot(Snapshot::JustCreated(snapshot)); - let mut runtime2 = JsRuntime::new(startup_data, false); + let snapshot = Snapshot::JustCreated(snapshot); + let mut runtime2 = JsRuntime::new(RuntimeOptions { + startup_snapshot: Some(snapshot), + ..Default::default() + }); js_check(runtime2.execute("check.js", "if (a != 3) throw Error('x')")); } #[test] fn test_from_boxed_snapshot() { let snapshot = { - let mut runtime = JsRuntime::new(StartupData::None, true); + let mut runtime = JsRuntime::new(RuntimeOptions { + will_snapshot: true, + ..Default::default() + }); js_check(runtime.execute("a.js", "a = 1 + 2")); let snap: &[u8] = &*runtime.snapshot(); Vec::from(snap).into_boxed_slice() }; - let startup_data = StartupData::Snapshot(Snapshot::Boxed(snapshot)); - let mut runtime2 = JsRuntime::new(startup_data, false); + let snapshot = Snapshot::Boxed(snapshot); + let mut runtime2 = JsRuntime::new(RuntimeOptions { + startup_snapshot: Some(snapshot), + ..Default::default() + }); js_check(runtime2.execute("check.js", "if (a != 3) throw Error('x')")); } @@ -1839,8 +1772,10 @@ pub mod tests { initial: 0, max: 20 * 1024, // 20 kB }; - let mut runtime = - JsRuntime::with_heap_limits(StartupData::None, heap_limits); + let mut runtime = JsRuntime::new(RuntimeOptions { + heap_limits: Some(heap_limits), + ..Default::default() + }); let cb_handle = runtime.thread_safe_handle(); let callback_invoke_count = Rc::new(AtomicUsize::default()); @@ -1868,7 +1803,7 @@ pub mod tests { #[test] fn test_heap_limit_cb_remove() { - let mut runtime = JsRuntime::new(StartupData::None, false); + let mut runtime = JsRuntime::new(Default::default()); runtime.add_near_heap_limit_callback(|current_limit, _initial_limit| { current_limit * 2 @@ -1883,8 +1818,10 @@ pub mod tests { initial: 0, max: 20 * 1024, // 20 kB }; - let mut runtime = - JsRuntime::with_heap_limits(StartupData::None, heap_limits); + let mut runtime = JsRuntime::new(RuntimeOptions { + heap_limits: Some(heap_limits), + ..Default::default() + }); let cb_handle = runtime.thread_safe_handle(); let callback_invoke_count_first = Rc::new(AtomicUsize::default()); @@ -1966,8 +1903,10 @@ pub mod tests { Op::Async(futures::future::ready(buf).boxed()) }; - let mut runtime = - JsRuntime::new_with_loader(loader, StartupData::None, false); + let mut runtime = JsRuntime::new(RuntimeOptions { + module_loader: Some(loader), + ..Default::default() + }); runtime.register_op("test", dispatcher); js_check(runtime.execute( @@ -2062,8 +2001,10 @@ pub mod tests { run_in_task(|cx| { let loader = Rc::new(DynImportErrLoader::default()); let count = loader.count.clone(); - let mut runtime = - JsRuntime::new_with_loader(loader, StartupData::None, false); + let mut runtime = JsRuntime::new(RuntimeOptions { + module_loader: Some(loader), + ..Default::default() + }); js_check(runtime.execute( "file:///dyn_import2.js", @@ -2140,8 +2081,10 @@ pub mod tests { let prepare_load_count = loader.prepare_load_count.clone(); let resolve_count = loader.resolve_count.clone(); let load_count = loader.load_count.clone(); - let mut runtime = - JsRuntime::new_with_loader(loader, StartupData::None, false); + let mut runtime = JsRuntime::new(RuntimeOptions { + module_loader: Some(loader), + ..Default::default() + }); // Dynamically import mod_b js_check(runtime.execute( @@ -2181,8 +2124,10 @@ pub mod tests { run_in_task(|cx| { let loader = Rc::new(DynImportOkLoader::default()); let prepare_load_count = loader.prepare_load_count.clone(); - let mut runtime = - JsRuntime::new_with_loader(loader, StartupData::None, false); + let mut runtime = JsRuntime::new(RuntimeOptions { + module_loader: Some(loader), + ..Default::default() + }); js_check(runtime.execute( "file:///dyn_import3.js", r#" @@ -2233,8 +2178,11 @@ pub mod tests { } let loader = std::rc::Rc::new(ModsLoader::default()); - let mut runtime = - JsRuntime::new_with_loader(loader, StartupData::None, true); + let mut runtime = JsRuntime::new(RuntimeOptions { + module_loader: Some(loader), + will_snapshot: true, + ..Default::default() + }); let specifier = ModuleSpecifier::resolve_url("file:///main.js").unwrap(); let source_code = "Deno.core.print('hello\\n')".to_string(); |