From 688c93fa30196c997ca46b2b4627c96324ebcd2c Mon Sep 17 00:00:00 2001 From: snek Date: Tue, 10 Sep 2024 07:59:46 -0700 Subject: [PATCH] fix: preserve cped in dynamic imports (#888) Fix for https://github.com/denoland/deno/issues/25275 This code is like hacks on top of hacks, but basically save & restore cped in the dynamic import flow. --- core/modules/map.rs | 39 +++++++++++++++++++++++++++++++-------- core/runtime/bindings.rs | 4 ++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/core/modules/map.rs b/core/modules/map.rs index 45fc87511..9fd61a0cf 100644 --- a/core/modules/map.rs +++ b/core/modules/map.rs @@ -115,6 +115,11 @@ struct DynImportModEvaluate { module: v8::Global, } +struct DynImportState { + resolver: v8::Global, + cped: v8::Global, +} + /// A collection of JS modules. pub(crate) struct ModuleMap { // Handling of futures for loading module sources @@ -123,8 +128,7 @@ pub(crate) struct ModuleMap { pub(crate) import_meta_resolve_cb: ImportMetaResolveCallback, exception_state: Rc, - dynamic_import_map: - RefCell>>, + dynamic_import_map: RefCell>, preparing_dynamic_imports: RefCell>>>, preparing_dynamic_imports_pending: Cell, @@ -941,6 +945,7 @@ impl ModuleMap { referrer: &str, requested_module_type: RequestedModuleType, resolver_handle: v8::Global, + cped_handle: v8::Global, ) { let load = RecursiveModuleLoad::dynamic_import( specifier, @@ -949,10 +954,13 @@ impl ModuleMap { self.clone(), ); - self - .dynamic_import_map - .borrow_mut() - .insert(load.id, resolver_handle); + self.dynamic_import_map.borrow_mut().insert( + load.id, + DynImportState { + resolver: resolver_handle, + cped: cped_handle, + }, + ); let resolve_result = self.resolve(specifier, referrer, ResolutionKind::DynamicImport); @@ -1230,6 +1238,19 @@ impl ModuleMap { // https://github.com/denoland/deno/issues/4908 // https://v8.dev/features/top-level-await#module-execution-order let tc_scope = &mut v8::TryCatch::new(scope); + + { + let cped = self + .dynamic_import_map + .borrow() + .get(&load_id) + .unwrap() + .cped + .clone(); + let cped = v8::Local::new(tc_scope, cped); + tc_scope.set_continuation_preserved_embedder_data(cped); + } + let module = v8::Local::new(tc_scope, &module_handle); let maybe_value = module.evaluate(tc_scope); @@ -1351,7 +1372,8 @@ impl ModuleMap { .dynamic_import_map .borrow_mut() .remove(&id) - .expect("Invalid dynamic import id"); + .expect("Invalid dynamic import id") + .resolver; let resolver = resolver_handle.open(scope); let exception = v8::Local::new(scope, exception); @@ -1369,7 +1391,8 @@ impl ModuleMap { .dynamic_import_map .borrow_mut() .remove(&id) - .expect("Invalid dynamic import id"); + .expect("Invalid dynamic import id") + .resolver; let resolver = resolver_handle.open(scope); let module = self diff --git a/core/runtime/bindings.rs b/core/runtime/bindings.rs index 2d85094c1..eb9ae8889 100644 --- a/core/runtime/bindings.rs +++ b/core/runtime/bindings.rs @@ -426,6 +426,8 @@ pub fn host_import_module_dynamically_callback<'s>( specifier: v8::Local<'s, v8::String>, import_attributes: v8::Local<'s, v8::FixedArray>, ) -> Option> { + let cped = scope.get_continuation_preserved_embedder_data(); + // NOTE(bartlomieju): will crash for non-UTF-8 specifier let specifier_str = specifier .to_string(scope) @@ -465,6 +467,7 @@ pub fn host_import_module_dynamically_callback<'s>( get_requested_module_type_from_attributes(&assertions); let resolver_handle = v8::Global::new(scope, resolver); + let cped_handle = v8::Global::new(scope, cped); { let state = JsRuntime::state_from(scope); let module_map_rc = JsRealm::module_map_from(scope); @@ -475,6 +478,7 @@ pub fn host_import_module_dynamically_callback<'s>( &referrer_name_str, requested_module_type, resolver_handle, + cped_handle, ); state.notify_new_dynamic_import(); }