diff --git a/emcc.py b/emcc.py index 5ebefb9b8c99b..3f590901a6c09 100755 --- a/emcc.py +++ b/emcc.py @@ -1739,6 +1739,9 @@ def include_and_export(name): # requires JS legalization shared.Settings.LEGALIZE_JS_FFI = 0 + if shared.Settings.STANDALONE_WASM or (shared.Settings.MINIMAL_RUNTIME and not shared.Settings.USE_PTHREADS): + shared.Settings.MEMORY_DEFINED_IN_WASM = 1 + if shared.Settings.WASM_BIGINT: shared.Settings.LEGALIZE_JS_FFI = 0 diff --git a/emscripten.py b/emscripten.py index 0fa36419622ad..39a28f8f283f2 100644 --- a/emscripten.py +++ b/emscripten.py @@ -536,10 +536,7 @@ def create_em_js(forwarded_json, metadata): def add_standard_wasm_imports(send_items_map): - # Normally we import these into the wasm (so that JS could use them even - # before the wasm loads), while in standalone mode we do not depend - # on JS to create them, but create them in the wasm and export them. - if not shared.Settings.STANDALONE_WASM: + if not shared.Settings.MEMORY_DEFINED_IN_WASM: memory_import = 'wasmMemory' if shared.Settings.MODULARIZE and shared.Settings.USE_PTHREADS: # Pthreads assign wasmMemory in their worker startup. In MODULARIZE mode, they cannot assign inside the diff --git a/src/postamble_minimal.js b/src/postamble_minimal.js index 03d70a2161011..4ddc50b0a3417 100644 --- a/src/postamble_minimal.js +++ b/src/postamble_minimal.js @@ -204,6 +204,25 @@ WebAssembly.instantiate(Module['wasm'], imports).then(function(output) { /*** ASM_MODULE_EXPORTS ***/ #endif wasmTable = asm['__indirect_function_table']; +#if ASSERTIONS + assert(wasmTable); +#endif + +#if !USE_PTHREADS + wasmMemory = asm['memory']; +#if ASSERTIONS + assert(wasmMemory); + assert(wasmMemory.buffer.byteLength === {{{ INITIAL_MEMORY }}}); +#endif + updateGlobalBufferAndViews(wasmMemory.buffer); +#endif + +#if MEM_INIT_METHOD == 1 && !MEM_INIT_IN_WASM && !SINGLE_FILE +#if ASSERTIONS + if (!Module['mem']) throw 'Must load memory initializer as an ArrayBuffer in to variable Module.mem before adding compiled output .js script to the DOM'; +#endif + HEAPU8.set(new Uint8Array(Module['mem']), {{{ GLOBAL_BASE }}}); +#endif initRuntime(asm); #if USE_PTHREADS && PTHREAD_POOL_SIZE diff --git a/src/preamble_minimal.js b/src/preamble_minimal.js index 76a4cba0c3783..edeaf789ebd72 100644 --- a/src/preamble_minimal.js +++ b/src/preamble_minimal.js @@ -55,52 +55,13 @@ Module['wasm'] = base64Decode('{{{ getQuoted("WASM_BINARY_DATA") }}}'); #include "runtime_functions.js" #include "runtime_strings.js" -#if USE_PTHREADS -if (!ENVIRONMENT_IS_PTHREAD) { -#endif - -#if ALLOW_MEMORY_GROWTH && MAXIMUM_MEMORY != -1 -var wasmMaximumMemory = {{{ MAXIMUM_MEMORY >>> 16 }}}; -#else -var wasmMaximumMemory = {{{ INITIAL_MEMORY >>> 16}}}; -#endif - -var wasmMemory = new WebAssembly.Memory({ - 'initial': {{{ INITIAL_MEMORY >>> 16 }}} -#if USE_PTHREADS || !ALLOW_MEMORY_GROWTH || MAXIMUM_MEMORY != -1 - , 'maximum': wasmMaximumMemory -#endif -#if USE_PTHREADS - , 'shared': true -#endif - }); - -var wasmTable; -var buffer = wasmMemory.buffer; - -#if USE_PTHREADS -} -#if ASSERTIONS -assert(buffer instanceof SharedArrayBuffer, 'requested a shared WebAssembly.Memory but the returned buffer is not a SharedArrayBuffer, indicating that while the browser has SharedArrayBuffer it does not have WebAssembly threads support - you may need to set a flag'); -#endif -#endif - -#if ASSERTIONS -#if USE_PTHREADS -if (!ENVIRONMENT_IS_PTHREAD) { -#endif -assert(buffer.byteLength === {{{ INITIAL_MEMORY }}}); -#if USE_PTHREADS -} -#endif -#endif // ASSERTIONS - -#if ALLOW_MEMORY_GROWTH -// In ALLOW_MEMORY_GROWTH, we need to be able to re-initialize the -// typed array buffer and heap views to the buffer whenever the heap -// is resized. var HEAP8, HEAP16, HEAP32, HEAPU8, HEAPU16, HEAPU32, HEAPF32, HEAPF64; +var wasmMemory, buffer, wasmTable; + function updateGlobalBufferAndViews(b) { +#if ASSERTIONS && USE_PTHREADS + assert(b instanceof SharedArrayBuffer, 'requested a shared WebAssembly.Memory but the returned buffer is not a SharedArrayBuffer, indicating that while the browser has SharedArrayBuffer it does not have WebAssembly threads support - you may need to set a flag'); +#endif buffer = b; HEAP8 = new Int8Array(b); HEAP16 = new Int16Array(b); @@ -111,33 +72,33 @@ function updateGlobalBufferAndViews(b) { HEAPF32 = new Float32Array(b); HEAPF64 = new Float64Array(b); } -updateGlobalBufferAndViews(buffer); -#else -// In non-ALLOW_MEMORY_GROWTH scenario, we only need to initialize -// the heap once, so optimize code size to do it statically here. -var HEAP8 = new Int8Array(buffer); -var HEAP16 = new Int16Array(buffer); -var HEAP32 = new Int32Array(buffer); -var HEAPU8 = new Uint8Array(buffer); -var HEAPU16 = new Uint16Array(buffer); -var HEAPU32 = new Uint32Array(buffer); -var HEAPF32 = new Float32Array(buffer); -var HEAPF64 = new Float64Array(buffer); -#endif -#if USE_PTHREADS && ((MEM_INIT_METHOD == 1 && !MEM_INIT_IN_WASM && !SINGLE_FILE) || USES_DYNAMIC_ALLOC) +#if USE_PTHREADS if (!ENVIRONMENT_IS_PTHREAD) { +#if ALLOW_MEMORY_GROWTH && MAXIMUM_MEMORY != -1 + var wasmMaximumMemory = {{{ MAXIMUM_MEMORY >>> 16 }}}; +#else + var wasmMaximumMemory = {{{ INITIAL_MEMORY >>> 16}}}; #endif - -#if MEM_INIT_METHOD == 1 && !MEM_INIT_IN_WASM && !SINGLE_FILE -#if ASSERTIONS -if (!Module['mem']) throw 'Must load memory initializer as an ArrayBuffer in to variable Module.mem before adding compiled output .js script to the DOM'; -#endif -HEAPU8.set(new Uint8Array(Module['mem']), {{{ GLOBAL_BASE }}}); + wasmMemory = new WebAssembly.Memory({ + 'initial': {{{ INITIAL_MEMORY >>> 16 }}} +#if USE_PTHREADS || !ALLOW_MEMORY_GROWTH || MAXIMUM_MEMORY != -1 + , 'maximum': wasmMaximumMemory #endif + , 'shared': true + }); +} -#if USE_PTHREADS && ((MEM_INIT_METHOD == 1 && !MEM_INIT_IN_WASM && !SINGLE_FILE) || USES_DYNAMIC_ALLOC) +#if MODULARIZE +if (ENVIRONMENT_IS_WORKER) { + updateGlobalBufferAndViews({{{EXPORT_NAME}}}.buffer); +} else { + updateGlobalBufferAndViews(wasmMemory.buffer); } +#else +updateGlobalBufferAndViews(wasmMemory.buffer); +#endif + #endif #include "runtime_stack_check.js" diff --git a/src/settings_internal.js b/src/settings_internal.js index e77e6ef0b9610..a48bc5a8a0300 100644 --- a/src/settings_internal.js +++ b/src/settings_internal.js @@ -187,3 +187,9 @@ var STRUCT_INFO = ''; var MEMORYPROFILER = 0; var GENERATE_SOURCE_MAP = 0; + +// By default we set this to 0 meaning the wasm file does not defined its own +// memory and instead the memory is defined in JavaScript. +// This is set 1 in STANDALONE_WASM or MINIMAL_RUNTIME mode in which case +// the wasm module exports its memory to JavaScript. +var MEMORY_DEFINED_IN_WASM = 0; diff --git a/src/shell_minimal.js b/src/shell_minimal.js index 2f3597ea712f5..8c1c15c92013e 100644 --- a/src/shell_minimal.js +++ b/src/shell_minimal.js @@ -140,12 +140,6 @@ var _scriptDir = (typeof document !== 'undefined' && document.currentScript) ? d // coincide. var ENVIRONMENT_IS_WORKER = ENVIRONMENT_IS_PTHREAD = typeof importScripts === 'function'; -#if MODULARIZE -if (ENVIRONMENT_IS_WORKER) { - var buffer = {{{EXPORT_NAME}}}.buffer; -} -#endif - var currentScriptUrl = typeof _scriptDir !== 'undefined' ? _scriptDir : ((typeof document !== 'undefined' && document.currentScript) ? document.currentScript.src : undefined); #endif // USE_PTHREADS diff --git a/system/lib/pthread/library_pthread.c b/system/lib/pthread/library_pthread.c index 447aff8ddbc35..d9ea9e648c43b 100644 --- a/system/lib/pthread/library_pthread.c +++ b/system/lib/pthread/library_pthread.c @@ -440,7 +440,7 @@ EMSCRIPTEN_RESULT emscripten_wait_for_call_i( return res; } -static pthread_t main_browser_thread_id_ = 0; +static pthread_t main_browser_thread_id_; void EMSCRIPTEN_KEEPALIVE emscripten_register_main_browser_thread_id( pthread_t main_browser_thread_id) { @@ -448,6 +448,7 @@ void EMSCRIPTEN_KEEPALIVE emscripten_register_main_browser_thread_id( } pthread_t EMSCRIPTEN_KEEPALIVE emscripten_main_browser_thread_id() { + assert(main_browser_thread_id_); return main_browser_thread_id_; } diff --git a/tests/code_size/hello_webgl2_wasm.json b/tests/code_size/hello_webgl2_wasm.json index 75721e160888f..effc582b06353 100644 --- a/tests/code_size/hello_webgl2_wasm.json +++ b/tests/code_size/hello_webgl2_wasm.json @@ -1,10 +1,10 @@ { "a.html": 563, "a.html.gz": 377, - "a.js": 4957, - "a.js.gz": 2373, - "a.wasm": 10893, - "a.wasm.gz": 6929, - "total": 16413, - "total_gz": 9679 + "a.js": 4927, + "a.js.gz": 2352, + "a.wasm": 10895, + "a.wasm.gz": 6927, + "total": 16385, + "total_gz": 9656 } diff --git a/tests/code_size/hello_webgl2_wasm2js.json b/tests/code_size/hello_webgl2_wasm2js.json index 44382f5c308eb..3e7cef7348cd5 100644 --- a/tests/code_size/hello_webgl2_wasm2js.json +++ b/tests/code_size/hello_webgl2_wasm2js.json @@ -1,10 +1,10 @@ { "a.html": 588, "a.html.gz": 386, - "a.js": 21297, - "a.js.gz": 8265, + "a.js": 21310, + "a.js.gz": 8280, "a.mem": 3171, "a.mem.gz": 2715, - "total": 25056, - "total_gz": 11366 + "total": 25069, + "total_gz": 11381 } diff --git a/tests/code_size/hello_webgl_wasm.json b/tests/code_size/hello_webgl_wasm.json index 0a0d2ffb13350..31d1e7bc552b0 100644 --- a/tests/code_size/hello_webgl_wasm.json +++ b/tests/code_size/hello_webgl_wasm.json @@ -1,10 +1,10 @@ { "a.html": 563, "a.html.gz": 377, - "a.js": 4444, - "a.js.gz": 2199, - "a.wasm": 10893, - "a.wasm.gz": 6929, - "total": 15900, - "total_gz": 9505 + "a.js": 4410, + "a.js.gz": 2172, + "a.wasm": 10895, + "a.wasm.gz": 6927, + "total": 15868, + "total_gz": 9476 } diff --git a/tests/code_size/hello_webgl_wasm2js.json b/tests/code_size/hello_webgl_wasm2js.json index af03a30e00692..c2389a3ce2312 100644 --- a/tests/code_size/hello_webgl_wasm2js.json +++ b/tests/code_size/hello_webgl_wasm2js.json @@ -1,10 +1,10 @@ { "a.html": 588, "a.html.gz": 386, - "a.js": 20785, - "a.js.gz": 8104, + "a.js": 20794, + "a.js.gz": 8109, "a.mem": 3171, "a.mem.gz": 2715, - "total": 24544, - "total_gz": 11205 + "total": 24553, + "total_gz": 11210 } diff --git a/tests/code_size/hello_world_wasm.json b/tests/code_size/hello_world_wasm.json index 7455f348db944..11563a524b990 100644 --- a/tests/code_size/hello_world_wasm.json +++ b/tests/code_size/hello_world_wasm.json @@ -1,10 +1,10 @@ { "a.html": 665, "a.html.gz": 427, - "a.js": 360, - "a.js.gz": 281, - "a.wasm": 102, - "a.wasm.gz": 114, - "total": 1127, - "total_gz": 822 + "a.js": 322, + "a.js.gz": 259, + "a.wasm": 104, + "a.wasm.gz": 112, + "total": 1091, + "total_gz": 798 } diff --git a/tests/code_size/hello_world_wasm2js.json b/tests/code_size/hello_world_wasm2js.json index dcd139ec5cead..33c37785fbbbc 100644 --- a/tests/code_size/hello_world_wasm2js.json +++ b/tests/code_size/hello_world_wasm2js.json @@ -1,10 +1,10 @@ { "a.html": 697, "a.html.gz": 437, - "a.js": 861, - "a.js.gz": 501, + "a.js": 1131, + "a.js.gz": 605, "a.mem": 6, "a.mem.gz": 32, - "total": 1564, - "total_gz": 970 + "total": 1834, + "total_gz": 1074 } diff --git a/tests/code_size/random_printf_wasm.json b/tests/code_size/random_printf_wasm.json index ad5c2bb6c1b7e..32840512adbfa 100644 --- a/tests/code_size/random_printf_wasm.json +++ b/tests/code_size/random_printf_wasm.json @@ -1,6 +1,6 @@ { - "a.html": 13665, - "a.html.gz": 7313, - "total": 13665, - "total_gz": 7313 + "a.html": 13742, + "a.html.gz": 7291, + "total": 13742, + "total_gz": 7291 } diff --git a/tests/code_size/random_printf_wasm2js.json b/tests/code_size/random_printf_wasm2js.json index 596720dae9d00..2a05677eebd5e 100644 --- a/tests/code_size/random_printf_wasm2js.json +++ b/tests/code_size/random_printf_wasm2js.json @@ -1,6 +1,6 @@ { - "a.html": 18857, - "a.html.gz": 7904, - "total": 18857, - "total_gz": 7904 + "a.html": 18972, + "a.html.gz": 7942, + "total": 18972, + "total_gz": 7942 } diff --git a/tests/other/metadce/minimal_Os_MINIMAL_RUNTIME.exports b/tests/other/metadce/minimal_Os_MINIMAL_RUNTIME.exports index de980441c3ab0..d68dd4031d2ad 100644 --- a/tests/other/metadce/minimal_Os_MINIMAL_RUNTIME.exports +++ b/tests/other/metadce/minimal_Os_MINIMAL_RUNTIME.exports @@ -1,3 +1,4 @@ a b c +d diff --git a/tests/other/metadce/minimal_Os_MINIMAL_RUNTIME.sent b/tests/other/metadce/minimal_Os_MINIMAL_RUNTIME.sent index 2142c3ad3ce3e..8b137891791fe 100644 --- a/tests/other/metadce/minimal_Os_MINIMAL_RUNTIME.sent +++ b/tests/other/metadce/minimal_Os_MINIMAL_RUNTIME.sent @@ -1 +1 @@ -memory + diff --git a/tests/test_other.py b/tests/test_other.py index 88a1e4edc1033..d8d4e1567a8da 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -6721,7 +6721,7 @@ def strip_numeric_suffixes(funcname): 'O3': (['-O3'], [], [], 62), # noqa 'Os': (['-Os'], [], [], 62), # noqa 'Oz': (['-Oz'], [], [], 62), # noqa - 'Os_mr': (['-Os', '-s', 'MINIMAL_RUNTIME'], [], [], 62), # noqa + 'Os_mr': (['-Os', '-s', 'MINIMAL_RUNTIME'], [], [], 74), # noqa }) def test_metadce_minimal(self, *args): self.run_metadce_test('minimal.c', *args) diff --git a/tools/building.py b/tools/building.py index d8428df17523c..a65b4943056ec 100644 --- a/tools/building.py +++ b/tools/building.py @@ -478,10 +478,7 @@ def lld_flags_for_executable(external_symbol_list): else: cmd.append('--allow-undefined') - # wasi does not import the memory (but for JS it is efficient to do so, - # as it allows us to set up memory, preload files, etc. even before the - # wasm module arrives) - if not Settings.STANDALONE_WASM: + if not Settings.MEMORY_DEFINED_IN_WASM: cmd.append('--import-memory') if Settings.USE_PTHREADS: