From 7ec7c503cd9ec2d9b6bdb9730c01a107a85fa33e Mon Sep 17 00:00:00 2001 From: Rusty Conover Date: Sat, 17 Oct 2026 12:30:27 -0400 Subject: [PATCH 1/6] Read exported global mutability from the side module binary relocateExports used isImmutableGlobal on every exported global, which detects an immutable global by trying to write it and catching the exception. Side modules export each data symbol as an immutable global, so loading one throws and catches an exception per data export (over a thousand for some real libraries). getDylinkMetadata now also reads the import, global and export sections when it has the module bytes, and records which exported globals are mutable. relocateExports uses that instead of probing. When only a compiled WebAssembly.Module is available, or the sections contain something the parser doesn't handle, it falls back to isImmutableGlobal. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/lib/libdylink.js | 100 ++++++++++++++++++++++++++++++++++++++++--- test/test_other.py | 54 +++++++++++++++++++++++ 2 files changed, 149 insertions(+), 5 deletions(-) diff --git a/src/lib/libdylink.js b/src/lib/libdylink.js index f4fe51f2fc3d9..02ae9db42adc1 100644 --- a/src/lib/libdylink.js +++ b/src/lib/libdylink.js @@ -280,7 +280,8 @@ var LibraryDylink = { // Applies relocations to exported things. $relocateExports__internal: true, $relocateExports__deps: ['$isImmutableGlobal'], - $relocateExports: (exports, memoryBase = 0) => { + $relocateExports__docs: '/** @param {Set=} mutableGlobals */', + $relocateExports: (exports, memoryBase = 0, mutableGlobals) => { #if DYLINK_DEBUG dbg(`relocateExports memoryBase=${memoryBase} count=${Object.keys(exports).length}`); #endif @@ -293,8 +294,12 @@ var LibraryDylink = { } #endif // Detect immutable wasm global exports. These represent data addresses - // which are relative to `memoryBase` - if (isImmutableGlobal(value)) { + // which are relative to `memoryBase`. `mutableGlobals`, when known, + // saves probing each global. + var immutable = mutableGlobals + ? value instanceof WebAssembly.Global && !mutableGlobals.has(name) + : isImmutableGlobal(value); + if (immutable) { return new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}'}, value.value + {{{ to64('memoryBase') }}}); } @@ -476,7 +481,89 @@ var LibraryDylink = { if (condition) throw new Error(message); } - if (binary instanceof WebAssembly.Module) { + // Returns the names of the exported globals that are mutable, read from + // the import, global and export sections that follow the dylink section. + // This saves relocateExports from probing each exported global with + // isImmutableGlobal, which throws for every immutable one. Returns + // undefined if it finds something it doesn't handle. + function getMutableGlobals() { + // The mutability of each global, imported globals first. + var mutable = []; + var result = new Set(); + + function skipString() { + var len = getLEB(); + offset += len; + } + + function skipValType() { + // (ref null? heaptype) has a heap type immediate. + var type = getU8(); + if (type === 0x63 || type === 0x64) getLEB(); + } + + function skipLimits() { + var flags = getU8(); + getLEB(); // min + if (flags & 1) getLEB(); // max + if (flags & 8) getLEB(); // page size (custom-page-sizes) + } + + while (offset < binary.length) { + var id = getU8(); + var size = getLEB(); + var sectionEnd = offset + size; + if (id === 2) { // import + for (var count = getLEB(); count--;) { + skipString(); + skipString(); + var kind = getU8(); + if (kind === 0) getLEB(); // function + else if (kind === 1) { skipValType(); skipLimits(); } // table + else if (kind === 2) skipLimits(); // memory + else if (kind === 3) { skipValType(); mutable.push(getU8() & 1); } // global + else if (kind === 4) { getU8(); getLEB(); } // tag + else return; + } + } else if (id === 6) { // global + for (var count = getLEB(); count--;) { + skipValType(); + mutable.push(getU8() & 1); + // Skip the constant init expression. + for (var op; (op = getU8()) !== 0x0b;) { + if (op === 0x43) offset += 4; // f32.const + else if (op === 0x44) offset += 8; // f64.const + // i32.const, i64.const, global.get, ref.null, ref.func + else if (op === 0x41 || op === 0x42 || op === 0x23 || op === 0xd0 || op === 0xd2) getLEB(); + // Anything but the extended-const add, sub and mul instructions + else if (!(op >= 0x6a && op <= 0x6c || op >= 0x7c && op <= 0x7e)) return; + } + } + } else if (id === 7) { // export + for (var count = getLEB(); count--;) { + var nameStart = offset; + skipString(); + var kind = getU8(); + var index = getLEB(); + if (kind === 3 && mutable[index]) { + var saved = offset; + offset = nameStart; + result.add(getString()); + offset = saved; + } + } + // The export section is the last one we need. + return offset === sectionEnd ? result : undefined; + } else { + offset = sectionEnd; + } + if (offset !== sectionEnd) return; + } + return result; + } + + var isModule = binary instanceof WebAssembly.Module; + if (isModule) { var dylinkSection = WebAssembly.Module.customSections(binary, 'dylink.0'); failIf(!dylinkSection.length, 'need dylink section'); binary = new Uint8Array(dylinkSection[0]); @@ -562,6 +649,9 @@ var LibraryDylink = { dbg('dylink needed:', customSection.neededDynlibs); #endif + if (!isModule) { + customSection.mutableGlobals = getMutableGlobals(); + } return customSection; }, @@ -885,7 +975,7 @@ var LibraryDylink = { #endif // add new entries to functionsInTableMap updateTableMap(tableBase, metadata.tableSize); - moduleExports = relocateExports(instance.exports, memoryBase); + moduleExports = relocateExports(instance.exports, memoryBase, metadata.mutableGlobals); updateGOT(moduleExports); #if ASYNCIFY moduleExports = Asyncify.instrumentWasmExports(moduleExports); diff --git a/test/test_other.py b/test/test_other.py index f4162deb73fad..9a157a77697b1 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -7314,6 +7314,60 @@ def test_dlopen_constructors(self): # Repeat the test without NO_AUTOLOAD_DYLIBS self.do_runf('main.c', 'done\n', cflags=['-g', '-sMAIN_MODULE=2', 'libside.wasm']) + def test_dlopen_exported_globals(self): + # A side module's data symbols are exported as immutable globals that must + # be relocated by the module's memory base, while an exported mutable + # global must be passed through as is. + create_file('side.c', r''' + __asm__( + ".section .data.side_global,\"\",@\n" + ".globl side_global\n" + ".globaltype side_global, i32\n" + "side_global:\n" + ); + + int side_data = 42; + int* side_data_addr() { return &side_data; } + + int get_side_global() { + int val; + __asm__ volatile("global.get side_global\n" + "local.set %0\n" : "=r" (val)); + return val; + } + ''') + create_file('main.c', r''' + #include + #include + #include + #include + + int main() { + void* h = dlopen("libside.wasm", RTLD_NOW); + assert(h); + int* side_data = dlsym(h, "side_data"); + int* (*side_data_addr)() = dlsym(h, "side_data_addr"); + int (*get_side_global)() = dlsym(h, "get_side_global"); + assert(side_data && side_data == side_data_addr()); + assert(*side_data == 42); + EM_ASM({ + // The loader read the mutable globals from the binary, rather than + // falling back to probing each one. + var metadata = getDylinkMetadata(new Uint8Array(require('fs').readFileSync('libside.wasm'))); + assert(metadata.mutableGlobals, 'mutableGlobals not parsed'); + assert(metadata.mutableGlobals.size == 1 && metadata.mutableGlobals.has('side_global')); + + var g = LDSO.loadedLibsByHandle[$0].exports['side_global']; + assert(g instanceof WebAssembly.Global); + g.value = 7; + }, h); + assert(get_side_global() == 7); + printf("done\n"); + return 0; + }''') + self.run_process([EMCC, 'side.c', '-sSIDE_MODULE', '-o', 'libside.wasm']) + self.do_runf('main.c', 'done\n', cflags=['-sMAIN_MODULE=2']) + @requires_node def test_dlopen_binary_not_retained(self): # The bytes of a side module should not be kept alive once it has been From ddb5bcafb7cfe1f24df8790741e29a1799c00ba0 Mon Sep 17 00:00:00 2001 From: Rusty Conover Date: Mon, 19 Oct 2026 14:15:34 -0400 Subject: [PATCH 2/6] Drop the memoryBase default so the optional argument comes last Co-Authored-By: Claude Opus 5.5 (1M context) --- src/lib/libdylink.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/libdylink.js b/src/lib/libdylink.js index 02ae9db42adc1..70ac59fe1d360 100644 --- a/src/lib/libdylink.js +++ b/src/lib/libdylink.js @@ -281,7 +281,7 @@ var LibraryDylink = { $relocateExports__internal: true, $relocateExports__deps: ['$isImmutableGlobal'], $relocateExports__docs: '/** @param {Set=} mutableGlobals */', - $relocateExports: (exports, memoryBase = 0, mutableGlobals) => { + $relocateExports: (exports, memoryBase, mutableGlobals) => { #if DYLINK_DEBUG dbg(`relocateExports memoryBase=${memoryBase} count=${Object.keys(exports).length}`); #endif From 1757e773c958770a411a83836fc2230e3935ad7b Mon Sep 17 00:00:00 2001 From: Rusty Conover Date: Sat, 24 Oct 2026 13:41:47 -0400 Subject: [PATCH 3/6] Update codesize expectations after rebasing on main --- test/codesize/test_codesize_hello_dylink.json | 8 ++++---- test/codesize/test_codesize_hello_dylink_all.json | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/codesize/test_codesize_hello_dylink.json b/test/codesize/test_codesize_hello_dylink.json index 15ca5b6de0401..bfa1e7bc269db 100644 --- a/test/codesize/test_codesize_hello_dylink.json +++ b/test/codesize/test_codesize_hello_dylink.json @@ -1,10 +1,10 @@ { - "a.out.js": 26229, - "a.out.js.gz": 11137, + "a.out.js": 27061, + "a.out.js.gz": 11491, "a.out.nodebug.wasm": 16986, "a.out.nodebug.wasm.gz": 8667, - "total": 43215, - "total_gz": 19804, + "total": 44047, + "total_gz": 20158, "sent": [ "__syscall_stat64", "emscripten_resize_heap", diff --git a/test/codesize/test_codesize_hello_dylink_all.json b/test/codesize/test_codesize_hello_dylink_all.json index 4d4e9e1e31f10..4977599c47c1a 100644 --- a/test/codesize/test_codesize_hello_dylink_all.json +++ b/test/codesize/test_codesize_hello_dylink_all.json @@ -1,7 +1,7 @@ { - "a.out.js": 272704, + "a.out.js": 273543, "a.out.nodebug.wasm": 589443, - "total": 862147, + "total": 862986, "sent": [ "IMG_Init", "IMG_Load", From 5bcf0e66c5592b95206c99f54cb640fb4cf395cd Mon Sep 17 00:00:00 2001 From: Rusty Conover Date: Sun, 25 Oct 2026 12:49:51 -0400 Subject: [PATCH 4/6] Skip parsing global mutability at -Oz At SHRINK_LEVEL 2 the loader now leaves out the parser and probes each exported global with isImmutableGlobal, as before, trading load time for code size. -Os keeps the parser. test_dlopen_exported_globals gains an -Oz variant covering the fallback. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/lib/libdylink.js | 12 ++++++++++-- test/test_other.py | 27 ++++++++++++++++++--------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/lib/libdylink.js b/src/lib/libdylink.js index 70ac59fe1d360..08cb02afd3594 100644 --- a/src/lib/libdylink.js +++ b/src/lib/libdylink.js @@ -294,11 +294,15 @@ var LibraryDylink = { } #endif // Detect immutable wasm global exports. These represent data addresses - // which are relative to `memoryBase`. `mutableGlobals`, when known, - // saves probing each global. + // which are relative to `memoryBase`. +#if SHRINK_LEVEL < 2 + // `mutableGlobals`, when known, saves probing each global. var immutable = mutableGlobals ? value instanceof WebAssembly.Global && !mutableGlobals.has(name) : isImmutableGlobal(value); +#else + var immutable = isImmutableGlobal(value); +#endif if (immutable) { return new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}'}, value.value + {{{ to64('memoryBase') }}}); } @@ -481,6 +485,7 @@ var LibraryDylink = { if (condition) throw new Error(message); } +#if SHRINK_LEVEL < 2 // Returns the names of the exported globals that are mutable, read from // the import, global and export sections that follow the dylink section. // This saves relocateExports from probing each exported global with @@ -561,6 +566,7 @@ var LibraryDylink = { } return result; } +#endif // SHRINK_LEVEL < 2 var isModule = binary instanceof WebAssembly.Module; if (isModule) { @@ -649,9 +655,11 @@ var LibraryDylink = { dbg('dylink needed:', customSection.neededDynlibs); #endif +#if SHRINK_LEVEL < 2 if (!isModule) { customSection.mutableGlobals = getMutableGlobals(); } +#endif return customSection; }, diff --git a/test/test_other.py b/test/test_other.py index 9a157a77697b1..935b5c2e824c1 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -7314,7 +7314,12 @@ def test_dlopen_constructors(self): # Repeat the test without NO_AUTOLOAD_DYLIBS self.do_runf('main.c', 'done\n', cflags=['-g', '-sMAIN_MODULE=2', 'libside.wasm']) - def test_dlopen_exported_globals(self): + @parameterized({ + '': ([], True), + # At -Oz the loader skips parsing the binary and probes each global instead. + 'Oz': (['-Oz'], False), + }) + def test_dlopen_exported_globals(self, args, expect_parsed): # A side module's data symbols are exported as immutable globals that must # be relocated by the module's memory base, while an exported mutable # global must be passed through as is. @@ -7351,22 +7356,26 @@ def test_dlopen_exported_globals(self): assert(side_data && side_data == side_data_addr()); assert(*side_data == 42); EM_ASM({ - // The loader read the mutable globals from the binary, rather than - // falling back to probing each one. + // Unless optimizing for size, the loader read the mutable globals + // from the binary, rather than falling back to probing each one. var metadata = getDylinkMetadata(new Uint8Array(require('fs').readFileSync('libside.wasm'))); - assert(metadata.mutableGlobals, 'mutableGlobals not parsed'); - assert(metadata.mutableGlobals.size == 1 && metadata.mutableGlobals.has('side_global')); + if ($1) { + if (!metadata.mutableGlobals) throw new Error('mutableGlobals not parsed'); + if (metadata.mutableGlobals.size != 1 || !metadata.mutableGlobals.has('side_global')) throw new Error('wrong mutableGlobals'); + } else if (metadata.mutableGlobals) { + throw new Error('mutableGlobals unexpectedly parsed'); + } var g = LDSO.loadedLibsByHandle[$0].exports['side_global']; - assert(g instanceof WebAssembly.Global); + if (!(g instanceof WebAssembly.Global)) throw new Error('side_global is not a Global'); g.value = 7; - }, h); + }, h, EXPECT_PARSED); assert(get_side_global() == 7); printf("done\n"); return 0; }''') - self.run_process([EMCC, 'side.c', '-sSIDE_MODULE', '-o', 'libside.wasm']) - self.do_runf('main.c', 'done\n', cflags=['-sMAIN_MODULE=2']) + self.run_process([EMCC, 'side.c', '-sSIDE_MODULE', '-o', 'libside.wasm'] + args) + self.do_runf('main.c', 'done\n', cflags=['-sMAIN_MODULE=2', f'-DEXPECT_PARSED={int(expect_parsed)}'] + args) @requires_node def test_dlopen_binary_not_retained(self): From 8f3bc6d82f992445219b25cbe6f9db6255962cef Mon Sep 17 00:00:00 2001 From: Rusty Conover Date: Mon, 26 Oct 2026 13:09:11 -0400 Subject: [PATCH 5/6] Track immutable rather than mutable exported globals As suggested in review, this lets relocateExports check membership directly instead of also testing for WebAssembly.Global. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/lib/libdylink.js | 20 +++++++++---------- test/codesize/test_codesize_hello_dylink.json | 8 ++++---- .../test_codesize_hello_dylink_all.json | 4 ++-- test/test_other.py | 11 +++++----- 4 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/lib/libdylink.js b/src/lib/libdylink.js index 08cb02afd3594..a0d3002ddfaad 100644 --- a/src/lib/libdylink.js +++ b/src/lib/libdylink.js @@ -280,8 +280,8 @@ var LibraryDylink = { // Applies relocations to exported things. $relocateExports__internal: true, $relocateExports__deps: ['$isImmutableGlobal'], - $relocateExports__docs: '/** @param {Set=} mutableGlobals */', - $relocateExports: (exports, memoryBase, mutableGlobals) => { + $relocateExports__docs: '/** @param {Set=} immutableGlobals */', + $relocateExports: (exports, memoryBase, immutableGlobals) => { #if DYLINK_DEBUG dbg(`relocateExports memoryBase=${memoryBase} count=${Object.keys(exports).length}`); #endif @@ -296,9 +296,9 @@ var LibraryDylink = { // Detect immutable wasm global exports. These represent data addresses // which are relative to `memoryBase`. #if SHRINK_LEVEL < 2 - // `mutableGlobals`, when known, saves probing each global. - var immutable = mutableGlobals - ? value instanceof WebAssembly.Global && !mutableGlobals.has(name) + // `immutableGlobals`, when known, saves probing each global. + var immutable = immutableGlobals + ? immutableGlobals.has(name) : isImmutableGlobal(value); #else var immutable = isImmutableGlobal(value); @@ -486,12 +486,12 @@ var LibraryDylink = { } #if SHRINK_LEVEL < 2 - // Returns the names of the exported globals that are mutable, read from + // Returns the names of the exported globals that are immutable, read from // the import, global and export sections that follow the dylink section. // This saves relocateExports from probing each exported global with // isImmutableGlobal, which throws for every immutable one. Returns // undefined if it finds something it doesn't handle. - function getMutableGlobals() { + function getImmutableGlobals() { // The mutability of each global, imported globals first. var mutable = []; var result = new Set(); @@ -550,7 +550,7 @@ var LibraryDylink = { skipString(); var kind = getU8(); var index = getLEB(); - if (kind === 3 && mutable[index]) { + if (kind === 3 && mutable[index] === 0) { var saved = offset; offset = nameStart; result.add(getString()); @@ -657,7 +657,7 @@ var LibraryDylink = { #if SHRINK_LEVEL < 2 if (!isModule) { - customSection.mutableGlobals = getMutableGlobals(); + customSection.immutableGlobals = getImmutableGlobals(); } #endif return customSection; @@ -983,7 +983,7 @@ var LibraryDylink = { #endif // add new entries to functionsInTableMap updateTableMap(tableBase, metadata.tableSize); - moduleExports = relocateExports(instance.exports, memoryBase, metadata.mutableGlobals); + moduleExports = relocateExports(instance.exports, memoryBase, metadata.immutableGlobals); updateGOT(moduleExports); #if ASYNCIFY moduleExports = Asyncify.instrumentWasmExports(moduleExports); diff --git a/test/codesize/test_codesize_hello_dylink.json b/test/codesize/test_codesize_hello_dylink.json index bfa1e7bc269db..fe310cd65beb8 100644 --- a/test/codesize/test_codesize_hello_dylink.json +++ b/test/codesize/test_codesize_hello_dylink.json @@ -1,10 +1,10 @@ { - "a.out.js": 27061, - "a.out.js.gz": 11491, + "a.out.js": 27031, + "a.out.js.gz": 11489, "a.out.nodebug.wasm": 16986, "a.out.nodebug.wasm.gz": 8667, - "total": 44047, - "total_gz": 20158, + "total": 44017, + "total_gz": 20156, "sent": [ "__syscall_stat64", "emscripten_resize_heap", diff --git a/test/codesize/test_codesize_hello_dylink_all.json b/test/codesize/test_codesize_hello_dylink_all.json index 4977599c47c1a..deb1083213923 100644 --- a/test/codesize/test_codesize_hello_dylink_all.json +++ b/test/codesize/test_codesize_hello_dylink_all.json @@ -1,7 +1,7 @@ { - "a.out.js": 273543, + "a.out.js": 273513, "a.out.nodebug.wasm": 589443, - "total": 862986, + "total": 862956, "sent": [ "IMG_Init", "IMG_Load", diff --git a/test/test_other.py b/test/test_other.py index 935b5c2e824c1..2f8834d3ef278 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -7356,14 +7356,15 @@ def test_dlopen_exported_globals(self, args, expect_parsed): assert(side_data && side_data == side_data_addr()); assert(*side_data == 42); EM_ASM({ - // Unless optimizing for size, the loader read the mutable globals + // Unless optimizing for size, the loader read the immutable globals // from the binary, rather than falling back to probing each one. var metadata = getDylinkMetadata(new Uint8Array(require('fs').readFileSync('libside.wasm'))); if ($1) { - if (!metadata.mutableGlobals) throw new Error('mutableGlobals not parsed'); - if (metadata.mutableGlobals.size != 1 || !metadata.mutableGlobals.has('side_global')) throw new Error('wrong mutableGlobals'); - } else if (metadata.mutableGlobals) { - throw new Error('mutableGlobals unexpectedly parsed'); + var immutableGlobals = metadata.immutableGlobals; + if (!immutableGlobals) throw new Error('immutableGlobals not parsed'); + if (!immutableGlobals.has('side_data') || immutableGlobals.has('side_global')) throw new Error('wrong immutableGlobals'); + } else if (metadata.immutableGlobals) { + throw new Error('immutableGlobals unexpectedly parsed'); } var g = LDSO.loadedLibsByHandle[$0].exports['side_global']; From 93d7551b75214a7012116f440e39e52f7ee71a65 Mon Sep 17 00:00:00 2001 From: Rusty Conover Date: Mon, 26 Oct 2026 20:38:24 -0400 Subject: [PATCH 6/6] Parse immutable globals in the non-Module branch As suggested in review, this drops the isModule variable. Co-Authored-By: Claude Opus 5.5 (1M context) --- src/lib/libdylink.js | 13 ++++++++----- test/codesize/test_codesize_hello_dylink.json | 8 ++++---- test/codesize/test_codesize_hello_dylink_all.json | 4 ++-- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/lib/libdylink.js b/src/lib/libdylink.js index a0d3002ddfaad..90b6f93d91504 100644 --- a/src/lib/libdylink.js +++ b/src/lib/libdylink.js @@ -568,8 +568,7 @@ var LibraryDylink = { } #endif // SHRINK_LEVEL < 2 - var isModule = binary instanceof WebAssembly.Module; - if (isModule) { + if (binary instanceof WebAssembly.Module) { var dylinkSection = WebAssembly.Module.customSections(binary, 'dylink.0'); failIf(!dylinkSection.length, 'need dylink section'); binary = new Uint8Array(dylinkSection[0]); @@ -589,6 +588,12 @@ var LibraryDylink = { end = offset + section_size; var name = getString(); failIf(name !== 'dylink.0'); +#if SHRINK_LEVEL < 2 + var dylinkStart = offset; + offset = end; + var immutableGlobals = getImmutableGlobals(); + offset = dylinkStart; +#endif } var customSection = { neededDynlibs: [], tlsExports: new Set(), weakImports: new Set(), runtimePaths: [] }; @@ -656,9 +661,7 @@ var LibraryDylink = { #endif #if SHRINK_LEVEL < 2 - if (!isModule) { - customSection.immutableGlobals = getImmutableGlobals(); - } + customSection.immutableGlobals = immutableGlobals; #endif return customSection; }, diff --git a/test/codesize/test_codesize_hello_dylink.json b/test/codesize/test_codesize_hello_dylink.json index fe310cd65beb8..1f56983db4636 100644 --- a/test/codesize/test_codesize_hello_dylink.json +++ b/test/codesize/test_codesize_hello_dylink.json @@ -1,10 +1,10 @@ { - "a.out.js": 27031, - "a.out.js.gz": 11489, + "a.out.js": 27042, + "a.out.js.gz": 11502, "a.out.nodebug.wasm": 16986, "a.out.nodebug.wasm.gz": 8667, - "total": 44017, - "total_gz": 20156, + "total": 44028, + "total_gz": 20169, "sent": [ "__syscall_stat64", "emscripten_resize_heap", diff --git a/test/codesize/test_codesize_hello_dylink_all.json b/test/codesize/test_codesize_hello_dylink_all.json index deb1083213923..538bb803842e7 100644 --- a/test/codesize/test_codesize_hello_dylink_all.json +++ b/test/codesize/test_codesize_hello_dylink_all.json @@ -1,7 +1,7 @@ { - "a.out.js": 273513, + "a.out.js": 273524, "a.out.nodebug.wasm": 589443, - "total": 862956, + "total": 862967, "sent": [ "IMG_Init", "IMG_Load",