diff --git a/lib/internal/modules/esm/create_dynamic_module.js b/lib/internal/modules/esm/create_dynamic_module.js index 26e21d8407c729..e66f032e29f3af 100644 --- a/lib/internal/modules/esm/create_dynamic_module.js +++ b/lib/internal/modules/esm/create_dynamic_module.js @@ -44,7 +44,7 @@ import.meta.exports[${nameStringLit}] = { * @param {string} [url=''] - The URL of the module. * @param {(reflect: DynamicModuleReflect) => void} evaluate - The function to evaluate the module. * @typedef {object} DynamicModuleReflect - * @property {string[]} imports - The imports of the module. + * @property {Record>} imports - The imports of the module. * @property {string[]} exports - The exports of the module. * @property {(cb: (reflect: DynamicModuleReflect) => void) => void} onReady - Callback to evaluate the module. */ diff --git a/lib/internal/modules/esm/translators.js b/lib/internal/modules/esm/translators.js index 0a8e4c9e5d3af5..5e9fd3a96112fd 100644 --- a/lib/internal/modules/esm/translators.js +++ b/lib/internal/modules/esm/translators.js @@ -1,16 +1,18 @@ 'use strict'; const { + ArrayPrototypeFilter, ArrayPrototypeMap, ArrayPrototypePush, FunctionPrototypeCall, JSONParse, - ObjectKeys, + ObjectAssign, ObjectPrototypeHasOwnProperty, ReflectApply, SafeArrayIterator, SafeMap, SafeSet, + SafeWeakMap, StringPrototypeIncludes, StringPrototypeReplaceAll, StringPrototypeSlice, @@ -483,6 +485,14 @@ translators.set('json', function jsonStrategy(url, source) { }); // Strategy for loading a wasm module +// This logic should collapse into WebAssembly Module Record in future. +/** + * @type {WeakMap< + * import('internal/modules/esm/utils').ModuleNamespaceObject, + * WebAssembly.Instance + * >} [[Instance]] slot proxy for WebAssembly Module Record + */ +const wasmInstances = new SafeWeakMap(); translators.set('wasm', async function(url, source) { emitExperimentalWarning('Importing WebAssembly modules'); @@ -501,19 +511,54 @@ translators.set('wasm', async function(url, source) { throw err; } - const imports = - ArrayPrototypeMap(WebAssembly.Module.imports(compiled), - ({ module }) => module); - const exports = - ArrayPrototypeMap(WebAssembly.Module.exports(compiled), - ({ name }) => name); + const wasmImports = WebAssembly.Module.imports(compiled); + const wasmGlobalImports = ArrayPrototypeFilter(wasmImports, ({ kind }) => kind === 'global'); + + const wasmExports = WebAssembly.Module.exports(compiled); + const wasmGlobalExports = new SafeSet(ArrayPrototypeMap( + ArrayPrototypeFilter(wasmExports, ({ kind }) => kind === 'global'), + ({ name }) => name, + )); + + const importsList = new SafeSet(ArrayPrototypeMap(wasmImports, ({ module }) => module)); + const exportsList = ArrayPrototypeMap(wasmExports, ({ name }) => name); const createDynamicModule = require( 'internal/modules/esm/create_dynamic_module'); - const { module } = createDynamicModule(imports, exports, url, (reflect) => { + + const { module } = createDynamicModule([...importsList], exportsList, url, (reflect) => { + for (const impt of importsList) { + const importNs = reflect.imports[impt]; + const wasmInstance = wasmInstances.get(importNs); + if (wasmInstance) { + const wrappedModule = ObjectAssign({ __proto__: null }, reflect.imports[impt]); + for (const { module, name } of wasmGlobalImports) { + if (module !== impt) { + continue; + } + // Import of Wasm module global -> get direct WebAssembly.Global wrapped value. + // JS API validations otherwise remain the same. + wrappedModule[name] = wasmInstance[name]; + } + reflect.imports[impt] = wrappedModule; + } + } + // In cycles importing unexecuted Wasm, wasmInstance will be undefined, which will fail during + // instantiation, since all bindings will be in TDZ. const { exports } = new WebAssembly.Instance(compiled, reflect.imports); - for (const expt of ObjectKeys(exports)) { - reflect.exports[expt].set(exports[expt]); + wasmInstances.set(module.getNamespace(), exports); + for (const expt of exportsList) { + let val = exports[expt]; + // Unwrap WebAssembly.Global for JS bindings + if (wasmGlobalExports.has(expt)) { + // v128 doesn't support ToJsValue() -> undefined (ideally should stay in TDZ) + try { + val = val.value; + } catch { + continue; + } + } + reflect.exports[expt].set(val); } }); // WebAssembly modules support source phase imports, to import the compiled module diff --git a/test/es-module/test-esm-wasm.mjs b/test/es-module/test-esm-wasm.mjs index cdfcad517efb7c..32082e0d0fa372 100644 --- a/test/es-module/test-esm-wasm.mjs +++ b/test/es-module/test-esm-wasm.mjs @@ -52,7 +52,142 @@ describe('ESM: WASM modules', { concurrency: !process.env.TEST_PARALLEL }, () => [ 'import { strictEqual } from "node:assert";', `import * as wasmExports from ${JSON.stringify(fixtures.fileURL('es-modules/export-name-syntax-error.wasm'))};`, - 'assert.strictEqual(wasmExports["?f!o:oa[r]"]?.value, 12682);', + 'assert.strictEqual(wasmExports["?f!o:oa[r]"], 12682);', + ].join('\n'), + ]); + + strictEqual(stderr, ''); + strictEqual(stdout, ''); + strictEqual(code, 0); + }); + + it('should properly handle all WebAssembly global types', async () => { + const { code, stderr, stdout } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-wasm-modules', + '--input-type=module', + '--eval', + [ + 'import { strictEqual, deepStrictEqual } from "node:assert";', + `import * as wasmExports from ${JSON.stringify(fixtures.fileURL('es-modules/globals.wasm'))};`, + + // Test imported globals using direct access + 'strictEqual(wasmExports.importedI32, 42);', + 'strictEqual(wasmExports.importedMutI32, 100);', + 'strictEqual(wasmExports.importedI64, 9223372036854775807n);', + 'strictEqual(wasmExports.importedMutI64, 200n);', + 'strictEqual(Math.round(wasmExports.importedF32 * 100000) / 100000, 3.14159);', + 'strictEqual(Math.round(wasmExports.importedMutF32 * 100000) / 100000, 2.71828);', + 'strictEqual(wasmExports.importedF64, 3.141592653589793);', + 'strictEqual(wasmExports.importedMutF64, 2.718281828459045);', + 'strictEqual(wasmExports.importedExternref !== null, true);', + 'strictEqual(wasmExports.importedMutExternref !== null, true);', + 'strictEqual(wasmExports.importedNullExternref, null);', + + // Test local globals exported directly + 'strictEqual(wasmExports[\'🚀localI32\'], 42);', + 'strictEqual(wasmExports.localMutI32, 100);', + 'strictEqual(wasmExports.localI64, 9223372036854775807n);', + 'strictEqual(wasmExports.localMutI64, 200n);', + 'strictEqual(Math.round(wasmExports.localF32 * 100000) / 100000, 3.14159);', + 'strictEqual(Math.round(wasmExports.localMutF32 * 100000) / 100000, 2.71828);', + 'strictEqual(wasmExports.localF64, 2.718281828459045);', + 'strictEqual(wasmExports.localMutF64, 3.141592653589793);', + + // Test imported globals using getter functions + 'strictEqual(wasmExports.getImportedMutI32(), 100);', + 'strictEqual(wasmExports.getImportedMutI64(), 200n);', + 'strictEqual(Math.round(wasmExports.getImportedMutF32() * 100000) / 100000, 2.71828);', + 'strictEqual(wasmExports.getImportedMutF64(), 2.718281828459045);', + 'strictEqual(wasmExports.getImportedMutExternref() !== null, true);', + + // Test local globals using getter functions + 'strictEqual(wasmExports.getLocalMutI32(), 100);', + 'strictEqual(wasmExports.getLocalMutI64(), 200n);', + 'strictEqual(Math.round(wasmExports.getLocalMutF32() * 100000) / 100000, 2.71828);', + 'strictEqual(wasmExports.getLocalMutF64(), 3.141592653589793);', + 'strictEqual(wasmExports.getLocalMutExternref(), null);', + + 'assert.throws(wasmExports.getLocalMutV128);', + + // Pending TDZ support + 'strictEqual(wasmExports.depV128, undefined);', + + // Test modifying mutable globals and reading the new values + 'wasmExports.setImportedMutI32(999);', + 'strictEqual(wasmExports.getImportedMutI32(), 999);', + + 'wasmExports.setImportedMutI64(888n);', + 'strictEqual(wasmExports.getImportedMutI64(), 888n);', + + 'wasmExports.setImportedMutF32(7.77);', + 'strictEqual(Math.round(wasmExports.getImportedMutF32() * 100) / 100, 7.77);', + + 'wasmExports.setImportedMutF64(6.66);', + 'strictEqual(wasmExports.getImportedMutF64(), 6.66);', + + // Test modifying mutable externref + 'const testObj = { test: "object" };', + 'wasmExports.setImportedMutExternref(testObj);', + 'strictEqual(wasmExports.getImportedMutExternref(), testObj);', + + // Test modifying local mutable globals + 'wasmExports.setLocalMutI32(555);', + 'strictEqual(wasmExports.getLocalMutI32(), 555);', + + 'wasmExports.setLocalMutI64(444n);', + 'strictEqual(wasmExports.getLocalMutI64(), 444n);', + + 'wasmExports.setLocalMutF32(3.33);', + 'strictEqual(Math.round(wasmExports.getLocalMutF32() * 100) / 100, 3.33);', + + 'wasmExports.setLocalMutF64(2.22);', + 'strictEqual(wasmExports.getLocalMutF64(), 2.22);', + + // These mutating pending live bindings support + 'strictEqual(wasmExports.localMutI32, 100);', + 'strictEqual(wasmExports.localMutI64, 200n);', + 'strictEqual(Math.round(wasmExports.localMutF32 * 100) / 100, 2.72);', + 'strictEqual(wasmExports.localMutF64, 3.141592653589793);', + + // Test modifying local mutable externref + 'const anotherTestObj = { another: "test object" };', + 'wasmExports.setLocalMutExternref(anotherTestObj);', + 'strictEqual(wasmExports.getLocalMutExternref(), anotherTestObj);', + 'strictEqual(wasmExports.localMutExternref, null);', + + // Test dep.wasm imports + 'strictEqual(wasmExports.depI32, 1001);', + 'strictEqual(wasmExports.depMutI32, 2001);', + 'strictEqual(wasmExports.getDepMutI32(), 2001);', + 'strictEqual(wasmExports.depI64, 10000000001n);', + 'strictEqual(wasmExports.depMutI64, 20000000001n);', + 'strictEqual(wasmExports.getDepMutI64(), 20000000001n);', + 'strictEqual(Math.round(wasmExports.depF32 * 100) / 100, 10.01);', + 'strictEqual(Math.round(wasmExports.depMutF32 * 100) / 100, 20.01);', + 'strictEqual(Math.round(wasmExports.getDepMutF32() * 100) / 100, 20.01);', + 'strictEqual(wasmExports.depF64, 100.0001);', + 'strictEqual(wasmExports.depMutF64, 200.0001);', + 'strictEqual(wasmExports.getDepMutF64(), 200.0001);', + + // Test modifying dep.wasm mutable globals + 'wasmExports.setDepMutI32(3001);', + 'strictEqual(wasmExports.getDepMutI32(), 3001);', + + 'wasmExports.setDepMutI64(30000000001n);', + 'strictEqual(wasmExports.getDepMutI64(), 30000000001n);', + + 'wasmExports.setDepMutF32(30.01);', + 'strictEqual(Math.round(wasmExports.getDepMutF32() * 100) / 100, 30.01);', + + 'wasmExports.setDepMutF64(300.0001);', + 'strictEqual(wasmExports.getDepMutF64(), 300.0001);', + + // These pending live bindings support + 'strictEqual(wasmExports.depMutI32, 2001);', + 'strictEqual(wasmExports.depMutI64, 20000000001n);', + 'strictEqual(Math.round(wasmExports.depMutF32 * 100) / 100, 20.01);', + 'strictEqual(wasmExports.depMutF64, 200.0001);', ].join('\n'), ]); diff --git a/test/fixtures/es-modules/dep.wasm b/test/fixtures/es-modules/dep.wasm new file mode 100644 index 00000000000000..ad9abfaa66af53 Binary files /dev/null and b/test/fixtures/es-modules/dep.wasm differ diff --git a/test/fixtures/es-modules/dep.wat b/test/fixtures/es-modules/dep.wat new file mode 100644 index 00000000000000..26edc9799ce5cb --- /dev/null +++ b/test/fixtures/es-modules/dep.wat @@ -0,0 +1,32 @@ +(module + (type (;0;) (func (result i32))) + (type (;1;) (func (result i64))) + (type (;2;) (func (result f32))) + (type (;3;) (func (result f64))) + (type (;4;) (func (result externref))) + (type (;5;) (func (result v128))) + (global $i32_value (;0;) i32 i32.const 1001) + (global $i32_mut_value (;1;) (mut i32) i32.const 2001) + (global $i64_value (;2;) i64 i64.const 10000000001) + (global $i64_mut_value (;3;) (mut i64) i64.const 20000000001) + (global $f32_value (;4;) f32 f32.const 0x1.4051ecp+3 (;=10.01;)) + (global $f32_mut_value (;5;) (mut f32) f32.const 0x1.4028f6p+4 (;=20.01;)) + (global $f64_value (;6;) f64 f64.const 0x1.90001a36e2eb2p+6 (;=100.0001;)) + (global $f64_mut_value (;7;) (mut f64) f64.const 0x1.90000d1b71759p+7 (;=200.0001;)) + (global $externref_value (;8;) externref ref.null extern) + (global $externref_mut_value (;9;) (mut externref) ref.null extern) + (global $v128_value (;10;) v128 v128.const i32x4 0x0000000a 0x00000014 0x0000001e 0x00000028) + (global $v128_mut_value (;11;) (mut v128) v128.const i32x4 0x00000032 0x0000003c 0x00000046 0x00000050) + (export "i32_value" (global $i32_value)) + (export "i32_mut_value" (global $i32_mut_value)) + (export "i64_value" (global $i64_value)) + (export "i64_mut_value" (global $i64_mut_value)) + (export "f32_value" (global $f32_value)) + (export "f32_mut_value" (global $f32_mut_value)) + (export "f64_value" (global $f64_value)) + (export "f64_mut_value" (global $f64_mut_value)) + (export "externref_value" (global $externref_value)) + (export "externref_mut_value" (global $externref_mut_value)) + (export "v128_value" (global $v128_value)) + (export "v128_mut_value" (global $v128_mut_value)) +) diff --git a/test/fixtures/es-modules/globals.js b/test/fixtures/es-modules/globals.js new file mode 100644 index 00000000000000..0b01c0225e020d --- /dev/null +++ b/test/fixtures/es-modules/globals.js @@ -0,0 +1,18 @@ +// globals.js - Direct global exports for WebAssembly imports + +// Immutable globals (simple values) +const i32_value = 42; +export { i32_value as '🚀i32_value' } +export const i64_value = 9223372036854775807n; // Max i64 value +export const f32_value = 3.14159; +export const f64_value = 3.141592653589793; + +// Mutable globals with WebAssembly.Global wrapper +export const i32_mut_value = new WebAssembly.Global({ value: 'i32', mutable: true }, 100); +export const i64_mut_value = new WebAssembly.Global({ value: 'i64', mutable: true }, 200n); +export const f32_mut_value = new WebAssembly.Global({ value: 'f32', mutable: true }, 2.71828); +export const f64_mut_value = new WebAssembly.Global({ value: 'f64', mutable: true }, 2.718281828459045); + +export const externref_value = { hello: 'world' }; +export const externref_mut_value = new WebAssembly.Global({ value: 'externref', mutable: true }, { mutable: 'global' }); +export const null_externref_value = null; diff --git a/test/fixtures/es-modules/globals.wasm b/test/fixtures/es-modules/globals.wasm new file mode 100644 index 00000000000000..45188ab26ee5c1 Binary files /dev/null and b/test/fixtures/es-modules/globals.wasm differ diff --git a/test/fixtures/es-modules/globals.wat b/test/fixtures/es-modules/globals.wat new file mode 100644 index 00000000000000..c261222dd3cdab --- /dev/null +++ b/test/fixtures/es-modules/globals.wat @@ -0,0 +1,237 @@ +(module + (type (;0;) (func (result i32))) + (type (;1;) (func (result i64))) + (type (;2;) (func (result f32))) + (type (;3;) (func (result f64))) + (type (;4;) (func (result externref))) + (type (;5;) (func (result v128))) + (type (;6;) (func (param i32))) + (type (;7;) (func (param i64))) + (type (;8;) (func (param f32))) + (type (;9;) (func (param f64))) + (type (;10;) (func (param externref))) + (type (;11;) (func (param v128))) + (import "./globals.js" "\u{1f680}i32_value" (global $imported_i32 (;0;) i32)) + (import "./globals.js" "i32_mut_value" (global $imported_mut_i32 (;1;) (mut i32))) + (import "./globals.js" "i64_value" (global $imported_i64 (;2;) i64)) + (import "./globals.js" "i64_mut_value" (global $imported_mut_i64 (;3;) (mut i64))) + (import "./globals.js" "f32_value" (global $imported_f32 (;4;) f32)) + (import "./globals.js" "f32_mut_value" (global $imported_mut_f32 (;5;) (mut f32))) + (import "./globals.js" "f64_value" (global $imported_f64 (;6;) f64)) + (import "./globals.js" "f64_mut_value" (global $imported_mut_f64 (;7;) (mut f64))) + (import "./globals.js" "externref_value" (global $imported_externref (;8;) externref)) + (import "./globals.js" "externref_mut_value" (global $imported_mut_externref (;9;) (mut externref))) + (import "./globals.js" "null_externref_value" (global $imported_null_externref (;10;) externref)) + (import "./dep.wasm" "i32_value" (global $dep_i32 (;11;) i32)) + (import "./dep.wasm" "i32_mut_value" (global $dep_mut_i32 (;12;) (mut i32))) + (import "./dep.wasm" "i64_value" (global $dep_i64 (;13;) i64)) + (import "./dep.wasm" "i64_mut_value" (global $dep_mut_i64 (;14;) (mut i64))) + (import "./dep.wasm" "f32_value" (global $dep_f32 (;15;) f32)) + (import "./dep.wasm" "f32_mut_value" (global $dep_mut_f32 (;16;) (mut f32))) + (import "./dep.wasm" "f64_value" (global $dep_f64 (;17;) f64)) + (import "./dep.wasm" "f64_mut_value" (global $dep_mut_f64 (;18;) (mut f64))) + (import "./dep.wasm" "externref_value" (global $dep_externref (;19;) externref)) + (import "./dep.wasm" "externref_mut_value" (global $dep_mut_externref (;20;) (mut externref))) + (import "./dep.wasm" "v128_value" (global $dep_v128 (;21;) v128)) + (import "./dep.wasm" "v128_mut_value" (global $dep_mut_v128 (;22;) (mut v128))) + (global $local_i32 (;23;) i32 i32.const 42) + (global $local_mut_i32 (;24;) (mut i32) i32.const 100) + (global $local_i64 (;25;) i64 i64.const 9223372036854775807) + (global $local_mut_i64 (;26;) (mut i64) i64.const 200) + (global $local_f32 (;27;) f32 f32.const 0x1.921fap+1 (;=3.14159;)) + (global $local_mut_f32 (;28;) (mut f32) f32.const 0x1.5bf09ap+1 (;=2.71828;)) + (global $local_f64 (;29;) f64 f64.const 0x1.5bf0a8b145769p+1 (;=2.718281828459045;)) + (global $local_mut_f64 (;30;) (mut f64) f64.const 0x1.921fb54442d18p+1 (;=3.141592653589793;)) + (global $local_externref (;31;) externref ref.null extern) + (global $local_mut_externref (;32;) (mut externref) ref.null extern) + (global $local_v128 (;33;) v128 v128.const i32x4 0x00000001 0x00000002 0x00000003 0x00000004) + (global $local_mut_v128 (;34;) (mut v128) v128.const i32x4 0x00000005 0x00000006 0x00000007 0x00000008) + (export "importedI32" (global $imported_i32)) + (export "importedMutI32" (global $imported_mut_i32)) + (export "importedI64" (global $imported_i64)) + (export "importedMutI64" (global $imported_mut_i64)) + (export "importedF32" (global $imported_f32)) + (export "importedMutF32" (global $imported_mut_f32)) + (export "importedF64" (global $imported_f64)) + (export "importedMutF64" (global $imported_mut_f64)) + (export "importedExternref" (global $imported_externref)) + (export "importedMutExternref" (global $imported_mut_externref)) + (export "importedNullExternref" (global $imported_null_externref)) + (export "depI32" (global $dep_i32)) + (export "depMutI32" (global $dep_mut_i32)) + (export "depI64" (global $dep_i64)) + (export "depMutI64" (global $dep_mut_i64)) + (export "depF32" (global $dep_f32)) + (export "depMutF32" (global $dep_mut_f32)) + (export "depF64" (global $dep_f64)) + (export "depMutF64" (global $dep_mut_f64)) + (export "depExternref" (global $dep_externref)) + (export "depMutExternref" (global $dep_mut_externref)) + (export "depV128" (global $dep_v128)) + (export "depMutV128" (global $dep_mut_v128)) + (export "\u{1f680}localI32" (global $local_i32)) + (export "localMutI32" (global $local_mut_i32)) + (export "localI64" (global $local_i64)) + (export "localMutI64" (global $local_mut_i64)) + (export "localF32" (global $local_f32)) + (export "localMutF32" (global $local_mut_f32)) + (export "localF64" (global $local_f64)) + (export "localMutF64" (global $local_mut_f64)) + (export "localExternref" (global $local_externref)) + (export "localMutExternref" (global $local_mut_externref)) + (export "localV128" (global $local_v128)) + (export "localMutV128" (global $local_mut_v128)) + (export "getImportedMutI32" (func $getImportedMutI32)) + (export "getImportedMutI64" (func $getImportedMutI64)) + (export "getImportedMutF32" (func $getImportedMutF32)) + (export "getImportedMutF64" (func $getImportedMutF64)) + (export "getImportedMutExternref" (func $getImportedMutExternref)) + (export "getLocalMutI32" (func $getLocalMutI32)) + (export "getLocalMutI64" (func $getLocalMutI64)) + (export "getLocalMutF32" (func $getLocalMutF32)) + (export "getLocalMutF64" (func $getLocalMutF64)) + (export "getLocalMutExternref" (func $getLocalMutExternref)) + (export "getLocalMutV128" (func $getLocalMutV128)) + (export "getDepMutI32" (func $getDepMutI32)) + (export "getDepMutI64" (func $getDepMutI64)) + (export "getDepMutF32" (func $getDepMutF32)) + (export "getDepMutF64" (func $getDepMutF64)) + (export "getDepMutExternref" (func $getDepMutExternref)) + (export "getDepMutV128" (func $getDepMutV128)) + (export "setImportedMutI32" (func $setImportedMutI32)) + (export "setImportedMutI64" (func $setImportedMutI64)) + (export "setImportedMutF32" (func $setImportedMutF32)) + (export "setImportedMutF64" (func $setImportedMutF64)) + (export "setImportedMutExternref" (func $setImportedMutExternref)) + (export "setLocalMutI32" (func $setLocalMutI32)) + (export "setLocalMutI64" (func $setLocalMutI64)) + (export "setLocalMutF32" (func $setLocalMutF32)) + (export "setLocalMutF64" (func $setLocalMutF64)) + (export "setLocalMutExternref" (func $setLocalMutExternref)) + (export "setLocalMutV128" (func $setLocalMutV128)) + (export "setDepMutI32" (func $setDepMutI32)) + (export "setDepMutI64" (func $setDepMutI64)) + (export "setDepMutF32" (func $setDepMutF32)) + (export "setDepMutF64" (func $setDepMutF64)) + (export "setDepMutExternref" (func $setDepMutExternref)) + (export "setDepMutV128" (func $setDepMutV128)) + (func $getImportedMutI32 (;0;) (type 0) (result i32) + global.get $imported_mut_i32 + ) + (func $getImportedMutI64 (;1;) (type 1) (result i64) + global.get $imported_mut_i64 + ) + (func $getImportedMutF32 (;2;) (type 2) (result f32) + global.get $imported_mut_f32 + ) + (func $getImportedMutF64 (;3;) (type 3) (result f64) + global.get $imported_mut_f64 + ) + (func $getImportedMutExternref (;4;) (type 4) (result externref) + global.get $imported_mut_externref + ) + (func $setImportedMutI32 (;5;) (type 6) (param i32) + local.get 0 + global.set $imported_mut_i32 + ) + (func $setImportedMutI64 (;6;) (type 7) (param i64) + local.get 0 + global.set $imported_mut_i64 + ) + (func $setImportedMutF32 (;7;) (type 8) (param f32) + local.get 0 + global.set $imported_mut_f32 + ) + (func $setImportedMutF64 (;8;) (type 9) (param f64) + local.get 0 + global.set $imported_mut_f64 + ) + (func $setImportedMutExternref (;9;) (type 10) (param externref) + local.get 0 + global.set $imported_mut_externref + ) + (func $getLocalMutI32 (;10;) (type 0) (result i32) + global.get $local_mut_i32 + ) + (func $getLocalMutI64 (;11;) (type 1) (result i64) + global.get $local_mut_i64 + ) + (func $getLocalMutF32 (;12;) (type 2) (result f32) + global.get $local_mut_f32 + ) + (func $getLocalMutF64 (;13;) (type 3) (result f64) + global.get $local_mut_f64 + ) + (func $getLocalMutExternref (;14;) (type 4) (result externref) + global.get $local_mut_externref + ) + (func $getLocalMutV128 (;15;) (type 5) (result v128) + global.get $local_mut_v128 + ) + (func $setLocalMutI32 (;16;) (type 6) (param i32) + local.get 0 + global.set $local_mut_i32 + ) + (func $setLocalMutI64 (;17;) (type 7) (param i64) + local.get 0 + global.set $local_mut_i64 + ) + (func $setLocalMutF32 (;18;) (type 8) (param f32) + local.get 0 + global.set $local_mut_f32 + ) + (func $setLocalMutF64 (;19;) (type 9) (param f64) + local.get 0 + global.set $local_mut_f64 + ) + (func $setLocalMutExternref (;20;) (type 10) (param externref) + local.get 0 + global.set $local_mut_externref + ) + (func $setLocalMutV128 (;21;) (type 11) (param v128) + local.get 0 + global.set $local_mut_v128 + ) + (func $getDepMutI32 (;22;) (type 0) (result i32) + global.get $dep_mut_i32 + ) + (func $getDepMutI64 (;23;) (type 1) (result i64) + global.get $dep_mut_i64 + ) + (func $getDepMutF32 (;24;) (type 2) (result f32) + global.get $dep_mut_f32 + ) + (func $getDepMutF64 (;25;) (type 3) (result f64) + global.get $dep_mut_f64 + ) + (func $getDepMutExternref (;26;) (type 4) (result externref) + global.get $dep_mut_externref + ) + (func $getDepMutV128 (;27;) (type 5) (result v128) + global.get $dep_mut_v128 + ) + (func $setDepMutI32 (;28;) (type 6) (param i32) + local.get 0 + global.set $dep_mut_i32 + ) + (func $setDepMutI64 (;29;) (type 7) (param i64) + local.get 0 + global.set $dep_mut_i64 + ) + (func $setDepMutF32 (;30;) (type 8) (param f32) + local.get 0 + global.set $dep_mut_f32 + ) + (func $setDepMutF64 (;31;) (type 9) (param f64) + local.get 0 + global.set $dep_mut_f64 + ) + (func $setDepMutExternref (;32;) (type 10) (param externref) + local.get 0 + global.set $dep_mut_externref + ) + (func $setDepMutV128 (;33;) (type 11) (param v128) + local.get 0 + global.set $dep_mut_v128 + ) +)