diff options
author | Giovanny GutiƩrrez <giovanny.gutierrez@commure.com> | 2022-09-06 07:35:04 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-06 14:35:04 +0200 |
commit | 2929ddabaab016520eb47411fcd8eb543fb256dd (patch) | |
tree | 13cbd0e0878ee5d5a3da2f6083ea4684aa758dad /core/modules.rs | |
parent | 118dd47ad0ced501b1ad8d9e1cc2a2f443f101e6 (diff) |
fix(core): Register external references for imports to the SnapshotCreator (#15621)
Several functions used for handling of dynamic imports and "import.meta"
object were not registered as external references and caused V8 to crash
during snapshotting. These functions are now registered as external refs
and aborts are no longer happening.
Diffstat (limited to 'core/modules.rs')
-rw-r--r-- | core/modules.rs | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/core/modules.rs b/core/modules.rs index 545ad54d8..65b3852d9 100644 --- a/core/modules.rs +++ b/core/modules.rs @@ -1145,6 +1145,7 @@ mod tests { use crate::Extension; use crate::JsRuntime; use crate::RuntimeOptions; + use crate::Snapshot; use deno_ops::op; use futures::future::FutureExt; use parking_lot::Mutex; @@ -2305,4 +2306,86 @@ if (import.meta.url != 'file:///main_with_code.js') throw Error(); let _ = runtime.mod_evaluate(side_id); futures::executor::block_on(runtime.run_event_loop(false)).unwrap(); } + + #[test] + fn dynamic_imports_snapshot() { + //TODO: Once the issue with the ModuleNamespaceEntryGetter is fixed, we can maintain a reference to the module + // and use it when loading the snapshot + let snapshot = { + const MAIN_WITH_CODE_SRC: &str = r#" + await import("./b.js"); + "#; + + let loader = MockLoader::new(); + let mut runtime = JsRuntime::new(RuntimeOptions { + module_loader: Some(loader), + will_snapshot: true, + ..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. + let spec = resolve_url("file:///main_with_code.js").unwrap(); + let main_id_fut = runtime + .load_main_module(&spec, Some(MAIN_WITH_CODE_SRC.to_owned())) + .boxed_local(); + let main_id = futures::executor::block_on(main_id_fut).unwrap(); + + let _ = runtime.mod_evaluate(main_id); + futures::executor::block_on(runtime.run_event_loop(false)).unwrap(); + runtime.snapshot() + }; + + let snapshot = Snapshot::JustCreated(snapshot); + let mut runtime2 = JsRuntime::new(RuntimeOptions { + startup_snapshot: Some(snapshot), + ..Default::default() + }); + + //Evaluate the snapshot with an empty function + runtime2.execute_script("check.js", "true").unwrap(); + } + + #[test] + fn import_meta_snapshot() { + let snapshot = { + const MAIN_WITH_CODE_SRC: &str = r#" + if (import.meta.url != 'file:///main_with_code.js') throw Error(); + globalThis.meta = import.meta; + globalThis.url = import.meta.url; + "#; + + let loader = MockLoader::new(); + let mut runtime = JsRuntime::new(RuntimeOptions { + module_loader: Some(loader), + will_snapshot: true, + ..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. + let spec = resolve_url("file:///main_with_code.js").unwrap(); + let main_id_fut = runtime + .load_main_module(&spec, Some(MAIN_WITH_CODE_SRC.to_owned())) + .boxed_local(); + let main_id = futures::executor::block_on(main_id_fut).unwrap(); + + let _ = runtime.mod_evaluate(main_id); + futures::executor::block_on(runtime.run_event_loop(false)).unwrap(); + runtime.snapshot() + }; + + let snapshot = Snapshot::JustCreated(snapshot); + let mut runtime2 = JsRuntime::new(RuntimeOptions { + startup_snapshot: Some(snapshot), + ..Default::default() + }); + + runtime2 + .execute_script( + "check.js", + "if (globalThis.url !== 'file:///main_with_code.js') throw Error('x')", + ) + .unwrap(); + } } |