Skip to content

Commit 20de480

Browse files
committed
Merge branch 'main' into anonymous-file-descriptors
2 parents efff804 + aead0b0 commit 20de480

File tree

168 files changed

+564
-383
lines changed

Some content is hidden

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

168 files changed

+564
-383
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ jobs:
2828

2929
check-expectations:
3030
runs-on: ubuntu-latest
31+
if: github.event_name == 'pull_request'
3132
steps:
3233
- name: Checkout repo
3334
uses: actions/checkout@v4
@@ -52,14 +53,15 @@ jobs:
5253
echo "JS_ENGINES = [NODE_JS]" >> $EM_CONFIG
5354
echo "final config:"
5455
cat $EM_CONFIG
55-
- name: Check test expectations on main
56+
- name: Check test expectations on target branch
5657
run: |
57-
git checkout origin/main
58+
git checkout ${{ github.base_ref }}
59+
git rev-parse HEAD
5860
# Hack to honor changes to rebaseline_tests.py in the current PR
5961
git checkout - ./tools/maint/rebaseline_tests.py
6062
./bootstrap
6163
if ! ./tools/maint/rebaseline_tests.py --check-only; then
62-
echo "Test expectations are out-of-date on the main branch."
64+
echo "Test expectations are out-of-date on the target branch."
6365
echo "You can run `./tools/maint/rebaseline_tests.py --new-branch`"
6466
echo "and use it to create a seperate PR."
6567
exit 1

ChangeLog.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Note that version numbers do not necessarily reflect the amount of changes
44
between versions. A version number reflects a release that is known to pass all
55
tests, and versions may be tagged more or less frequently at different times.
66

7-
Note that there is *no* ABI compatibility guarantee between versions - the ABI
7+
nNote that there is *no* ABI compatibility guarantee between versions - the ABI
88
may change, so that we can keep improving and optimizing it. The compiler will
99
automatically invalidate system caches when the version number updates, so that
1010
libc etc. are rebuilt for you. You should also rebuild object files and
@@ -20,11 +20,25 @@ See docs/process.md for more on how version tagging works.
2020

2121
3.1.75 (in development)
2222
-----------------------
23+
- The `WASM_BIGINT` feature has been enabled by default. This has the effect that
24+
Wasm i64 values are passed and returned between Wasm and JS as BigInt values
25+
rather than being split by Binaryen into pairs of Numbers. (#22993)
26+
- When using `-sMODULARIZE` we now assert if the factory function is called with
27+
the JS `new` keyword. e.g. `a = new Module()` rather than `b = Module()`.
28+
This paves the way for marking the function as `async` which does not allow
29+
`new` to be used. This usage of `new` here was never documented and is
30+
considered and antipattern. (#23210)
2331
- `PATH.basename()` no longer calls `PATH.normalize()`, so that
2432
`PATH.basename("a/.")` returns `"."` instead of `"a"` and
2533
`PATH.basename("a/b/..")` returns `".."` instead of `"a"`. This is in line with
2634
the behaviour of both node and coreutils, and is already the case when using
2735
NODERAWFS". (#23180)
36+
- The factory function exposed in `-sMODULARIZE` mode is now marked as `async`
37+
when `WASM_ASYNC_COMPILATION` is enabled (the default). This allows us to use
38+
`await` during module creation. One side effect of this is that code in
39+
`--post-js` files will now be delayed until after module creation and after
40+
`main` runs. This matches the existing behaviour when using sync instantation
41+
(`-sWASM_ASYNC_COMPILATION=0`) but is an observable difference. (#23157)
2842

2943
3.1.74 - 12/14/24
3044
-----------------

site/source/docs/tools_reference/settings_reference.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2189,7 +2189,7 @@ legalize i64s into pairs of i32s, as the wasm VM will use a BigInt where an
21892189
i64 is used. If WASM_BIGINT is present, the default minimum supported browser
21902190
versions will be increased to the min version that supports BigInt.
21912191

2192-
Default value: false
2192+
Default value: true
21932193

21942194
.. _emit_producers_section:
21952195

src/library_fs.js

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ FS.staticInit();
182182
// limit max consecutive symlinks to 40 (SYMLOOP_MAX).
183183
linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) {
184184
// split the absolute path
185-
var parts = path.split('/').filter((p) => !!p && (p !== '.'));
185+
var parts = path.split('/').filter((p) => !!p);
186186

187187
// start at the root
188188
var current = FS.root;
@@ -195,6 +195,10 @@ FS.staticInit();
195195
break;
196196
}
197197

198+
if (parts[i] === '.') {
199+
continue;
200+
}
201+
198202
if (parts[i] === '..') {
199203
current_path = PATH.dirname(current_path);
200204
current = current.parent;
@@ -422,8 +426,8 @@ FS.staticInit();
422426
if (FS.isLink(node.mode)) {
423427
return {{{ cDefs.ELOOP }}};
424428
} else if (FS.isDir(node.mode)) {
425-
if (FS.flagsToPermissionString(flags) !== 'r' || // opening for write
426-
(flags & {{{ cDefs.O_TRUNC }}})) { // TODO: check for O_SEARCH? (== search for dir only)
429+
if (FS.flagsToPermissionString(flags) !== 'r' // opening for write
430+
|| (flags & ({{{ cDefs.O_TRUNC }}} | {{{ cDefs.O_CREAT }}}))) { // TODO: check for O_SEARCH? (== search for dir only)
427431
return {{{ cDefs.EISDIR }}};
428432
}
429433
}
@@ -665,9 +669,12 @@ FS.staticInit();
665669
var lookup = FS.lookupPath(path, { parent: true });
666670
var parent = lookup.node;
667671
var name = PATH.basename(path);
668-
if (!name || name === '.' || name === '..') {
672+
if (!name) {
669673
throw new FS.ErrnoError({{{ cDefs.EINVAL }}});
670674
}
675+
if (name === '.' || name === '..') {
676+
throw new FS.ErrnoError({{{ cDefs.EEXIST }}});
677+
}
671678
var errCode = FS.mayCreate(parent, name);
672679
if (errCode) {
673680
throw new FS.ErrnoError(errCode);
@@ -1091,9 +1098,11 @@ FS.staticInit();
10911098
mode = 0;
10921099
}
10931100
var node;
1101+
var isDirPath;
10941102
if (typeof path == 'object') {
10951103
node = path;
10961104
} else {
1105+
isDirPath = path.endsWith("/");
10971106
// noent_okay makes it so that if the final component of the path
10981107
// doesn't exist, lookupPath returns `node: undefined`. `path` will be
10991108
// updated to point to the target of all symlinks.
@@ -1112,9 +1121,14 @@ FS.staticInit();
11121121
if ((flags & {{{ cDefs.O_EXCL }}})) {
11131122
throw new FS.ErrnoError({{{ cDefs.EEXIST }}});
11141123
}
1124+
} else if (isDirPath) {
1125+
throw new FS.ErrnoError({{{ cDefs.EISDIR }}});
11151126
} else {
11161127
// node doesn't exist, try to create it
1117-
node = FS.mknod(path, mode, 0);
1128+
// Ignore the permission bits here to ensure we can `open` this new
1129+
// file below. We use chmod below the apply the permissions once the
1130+
// file is open.
1131+
node = FS.mknod(path, mode | 0o777, 0);
11181132
created = true;
11191133
}
11201134
}
@@ -1164,6 +1178,9 @@ FS.staticInit();
11641178
if (stream.stream_ops.open) {
11651179
stream.stream_ops.open(stream);
11661180
}
1181+
if (created) {
1182+
FS.chmod(node, mode & 0o777);
1183+
}
11671184
#if expectToReceiveOnModule('logReadFiles')
11681185
if (Module['logReadFiles'] && !(flags & {{{ cDefs.O_WRONLY}}})) {
11691186
if (!(path in FS.readFiles)) {

src/library_nodefs.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ addToLibrary({
116116
}
117117
return newFlags;
118118
},
119-
getattr(func) {
119+
getattr(func, node) {
120120
var stat = NODEFS.tryFSOperation(func);
121121
if (NODEFS.isWindows) {
122122
// node.js v0.10.20 doesn't report blksize and blocks on Windows. Fake
@@ -134,7 +134,7 @@ addToLibrary({
134134
}
135135
return {
136136
dev: stat.dev,
137-
ino: stat.ino,
137+
ino: node.ino,
138138
mode: stat.mode,
139139
nlink: stat.nlink,
140140
uid: stat.uid,
@@ -171,7 +171,7 @@ addToLibrary({
171171
if (attr.atime || attr.mtime) {
172172
var atime = attr.atime && new Date(attr.atime);
173173
var mtime = attr.mtime && new Date(attr.mtime);
174-
fs.utimesSync(arg, atime, mtime);
174+
utimes(arg, atime, mtime);
175175
}
176176
if (attr.size !== undefined) {
177177
truncate(arg, attr.size);
@@ -181,7 +181,7 @@ addToLibrary({
181181
node_ops: {
182182
getattr(node) {
183183
var path = NODEFS.realPath(node);
184-
return NODEFS.getattr(() => fs.lstatSync(path));
184+
return NODEFS.getattr(() => fs.lstatSync(path), node);
185185
},
186186
setattr(node, attr) {
187187
var path = NODEFS.realPath(node);
@@ -244,7 +244,7 @@ addToLibrary({
244244
},
245245
stream_ops: {
246246
getattr(stream) {
247-
return NODEFS.getattr(() => fs.fstatSync(stream.nfd));
247+
return NODEFS.getattr(() => fs.fstatSync(stream.nfd), stream.node);
248248
},
249249
setattr(stream, attr) {
250250
NODEFS.setattr(stream.nfd, stream.node, attr, fs.fchmodSync, fs.futimesSync, fs.ftruncateSync);

src/library_path.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,9 @@ addToLibrary({
6363
}
6464
return root + dir;
6565
},
66-
basename: (path) => {
67-
// EMSCRIPTEN return '/' for '/', not an empty string
68-
if (path === '/') return '/';
69-
path = path.replace(/\/+$/g, "");
70-
var lastSlash = path.lastIndexOf('/');
71-
if (lastSlash === -1) return path;
72-
return path.substr(lastSlash+1);
73-
},
66+
// This differs from node's path.basename in that it returns '/' for '/'
67+
// rather than the empty string.
68+
basename: (path) => path && path.match(/([^\/]+|\/)\/*$/)[1],
7469
join: (...paths) => PATH.normalize(paths.join('/')),
7570
join2: (l, r) => PATH.normalize(l + '/' + r),
7671
},

src/library_pipefs.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ addToLibrary({
7777

7878
return 0;
7979
},
80+
dup(stream) {
81+
stream.node.pipe.refcnt++;
82+
},
8083
ioctl(stream, request, varargs) {
8184
return {{{ cDefs.EINVAL }}};
8285
},

src/preamble.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1036,11 +1036,11 @@ function getWasmImports() {
10361036
trueModule = null;
10371037
#endif
10381038
#if SHARED_MEMORY || RELOCATABLE
1039-
receiveInstance(result['instance'], result['module']);
1039+
return receiveInstance(result['instance'], result['module']);
10401040
#else
10411041
// TODO: Due to Closure regression https://github.com/google/closure-compiler/issues/3193, the above line no longer optimizes out down to the following line.
10421042
// When the regression is fixed, can restore the above PTHREADS-enabled path.
1043-
receiveInstance(result['instance']);
1043+
return receiveInstance(result['instance']);
10441044
#endif
10451045
}
10461046
#endif // WASM_ASYNC_COMPILATION
@@ -1076,8 +1076,7 @@ function getWasmImports() {
10761076
// Instantiate from the module posted from the main thread.
10771077
// We can just use sync instantiation in the worker.
10781078
var instance = new WebAssembly.Instance(module, getWasmImports());
1079-
receiveInstance(instance, module);
1080-
resolve();
1079+
resolve(receiveInstance(instance, module));
10811080
};
10821081
});
10831082
}
@@ -1095,16 +1094,16 @@ function getWasmImports() {
10951094
try {
10961095
#endif
10971096
var result = await instantiateAsync(wasmBinary, wasmBinaryFile, info);
1098-
receiveInstantiationResult(result);
1097+
var exports = receiveInstantiationResult(result);
10991098
#if LOAD_SOURCE_MAP
11001099
receiveSourceMapJSON(await getSourceMapAsync());
11011100
#endif
1102-
return result;
1101+
return exports;
11031102
#if MODULARIZE
11041103
} catch (e) {
11051104
// If instantiation fails, reject the module ready promise.
11061105
readyPromiseReject(e);
1107-
return;
1106+
return Promise.reject(e);
11081107
}
11091108
#endif
11101109
#else // WASM_ASYNC_COMPILATION

src/settings.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1498,7 +1498,7 @@ var DYNCALLS = false;
14981498
// i64 is used. If WASM_BIGINT is present, the default minimum supported browser
14991499
// versions will be increased to the min version that supports BigInt.
15001500
// [link]
1501-
var WASM_BIGINT = false;
1501+
var WASM_BIGINT = true;
15021502

15031503
// WebAssembly defines a "producers section" which compilers and tools can
15041504
// annotate themselves in, and LLVM emits this by default.

src/shell.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ var Module = typeof {{{ EXPORT_NAME }}} != 'undefined' ? {{{ EXPORT_NAME }}} : {
3434
#endif // USE_CLOSURE_COMPILER
3535

3636
#if POLYFILL
37-
#if WASM_BIGINT && MIN_SAFARI_VERSION < 150000
37+
#if WASM_BIGINT && MIN_SAFARI_VERSION < 140100
38+
// TODO(https://github.com/emscripten-core/emscripten/issues/23184): Fix this back to 150000
3839
// See https://caniuse.com/mdn-javascript_builtins_bigint64array
3940
#include "polyfill/bigint64array.js"
4041
#endif

0 commit comments

Comments
 (0)