summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2020-06-05 18:36:54 -0400
committerGitHub <noreply@github.com>2020-06-05 18:36:54 -0400
commit79d9cf52d0298ba85e0ac4a58014116bb84bfc59 (patch)
tree87d9855045812a5f14672a3f14c4b9b7be1b0c8f
parentd2243b1125722e775b1f9719197260d1cda1220d (diff)
fix(core): ES module snapshots (#6111)
Co-authored-by: Bert Belder <bertbelder@gmail.com>
-rw-r--r--core/core_isolate.rs2
-rw-r--r--core/es_isolate.rs54
2 files changed, 54 insertions, 2 deletions
diff --git a/core/core_isolate.rs b/core/core_isolate.rs
index 984a6a2a6..dc22d821a 100644
--- a/core/core_isolate.rs
+++ b/core/core_isolate.rs
@@ -270,7 +270,7 @@ impl CoreIsolate {
}
/// Executes a bit of built-in JavaScript to provide Deno.sharedQueue.
- fn shared_init(&mut self) {
+ pub(crate) fn shared_init(&mut self) {
if self.needs_init {
self.needs_init = false;
js_check(self.execute("core.js", include_str!("core.js")));
diff --git a/core/es_isolate.rs b/core/es_isolate.rs
index e14798407..c778de1cc 100644
--- a/core/es_isolate.rs
+++ b/core/es_isolate.rs
@@ -211,6 +211,7 @@ impl EsIsolate {
/// the V8 exception. By default this type is JSError, however it may be a
/// different type if CoreIsolate::set_js_error_create_fn() has been used.
pub fn mod_evaluate(&mut self, id: ModuleId) -> Result<(), ErrBox> {
+ self.shared_init();
let state_rc = Self::state(self);
let state = state_rc.borrow();
@@ -553,6 +554,7 @@ impl EsIsolate {
specifier: &ModuleSpecifier,
code: Option<String>,
) -> Result<ModuleId, ErrBox> {
+ self.shared_init();
let loader = {
let state_rc = Self::state(self);
let state = state_rc.borrow();
@@ -573,6 +575,12 @@ impl EsIsolate {
self.mod_instantiate(root_id).map(|_| root_id)
}
+ pub fn snapshot(&mut self) -> v8::StartupData {
+ let state_rc = Self::state(self);
+ std::mem::take(&mut state_rc.borrow_mut().modules);
+ CoreIsolate::snapshot(self)
+ }
+
pub fn state(isolate: &v8::Isolate) -> Rc<RefCell<EsIsolateState>> {
let s = isolate.get_slot::<Rc<RefCell<EsIsolateState>>>().unwrap();
s.clone()
@@ -677,7 +685,7 @@ pub mod tests {
#[test]
fn test_mods() {
- #[derive(Clone, Default)]
+ #[derive(Default)]
struct ModsLoader {
pub count: Arc<AtomicUsize>,
}
@@ -966,4 +974,48 @@ pub mod tests {
let _ = isolate.poll_unpin(cx);
})
}
+
+ #[test]
+ fn es_snapshot() {
+ #[derive(Default)]
+ struct ModsLoader;
+
+ impl ModuleLoader for ModsLoader {
+ fn resolve(
+ &self,
+ specifier: &str,
+ referrer: &str,
+ _is_main: bool,
+ ) -> Result<ModuleSpecifier, ErrBox> {
+ assert_eq!(specifier, "file:///main.js");
+ assert_eq!(referrer, ".");
+ let s = ModuleSpecifier::resolve_import(specifier, referrer).unwrap();
+ Ok(s)
+ }
+
+ fn load(
+ &self,
+ _module_specifier: &ModuleSpecifier,
+ _maybe_referrer: Option<ModuleSpecifier>,
+ _is_dyn_import: bool,
+ ) -> Pin<Box<ModuleSourceFuture>> {
+ unreachable!()
+ }
+ }
+
+ let loader = std::rc::Rc::new(ModsLoader::default());
+ let mut runtime_isolate = EsIsolate::new(loader, StartupData::None, true);
+
+ let specifier = ModuleSpecifier::resolve_url("file:///main.js").unwrap();
+ let source_code = "Deno.core.print('hello\\n')".to_string();
+
+ let module_id = futures::executor::block_on(
+ runtime_isolate.load_module(&specifier, Some(source_code)),
+ )
+ .unwrap();
+
+ js_check(runtime_isolate.mod_evaluate(module_id));
+
+ let _snapshot = runtime_isolate.snapshot();
+ }
}