diff --git a/emcc.py b/emcc.py index 1134bce7f9c9c..1c155d7891fc5 100755 --- a/emcc.py +++ b/emcc.py @@ -2866,10 +2866,10 @@ def get_full_import_name(name): # check if we can address the 2GB mark and higher: either if we start at # 2GB, or if we allow growth to either any amount or to 2GB or more. - if settings.INITIAL_MEMORY > 2 * 1024 * 1024 * 1024 or \ + if not settings.MEMORY64 and (settings.INITIAL_MEMORY > 2 * 1024 * 1024 * 1024 or (settings.ALLOW_MEMORY_GROWTH and (settings.MAXIMUM_MEMORY < 0 or - settings.MAXIMUM_MEMORY > 2 * 1024 * 1024 * 1024)): + settings.MAXIMUM_MEMORY > 2 * 1024 * 1024 * 1024))): settings.CAN_ADDRESS_2GB = 1 settings.EMSCRIPTEN_VERSION = shared.EMSCRIPTEN_VERSION diff --git a/src/jsifier.js b/src/jsifier.js index e7f73395b3cd0..80ba7394550b8 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -128,7 +128,7 @@ function runJSify() { for (let i = 1; i < sig.length; i++) { const name = argNames[i - 1]; if (!name) { - error(`convertPointerParams: missing name for argument ${i} in ${symbol}`); + error(`handleI64Signatures: missing name for argument ${i} in ${symbol}`); return snippet; } if (WASM_BIGINT) { @@ -139,6 +139,9 @@ function runJSify() { if (sig[i] == 'j' && i53abi) { argConvertions += ` ${receiveI64ParamAsI53(name, undefined, false)}\n`; newArgs.push(defineI64Param(name)); + } else if (sig[i] == 'p' && CAN_ADDRESS_2GB) { + argConvertions += ` ${name} >>>= 0;\n`; + newArgs.push(name); } else { newArgs.push(name); } @@ -197,8 +200,8 @@ function(${args}) { const sig = LibraryManager.library[symbol + '__sig']; const i53abi = LibraryManager.library[symbol + '__i53abi']; - if (sig && ((i53abi && sig.includes('j')) || - (MEMORY64 && sig.includes('p')))) { + if (sig && + ((i53abi && sig.includes('j')) || ((MEMORY64 || CAN_ADDRESS_2GB) && sig.includes('p')))) { snippet = handleI64Signatures(symbol, snippet, sig, i53abi); i53ConversionDeps.forEach((d) => deps.push(d)) } diff --git a/src/library.js b/src/library.js index 57b729c55196b..f9e7aaab57cce 100644 --- a/src/library.js +++ b/src/library.js @@ -24,6 +24,10 @@ mergeInto(LibraryManager.library, { $ptrToString: (ptr) => { #if ASSERTIONS assert(typeof ptr === 'number'); +#endif +#if !CAN_ADDRESS_2GB && !MEMORY64 + // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned. + ptr >>>= 0; #endif return '0x' + ptr.toString(16).padStart(8, '0'); }, @@ -199,9 +203,6 @@ mergeInto(LibraryManager.library, { emscripten_resize_heap: 'ip', emscripten_resize_heap: (requestedSize) => { var oldSize = HEAPU8.length; -#if MEMORY64 != 1 - requestedSize = requestedSize >>> 0; -#endif #if ALLOW_MEMORY_GROWTH == 0 #if ABORTING_MALLOC abortOnCannotGrowMemory(requestedSize); @@ -211,6 +212,10 @@ mergeInto(LibraryManager.library, { #else // ALLOW_MEMORY_GROWTH == 0 // With multithreaded builds, races can happen (another thread might increase the size // in between), so return a failure, and let the caller retry. +#if !MEMORY64 && !CAN_ADDRESS_2GB + // With CAN_ADDRESS_2GB or MEMORY64, pointers are already unsigned. + requestedSize >>>= 0; +#endif #if SHARED_MEMORY if (requestedSize <= oldSize) { return false; @@ -3090,7 +3095,6 @@ mergeInto(LibraryManager.library, { // Used by wasm-emscripten-finalize to implement STACK_OVERFLOW_CHECK __handle_stack_overflow__deps: ['emscripten_stack_get_base', 'emscripten_stack_get_end', '$ptrToString'], __handle_stack_overflow: (requested) => { - requested = requested >>> 0; var base = _emscripten_stack_get_base(); var end = _emscripten_stack_get_end(); abort(`stack overflow (Attempt to set SP to ${ptrToString(requested)}` + @@ -3548,6 +3552,11 @@ mergeInto(LibraryManager.library, { #if hasExportedSymbol('emscripten_builtin_memalign') size = alignMemory(size, {{{ WASM_PAGE_SIZE }}}); var ptr = _emscripten_builtin_memalign({{{ WASM_PAGE_SIZE }}}, size); +#if CAN_ADDRESS_2GB + // TODO(sbc): Automate this unsigned convertion when we know that a call + // into wasm returns a pointer. + ptr >>>= 0; +#endif if (!ptr) return 0; return zeroMemory(ptr, size); #elif ASSERTIONS diff --git a/src/library_fs.js b/src/library_fs.js index da4a1e79bbb2b..55326f3734c6b 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -1132,9 +1132,6 @@ FS.staticInit();` + return stream.position; }, read: (stream, buffer, offset, length, position) => { -#if CAN_ADDRESS_2GB - offset >>>= 0; -#endif if (length < 0 || position < 0) { throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); } @@ -1166,9 +1163,6 @@ FS.staticInit();` + return bytesRead; }, write: (stream, buffer, offset, length, position, canOwn) => { -#if CAN_ADDRESS_2GB - offset >>>= 0; -#endif if (length < 0 || position < 0) { throw new FS.ErrnoError({{{ cDefs.EINVAL }}}); } @@ -1242,9 +1236,6 @@ FS.staticInit();` + return stream.stream_ops.mmap(stream, length, position, prot, flags); }, msync: (stream, buffer, offset, length, mmapFlags) => { -#if CAN_ADDRESS_2GB - offset >>>= 0; -#endif if (!stream.stream_ops.msync) { return 0; } diff --git a/src/library_memfs.js b/src/library_memfs.js index fc01deae05180..0a78a31773059 100644 --- a/src/library_memfs.js +++ b/src/library_memfs.js @@ -105,9 +105,6 @@ mergeInto(LibraryManager.library, { // May allocate more, to provide automatic geometric increase and amortized linear performance appending writes. // Never shrinks the storage. expandFileStorage: function(node, newCapacity) { -#if CAN_ADDRESS_2GB - newCapacity >>>= 0; -#endif var prevCapacity = node.contents ? node.contents.length : 0; if (prevCapacity >= newCapacity) return; // No need to expand, the storage was already large enough. // Don't expand strictly to the given requested limit if it's only a very small increase, but instead geometrically grow capacity. @@ -123,9 +120,6 @@ mergeInto(LibraryManager.library, { // Performs an exact resize of the backing file storage to the given size, if the size is not exactly this, the storage is fully reallocated. resizeFileStorage: function(node, newSize) { -#if CAN_ADDRESS_2GB - newSize >>>= 0; -#endif if (node.usedBytes == newSize) return; if (newSize == 0) { node.contents = null; // Fully decommit when requesting a resize to zero. @@ -360,9 +354,6 @@ mergeInto(LibraryManager.library, { if (!ptr) { throw new FS.ErrnoError({{{ cDefs.ENOMEM }}}); } -#if CAN_ADDRESS_2GB - ptr >>>= 0; -#endif HEAP8.set(contents, ptr); } return { ptr, allocated }; diff --git a/src/library_strings.js b/src/library_strings.js index 6110ba8bb171f..1ad54072971f7 100644 --- a/src/library_strings.js +++ b/src/library_strings.js @@ -27,9 +27,6 @@ mergeInto(LibraryManager.library, { $UTF8ArrayToString__deps: ['$UTF8Decoder'], #endif $UTF8ArrayToString: (heapOrArray, idx, maxBytesToRead) => { -#if CAN_ADDRESS_2GB - idx >>>= 0; -#endif var endIdx = idx + maxBytesToRead; #if TEXTDECODER var endPtr = idx; @@ -118,9 +115,6 @@ mergeInto(LibraryManager.library, { #if ASSERTIONS assert(typeof ptr == 'number'); #endif -#if CAN_ADDRESS_2GB - ptr >>>= 0; -#endif #if TEXTDECODER == 2 if (!ptr) return ''; var maxPtr = ptr + maxBytesToRead; @@ -154,9 +148,6 @@ mergeInto(LibraryManager.library, { * @return {number} The number of bytes written, EXCLUDING the null terminator. */ $stringToUTF8Array: (str, heap, outIdx, maxBytesToWrite) => { -#if CAN_ADDRESS_2GB - outIdx >>>= 0; -#endif #if ASSERTIONS assert(typeof str === 'string'); #endif @@ -262,9 +253,6 @@ mergeInto(LibraryManager.library, { // emscripten HEAP, returns a copy of that string as a Javascript String // object. $AsciiToString: (ptr) => { -#if CAN_ADDRESS_2GB - ptr >>>= 0; -#endif var str = ''; while (1) { var ch = {{{ makeGetValue('ptr++', 0, 'u8') }}}; @@ -429,9 +417,6 @@ mergeInto(LibraryManager.library, { // output, not even the null terminator. // Returns the number of bytes written, EXCLUDING the null terminator. $stringToUTF32: (str, outPtr, maxBytesToWrite) => { -#if CAN_ADDRESS_2GB - outPtr >>>= 0; -#endif #if ASSERTIONS assert(outPtr % 4 == 0, 'Pointer passed to stringToUTF32 must be aligned to four bytes!'); #endif diff --git a/src/library_syscall.js b/src/library_syscall.js index 40ab08e493021..df30beb1c2d73 100644 --- a/src/library_syscall.js +++ b/src/library_syscall.js @@ -80,9 +80,6 @@ var SyscallsLibrary = { // MAP_PRIVATE calls need not to be synced back to underlying fs return 0; } -#if CAN_ADDRESS_2GB - addr >>>= 0; -#endif var buffer = HEAPU8.slice(addr, addr + len); FS.msync(stream, buffer, offset, len, flags); }, @@ -142,9 +139,6 @@ var SyscallsLibrary = { var res = FS.mmap(stream, len, offset, prot, flags); var ptr = res.ptr; {{{ makeSetValue('allocated', 0, 'res.allocated', 'i32') }}}; -#if CAN_ADDRESS_2GB - ptr >>>= 0; -#endif {{{ makeSetValue('addr', 0, 'ptr', '*') }}}; return 0; #else // no filesystem support; report lack of support diff --git a/src/library_webgpu.js b/src/library_webgpu.js index c84e5a6ea5934..2c60f5184614b 100644 --- a/src/library_webgpu.js +++ b/src/library_webgpu.js @@ -1841,7 +1841,6 @@ var LibraryWebGPU = { if (size === 0) warnOnce('getMappedRange size=0 no longer means WGPU_WHOLE_MAP_SIZE'); - size = size >>> 0; if (size === {{{ gpu.WHOLE_MAP_SIZE }}}) size = undefined; var mapped; @@ -1875,7 +1874,6 @@ var LibraryWebGPU = { if (size === 0) warnOnce('getMappedRange size=0 no longer means WGPU_WHOLE_MAP_SIZE'); - size = size >>> 0; if (size === {{{ gpu.WHOLE_MAP_SIZE }}}) size = undefined; if (bufferWrapper.mapMode !== {{{ gpu.MapMode.Write }}}) { @@ -1916,7 +1914,6 @@ var LibraryWebGPU = { bufferWrapper.onUnmap = []; var buffer = bufferWrapper.object; - size = size >>> 0; if (size === {{{ gpu.WHOLE_MAP_SIZE }}}) size = undefined; // `callback` takes (WGPUBufferMapAsyncStatus status, void * userdata) diff --git a/src/settings_internal.js b/src/settings_internal.js index b9cb0ea0fc404..82ca320dbf1b2 100644 --- a/src/settings_internal.js +++ b/src/settings_internal.js @@ -186,8 +186,14 @@ var WASM_SYSTEM_EXPORTS = ['stackAlloc', 'stackSave', 'stackRestore', 'getTempRe // Internal: value of -flto argument (either full or thin) var LTO = 0; -// Whether we may be accessing the address 2GB or higher. If so then we need -// to be using unsigned pointers in JS. +// Whether we may be accessing the address 2GB or higher. If so, then we need +// to interpret incoming i32 pointers as unsigned when they arrive in JS. +// In most cases this taken care of automatically based on the `__sig` of JS +// library functions. +// +// This setting does not apply (and is never set to true) unser MEMORY64, since +// in that case we get 64-bit pointers coming throught to JS (converting them to +// i53 in most cases. var CAN_ADDRESS_2GB = false; // Whether to emit DWARF in a separate wasm file on the side (this is not called diff --git a/test/other/metadce/test_metadce_mem_O3_grow.jssize b/test/other/metadce/test_metadce_mem_O3_grow.jssize index 9d89391e19f5c..230ddc863bca0 100644 --- a/test/other/metadce/test_metadce_mem_O3_grow.jssize +++ b/test/other/metadce/test_metadce_mem_O3_grow.jssize @@ -1 +1 @@ -6195 +6188