From a8874fae4711d8fe37d6737ed7a36506a5efb8c2 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 9 May 2025 12:15:48 +0100 Subject: [PATCH 1/9] Add failing test for i64 + SAFE_HEAP --- test/test_core.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/test_core.py b/test/test_core.py index fb1ed5663e2df..e57921d8d3f8e 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -7493,9 +7493,14 @@ def test_embind_dynamic_initialization(self): self.do_run_in_out_file_test('embind/test_dynamic_initialization.cpp') @no_wasm2js('wasm_bigint') - def test_embind_i64_val(self): + @parameterized({ + '': ([],), + 'safe_heap': (['-sSAFE_HEAP'],), + }) + def test_embind_i64_val(self, extra_args): self.set_setting('WASM_BIGINT') self.emcc_args += ['-lembind'] + self.emcc_args += extra_args self.node_args += shared.node_bigint_flags(self.get_nodejs()) self.do_run_in_out_file_test('embind/test_i64_val.cpp', assert_identical=True) From 946bfd1e74200d4544eda69fb1f059a43a8e82fb Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 9 May 2025 12:18:17 +0100 Subject: [PATCH 2/9] Simplify `SAFE_HEAP` implementation This streamlines the `SAFE_HEAP` transform in acorn-optimizer. I was going to send this as a separate cleanup PR as part of my other work on acorn-optimizer, but it happens to also be the easy fix for a regression mentioned in https://github.com/emscripten-core/emscripten/pull/24289 and caused by https://github.com/emscripten-core/emscripten/pull/24283 which added support for 64-bit integers to acorn-optimizer passes. I could fix that issue separately by tweaking `unSign`, but this way we don't need to bother - the values with correct sign are now automatically retrieved by accessing the correct `HEAP*` array. I've added a regression test for the linked issue as well, which fails before this PR and passes after. --- src/runtime_safe_heap.js | 76 ++-------- test/js_optimizer/safeHeap-output.js | 50 +++---- .../codesize/test_codesize_cxx_wasmfs.size | 2 +- .../codesize/test_codesize_files_wasmfs.size | 2 +- .../test_codesize_hello_single_file.gzsize | 2 +- .../test_codesize_hello_single_file.jssize | 2 +- tools/acorn-optimizer.mjs | 131 +----------------- 7 files changed, 46 insertions(+), 219 deletions(-) diff --git a/src/runtime_safe_heap.js b/src/runtime_safe_heap.js index ca0c0cc42b717..71e834cfe11a4 100644 --- a/src/runtime_safe_heap.js +++ b/src/runtime_safe_heap.js @@ -8,91 +8,39 @@ #error "should only be inclded in SAFE_HEAP mode" #endif -/** @param {number|boolean=} isFloat */ -function getSafeHeapType(bytes, isFloat) { - switch (bytes) { - case 1: return 'i8'; - case 2: return 'i16'; - case 4: return isFloat ? 'float' : 'i32'; - case 8: return isFloat ? 'double' : 'i64'; - default: abort(`getSafeHeapType() invalid bytes=${bytes}`); - } -} - #if SAFE_HEAP_LOG var SAFE_HEAP_COUNTER = 0; #endif -/** @param {number|boolean=} isFloat */ -function SAFE_HEAP_STORE(dest, value, bytes, isFloat) { +function SAFE_HEAP_INDEX(arr, idx, log) { #if CAN_ADDRESS_2GB - dest >>>= 0; + idx >>>= 0; #endif + const bytes = arr.BYTES_PER_ELEMENT; + const dest = idx * bytes; #if SAFE_HEAP_LOG - dbg('SAFE_HEAP store: ' + [dest, value, bytes, isFloat, SAFE_HEAP_COUNTER++]); -#endif - if (dest <= 0) abort(`segmentation fault storing ${bytes} bytes to address ${dest}`); -#if SAFE_HEAP == 1 - if (dest % bytes !== 0) abort(`alignment error storing to address ${dest}, which was expected to be aligned to a multiple of ${bytes}`); -#else - if (dest % bytes !== 0) warnOnce(`alignment error in a memory store operation, alignment was a multiple of ${(((dest ^ (dest-1)) >> 1) + 1)}, but was was expected to be aligned to a multiple of ${bytes}`); + dbg(`SAFE_HEAP ${log}: ${[arr.constructor.name, idx, SAFE_HEAP_COUNTER++]}`); #endif + if (idx <= 0) abort(`segmentation fault ${log} ${bytes} bytes from address ${dest}`); #if EXIT_RUNTIME if (runtimeInitialized && !runtimeExited) { #else if (runtimeInitialized) { #endif var brk = _sbrk(0); - if (dest + bytes > brk) abort(`segmentation fault, exceeded the top of the available dynamic heap when storing ${bytes} bytes to address ${dest}. DYNAMICTOP=${brk}`); + if (dest + bytes > brk) abort(`segmentation fault, exceeded the top of the available dynamic heap when ${log} ${bytes} bytes from address ${dest}. DYNAMICTOP=${brk}`); if (brk < _emscripten_stack_get_base()) abort(`brk >= _emscripten_stack_get_base() (brk=${brk}, _emscripten_stack_get_base()=${_emscripten_stack_get_base()})`); // sbrk-managed memory must be above the stack if (brk > wasmMemory.buffer.byteLength) abort(`brk <= wasmMemory.buffer.byteLength (brk=${brk}, wasmMemory.buffer.byteLength=${wasmMemory.buffer.byteLength})`); } - setValue_safe(dest, value, getSafeHeapType(bytes, isFloat)); - return value; -} -function SAFE_HEAP_STORE_D(dest, value, bytes) { - return SAFE_HEAP_STORE(dest, value, bytes, true); + return idx; } -/** @param {number|boolean=} isFloat */ -function SAFE_HEAP_LOAD(dest, bytes, unsigned, isFloat) { -#if CAN_ADDRESS_2GB - dest >>>= 0; -#endif - if (dest <= 0) abort(`segmentation fault loading ${bytes} bytes from address ${dest}`); -#if SAFE_HEAP == 1 - if (dest % bytes !== 0) abort(`alignment error loading from address ${dest}, which was expected to be aligned to a multiple of ${bytes}`); -#else - if (dest % bytes !== 0) warnOnce(`alignment error in a memory load operation, alignment was a multiple of ${(((dest ^ (dest-1)) >> 1) + 1)}, but was was expected to be aligned to a multiple of ${bytes}`); -#endif -#if EXIT_RUNTIME - if (runtimeInitialized && !runtimeExited) { -#else - if (runtimeInitialized) { -#endif - var brk = _sbrk(0); - if (dest + bytes > brk) abort(`segmentation fault, exceeded the top of the available dynamic heap when loading ${bytes} bytes from address ${dest}. DYNAMICTOP=${brk}`); - if (brk < _emscripten_stack_get_base()) abort(`brk >= _emscripten_stack_get_base() (brk=${brk}, _emscripten_stack_get_base()=${_emscripten_stack_get_base()})`); // sbrk-managed memory must be above the stack - if (brk > wasmMemory.buffer.byteLength) abort(`brk <= wasmMemory.buffer.byteLength (brk=${brk}, wasmMemory.buffer.byteLength=${wasmMemory.buffer.byteLength})`); - } - var type = getSafeHeapType(bytes, isFloat); - var ret = getValue_safe(dest, type); - if (unsigned) ret = unSign(ret, parseInt(type.slice(1), 10)); -#if SAFE_HEAP_LOG - dbg('SAFE_HEAP load: ' + [dest, ret, bytes, isFloat, unsigned, SAFE_HEAP_COUNTER++]); -#endif - return ret; -} -function SAFE_HEAP_LOAD_D(dest, bytes, unsigned) { - return SAFE_HEAP_LOAD(dest, bytes, unsigned, true); +function SAFE_HEAP_LOAD(arr, idx) { + return arr[SAFE_HEAP_INDEX(arr, idx, 'loading')]; } -function SAFE_FT_MASK(value, mask) { - var ret = value & mask; - if (ret !== value) { - abort(`Function table mask error: function pointer is ${value} which is masked by ${mask}, the likely cause of this is that the function pointer is being called by the wrong type.`); - } - return ret; +function SAFE_HEAP_STORE(arr, idx, value) { + return arr[SAFE_HEAP_INDEX(arr, idx, 'storing')] = value; } function segfault() { diff --git a/test/js_optimizer/safeHeap-output.js b/test/js_optimizer/safeHeap-output.js index cc7bfddca7e77..b3804c6cd676f 100644 --- a/test/js_optimizer/safeHeap-output.js +++ b/test/js_optimizer/safeHeap-output.js @@ -1,48 +1,48 @@ -SAFE_HEAP_STORE(x, 1, 1); +SAFE_HEAP_STORE(HEAP8, x, 1); -SAFE_HEAP_STORE(x * 2, 2, 2); +SAFE_HEAP_STORE(HEAP16, x, 2); -SAFE_HEAP_STORE(x * 4, 3, 4); +SAFE_HEAP_STORE(HEAP32, x, 3); -SAFE_HEAP_STORE(x, 4, 1); +SAFE_HEAP_STORE(HEAPU8, x, 4); -SAFE_HEAP_STORE(x * 2, 5, 2); +SAFE_HEAP_STORE(HEAPU16, x, 5); -SAFE_HEAP_STORE(x * 4, 6, 4); +SAFE_HEAP_STORE(HEAPU32, x, 6); -SAFE_HEAP_STORE_D(x * 4, 7, 4); +SAFE_HEAP_STORE(HEAPF32, x, 7); -SAFE_HEAP_STORE_D(x * 8, 8, 8); +SAFE_HEAP_STORE(HEAPF64, x, 8); -SAFE_HEAP_STORE(x * 8, 9n, 8); +SAFE_HEAP_STORE(HEAP64, x, 9n); -SAFE_HEAP_STORE(x * 8, 10n, 8); +SAFE_HEAP_STORE(HEAPU64, x, 10n); -a1 = SAFE_HEAP_LOAD(x, 1, 0); +a1 = SAFE_HEAP_LOAD(HEAP8, x); -a2 = SAFE_HEAP_LOAD(x * 2, 2, 0); +a2 = SAFE_HEAP_LOAD(HEAP16, x); -a3 = SAFE_HEAP_LOAD(x * 4, 4, 0); +a3 = SAFE_HEAP_LOAD(HEAP32, x); -a4 = SAFE_HEAP_LOAD(x, 1, 1); +a4 = SAFE_HEAP_LOAD(HEAPU8, x); -a5 = SAFE_HEAP_LOAD(x * 2, 2, 1); +a5 = SAFE_HEAP_LOAD(HEAPU16, x); -a6 = SAFE_HEAP_LOAD(x * 4, 4, 1); +a6 = SAFE_HEAP_LOAD(HEAPU32, x); -a7 = SAFE_HEAP_LOAD_D(x * 4, 4, 0); +a7 = SAFE_HEAP_LOAD(HEAPF32, x); -a8 = SAFE_HEAP_LOAD_D(x * 8, 8, 0); +a8 = SAFE_HEAP_LOAD(HEAPF64, x); -a9 = SAFE_HEAP_LOAD(x * 8, 8, 0); +a9 = SAFE_HEAP_LOAD(HEAP64, x); -a10 = SAFE_HEAP_LOAD(x * 8, 8, 1); +a10 = SAFE_HEAP_LOAD(HEAPU64, x); -foo = SAFE_HEAP_STORE(1337, 42, 1); +foo = SAFE_HEAP_STORE(HEAPU8, 1337, 42); -SAFE_HEAP_LOAD(bar(SAFE_HEAP_LOAD_D(5 * 8, 8, 0)) * 2, 2, 0); +SAFE_HEAP_LOAD(HEAP16, bar(SAFE_HEAP_LOAD(HEAPF64, 5))); -SAFE_HEAP_STORE_D(x * 4, SAFE_HEAP_LOAD(y * 4, 4, 0), 4); +SAFE_HEAP_STORE(HEAPF32, x, SAFE_HEAP_LOAD(HEAP32, y)); function SAFE_HEAP_FOO(ptr) { return HEAP8[ptr]; @@ -57,9 +57,9 @@ function getValue_safe(ptr) { } function somethingElse() { - return SAFE_HEAP_LOAD(ptr, 1, 0); + return SAFE_HEAP_LOAD(HEAP8, ptr); } HEAP8.length; -SAFE_HEAP_LOAD(length, 1, 0); +SAFE_HEAP_LOAD(HEAP8, length); diff --git a/test/other/codesize/test_codesize_cxx_wasmfs.size b/test/other/codesize/test_codesize_cxx_wasmfs.size index f3d63f8c6ab2f..de4b1df11dcc2 100644 --- a/test/other/codesize/test_codesize_cxx_wasmfs.size +++ b/test/other/codesize/test_codesize_cxx_wasmfs.size @@ -1 +1 @@ -169161 +169140 diff --git a/test/other/codesize/test_codesize_files_wasmfs.size b/test/other/codesize/test_codesize_files_wasmfs.size index dda8ecfb72a4d..de78f8fa0b341 100644 --- a/test/other/codesize/test_codesize_files_wasmfs.size +++ b/test/other/codesize/test_codesize_files_wasmfs.size @@ -1 +1 @@ -49985 +49964 diff --git a/test/other/codesize/test_codesize_hello_single_file.gzsize b/test/other/codesize/test_codesize_hello_single_file.gzsize index 61b86d0fa055c..400464624a41d 100644 --- a/test/other/codesize/test_codesize_hello_single_file.gzsize +++ b/test/other/codesize/test_codesize_hello_single_file.gzsize @@ -1 +1 @@ -3626 +3634 diff --git a/test/other/codesize/test_codesize_hello_single_file.jssize b/test/other/codesize/test_codesize_hello_single_file.jssize index d99a176aab4c8..583ea7dea61eb 100644 --- a/test/other/codesize/test_codesize_hello_single_file.jssize +++ b/test/other/codesize/test_codesize_hello_single_file.jssize @@ -1 +1 @@ -6690 +6702 diff --git a/tools/acorn-optimizer.mjs b/tools/acorn-optimizer.mjs index 379412e20349f..c3a1d197c616e 100755 --- a/tools/acorn-optimizer.mjs +++ b/tools/acorn-optimizer.mjs @@ -1606,57 +1606,7 @@ function safeHeap(ast) { c(value); if (isHEAPAccess(target)) { // Instrument a store. - const ptr = target.property; - switch (target.object.name) { - case 'HEAP8': - case 'HEAPU8': { - makeCallExpression(node, 'SAFE_HEAP_STORE', [ptr, value, createLiteral(1)]); - break; - } - case 'HEAP16': - case 'HEAPU16': { - makeCallExpression(node, 'SAFE_HEAP_STORE', [ - multiply(ptr, 2), - value, - createLiteral(2), - ]); - break; - } - case 'HEAP32': - case 'HEAPU32': { - makeCallExpression(node, 'SAFE_HEAP_STORE', [ - multiply(ptr, 4), - value, - createLiteral(4), - ]); - break; - } - case 'HEAP64': - case 'HEAPU64': { - makeCallExpression(node, 'SAFE_HEAP_STORE', [ - multiply(ptr, 8), - value, - createLiteral(8), - ]); - break; - } - case 'HEAPF32': { - makeCallExpression(node, 'SAFE_HEAP_STORE_D', [ - multiply(ptr, 4), - value, - createLiteral(4), - ]); - break; - } - case 'HEAPF64': { - makeCallExpression(node, 'SAFE_HEAP_STORE_D', [ - multiply(ptr, 8), - value, - createLiteral(8), - ]); - break; - } - } + makeCallExpression(node, 'SAFE_HEAP_STORE', [target.object, target.property, value]); } else { c(target); } @@ -1667,81 +1617,10 @@ function safeHeap(ast) { c(node.object); } else { // Instrument a load. - const ptr = node.property; - switch (node.object.name) { - case 'HEAP8': { - makeCallExpression(node, 'SAFE_HEAP_LOAD', [ptr, createLiteral(1), createLiteral(0)]); - break; - } - case 'HEAPU8': { - makeCallExpression(node, 'SAFE_HEAP_LOAD', [ptr, createLiteral(1), createLiteral(1)]); - break; - } - case 'HEAP16': { - makeCallExpression(node, 'SAFE_HEAP_LOAD', [ - multiply(ptr, 2), - createLiteral(2), - createLiteral(0), - ]); - break; - } - case 'HEAPU16': { - makeCallExpression(node, 'SAFE_HEAP_LOAD', [ - multiply(ptr, 2), - createLiteral(2), - createLiteral(1), - ]); - break; - } - case 'HEAP32': { - makeCallExpression(node, 'SAFE_HEAP_LOAD', [ - multiply(ptr, 4), - createLiteral(4), - createLiteral(0), - ]); - break; - } - case 'HEAPU32': { - makeCallExpression(node, 'SAFE_HEAP_LOAD', [ - multiply(ptr, 4), - createLiteral(4), - createLiteral(1), - ]); - break; - } - case 'HEAP64': { - makeCallExpression(node, 'SAFE_HEAP_LOAD', [ - multiply(ptr, 8), - createLiteral(8), - createLiteral(0), - ]); - break; - } - case 'HEAPU64': { - makeCallExpression(node, 'SAFE_HEAP_LOAD', [ - multiply(ptr, 8), - createLiteral(8), - createLiteral(1), - ]); - break; - } - case 'HEAPF32': { - makeCallExpression(node, 'SAFE_HEAP_LOAD_D', [ - multiply(ptr, 4), - createLiteral(4), - createLiteral(0), - ]); - break; - } - case 'HEAPF64': { - makeCallExpression(node, 'SAFE_HEAP_LOAD_D', [ - multiply(ptr, 8), - createLiteral(8), - createLiteral(0), - ]); - break; - } - } + makeCallExpression(node, 'SAFE_HEAP_LOAD', [ + node.object, + node.property + ]); } }, }); From ba4146b195788bbc1e638d67757295c361cf771a Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 9 May 2025 21:55:47 +0100 Subject: [PATCH 3/9] Rebaseline --- test/other/codesize/test_codesize_cxx_wasmfs.size | 2 +- test/other/codesize/test_codesize_files_wasmfs.size | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/other/codesize/test_codesize_cxx_wasmfs.size b/test/other/codesize/test_codesize_cxx_wasmfs.size index de4b1df11dcc2..f3d63f8c6ab2f 100644 --- a/test/other/codesize/test_codesize_cxx_wasmfs.size +++ b/test/other/codesize/test_codesize_cxx_wasmfs.size @@ -1 +1 @@ -169140 +169161 diff --git a/test/other/codesize/test_codesize_files_wasmfs.size b/test/other/codesize/test_codesize_files_wasmfs.size index de78f8fa0b341..dda8ecfb72a4d 100644 --- a/test/other/codesize/test_codesize_files_wasmfs.size +++ b/test/other/codesize/test_codesize_files_wasmfs.size @@ -1 +1 @@ -49964 +49985 From 34b458ee30eed472583d95d6ae8c2eef3bc954a8 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 9 May 2025 22:00:46 +0100 Subject: [PATCH 4/9] Fixups --- src/runtime_safe_heap.js | 8 ++++---- test/test_core.py | 7 +++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/runtime_safe_heap.js b/src/runtime_safe_heap.js index 71e834cfe11a4..6f73e666d1188 100644 --- a/src/runtime_safe_heap.js +++ b/src/runtime_safe_heap.js @@ -12,23 +12,23 @@ var SAFE_HEAP_COUNTER = 0; #endif -function SAFE_HEAP_INDEX(arr, idx, log) { +function SAFE_HEAP_INDEX(arr, idx, action) { #if CAN_ADDRESS_2GB idx >>>= 0; #endif const bytes = arr.BYTES_PER_ELEMENT; const dest = idx * bytes; #if SAFE_HEAP_LOG - dbg(`SAFE_HEAP ${log}: ${[arr.constructor.name, idx, SAFE_HEAP_COUNTER++]}`); + dbg(`SAFE_HEAP ${action}: ${[arr.constructor.name, idx, SAFE_HEAP_COUNTER++]}`); #endif - if (idx <= 0) abort(`segmentation fault ${log} ${bytes} bytes from address ${dest}`); + if (idx <= 0) abort(`segmentation fault ${action} ${bytes} bytes at address ${dest}`); #if EXIT_RUNTIME if (runtimeInitialized && !runtimeExited) { #else if (runtimeInitialized) { #endif var brk = _sbrk(0); - if (dest + bytes > brk) abort(`segmentation fault, exceeded the top of the available dynamic heap when ${log} ${bytes} bytes from address ${dest}. DYNAMICTOP=${brk}`); + if (dest + bytes > brk) abort(`segmentation fault, exceeded the top of the available dynamic heap when ${action} ${bytes} bytes at address ${dest}. DYNAMICTOP=${brk}`); if (brk < _emscripten_stack_get_base()) abort(`brk >= _emscripten_stack_get_base() (brk=${brk}, _emscripten_stack_get_base()=${_emscripten_stack_get_base()})`); // sbrk-managed memory must be above the stack if (brk > wasmMemory.buffer.byteLength) abort(`brk <= wasmMemory.buffer.byteLength (brk=${brk}, wasmMemory.buffer.byteLength=${wasmMemory.buffer.byteLength})`); } diff --git a/test/test_core.py b/test/test_core.py index e57921d8d3f8e..f4995076ae7dc 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -7497,10 +7497,9 @@ def test_embind_dynamic_initialization(self): '': ([],), 'safe_heap': (['-sSAFE_HEAP'],), }) - def test_embind_i64_val(self, extra_args): + def test_embind_i64_val(self, args): self.set_setting('WASM_BIGINT') - self.emcc_args += ['-lembind'] - self.emcc_args += extra_args + self.emcc_args += ['-lembind'] + args self.node_args += shared.node_bigint_flags(self.get_nodejs()) self.do_run_in_out_file_test('embind/test_i64_val.cpp', assert_identical=True) @@ -8970,7 +8969,7 @@ def test_asan_modularized_with_closure(self): def test_safe_heap_user_js(self): self.set_setting('SAFE_HEAP') self.do_runf('core/test_safe_heap_user_js.c', - expected_output=['Aborted(segmentation fault storing 1 bytes to address 0)'], assert_returncode=NON_ZERO) + expected_output=['Aborted(segmentation fault storing 1 bytes at address 0)'], assert_returncode=NON_ZERO) def test_safe_stack(self): self.set_setting('STACK_OVERFLOW_CHECK', 2) From d3f196ea785af39e5fe3e94be944f96b1ec516f1 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 9 May 2025 22:05:07 +0100 Subject: [PATCH 5/9] Format --- tools/acorn-optimizer.mjs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tools/acorn-optimizer.mjs b/tools/acorn-optimizer.mjs index c3a1d197c616e..54d14e12a2529 100755 --- a/tools/acorn-optimizer.mjs +++ b/tools/acorn-optimizer.mjs @@ -1617,10 +1617,7 @@ function safeHeap(ast) { c(node.object); } else { // Instrument a load. - makeCallExpression(node, 'SAFE_HEAP_LOAD', [ - node.object, - node.property - ]); + makeCallExpression(node, 'SAFE_HEAP_LOAD', [node.object, node.property]); } }, }); From eba471f2e32c7039dc5beda60fd36a9ac272b0ba Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 9 May 2025 23:02:33 +0100 Subject: [PATCH 6/9] Also remove obsolete (get|set)Value_safe helpers --- src/lib/libgetvalue.js | 13 ------------- test/js_optimizer/safeHeap-output.js | 8 -------- test/js_optimizer/safeHeap.js | 6 ------ tools/acorn-optimizer.mjs | 7 +------ tools/link.py | 3 --- 5 files changed, 1 insertion(+), 36 deletions(-) diff --git a/src/lib/libgetvalue.js b/src/lib/libgetvalue.js index 061b797c83a2d..9a35b2cb1f6c6 100644 --- a/src/lib/libgetvalue.js +++ b/src/lib/libgetvalue.js @@ -59,19 +59,6 @@ var LibraryMemOps = { * @param {string} type */`, $getValue: getValueImpl, - -#if SAFE_HEAP - // The same as the above two functions, but known to the safeHeap pass - // in tools/acorn-optimizer.mjs. The heap accesses within these two - // functions will *not* get re-written. - // Note that we do not use the alias mechanism here since we need separate - // instances of above setValueImpl/getValueImpl functions. - $setValue_safe__internal: true, - $setValue_safe: setValueImpl, - - $getValue_safe__internal: true, - $getValue_safe: getValueImpl, -#endif }; addToLibrary(LibraryMemOps); diff --git a/test/js_optimizer/safeHeap-output.js b/test/js_optimizer/safeHeap-output.js index b3804c6cd676f..07745ce63e0e8 100644 --- a/test/js_optimizer/safeHeap-output.js +++ b/test/js_optimizer/safeHeap-output.js @@ -48,14 +48,6 @@ function SAFE_HEAP_FOO(ptr) { return HEAP8[ptr]; } -function setValue_safe(ptr) { - return HEAP8[ptr]; -} - -function getValue_safe(ptr) { - return HEAP8[ptr]; -} - function somethingElse() { return SAFE_HEAP_LOAD(HEAP8, ptr); } diff --git a/test/js_optimizer/safeHeap.js b/test/js_optimizer/safeHeap.js index 0f6a88b108b06..848f928dddc49 100644 --- a/test/js_optimizer/safeHeap.js +++ b/test/js_optimizer/safeHeap.js @@ -40,12 +40,6 @@ HEAPF32[x] = HEAP32[y]; function SAFE_HEAP_FOO(ptr) { return HEAP8[ptr]; } -function setValue_safe(ptr) { - return HEAP8[ptr]; -} -function getValue_safe(ptr) { - return HEAP8[ptr]; -} // but do handle everything else function somethingElse() { diff --git a/tools/acorn-optimizer.mjs b/tools/acorn-optimizer.mjs index 54d14e12a2529..317e6682c1c60 100755 --- a/tools/acorn-optimizer.mjs +++ b/tools/acorn-optimizer.mjs @@ -1588,12 +1588,7 @@ function multiply(value, by) { function safeHeap(ast) { recursiveWalk(ast, { FunctionDeclaration(node, c) { - if ( - node.id.type === 'Identifier' && - (node.id.name.startsWith('SAFE_HEAP') || - node.id.name === 'setValue_safe' || - node.id.name === 'getValue_safe') - ) { + if (node.id.type === 'Identifier' && node.id.name.startsWith('SAFE_HEAP')) { // do not recurse into this js impl function, which we use during // startup before the wasm is ready } else { diff --git a/tools/link.py b/tools/link.py index 60874b5aa4041..407f2343719e4 100644 --- a/tools/link.py +++ b/tools/link.py @@ -1050,9 +1050,6 @@ def limit_incoming_module_api(): settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$ExitStatus'] - if not settings.BOOTSTRAPPING_STRUCT_INFO and settings.SAFE_HEAP: - settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$getValue_safe', '$setValue_safe'] - if settings.ABORT_ON_WASM_EXCEPTIONS or settings.SPLIT_MODULE: settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$wasmTable'] From 2a0b10c64ac4d7200c0a68598618828a37b6a16d Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 9 May 2025 23:04:07 +0100 Subject: [PATCH 7/9] Reset codesize files --- test/other/codesize/test_codesize_hello_single_file.gzsize | 2 +- test/other/codesize/test_codesize_hello_single_file.jssize | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/other/codesize/test_codesize_hello_single_file.gzsize b/test/other/codesize/test_codesize_hello_single_file.gzsize index 400464624a41d..61b86d0fa055c 100644 --- a/test/other/codesize/test_codesize_hello_single_file.gzsize +++ b/test/other/codesize/test_codesize_hello_single_file.gzsize @@ -1 +1 @@ -3634 +3626 diff --git a/test/other/codesize/test_codesize_hello_single_file.jssize b/test/other/codesize/test_codesize_hello_single_file.jssize index 583ea7dea61eb..d99a176aab4c8 100644 --- a/test/other/codesize/test_codesize_hello_single_file.jssize +++ b/test/other/codesize/test_codesize_hello_single_file.jssize @@ -1 +1 @@ -6702 +6690 From 00de2cf06561a0424ef939ccf59a4a8dc608a149 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Fri, 9 May 2025 23:40:40 +0100 Subject: [PATCH 8/9] Skip test on SAFE_HEAP + ASan together --- test/test_core.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/test_core.py b/test/test_core.py index f4995076ae7dc..d02cad77ce496 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -7494,12 +7494,15 @@ def test_embind_dynamic_initialization(self): @no_wasm2js('wasm_bigint') @parameterized({ - '': ([],), - 'safe_heap': (['-sSAFE_HEAP'],), + '': (False,), + 'safe_heap': (True,), }) - def test_embind_i64_val(self, args): + def test_embind_i64_val(self, safe_heap): self.set_setting('WASM_BIGINT') - self.emcc_args += ['-lembind'] + args + if safe_heap and '-fsanitize=address' in self.emcc_args: + self.skipTest('asan does not work with SAFE_HEAP') + self.set_setting('SAFE_HEAP', safe_heap) + self.emcc_args += ['-lembind'] self.node_args += shared.node_bigint_flags(self.get_nodejs()) self.do_run_in_out_file_test('embind/test_i64_val.cpp', assert_identical=True) From 7946613c6cd72f0eee725a741022de2b9919b165 Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Sat, 10 May 2025 00:36:34 +0100 Subject: [PATCH 9/9] Fix test --- test/test_other.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_other.py b/test/test_other.py index ffc83109ff681..b4477c9e851a9 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -12048,7 +12048,7 @@ def test_safe_heap_2(self): def test_safe_heap_log(self): self.set_setting('SAFE_HEAP') self.set_setting('SAFE_HEAP_LOG') - self.do_runf('hello_world.c', 'SAFE_HEAP load: ') + self.do_runf('hello_world.c', 'SAFE_HEAP loading: ') def test_mini_printfs(self): def test(code):