diff --git a/moli-benchmark/wpt-cross-current/failed-cases.txt b/moli-benchmark/wpt-cross-current/failed-cases.txt index 00aece7268..407517cf5f 100644 --- a/moli-benchmark/wpt-cross-current/failed-cases.txt +++ b/moli-benchmark/wpt-cross-current/failed-cases.txt @@ -3147,12 +3147,10 @@ html/semantics/popovers/popover-shadow-dom.html html/semantics/popovers/popover-stacking.html html/semantics/popovers/popover-types-with-hints.html html/semantics/scripting-1/the-script-element/css-module/content-type-checking.html -html/semantics/scripting-1/the-script-element/css-module/cors-crossorigin-requests.html html/semantics/scripting-1/the-script-element/execution-timing/083.html html/semantics/scripting-1/the-script-element/execution-timing/085.html html/semantics/scripting-1/the-script-element/execution-timing/128.html html/semantics/scripting-1/the-script-element/execution-timing/137.html -html/semantics/scripting-1/the-script-element/json-module/cors-crossorigin-requests.html html/semantics/scripting-1/the-script-element/json-module/json-module-service-worker-test.https.html html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-window-onerror-module.html html/semantics/scripting-1/the-script-element/microtasks/checkpoint-after-window-onerror.html diff --git a/moli-benchmark/wpt-cross-current/passed-cases.txt b/moli-benchmark/wpt-cross-current/passed-cases.txt index 3976a2be71..049259e05b 100644 --- a/moli-benchmark/wpt-cross-current/passed-cases.txt +++ b/moli-benchmark/wpt-cross-current/passed-cases.txt @@ -6612,6 +6612,7 @@ html/semantics/scripting-1/the-script-element/async_011.htm html/semantics/scripting-1/the-script-element/css-module/charset-2.html html/semantics/scripting-1/the-script-element/css-module/charset-bom.html html/semantics/scripting-1/the-script-element/css-module/charset.html +html/semantics/scripting-1/the-script-element/css-module/cors-crossorigin-requests.html html/semantics/scripting-1/the-script-element/css-module/css-module-parse-error.html html/semantics/scripting-1/the-script-element/css-module/import-css-module-basic.html html/semantics/scripting-1/the-script-element/css-module/import-css-module-dynamic.html @@ -6778,6 +6779,7 @@ html/semantics/scripting-1/the-script-element/import-attributes/invalid-type-att html/semantics/scripting-1/the-script-element/import-attributes/unsupported-attribute.html html/semantics/scripting-1/the-script-element/json-module/charset-2.html html/semantics/scripting-1/the-script-element/json-module/charset.html +html/semantics/scripting-1/the-script-element/json-module/cors-crossorigin-requests.html html/semantics/scripting-1/the-script-element/json-module/integrity.html html/semantics/scripting-1/the-script-element/json-module/module.html html/semantics/scripting-1/the-script-element/json-module/parse-error.html diff --git a/moli-core/tests/scripts.rs b/moli-core/tests/scripts.rs index e7d93a2344..711129235e 100644 --- a/moli-core/tests/scripts.rs +++ b/moli-core/tests/scripts.rs @@ -13,6 +13,9 @@ use moli_core::{ use support::FixtureServer; use tokio::time::Duration; +#[path = "scripts/child_synthetic_modules.rs"] +mod child_synthetic_modules; + fn diagnostic_global<'a>( page: &'a moli_core::page::Page, name: &str, diff --git a/moli-core/tests/scripts/child_synthetic_modules.rs b/moli-core/tests/scripts/child_synthetic_modules.rs new file mode 100644 index 0000000000..e6cb8a16c7 --- /dev/null +++ b/moli-core/tests/scripts/child_synthetic_modules.rs @@ -0,0 +1,153 @@ +use super::*; + +async fn evaluate_child_synthetic_expression(expression: &str) -> Result { + let server = FixtureServer::spawn().await?; + let browser = Browser::new(AppConfig::default())?; + let mut page = browser.fetch(&server.url("/static")).await?; + let result = page + .evaluate_runtime_expression_with_await_async(expression, true) + .await?; + server.shutdown().await; + Ok(result) +} + +async fn child_synthetic_probe(source: &str) -> Result { + let html = format!( + r#""# + ); + let expression = format!( + r#"new Promise(resolve => {{ + const frame = document.createElement('iframe'); + frame.onload = () => resolve(frame.contentWindow.result); + frame.srcdoc = {}; + document.body.appendChild(frame); + }})"#, + serde_json::to_string(&html)? + ); + evaluate_child_synthetic_expression(&expression).await +} + +#[tokio::test(flavor = "multi_thread")] +async fn child_synthetic_json_module_uses_its_own_document_source() -> Result<()> { + let result = child_synthetic_probe( + r#"import value from 'data:application/json,{"answer":42}' with { type: 'json' }; + window.result = value.answer + ':' + (Object.getPrototypeOf(value) === Object.prototype);"#, + ) + .await?; + assert_eq!(result["value"], "42:true", "{result:?}"); + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn child_synthetic_css_module_uses_its_own_document_source() -> Result<()> { + let result = child_synthetic_probe( + r#"import sheet from 'data:text/css,body%20%7B%20color%3A%20red%3B%20%7D' with { type: 'css' }; + window.result = (sheet instanceof CSSStyleSheet) + ':' + sheet.cssRules.length;"#, + ) + .await?; + assert_eq!(result["value"], "true:1", "{result:?}"); + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn child_synthetic_json_parse_error_is_not_a_missing_source_error() -> Result<()> { + let result = child_synthetic_probe( + r#"import value from 'data:application/json,not-json' with { type: 'json' }; + window.result = 'must not execute';"#, + ) + .await?; + assert!( + result["value"] + .as_str() + .is_some_and(|value| value.starts_with("SyntaxError: ")), + "{result:?}" + ); + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn child_synthetic_dynamic_import_after_load_uses_its_realm() -> Result<()> { + let result = evaluate_child_synthetic_expression( + r#"(async () => { + const frame = document.createElement('iframe'); + const loaded = new Promise(resolve => frame.onload = resolve); + frame.srcdoc = ``; + document.body.appendChild(frame); + await loaded; + return await frame.contentWindow.probe(); + })()"#, + ) + .await?; + assert_eq!( + result["value"], "true:true:true:true:true:true", + "{result:?}" + ); + Ok(()) +} + +#[tokio::test(flavor = "multi_thread")] +async fn child_synthetic_module_values_are_cached_per_realm_not_per_url() -> Result<()> { + let result = evaluate_child_synthetic_expression( + r#"(async () => { + const jsonUrl = 'data:application/json,{"answer":42}'; + const cssUrl = 'data:text/css,body%7Bcolor%3Ared%7D'; + const rootJson = (await import(jsonUrl, {with: {type: 'json'}})).default; + const rootSheet = (await import(cssUrl, {with: {type: 'css'}})).default; + const makeFrame = async () => { + const frame = document.createElement('iframe'); + const loaded = new Promise(resolve => frame.onload = resolve); + frame.srcdoc = ``; + document.body.appendChild(frame); + await loaded; + return frame.contentWindow; + }; + const [left, right] = await Promise.all([makeFrame(), makeFrame()]); + left.value.answer = 7; + left.sheet.insertRule('p { color: blue; }', 1); + return [rootJson.answer === 42, right.value.answer === 42, + left.value.answer === 7, rootSheet.cssRules.length === 1, + right.sheet.cssRules.length === 1, left.sheet.cssRules.length === 2, + left.value !== right.value, left.value !== rootJson, + left.sheet !== right.sheet, left.sheet !== rootSheet, + Object.getPrototypeOf(left.value) === left.Object.prototype, + Object.getPrototypeOf(right.value) === right.Object.prototype, + left.sheet instanceof left.CSSStyleSheet, + right.sheet instanceof right.CSSStyleSheet, + await left.readAgain(), await right.readAgain()].join(':'); + })()"#, + ) + .await?; + assert_eq!(result["value"], ["true"; 16].join(":"), "{result:?}"); + Ok(()) +} diff --git a/moli-renderer-v8/src/document_runtime/script_scheduling/module_facade.rs b/moli-renderer-v8/src/document_runtime/script_scheduling/module_facade.rs index 7ee40424dc..7f76029dde 100644 --- a/moli-renderer-v8/src/document_runtime/script_scheduling/module_facade.rs +++ b/moli-renderer-v8/src/document_runtime/script_scheduling/module_facade.rs @@ -198,15 +198,6 @@ impl DocumentRuntime { .native_module_source(entry_id) } - pub(crate) fn native_module_source_for( - &self, - module: v8::Local<'_, v8::Module>, - ) -> Option<(ModuleMapKey, ModuleSource)> { - self.script_lifecycle - .scripts() - .native_module_source_for(module) - } - pub(crate) fn native_module_wasm_record_for( &self, module: v8::Local<'_, v8::Module>, diff --git a/moli-renderer-v8/src/host/scripts.rs b/moli-renderer-v8/src/host/scripts.rs index ad6dfd02a4..3e5475efc3 100644 --- a/moli-renderer-v8/src/host/scripts.rs +++ b/moli-renderer-v8/src/host/scripts.rs @@ -601,13 +601,6 @@ impl HostScriptScheduler { self.module_owner.native_module_source(entry_id) } - pub(crate) fn native_module_source_for( - &self, - module: v8::Local<'_, v8::Module>, - ) -> Option<(ModuleMapKey, ModuleSource)> { - self.module_owner.native_module_source_for(module) - } - pub(crate) fn native_module_wasm_record_for( &self, module: v8::Local<'_, v8::Module>, diff --git a/moli-renderer-v8/src/module_runtime.rs b/moli-renderer-v8/src/module_runtime.rs index 9b1278a455..54e6452bc0 100644 --- a/moli-renderer-v8/src/module_runtime.rs +++ b/moli-renderer-v8/src/module_runtime.rs @@ -12,6 +12,7 @@ mod record; mod record_resolver; mod resolver; mod single_module_fetch; +mod synthetic_text; #[cfg(test)] mod tests; mod tree_adapter; @@ -51,6 +52,7 @@ pub(crate) use self::resolver::{ ResolverScopeGuard, resolve_static_module_callback, resolve_static_source_callback, }; pub(crate) use self::single_module_fetch::NativeModuleSingleFetchRequest; +pub(crate) use self::synthetic_text::SyntheticTextModuleSource; pub(crate) use self::tree_owner::{ NativeModuleTreeDocumentOwnerAdapter, NativeModuleTreeFrameDocumentOwner, }; @@ -486,13 +488,6 @@ impl ModuleOwnerState { self.document_modulator.entry(entry_id).source().cloned() } - pub(crate) fn native_module_source_for( - &self, - module: v8::Local<'_, v8::Module>, - ) -> Option<(ModuleMapKey, ModuleSource)> { - self.document_modulator.module_source_for(module) - } - pub(crate) fn native_module_wasm_record_for( &self, module: v8::Local<'_, v8::Module>, diff --git a/moli-renderer-v8/src/module_runtime/modulator.rs b/moli-renderer-v8/src/module_runtime/modulator.rs index 45c8f31cc5..05e75121d0 100644 --- a/moli-renderer-v8/src/module_runtime/modulator.rs +++ b/moli-renderer-v8/src/module_runtime/modulator.rs @@ -655,14 +655,6 @@ impl NativeDocumentModulator { .set_record_state_for_entry(self.core.entry(entry_id), ModuleRecordState::Evaluated); } - pub(crate) fn module_source_for( - &self, - module: v8::Local<'_, v8::Module>, - ) -> Option<(ModuleMapKey, ModuleSource)> { - let entry = self.entry(self.module_entry_id_for(module)?); - Some((entry.effective_key().clone(), entry.source()?.clone())) - } - pub(crate) fn module_wasm_record_for( &self, module: v8::Local<'_, v8::Module>, diff --git a/moli-renderer-v8/src/module_runtime/record.rs b/moli-renderer-v8/src/module_runtime/record.rs index 335fd32ad8..aacf68cebe 100644 --- a/moli-renderer-v8/src/module_runtime/record.rs +++ b/moli-renderer-v8/src/module_runtime/record.rs @@ -19,6 +19,8 @@ pub(crate) struct ModuleRecordEntry { compiled_module: v8::Global, requests: Vec, wasm_module: Option, + // Own the evaluation data; the Context's lookup only keeps a weak reference. + synthetic_text_module_source: Option>, state: ModuleRecordState, } @@ -33,6 +35,7 @@ impl ModuleRecordEntry { compiled_module, requests, wasm_module: None, + synthetic_text_module_source: None, state: ModuleRecordState::Compiled, } } @@ -48,6 +51,7 @@ impl ModuleRecordEntry { compiled_module, requests, wasm_module: Some(wasm_module), + synthetic_text_module_source: None, state: ModuleRecordState::Compiled, } } @@ -56,6 +60,14 @@ impl ModuleRecordEntry { &self.key } + pub(crate) fn with_synthetic_text_module_source( + mut self, + source: Rc, + ) -> Self { + self.synthetic_text_module_source = Some(source); + self + } + pub(crate) fn compiled_module(&self) -> &v8::Global { &self.compiled_module } diff --git a/moli-renderer-v8/src/module_runtime/synthetic_text.rs b/moli-renderer-v8/src/module_runtime/synthetic_text.rs new file mode 100644 index 0000000000..2906395af0 --- /dev/null +++ b/moli-renderer-v8/src/module_runtime/synthetic_text.rs @@ -0,0 +1,153 @@ +use std::cell::RefCell; +use std::collections::HashMap; +use std::rc::{Rc, Weak}; + +use super::{ModuleIdentityHash, ModuleMapKey, module_identity_hash_from_v8_module}; + +/// Evaluation data belongs to the compiled module record, not the page's +/// default Document. The Context only holds weak references, so this lookup +/// does not keep a disposed realm or its compiled modules alive. +#[derive(Debug)] +pub(crate) struct SyntheticTextModuleSource { + module: v8::Global, + key: ModuleMapKey, + source: String, +} + +#[derive(Default)] +struct SyntheticTextModuleSources { + entries: RefCell>>>, +} + +impl SyntheticTextModuleSource { + pub(crate) fn register( + scope: &mut v8::PinScope<'_, '_>, + module: v8::Local<'_, v8::Module>, + key: ModuleMapKey, + source: &str, + ) -> Rc { + let context = scope.get_current_context(); + let sources = context + .get_slot::() + .unwrap_or_else(|| { + let sources = Rc::new(SyntheticTextModuleSources::default()); + context.set_slot(sources.clone()); + sources + }); + let record = Rc::new(Self { + module: v8::Global::new(scope, module), + key, + source: source.to_owned(), + }); + let mut entries = sources.entries.borrow_mut(); + let candidates = entries + .entry(module_identity_hash_from_v8_module(module)) + .or_default(); + candidates.retain(|candidate| candidate.strong_count() != 0); + candidates.push(Rc::downgrade(&record)); + record + } + + pub(crate) fn for_module( + context: v8::Local<'_, v8::Context>, + module: v8::Local<'_, v8::Module>, + ) -> Option> { + let sources = context.get_slot::()?; + let entries = sources.entries.borrow(); + entries + .get(&module_identity_hash_from_v8_module(module))? + .iter() + .filter_map(Weak::upgrade) + // V8 identity hashes are not unique, even within one Context. + .find(|candidate| module == candidate.module) + } + + pub(crate) fn key(&self) -> &ModuleMapKey { + &self.key + } + + pub(crate) fn source(&self) -> &str { + &self.source + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::module_runtime::{ModuleAttributesKey, ModuleRecordEntry}; + use url::Url; + + fn unused_evaluation_steps<'s>( + context: v8::Local<'s, v8::Context>, + _module: v8::Local<'s, v8::Module>, + ) -> Option> { + v8::callback_scope!(unsafe scope, context); + Some(v8::undefined(scope).into()) + } + + #[test] + fn synthetic_text_module_lookup_checks_context_and_exact_identity() { + crate::ensure_v8_for_test(); + let mut isolate = v8::Isolate::new(Default::default()); + let scope = std::pin::pin!(v8::HandleScope::new(&mut isolate)); + let scope = &mut scope.init(); + let context = v8::Context::new(scope, Default::default()); + let scope = &mut v8::ContextScope::new(scope, context); + let name = v8::String::new(scope, "https://example.test/shared.json").unwrap(); + let first = v8::Module::create_synthetic_module(scope, name, &[], unused_evaluation_steps); + let second = v8::Module::create_synthetic_module(scope, name, &[], unused_evaluation_steps); + let key = ModuleMapKey::json_with_attributes( + Url::parse("https://example.test/shared.json").unwrap(), + ModuleAttributesKey::empty(), + ); + let first_source = SyntheticTextModuleSource::register(scope, first, key.clone(), "1"); + let second_source = SyntheticTextModuleSource::register(scope, second, key, "2"); + + // Inject a conflicting candidate deterministically instead of waiting + // for a random V8 identity-hash collision. + let sources = context.get_slot::().unwrap(); + sources + .entries + .borrow_mut() + .get_mut(&module_identity_hash_from_v8_module(second)) + .unwrap() + .insert(0, Rc::downgrade(&first_source)); + assert!(Rc::ptr_eq( + &SyntheticTextModuleSource::for_module(context, second).unwrap(), + &second_source, + )); + let foreign = v8::Context::new(scope, Default::default()); + assert!(SyntheticTextModuleSource::for_module(foreign, first).is_none()); + } + + #[test] + fn synthetic_text_module_lookup_does_not_keep_disposed_records_alive() { + crate::ensure_v8_for_test(); + let mut isolate = v8::Isolate::new(Default::default()); + let scope = std::pin::pin!(v8::HandleScope::new(&mut isolate)); + let scope = &mut scope.init(); + let context = v8::Context::new(scope, Default::default()); + let scope = &mut v8::ContextScope::new(scope, context); + let name = v8::String::new(scope, "https://example.test/value.json").unwrap(); + let module = v8::Module::create_synthetic_module(scope, name, &[], unused_evaluation_steps); + let key = ModuleMapKey::json_with_attributes( + Url::parse("https://example.test/value.json").unwrap(), + ModuleAttributesKey::empty(), + ); + let source = SyntheticTextModuleSource::register(scope, module, key.clone(), "42"); + let weak = Rc::downgrade(&source); + let record = ModuleRecordEntry::new(key, v8::Global::new(scope, module), Vec::new()) + .with_synthetic_text_module_source(source); + let clone = record.clone(); + drop(record); + assert_eq!( + SyntheticTextModuleSource::for_module(context, module) + .unwrap() + .source(), + "42" + ); + drop(clone); + assert!(weak.upgrade().is_none()); + assert!(SyntheticTextModuleSource::for_module(context, module).is_none()); + } +} diff --git a/moli-renderer-v8/src/native_bridge/context_host/resource_loading.rs b/moli-renderer-v8/src/native_bridge/context_host/resource_loading.rs index 638c8798e3..bc781f4620 100644 --- a/moli-renderer-v8/src/native_bridge/context_host/resource_loading.rs +++ b/moli-renderer-v8/src/native_bridge/context_host/resource_loading.rs @@ -2,10 +2,7 @@ use super::{JsContextHost, OwnerDispatchScope}; use crate::network::loads::{ResourceLoadDisposition, ResourceLoadKind, ResourceLoadLease}; use crate::types::DedicatedWorkerId; use crate::{ - module_runtime::{ - ModuleAttributesKey, ModuleMapKey, ModuleSource, PendingDynamicModuleImport, - WasmModuleRecord, - }, + module_runtime::{ModuleAttributesKey, PendingDynamicModuleImport, WasmModuleRecord}, page_task_queue::RendererResourceCompletionSender, renderer_resource_scheduler::RendererResourceScheduler, types::{ @@ -86,14 +83,6 @@ impl JsContextHost { unsafe { &mut *self.runtime }.resolve_module_specifier(specifier, base_url) } - pub(crate) fn native_module_source_for( - &self, - module: v8::Local<'_, v8::Module>, - ) -> Option<(ModuleMapKey, ModuleSource)> { - // SAFETY: JsContextHost is owned by the ScriptVm that owns this DocumentRuntime. - unsafe { &*self.runtime }.native_module_source_for(module) - } - pub(crate) fn native_module_wasm_record_for( &self, module: v8::Local<'_, v8::Module>, diff --git a/moli-renderer-v8/src/script_vm/native_module.rs b/moli-renderer-v8/src/script_vm/native_module.rs index d7d30eed34..dba03d0d8d 100644 --- a/moli-renderer-v8/src/script_vm/native_module.rs +++ b/moli-renderer-v8/src/script_vm/native_module.rs @@ -3433,22 +3433,6 @@ impl ScriptVm { }) } - fn compile_synthetic_module_record_in_context( - &mut self, - context_ptr: *const v8::Global, - key: ModuleMapKey, - _source: &str, - source_url: &Url, - ) -> std::result::Result<(ModuleRecordEntry, ModuleIdentityHash), ModuleLoadError> { - self.compile_synthetic_module_record_with_exports_in_context( - context_ptr, - key, - source_url, - &["default"], - None, - ) - } - fn compile_wasm_module_record_in_context( &mut self, context_ptr: *const v8::Global, @@ -3499,7 +3483,7 @@ impl ScriptVm { &scope, module_name, &export_names, - synthetic_module_evaluation_steps, + wasm_synthetic_module_evaluation_steps, ); let identity = module_identity_hash_from_v8_module(module); let compiled_module = v8::Global::new(scope.as_ref(), module); @@ -3519,13 +3503,12 @@ impl ScriptVm { }) } - fn compile_synthetic_module_record_with_exports_in_context( + fn compile_synthetic_module_record_in_context( &mut self, context_ptr: *const v8::Global, key: ModuleMapKey, + source: &str, source_url: &Url, - export_names: &[&str], - wasm_record: Option<(Vec, WasmModuleRecord)>, ) -> std::result::Result<(ModuleRecordEntry, ModuleIdentityHash), ModuleLoadError> { self.renderer_document_isolate .with_entered_renderer_document_isolate(|isolate| { @@ -3534,36 +3517,29 @@ impl ScriptVm { let context = unsafe { v8::Local::new(scope, &*context_ptr) }; let scope = &mut v8::ContextScope::new(scope, context); let try_catch = pin!(v8::TryCatch::new(scope)); - let scope = try_catch.init(); + let mut scope = try_catch.init(); let module_name = v8_string(&scope, source_url.as_str()).ok_or_else(|| { anyhow::anyhow!("failed to allocate v8 synthetic module name") })?; - let export_names = export_names - .iter() - .map(|name| { - v8_string(&scope, name).ok_or_else(|| { - anyhow::anyhow!("failed to allocate synthetic export name") - }) - }) - .collect::>>()?; + let default_export = v8_string(&scope, "default") + .ok_or_else(|| anyhow::anyhow!("failed to allocate synthetic export name"))?; let module = v8::Module::create_synthetic_module( &scope, module_name, - &export_names, - synthetic_module_evaluation_steps, + &[default_export], + synthetic_text_module_evaluation_steps, ); let identity = module_identity_hash_from_v8_module(module); + let evaluation_source = crate::module_runtime::SyntheticTextModuleSource::register( + &mut scope, + module, + key.clone(), + source, + ); let compiled_module = v8::Global::new(scope.as_ref(), module); - let entry = match wasm_record { - Some((requests, wasm_module)) => ModuleRecordEntry::new_with_wasm_module( - key, - compiled_module, - requests, - wasm_module, - ), - None => ModuleRecordEntry::new(key, compiled_module, Vec::new()), - }; + let entry = ModuleRecordEntry::new(key, compiled_module, Vec::new()) + .with_synthetic_text_module_source(evaluation_source); Ok((entry, identity)) }) .map_err(|error| ModuleLoadError::new(ModuleLoadStage::Compile, error.to_string())) @@ -4639,7 +4615,27 @@ fn get_i64_reaction_data_slot<'s>( lossless.then_some(value) } -fn synthetic_module_evaluation_steps<'s>( +fn synthetic_text_module_evaluation_steps<'s>( + context: v8::Local<'s, v8::Context>, + module: v8::Local<'s, v8::Module>, +) -> Option> { + v8::callback_scope!(unsafe scope, context); + let Some(record) = + crate::module_runtime::SyntheticTextModuleSource::for_module(context, module) + else { + return throw_synthetic_module_error(scope, "synthetic module source is not available"); + }; + let source = record.source(); + match record.key().kind() { + ModuleKind::Json => evaluate_json_synthetic_module(scope, module, source), + ModuleKind::Css => { + evaluate_css_synthetic_module(scope, module, record.key().url().as_str(), source) + } + _ => throw_synthetic_module_error(scope, "unexpected synthetic text module kind"), + } +} + +fn wasm_synthetic_module_evaluation_steps<'s>( context: v8::Local<'s, v8::Context>, module: v8::Local<'s, v8::Module>, ) -> Option> { @@ -4647,39 +4643,15 @@ fn synthetic_module_evaluation_steps<'s>( let Some(host_ptr) = context_host_ptr_from_global_bridge(scope) else { return throw_synthetic_module_error(scope, "synthetic module host is not available"); }; - let Some((key, source)) = (unsafe { &*host_ptr }).native_module_source_for(module) else { - return throw_synthetic_module_error(scope, "synthetic module source is not available"); - }; - match key.kind() { - ModuleKind::Json => { - let Some(source) = source.text_source() else { - return throw_synthetic_module_error(scope, "JSON module source is not text"); - }; - evaluate_json_synthetic_module(scope, module, source) - } - ModuleKind::Css => { - let Some(source) = source.text_source() else { - return throw_synthetic_module_error(scope, "CSS module source is not text"); - }; - evaluate_css_synthetic_module(scope, module, key.url().as_str(), source) - } - ModuleKind::WebAssembly => { - let Some(wasm_record) = (unsafe { &*host_ptr }).native_module_wasm_record_for(module) - else { - return throw_synthetic_module_error( - scope, - "WebAssembly synthetic module record is not available", - ); - }; - evaluate_wasm_synthetic_module(scope, module, &wasm_record, |scope, import| { - wasm_import_value(scope, module, import) - }) - } - ModuleKind::JavaScript | ModuleKind::ModulePreloadText => throw_synthetic_module_error( + let Some(wasm_record) = (unsafe { &*host_ptr }).native_module_wasm_record_for(module) else { + return throw_synthetic_module_error( scope, - "non-synthetic module reached synthetic module evaluation", - ), - } + "WebAssembly synthetic module record is not available", + ); + }; + evaluate_wasm_synthetic_module(scope, module, &wasm_record, |scope, import| { + wasm_import_value(scope, module, import) + }) } fn evaluate_json_synthetic_module<'s>(