Skip to content

Commit

Permalink
Automatically convert i32 pointer args to unsigned when CAN_ADDRESS_2…
Browse files Browse the repository at this point in the history
…GB is set

This extends the use automatically-generated JS wrappers to handle
conversion of incoming i32 pointer to u32 JS numbers.  This is only
needed when CAN_ADDRESS_2GB is set.

See #19737
  • Loading branch information
sbc100 committed Jun 28, 2023
1 parent 818523a commit 9e54560
Show file tree
Hide file tree
Showing 10 changed files with 30 additions and 54 deletions.
4 changes: 2 additions & 2 deletions emcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 6 additions & 3 deletions src/jsifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}
Expand Down Expand Up @@ -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))
}
Expand Down
17 changes: 13 additions & 4 deletions src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -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');
},
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down Expand Up @@ -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)}` +
Expand Down Expand Up @@ -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
Expand Down
9 changes: 0 additions & 9 deletions src/library_fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}});
}
Expand Down Expand Up @@ -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 }}});
}
Expand Down Expand Up @@ -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;
}
Expand Down
9 changes: 0 additions & 9 deletions src/library_memfs.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down Expand Up @@ -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 };
Expand Down
15 changes: 0 additions & 15 deletions src/library_strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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') }}};
Expand Down Expand Up @@ -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
Expand Down
6 changes: 0 additions & 6 deletions src/library_syscall.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
},
Expand Down Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions src/library_webgpu.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 }}}) {
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 8 additions & 2 deletions src/settings_internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion test/other/metadce/test_metadce_mem_O3_grow.jssize
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6195
6188

0 comments on commit 9e54560

Please sign in to comment.