Skip to content

Commit b5f597f

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. Update library_html5.js for >2GB Address review and fix convertPtrToIdx on non-byte shifts
1 parent 3a55fe1 commit b5f597f

13 files changed

+276
-205
lines changed

src/library.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3215,6 +3215,9 @@ addToLibrary({
32153215
// Function pointers are 64-bit, but wasmTable.get() requires a Number.
32163216
// https://github.com/emscripten-core/emscripten/issues/18200
32173217
funcPtr = Number(funcPtr);
3218+
#endif
3219+
#if ASSERTIONS
3220+
assert(funcPtr >= 0, "Function pointers must be nonnegative!");
32183221
#endif
32193222
var func = wasmTableMirror[funcPtr];
32203223
if (!func) {
@@ -3241,6 +3244,9 @@ addToLibrary({
32413244
// Function pointers are 64-bit, but wasmTable.get() requires a Number.
32423245
// https://github.com/emscripten-core/emscripten/issues/18200
32433246
funcPtr = Number(funcPtr);
3247+
#endif
3248+
#if ASSERTIONS
3249+
assert(funcPtr >= 0, "Function pointers must be nonnegative!");
32443250
#endif
32453251
// In -Os and -Oz builds, do not implement a JS side wasm table mirror for small
32463252
// code size, but directly access wasmTable, which is a bit slower as uncached.
@@ -3514,11 +3520,11 @@ addToLibrary({
35143520
#if RELOCATABLE
35153521
// Globals that are normally exported from the wasm module but in relocatable
35163522
// mode are created here and imported by the module.
3517-
__stack_pointer: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': true}, {{{ to64(STACK_HIGH) }}})",
3523+
__stack_pointer: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': true}, {{{ idxToPtr(STACK_HIGH) }}})",
35183524
// tell the memory segments where to place themselves
3519-
__memory_base: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': false}, {{{ to64(GLOBAL_BASE) }}})",
3525+
__memory_base: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': false}, {{{ idxToPtr(GLOBAL_BASE) }}})",
35203526
// the wasm backend reserves slot 0 for the NULL function pointer
3521-
__table_base: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': false}, {{{ to64(1) }}})",
3527+
__table_base: "new WebAssembly.Global({'value': '{{{ POINTER_WASM_TYPE }}}', 'mutable': false}, {{{ idxToPtr(1) }}})",
35223528
#if MEMORY64 == 2
35233529
__memory_base32: "new WebAssembly.Global({'value': 'i32', 'mutable': false}, {{{ GLOBAL_BASE }}})",
35243530
#endif

src/library_ccall.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,30 +27,29 @@ addToLibrary({
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
@@ -226,7 +226,7 @@ var LibraryDylink = {
226226
dbg(`updateGOT: before: ${symName} : ${GOT[symName].value}`);
227227
#endif
228228
if (typeof value == 'function') {
229-
GOT[symName].value = {{{ to64('addFunction(value)') }}};
229+
GOT[symName].value = {{{ idxToPtr('addFunction(value)') }}};
230230
#if DYLINK_DEBUG == 2
231231
dbg(`updateGOT: FUNC: ${symName} : ${GOT[symName].value}`);
232232
#endif
@@ -272,7 +272,7 @@ var LibraryDylink = {
272272
value = value.value;
273273
}
274274
if (typeof value == {{{ POINTER_JS_TYPE }}}) {
275-
value += {{{ to64('memoryBase') }}};
275+
value += {{{ idxToPtr('memoryBase') }}};
276276
}
277277
relocated[e] = value;
278278
}
@@ -304,12 +304,12 @@ var LibraryDylink = {
304304
#endif
305305
if (typeof value == 'function') {
306306
/** @suppress {checkTypes} */
307-
GOT[symName].value = {{{ to64('addFunction(value, value.sig)') }}};
307+
GOT[symName].value = {{{ idxToPtr('addFunction(value, value.sig)') }}};
308308
#if DYLINK_DEBUG == 2
309309
dbg(`assigning table entry for : ${symName} -> ${GOT[symName].value}`);
310310
#endif
311311
} else if (typeof value == 'number') {
312-
GOT[symName].value = {{{ to64('value') }}};
312+
GOT[symName].value = {{{ idxToPtr('value') }}};
313313
#if MEMORY64
314314
} else if (typeof value == 'bigint') {
315315
GOT[symName].value = value;
@@ -381,7 +381,7 @@ var LibraryDylink = {
381381
assert(end <= HEAP8.length, 'failure to getMemory - memory growth etc. is not supported there, call malloc/sbrk directly or increase INITIAL_MEMORY');
382382
#endif
383383
___heap_base = end;
384-
GOT['__heap_base'].value = {{{ to64('end') }}};
384+
GOT['__heap_base'].value = {{{ idxToPtr('end') }}};
385385
return ret;
386386
},
387387

@@ -690,9 +690,9 @@ var LibraryDylink = {
690690
// symbols that should be local to this module
691691
switch (prop) {
692692
case '__memory_base':
693-
return {{{ to64('memoryBase') }}};
693+
return {{{ idxToPtr('memoryBase') }}};
694694
case '__table_base':
695-
return {{{ to64('tableBase') }}};
695+
return {{{ idxToPtr('tableBase') }}};
696696
#if MEMORY64
697697
#if MEMORY64 == 2
698698
case '__memory_base32':
@@ -755,7 +755,7 @@ var LibraryDylink = {
755755
// now. Otherwise this is delayed until `setDylinkStackLimits` is
756756
// called after initialization.
757757
if (moduleExports['__set_stack_limits'] && runtimeInitialized) {
758-
moduleExports['__set_stack_limits']({{{ to64('_emscripten_stack_get_base()') }}}, {{{ to64('_emscripten_stack_get_end()') }}});
758+
moduleExports['__set_stack_limits']({{{ idxToPtr('_emscripten_stack_get_base()') }}}, {{{ idxToPtr('_emscripten_stack_get_end()') }}});
759759
}
760760
#endif
761761

@@ -780,10 +780,8 @@ var LibraryDylink = {
780780

781781
// Add any EM_ASM function that exist in the side module
782782
if ('__start_em_asm' in moduleExports) {
783-
var start = moduleExports['__start_em_asm'];
784-
var stop = moduleExports['__stop_em_asm'];
785-
{{{ from64('start') }}}
786-
{{{ from64('stop') }}}
783+
var start = {{{ ptrToIdx('moduleExports["__start_em_asm"]') }}};
784+
var stop = {{{ ptrToIdx('moduleExports["__stop_em_asm"]') }}};
787785
while (start < stop) {
788786
var jsString = UTF8ToString(start);
789787
addEmAsm(start, jsString);

src/library_glemu.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,7 @@ var LibraryGLEmulation = {
399399
(GL.currentContext.compressionExt ? ' GL_ARB_texture_compression GL_EXT_texture_compression_s3tc' : '') +
400400
(GL.currentContext.anisotropicExt ? ' GL_EXT_texture_filter_anisotropic' : '')
401401
);
402-
return GL.stringCache[name_] = {{{ to64('ret') }}};
402+
return GL.stringCache[name_] = {{{ idxToPtr('ret') }}};
403403
}
404404
return glGetString(name_);
405405
};

0 commit comments

Comments
 (0)