diff --git a/ChangeLog.md b/ChangeLog.md index fd9ed3f4895e..a0dab80f080e 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -20,6 +20,11 @@ See docs/process.md for more on how version tagging works. 3.1.47 (in development) ----------------------- +- The `noExitRuntime` global is now a JS library symbol that will only be + included as needed. User of `noExitRuntime` will now need to declare a + dependency on it. It will get implicitly included if `noExitRuntime` is part + of `INCOMING_MODULE_JS_API.` (which it is by default), or it can be added to + either `DEFAULT_LIBRARY_FUNCS_TO_INCLUDE` or `noExitRuntime`. (#20336) - The egl, html5, sdl and webgpu libraries now support basic functionality with `-sMEMORY64`. (#20276) - Value types in `emscripten/html5.h` that correspond the WebIDL `long` type are diff --git a/emcc.py b/emcc.py index a863b486306d..6fe7855382fd 100644 --- a/emcc.py +++ b/emcc.py @@ -1804,6 +1804,9 @@ def phase_linker_setup(options, state, newargs): system_libpath = '-L' + str(cache.get_lib_dir(absolute=True)) add_link_flag(state, sys.maxsize, system_libpath) + if 'noExitRuntime' in settings.INCOMING_MODULE_JS_API: + settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.append('$noExitRuntime') + if settings.OPT_LEVEL >= 1: default_setting('ASSERTIONS', 0) diff --git a/src/jsifier.js b/src/jsifier.js index 0c9779ce8e81..a06842e5410d 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -487,6 +487,12 @@ function(${args}) { if (typeof dep == 'function') { return dep(); } + // $noExitRuntime is special since there are conditional usages of it + // in library.js and library_pthread.js. These happen before deps are + // processed so depending on it via `__deps` doesn't work. + if (dep === '$noExitRuntime') { + error('noExitRuntime cannot be referenced via __deps mechansim. Use DEFAULT_LIBRARY_FUNCS_TO_INCLUDE or EXPORTED_RUNTIME_METHODS') + } return addFromLibrary(dep, `${symbol}, referenced by ${dependent}`, dep === aliasTarget); } let contentText; diff --git a/src/library.js b/src/library.js index ae7d97fb2745..6b3441d2de36 100644 --- a/src/library.js +++ b/src/library.js @@ -3269,8 +3269,10 @@ addToLibrary({ _emscripten_runtime_keepalive_clear__proxy: 'sync', _emscripten_runtime_keepalive_clear: () => { -#if !MINIMAL_RUNTIME +#if isSymbolNeeded('$noExitRuntime') noExitRuntime = false; +#endif +#if !MINIMAL_RUNTIME runtimeKeepaliveCounter = 0; #endif }, @@ -3388,7 +3390,11 @@ addToLibrary({ $runtimeKeepaliveCounter: 0, $keepRuntimeAlive__deps: ['$runtimeKeepaliveCounter'], +#if isSymbolNeeded('$noExitRuntime') $keepRuntimeAlive: () => noExitRuntime || runtimeKeepaliveCounter > 0, +#else + $keepRuntimeAlive: () => runtimeKeepaliveCounter > 0, +#endif // Callable in pthread without __proxy needed. $runtimeKeepalivePush__deps: ['$runtimeKeepaliveCounter'], @@ -3646,6 +3652,8 @@ addToLibrary({ $wasmTable: undefined, #endif + $noExitRuntime: "{{{ makeModuleReceiveExpr('noExitRuntime', !EXIT_RUNTIME) }}}", + // We used to define these globals unconditionally in support code. // Instead, we now define them here so folks can pull it in explicitly, on // demand. diff --git a/src/library_pthread.js b/src/library_pthread.js index 1fc24830c597..864bd7eeabed 100644 --- a/src/library_pthread.js +++ b/src/library_pthread.js @@ -129,7 +129,7 @@ var LibraryPThread = { #endif #endif -#if !MINIMAL_RUNTIME +#if isSymbolNeeded('$noExitRuntime') // The default behaviour for pthreads is always to exit once they return // from their entry point (or call pthread_exit). If we set noExitRuntime // to true here on pthreads they would never complete and attempt to diff --git a/src/parseTools.js b/src/parseTools.js index 3f2695f04fe2..e1d8a77637fd 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -744,6 +744,18 @@ function expectToReceiveOnModule(name) { return INCOMING_MODULE_JS_API.has(name); } +// Return true if the user requested that a library symbol be included +// either via DEFAULT_LIBRARY_FUNCS_TO_INCLUDE or EXPORTED_RUNTIME_METHODS. +function isSymbolNeeded(symName) { + if (DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.includes(symName)) { + return true; + } + if (symName.startsWith('$') && symName.slice(1) in EXPORTED_RUNTIME_METHODS) { + return true; + } + return false; +} + function makeRemovedModuleAPIAssert(moduleName, localName) { if (!ASSERTIONS) return ''; if (!localName) localName = moduleName; diff --git a/src/preamble.js b/src/preamble.js index 040f83157fa3..78dc4ce958a1 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -24,7 +24,6 @@ out = err = () => {}; #endif {{{ makeModuleReceiveWithVar('wasmBinary') }}} -{{{ makeModuleReceiveWithVar('noExitRuntime', undefined, EXIT_RUNTIME ? 'false' : 'true') }}} #if WASM != 2 && MAYBE_WASM2JS #if !WASM2JS diff --git a/test/other/metadce/test_metadce_cxx_ctors1.jssize b/test/other/metadce/test_metadce_cxx_ctors1.jssize index 6f859f5ef006..ccfeaacb9c53 100644 --- a/test/other/metadce/test_metadce_cxx_ctors1.jssize +++ b/test/other/metadce/test_metadce_cxx_ctors1.jssize @@ -1 +1 @@ -25031 +25027 diff --git a/test/other/metadce/test_metadce_cxx_ctors2.jssize b/test/other/metadce/test_metadce_cxx_ctors2.jssize index f594cab48c8e..17eaf232ece9 100644 --- a/test/other/metadce/test_metadce_cxx_ctors2.jssize +++ b/test/other/metadce/test_metadce_cxx_ctors2.jssize @@ -1 +1 @@ -24999 +24995 diff --git a/test/other/metadce/test_metadce_cxx_except.jssize b/test/other/metadce/test_metadce_cxx_except.jssize index ba79ffcd9a76..5fbadda034c2 100644 --- a/test/other/metadce/test_metadce_cxx_except.jssize +++ b/test/other/metadce/test_metadce_cxx_except.jssize @@ -1 +1 @@ -29164 +29160 diff --git a/test/other/metadce/test_metadce_cxx_except_wasm.jssize b/test/other/metadce/test_metadce_cxx_except_wasm.jssize index 48f3846f9e54..8623f45402eb 100644 --- a/test/other/metadce/test_metadce_cxx_except_wasm.jssize +++ b/test/other/metadce/test_metadce_cxx_except_wasm.jssize @@ -1 +1 @@ -24805 +24801 diff --git a/test/other/metadce/test_metadce_cxx_mangle.jssize b/test/other/metadce/test_metadce_cxx_mangle.jssize index c7719ae2d19d..ee8c5e35c09b 100644 --- a/test/other/metadce/test_metadce_cxx_mangle.jssize +++ b/test/other/metadce/test_metadce_cxx_mangle.jssize @@ -1 +1 @@ -29163 +29159 diff --git a/test/other/metadce/test_metadce_cxx_noexcept.jssize b/test/other/metadce/test_metadce_cxx_noexcept.jssize index 6f859f5ef006..ccfeaacb9c53 100644 --- a/test/other/metadce/test_metadce_cxx_noexcept.jssize +++ b/test/other/metadce/test_metadce_cxx_noexcept.jssize @@ -1 +1 @@ -25031 +25027 diff --git a/test/other/metadce/test_metadce_cxx_wasmfs.jssize b/test/other/metadce/test_metadce_cxx_wasmfs.jssize index 9f3c05e1f741..500569dc4ee8 100644 --- a/test/other/metadce/test_metadce_cxx_wasmfs.jssize +++ b/test/other/metadce/test_metadce_cxx_wasmfs.jssize @@ -1 +1 @@ -12440 +12436 diff --git a/test/other/metadce/test_metadce_files_js_fs.jssize b/test/other/metadce/test_metadce_files_js_fs.jssize index 1d39f4b55735..9f0ef20fa0b5 100644 --- a/test/other/metadce/test_metadce_files_js_fs.jssize +++ b/test/other/metadce/test_metadce_files_js_fs.jssize @@ -1 +1 @@ -19930 +19926 diff --git a/test/other/metadce/test_metadce_files_wasmfs.jssize b/test/other/metadce/test_metadce_files_wasmfs.jssize index 8e2fb3e26411..5e3bd39f6d97 100644 --- a/test/other/metadce/test_metadce_files_wasmfs.jssize +++ b/test/other/metadce/test_metadce_files_wasmfs.jssize @@ -1 +1 @@ -7070 +7065 diff --git a/test/other/metadce/test_metadce_hello_O0.jssize b/test/other/metadce/test_metadce_hello_O0.jssize index 6ba39ac9457a..32cf107dbcc7 100644 --- a/test/other/metadce/test_metadce_hello_O0.jssize +++ b/test/other/metadce/test_metadce_hello_O0.jssize @@ -1 +1 @@ -23549 +23522 diff --git a/test/other/metadce/test_metadce_hello_O1.jssize b/test/other/metadce/test_metadce_hello_O1.jssize index e5c1a3ee9af0..258bfeb08822 100644 --- a/test/other/metadce/test_metadce_hello_O1.jssize +++ b/test/other/metadce/test_metadce_hello_O1.jssize @@ -1 +1 @@ -8062 +8058 diff --git a/test/other/metadce/test_metadce_hello_O2.jssize b/test/other/metadce/test_metadce_hello_O2.jssize index e0ffa8a2f687..3a335e43fc29 100644 --- a/test/other/metadce/test_metadce_hello_O2.jssize +++ b/test/other/metadce/test_metadce_hello_O2.jssize @@ -1 +1 @@ -5724 +5719 diff --git a/test/other/metadce/test_metadce_hello_O3.jssize b/test/other/metadce/test_metadce_hello_O3.jssize index 46ca18ff751e..41fe758666ae 100644 --- a/test/other/metadce/test_metadce_hello_O3.jssize +++ b/test/other/metadce/test_metadce_hello_O3.jssize @@ -1 +1 @@ -5571 +5566 diff --git a/test/other/metadce/test_metadce_hello_Os.jssize b/test/other/metadce/test_metadce_hello_Os.jssize index 46ca18ff751e..41fe758666ae 100644 --- a/test/other/metadce/test_metadce_hello_Os.jssize +++ b/test/other/metadce/test_metadce_hello_Os.jssize @@ -1 +1 @@ -5571 +5566 diff --git a/test/other/metadce/test_metadce_hello_Oz.jssize b/test/other/metadce/test_metadce_hello_Oz.jssize index b7b57d282909..04383b66b691 100644 --- a/test/other/metadce/test_metadce_hello_Oz.jssize +++ b/test/other/metadce/test_metadce_hello_Oz.jssize @@ -1 +1 @@ -5537 +5533 diff --git a/test/other/metadce/test_metadce_hello_dylink.jssize b/test/other/metadce/test_metadce_hello_dylink.jssize index a8a58af06d23..ed2b0d4030b1 100644 --- a/test/other/metadce/test_metadce_hello_dylink.jssize +++ b/test/other/metadce/test_metadce_hello_dylink.jssize @@ -1 +1 @@ -14810 +14806 diff --git a/test/other/metadce/test_metadce_hello_wasmfs.jssize b/test/other/metadce/test_metadce_hello_wasmfs.jssize index 46ca18ff751e..41fe758666ae 100644 --- a/test/other/metadce/test_metadce_hello_wasmfs.jssize +++ b/test/other/metadce/test_metadce_hello_wasmfs.jssize @@ -1 +1 @@ -5571 +5566 diff --git a/test/other/metadce/test_metadce_libcxxabi_message_O3.jssize b/test/other/metadce/test_metadce_libcxxabi_message_O3.jssize index 4be6305633c1..4d4433e4c0f5 100644 --- a/test/other/metadce/test_metadce_libcxxabi_message_O3.jssize +++ b/test/other/metadce/test_metadce_libcxxabi_message_O3.jssize @@ -1 +1 @@ -4855 +4850 diff --git a/test/other/metadce/test_metadce_libcxxabi_message_O3_standalone.jssize b/test/other/metadce/test_metadce_libcxxabi_message_O3_standalone.jssize index 1e14a4ae72a7..546b2455bced 100644 --- a/test/other/metadce/test_metadce_libcxxabi_message_O3_standalone.jssize +++ b/test/other/metadce/test_metadce_libcxxabi_message_O3_standalone.jssize @@ -1 +1 @@ -4904 +4899 diff --git a/test/other/metadce/test_metadce_mem_O3.jssize b/test/other/metadce/test_metadce_mem_O3.jssize index 3acaec926a8f..33595ef713e0 100644 --- a/test/other/metadce/test_metadce_mem_O3.jssize +++ b/test/other/metadce/test_metadce_mem_O3.jssize @@ -1 +1 @@ -5752 +5748 diff --git a/test/other/metadce/test_metadce_mem_O3_grow.jssize b/test/other/metadce/test_metadce_mem_O3_grow.jssize index 37bc2c2a5584..e086a733090d 100644 --- a/test/other/metadce/test_metadce_mem_O3_grow.jssize +++ b/test/other/metadce/test_metadce_mem_O3_grow.jssize @@ -1 +1 @@ -6074 +6070 diff --git a/test/other/metadce/test_metadce_mem_O3_grow_standalone.jssize b/test/other/metadce/test_metadce_mem_O3_grow_standalone.jssize index 9d3c219d48f0..4e8a6e6d26b4 100644 --- a/test/other/metadce/test_metadce_mem_O3_grow_standalone.jssize +++ b/test/other/metadce/test_metadce_mem_O3_grow_standalone.jssize @@ -1 +1 @@ -5468 +5464 diff --git a/test/other/metadce/test_metadce_mem_O3_standalone.jssize b/test/other/metadce/test_metadce_mem_O3_standalone.jssize index f135ff269913..d4a03e270f12 100644 --- a/test/other/metadce/test_metadce_mem_O3_standalone.jssize +++ b/test/other/metadce/test_metadce_mem_O3_standalone.jssize @@ -1 +1 @@ -5399 +5395 diff --git a/test/other/metadce/test_metadce_mem_O3_standalone_lib.jssize b/test/other/metadce/test_metadce_mem_O3_standalone_lib.jssize index b76f96d7b79c..e3bda3519fc4 100644 --- a/test/other/metadce/test_metadce_mem_O3_standalone_lib.jssize +++ b/test/other/metadce/test_metadce_mem_O3_standalone_lib.jssize @@ -1 +1 @@ -4906 +4901 diff --git a/test/other/metadce/test_metadce_mem_O3_standalone_narg.jssize b/test/other/metadce/test_metadce_mem_O3_standalone_narg.jssize index 1e14a4ae72a7..546b2455bced 100644 --- a/test/other/metadce/test_metadce_mem_O3_standalone_narg.jssize +++ b/test/other/metadce/test_metadce_mem_O3_standalone_narg.jssize @@ -1 +1 @@ -4904 +4899 diff --git a/test/other/metadce/test_metadce_mem_O3_standalone_narg_flto.jssize b/test/other/metadce/test_metadce_mem_O3_standalone_narg_flto.jssize index 1e14a4ae72a7..546b2455bced 100644 --- a/test/other/metadce/test_metadce_mem_O3_standalone_narg_flto.jssize +++ b/test/other/metadce/test_metadce_mem_O3_standalone_narg_flto.jssize @@ -1 +1 @@ -4904 +4899 diff --git a/test/other/metadce/test_metadce_minimal_O0.jssize b/test/other/metadce/test_metadce_minimal_O0.jssize index 2b6963291ce3..0a0a06ec164f 100644 --- a/test/other/metadce/test_metadce_minimal_O0.jssize +++ b/test/other/metadce/test_metadce_minimal_O0.jssize @@ -1 +1 @@ -20027 +20004 diff --git a/test/other/test_unoptimized_code_size.js.size b/test/other/test_unoptimized_code_size.js.size index 2b03a7def8d9..8efd6a3fcc03 100644 --- a/test/other/test_unoptimized_code_size.js.size +++ b/test/other/test_unoptimized_code_size.js.size @@ -1 +1 @@ -58384 +58355 diff --git a/test/other/test_unoptimized_code_size_no_asserts.js.size b/test/other/test_unoptimized_code_size_no_asserts.js.size index 1621fbde9202..3d61a6a66758 100644 --- a/test/other/test_unoptimized_code_size_no_asserts.js.size +++ b/test/other/test_unoptimized_code_size_no_asserts.js.size @@ -1 +1 @@ -31749 +31752 diff --git a/test/other/test_unoptimized_code_size_strict.js.size b/test/other/test_unoptimized_code_size_strict.js.size index 60cab92a6149..e91cec8fc62c 100644 --- a/test/other/test_unoptimized_code_size_strict.js.size +++ b/test/other/test_unoptimized_code_size_strict.js.size @@ -1 +1 @@ -57098 +57069 diff --git a/test/test_other.py b/test/test_other.py index ef6abe3c1e12..ebaed36e3134 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -13888,17 +13888,17 @@ def test_webidl_empty(self): def test_noExitRuntime(self): onexit_called = 'onExit called' - create_file('pre.js', f'Module.onExit = () => console.log("${onexit_called}");') + create_file('pre.js', f'Module.onExit = () => console.log("${onexit_called}");\n') self.emcc_args += ['--pre-js=pre.js'] self.set_setting('EXIT_RUNTIME') - # Normally with EXIT_RUNTIME set we expect onExit to be called; + # Normally, with EXIT_RUNTIME set we expect onExit to be called. output = self.do_runf(test_file('hello_world.c'), 'hello, world') self.assertContained(onexit_called, output) - # However, if we set `Module.noExitRuntime = true`, then we expect - # it not to be called. - create_file('noexit.js', 'Module.noExitRuntime = true;') + # However, if we set `Module.noExitRuntime = true`, then it should + # not be called. + create_file('noexit.js', 'Module.noExitRuntime = true;\n') output = self.do_runf(test_file('hello_world.c'), 'hello, world', emcc_args=['--pre-js=noexit.js']) self.assertNotContained(onexit_called, output) @@ -13907,3 +13907,15 @@ def test_noExitRuntime(self): create_file('noexit_oninit.js', 'Module.preRun = () => { noExitRuntime = true; }') output = self.do_runf(test_file('hello_world.c'), 'hello, world', emcc_args=['--pre-js=noexit_oninit.js']) self.assertNotContained(onexit_called, output) + + def test_noExitRuntime_deps(self): + create_file('lib.js', r''' +addToLibrary({ + foo__deps: ['$noExitRuntime'], + foo: () => { + return 0; + } +}); +''') + err = self.expect_fail([EMCC, test_file('hello_world.c'), '--js-library=lib.js', '-sDEFAULT_LIBRARY_FUNCS_TO_INCLUDE=foo']) + self.assertContained('error: noExitRuntime cannot be referenced via __deps mechansim', err) diff --git a/tools/gen_struct_info.py b/tools/gen_struct_info.py index 7864549886ed..18d296c59acd 100755 --- a/tools/gen_struct_info.py +++ b/tools/gen_struct_info.py @@ -250,6 +250,7 @@ def inspect_headers(headers, cflags): '-nostdlib', compiler_rt, '-sBOOTSTRAPPING_STRUCT_INFO', + '-sINCOMING_MODULE_JS_API=', '-sSTRICT', '-sASSERTIONS=0'] + node_flags