Skip to content

Commit e69b6cf

Browse files
authored
Set INCOMING_MODULE_JS_API to empty in STRICT mode (#16372)
In strict mode, make this list empty default which saves on code size and complexity. In this mode one needs to opt into any incoming module symbols you want to use.
1 parent 7b3d638 commit e69b6cf

File tree

9 files changed

+32
-28
lines changed

9 files changed

+32
-28
lines changed

ChangeLog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ See docs/process.md for more on how version tagging works.
2424
- The `--minify=0` commnad line flag will now preserve comments as well as
2525
whitespace. This means the resulting output can then be run though closure
2626
compiler or some other tool that gives comments semantic meaning. (#20121)
27+
- `-sSTRICT` now implies `-sINCOMING_MODULE_API=[]` which is generally good
28+
for code size. If you `-sSTRICT` you now need to be explicit about the
29+
incoming module APIs you are supplying. Users who supply symbols on the
30+
incoming module but forget to include them in `-sINCOMING_MODULE_API`
31+
will see an error in debug builds so this change will not generate any
32+
silent failures.
2733

2834
3.1.45 - 08/23/23
2935
-----------------

emcc.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
STATICLIB_ENDINGS = ['.a']
7676
ASSEMBLY_ENDINGS = ['.s']
7777
HEADER_ENDINGS = ['.h', '.hxx', '.hpp', '.hh', '.H', '.HXX', '.HPP', '.HH']
78+
DEFAULT_SHELL_HTML = utils.path_from_root('src/shell.html')
7879

7980
# Supported LLD flags which we will pass through to the linker.
8081
SUPPORTED_LINKER_FLAGS = (
@@ -268,7 +269,7 @@ def __init__(self):
268269
self.embed_files = []
269270
self.exclude_files = []
270271
self.ignore_dynamic_linking = False
271-
self.shell_path = utils.path_from_root('src/shell.html')
272+
self.shell_path = DEFAULT_SHELL_HTML
272273
self.source_map_base = ''
273274
self.embind_emit_tsd = ''
274275
self.emrun = False
@@ -2041,6 +2042,11 @@ def phase_linker_setup(options, state, newargs):
20412042
default_setting('AUTO_ARCHIVE_INDEXES', 0)
20422043
default_setting('IGNORE_MISSING_MAIN', 0)
20432044
default_setting('ALLOW_UNIMPLEMENTED_SYSCALLS', 0)
2045+
if options.oformat == OFormat.HTML and options.shell_path == DEFAULT_SHELL_HTML:
2046+
# Out default shell.html file has minimal set of INCOMING_MODULE_JS_API elements that it expects
2047+
default_setting('INCOMING_MODULE_JS_API', 'canvas,monitorRunDependencies,onAbort,onExit,print,setStatus'.split(','))
2048+
else:
2049+
default_setting('INCOMING_MODULE_JS_API', [])
20442050

20452051
if 'GLOBAL_BASE' not in user_settings and not settings.SHRINK_LEVEL and not settings.OPT_LEVEL:
20462052
# When optimizing for size it helps to put static data first before
@@ -2602,7 +2608,7 @@ def check_memory_setting(setting):
26022608

26032609
if settings.MINIMAL_RUNTIME:
26042610
# Minimal runtime uses a different default shell file
2605-
if options.shell_path == utils.path_from_root('src/shell.html'):
2611+
if options.shell_path == DEFAULT_SHELL_HTML:
26062612
options.shell_path = utils.path_from_root('src/shell_minimal_runtime.html')
26072613

26082614
if settings.ASSERTIONS:
@@ -2614,7 +2620,7 @@ def check_memory_setting(setting):
26142620

26152621
if settings.MODULARIZE and not (settings.EXPORT_ES6 and not settings.SINGLE_FILE) and \
26162622
settings.EXPORT_NAME == 'Module' and options.oformat == OFormat.HTML and \
2617-
(options.shell_path == utils.path_from_root('src/shell.html') or options.shell_path == utils.path_from_root('src/shell_minimal.html')):
2623+
(options.shell_path == DEFAULT_SHELL_HTML or options.shell_path == utils.path_from_root('src/shell_minimal.html')):
26182624
exit_with_error(f'Due to collision in variable name "Module", the shell file "{options.shell_path}" is not compatible with build options "-sMODULARIZE -sEXPORT_NAME=Module". Either provide your own shell file, change the name of the export to something else to avoid the name collision. (see https://github.com/emscripten-core/emscripten/issues/7950 for details)')
26192625

26202626
# TODO(sbc): Remove WASM2JS here once the size regression it would introduce has been fixed.
@@ -4154,7 +4160,7 @@ def generate_html(target, options, js_target, target_basename,
41544160

41554161
if settings.EXPORT_NAME != 'Module' and \
41564162
not settings.MINIMAL_RUNTIME and \
4157-
options.shell_path == utils.path_from_root('src/shell.html'):
4163+
options.shell_path == DEFAULT_SHELL_HTML:
41584164
# the minimal runtime shell HTML is designed to support changing the export
41594165
# name, but the normal one does not support that currently
41604166
exit_with_error('Customizing EXPORT_NAME requires that the HTML be customized to use that name (see https://github.com/emscripten-core/emscripten/issues/10086)')

site/source/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -755,7 +755,7 @@ For example, to set an environment variable ``MY_FILE_ROOT`` to be
755755

756756
.. code:: javascript
757757
758-
Module.preRun.push(function() {ENV.MY_FILE_ROOT = "/usr/lib/test"})
758+
Module.preRun = () => {ENV.MY_FILE_ROOT = "/usr/lib/test"};
759759
760760
Note that Emscripten will set default values for some environment variables
761761
(e.g. LANG) after you have configured ``ENV``, if you have not set your own
@@ -764,7 +764,7 @@ their value to `undefined`. For example:
764764

765765
.. code:: javascript
766766
767-
Module.preRun.push(function() {ENV.LANG = undefined})
767+
Module.preRun = () => {ENV.LANG = undefined};
768768
769769
.. _interacting-with-code-binding-cpp:
770770

src/settings.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,6 +1116,7 @@ var LINKABLE = false;
11161116
// * DEFAULT_TO_CXX is disabled.
11171117
// * USE_GLFW is set to 0 rather than 2 by default.
11181118
// * ALLOW_UNIMPLEMENTED_SYSCALLS is disabled.
1119+
// * INCOMING_MODULE_JS_API is set to empty by default.
11191120
// [compile+link]
11201121
var STRICT = false;
11211122

src/shell.html

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,8 +1222,6 @@
12221222
var spinnerElement = document.getElementById('spinner');
12231223

12241224
var Module = {
1225-
preRun: [],
1226-
postRun: [],
12271225
print: (function() {
12281226
var element = document.getElementById('output');
12291227
if (element) element.value = ''; // clear browser cache

src/shell_minimal.html

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@
7474
var spinnerElement = document.getElementById('spinner');
7575

7676
var Module = {
77-
preRun: [],
78-
postRun: [],
7977
print: (function() {
8078
var element = document.getElementById('output');
8179
if (element) element.value = ''; // clear browser cache

test/browser/cwrap_early.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
2-
Module['preRun'].push(function() {
1+
Module['preRun'] = () => {
32
console.log('preRun');
43
// it is ok to call cwrap before the runtime is loaded. we don't need the code
54
// and everything to be ready, since cwrap just prepares to call code, it
@@ -15,6 +14,4 @@ Module['preRun'].push(function() {
1514
xhr.send();
1615
setTimeout(function() { window.close() }, 1000);
1716
};
18-
});
19-
20-
17+
};

test/test_browser.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2241,9 +2241,9 @@ def test_sdl_gfx_primitives(self):
22412241

22422242
def test_sdl_canvas_palette_2(self):
22432243
create_file('pre.js', '''
2244-
Module['preRun'].push(function() {
2244+
Module['preRun'] = () => {
22452245
SDL.defaults.copyOnLock = false;
2246-
});
2246+
};
22472247
''')
22482248

22492249
create_file('args-r.js', '''
@@ -2525,11 +2525,11 @@ def test_runtime_misuse(self, mode):
25252525
create_file('post.js', post_prep + post_test + post_hook)
25262526
self.btest(filename, expected='600', args=['--post-js', 'post.js', '-sEXIT_RUNTIME'] + extra_args + mode, reporting=Reporting.NONE)
25272527
print('sync startup, call too late')
2528-
create_file('post.js', post_prep + 'Module.postRun.push(function() { ' + post_test + ' });' + post_hook)
2528+
create_file('post.js', post_prep + 'Module.postRun = () => { ' + post_test + ' };' + post_hook)
25292529
self.btest(filename, expected=str(second_code), args=['--post-js', 'post.js', '-sEXIT_RUNTIME'] + extra_args + mode, reporting=Reporting.NONE)
25302530

25312531
print('sync, runtime still alive, so all good')
2532-
create_file('post.js', post_prep + 'expected_ok = true; Module.postRun.push(function() { ' + post_test + ' });' + post_hook)
2532+
create_file('post.js', post_prep + 'expected_ok = true; Module.postRun = () => { ' + post_test + ' };' + post_hook)
25332533
self.btest(filename, expected='606', args=['--post-js', 'post.js'] + extra_args + mode, reporting=Reporting.NONE)
25342534

25352535
def test_cwrap_early(self):
@@ -2644,11 +2644,10 @@ def test_glew(self):
26442644

26452645
def test_doublestart_bug(self):
26462646
create_file('pre.js', r'''
2647-
if (!Module['preRun']) Module['preRun'] = [];
2648-
Module["preRun"].push(function () {
2647+
Module["preRun"] = () => {
26492648
addRunDependency('test_run_dependency');
26502649
removeRunDependency('test_run_dependency');
2651-
});
2650+
};
26522651
''')
26532652

26542653
self.btest('doublestart.c', args=['--pre-js', 'pre.js'], expected='1')

test/test_other.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4030,17 +4030,16 @@ def test_doublestart_bug(self):
40304030
''')
40314031

40324032
create_file('pre.js', r'''
4033-
if (!Module['preRun']) Module['preRun'] = [];
4034-
Module["preRun"].push(function () {
4035-
addRunDependency('test_run_dependency');
4036-
removeRunDependency('test_run_dependency');
4037-
});
4033+
Module["preRun"] = () => {
4034+
addRunDependency('test_run_dependency');
4035+
removeRunDependency('test_run_dependency');
4036+
};
40384037
''')
40394038

40404039
self.run_process([EMCC, 'code.c', '--pre-js', 'pre.js'])
40414040
output = self.run_js('a.out.js')
40424041

4043-
assert output.count('This should only appear once.') == 1, output
4042+
self.assertEqual(output.count('This should only appear once.'), 1)
40444043

40454044
def test_module_print(self):
40464045
create_file('code.c', r'''

0 commit comments

Comments
 (0)