From 7097d6202bd91b1bcc822fc0317c99c22694e228 Mon Sep 17 00:00:00 2001 From: Zsolt Szilagyi Date: Thu, 28 May 2026 17:59:15 +0200 Subject: [PATCH] Fix cwrap with returnType 'boolean' to return a JS boolean (#27021) The cwrap fast path returned the raw wasm export whenever the return type was not 'string', bypassing the Boolean() coercion that ccall applies. Exclude 'boolean' from the fast-path return check so boolean returns go through ccall, matching ccall's behavior. --- src/lib/libccall.js | 2 +- test/test_core.py | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/lib/libccall.js b/src/lib/libccall.js index 4d40b8dbf884c..273d34e0de912 100644 --- a/src/lib/libccall.js +++ b/src/lib/libccall.js @@ -146,7 +146,7 @@ addToLibrary({ // When the function takes numbers and returns a number, we can just return // the original function var numericArgs = !argTypes || argTypes.every((type) => type === 'number' || type === 'boolean'); - var numericRet = returnType !== 'string'; + var numericRet = returnType !== 'string' && returnType !== 'boolean'; if (numericRet && numericArgs && !opts) { return getCFunc(ident); } diff --git a/test/test_core.py b/test/test_core.py index 045c5dc1fe477..841f78c0f6b53 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -7097,10 +7097,14 @@ def test_ccall_cwrap_fast_path(self): create_file('post.js', ''' var printBool = Module['cwrap']('print_bool', null, ['boolean']); out(Module['_print_bool'] === printBool); // the function should be the exact raw function in the module rather than a wrapped one + var getBool = Module['cwrap']('get_bool', 'boolean'); + out(Module['_get_bool'] !== getBool); // boolean return must not use the fast path so the result is coerced to a JS boolean + var ret = getBool(); + out([typeof ret, ret].join(',')); ''') - self.set_setting('EXPORTED_FUNCTIONS', ['_print_bool']) - self.do_runf('core/test_ccall.cpp', 'true', cflags=['--post-js=post.js', '-Wno-return-stack-address']) + self.set_setting('EXPORTED_FUNCTIONS', ['_print_bool', '_get_bool']) + self.do_runf('core/test_ccall.cpp', 'true\ntrue\nboolean,true\n', cflags=['--post-js=post.js', '-Wno-return-stack-address']) @no_modularize_instance('ccall is not yet compatible with MODULARIZE=instance') def test_ccall_return_pointer(self):