Skip to content

Commit 41551a4

Browse files
committed
Implement macros {{{ ptrToIdx() }}}, {{{ convertPtrToIdx() }}}, {{{ idxToPtr() }}} 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
1 parent c513aed commit 41551a4

11 files changed

+233
-177
lines changed

src/library.js

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ mergeInto(LibraryManager.library, {
194194
emscripten_resize_heap: 'ip',
195195
emscripten_resize_heap: function(requestedSize) {
196196
var oldSize = HEAPU8.length;
197-
requestedSize = requestedSize >>> 0;
197+
{{{ convertPtrToIdx('requestedSize') }}};
198198
#if ALLOW_MEMORY_GROWTH == 0
199199
#if ABORTING_MALLOC
200200
abortOnCannotGrowMemory(requestedSize);
@@ -2577,10 +2577,10 @@ mergeInto(LibraryManager.library, {
25772577

25782578
emscripten_get_callstack__deps: ['$getCallstack', '$lengthBytesUTF8', '$stringToUTF8'],
25792579
emscripten_get_callstack: function(flags, str, maxbytes) {
2580-
// Use explicit calls to from64 rather then using the __sig
2580+
// Use explicit calls to convertPtrToIdx() rather than using the __sig
25812581
// magic here. This is because the __sig wrapper uses arrow function
25822582
// notation which causes the inner call to traverseStack to fail.
2583-
{{{ from64('str') }}};
2583+
{{{ convertPtrToIdx('str') }}};
25842584
var callstack = getCallstack(flags);
25852585
// User can query the required amount of bytes to hold the callstack.
25862586
if (!str || maxbytes <= 0) {
@@ -3128,7 +3128,7 @@ mergeInto(LibraryManager.library, {
31283128
// Used by wasm-emscripten-finalize to implement STACK_OVERFLOW_CHECK
31293129
__handle_stack_overflow__deps: ['emscripten_stack_get_base', 'emscripten_stack_get_end', '$ptrToString'],
31303130
__handle_stack_overflow: function(requested) {
3131-
requested = requested >>> 0;
3131+
{{{ convertPtrToIdx('requested') }}};
31323132
var base = _emscripten_stack_get_base();
31333133
var end = _emscripten_stack_get_end();
31343134
abort('stack overflow (Attempt to set SP to ' + ptrToString(requested) +
@@ -3303,11 +3303,9 @@ mergeInto(LibraryManager.library, {
33033303
$getWasmTableEntry__internal: true,
33043304
$getWasmTableEntry__deps: ['$wasmTableMirror'],
33053305
$getWasmTableEntry: function(funcPtr) {
3306-
#if MEMORY64
33073306
// Function pointers are 64-bit, but wasmTable.get() requires a Number.
33083307
// https://github.com/emscripten-core/emscripten/issues/18200
3309-
funcPtr = Number(funcPtr);
3310-
#endif
3308+
{{{ convertPtrToIdx(funcPtr); }}}
33113309
var func = wasmTableMirror[funcPtr];
33123310
if (!func) {
33133311
if (funcPtr >= wasmTableMirror.length) wasmTableMirror.length = funcPtr + 1;
@@ -3326,11 +3324,9 @@ mergeInto(LibraryManager.library, {
33263324
},
33273325

33283326
$getWasmTableEntry: function(funcPtr) {
3329-
#if MEMORY64
33303327
// Function pointers are 64-bit, but wasmTable.get() requires a Number.
33313328
// https://github.com/emscripten-core/emscripten/issues/18200
3332-
funcPtr = Number(funcPtr);
3333-
#endif
3329+
{{{ convertPtrToIdx(funcPtr); }}}
33343330
// In -Os and -Oz builds, do not implement a JS side wasm table mirror for small
33353331
// code size, but directly access wasmTable, which is a bit slower as uncached.
33363332
return wasmTable.get(funcPtr);
@@ -3605,11 +3601,11 @@ mergeInto(LibraryManager.library, {
36053601
#if RELOCATABLE
36063602
// Globals that are normally exported from the wasm module but in relocatable
36073603
// mode are created here and imported by the module.
3608-
__stack_pointer: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': true}, {{{ to64(STACK_HIGH) }}})",
3604+
__stack_pointer: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': true}, {{{ idxToPtr(STACK_HIGH) }}})",
36093605
// tell the memory segments where to place themselves
3610-
__memory_base: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': false}, {{{ to64(GLOBAL_BASE) }}})",
3606+
__memory_base: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': false}, {{{ idxToPtr(GLOBAL_BASE) }}})",
36113607
// the wasm backend reserves slot 0 for the NULL function pointer
3612-
__table_base: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': false}, {{{ to64(1) }}})",
3608+
__table_base: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': false}, {{{ idxToPtr(1) }}})",
36133609
#if MEMORY64 == 2
36143610
__memory_base32: "new WebAssembly.Global({'value': 'i32', 'mutable': false}, {{{ GLOBAL_BASE }}})",
36153611
#endif

src/library_ccall.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,29 @@ mergeInto(LibraryManager.library, {
2727
// For fast lookup of conversion functions
2828
var toC = {
2929
#if MEMORY64
30-
'pointer': (p) => {{{ to64('p') }}},
30+
'pointer': (p) => {{{ idxToPtr('p') }}},
3131
#endif
3232
'string': (str) => {
3333
var ret = 0;
3434
if (str !== null && str !== undefined && str !== 0) { // null string
3535
// at most 4 bytes per UTF-8 code point, +1 for the trailing '\0'
3636
ret = stringToUTF8OnStack(str);
3737
}
38-
return {{{ to64('ret') }}};
38+
return {{{ idxToPtr('ret') }}};
3939
},
4040
'array': (arr) => {
4141
var ret = stackAlloc(arr.length);
4242
writeArrayToMemory(arr, ret);
43-
return {{{ to64('ret') }}};
43+
return {{{ idxToPtr('ret') }}};
4444
}
4545
};
4646

4747
function convertReturnValue(ret) {
4848
if (returnType === 'string') {
49-
{{{ from64('ret') }}}
50-
return UTF8ToString(ret);
49+
return UTF8ToString({{{ ptrToIdx('ret') }}});
5150
}
5251
#if MEMORY64
53-
if (returnType === 'pointer') return Number(ret);
52+
if (returnType === 'pointer') return {{{ ptrToIdx('ret') }}};
5453
#endif
5554
if (returnType === 'boolean') return Boolean(ret);
5655
return ret;

src/library_dylink.js

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ var LibraryDylink = {
140140
dbg("updateGOT: before: " + symName + ' : ' + GOT[symName].value);
141141
#endif
142142
if (typeof value == 'function') {
143-
GOT[symName].value = {{{ to64('addFunction(value)') }}};
143+
GOT[symName].value = {{{ idxToPtr('addFunction(value)') }}};
144144
#if DYLINK_DEBUG
145145
dbg("updateGOT: FUNC: " + symName + ' : ' + GOT[symName].value);
146146
#endif
@@ -186,7 +186,7 @@ var LibraryDylink = {
186186
value = value.value;
187187
}
188188
if (typeof value == {{{ POINTER_JS_TYPE }}}) {
189-
value += {{{ to64('memoryBase') }}};
189+
value += {{{ idxToPtr('memoryBase') }}};
190190
}
191191
relocated[e] = value;
192192
}
@@ -218,12 +218,12 @@ var LibraryDylink = {
218218
#endif
219219
if (typeof value == 'function') {
220220
/** @suppress {checkTypes} */
221-
GOT[symName].value = {{{ to64('addFunction(value, value.sig)') }}};
221+
GOT[symName].value = {{{ idxToPtr('addFunction(value, value.sig)') }}};
222222
#if DYLINK_DEBUG
223223
dbg('assigning table entry for : ' + symName + ' -> ' + GOT[symName].value);
224224
#endif
225225
} else if (typeof value == 'number') {
226-
GOT[symName].value = {{{ to64('value') }}};
226+
GOT[symName].value = {{{ idxToPtr('value') }}};
227227
#if MEMORY64
228228
} else if (typeof value == 'bigint') {
229229
GOT[symName].value = value;
@@ -364,7 +364,7 @@ var LibraryDylink = {
364364
assert(end <= HEAP8.length, 'failure to getMemory - memory growth etc. is not supported there, call malloc/sbrk directly or increase INITIAL_MEMORY');
365365
#endif
366366
___heap_base = end;
367-
GOT['__heap_base'].value = {{{ to64('end') }}};
367+
GOT['__heap_base'].value = {{{ idxToPtr('end') }}};
368368
return ret;
369369
},
370370

@@ -675,9 +675,9 @@ var LibraryDylink = {
675675
// symbols that should be local to this module
676676
switch (prop) {
677677
case '__memory_base':
678-
return {{{ to64('memoryBase') }}};
678+
return {{{ idxToPtr('memoryBase') }}};
679679
case '__table_base':
680-
return {{{ to64('tableBase') }}};
680+
return {{{ idxToPtr('tableBase') }}};
681681
#if MEMORY64
682682
#if MEMORY64 == 2
683683
case '__memory_base32':
@@ -732,7 +732,7 @@ var LibraryDylink = {
732732
// __set_stack_limits until $setDylinkStackLimits.
733733
if (!ENVIRONMENT_IS_PTHREAD || runtimeInitialized)
734734
#endif
735-
moduleExports['__set_stack_limits']({{{ to64('_emscripten_stack_get_base()') }}}, {{{ to64('_emscripten_stack_get_end()') }}});
735+
moduleExports['__set_stack_limits']({{{ idxToPtr('_emscripten_stack_get_base()') }}}, {{{ idxToPtr('_emscripten_stack_get_end()') }}});
736736
}
737737
#endif
738738

@@ -757,10 +757,8 @@ var LibraryDylink = {
757757

758758
// Add any EM_ASM function that exist in the side module
759759
if ('__start_em_asm' in moduleExports) {
760-
var start = moduleExports['__start_em_asm'];
761-
var stop = moduleExports['__stop_em_asm'];
762-
{{{ from64('start') }}}
763-
{{{ from64('stop') }}}
760+
var start = {{{ ptrToIdx('moduleExports["__start_em_asm"]') }}};
761+
var stop = {{{ ptrToIdx('moduleExports["__stop_em_asm"]') }}};
764762
while (start < stop) {
765763
var jsString = UTF8ToString(start);
766764
addEmAsm(start, jsString);

src/library_exceptions.js

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ var LibraryExceptions = {
244244
// We'll do that here, instead, to keep things simpler.
245245
__cxa_find_matching_catch__deps: ['$exceptionLast', '$ExceptionInfo', '__resumeException', '__cxa_can_catch', 'setTempRet0'],
246246
__cxa_find_matching_catch: function() {
247-
// Here we use explicit calls to `from64`/`to64` rather then using the
247+
// Here we use explicit calls to `ptrToIdx`/`idxToPtr` rather then using the
248248
// `__sig` attribute to perform these automatically. This is because the
249249
// `__sig` wrapper uses arrow function notation, which is not compatible
250250
// with the use of `arguments` in this function.
@@ -257,15 +257,15 @@ var LibraryExceptions = {
257257
if (!thrown) {
258258
// just pass through the null ptr
259259
setTempRet0(0);
260-
return {{{ to64(0) }}};
260+
return {{{ idxToPtr(0) }}};
261261
}
262262
var info = new ExceptionInfo(thrown);
263263
info.set_adjusted_ptr(thrown);
264264
var thrownType = info.get_type();
265265
if (!thrownType) {
266266
// just pass through the thrown ptr
267267
setTempRet0(0);
268-
return {{{ to64('thrown') }}};
268+
return {{{ idxToPtr('thrown') }}};
269269
}
270270

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

283282
if (caughtType === 0 || caughtType === thrownType) {
284283
// Catch all clause matched or exactly the same type is caught
@@ -290,11 +289,11 @@ var LibraryExceptions = {
290289
dbg(" __cxa_find_matching_catch found " + [ptrToString(info.get_adjusted_ptr()), caughtType]);
291290
#endif
292291
setTempRet0(caughtType);
293-
return {{{ to64('thrown') }}};
292+
return {{{ idxToPtr('thrown') }}};
294293
}
295294
}
296295
setTempRet0(thrownType);
297-
return {{{ to64('thrown') }}};
296+
return {{{ idxToPtr('thrown') }}};
298297
},
299298

300299
__resumeException__deps: ['$exceptionLast'],
@@ -316,7 +315,7 @@ var LibraryExceptions = {
316315
return withStackSave(function() {
317316
var type_addr_addr = stackAlloc({{{ POINTER_SIZE }}});
318317
var message_addr_addr = stackAlloc({{{ POINTER_SIZE }}});
319-
___get_exception_message({{{ to64('ptr') }}}, {{{ to64('type_addr_addr') }}}, {{{ to64('message_addr_addr') }}});
318+
___get_exception_message({{{ idxToPtr('ptr') }}}, {{{ idxToPtr('type_addr_addr') }}}, {{{ idxToPtr('message_addr_addr') }}});
320319
var type_addr = {{{ makeGetValue('type_addr_addr', 0, '*') }}};
321320
var message_addr = {{{ makeGetValue('message_addr_addr', 0, '*') }}};
322321
var type = UTF8ToString(type_addr);

src/library_glemu.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ var LibraryGLEmulation = {
417417
(GL.currentContext.compressionExt ? ' GL_ARB_texture_compression GL_EXT_texture_compression_s3tc' : '') +
418418
(GL.currentContext.anisotropicExt ? ' GL_EXT_texture_filter_anisotropic' : '')
419419
);
420-
return GL.stringCache[name_] = {{{ to64('ret') }}};
420+
return GL.stringCache[name_] = {{{ idxToPtr('ret') }}};
421421
}
422422
return glGetString(name_);
423423
};

src/library_wasmfs.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ FS.createPreloadedFile = FS_createPreloadedFile;
8484
return withStackSave(() => {
8585
mode = mode !== undefined ? mode : 511 /* 0777 */;
8686
var buffer = stringToUTF8OnStack(path);
87-
return __wasmfs_mkdir({{{ to64('buffer') }}}, mode);
87+
return __wasmfs_mkdir({{{ idxToPtr('buffer') }}}, mode);
8888
});
8989
},
9090
// TODO: mkdirTree
@@ -101,7 +101,7 @@ FS.createPreloadedFile = FS_createPreloadedFile;
101101
mode = typeof mode == 'undefined' ? 438 /* 0666 */ : mode;
102102
return withStackSave(() => {
103103
var buffer = stringToUTF8OnStack(path);
104-
return __wasmfs_open({{{ to64('buffer') }}}, flags, mode);
104+
return __wasmfs_open({{{ idxToPtr('buffer') }}}, flags, mode);
105105
})
106106
},
107107
// TODO: create

0 commit comments

Comments
 (0)