Skip to content

Commit

Permalink
Merge branch 'main' into open-broken-link-create
Browse files Browse the repository at this point in the history
  • Loading branch information
hoodmane committed Dec 4, 2024
2 parents 7cd0603 + 58889f9 commit a7a0bcd
Show file tree
Hide file tree
Showing 167 changed files with 3,158 additions and 2,462 deletions.
1 change: 1 addition & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,7 @@ jobs:
EMTEST_SKIP_NODE_CANARY: "1"
EMTEST_SKIP_RUST: "1"
EMTEST_SKIP_WASM64: "1"
EMTEST_SKIP_NEW_CMAKE: "1"
steps:
- install-rust
- run: apt-get install -q -y ninja-build scons ccache
Expand Down
5 changes: 4 additions & 1 deletion ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ to browse the changes between the tags.

See docs/process.md for more on how version tagging works.

3.1.73 (in development)
3.1.74 (in development)
-----------------------

3.1.73 - 11/28/24
-----------------
- libunwind was updated to LLVM 19.1.4. (#22394)

3.1.72 - 11/19/24
Expand Down
4 changes: 4 additions & 0 deletions cmake/Modules/Platform/Emscripten.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@ set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1)
set(CMAKE_C_RESPONSE_FILE_LINK_FLAG "@")
set(CMAKE_CXX_RESPONSE_FILE_LINK_FLAG "@")

# Enable $<LINK_LIBRARY:WHOLE_ARCHIVE,static_lib> for CMake 3.24+
set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "-Wl,--whole-archive" "<LINK_ITEM>" "-Wl,--no-whole-archive")
set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED True)

# Set a global EMSCRIPTEN variable that can be used in client CMakeLists.txt to
# detect when building using Emscripten.
set(EMSCRIPTEN 1 CACHE INTERNAL "If true, we are targeting Emscripten output.")
Expand Down
2 changes: 1 addition & 1 deletion emscripten-version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.1.73-git
3.1.74-git
2 changes: 1 addition & 1 deletion src/cpuprofiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,7 @@ var emscriptenCpuProfiler = {
detectWebGLContext() {
if (Module['canvas']?.GLctxObject?.GLctx) return Module['canvas'].GLctxObject.GLctx;
else if (typeof GLctx != 'undefined') return GLctx;
else if (Module.ctx) return Module.ctx;
else if (Module['ctx']) return Module['ctx'];
return null;
},

Expand Down
32 changes: 13 additions & 19 deletions src/library.js
Original file line number Diff line number Diff line change
Expand Up @@ -2182,25 +2182,19 @@ addToLibrary({
},

$asyncLoad__docs: '/** @param {boolean=} noRunDep */',
$asyncLoad: (url, onload, onerror, noRunDep) => {
var dep = !noRunDep ? getUniqueRunDependency(`al ${url}`) : '';
readAsync(url).then(
(arrayBuffer) => {
#if ASSERTIONS
assert(arrayBuffer, `Loading data file "${url}" failed (no arrayBuffer).`);
#endif
onload(new Uint8Array(arrayBuffer));
if (dep) removeRunDependency(dep);
},
(err) => {
if (onerror) {
onerror();
} else {
throw `Loading data file "${url}" failed.`;
}
}
);
if (dep) addRunDependency(dep);
$asyncLoad: (url, noRunDep) => {
return new Promise((resolve, reject) => {
var dep = !noRunDep ? getUniqueRunDependency(`al ${url}`) : '';
if (dep) addRunDependency(dep);
readAsync(url).then(
(arrayBuffer) => {
#if ASSERTIONS
assert(arrayBuffer, `Loading data file "${url}" failed (no arrayBuffer).`);
#endif
resolve(new Uint8Array(arrayBuffer));
if (dep) removeRunDependency(dep);
}, reject);
});
},

$alignMemory: (size, alignment) => {
Expand Down
5 changes: 3 additions & 2 deletions src/library_async.js
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,8 @@ addToLibrary({
emscripten_wget_data__async: true,
emscripten_wget_data: (url, pbuffer, pnum, perror) => {
return Asyncify.handleSleep((wakeUp) => {
asyncLoad(UTF8ToString(url), (byteArray) => {
/* no need for run dependency, this is async but will not do any prepare etc. step */
asyncLoad(UTF8ToString(url), /*noRunDep=*/true).then((byteArray) => {
// can only allocate the buffer after the wakeUp, not during an asyncing
var buffer = _malloc(byteArray.length); // must be freed by caller!
HEAPU8.set(byteArray, buffer);
Expand All @@ -481,7 +482,7 @@ addToLibrary({
}, () => {
{{{ makeSetValue('perror', 0, '1', 'i32') }}};
wakeUp();
}, true /* no need for run dependency, this is async but will not do any prepare etc. step */ );
});
});
},

Expand Down
4 changes: 2 additions & 2 deletions src/library_browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ var LibraryBrowser = {
},

createContext(/** @type {HTMLCanvasElement} */ canvas, useWebGL, setInModule, webGLContextAttributes) {
if (useWebGL && Module.ctx && canvas == Module['canvas']) return Module.ctx; // no need to recreate GL context if it's already been created for this canvas.
if (useWebGL && Module['ctx'] && canvas == Module['canvas']) return Module['ctx']; // no need to recreate GL context if it's already been created for this canvas.

var ctx;
var contextHandle;
Expand Down Expand Up @@ -235,7 +235,7 @@ var LibraryBrowser = {
#if ASSERTIONS
if (!useWebGL) assert(typeof GLctx == 'undefined', 'cannot set in module if GLctx is used, but we are a non-GL context that would replace it');
#endif
Module.ctx = ctx;
Module['ctx'] = ctx;
if (useWebGL) GL.makeContextCurrent(contextHandle);
Browser.useWebGL = useWebGL;
Browser.moduleContextCreatedCallbacks.forEach((callback) => callback());
Expand Down
2 changes: 1 addition & 1 deletion src/library_dylink.js
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,7 @@ var LibraryDylink = {

var libFile = locateFile(libName);
if (flags.loadAsync) {
return new Promise((resolve, reject) => asyncLoad(libFile, resolve, reject));
return asyncLoad(libFile);
}

// load the binary synchronously
Expand Down
2 changes: 1 addition & 1 deletion src/library_eventloop.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ LibraryJSEventLoop = {
}

#if ASSERTIONS
if (MainLoop.method === 'timeout' && Module.ctx) {
if (MainLoop.method === 'timeout' && Module['ctx']) {
warnOnce('Looks like you are rendering without using requestAnimationFrame for the main loop. You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!');
MainLoop.method = ''; // just warn once per call to set main loop
}
Expand Down
131 changes: 67 additions & 64 deletions src/library_fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,76 +174,56 @@ FS.staticInit();
path = PATH_FS.resolve(path);

if (!path) return { path: '', node: null };
opts.follow_mount ??= true

var defaults = {
follow_mount: true,
recurse_count: 0
};
opts = Object.assign(defaults, opts)

if (opts.recurse_count > 8) { // max recursive lookup of 8
throw new FS.ErrnoError({{{ cDefs.ELOOP }}});
}
// limit max consecutive symlinks to 40 (SYMLOOP_MAX).
linkloop: for (var nlinks = 0; nlinks < 40; nlinks++) {
// split the absolute path
var parts = path.split('/').filter((p) => !!p);

// split the absolute path
var parts = path.split('/').filter((p) => !!p);
// start at the root
var current = FS.root;
var current_path = '/';

// start at the root
var current = FS.root;
var current_path = '/';

for (var i = 0; i < parts.length; i++) {
var islast = (i === parts.length-1);
if (islast && opts.parent) {
// stop resolving
break;
}
for (var i = 0; i < parts.length; i++) {
var islast = (i === parts.length-1);
if (islast && opts.parent) {
// stop resolving
break;
}

current_path = PATH.join2(current_path, parts[i]);
try {
current = FS.lookupNode(current, parts[i]);
} catch (e) {
// if noent_okay is true, suppress a ENOENT in the last component
// and return an object with an undefined node. This is needed for
// resolving symlinks in the path when creating a file.
if ((e?.errno === {{{ cDefs.ENOENT }}}) && islast && opts.noent_okay) {
return { path: current_path };
current_path = PATH.join2(current_path, parts[i]);
try {
current = FS.lookupNode(current, parts[i]);
} catch (e) {
// if noent_okay is true, suppress a ENOENT in the last component
// and return an object with an undefined node. This is needed for
// resolving symlinks in the path when creating a file.
if ((e?.errno === {{{ cDefs.ENOENT }}}) && islast && opts.noent_okay) {
return { path: current_path };
}
throw e;
}
throw e;
}

// jump to the mount's root node if this is a mountpoint
if (FS.isMountpoint(current)) {
if (!islast || (islast && opts.follow_mount)) {
// jump to the mount's root node if this is a mountpoint
if (FS.isMountpoint(current) && (!islast || opts.follow_mount)) {
current = current.mounted.root;
}
}

// by default, lookupPath will not follow a symlink if it is the final path component.
// setting opts.follow = true will override this behavior.
if (!islast || opts.follow) {
var count = 0;
while (current && FS.isLink(current.mode)) {
// by default, lookupPath will not follow a symlink if it is the final path component.
// setting opts.follow = true will override this behavior.
if (FS.isLink(current.mode) && (!islast || opts.follow)) {
if (!current.node_ops.readlink) {
throw new FS.ErrnoError({{{ cDefs.ENOSYS }}});
}
var link = current.node_ops.readlink(current);
current_path = PATH_FS.resolve(PATH.dirname(current_path), link);

var lookup = FS.lookupPath(current_path, {
recurse_count: opts.recurse_count + 1,
noent_okay: islast && opts.noent_okay
});
current = lookup.node;

if (count++ > 40) { // limit max consecutive symlinks to 40 (SYMLOOP_MAX).
throw new FS.ErrnoError({{{ cDefs.ELOOP }}});
}
path = PATH_FS.resolve(PATH.dirname(current_path), link, ...parts.slice(i + 1));
continue linkloop;
}
}
return { path: current_path, node: current };
}

return { path: current_path, node: current };
throw new FS.ErrnoError({{{ cDefs.ELOOP }}});
},
getPath(node) {
var path;
Expand Down Expand Up @@ -388,6 +368,9 @@ FS.staticInit();
return 0;
},
mayCreate(dir, name) {
if (!FS.isDir(dir.mode)) {
return {{{ cDefs.ENOTDIR }}};
}
try {
var node = FS.lookupNode(dir, name);
return {{{ cDefs.EEXIST }}};
Expand Down Expand Up @@ -682,15 +665,36 @@ FS.staticInit();
}
return parent.node_ops.mknod(parent, name, mode, dev);
},
statfs(path) {

// NOTE: None of the defaults here are true. We're just returning safe and
// sane values.
var rtn = {
bsize: 4096,
frsize: 4096,
blocks: 1e6,
bfree: 5e5,
bavail: 5e5,
files: FS.nextInode,
ffree: FS.nextInode - 1,
fsid: 42,
flags: 2,
namelen: 255,
};

var parent = FS.lookupPath(path, {follow: true}).node;
if (parent?.node_ops.statfs) {
Object.assign(rtn, parent.node_ops.statfs(parent.mount.opts.root));
}
return rtn;
},
// helpers to create specific types of nodes
create(path, mode) {
mode = mode !== undefined ? mode : 438 /* 0666 */;
create(path, mode = 0o666) {
mode &= {{{ cDefs.S_IALLUGO }}};
mode |= {{{ cDefs.S_IFREG }}};
return FS.mknod(path, mode, 0);
},
mkdir(path, mode) {
mode = mode !== undefined ? mode : 511 /* 0777 */;
mkdir(path, mode = 0o777) {
mode &= {{{ cDefs.S_IRWXUGO }}} | {{{ cDefs.S_ISVTX }}};
mode |= {{{ cDefs.S_IFDIR }}};
#if FS_DEBUG
Expand All @@ -717,7 +721,7 @@ FS.staticInit();
mkdev(path, mode, dev) {
if (typeof dev == 'undefined') {
dev = mode;
mode = 438 /* 0666 */;
mode = 0o666;
}
mode |= {{{ cDefs.S_IFCHR }}};
return FS.mknod(path, mode, dev);
Expand Down Expand Up @@ -825,7 +829,7 @@ FS.staticInit();
// do the underlying fs rename
try {
old_dir.node_ops.rename(old_node, new_dir, new_name);
// update old node (we do this here to avoid each backend
// update old node (we do this here to avoid each backend
// needing to)
old_node.parent = new_dir;
} catch (e) {
Expand Down Expand Up @@ -920,7 +924,7 @@ FS.staticInit();
if (!link.node_ops.readlink) {
throw new FS.ErrnoError({{{ cDefs.EINVAL }}});
}
return PATH_FS.resolve(FS.getPath(link.parent), link.node_ops.readlink(link));
return link.node_ops.readlink(link);
},
stat(path, dontFollow) {
var lookup = FS.lookupPath(path, { follow: !dontFollow });
Expand Down Expand Up @@ -1025,13 +1029,12 @@ FS.staticInit();
timestamp: Math.max(atime, mtime)
});
},
open(path, flags, mode) {
open(path, flags, mode = 0o666) {
if (path === "") {
throw new FS.ErrnoError({{{ cDefs.ENOENT }}});
}
flags = typeof flags == 'string' ? FS_modeStringToFlags(flags) : flags;
if ((flags & {{{ cDefs.O_CREAT }}})) {
mode = typeof mode == 'undefined' ? 438 /* 0666 */ : mode;
mode = (mode & {{{ cDefs.S_IALLUGO }}}) | {{{ cDefs.S_IFREG }}};
} else {
mode = 0;
Expand Down Expand Up @@ -1398,7 +1401,7 @@ FS.staticInit();
FS.mkdir('/proc/self/fd');
FS.mount({
mount() {
var node = FS.createNode(proc_self, 'fd', {{{ cDefs.S_IFDIR }}} | 511 /* 0777 */, {{{ cDefs.S_IXUGO }}});
var node = FS.createNode(proc_self, 'fd', {{{ cDefs.S_IFDIR | 0o777 }}}, {{{ cDefs.S_IXUGO }}});
node.node_ops = {
lookup(parent, name) {
var fd = +name;
Expand Down
2 changes: 1 addition & 1 deletion src/library_fs_shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ addToLibrary({
}
addRunDependency(dep);
if (typeof url == 'string') {
asyncLoad(url, processData, onerror);
asyncLoad(url).then(processData, onerror);
} else {
processData(url);
}
Expand Down
4 changes: 2 additions & 2 deletions src/library_glfw.js
Original file line number Diff line number Diff line change
Expand Up @@ -1108,7 +1108,7 @@ var LibraryGLFW = {
}

// If context creation failed, do not return a valid window
if (!Module.ctx && useWebGL) return 0;
if (!Module['ctx'] && useWebGL) return 0;

// Initializes the framebuffer size from the canvas
const canvas = Module['canvas'];
Expand Down Expand Up @@ -1144,7 +1144,7 @@ var LibraryGLFW = {
for (var i = 0; i < GLFW.windows.length; i++)
if (GLFW.windows[i] !== null) return;

delete Module.ctx;
delete Module['ctx'];
},

swapBuffers: (winid) => {
Expand Down
2 changes: 1 addition & 1 deletion src/library_glut.js
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ var LibraryGLUT = {
glutDestroyWindow__proxy: 'sync',
glutDestroyWindow__deps: ['$Browser'],
glutDestroyWindow: (name) => {
delete Module.ctx;
delete Module['ctx'];
return 1;
},

Expand Down
2 changes: 1 addition & 1 deletion src/library_html5_webgl.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ var LibraryHtml5WebGL = {
});`,
#endif
_emscripten_proxied_gl_context_activated_from_main_browser_thread: (contextHandle) => {
GLctx = Module.ctx = GL.currentContext = contextHandle;
GLctx = Module['ctx'] = GL.currentContext = contextHandle;
GL.currentContextIsProxied = true;
},
#else
Expand Down
Loading

0 comments on commit a7a0bcd

Please sign in to comment.