1
0
Fork 0
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:
Ryan Dahl 2020-06-03 12:18:29 -04:00 committed by GitHub
parent 445e44199b
commit a90d9fbd34
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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<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]
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| {
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);
})
}
}