Skip to content

Commit a7d7a69

Browse files
committed
Create memory in wasm binaryn by default
There are some cases where we want to create the memory in JS but for most programs exporting the memory from wasm makes more sense and is more compact and reliable. The new EXTERNAL_MEMORY setting can be used to override this behaviour.
1 parent 59aedd4 commit a7d7a69

File tree

75 files changed

+177
-180
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+177
-180
lines changed

emcc.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,6 +1739,9 @@ def include_and_export(name):
17391739
# requires JS legalization
17401740
shared.Settings.LEGALIZE_JS_FFI = 0
17411741

1742+
if shared.Settings.USE_PTHREADS or shared.Settings.RELOCATABLE or shared.Settings.ASYNCIFY_LAZY_LOAD_CODE:
1743+
shared.Settings.EXTERNAL_MEMORY = 1
1744+
17421745
if shared.Settings.WASM_BIGINT:
17431746
shared.Settings.LEGALIZE_JS_FFI = 0
17441747

emscripten.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -536,10 +536,7 @@ def create_em_js(forwarded_json, metadata):
536536

537537

538538
def add_standard_wasm_imports(send_items_map):
539-
# Normally we import these into the wasm (so that JS could use them even
540-
# before the wasm loads), while in standalone mode we do not depend
541-
# on JS to create them, but create them in the wasm and export them.
542-
if not shared.Settings.STANDALONE_WASM:
539+
if shared.Settings.EXTERNAL_MEMORY:
543540
memory_import = 'wasmMemory'
544541
if shared.Settings.MODULARIZE and shared.Settings.USE_PTHREADS:
545542
# Pthreads assign wasmMemory in their worker startup. In MODULARIZE mode, they cannot assign inside the

src/postamble.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@
88

99
{{{ exportRuntime() }}}
1010

11-
#if MEM_INIT_IN_WASM == 0
11+
#if !MEM_INIT_IN_WASM
12+
function runMemoryInitializer() {
1213
#if USE_PTHREADS
13-
if (memoryInitializer && !ENVIRONMENT_IS_PTHREAD) {
14+
if (!memoryInitializer || ENVIRONMENT_IS_PTHREAD) return;
1415
#else
15-
if (memoryInitializer) {
16+
if (!memoryInitializer) return
1617
#endif
1718
if (!isDataURI(memoryInitializer)) {
1819
memoryInitializer = locateFile(memoryInitializer);

src/postamble_minimal.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,25 @@ WebAssembly.instantiate(Module['wasm'], imports).then(function(output) {
204204
/*** ASM_MODULE_EXPORTS ***/
205205
#endif
206206
wasmTable = asm['__indirect_function_table'];
207+
#if ASSERTIONS
208+
assert(wasmTable);
209+
#endif
210+
211+
#if !EXTERNAL_MEMORY
212+
wasmMemory = asm['memory'];
213+
#if ASSERTIONS
214+
assert(wasmMemory);
215+
assert(wasmMemory.buffer.byteLength === {{{ INITIAL_MEMORY }}});
216+
#endif
217+
updateGlobalBufferAndViews(wasmMemory.buffer);
218+
#endif
219+
220+
#if MEM_INIT_METHOD == 1 && !MEM_INIT_IN_WASM && !SINGLE_FILE
221+
#if ASSERTIONS
222+
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';
223+
#endif
224+
HEAPU8.set(new Uint8Array(Module['mem']), {{{ GLOBAL_BASE }}});
225+
#endif
207226

208227
initRuntime(asm);
209228
#if USE_PTHREADS && PTHREAD_POOL_SIZE

src/preamble.js

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -325,15 +325,16 @@ if (typeof SharedArrayBuffer === 'undefined' || typeof Atomics === 'undefined')
325325
#endif
326326
#endif
327327

328-
#if STANDALONE_WASM
329-
#if ASSERTIONS
330-
// In standalone mode, the wasm creates the memory, and the user can't provide it.
331-
assert(!Module['wasmMemory']);
332-
#endif // ASSERTIONS
333-
#else // !STANDALONE_WASM
328+
#if EXTERNAL_MEMORY
334329
// In non-standalone/normal mode, we create the memory here.
335330
#include "runtime_init_memory.js"
336-
#endif // !STANDALONE_WASM
331+
#else // EXTERNAL_MEMORY
332+
#if ASSERTIONS
333+
// If memory is defined in wasm, the user can't provide it.
334+
assert(!Module['wasmMemory'], 'Use of `wasmMemory` detected. Use -s EXTERNAL_MEMORY to define wasmMemory externally');
335+
assert(INITIAL_MEMORY == {{{INITIAL_MEMORY}}}, 'Detected runtime INITIAL_MEMORY setting. Use -s EXTERNAL_MEMORY to define wasmMemory dynamically');
336+
#endif // ASSERTIONS
337+
#endif // EXTERNAL_MEMORY
337338

338339
#include "runtime_init_table.js"
339340
#include "runtime_stack_check.js"
@@ -833,6 +834,18 @@ function createWasm() {
833834

834835
Module['asm'] = exports;
835836

837+
#if !EXTERNAL_MEMORY
838+
wasmMemory = Module['asm']['memory'];
839+
#if ASSERTIONS
840+
assert(wasmMemory);
841+
assert(wasmMemory.buffer.byteLength === {{{ INITIAL_MEMORY }}});
842+
#endif
843+
updateGlobalBufferAndViews(wasmMemory.buffer);
844+
#endif
845+
#if !MEM_INIT_IN_WASM
846+
runMemoryInitializer();
847+
#endif
848+
836849
#if !RELOCATABLE
837850
wasmTable = Module['asm']['__indirect_function_table'];
838851
#if ASSERTIONS && !PURE_WASI

src/preamble_minimal.js

Lines changed: 25 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -55,52 +55,13 @@ Module['wasm'] = base64Decode('{{{ getQuoted("WASM_BINARY_DATA") }}}');
5555
#include "runtime_functions.js"
5656
#include "runtime_strings.js"
5757

58-
#if USE_PTHREADS
59-
if (!ENVIRONMENT_IS_PTHREAD) {
60-
#endif
61-
62-
#if ALLOW_MEMORY_GROWTH && MAXIMUM_MEMORY != -1
63-
var wasmMaximumMemory = {{{ MAXIMUM_MEMORY >>> 16 }}};
64-
#else
65-
var wasmMaximumMemory = {{{ INITIAL_MEMORY >>> 16}}};
66-
#endif
67-
68-
var wasmMemory = new WebAssembly.Memory({
69-
'initial': {{{ INITIAL_MEMORY >>> 16 }}}
70-
#if USE_PTHREADS || !ALLOW_MEMORY_GROWTH || MAXIMUM_MEMORY != -1
71-
, 'maximum': wasmMaximumMemory
72-
#endif
73-
#if USE_PTHREADS
74-
, 'shared': true
75-
#endif
76-
});
77-
78-
var wasmTable;
79-
var buffer = wasmMemory.buffer;
80-
81-
#if USE_PTHREADS
82-
}
83-
#if ASSERTIONS
84-
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');
85-
#endif
86-
#endif
87-
88-
#if ASSERTIONS
89-
#if USE_PTHREADS
90-
if (!ENVIRONMENT_IS_PTHREAD) {
91-
#endif
92-
assert(buffer.byteLength === {{{ INITIAL_MEMORY }}});
93-
#if USE_PTHREADS
94-
}
95-
#endif
96-
#endif // ASSERTIONS
97-
98-
#if ALLOW_MEMORY_GROWTH
99-
// In ALLOW_MEMORY_GROWTH, we need to be able to re-initialize the
100-
// typed array buffer and heap views to the buffer whenever the heap
101-
// is resized.
10258
var HEAP8, HEAP16, HEAP32, HEAPU8, HEAPU16, HEAPU32, HEAPF32, HEAPF64;
59+
var wasmMemory, buffer, wasmTable;
60+
10361
function updateGlobalBufferAndViews(b) {
62+
#if ASSERTIONS && USE_PTHREADS
63+
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');
64+
#endif
10465
buffer = b;
10566
HEAP8 = new Int8Array(b);
10667
HEAP16 = new Int16Array(b);
@@ -111,34 +72,33 @@ function updateGlobalBufferAndViews(b) {
11172
HEAPF32 = new Float32Array(b);
11273
HEAPF64 = new Float64Array(b);
11374
}
114-
updateGlobalBufferAndViews(buffer);
115-
#else
116-
// In non-ALLOW_MEMORY_GROWTH scenario, we only need to initialize
117-
// the heap once, so optimize code size to do it statically here.
118-
var HEAP8 = new Int8Array(buffer);
119-
var HEAP16 = new Int16Array(buffer);
120-
var HEAP32 = new Int32Array(buffer);
121-
var HEAPU8 = new Uint8Array(buffer);
122-
var HEAPU16 = new Uint16Array(buffer);
123-
var HEAPU32 = new Uint32Array(buffer);
124-
var HEAPF32 = new Float32Array(buffer);
125-
var HEAPF64 = new Float64Array(buffer);
126-
#endif
12775

128-
#if USE_PTHREADS && ((MEM_INIT_METHOD == 1 && !MEM_INIT_IN_WASM && !SINGLE_FILE) || USES_DYNAMIC_ALLOC)
76+
#if EXTERNAL_MEMORY
12977
if (!ENVIRONMENT_IS_PTHREAD) {
78+
#if ALLOW_MEMORY_GROWTH && MAXIMUM_MEMORY != -1
79+
var wasmMaximumMemory = {{{ MAXIMUM_MEMORY >>> 16 }}};
80+
#else
81+
var wasmMaximumMemory = {{{ INITIAL_MEMORY >>> 16}}};
13082
#endif
131-
132-
#if MEM_INIT_METHOD == 1 && !MEM_INIT_IN_WASM && !SINGLE_FILE
133-
#if ASSERTIONS
134-
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';
135-
#endif
136-
HEAPU8.set(new Uint8Array(Module['mem']), {{{ GLOBAL_BASE }}});
83+
wasmMemory = new WebAssembly.Memory({
84+
'initial': {{{ INITIAL_MEMORY >>> 16 }}}
85+
#if USE_PTHREADS || !ALLOW_MEMORY_GROWTH || MAXIMUM_MEMORY != -1
86+
, 'maximum': wasmMaximumMemory
13787
#endif
88+
, 'shared': true
89+
});
90+
}
13891

139-
#if USE_PTHREADS && ((MEM_INIT_METHOD == 1 && !MEM_INIT_IN_WASM && !SINGLE_FILE) || USES_DYNAMIC_ALLOC)
92+
#if MODULARIZE
93+
if (ENVIRONMENT_IS_WORKER) {
94+
updateGlobalBufferAndViews({{{EXPORT_NAME}}}.buffer);
95+
} else {
96+
updateGlobalBufferAndViews(wasmMemory.buffer);
14097
}
98+
#else
99+
updateGlobalBufferAndViews(wasmMemory.buffer);
141100
#endif
101+
#endif // EXTERNAL_MEMORY
142102

143103
#include "runtime_stack_check.js"
144104
#include "runtime_assertions.js"

src/runtime_init_memory.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44
* SPDX-License-Identifier: MIT
55
*/
66

7-
// Create the main memory. (Note: this isn't used in STANDALONE_WASM mode since the wasm
8-
// memory is created in the wasm, not in JS.)
7+
// Create the wasm memory. (Note: this only applies if EXTERNAL_MEMORY is defined)
8+
#if !EXTERNAL_MEMORY
9+
assert(false, "should be be included when EXTERNAL_MEMORY is set");
10+
#endif
11+
912
#if USE_PTHREADS
1013
if (ENVIRONMENT_IS_PTHREAD) {
1114
wasmMemory = Module['wasmMemory'];

src/settings.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,6 +1630,16 @@ var ABORT_ON_WASM_EXCEPTIONS = 0;
16301630
// Implies STANDALONE_WASM.
16311631
var PURE_WASI = 0;
16321632

1633+
// Set to 1 to define the WebAssembly.Memory object outside of the wasm
1634+
// module. By default the wasm module defines the memory and exports
1635+
// it to JavaScript.
1636+
// Use of the following settings will enable this settings since they
1637+
// depend on being able to define the memory in JavaScript:
1638+
// - USE_PTHREADS
1639+
// - RELOCATABLE
1640+
// - ASYNCIFY_LAZY_LOAD_CODE
1641+
var EXTERNAL_MEMORY = 0;
1642+
16331643
//===========================================
16341644
// Internal, used for testing only, from here
16351645
//===========================================

src/shell_minimal.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,6 @@ var _scriptDir = (typeof document !== 'undefined' && document.currentScript) ? d
140140
// coincide.
141141
var ENVIRONMENT_IS_WORKER = ENVIRONMENT_IS_PTHREAD = typeof importScripts === 'function';
142142

143-
#if MODULARIZE
144-
if (ENVIRONMENT_IS_WORKER) {
145-
var buffer = {{{EXPORT_NAME}}}.buffer;
146-
}
147-
#endif
148-
149143
var currentScriptUrl = typeof _scriptDir !== 'undefined' ? _scriptDir : ((typeof document !== 'undefined' && document.currentScript) ? document.currentScript.src : undefined);
150144
#endif // USE_PTHREADS
151145

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"a.html": 563,
33
"a.html.gz": 377,
4-
"a.js": 4957,
5-
"a.js.gz": 2373,
6-
"a.wasm": 10893,
7-
"a.wasm.gz": 6923,
8-
"total": 16413,
9-
"total_gz": 9673
4+
"a.js": 4927,
5+
"a.js.gz": 2352,
6+
"a.wasm": 10895,
7+
"a.wasm.gz": 6927,
8+
"total": 16385,
9+
"total_gz": 9656
1010
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"a.html": 588,
33
"a.html.gz": 386,
4-
"a.js": 21297,
5-
"a.js.gz": 8263,
4+
"a.js": 21310,
5+
"a.js.gz": 8280,
66
"a.mem": 3171,
77
"a.mem.gz": 2715,
8-
"total": 25056,
9-
"total_gz": 11364
8+
"total": 25069,
9+
"total_gz": 11381
1010
}

tests/code_size/hello_webgl_wasm.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"a.html": 563,
33
"a.html.gz": 377,
4-
"a.js": 4444,
5-
"a.js.gz": 2199,
6-
"a.wasm": 10893,
7-
"a.wasm.gz": 6923,
8-
"total": 15900,
9-
"total_gz": 9499
4+
"a.js": 4410,
5+
"a.js.gz": 2172,
6+
"a.wasm": 10895,
7+
"a.wasm.gz": 6927,
8+
"total": 15868,
9+
"total_gz": 9476
1010
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"a.html": 588,
33
"a.html.gz": 386,
4-
"a.js": 20785,
5-
"a.js.gz": 8102,
4+
"a.js": 20794,
5+
"a.js.gz": 8109,
66
"a.mem": 3171,
77
"a.mem.gz": 2715,
8-
"total": 24544,
9-
"total_gz": 11203
8+
"total": 24553,
9+
"total_gz": 11210
1010
}

tests/code_size/hello_world_wasm.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"a.html": 665,
33
"a.html.gz": 427,
4-
"a.js": 360,
5-
"a.js.gz": 281,
6-
"a.wasm": 102,
7-
"a.wasm.gz": 114,
8-
"total": 1127,
9-
"total_gz": 822
4+
"a.js": 322,
5+
"a.js.gz": 259,
6+
"a.wasm": 104,
7+
"a.wasm.gz": 112,
8+
"total": 1091,
9+
"total_gz": 798
1010
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
22
"a.html": 697,
33
"a.html.gz": 437,
4-
"a.js": 865,
5-
"a.js.gz": 503,
4+
"a.js": 1131,
5+
"a.js.gz": 605,
66
"a.mem": 6,
77
"a.mem.gz": 32,
8-
"total": 1568,
9-
"total_gz": 972
8+
"total": 1834,
9+
"total_gz": 1074
1010
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"a.html": 13665,
3-
"a.html.gz": 7286,
4-
"total": 13665,
5-
"total_gz": 7286
2+
"a.html": 13742,
3+
"a.html.gz": 7291,
4+
"total": 13742,
5+
"total_gz": 7291
66
}
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"a.html": 18844,
3-
"a.html.gz": 7893,
4-
"total": 18844,
5-
"total_gz": 7893
2+
"a.html": 18972,
3+
"a.html.gz": 7942,
4+
"total": 18972,
5+
"total_gz": 7942
66
}

tests/other/metadce/hello_libcxx_O2.exports

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ dynCall_iiiiijj
77
dynCall_jiji
88
dynCall_viijii
99
main
10+
memory
1011
stackAlloc
1112
stackRestore
1213
stackSave

tests/other/metadce/hello_libcxx_O2.imports

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
env.abort
22
env.emscripten_memcpy_big
33
env.emscripten_resize_heap
4-
env.memory
54
env.setTempRet0
65
env.strftime_l
76
wasi_snapshot_preview1.environ_get

0 commit comments

Comments
 (0)