Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ jobs:
executor: bionic
steps:
- run-tests-linux:
test_targets: "wasm64.test_hello_world wasm64.test_ccall wasm64l.test_hello_world wasm64l.test_mmap wasm64l.test_unistd_* skip:wasm64l.test_unistd_sysconf wasm64l.test_mmap_file wasm64l.test_ccall wasm64l.test_signals wasm64l.test_emscripten_get_compiler_setting wasm64l.test_float_builtins wasm64l.test_getopt wasm64l.test_em_asm*"
test_targets: "wasm64.test_hello_world wasm64.test_ccall wasm64l.test_hello_world wasm64l.test_mmap wasm64l.test_unistd_* skip:wasm64l.test_unistd_sysconf wasm64l.test_mmap_file wasm64l.test_ccall wasm64l.test_signals wasm64l.test_emscripten_get_compiler_setting wasm64l.test_float_builtins wasm64l.test_getopt wasm64l.test_em_asm* wasm64l.test_minimal_runtime_utf8_invalid"
test-other:
executor: bionic
steps:
Expand Down
1 change: 1 addition & 0 deletions embuilder.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
'libc++-noexcept',
'libal',
'libdlmalloc',
'libdlmalloc-noerrno',
'libdlmalloc-debug',
'libemmalloc',
'libemmalloc-debug',
Expand Down
4 changes: 4 additions & 0 deletions src/postamble_minimal.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ WebAssembly.instantiate(Module['wasm'], imports).then(function(output) {
asm = output.instance.exports;
#endif

#if MEMORY64
asm = instrumentWasmExportsForMemory64(asm);
#endif

#if USE_OFFSET_CONVERTER
#if USE_PTHREADS
if (!ENVIRONMENT_IS_PTHREAD)
Expand Down
56 changes: 4 additions & 52 deletions src/preamble.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ if (typeof WebAssembly != 'object') {
#include "runtime_asan.js"
#endif

#if MEMORY64
#include "runtime_wasm64.js"
#endif

// Wasm globals

var wasmMemory;
Expand Down Expand Up @@ -772,58 +776,6 @@ 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, so we can turn MINIFY_WASM_IMPORTS_AND_EXPORTS
// back on for MEMORY64.
function instrumentWasmExportsForMemory64(exports) {
var instExports = {};
for (var name in exports) {
(function(name) {
var original = exports[name];
var replacement = original;
if (name === 'stackAlloc' || name === 'malloc' || name === 'emscripten_builtin_malloc') {
// get one i64, return an i64
replacement = (x) => {
var r = Number(original(BigInt(x)));
return r;
};
} else if (name === 'free') {
// get one i64
replacement = (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 = () => {
var r = Number(original());
return r;
};
} else if (name === 'emscripten_builtin_memalign') {
// get two i64, return an i64
replacement = (x, y) => {
var r = Number(original(BigInt(x), BigInt(y)));
return r;
};
} else if (name === 'main') {
// get a i64 as second arg
replacement = (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']) {
Expand Down
4 changes: 4 additions & 0 deletions src/preamble_minimal.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
#include "runtime_asan.js"
#endif

#if MEMORY64
#include "runtime_wasm64.js"
#endif

#if ASSERTIONS || SAFE_HEAP
/** @type {function(*, string=)} */
function assert(condition, text) {
Expand Down
67 changes: 67 additions & 0 deletions src/runtime_wasm64.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* @license
* Copyright 2022 The Emscripten Authors
* SPDX-License-Identifier: MIT
*/

#if !MEMORY64
#error "should only be inclded in MEMORY64 mode"
#endif

// In memory64 mode wasm pointers are 64-bit. In JS these show up as 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, so we can turn
// MINIFY_WASM_IMPORTS_AND_EXPORTS back on for MEMORY64.
// TODO: Remove this hacky mechanism and replace with something more like the
// `__sig` attributes we have in JS library code.
function instrumentWasmExportsForMemory64(exports) {
var instExports = {};
for (var name in exports) {
(function(name) {
var original = exports[name];
var replacement = original;
if (['stackAlloc', 'emscripten_builtin_malloc', 'malloc', '__getTypeName'].includes(name)) {
// get one i64, return an i64.
replacement = (x) => {
var r = Number(original(BigInt(x)));
return r;
};
} else if (['setThrew', 'free', 'stackRestore', '__cxa_is_pointer_type'].includes(name)) {
// get one i64
replacement = (x) => {
original(BigInt(x));
};
} else if (['stackSave', 'emscripten_stack_get_end',
'emscripten_stack_get_base', 'pthread_self',
'emscripten_stack_get_current',
'__errno_location'].includes(name)) {
// return an i64
replacement = () => {
var r = Number(original());
return r;
};
} else if (name === 'emscripten_builtin_memalign') {
// get two i64, return an i64
replacement = (x, y) => {
var r = Number(original(BigInt(x), BigInt(y)));
return r;
};
} else if (name === 'main') {
// Special case for main. Use `function` here rather than arrow
// function to avoid implicit `strict`.
replacement = function(x, y) {
// Pass an extra 0 in case its a 3-argument form of main. Sadly we
// can't just omit that argument like we can for wasm32 because the
// missing third argument will generate:
// `TypeError: Cannot convert undefined to a BigInt`.
// See https://github.com/WebAssembly/JS-BigInt-integration/issues/12
return original(x, BigInt(y ? y : 0), BigInt(0));
};
}
instExports[name] = replacement;
})(name);
}
return instExports;
}