Skip to content

Commit 9ba43ae

Browse files
committed
[wasm64] Fix for bad Memory initial size under firefox
Recent versions of firefox started requiring bigint values for initial and max memory. See WebAssembly/memory64#68 Fixes: #22486
1 parent a7f5361 commit 9ba43ae

File tree

6 files changed

+45
-21
lines changed

6 files changed

+45
-21
lines changed

.circleci/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,6 +850,7 @@ jobs:
850850
# further blocked by issue #6897.
851851
test_targets: "
852852
browser64.test_sdl_image
853+
browser64.test_dylink_many
853854
browser
854855
skip:browser.test_sdl2_mouse
855856
skip:browser.test_html5_webgl_create_context

src/library.js

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,41 +1966,38 @@ addToLibrary({
19661966
$setWasmTableEntry__internal: true,
19671967
$setWasmTableEntry__deps: ['$wasmTableMirror', '$wasmTable'],
19681968
$setWasmTableEntry: (idx, func) => {
1969-
wasmTable.set(idx, func);
1969+
wasmTable.set({{{ toIndexType('idx') }}}, func);
19701970
// With ABORT_ON_WASM_EXCEPTIONS wasmTable.get is overridden to return wrapped
19711971
// functions so we need to call it here to retrieve the potential wrapper correctly
19721972
// instead of just storing 'func' directly into wasmTableMirror
1973-
wasmTableMirror[idx] = wasmTable.get(idx);
1973+
wasmTableMirror[idx] = wasmTable.get({{{ toIndexType('idx') }}});
19741974
},
19751975

19761976
$getWasmTableEntry__internal: true,
19771977
$getWasmTableEntry__deps: ['$wasmTableMirror', '$wasmTable'],
19781978
$getWasmTableEntry: (funcPtr) => {
1979-
#if MEMORY64
1980-
// Function pointers are 64-bit, but wasmTable.get() requires a Number.
1981-
// https://github.com/emscripten-core/emscripten/issues/18200
1982-
funcPtr = Number(funcPtr);
1983-
#endif
1979+
// Pointers are expected to be JS numbers, even under wasm64
1980+
assert(typeof funcPtr == 'number');
19841981
var func = wasmTableMirror[funcPtr];
19851982
if (!func) {
19861983
if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1;
1987-
wasmTableMirror[funcPtr] = func = wasmTable.get(funcPtr);
1984+
wasmTableMirror[funcPtr] = func = wasmTable.get({{{ toIndexType('funcPtr') }}});
19881985
#if ASYNCIFY == 2
19891986
if (Asyncify.isAsyncExport(func)) {
19901987
wasmTableMirror[funcPtr] = func = Asyncify.makeAsyncFunction(func);
19911988
}
19921989
#endif
19931990
}
19941991
#if ASSERTIONS && ASYNCIFY != 2 // With JSPI the function stored in the table will be a wrapper.
1995-
assert(wasmTable.get(funcPtr) == func, 'JavaScript-side Wasm function table mirror is out of date!');
1992+
assert(wasmTable.get({{{ toIndexType('funcPtr') }}}) == func, 'JavaScript-side Wasm function table mirror is out of date!');
19961993
#endif
19971994
return func;
19981995
},
19991996

20001997
#else
20011998

20021999
$setWasmTableEntry__deps: ['$wasmTable'],
2003-
$setWasmTableEntry: (idx, func) => wasmTable.set(idx, func),
2000+
$setWasmTableEntry: (idx, func) => wasmTable.set({{{ toIndexType('idx') }}}, func),
20042001

20052002
$getWasmTableEntry__deps: ['$wasmTable'],
20062003
$getWasmTableEntry: (funcPtr) => {
@@ -2391,9 +2388,9 @@ addToLibrary({
23912388
#if RELOCATABLE
23922389
// In RELOCATABLE mode we create the table in JS.
23932390
$wasmTable: `=new WebAssembly.Table({
2394-
'initial': {{{ INITIAL_TABLE }}},
2391+
'initial': {{{ toIndexType(INITIAL_TABLE) }}},
23952392
#if !ALLOW_TABLE_GROWTH
2396-
'maximum': {{{ INITIAL_TABLE }}},
2393+
'maximum': {{{ toIndexType(INITIAL_TABLE) }}},
23972394
#endif
23982395
#if MEMORY64 == 1
23992396
'index': 'i64',

src/library_addfunction.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,14 +151,14 @@ addToLibrary({
151151
}
152152
// Grow the table
153153
try {
154-
wasmTable.grow(1);
154+
wasmTable.grow({{{ toIndexType('1') }}});
155155
} catch (err) {
156156
if (!(err instanceof RangeError)) {
157157
throw err;
158158
}
159159
throw 'Unable to grow wasm table. Set ALLOW_TABLE_GROWTH.';
160160
}
161-
return wasmTable.length - 1;
161+
return {{{ from64Expr('wasmTable.length') }}} - 1;
162162
},
163163

164164
$updateTableMap__deps: ['$getWasmTableEntry'],
@@ -179,7 +179,7 @@ addToLibrary({
179179
// First, create the map if this is the first use.
180180
if (!functionsInTableMap) {
181181
functionsInTableMap = new WeakMap();
182-
updateTableMap(0, wasmTable.length);
182+
updateTableMap(0, {{{ from64Expr('wasmTable.length') }}});
183183
}
184184
return functionsInTableMap.get(func) || 0;
185185
},

src/library_dylink.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -581,8 +581,9 @@ var LibraryDylink = {
581581
#if DYLINK_DEBUG
582582
$dumpTable__deps: ['$wasmTable'],
583583
$dumpTable: () => {
584-
for (var i = 0; i < wasmTable.length; i++)
585-
dbg(`table: ${i} : ${wasmTable.get(i)}`);
584+
var len = {{{ from64Expr('wasmTable.length') }}};
585+
for (var i = 0; i < len; i++)
586+
dbg(`table: ${i} : ${wasmTable.get({{{ to64(i) }}})}`);
586587
},
587588
#endif
588589

@@ -641,7 +642,7 @@ var LibraryDylink = {
641642
tableBase = {{{ makeGetValue('handle', C_STRUCTS.dso.table_addr, '*') }}};
642643
}
643644

644-
var tableGrowthNeeded = tableBase + metadata.tableSize - wasmTable.length;
645+
var tableGrowthNeeded = tableBase + metadata.tableSize - {{{ from64Expr('wasmTable.length') }}};
645646
if (tableGrowthNeeded > 0) {
646647
#if DYLINK_DEBUG
647648
dbg("loadModule: growing table: " + tableGrowthNeeded);

src/parseTools.mjs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,13 @@ function from64Expr(x, assign = true) {
963963
return `Number(${x})`;
964964
}
965965

966+
function toIndexType(val) {
967+
if (MEMORY64 == 1) {
968+
return `toIndexType(${val})`;
969+
}
970+
return val;
971+
}
972+
966973
function to64(x) {
967974
if (!MEMORY64) return x;
968975
return `BigInt(${x})`;
@@ -1153,4 +1160,5 @@ addToCompileTimeContext({
11531160
splitI64,
11541161
storeException,
11551162
to64,
1163+
toIndexType,
11561164
});

src/runtime_init_memory.js

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,23 @@
99
{{{ throw "this file should not be be included when IMPORTED_MEMORY is set"; }}}
1010
#endif
1111

12+
#if MEMORY64 == 1
13+
var toIndexType = (function() {
14+
// Probe for support of bigint bounds with memory64.
15+
// TODO(sbc): Remove this once all browsers start requiring bigint here.
16+
// See https://github.com/WebAssembly/memory64/issues/68
17+
var bigintMemoryBounds = 1;
18+
try {
19+
/** @suppress {checkTypes} */
20+
new WebAssembly.Memory({'initial': 1n, 'index': 'i64'})
21+
} catch (e) {
22+
console.log(e);
23+
bigintMemoryBounds = 0;
24+
}
25+
return (i) => bigintMemoryBounds ? BigInt(i) : i;
26+
})();
27+
#endif
28+
1229
// check for full engine support (use string 'subarray' to avoid closure compiler confusion)
1330

1431
#if PTHREADS
@@ -27,16 +44,16 @@ if (!ENVIRONMENT_IS_PTHREAD) {
2744
assert(INITIAL_MEMORY >= {{{STACK_SIZE}}}, 'INITIAL_MEMORY should be larger than STACK_SIZE, was ' + INITIAL_MEMORY + '! (STACK_SIZE=' + {{{STACK_SIZE}}} + ')');
2845
#endif
2946
wasmMemory = new WebAssembly.Memory({
30-
'initial': INITIAL_MEMORY / {{{ WASM_PAGE_SIZE }}},
47+
'initial': {{{ toIndexType(`INITIAL_MEMORY / ${WASM_PAGE_SIZE}`) }}},
3148
#if ALLOW_MEMORY_GROWTH
3249
// In theory we should not need to emit the maximum if we want "unlimited"
3350
// or 4GB of memory, but VMs error on that atm, see
3451
// https://github.com/emscripten-core/emscripten/issues/14130
3552
// And in the pthreads case we definitely need to emit a maximum. So
3653
// always emit one.
37-
'maximum': {{{ MAXIMUM_MEMORY }}} / {{{ WASM_PAGE_SIZE }}},
54+
'maximum': {{{ toIndexType(MAXIMUM_MEMORY / WASM_PAGE_SIZE) }}},
3855
#else
39-
'maximum': INITIAL_MEMORY / {{{ WASM_PAGE_SIZE }}},
56+
'maximum': {{{ toIndexType(`INITIAL_MEMORY / ${WASM_PAGE_SIZE}`) }}},
4057
#endif // ALLOW_MEMORY_GROWTH
4158
#if SHARED_MEMORY
4259
'shared': true,

0 commit comments

Comments
 (0)