diff --git a/core/es_isolate.rs b/core/es_isolate.rs index f8770db4db..059387d7bf 100644 --- a/core/es_isolate.rs +++ b/core/es_isolate.rs @@ -330,13 +330,15 @@ impl EsIsolate { let state_rc = Self::state(self); let core_state_rc = CoreIsolate::state(self); - let core_state = core_state_rc.borrow(); debug!("dyn_import_done {} {:?}", id, mod_id); assert!(mod_id != 0); let mut hs = v8::HandleScope::new(&mut self.0); let scope = hs.enter(); - let context = core_state.global_context.get(scope).unwrap(); + let context = { + let core_state = core_state_rc.borrow(); + core_state.global_context.get(scope).unwrap() + }; let mut cs = v8::ContextScope::new(scope, context); let scope = cs.enter(); @@ -837,57 +839,57 @@ pub mod tests { }) } + #[derive(Clone, Default)] + struct DynImportOkLoader { + pub prepare_load_count: Arc, + pub resolve_count: Arc, + pub load_count: Arc, + } + + impl ModuleLoader for DynImportOkLoader { + fn resolve( + &self, + specifier: &str, + referrer: &str, + _is_main: bool, + ) -> Result { + let c = self.resolve_count.fetch_add(1, Ordering::Relaxed); + assert!(c < 4); + assert_eq!(specifier, "./b.js"); + assert_eq!(referrer, "file:///dyn_import3.js"); + let s = ModuleSpecifier::resolve_import(specifier, referrer).unwrap(); + Ok(s) + } + + fn load( + &self, + specifier: &ModuleSpecifier, + _maybe_referrer: Option, + _is_dyn_import: bool, + ) -> Pin> { + self.load_count.fetch_add(1, Ordering::Relaxed); + let info = ModuleSource { + module_url_specified: specifier.to_string(), + module_url_found: specifier.to_string(), + code: "export function b() { return 'b' }".to_owned(), + }; + async move { Ok(info) }.boxed() + } + + fn prepare_load( + &self, + _load_id: ModuleLoadId, + _module_specifier: &ModuleSpecifier, + _maybe_referrer: Option, + _is_dyn_import: bool, + ) -> Pin>>> { + self.prepare_load_count.fetch_add(1, Ordering::Relaxed); + async { Ok(()) }.boxed_local() + } + } + #[test] fn dyn_import_ok() { - #[derive(Clone, Default)] - struct DynImportOkLoader { - pub prepare_load_count: Arc, - pub resolve_count: Arc, - pub load_count: Arc, - } - - impl ModuleLoader for DynImportOkLoader { - fn resolve( - &self, - specifier: &str, - referrer: &str, - _is_main: bool, - ) -> Result { - let c = self.resolve_count.fetch_add(1, Ordering::Relaxed); - assert!(c < 4); - assert_eq!(specifier, "./b.js"); - assert_eq!(referrer, "file:///dyn_import3.js"); - let s = ModuleSpecifier::resolve_import(specifier, referrer).unwrap(); - Ok(s) - } - - fn load( - &self, - specifier: &ModuleSpecifier, - _maybe_referrer: Option, - _is_dyn_import: bool, - ) -> Pin> { - self.load_count.fetch_add(1, Ordering::Relaxed); - let info = ModuleSource { - module_url_specified: specifier.to_string(), - module_url_found: specifier.to_string(), - code: "export function b() { return 'b' }".to_owned(), - }; - async move { Ok(info) }.boxed() - } - - fn prepare_load( - &self, - _load_id: ModuleLoadId, - _module_specifier: &ModuleSpecifier, - _maybe_referrer: Option, - _is_dyn_import: bool, - ) -> Pin>>> { - self.prepare_load_count.fetch_add(1, Ordering::Relaxed); - async { Ok(()) }.boxed_local() - } - } - run_in_task(|cx| { let loader = Rc::new(DynImportOkLoader::default()); let prepare_load_count = loader.prepare_load_count.clone(); @@ -935,4 +937,32 @@ pub mod tests { assert_eq!(load_count.load(Ordering::Relaxed), 2); }) } + + #[test] + fn dyn_import_borrow_mut_error() { + // https://github.com/denoland/deno/issues/6054 + run_in_task(|cx| { + let loader = Rc::new(DynImportOkLoader::default()); + let prepare_load_count = loader.prepare_load_count.clone(); + let mut isolate = EsIsolate::new(loader, StartupData::None, false); + js_check(isolate.execute( + "file:///dyn_import3.js", + r#" + (async () => { + let mod = await import("./b.js"); + if (mod.b() !== 'b') { + throw Error("bad"); + } + // Now do any op + Deno.core.ops(); + })(); + "#, + )); + // First poll runs `prepare_load` hook. + let _ = isolate.poll_unpin(cx); + assert_eq!(prepare_load_count.load(Ordering::Relaxed), 1); + // Second poll triggers error + let _ = isolate.poll_unpin(cx); + }) + } }