From 51c3e358a055bac836131cbda8d9f0411051cb9c Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sat, 3 May 2025 12:26:41 -0700 Subject: [PATCH 1/5] esm: add support for dynamic source phase hook --- doc/api/esm.md | 11 +++++++++++ src/module_wrap.cc | 6 ++---- test/es-module/test-esm-wasm.mjs | 12 ++++-------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 93152f569d3e26..00788f866f60cc 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -726,6 +726,17 @@ const instance2 = await WebAssembly.instantiate(libraryModule, { }); ``` +In addition to the static source phase, there is also a dynamic variant of the +source phase via the `import.source` dynamic phase import syntax: + +```js +const dynamicLibrary = await import.source('./library.wasm'); + +const instance = await WebAssembly.instantiate(dynamicLibrary, { + custom: import +}); +``` + ## Top-level `await` diff --git a/src/module_wrap.cc b/src/module_wrap.cc index 1c7e9ff5a55474..2290a9072bfcfb 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -1065,10 +1065,8 @@ void ModuleWrap::SetImportModuleDynamicallyCallback( realm->set_host_import_module_dynamically_callback(import_callback); isolate->SetHostImportModuleDynamicallyCallback(ImportModuleDynamically); - // TODO(guybedford): Enable this once - // https://github.com/nodejs/node/pull/56842 lands. - // isolate->SetHostImportModuleWithPhaseDynamicallyCallback( - // ImportModuleDynamicallyWithPhase); + isolate->SetHostImportModuleWithPhaseDynamicallyCallback( + ImportModuleDynamicallyWithPhase); } void ModuleWrap::HostInitializeImportMetaObjectCallback( diff --git a/test/es-module/test-esm-wasm.mjs b/test/es-module/test-esm-wasm.mjs index b7a9230dd184b2..3abb1ca66303a0 100644 --- a/test/es-module/test-esm-wasm.mjs +++ b/test/es-module/test-esm-wasm.mjs @@ -124,8 +124,7 @@ describe('ESM: WASM modules', { concurrency: !process.env.TEST_PARALLEL }, () => strictEqual(code, 0); }); - // TODO: Enable this once https://github.com/nodejs/node/pull/56842 lands. - it.skip('should support dynamic source phase imports', async () => { + it('should support dynamic source phase imports', async () => { const { code, stderr, stdout } = await spawnPromisified(execPath, [ '--no-warnings', '--experimental-wasm-modules', @@ -166,8 +165,7 @@ describe('ESM: WASM modules', { concurrency: !process.env.TEST_PARALLEL }, () => strictEqual(code, 0); }); - // TODO: Enable this once https://github.com/nodejs/node/pull/56842 lands. - it.skip('should not execute dynamic source phase imports', async () => { + it('should not execute dynamic source phase imports', async () => { const { code, stderr, stdout } = await spawnPromisified(execPath, [ '--no-warnings', '--experimental-wasm-modules', @@ -181,8 +179,7 @@ describe('ESM: WASM modules', { concurrency: !process.env.TEST_PARALLEL }, () => strictEqual(code, 0); }); - // TODO: Enable this once https://github.com/nodejs/node/pull/56842 lands. - it.skip('should throw for dynamic source phase imports not defined', async () => { + it('should throw for dynamic source phase imports not defined', async () => { const fileUrl = fixtures.fileURL('es-modules/wasm-source-phase.js'); const { code, stderr, stdout } = await spawnPromisified(execPath, [ '--no-warnings', @@ -238,8 +235,7 @@ describe('ESM: WASM modules', { concurrency: !process.env.TEST_PARALLEL }, () => notStrictEqual(code, 0); }); - // TODO: Enable this once https://github.com/nodejs/node/pull/56842 lands. - it.skip('should throw for vm source phase dynamic import', async () => { + it('should throw for vm source phase dynamic import', async () => { const { code, stderr, stdout } = await spawnPromisified(execPath, [ '--no-warnings', '--experimental-wasm-modules', From f7ddd5728f5d2cf9100631c683565da30217dc45 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sat, 3 May 2025 12:39:40 -0700 Subject: [PATCH 2/5] eslint fix --- doc/api/esm.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/api/esm.md b/doc/api/esm.md index 00788f866f60cc..f29fb0d8beebe1 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -729,6 +729,8 @@ const instance2 = await WebAssembly.instantiate(libraryModule, { In addition to the static source phase, there is also a dynamic variant of the source phase via the `import.source` dynamic phase import syntax: + + ```js const dynamicLibrary = await import.source('./library.wasm'); From ac7c2334fc81f4a88875327336f22f13988a178f Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Sat, 3 May 2025 12:46:02 -0700 Subject: [PATCH 3/5] fixup validation function --- test/es-module/test-esm-wasm.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/test/es-module/test-esm-wasm.mjs b/test/es-module/test-esm-wasm.mjs index 3abb1ca66303a0..41e56b988a9f8f 100644 --- a/test/es-module/test-esm-wasm.mjs +++ b/test/es-module/test-esm-wasm.mjs @@ -192,6 +192,7 @@ describe('ESM: WASM modules', { concurrency: !process.env.TEST_PARALLEL }, () => ' strictEqual(e instanceof SyntaxError, true);', ' strictEqual(e.message.includes("Source phase import object is not defined for module"), true);', ` strictEqual(e.message.includes(${JSON.stringify(fileUrl)}), true);`, + ` return true`, '});', ].join('\n'), ]); From b7de7ee36dd17dabf50a9cf88ae8f82c32afc8c9 Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Tue, 13 May 2025 14:21:34 -0700 Subject: [PATCH 4/5] docs lint fix --- doc/api/esm.md | 4 +--- eslint.config.mjs | 1 + 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index f29fb0d8beebe1..3e317034431309 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -729,13 +729,11 @@ const instance2 = await WebAssembly.instantiate(libraryModule, { In addition to the static source phase, there is also a dynamic variant of the source phase via the `import.source` dynamic phase import syntax: - - ```js const dynamicLibrary = await import.source('./library.wasm'); const instance = await WebAssembly.instantiate(dynamicLibrary, { - custom: import + custom: importObj, }); ``` diff --git a/eslint.config.mjs b/eslint.config.mjs index 75241d0eed65c4..5f2e5b3b857cea 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -104,6 +104,7 @@ export default [ parser: babelEslintParser, parserOptions: { babelOptions: { + parserOpts: { createImportExpressions: true }, plugins: [ babelPluginProposalExplicitResourceManagement, babelPluginSyntaxImportAttributes, From 7ca049e200c066aa7f06873c8c4d9e0b320c1a0a Mon Sep 17 00:00:00 2001 From: Guy Bedford Date: Wed, 21 May 2025 18:41:58 -0700 Subject: [PATCH 5/5] just use importobj term directly --- doc/api/esm.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/doc/api/esm.md b/doc/api/esm.md index 3e317034431309..707eb9d41d172c 100644 --- a/doc/api/esm.md +++ b/doc/api/esm.md @@ -717,13 +717,9 @@ into a new instance of `library.wasm`: ```js import source libraryModule from './library.wasm'; -const instance1 = await WebAssembly.instantiate(libraryModule, { - custom: import1, -}); +const instance1 = await WebAssembly.instantiate(libraryModule, importObject1); -const instance2 = await WebAssembly.instantiate(libraryModule, { - custom: import2, -}); +const instance2 = await WebAssembly.instantiate(libraryModule, importObject2); ``` In addition to the static source phase, there is also a dynamic variant of the @@ -732,9 +728,7 @@ source phase via the `import.source` dynamic phase import syntax: ```js const dynamicLibrary = await import.source('./library.wasm'); -const instance = await WebAssembly.instantiate(dynamicLibrary, { - custom: importObj, -}); +const instance = await WebAssembly.instantiate(dynamicLibrary, importObject); ```