mirror of
https://github.com/denoland/deno.git
synced 2024-12-23 07:44:48 -05:00
fix: dynamic import BorrowMutError (#6065)
This commit is contained in:
parent
445e44199b
commit
a90d9fbd34
1 changed files with 81 additions and 51 deletions
|
@ -330,13 +330,15 @@ impl EsIsolate {
|
||||||
let state_rc = Self::state(self);
|
let state_rc = Self::state(self);
|
||||||
|
|
||||||
let core_state_rc = CoreIsolate::state(self);
|
let core_state_rc = CoreIsolate::state(self);
|
||||||
let core_state = core_state_rc.borrow();
|
|
||||||
|
|
||||||
debug!("dyn_import_done {} {:?}", id, mod_id);
|
debug!("dyn_import_done {} {:?}", id, mod_id);
|
||||||
assert!(mod_id != 0);
|
assert!(mod_id != 0);
|
||||||
let mut hs = v8::HandleScope::new(&mut self.0);
|
let mut hs = v8::HandleScope::new(&mut self.0);
|
||||||
let scope = hs.enter();
|
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 mut cs = v8::ContextScope::new(scope, context);
|
||||||
let scope = cs.enter();
|
let scope = cs.enter();
|
||||||
|
|
||||||
|
@ -837,57 +839,57 @@ pub mod tests {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Default)]
|
||||||
|
struct DynImportOkLoader {
|
||||||
|
pub prepare_load_count: Arc<AtomicUsize>,
|
||||||
|
pub resolve_count: Arc<AtomicUsize>,
|
||||||
|
pub load_count: Arc<AtomicUsize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModuleLoader for DynImportOkLoader {
|
||||||
|
fn resolve(
|
||||||
|
&self,
|
||||||
|
specifier: &str,
|
||||||
|
referrer: &str,
|
||||||
|
_is_main: bool,
|
||||||
|
) -> Result<ModuleSpecifier, ErrBox> {
|
||||||
|
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<ModuleSpecifier>,
|
||||||
|
_is_dyn_import: bool,
|
||||||
|
) -> Pin<Box<ModuleSourceFuture>> {
|
||||||
|
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<String>,
|
||||||
|
_is_dyn_import: bool,
|
||||||
|
) -> Pin<Box<dyn Future<Output = Result<(), ErrBox>>>> {
|
||||||
|
self.prepare_load_count.fetch_add(1, Ordering::Relaxed);
|
||||||
|
async { Ok(()) }.boxed_local()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn dyn_import_ok() {
|
fn dyn_import_ok() {
|
||||||
#[derive(Clone, Default)]
|
|
||||||
struct DynImportOkLoader {
|
|
||||||
pub prepare_load_count: Arc<AtomicUsize>,
|
|
||||||
pub resolve_count: Arc<AtomicUsize>,
|
|
||||||
pub load_count: Arc<AtomicUsize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ModuleLoader for DynImportOkLoader {
|
|
||||||
fn resolve(
|
|
||||||
&self,
|
|
||||||
specifier: &str,
|
|
||||||
referrer: &str,
|
|
||||||
_is_main: bool,
|
|
||||||
) -> Result<ModuleSpecifier, ErrBox> {
|
|
||||||
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<ModuleSpecifier>,
|
|
||||||
_is_dyn_import: bool,
|
|
||||||
) -> Pin<Box<ModuleSourceFuture>> {
|
|
||||||
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<String>,
|
|
||||||
_is_dyn_import: bool,
|
|
||||||
) -> Pin<Box<dyn Future<Output = Result<(), ErrBox>>>> {
|
|
||||||
self.prepare_load_count.fetch_add(1, Ordering::Relaxed);
|
|
||||||
async { Ok(()) }.boxed_local()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
run_in_task(|cx| {
|
run_in_task(|cx| {
|
||||||
let loader = Rc::new(DynImportOkLoader::default());
|
let loader = Rc::new(DynImportOkLoader::default());
|
||||||
let prepare_load_count = loader.prepare_load_count.clone();
|
let prepare_load_count = loader.prepare_load_count.clone();
|
||||||
|
@ -935,4 +937,32 @@ pub mod tests {
|
||||||
assert_eq!(load_count.load(Ordering::Relaxed), 2);
|
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);
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue