Skip to content

Commit 69b1495

Browse files
committed
[wasm64] making JS bindings wasm64 aware
1 parent 0941ca2 commit 69b1495

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+395
-115
lines changed

embuilder.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ def main():
125125
help='build relocatable objects for suitable for dynamic linking')
126126
parser.add_argument('--force', action='store_true',
127127
help='force rebuild of target (by removing it first)')
128+
parser.add_argument('--wasm64', action='store_true',
129+
help='use wasm64 architecture')
128130
parser.add_argument('operation', help='currently only "build" is supported')
129131
parser.add_argument('targets', nargs='+', help='see below')
130132
args = parser.parse_args()
@@ -145,6 +147,9 @@ def main():
145147
if args.pic:
146148
settings.RELOCATABLE = 1
147149

150+
if args.wasm64:
151+
settings.MEMORY64 = 2
152+
148153
if args.force:
149154
force = True
150155

emscripten.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,9 @@ def update_settings_glue(metadata, DEBUG):
127127

128128
# start with the MVP features, and add any detected features.
129129
settings.BINARYEN_FEATURES = ['--mvp-features'] + metadata['features']
130+
# ensure '--enable-memory64' is set exactly once:
131+
if settings.MEMORY64 and '--enable-memory64' not in settings.BINARYEN_FEATURES:
132+
settings.BINARYEN_FEATURES += ['--enable-memory64']
130133
if settings.USE_PTHREADS:
131134
assert '--enable-threads' in settings.BINARYEN_FEATURES
132135
if settings.MEMORY64:

src/embind/embind.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ var LibraryEmbind = {
405405
},
406406

407407
$heap32VectorToArray: function(count, firstElement) {
408+
{{{ from64('firstElement') }}}
408409
var array = [];
409410
for (var i = 0; i < count; i++) {
410411
array.push(HEAP32[(firstElement >> 2) + i]);
@@ -476,6 +477,7 @@ var LibraryEmbind = {
476477

477478
$getShiftFromSize__deps: [],
478479
$getShiftFromSize: function(size) {
480+
{{{ from64('size') }}}
479481
switch (size) {
480482
case 1: return 0;
481483
case 2: return 1;
@@ -874,6 +876,10 @@ var LibraryEmbind = {
874876
Uint32Array,
875877
Float32Array,
876878
Float64Array,
879+
#if WASM_BIGINT
880+
BigInt64Array,
881+
BigUint64Array,
882+
#endif
877883
];
878884

879885
var TA = typeMapping[dataTypeIndex];

src/library.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ LibraryManager.library = {
9191
utime__proxy: 'sync',
9292
utime__sig: 'iii',
9393
utime: function(path, times) {
94+
{{{ from64('times') }}};
9495
// int utime(const char *path, const struct utimbuf *times);
9596
// http://pubs.opengroup.org/onlinepubs/009695399/basedefs/utime.h.html
9697
var time;
@@ -523,6 +524,7 @@ LibraryManager.library = {
523524

524525
time__sig: 'ii',
525526
time: function(ptr) {
527+
{{{ from64('ptr') }}};
526528
var ret = (Date.now()/1000)|0;
527529
if (ptr) {
528530
{{{ makeSetValue('ptr', 0, 'ret', 'i32') }}};
@@ -3260,6 +3262,7 @@ LibraryManager.library = {
32603262
$readAsmConstArgsArray: '=[]',
32613263
$readAsmConstArgs__deps: ['$readAsmConstArgsArray'],
32623264
$readAsmConstArgs: function(sigPtr, buf) {
3265+
{{{ from64(['sigPtr', 'buf']) }}};
32633266
#if ASSERTIONS
32643267
// Nobody should have mutated _readAsmConstArgsArray underneath us to be something else than an array.
32653268
assert(Array.isArray(readAsmConstArgsArray));
@@ -3769,20 +3772,26 @@ LibraryManager.library = {
37693772
// mode are created here and imported by the module.
37703773
// Mark with `__import` so these are usable from native code. This is needed
37713774
// because, by default, only functions can be be imported.
3772-
__stack_pointer: "new WebAssembly.Global({'value': 'i32', 'mutable': true}, {{{ STACK_BASE }}})",
3775+
__stack_pointer:
3776+
"new WebAssembly.Global({'value': '{{{ SIZE_TYPE }}}', 'mutable': true}, {{{ to64(STACK_BASE) }}})",
37733777
__stack_pointer__import: true,
37743778
// tell the memory segments where to place themselves
3775-
__memory_base: '{{{ GLOBAL_BASE }}}',
3779+
__memory_base:
3780+
"new WebAssembly.Global({'value': '{{{ SIZE_TYPE}}}', 'mutable': false}, {{{ to64(GLOBAL_BASE) }}})",
37763781
__memory_base__import: true,
37773782
// the wasm backend reserves slot 0 for the NULL function pointer
3778-
__table_base: 1,
3783+
__table_base:
3784+
"new WebAssembly.Global({'value': '{{{ SIZE_TYPE }}}', 'mutable': false}, {{{ to64(1) }}})",
37793785
__table_base__import: true,
3786+
#if MEMORY64
3787+
__table_base32: 1,
3788+
#endif
37803789
// To support such allocations during startup, track them on __heap_base and
37813790
// then when the main module is loaded it reads that value and uses it to
37823791
// initialize sbrk (the main module is relocatable itself, and so it does not
37833792
// have __heap_base hardcoded into it - it receives it from JS as an extern
37843793
// global, basically).
3785-
__heap_base: '{{{ HEAP_BASE }}}',
3794+
__heap_base: '{{{ to64(HEAP_BASE) }}}',
37863795
__heap_base__import: true,
37873796
#endif
37883797
};

src/library_dylink.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,13 @@ var LibraryDylink = {
4343
$GOTHandler: {
4444
'get': function(obj, symName) {
4545
if (!GOT[symName]) {
46-
GOT[symName] = new WebAssembly.Global({'value': 'i32', 'mutable': true});
46+
GOT[symName] = new WebAssembly.Global({'value':
47+
#if MEMORY64
48+
'i64',
49+
#else
50+
'i32',
51+
#endif
52+
'mutable': true});
4753
#if DYLINK_DEBUG
4854
err("new GOT entry: " + symName);
4955
#endif
@@ -101,6 +107,8 @@ var LibraryDylink = {
101107
#endif
102108
} else if (typeof value === 'number') {
103109
GOT[symName].value = value;
110+
} else if (typeof value === 'bigint') {
111+
GOT[symName].value = Number(value);
104112
} else {
105113
err("unhandled export type for `" + symName + "`: " + (typeof value));
106114
}

src/library_exceptions.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,17 @@ var LibraryExceptions = {
120120
};
121121

122122
this.set_adjusted_ptr = function(adjustedPtr) {
123-
{{{ makeSetValue('this.ptr', Runtime.POINTER_SIZE, 'adjustedPtr', '*') }}};
123+
var ptrSize = {{{ `${Runtime.POINTER_SIZE}` }}};
124+
{{{ makeSetValue('this.ptr', 'ptrSize', 'adjustedPtr', '*') }}};
124125
};
125126

126127
this.get_adjusted_ptr_addr = function() {
127128
return this.ptr + {{{ Runtime.POINTER_SIZE }}};
128129
}
129130

130131
this.get_adjusted_ptr = function() {
131-
return {{{ makeGetValue('this.ptr', Runtime.POINTER_SIZE, '*') }}};
132+
var ptrSize = {{{ `${Runtime.POINTER_SIZE}` }}};
133+
return {{{ makeGetValue('this.ptr', 'ptrSize', '*') }}};
132134
};
133135

134136
// Get pointer which is expected to be received by catch clause in C++ code. It may be adjusted
@@ -153,7 +155,7 @@ var LibraryExceptions = {
153155
};
154156

155157
if (ptr === undefined) {
156-
this.ptr = _malloc({{{ Runtime.POINTER_SIZE * 2 }}});
158+
this.ptr = _malloc({{{ `${Runtime.POINTER_SIZE}` * 2 }}});
157159
this.set_adjusted_ptr(0);
158160
} else {
159161
this.ptr = ptr;

src/library_formatString.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ mergeInto(LibraryManager.library, {
5252
#endif
5353
],
5454
$formatString: function(format, varargs) {
55+
{{{ from64(['format', 'varargs']) }}};
5556
#if ASSERTIONS
5657
assert((varargs & 3) === 0);
5758
#endif
@@ -470,6 +471,7 @@ mergeInto(LibraryManager.library, {
470471
// printf/puts/strlen implementations for when musl is not pulled in - very
471472
// partial. useful for tests, and when bootstrapping structInfo
472473
strlen: function(ptr) {
474+
{{{ from64('ptr') }}};
473475
var end = ptr;
474476
while (HEAPU8[end]) ++end;
475477
return end - ptr;

src/library_glfw.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1241,7 +1241,7 @@ var LibraryGLFW = {
12411241
glfwGetMonitors: function(count) {
12421242
setValue(count, 1, 'i32');
12431243
if (!GLFW.monitors) {
1244-
GLFW.monitors = {{{ makeMalloc('glfwGetMonitors', Runtime.POINTER_SIZE) }}};
1244+
GLFW.monitors = {{{ makeMalloc('glfwGetMonitors', `${Runtime.POINTER_SIZE}`) }}};
12451245
setValue(GLFW.monitors, 1, 'i32');
12461246
}
12471247
return GLFW.monitors;

src/library_pthread.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,11 @@ var LibraryPThread = {
667667
// Deduce which WebGL canvases (HTMLCanvasElements or OffscreenCanvases) should be passed over to the
668668
// Worker that hosts the spawned pthread.
669669
// Comma-delimited list of CSS selectors that must identify canvases by IDs: "#canvas1, #canvas2, ..."
670-
var transferredCanvasNames = attr ? {{{ makeGetValue('attr', 36, 'i32') }}} : 0;
670+
#if MEMORY64
671+
var transferredCanvasNames = attr ? {{{ makeGetValue('attr', 40, 'i64') }}} : 0;
672+
#else
673+
var transferredCanvasNames = attr ? {{{ makeGetValue('attr', 40, 'i32') }}} : 0;
674+
#endif
671675
#if OFFSCREENCANVASES_TO_PTHREAD
672676
// Proxied canvases string pointer -1 is used as a special token to fetch
673677
// whatever canvases were passed to build in -s

src/library_syscall.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ var SyscallsLibrary = {
679679
for (var i = 0; i < num; i++) {
680680
var iovbase = {{{ makeGetValue('iov', '(' + C_STRUCTS.iovec.__size__ + ' * i) + ' + C_STRUCTS.iovec.iov_base, 'i8*') }}};
681681
var iovlen = {{{ makeGetValue('iov', '(' + C_STRUCTS.iovec.__size__ + ' * i) + ' + C_STRUCTS.iovec.iov_len, 'i32') }}};
682-
for (var j = 0; j < iovlen; j++) {
682+
for (var j = 0; j < iovlen; j++) {
683683
view[offset++] = {{{ makeGetValue('iovbase', 'j', 'i8') }}};
684684
}
685685
}
@@ -796,7 +796,7 @@ var SyscallsLibrary = {
796796
#endif
797797

798798
var total = 0;
799-
799+
800800
var srcReadLow = (readfds ? {{{ makeGetValue('readfds', 0, 'i32') }}} : 0),
801801
srcReadHigh = (readfds ? {{{ makeGetValue('readfds', 4, 'i32') }}} : 0);
802802
var srcWriteLow = (writefds ? {{{ makeGetValue('writefds', 0, 'i32') }}} : 0),
@@ -863,7 +863,7 @@ var SyscallsLibrary = {
863863
{{{ makeSetValue('exceptfds', '0', 'dstExceptLow', 'i32') }}};
864864
{{{ makeSetValue('exceptfds', '4', 'dstExceptHigh', 'i32') }}};
865865
}
866-
866+
867867
return total;
868868
},
869869
__sys_msync: function(addr, len, flags) {
@@ -1425,6 +1425,18 @@ function wrapSyscallFunction(x, library, isWasi) {
14251425
var bodyEnd = t.lastIndexOf('}');
14261426
t = t.substring(0, bodyEnd) + post + t.substring(bodyEnd);
14271427
}
1428+
1429+
if (MEMORY64 && !isWasi) {
1430+
t = modifyFunction(t, function(name, args, body) {
1431+
var argnums = args.split(",").map((a) => 'Number(' + a + ')').join();
1432+
return 'function ' + name + '(' + args + ') {\n' +
1433+
' return BigInt((function ' + name + '_inner(' + args + ') {\n' +
1434+
body +
1435+
' })(' + argnums + '));' +
1436+
'}';
1437+
});
1438+
}
1439+
14281440
library[x] = eval('(' + t + ')');
14291441
if (!library[x + '__deps']) library[x + '__deps'] = [];
14301442
library[x + '__deps'].push('$SYSCALLS');

0 commit comments

Comments
 (0)