From 787cdde2bc9e0bc057a80671953aeb2035adcb8e Mon Sep 17 00:00:00 2001 From: Wouter van Oortmerssen Date: Mon, 4 Oct 2021 16:14:43 -0700 Subject: [PATCH] [Memory64] preamble JS changes for 64-bit --- src/preamble.js | 56 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/src/preamble.js b/src/preamble.js index db2756caf7e8f..44557262e6592 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -263,8 +263,10 @@ var HEAP_DATA_VIEW; #endif #if WASM_BIGINT -var HEAP64; -var HEAPU64; +/** @type {BigInt64Array} */ +var HEAP64, +/** @type {BigUint64Array} */ + HEAPU64; #endif #if USE_PTHREADS @@ -736,6 +738,7 @@ function instrumentWasmTableWithAbort() { var realGet = wasmTable.get; var wrapperCache = {}; wasmTable.get = function(i) { + {{{ from64('i') }}} var func = realGet.call(wasmTable, i); var cached = wrapperCache[i]; if (!cached || cached.func !== func) { @@ -749,6 +752,51 @@ function instrumentWasmTableWithAbort() { } #endif +#if MEMORY64 +// In memory64 mode wasm pointers are 64-bit. To support that in JS we must use +// BigInts. For now we keep JS as much the same as it always was, that is, +// stackAlloc() receives and returns a Number from the JS point of view - +// we translate BigInts automatically for that. +// TODO: support minified export names +function instrumentWasmExportsForMemory64(exports) { + var instExports = {}; + for (var name in exports) { + (function(name) { + var original = exports[name]; + var replacement = original; + if (name === 'stackAlloc' || name === 'malloc') { + // get one i64, return an i64 + replacement = function(x) { + var r = Number(original(BigInt(x))); + return r; + }; + } else if (name === 'free') { + // get one i64 + replacement = function(x) { + original(BigInt(x)); + }; + } else if (name === 'emscripten_stack_get_end' || + name === 'emscripten_stack_get_base' || + name === 'emscripten_stack_get_current') { + // return an i64 + replacement = function() { + var r = Number(original()); + return r; + }; + } else if (name === 'main') { + // get a i64 as second arg + replacement = function(x, y) { + var r = original(x, BigInt(y)); + return r; + }; + } + instExports[name] = replacement; + })(name); + } + return instExports; +} +#endif MEMORY64 + var wasmBinaryFile; #if EXPORT_ES6 && USE_ES6_IMPORT_META && !SINGLE_FILE if (Module['locateFile']) { @@ -968,6 +1016,10 @@ function createWasm() { exports = relocateExports(exports, {{{ GLOBAL_BASE }}}); #endif +#if MEMORY64 + exports = instrumentWasmExportsForMemory64(exports); +#endif + #if ASYNCIFY exports = Asyncify.instrumentWasmExports(exports); #endif