From 689dc115d4b2883c896b8f0a6066acb4b3e81454 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Wed, 28 Sep 2022 10:59:17 +0200 Subject: [PATCH 1/4] Deprecate export of module handlers via `EXPORTED_RUNTIME_METHODS` `print` / `printErr` are handlers that can be overridden by the user on the incoming module (just like `onAbort`) and not runtime elements that can be exported. Deprecate the export of `print` / `printErr` via `EXPORTED_RUNTIME_METHODS` in favor of `out` / `err`. --- src/modules.js | 23 +++++++++++++++++------ test/test_browser.py | 2 +- test/test_other.py | 13 ++++++++----- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/modules.js b/src/modules.js index 739ba1cc19d6f..896091c6db0cf 100644 --- a/src/modules.js +++ b/src/modules.js @@ -311,6 +311,10 @@ function addMissingLibraryStubs() { function exportRuntime() { const EXPORTED_RUNTIME_METHODS_SET = new Set(EXPORTED_RUNTIME_METHODS); + const legacyRuntimeElements = new Map(); + legacyRuntimeElements.set('print', 'out'); + legacyRuntimeElements.set('printErr', 'err'); + // optionally export something. // in ASSERTIONS mode we show a useful error if it is used without // being exported. how we show the message depends on whether it's @@ -323,10 +327,8 @@ function exportRuntime() { if (isFSPrefixed(exported)) { // this is a filesystem value, FS.x exported as FS_x exported = 'FS.' + exported.substr(3); - } else if (exported === 'print') { - exported = 'out'; - } else if (exported === 'printErr') { - exported = 'err'; + } else if (legacyRuntimeElements.has(exported)) { + exported = legacyRuntimeElements.get(exported); } return `Module["${name}"] = ${exported};`; } @@ -361,8 +363,8 @@ function exportRuntime() { 'registerFunctions', 'prettyPrint', 'getCompilerSetting', - 'print', - 'printErr', + 'out', + 'err', 'callMain', 'abort', 'keepRuntimeAlive', @@ -413,6 +415,15 @@ function exportRuntime() { } } + // Only export legacy runtime elements when explicitly + // requested. + for (const name of EXPORTED_RUNTIME_METHODS_SET) { + if (legacyRuntimeElements.has(name)) { + const newName = legacyRuntimeElements.get(name); + warn(`deprecated item in EXPORTED_RUNTIME_METHODS: ${name} use ${newName} instead.`); + runtimeElements.push(name); + } + } // Add JS library elements such as FS, GL, ENV, etc. These are prefixed with // '$ which indicates they are JS methods. diff --git a/test/test_browser.py b/test/test_browser.py index 040bc14ac09a7..40bdde862db16 100644 --- a/test/test_browser.py +++ b/test/test_browser.py @@ -4904,7 +4904,7 @@ def test_unicode_html_shell(self): # Tests the functionality of the emscripten_thread_sleep() function. @requires_threads def test_emscripten_thread_sleep(self): - self.btest_exit(test_file('pthread/emscripten_thread_sleep.c'), args=['-sUSE_PTHREADS', '-sEXPORTED_RUNTIME_METHODS=[print]']) + self.btest_exit(test_file('pthread/emscripten_thread_sleep.c'), args=['-sUSE_PTHREADS']) # Tests that Emscripten-compiled applications can be run from a relative path in browser that is different than the address of the current page def test_browser_run_from_different_directory(self): diff --git a/test/test_other.py b/test/test_other.py index 7eba6aaeca641..25dfac8bc6896 100644 --- a/test/test_other.py +++ b/test/test_other.py @@ -7130,7 +7130,7 @@ def test(contents): self.run_process([EMXX, 'src.cpp', '-O2']) # optimized, so no assertions self.assertNotContained(error, read_file('a.out.js')) - def test_warn_module_print_err(self): + def test_warn_module_out_err(self): error = 'was not exported. add it to EXPORTED_RUNTIME_METHODS (see the FAQ)' def test(contents, expected, args=[], assert_returncode=0): # noqa @@ -7145,12 +7145,15 @@ def test(contents, expected, args=[], assert_returncode=0): # noqa self.assertContained(expected, self.run_js('a.out.js', assert_returncode=assert_returncode)) # error shown (when assertions are on) - test("Module.print('x')", error, assert_returncode=NON_ZERO) - test("Module['print']('x')", error, assert_returncode=NON_ZERO) - test("Module.printErr('x')", error, assert_returncode=NON_ZERO) - test("Module['printErr']('x')", error, assert_returncode=NON_ZERO) + test("Module.out('x')", error, assert_returncode=NON_ZERO) + test("Module['out']('x')", error, assert_returncode=NON_ZERO) + test("Module.err('x')", error, assert_returncode=NON_ZERO) + test("Module['err']('x')", error, assert_returncode=NON_ZERO) # when exported, all good + test("Module['out']('print'); Module['err']('err'); ", 'print\nerr', ['-sEXPORTED_RUNTIME_METHODS=out,err']) + + # test backwards compatibility test("Module['print']('print'); Module['printErr']('err'); ", 'print\nerr', ['-sEXPORTED_RUNTIME_METHODS=print,printErr']) def test_warn_unexported_main(self): From f6c2f803c2085ab474af5c9664b6078c12a4000c Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 30 Sep 2022 16:25:04 +0200 Subject: [PATCH 2/4] Initialize map with key-value pairs. NFC. --- src/modules.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/modules.js b/src/modules.js index 896091c6db0cf..42e4203475a3e 100644 --- a/src/modules.js +++ b/src/modules.js @@ -311,9 +311,10 @@ function addMissingLibraryStubs() { function exportRuntime() { const EXPORTED_RUNTIME_METHODS_SET = new Set(EXPORTED_RUNTIME_METHODS); - const legacyRuntimeElements = new Map(); - legacyRuntimeElements.set('print', 'out'); - legacyRuntimeElements.set('printErr', 'err'); + const legacyRuntimeElements = new Map([ + ['print', 'out'], + ['printErr', 'err'], + ]); // optionally export something. // in ASSERTIONS mode we show a useful error if it is used without From 0d184419e32f123d87420681467a1e6c40609100 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 30 Sep 2022 16:32:55 +0200 Subject: [PATCH 3/4] Fix test failure in `browser.test_emscripten_thread_sleep` --- test/pthread/emscripten_thread_sleep.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/pthread/emscripten_thread_sleep.c b/test/pthread/emscripten_thread_sleep.c index 3a29ca485f11a..d8b6b662c0fce 100644 --- a/test/pthread/emscripten_thread_sleep.c +++ b/test/pthread/emscripten_thread_sleep.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -16,7 +17,7 @@ void Sleep(double msecs) void *thread_main(void *arg) { - EM_ASM(Module.print('hello from thread!')); + _emscripten_out("hello from thread!"); Sleep(1); Sleep(10); From 1dbb43af4145d9f11e8394f21d470e498db15370 Mon Sep 17 00:00:00 2001 From: Kleis Auke Wolthuizen Date: Fri, 14 Oct 2022 12:30:17 +0200 Subject: [PATCH 4/4] Update ChangeLog.md --- ChangeLog.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index e2403bd72dd73..edb119da2f2e7 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -20,6 +20,9 @@ See docs/process.md for more on how version tagging works. 3.1.25 (in development) ----------------------- +- Exporting `print`/`printErr` via `-sEXPORTED_RUNTIME_METHODS` is deprecated in + favor of `out`/`err`. The former symbols are supposed to be used with + `-sINCOMING_MODULE_JS_API` instead. (#17955) 3.1.24 - 10/11/22 ----------------- @@ -394,7 +397,7 @@ See docs/process.md for more on how version tagging works. `isFunctionDef`, `isPossiblyFunctionType`, `isFunctionType`, `getReturnType`, `splitTokenList`, `_IntToHex`, `IEEEUnHex`, `Compiletime.isPointerType`, `Compiletime.isStructType`, `Compiletime.INT_TYPES`, `isType`. -- The example `shell.html` and `shell_minimal.html` templaces no longer override +- The example `shell.html` and `shell_minimal.html` templates no longer override `printErr` on the module object. This means error message from emscripten and stderr from the application will go to the default location of `console.warn` rather than `console.error`. This only effects application that use the