Skip to content

Commit 206f45c

Browse files
committed
[Wasm64] Fix many remaining issues and add wasm64_4gb test configuration
1 parent 2e25dd9 commit 206f45c

31 files changed

+178
-105
lines changed

.circleci/config.yml

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -608,23 +608,38 @@ jobs:
608608
steps:
609609
- prepare-for-tests
610610
# The linux-python image uses /home/circleci rather than /root and jsvu
611-
# hardcodes /root into its launcher scripts do we need to reinstall v8.
611+
# hardcodes /root into its launcher scripts so we need to reinstall v8.
612612
- run: rm -rf $HOME/.jsvu
613613
- install-v8
614614
- install-node-canary
615615
- run-tests:
616616
title: "wasm64"
617617
test_targets: "
618618
wasm64
619-
wasm64_4gb.test_hello_world
620-
wasm64_4gb.test_em_asm
621-
wasm64_4gb.test_async_main
622-
wasm64_4gb.*embind*
623619
core_2gb.test_em_asm
624620
wasm64l.test_bigswitch
625621
other.test_memory64_proxies
626622
other.test_failing_growth_wasm64"
627623
- upload-test-results
624+
test-wasm64_4gb:
625+
environment:
626+
EMTEST_SKIP_NODE_CANARY: "1"
627+
# Only run 2 tests at a time to avoid OOM (since each tests used >4gb)
628+
EMCC_CORES: "2"
629+
# We don't use `bionic` here since its too old to run recent node versions:
630+
# `/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found`
631+
executor: linux-python
632+
steps:
633+
- prepare-for-tests
634+
# The linux-python image uses /home/circleci rather than /root and jsvu
635+
# hardcodes /root into its launcher scripts so we need to reinstall v8.
636+
- run: rm -rf $HOME/.jsvu
637+
- install-v8
638+
- install-node-canary
639+
- run-tests:
640+
title: "wasm64_4gb"
641+
test_targets: "wasm64_4gb"
642+
- upload-test-results
628643
test-jsc:
629644
executor: linux-python
630645
steps:
@@ -670,7 +685,7 @@ jobs:
670685
- run-tests:
671686
test_targets: "core0.test_hello_world core2.test_demangle_stacks_symbol_map"
672687
test-node-compat:
673-
# We don't use `bionic` here since its tool old to run recent node versions:
688+
# We don't use `bionic` here since its too old to run recent node versions:
674689
# `/lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found`
675690
executor: linux-python
676691
environment:
@@ -876,6 +891,9 @@ workflows:
876891
- test-wasm64:
877892
requires:
878893
- build-linux
894+
- test-wasm64_4gb:
895+
requires:
896+
- build-linux
879897
- test-wasm64l:
880898
requires:
881899
- build-linux

src/library.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,9 @@ addToLibrary({
159159
// it. Returns 1 on success, 0 on error.
160160
$growMemory: (size) => {
161161
var b = wasmMemory.buffer;
162-
var pages = (size - b.byteLength + 65535) >>> 16;
162+
var pages = (size - b.byteLength + {{{ WASM_PAGE_SIZE - 1 }}}) / {{{ WASM_PAGE_SIZE }}};
163163
#if RUNTIME_DEBUG
164-
dbg(`emscripten_resize_heap: ${size} (+${size - b.byteLength} bytes / ${pages} pages)`);
164+
dbg(`growMemory: ${size} (+${size - b.byteLength} bytes / ${pages} pages)`);
165165
#endif
166166
#if MEMORYPROFILER
167167
var oldHeapSize = b.byteLength;
@@ -249,7 +249,7 @@ addToLibrary({
249249
var maxHeapSize = getHeapMax();
250250
if (requestedSize > maxHeapSize) {
251251
#if ASSERTIONS
252-
err(`Cannot enlarge memory, asked to go up to ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!`);
252+
err(`Cannot enlarge memory, requested ${requestedSize} bytes, but the limit is ${maxHeapSize} bytes!`);
253253
#endif
254254
#if ABORTING_MALLOC
255255
abortOnCannotGrowMemory(requestedSize);
@@ -693,7 +693,7 @@ addToLibrary({
693693
// size_t strftime(char *restrict s, size_t maxsize, const char *restrict format, const struct tm *restrict timeptr);
694694
// http://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html
695695

696-
var tm_zone = {{{ makeGetValue('tm', C_STRUCTS.tm.tm_zone, 'i32') }}};
696+
var tm_zone = {{{ makeGetValue('tm', C_STRUCTS.tm.tm_zone, '*') }}};
697697

698698
var date = {
699699
tm_sec: {{{ makeGetValue('tm', C_STRUCTS.tm.tm_sec, 'i32') }}},

src/library_fs_shared.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ addToLibrary({
133133
var fd = process.stdin.fd;
134134

135135
try {
136-
bytesRead = fs.readSync(fd, buf, 0, BUFSIZE, -1);
136+
bytesRead = fs.readSync(fd, buf);
137137
} catch(e) {
138138
// Cross-platform differences: on Windows, reading EOF throws an exception, but on other OSes,
139139
// reading EOF returns 0. Uniformize behavior by treating the EOF exception to return 0.

src/library_int53.js

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,30 +19,32 @@ addToLibrary({
1919
// function $writeI53ToU64(): the implementation would be identical, and it is up to the
2020
// C/C++ side code to interpret the resulting number as signed or unsigned as is desirable.
2121
$writeI53ToI64: (ptr, num) => {
22-
HEAPU32[ptr>>2] = num;
23-
HEAPU32[ptr+4>>2] = (num - HEAPU32[ptr>>2])/4294967296;
22+
{{{ makeSetValue('ptr', 0, 'num', 'u32') }}};
23+
var lower = {{{ makeGetValue('ptr', 0, 'u32') }}};
24+
{{{ makeSetValue('ptr', 4, '(num - lower)/4294967296', 'u32') }}};
2425
#if ASSERTIONS
2526
var deserialized = (num >= 0) ? readI53FromU64(ptr) : readI53FromI64(ptr);
26-
if (deserialized != num) warnOnce('writeI53ToI64() out of range: serialized JS Number ' + num + ' to Wasm heap as bytes lo=' + ptrToString(HEAPU32[ptr>>2]) + ', hi=' + ptrToString(HEAPU32[ptr+4>>2]) + ', which deserializes back to ' + deserialized + ' instead!');
27+
if (deserialized != num) warnOnce(`writeI53ToI64() out of range: serialized JS Number ${num} to Wasm heap as bytes lo=${ptrToString(HEAPU32[ptr/4])}, hi=${ptrToString(HEAPU32[ptr/4+1])}, which deserializes back to ${deserialized} instead!`);
2728
#endif
2829
},
2930

3031
// Same as writeI53ToI64, but if the double precision number does not fit within the
3132
// 64-bit number, the number is clamped to range [-2^63, 2^63-1].
33+
$writeI53ToI64Clamped__deps: ['$writeI53ToI64'],
3234
$writeI53ToI64Clamped: (ptr, num) => {
3335
if (num > 0x7FFFFFFFFFFFFFFF) {
34-
HEAPU32[ptr>>2] = 0xFFFFFFFF;
35-
HEAPU32[ptr+4>>2] = 0x7FFFFFFF;
36+
{{{ makeSetValue('ptr', 0, 0xFFFFFFFF, 'u32') }}};
37+
{{{ makeSetValue('ptr', 4, 0x7FFFFFFF, 'u32') }}};
3638
} else if (num < -0x8000000000000000) {
37-
HEAPU32[ptr>>2] = 0;
38-
HEAPU32[ptr+4>>2] = 0x80000000;
39+
{{{ makeSetValue('ptr', 0, 0, 'u32') }}};
40+
{{{ makeSetValue('ptr', 4, 0x80000000, 'u32') }}};
3941
} else {
40-
HEAPU32[ptr>>2] = num;
41-
HEAPU32[ptr+4>>2] = (num - HEAPU32[ptr>>2])/4294967296;
42+
writeI53ToI64(ptr, num);
4243
}
4344
},
4445

4546
// Like writeI53ToI64, but throws if the passed number is out of range of int64.
47+
$writeI53ToI64__deps: ['$writeI53ToI64'],
4648
$writeI53ToI64Signaling: (ptr, num) => {
4749
if (num > 0x7FFFFFFFFFFFFFFF || num < -0x8000000000000000) {
4850
#if ASSERTIONS
@@ -51,22 +53,26 @@ addToLibrary({
5153
throw 'RangeError:' + num;
5254
#endif
5355
}
54-
HEAPU32[ptr>>2] = num;
55-
HEAPU32[ptr+4>>2] = (num - HEAPU32[ptr>>2])/4294967296;
56+
writeI53ToI64(ptr, num);
5657
},
5758

5859
// Uint64 variant of writeI53ToI64Clamped. Writes the Number to a Uint64 variable on
5960
// the heap, clamping out of range values to range [0, 2^64-1].
61+
$writeI53ToU64Clamped__deps: ['$writeI53ToI64'],
6062
$writeI53ToU64Clamped: (ptr, num) => {
61-
if (num > 0xFFFFFFFFFFFFFFFF) HEAPU32[ptr>>2] = HEAPU32[ptr+4>>2] = 0xFFFFFFFF;
62-
else if (num < 0) HEAPU32[ptr>>2] = HEAPU32[ptr+4>>2] = 0;
63-
else {
64-
HEAPU32[ptr>>2] = num;
65-
HEAPU32[ptr+4>>2] = (num - HEAPU32[ptr>>2])/4294967296;
63+
if (num > 0xFFFFFFFFFFFFFFFF) {
64+
{{{ makeSetValue('ptr', 0, 0xFFFFFFFF, 'u32') }}};
65+
{{{ makeSetValue('ptr', 4, 0xFFFFFFFF, 'u32') }}};
66+
} else if (num < 0) {
67+
{{{ makeSetValue('ptr', 0, 0, 'u32') }}};
68+
{{{ makeSetValue('ptr', 4, 0, 'u32') }}};
69+
} else {
70+
writeI53ToI64(ptr, num);
6671
}
6772
},
6873

6974
// Like writeI53ToI64, but throws if the passed number is out of range of uint64.
75+
$writeI53ToU64Signaling__deps: ['$writeI53ToI64'],
7076
$writeI53ToU64Signaling: (ptr, num) => {
7177
if (num < 0 || num > 0xFFFFFFFFFFFFFFFF) {
7278
#if ASSERTIONS
@@ -75,22 +81,21 @@ addToLibrary({
7581
throw 'RangeError:'+num;
7682
#endif
7783
}
78-
HEAPU32[ptr>>2] = num;
79-
HEAPU32[ptr+4>>2] = (num - HEAPU32[ptr>>2])/4294967296;
84+
writeI53ToI64(ptr, num);
8085
},
8186

8287
// Reads a 64-bit signed integer from the WebAssembly heap and
8388
// converts it to a JavaScript Number, which can represent 53 integer bits precisely.
8489
// TODO: Add $readI53FromI64Signaling() variant.
8590
$readI53FromI64: (ptr) => {
86-
return HEAPU32[ptr>>2] + HEAP32[ptr+4>>2] * 4294967296;
91+
return {{{ makeGetValue('ptr', 0, 'u32') }}} + {{{ makeGetValue('ptr', 4, 'i32') }}} * 4294967296;
8792
},
8893

8994
// Reads a 64-bit unsigned integer from the WebAssembly heap and
9095
// converts it to a JavaScript Number, which can represent 53 integer bits precisely.
9196
// TODO: Add $readI53FromU64Signaling() variant.
9297
$readI53FromU64: (ptr) => {
93-
return HEAPU32[ptr>>2] + HEAPU32[ptr+4>>2] * 4294967296;
98+
return {{{ makeGetValue('ptr', 0, 'u32') }}} + {{{ makeGetValue('ptr', 4, 'u32') }}} * 4294967296;
9499
},
95100

96101
// Converts the given signed 32-bit low-high pair to a JavaScript Number that

src/library_math.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ addToLibrary({
2323
emscripten_math_cosh: (x) => Math.cosh(x),
2424
emscripten_math_hypot: (count, varargs) => {
2525
var args = [];
26-
for (var i = 0; i < count; ++i) args.push(HEAPF64[(varargs>>3) + i]);
26+
for (var i = 0; i < count; ++i) {
27+
args.push({{{ makeGetValue('varargs', `i * ${getNativeTypeSize('double')}`, 'double') }}});
28+
}
2729
return Math.hypot.apply(null, args);
2830
},
2931
emscripten_math_sin: (x) => Math.sin(x),

src/library_nodefs.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,14 +272,14 @@ addToLibrary({
272272
// Node.js < 6 compatibility: node errors on 0 length reads
273273
if (length === 0) return 0;
274274
try {
275-
return fs.readSync(stream.nfd, Buffer.from(buffer.buffer), offset, length, position);
275+
return fs.readSync(stream.nfd, new Int8Array(buffer.buffer, offset, length), { position: position });
276276
} catch (e) {
277277
throw new FS.ErrnoError(NODEFS.convertNodeCode(e));
278278
}
279279
},
280280
write(stream, buffer, offset, length, position) {
281281
try {
282-
return fs.writeSync(stream.nfd, Buffer.from(buffer.buffer), offset, length, position);
282+
return fs.writeSync(stream.nfd, new Int8Array(buffer.buffer, offset, length), { position: position });
283283
} catch (e) {
284284
throw new FS.ErrnoError(NODEFS.convertNodeCode(e));
285285
}

src/library_noderawfs.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ addToLibrary({
148148
}
149149
var seeking = typeof position != 'undefined';
150150
if (!seeking && stream.seekable) position = stream.position;
151-
var bytesRead = fs.readSync(stream.nfd, Buffer.from(buffer.buffer), offset, length, position);
151+
var bytesRead = fs.readSync(stream.nfd, new Int8Array(buffer.buffer, offset, length), { position: position });
152152
// update position marker when non-seeking
153153
if (!seeking) stream.position += bytesRead;
154154
return bytesRead;
@@ -164,7 +164,7 @@ addToLibrary({
164164
}
165165
var seeking = typeof position != 'undefined';
166166
if (!seeking && stream.seekable) position = stream.position;
167-
var bytesWritten = fs.writeSync(stream.nfd, Buffer.from(buffer.buffer), offset, length, position);
167+
var bytesWritten = fs.writeSync(stream.nfd, new Int8Array(buffer.buffer, offset, length), { position: position });
168168
// update position marker when non-seeking
169169
if (!seeking) stream.position += bytesWritten;
170170
return bytesWritten;

src/library_pipefs.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,12 @@ addToLibrary({
9292
currentLength += bucket.offset - bucket.roffset;
9393
}
9494

95+
#if !MEMORY64
9596
#if PTHREADS
9697
assert(buffer instanceof ArrayBuffer || buffer instanceof SharedArrayBuffer || ArrayBuffer.isView(buffer));
9798
#else
9899
assert(buffer instanceof ArrayBuffer || ArrayBuffer.isView(buffer));
100+
#endif
99101
#endif
100102
var data = buffer.subarray(offset, offset + length);
101103

@@ -149,10 +151,12 @@ addToLibrary({
149151
write(stream, buffer, offset, length, position /* ignored */) {
150152
var pipe = stream.node.pipe;
151153

154+
#if !MEMORY64
152155
#if PTHREADS
153156
assert(buffer instanceof ArrayBuffer || buffer instanceof SharedArrayBuffer || ArrayBuffer.isView(buffer));
154157
#else
155158
assert(buffer instanceof ArrayBuffer || ArrayBuffer.isView(buffer));
159+
#endif
156160
#endif
157161
var data = buffer.subarray(offset, offset + length);
158162

src/library_syscall.js

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,30 @@ var SyscallsLibrary = {
9393
#if ASSERTIONS
9494
assert(SYSCALLS.varargs != undefined);
9595
#endif
96+
var ret = {{{ makeGetValue('SYSCALLS.varargs', 0, 'i32') }}};
9697
SYSCALLS.varargs += 4;
97-
var ret = {{{ makeGetValue('SYSCALLS.varargs', '-4', 'i32') }}};
9898
#if SYSCALL_DEBUG
9999
dbg(` (raw: "${ret}")`);
100100
#endif
101101
return ret;
102102
},
103+
104+
#if MEMORY64
105+
getp() {
106+
#if ASSERTIONS
107+
assert(SYSCALLS.varargs != undefined);
108+
#endif
109+
var ret = {{{ makeGetValue('SYSCALLS.varargs', 0, '*') }}};
110+
SYSCALLS.varargs += {{{ POINTER_SIZE }}};
111+
#if SYSCALL_DEBUG
112+
dbg(` (raw: "${ret}")`);
113+
#endif
114+
return ret;
115+
},
116+
#else
117+
getp() { return SYSCALLS.get() },
118+
#endif
119+
103120
getStr(ptr) {
104121
var ret = UTF8ToString(ptr);
105122
#if SYSCALL_DEBUG
@@ -216,7 +233,7 @@ var SyscallsLibrary = {
216233
if (!stream.tty) return -{{{ cDefs.ENOTTY }}};
217234
if (stream.tty.ops.ioctl_tcgets) {
218235
var termios = stream.tty.ops.ioctl_tcgets(stream);
219-
var argp = SYSCALLS.get();
236+
var argp = SYSCALLS.getp();
220237
{{{ makeSetValue('argp', C_STRUCTS.termios.c_iflag, 'termios.c_iflag || 0', 'i32') }}};
221238
{{{ makeSetValue('argp', C_STRUCTS.termios.c_oflag, 'termios.c_oflag || 0', 'i32') }}};
222239
{{{ makeSetValue('argp', C_STRUCTS.termios.c_cflag, 'termios.c_cflag || 0', 'i32') }}};
@@ -242,7 +259,7 @@ var SyscallsLibrary = {
242259
case {{{ cDefs.TCSETSF }}}: {
243260
if (!stream.tty) return -{{{ cDefs.ENOTTY }}};
244261
if (stream.tty.ops.ioctl_tcsets) {
245-
var argp = SYSCALLS.get();
262+
var argp = SYSCALLS.getp();
246263
var c_iflag = {{{ makeGetValue('argp', C_STRUCTS.termios.c_iflag, 'i32') }}};
247264
var c_oflag = {{{ makeGetValue('argp', C_STRUCTS.termios.c_oflag, 'i32') }}};
248265
var c_cflag = {{{ makeGetValue('argp', C_STRUCTS.termios.c_cflag, 'i32') }}};
@@ -257,7 +274,7 @@ var SyscallsLibrary = {
257274
}
258275
case {{{ cDefs.TIOCGPGRP }}}: {
259276
if (!stream.tty) return -{{{ cDefs.ENOTTY }}};
260-
var argp = SYSCALLS.get();
277+
var argp = SYSCALLS.getp();
261278
{{{ makeSetValue('argp', 0, 0, 'i32') }}};
262279
return 0;
263280
}
@@ -266,7 +283,7 @@ var SyscallsLibrary = {
266283
return -{{{ cDefs.EINVAL }}}; // not supported
267284
}
268285
case {{{ cDefs.FIONREAD }}}: {
269-
var argp = SYSCALLS.get();
286+
var argp = SYSCALLS.getp();
270287
return FS.ioctl(stream, op, argp);
271288
}
272289
case {{{ cDefs.TIOCGWINSZ }}}: {
@@ -275,7 +292,7 @@ var SyscallsLibrary = {
275292
if (!stream.tty) return -{{{ cDefs.ENOTTY }}};
276293
if (stream.tty.ops.ioctl_tiocgwinsz) {
277294
var winsize = stream.tty.ops.ioctl_tiocgwinsz(stream.tty);
278-
var argp = SYSCALLS.get();
295+
var argp = SYSCALLS.getp();
279296
{{{ makeSetValue('argp', 0, 'winsize[0]', 'i16') }}};
280297
{{{ makeSetValue('argp', 2, 'winsize[1]', 'i16') }}};
281298
}
@@ -770,7 +787,7 @@ var SyscallsLibrary = {
770787
return 0;
771788
}
772789
case {{{ cDefs.F_GETLK }}}: {
773-
var arg = SYSCALLS.get();
790+
var arg = SYSCALLS.getp();
774791
var offset = {{{ C_STRUCTS.flock.l_type }}};
775792
// We're always unlocked.
776793
{{{ makeSetValue('arg', 'offset', cDefs.F_UNLCK, 'i16') }}};

src/library_wasmfs_node.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ addToLibrary({
187187
try {
188188
// TODO: Cache open file descriptors to guarantee that opened files will
189189
// still exist when we try to access them.
190-
let nread = fs.readSync(fd, HEAPU8, buf_p, len, pos);
190+
let nread = fs.readSync(fd, new Int8Array(HEAPU8.buffer, buf_p, len), { position: pos });
191191
{{{ makeSetValue('nread_p', 0, 'nread', 'i32') }}};
192192
} catch (e) {
193193
if (!e.code) throw e;
@@ -201,7 +201,7 @@ addToLibrary({
201201
try {
202202
// TODO: Cache open file descriptors to guarantee that opened files will
203203
// still exist when we try to access them.
204-
let nwritten = fs.writeSync(fd, HEAPU8, buf_p, len, pos);
204+
let nwritten = fs.writeSync(fd, new Int8Array(HEAPU8.buffer, buf_p, len), { position: pos });
205205
{{{ makeSetValue('nwritten_p', 0, 'nwritten', 'i32') }}};
206206
} catch (e) {
207207
if (!e.code) throw e;

src/preamble_minimal.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,15 @@ function updateMemoryViews() {
7777
#if SUPPORT_BIG_ENDIAN
7878
{{{ maybeExport('HEAP_DATA_VIEW') }}} HEAP_DATA_VIEW = new DataView(b);
7979
#endif
80+
#if MEMORY64 && MAXIMUM_MEMORY > FOUR_GB
81+
#include "runtime_view_proxy.js"
82+
#else
8083
{{{ maybeExport('HEAP8') }}} HEAP8 = new Int8Array(b);
8184
{{{ maybeExport('HEAP16') }}} HEAP16 = new Int16Array(b);
82-
{{{ maybeExport('HEAP32') }}} HEAP32 = new Int32Array(b);
8385
{{{ maybeExport('HEAPU8') }}} HEAPU8 = new Uint8Array(b);
8486
{{{ maybeExport('HEAPU16') }}} HEAPU16 = new Uint16Array(b);
87+
#endif
88+
{{{ maybeExport('HEAP32') }}} HEAP32 = new Int32Array(b);
8589
{{{ maybeExportIfAudioWorklet('HEAPU32') }}} HEAPU32 = new Uint32Array(b);
8690
{{{ maybeExportIfAudioWorklet('HEAPF32') }}} HEAPF32 = new Float32Array(b);
8791
{{{ maybeExport('HEAPF64') }}} HEAPF64 = new Float64Array(b);

0 commit comments

Comments
 (0)