1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-03 12:58:54 -05:00

Re-implement init scripts in core (#1958)

Re-enables arm64 CI test
This commit is contained in:
andy finch 2019-03-18 20:03:37 -04:00 committed by Ryan Dahl
parent 34a2aa4de6
commit cdfd32dd74
10 changed files with 90 additions and 116 deletions

View file

@ -131,8 +131,7 @@ jobs:
- sudo apt -yq install qemu qemu-user binfmt-support qemu-user-binfmt - sudo apt -yq install qemu qemu-user binfmt-support qemu-user-binfmt
- sudo ln -s /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 /lib/ld-linux-aarch64.so.1 - sudo ln -s /usr/aarch64-linux-gnu/lib/ld-linux-aarch64.so.1 /lib/ld-linux-aarch64.so.1
- export QEMU_LD_PREFIX=/usr/aarch64-linux-gnu - export QEMU_LD_PREFIX=/usr/aarch64-linux-gnu
# TODO(ry) Temp disabling arm test to make progress on core integration. - $CARGO_TARGET_DIR/aarch64-unknown-linux-gnu/release/deno tests/002_hello.ts
#- $CARGO_TARGET_DIR/aarch64-unknown-linux-gnu/release/deno tests/002_hello.ts
# - DENO_BUILD_MODE=release ./tools/test.py $CARGO_TARGET_DIR/aarch64-unknown-linux-gnu/release TODO(afinch7): Get the tests working # - DENO_BUILD_MODE=release ./tools/test.py $CARGO_TARGET_DIR/aarch64-unknown-linux-gnu/release TODO(afinch7): Get the tests working
- name: "cargo release linux x86_64" - name: "cargo release linux x86_64"

View file

@ -99,8 +99,13 @@ pub type HttpBenchOp = dyn Future<Item = i32, Error = std::io::Error> + Send;
struct HttpBench(); struct HttpBench();
impl Behavior for HttpBench { impl Behavior for HttpBench {
fn startup_snapshot(&mut self) -> Option<deno_buf> { fn startup_data(&mut self) -> Option<StartupData> {
None let js_source = include_str!("http_bench.js");
Some(StartupData::Script(StartupScript {
source: js_source.to_string(),
filename: "http_bench.js".to_string(),
}))
} }
fn resolve(&mut self, _specifier: &str, _referrer: deno_mod) -> deno_mod { fn resolve(&mut self, _specifier: &str, _referrer: deno_mod) -> deno_mod {
@ -164,15 +169,12 @@ impl Behavior for HttpBench {
} }
fn main() { fn main() {
let js_source = include_str!("http_bench.js");
let main_future = lazy(move || { let main_future = lazy(move || {
let mut isolate = deno_core::Isolate::new(HttpBench());
// TODO currently isolate.execute() must be run inside tokio, hence the // TODO currently isolate.execute() must be run inside tokio, hence the
// lazy(). It would be nice to not have that contraint. Probably requires // lazy(). It would be nice to not have that contraint. Probably requires
// using v8::MicrotasksPolicy::kExplicit // using v8::MicrotasksPolicy::kExplicit
js_check(isolate.execute("http_bench.js", js_source)); let isolate = deno_core::Isolate::new(HttpBench());
isolate.then(|r| { isolate.then(|r| {
js_check(r); js_check(r);
Ok(()) Ok(())

View file

@ -42,11 +42,26 @@ impl Future for PendingOp {
} }
} }
/// Stores a script used to initalize a Isolate
pub struct StartupScript {
pub source: String,
pub filename: String,
}
/// Represents data used to initialize isolate at startup
/// either a binary snapshot or a javascript source file
/// in the form of the StartupScript struct.
pub enum StartupData {
Script(StartupScript),
Snapshot(deno_buf),
}
/// Defines the behavior of an Isolate. /// Defines the behavior of an Isolate.
pub trait Behavior { pub trait Behavior {
/// Called exactly once when an Isolate is created to retrieve the startup /// Allow for a behavior to define the snapshot or script used at
/// snapshot. /// startup to initalize the isolate. Called exactly once when an
fn startup_snapshot(&mut self) -> Option<deno_buf>; /// Isolate is created.
fn startup_data(&mut self) -> Option<StartupData>;
/// Called during mod_instantiate() to resolve imports. /// Called during mod_instantiate() to resolve imports.
fn resolve(&mut self, specifier: &str, referrer: deno_mod) -> deno_mod; fn resolve(&mut self, specifier: &str, referrer: deno_mod) -> deno_mod;
@ -96,9 +111,15 @@ impl<B: Behavior> Isolate<B> {
let shared = SharedQueue::new(RECOMMENDED_SIZE); let shared = SharedQueue::new(RECOMMENDED_SIZE);
let needs_init = true; let needs_init = true;
// Seperate into Option values for eatch startup type
let (startup_snapshot, startup_script) = match behavior.startup_data() {
Some(StartupData::Snapshot(d)) => (Some(d), None),
Some(StartupData::Script(d)) => (None, Some(d)),
None => (None, None),
};
let config = libdeno::deno_config { let config = libdeno::deno_config {
will_snapshot: 0, will_snapshot: 0,
load_snapshot: match behavior.startup_snapshot() { load_snapshot: match startup_snapshot {
Some(s) => s, Some(s) => s,
None => libdeno::deno_buf::empty(), None => libdeno::deno_buf::empty(),
}, },
@ -107,14 +128,24 @@ impl<B: Behavior> Isolate<B> {
}; };
let libdeno_isolate = unsafe { libdeno::deno_new(config) }; let libdeno_isolate = unsafe { libdeno::deno_new(config) };
Self { let mut core_isolate = Self {
libdeno_isolate, libdeno_isolate,
behavior, behavior,
shared, shared,
needs_init, needs_init,
pending_ops: Vec::new(), pending_ops: Vec::new(),
polled_recently: false, polled_recently: false,
} };
// If we want to use execute this has to happen here sadly.
match startup_script {
Some(s) => core_isolate
.execute(s.filename.as_str(), s.source.as_str())
.unwrap(),
None => {}
};
core_isolate
} }
/// Executes a bit of built-in JavaScript to provide Deno._sharedQueue. /// Executes a bit of built-in JavaScript to provide Deno._sharedQueue.
@ -475,7 +506,7 @@ mod tests {
} }
impl Behavior for TestBehavior { impl Behavior for TestBehavior {
fn startup_snapshot(&mut self) -> Option<deno_buf> { fn startup_data(&mut self) -> Option<StartupData> {
None None
} }

View file

@ -3,7 +3,6 @@
#![allow(dead_code)] #![allow(dead_code)]
use crate::errors::DenoResult; use crate::errors::DenoResult;
use crate::isolate_init::IsolateInit;
use crate::isolate_state::IsolateState; use crate::isolate_state::IsolateState;
use crate::ops; use crate::ops;
use crate::permissions::DenoPermissions; use crate::permissions::DenoPermissions;
@ -11,6 +10,7 @@ use deno_core::deno_buf;
use deno_core::deno_mod; use deno_core::deno_mod;
use deno_core::Behavior; use deno_core::Behavior;
use deno_core::Op; use deno_core::Op;
use deno_core::StartupData;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::sync::Arc; use std::sync::Arc;
@ -21,19 +21,19 @@ pub type Buf = Box<[u8]>;
/// Implements deno_core::Behavior for the main Deno command-line. /// Implements deno_core::Behavior for the main Deno command-line.
pub struct Cli { pub struct Cli {
init: IsolateInit, startup_data: Option<StartupData>,
pub state: Arc<IsolateState>, pub state: Arc<IsolateState>,
pub permissions: Arc<DenoPermissions>, // TODO(ry) move to IsolateState pub permissions: Arc<DenoPermissions>, // TODO(ry) move to IsolateState
} }
impl Cli { impl Cli {
pub fn new( pub fn new(
init: IsolateInit, startup_data: Option<StartupData>,
state: Arc<IsolateState>, state: Arc<IsolateState>,
permissions: DenoPermissions, permissions: DenoPermissions,
) -> Self { ) -> Self {
Self { Self {
init, startup_data,
state, state,
permissions: Arc::new(permissions), permissions: Arc::new(permissions),
} }
@ -66,8 +66,8 @@ impl Cli {
} }
impl Behavior for Cli { impl Behavior for Cli {
fn startup_snapshot(&mut self) -> Option<deno_buf> { fn startup_data(&mut self) -> Option<StartupData> {
self.init.snapshot.take() self.startup_data.take()
} }
fn resolve(&mut self, specifier: &str, referrer: deno_mod) -> deno_mod { fn resolve(&mut self, specifier: &str, referrer: deno_mod) -> deno_mod {

View file

@ -1,12 +1,12 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
use crate::cli::Buf; use crate::cli::Buf;
use crate::isolate_init;
use crate::isolate_state::IsolateState; use crate::isolate_state::IsolateState;
use crate::msg; use crate::msg;
use crate::permissions::{DenoPermissions, PermissionAccessor}; use crate::permissions::{DenoPermissions, PermissionAccessor};
use crate::resources; use crate::resources;
use crate::resources::Resource; use crate::resources::Resource;
use crate::resources::ResourceId; use crate::resources::ResourceId;
use crate::startup_data;
use crate::workers; use crate::workers;
use futures::Future; use futures::Future;
use serde_json; use serde_json;
@ -48,7 +48,7 @@ impl ModuleMetaData {
fn lazy_start(parent_state: &IsolateState) -> Resource { fn lazy_start(parent_state: &IsolateState) -> Resource {
let mut cell = C_RID.lock().unwrap(); let mut cell = C_RID.lock().unwrap();
let isolate_init = isolate_init::compiler_isolate_init(); let startup_data = startup_data::compiler_isolate_init();
let permissions = DenoPermissions { let permissions = DenoPermissions {
allow_read: PermissionAccessor::from(true), allow_read: PermissionAccessor::from(true),
allow_write: PermissionAccessor::from(true), allow_write: PermissionAccessor::from(true),
@ -58,7 +58,7 @@ fn lazy_start(parent_state: &IsolateState) -> Resource {
let rid = cell.get_or_insert_with(|| { let rid = cell.get_or_insert_with(|| {
let resource = workers::spawn( let resource = workers::spawn(
isolate_init, Some(startup_data),
parent_state, parent_state,
"compilerMain()".to_string(), "compilerMain()".to_string(),
permissions, permissions,

View file

@ -181,7 +181,6 @@ fn fetch_module_meta_data_and_maybe_compile(
mod tests { mod tests {
use super::*; use super::*;
use crate::flags; use crate::flags;
use crate::isolate_init::IsolateInit;
use crate::permissions::DenoPermissions; use crate::permissions::DenoPermissions;
use crate::tokio_util; use crate::tokio_util;
use futures::future::lazy; use futures::future::lazy;
@ -199,12 +198,8 @@ mod tests {
let state = Arc::new(IsolateState::new(flags, rest_argv, None)); let state = Arc::new(IsolateState::new(flags, rest_argv, None));
let state_ = state.clone(); let state_ = state.clone();
let init = IsolateInit {
snapshot: None,
init_script: None,
};
tokio_util::run(lazy(move || { tokio_util::run(lazy(move || {
let cli = Cli::new(init, state.clone(), DenoPermissions::default()); let cli = Cli::new(None, state.clone(), DenoPermissions::default());
let mut isolate = Isolate::new(cli); let mut isolate = Isolate::new(cli);
if let Err(err) = isolate.execute_mod(&filename, false) { if let Err(err) = isolate.execute_mod(&filename, false) {
eprintln!("execute_mod err {:?}", err); eprintln!("execute_mod err {:?}", err);
@ -226,12 +221,8 @@ mod tests {
let state = Arc::new(IsolateState::new(flags, rest_argv, None)); let state = Arc::new(IsolateState::new(flags, rest_argv, None));
let state_ = state.clone(); let state_ = state.clone();
let init = IsolateInit {
snapshot: None,
init_script: None,
};
tokio_util::run(lazy(move || { tokio_util::run(lazy(move || {
let cli = Cli::new(init, state.clone(), DenoPermissions::default()); let cli = Cli::new(None, state.clone(), DenoPermissions::default());
let mut isolate = Isolate::new(cli); let mut isolate = Isolate::new(cli);
if let Err(err) = isolate.execute_mod(&filename, false) { if let Err(err) = isolate.execute_mod(&filename, false) {
eprintln!("execute_mod err {:?}", err); eprintln!("execute_mod err {:?}", err);

View file

@ -19,7 +19,6 @@ mod global_timer;
mod http_body; mod http_body;
mod http_util; mod http_util;
pub mod isolate; pub mod isolate;
pub mod isolate_init;
pub mod isolate_state; pub mod isolate_state;
pub mod js_errors; pub mod js_errors;
pub mod modules; pub mod modules;
@ -30,6 +29,7 @@ pub mod permissions;
mod repl; mod repl;
pub mod resolve_addr; pub mod resolve_addr;
pub mod resources; pub mod resources;
mod startup_data;
mod tokio_util; mod tokio_util;
mod tokio_write; mod tokio_write;
pub mod version; pub mod version;
@ -110,9 +110,9 @@ fn main() {
let state = Arc::new(IsolateState::new(flags, rest_argv, None)); let state = Arc::new(IsolateState::new(flags, rest_argv, None));
let state_ = state.clone(); let state_ = state.clone();
let isolate_init = isolate_init::deno_isolate_init(); let startup_data = startup_data::deno_isolate_init();
let permissions = permissions::DenoPermissions::from_flags(&state.flags); let permissions = permissions::DenoPermissions::from_flags(&state.flags);
let cli = Cli::new(isolate_init, state_, permissions); let cli = Cli::new(Some(startup_data), state_, permissions);
let mut isolate = Isolate::new(cli); let mut isolate = Isolate::new(cli);
let main_future = lazy(move || { let main_future = lazy(move || {

View file

@ -1880,7 +1880,7 @@ fn op_worker_post_message(
mod tests { mod tests {
use super::*; use super::*;
use crate::cli::Cli; use crate::cli::Cli;
use crate::isolate_init::IsolateInit; use crate::isolate_state::IsolateState;
use crate::permissions::{DenoPermissions, PermissionAccessor}; use crate::permissions::{DenoPermissions, PermissionAccessor};
#[test] #[test]
@ -1893,14 +1893,7 @@ mod tests {
allow_run: PermissionAccessor::from(true), allow_run: PermissionAccessor::from(true),
..Default::default() ..Default::default()
}; };
let cli = Cli::new( let cli = Cli::new(None, state, permissions);
IsolateInit {
snapshot: None,
init_script: None,
},
state,
permissions,
);
let builder = &mut FlatBufferBuilder::new(); let builder = &mut FlatBufferBuilder::new();
let fetch_msg_args = msg::FetchModuleMetaDataArgs { let fetch_msg_args = msg::FetchModuleMetaDataArgs {
specifier: Some(builder.create_string("./somefile")), specifier: Some(builder.create_string("./somefile")),
@ -1934,14 +1927,7 @@ mod tests {
allow_run: PermissionAccessor::from(true), allow_run: PermissionAccessor::from(true),
..Default::default() ..Default::default()
}; };
let cli = Cli::new( let cli = Cli::new(None, state, permissions);
IsolateInit {
snapshot: None,
init_script: None,
},
state,
permissions,
);
let builder = &mut FlatBufferBuilder::new(); let builder = &mut FlatBufferBuilder::new();
let fetch_msg_args = msg::FetchModuleMetaDataArgs { let fetch_msg_args = msg::FetchModuleMetaDataArgs {
specifier: Some(builder.create_string("./somefile")), specifier: Some(builder.create_string("./somefile")),
@ -1975,14 +1961,7 @@ mod tests {
allow_run: PermissionAccessor::from(true), allow_run: PermissionAccessor::from(true),
..Default::default() ..Default::default()
}; };
let cli = Cli::new( let cli = Cli::new(None, state, permissions);
IsolateInit {
snapshot: None,
init_script: None,
},
state,
permissions,
);
let builder = &mut FlatBufferBuilder::new(); let builder = &mut FlatBufferBuilder::new();
let fetch_msg_args = msg::FetchModuleMetaDataArgs { let fetch_msg_args = msg::FetchModuleMetaDataArgs {
specifier: Some(builder.create_string("./somefile")), specifier: Some(builder.create_string("./somefile")),
@ -2015,14 +1994,7 @@ mod tests {
allow_net: PermissionAccessor::from(true), allow_net: PermissionAccessor::from(true),
..Default::default() ..Default::default()
}; };
let cli = Cli::new( let cli = Cli::new(None, state, permissions);
IsolateInit {
snapshot: None,
init_script: None,
},
state,
permissions,
);
let builder = &mut FlatBufferBuilder::new(); let builder = &mut FlatBufferBuilder::new();
let fetch_msg_args = msg::FetchModuleMetaDataArgs { let fetch_msg_args = msg::FetchModuleMetaDataArgs {
specifier: Some(builder.create_string("./somefile")), specifier: Some(builder.create_string("./somefile")),

View file

@ -1,17 +1,8 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
use deno_core::deno_buf; use deno_core::deno_buf;
use deno_core::{StartupData, StartupScript};
pub struct IsolateInitScript { pub fn deno_isolate_init() -> StartupData {
pub source: String,
pub filename: String,
}
pub struct IsolateInit {
pub snapshot: Option<deno_buf>,
pub init_script: Option<IsolateInitScript>,
}
pub fn deno_isolate_init() -> IsolateInit {
if cfg!(feature = "no-snapshot-init") { if cfg!(feature = "no-snapshot-init") {
debug!("Deno isolate init without snapshots."); debug!("Deno isolate init without snapshots.");
#[cfg(not(feature = "check-only"))] #[cfg(not(feature = "check-only"))]
@ -20,13 +11,10 @@ pub fn deno_isolate_init() -> IsolateInit {
#[cfg(feature = "check-only")] #[cfg(feature = "check-only")]
let source_bytes = vec![]; let source_bytes = vec![];
IsolateInit { StartupData::Script(StartupScript {
snapshot: None,
init_script: Some(IsolateInitScript {
filename: "gen/bundle/main.js".to_string(), filename: "gen/bundle/main.js".to_string(),
source: std::str::from_utf8(source_bytes).unwrap().to_string(), source: std::str::from_utf8(source_bytes).unwrap().to_string(),
}), })
}
} else { } else {
debug!("Deno isolate init with snapshots."); debug!("Deno isolate init with snapshots.");
#[cfg(not(any(feature = "check-only", feature = "no-snapshot-init")))] #[cfg(not(any(feature = "check-only", feature = "no-snapshot-init")))]
@ -36,15 +24,12 @@ pub fn deno_isolate_init() -> IsolateInit {
let data = vec![]; let data = vec![];
unsafe { unsafe {
IsolateInit { StartupData::Snapshot(deno_buf::from_raw_parts(data.as_ptr(), data.len()))
snapshot: Some(deno_buf::from_raw_parts(data.as_ptr(), data.len())),
init_script: None,
}
} }
} }
} }
pub fn compiler_isolate_init() -> IsolateInit { pub fn compiler_isolate_init() -> StartupData {
if cfg!(feature = "no-snapshot-init") { if cfg!(feature = "no-snapshot-init") {
debug!("Deno isolate init without snapshots."); debug!("Deno isolate init without snapshots.");
#[cfg(not(feature = "check-only"))] #[cfg(not(feature = "check-only"))]
@ -53,13 +38,10 @@ pub fn compiler_isolate_init() -> IsolateInit {
#[cfg(feature = "check-only")] #[cfg(feature = "check-only")]
let source_bytes = vec![]; let source_bytes = vec![];
IsolateInit { StartupData::Script(StartupScript {
snapshot: None,
init_script: Some(IsolateInitScript {
filename: "gen/bundle/compiler.js".to_string(), filename: "gen/bundle/compiler.js".to_string(),
source: std::str::from_utf8(source_bytes).unwrap().to_string(), source: std::str::from_utf8(source_bytes).unwrap().to_string(),
}), })
}
} else { } else {
debug!("Deno isolate init with snapshots."); debug!("Deno isolate init with snapshots.");
#[cfg(not(any(feature = "check-only", feature = "no-snapshot-init")))] #[cfg(not(any(feature = "check-only", feature = "no-snapshot-init")))]
@ -69,10 +51,7 @@ pub fn compiler_isolate_init() -> IsolateInit {
let data = vec![]; let data = vec![];
unsafe { unsafe {
IsolateInit { StartupData::Snapshot(deno_buf::from_raw_parts(data.as_ptr(), data.len()))
snapshot: Some(deno_buf::from_raw_parts(data.as_ptr(), data.len())),
init_script: None,
}
} }
} }
} }

View file

@ -3,7 +3,6 @@ use crate::cli::Buf;
use crate::cli::Cli; use crate::cli::Cli;
use crate::flags::DenoFlags; use crate::flags::DenoFlags;
use crate::isolate::Isolate; use crate::isolate::Isolate;
use crate::isolate_init::IsolateInit;
use crate::isolate_state::IsolateState; use crate::isolate_state::IsolateState;
use crate::isolate_state::WorkerChannels; use crate::isolate_state::WorkerChannels;
use crate::js_errors::JSErrorColor; use crate::js_errors::JSErrorColor;
@ -11,6 +10,7 @@ use crate::permissions::DenoPermissions;
use crate::resources; use crate::resources;
use crate::tokio_util; use crate::tokio_util;
use deno_core::JSError; use deno_core::JSError;
use deno_core::StartupData;
use futures::future::lazy; use futures::future::lazy;
use futures::sync::mpsc; use futures::sync::mpsc;
use futures::sync::oneshot; use futures::sync::oneshot;
@ -26,7 +26,7 @@ pub struct Worker {
impl Worker { impl Worker {
pub fn new( pub fn new(
init: IsolateInit, startup_data: Option<StartupData>,
flags: DenoFlags, flags: DenoFlags,
argv: Vec<String>, argv: Vec<String>,
permissions: DenoPermissions, permissions: DenoPermissions,
@ -40,7 +40,7 @@ impl Worker {
let state = let state =
Arc::new(IsolateState::new(flags, argv, Some(internal_channels))); Arc::new(IsolateState::new(flags, argv, Some(internal_channels)));
let cli = Cli::new(init, state, permissions); let cli = Cli::new(startup_data, state, permissions);
let isolate = Isolate::new(cli); let isolate = Isolate::new(cli);
let worker = Worker { isolate }; let worker = Worker { isolate };
@ -62,7 +62,7 @@ impl Future for Worker {
} }
pub fn spawn( pub fn spawn(
init: IsolateInit, startup_data: Option<StartupData>,
state: &IsolateState, state: &IsolateState,
js_source: String, js_source: String,
permissions: DenoPermissions, permissions: DenoPermissions,
@ -81,7 +81,7 @@ pub fn spawn(
.spawn(move || { .spawn(move || {
tokio_util::run(lazy(move || { tokio_util::run(lazy(move || {
let (mut worker, external_channels) = let (mut worker, external_channels) =
Worker::new(init, flags, argv, permissions); Worker::new(startup_data, flags, argv, permissions);
let resource = resources::add_worker(external_channels); let resource = resources::add_worker(external_channels);
p.send(resource.clone()).unwrap(); p.send(resource.clone()).unwrap();
@ -113,13 +113,13 @@ pub fn spawn(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::isolate_init; use crate::startup_data;
#[test] #[test]
fn test_spawn() { fn test_spawn() {
let isolate_init = isolate_init::compiler_isolate_init(); let startup_data = startup_data::compiler_isolate_init();
let resource = spawn( let resource = spawn(
isolate_init, Some(startup_data),
&IsolateState::mock(), &IsolateState::mock(),
r#" r#"
onmessage = function(e) { onmessage = function(e) {
@ -154,9 +154,9 @@ mod tests {
#[test] #[test]
fn removed_from_resource_table_on_close() { fn removed_from_resource_table_on_close() {
let isolate_init = isolate_init::compiler_isolate_init(); let startup_data = startup_data::compiler_isolate_init();
let resource = spawn( let resource = spawn(
isolate_init, Some(startup_data),
&IsolateState::mock(), &IsolateState::mock(),
"onmessage = () => close();".into(), "onmessage = () => close();".into(),
DenoPermissions::default(), DenoPermissions::default(),