diff --git a/system/include/emscripten/em_asm.h b/system/include/emscripten/em_asm.h index 3312ba8e15baf..92b710fc18c45 100644 --- a/system/include/emscripten/em_asm.h +++ b/system/include/emscripten/em_asm.h @@ -285,4 +285,20 @@ const char __em_asm_sig_builder<__em_asm_type_tuple >::buffer[] = { __e #define EM_ASM_INT_V(code) EM_ASM_INT(code) #define EM_ASM_DOUBLE_V(code) EM_ASM_DOUBLE(code) + +// Normally macros like `true` and `false` are not expanded inside +// of `EM_JS` or `EM_ASM` blocks. However, in the case then an +// additional macro later is added these will be expanded and we want +// to make sure the resulting expansion doesn't break the expectations +// of JS code +#if defined(true) && defined(false) +#undef true +#undef false +// These work for both C and javascript. +// In C !!0 ==> 0 and in javascript !!0 ==> false +// In C !!1 ==> 1 and in javascript !!1 ==> true +#define true (!!1) +#define false (!!0) +#endif + #endif // !defined(__cplusplus) && defined(__STRICT_ANSI__) diff --git a/system/include/emscripten/em_js.h b/system/include/emscripten/em_js.h index 0b565e0407c7d..3d51e29e37514 100644 --- a/system/include/emscripten/em_js.h +++ b/system/include/emscripten/em_js.h @@ -72,3 +72,19 @@ #define EM_ASYNC_JS(ret, name, params, ...) _EM_JS(ret, name, __asyncjs__##name, params, \ "{ return Asyncify.handleAsync(async () => " #__VA_ARGS__ "); }") + + +// Normally macros like `true` and `false` are not expanded inside +// of `EM_JS` or `EM_ASM` blocks. However, in the case then an +// additional macro later is added these will be expanded and we want +// to make sure the resulting expansion doesn't break the expectations +// of JS code +#if defined(true) && defined(false) +#undef true +#undef false +// These work for both C and javascript. +// In C !!0 ==> 0 and in javascript !!0 ==> false +// In C !!1 ==> 1 and in javascript !!1 ==> true +#define true (!!1) +#define false (!!0) +#endif diff --git a/test/test_other.py b/test/test_other.py index d411e7d7cd355..bda066c22271b 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -16060,3 +16060,28 @@ def test_getentropy_d8(self): self.do_runf('main.c', msg, assert_returncode=1) self.v8_args += ['--enable-os-system'] self.do_runf('main.c') + + def test_em_js_bool_macro_expansion(self): + # Normally macros like `true` and `false` are not expanded inside + # of `EM_JS` or `EM_ASM` blocks. However, in the case then an + # additional macro later is added these will be expanded and we want + # to make sure the resulting expansion doesn't break the expectations + # of JS code. + create_file('main.c', ''' + #include + + #define EM_JS_MACROS(ret, func_name, args, body...) \ + EM_JS(ret, func_name, args, body) + + EM_JS_MACROS(void, check_bool_type, (void), { + if (typeof true !== "boolean") { + throw new Error("typeof true is " + typeof true + " not boolean"); + } + }) + + int main() { + check_bool_type(); + return 0; + } + ''') + self.do_runf('main.c')