Skip to content

Commit

Permalink
Implement macros {{{ ptrToIdx() }}}, {{{ convertPtrToIdx() }}}, {{{ i…
Browse files Browse the repository at this point in the history
…dxToPtr() }}} to help 2GB, 4GB and MEMORY64 memory modes. Remove {{{ to64() }}} and {{{ from64() }}} since they had an awkward mismatch of in-place vs expression styles.

This is a looser form of PR #15433, and it embraces the idea that pointer values in JavaScript side will not need to retain the full 64-bit values, but can be truncated to 53 bits.

Fix typos and lint

Cleanup an use of convertPtrToIdx
  • Loading branch information
juj committed May 4, 2023
1 parent c513aed commit 41551a4
Show file tree
Hide file tree
Showing 11 changed files with 233 additions and 177 deletions.
22 changes: 9 additions & 13 deletions src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ mergeInto(LibraryManager.library, {
emscripten_resize_heap: 'ip',
emscripten_resize_heap: function(requestedSize) {
var oldSize = HEAPU8.length;
requestedSize = requestedSize >>> 0;
{{{ convertPtrToIdx('requestedSize') }}};
#if ALLOW_MEMORY_GROWTH == 0
#if ABORTING_MALLOC
abortOnCannotGrowMemory(requestedSize);
Expand Down Expand Up @@ -2577,10 +2577,10 @@ mergeInto(LibraryManager.library, {

emscripten_get_callstack__deps: ['$getCallstack', '$lengthBytesUTF8', '$stringToUTF8'],
emscripten_get_callstack: function(flags, str, maxbytes) {
// Use explicit calls to from64 rather then using the __sig
// Use explicit calls to convertPtrToIdx() rather than using the __sig
// magic here. This is because the __sig wrapper uses arrow function
// notation which causes the inner call to traverseStack to fail.
{{{ from64('str') }}};
{{{ convertPtrToIdx('str') }}};
var callstack = getCallstack(flags);
// User can query the required amount of bytes to hold the callstack.
if (!str || maxbytes <= 0) {
Expand Down Expand Up @@ -3128,7 +3128,7 @@ 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: function(requested) {
requested = requested >>> 0;
{{{ convertPtrToIdx('requested') }}};
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 @@ -3303,11 +3303,9 @@ mergeInto(LibraryManager.library, {
$getWasmTableEntry__internal: true,
$getWasmTableEntry__deps: ['$wasmTableMirror'],
$getWasmTableEntry: function(funcPtr) {
#if MEMORY64
// Function pointers are 64-bit, but wasmTable.get() requires a Number.
// https://github.com/emscripten-core/emscripten/issues/18200
funcPtr = Number(funcPtr);
#endif
{{{ convertPtrToIdx(funcPtr); }}}
var func = wasmTableMirror[funcPtr];
if (!func) {
if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1;
Expand All @@ -3326,11 +3324,9 @@ mergeInto(LibraryManager.library, {
},

$getWasmTableEntry: function(funcPtr) {
#if MEMORY64
// Function pointers are 64-bit, but wasmTable.get() requires a Number.
// https://github.com/emscripten-core/emscripten/issues/18200
funcPtr = Number(funcPtr);
#endif
{{{ convertPtrToIdx(funcPtr); }}}
// In -Os and -Oz builds, do not implement a JS side wasm table mirror for small
// code size, but directly access wasmTable, which is a bit slower as uncached.
return wasmTable.get(funcPtr);
Expand Down Expand Up @@ -3605,11 +3601,11 @@ mergeInto(LibraryManager.library, {
#if RELOCATABLE
// Globals that are normally exported from the wasm module but in relocatable
// mode are created here and imported by the module.
__stack_pointer: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': true}, {{{ to64(STACK_HIGH) }}})",
__stack_pointer: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': true}, {{{ idxToPtr(STACK_HIGH) }}})",
// tell the memory segments where to place themselves
__memory_base: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': false}, {{{ to64(GLOBAL_BASE) }}})",
__memory_base: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': false}, {{{ idxToPtr(GLOBAL_BASE) }}})",
// the wasm backend reserves slot 0 for the NULL function pointer
__table_base: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': false}, {{{ to64(1) }}})",
__table_base: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': false}, {{{ idxToPtr(1) }}})",
#if MEMORY64 == 2
__memory_base32: "new WebAssembly.Global({'value': 'i32', 'mutable': false}, {{{ GLOBAL_BASE }}})",
#endif
Expand Down
11 changes: 5 additions & 6 deletions src/library_ccall.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,29 @@ mergeInto(LibraryManager.library, {
// For fast lookup of conversion functions
var toC = {
#if MEMORY64
'pointer': (p) => {{{ to64('p') }}},
'pointer': (p) => {{{ idxToPtr('p') }}},
#endif
'string': (str) => {
var ret = 0;
if (str !== null && str !== undefined && str !== 0) { // null string
// at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'
ret = stringToUTF8OnStack(str);
}
return {{{ to64('ret') }}};
return {{{ idxToPtr('ret') }}};
},
'array': (arr) => {
var ret = stackAlloc(arr.length);
writeArrayToMemory(arr, ret);
return {{{ to64('ret') }}};
return {{{ idxToPtr('ret') }}};
}
};

function convertReturnValue(ret) {
if (returnType === 'string') {
{{{ from64('ret') }}}
return UTF8ToString(ret);
return UTF8ToString({{{ ptrToIdx('ret') }}});
}
#if MEMORY64
if (returnType === 'pointer') return Number(ret);
if (returnType === 'pointer') return {{{ ptrToIdx('ret') }}};
#endif
if (returnType === 'boolean') return Boolean(ret);
return ret;
Expand Down
22 changes: 10 additions & 12 deletions src/library_dylink.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ var LibraryDylink = {
dbg("updateGOT: before: " + symName + ' : ' + GOT[symName].value);
#endif
if (typeof value == 'function') {
GOT[symName].value = {{{ to64('addFunction(value)') }}};
GOT[symName].value = {{{ idxToPtr('addFunction(value)') }}};
#if DYLINK_DEBUG
dbg("updateGOT: FUNC: " + symName + ' : ' + GOT[symName].value);
#endif
Expand Down Expand Up @@ -186,7 +186,7 @@ var LibraryDylink = {
value = value.value;
}
if (typeof value == {{{ POINTER_JS_TYPE }}}) {
value += {{{ to64('memoryBase') }}};
value += {{{ idxToPtr('memoryBase') }}};
}
relocated[e] = value;
}
Expand Down Expand Up @@ -218,12 +218,12 @@ var LibraryDylink = {
#endif
if (typeof value == 'function') {
/** @suppress {checkTypes} */
GOT[symName].value = {{{ to64('addFunction(value, value.sig)') }}};
GOT[symName].value = {{{ idxToPtr('addFunction(value, value.sig)') }}};
#if DYLINK_DEBUG
dbg('assigning table entry for : ' + symName + ' -> ' + GOT[symName].value);
#endif
} else if (typeof value == 'number') {
GOT[symName].value = {{{ to64('value') }}};
GOT[symName].value = {{{ idxToPtr('value') }}};
#if MEMORY64
} else if (typeof value == 'bigint') {
GOT[symName].value = value;
Expand Down Expand Up @@ -364,7 +364,7 @@ var LibraryDylink = {
assert(end <= HEAP8.length, 'failure to getMemory - memory growth etc. is not supported there, call malloc/sbrk directly or increase INITIAL_MEMORY');
#endif
___heap_base = end;
GOT['__heap_base'].value = {{{ to64('end') }}};
GOT['__heap_base'].value = {{{ idxToPtr('end') }}};
return ret;
},

Expand Down Expand Up @@ -675,9 +675,9 @@ var LibraryDylink = {
// symbols that should be local to this module
switch (prop) {
case '__memory_base':
return {{{ to64('memoryBase') }}};
return {{{ idxToPtr('memoryBase') }}};
case '__table_base':
return {{{ to64('tableBase') }}};
return {{{ idxToPtr('tableBase') }}};
#if MEMORY64
#if MEMORY64 == 2
case '__memory_base32':
Expand Down Expand Up @@ -732,7 +732,7 @@ var LibraryDylink = {
// __set_stack_limits until $setDylinkStackLimits.
if (!ENVIRONMENT_IS_PTHREAD || runtimeInitialized)
#endif
moduleExports['__set_stack_limits']({{{ to64('_emscripten_stack_get_base()') }}}, {{{ to64('_emscripten_stack_get_end()') }}});
moduleExports['__set_stack_limits']({{{ idxToPtr('_emscripten_stack_get_base()') }}}, {{{ idxToPtr('_emscripten_stack_get_end()') }}});
}
#endif

Expand All @@ -757,10 +757,8 @@ var LibraryDylink = {

// Add any EM_ASM function that exist in the side module
if ('__start_em_asm' in moduleExports) {
var start = moduleExports['__start_em_asm'];
var stop = moduleExports['__stop_em_asm'];
{{{ from64('start') }}}
{{{ from64('stop') }}}
var start = {{{ ptrToIdx('moduleExports["__start_em_asm"]') }}};
var stop = {{{ ptrToIdx('moduleExports["__stop_em_asm"]') }}};
while (start < stop) {
var jsString = UTF8ToString(start);
addEmAsm(start, jsString);
Expand Down
15 changes: 7 additions & 8 deletions src/library_exceptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ var LibraryExceptions = {
// We'll do that here, instead, to keep things simpler.
__cxa_find_matching_catch__deps: ['$exceptionLast', '$ExceptionInfo', '__resumeException', '__cxa_can_catch', 'setTempRet0'],
__cxa_find_matching_catch: function() {
// Here we use explicit calls to `from64`/`to64` rather then using the
// Here we use explicit calls to `ptrToIdx`/`idxToPtr` rather then using the
// `__sig` attribute to perform these automatically. This is because the
// `__sig` wrapper uses arrow function notation, which is not compatible
// with the use of `arguments` in this function.
Expand All @@ -257,15 +257,15 @@ var LibraryExceptions = {
if (!thrown) {
// just pass through the null ptr
setTempRet0(0);
return {{{ to64(0) }}};
return {{{ idxToPtr(0) }}};
}
var info = new ExceptionInfo(thrown);
info.set_adjusted_ptr(thrown);
var thrownType = info.get_type();
if (!thrownType) {
// just pass through the thrown ptr
setTempRet0(0);
return {{{ to64('thrown') }}};
return {{{ idxToPtr('thrown') }}};
}

// can_catch receives a **, add indirection
Expand All @@ -277,8 +277,7 @@ var LibraryExceptions = {
// type of the thrown object. Find one which matches, and
// return the type of the catch block which should be called.
for (var i = 0; i < arguments.length; i++) {
var caughtType = arguments[i];
{{{ from64('caughtType') }}};
var caughtType = {{{ ptrToIdx('arguments[i]') }}};

if (caughtType === 0 || caughtType === thrownType) {
// Catch all clause matched or exactly the same type is caught
Expand All @@ -290,11 +289,11 @@ var LibraryExceptions = {
dbg(" __cxa_find_matching_catch found " + [ptrToString(info.get_adjusted_ptr()), caughtType]);
#endif
setTempRet0(caughtType);
return {{{ to64('thrown') }}};
return {{{ idxToPtr('thrown') }}};
}
}
setTempRet0(thrownType);
return {{{ to64('thrown') }}};
return {{{ idxToPtr('thrown') }}};
},

__resumeException__deps: ['$exceptionLast'],
Expand All @@ -316,7 +315,7 @@ var LibraryExceptions = {
return withStackSave(function() {
var type_addr_addr = stackAlloc({{{ POINTER_SIZE }}});
var message_addr_addr = stackAlloc({{{ POINTER_SIZE }}});
___get_exception_message({{{ to64('ptr') }}}, {{{ to64('type_addr_addr') }}}, {{{ to64('message_addr_addr') }}});
___get_exception_message({{{ idxToPtr('ptr') }}}, {{{ idxToPtr('type_addr_addr') }}}, {{{ idxToPtr('message_addr_addr') }}});
var type_addr = {{{ makeGetValue('type_addr_addr', 0, '*') }}};
var message_addr = {{{ makeGetValue('message_addr_addr', 0, '*') }}};
var type = UTF8ToString(type_addr);
Expand Down
2 changes: 1 addition & 1 deletion src/library_glemu.js
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ var LibraryGLEmulation = {
(GL.currentContext.compressionExt ? ' GL_ARB_texture_compression GL_EXT_texture_compression_s3tc' : '') +
(GL.currentContext.anisotropicExt ? ' GL_EXT_texture_filter_anisotropic' : '')
);
return GL.stringCache[name_] = {{{ to64('ret') }}};
return GL.stringCache[name_] = {{{ idxToPtr('ret') }}};
}
return glGetString(name_);
};
Expand Down
4 changes: 2 additions & 2 deletions src/library_wasmfs.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ FS.createPreloadedFile = FS_createPreloadedFile;
return withStackSave(() => {
mode = mode !== undefined ? mode : 511 /* 0777 */;
var buffer = stringToUTF8OnStack(path);
return __wasmfs_mkdir({{{ to64('buffer') }}}, mode);
return __wasmfs_mkdir({{{ idxToPtr('buffer') }}}, mode);
});
},
// TODO: mkdirTree
Expand All @@ -101,7 +101,7 @@ FS.createPreloadedFile = FS_createPreloadedFile;
mode = typeof mode == 'undefined' ? 438 /* 0666 */ : mode;
return withStackSave(() => {
var buffer = stringToUTF8OnStack(path);
return __wasmfs_open({{{ to64('buffer') }}}, flags, mode);
return __wasmfs_open({{{ idxToPtr('buffer') }}}, flags, mode);
})
},
// TODO: create
Expand Down
Loading

0 comments on commit 41551a4

Please sign in to comment.