-
Notifications
You must be signed in to change notification settings - Fork 3.5k
[WasmFS] Make the Node backend optional for web builds #26608
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
26eaedc
d30f7de
eea0053
4143136
4b86c1c
a2ab145
112bd63
d0c6c63
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,8 +4,8 @@ | |||||||||||||||||||||||
| * SPDX-License-Identifier: MIT | ||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| addToLibrary({ | ||||||||||||||||||||||||
| $wasmfsNodeIsWindows: !!process.platform.match(/^win/), | ||||||||||||||||||||||||
| var WasmFSNodeLibrary = { | ||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. JS names start with lowercase.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||||||||||||
| $wasmfsNodeIsWindows: "!!process.platform.match(/^win/)", | ||||||||||||||||||||||||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a small drive-by fix. Previously, this would emit (when building on Linux): var wasmfsNodeIsWindows = false;in the JS output, which breaks when deploying these binaries on Windows. As possible follow-up, we could also do:
Suggested change
This would allow a #include <emscripten/emscripten.h>
#include <emscripten/wasmfs.h>
EM_JS(bool, is_node, (), { return ENVIRONMENT_IS_NODE; });
backend_t wasmfs_create_root_dir() {
return is_node() ? wasmfs_create_node_backend("")
: wasmfs_create_memory_backend();
}
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... PR #26624 addresses this. |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| $wasmfsNodeConvertNodeCode__deps: ['$ERRNO_CODES'], | ||||||||||||||||||||||||
| $wasmfsNodeConvertNodeCode: (e) => { | ||||||||||||||||||||||||
|
|
@@ -29,8 +29,8 @@ addToLibrary({ | |||||||||||||||||||||||
| $wasmfsNodeFixStat__deps: ['$wasmfsNodeIsWindows'], | ||||||||||||||||||||||||
| $wasmfsNodeFixStat: (stat) => { | ||||||||||||||||||||||||
| if (wasmfsNodeIsWindows) { | ||||||||||||||||||||||||
| // Node.js on Windows never represents permission bit 'x', so | ||||||||||||||||||||||||
| // propagate read bits to execute bits | ||||||||||||||||||||||||
| // Windows does not report the 'x' permission bit, so propagate read | ||||||||||||||||||||||||
| // bits to execute bits. | ||||||||||||||||||||||||
| stat.mode |= (stat.mode & {{{ cDefs.S_IRUGO }}}) >> 2; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| return stat; | ||||||||||||||||||||||||
|
|
@@ -222,5 +222,32 @@ addToLibrary({ | |||||||||||||||||||||||
| // implicitly return 0 | ||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
| #if !ENVIRONMENT_MAY_BE_NODE | ||||||||||||||||||||||||
| function makeStub(x, library) { | ||||||||||||||||||||||||
| if (isJsOnlySymbol(x) || isDecorator(x)) { | ||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| var t = library[x]; | ||||||||||||||||||||||||
| if (typeof t == 'string') return; | ||||||||||||||||||||||||
| t = t.toString(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| delete library[x + '__i53abi']; | ||||||||||||||||||||||||
| delete library[x + '__deps']; | ||||||||||||||||||||||||
| t = modifyJSFunction(t, (args, body) => { | ||||||||||||||||||||||||
| return `(${args}) => {\n` + | ||||||||||||||||||||||||
| (ASSERTIONS ? "abort('wasmfs::NodeBackend is no-op when !ENVIRONMENT_MAY_BE_NODE');\n" : '') + | ||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about just I think the
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Commit eea0053 adjusts the error message. I tried enabling
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... it was able to DCE away these functions as
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Regarding Lines 2514 to 2524 in 34f6bcf
|
||||||||||||||||||||||||
| '}'; | ||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| library[x] = eval(`(${t})`); | ||||||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is eval needed here? I don't think we normally use eval in combination with
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I copied-pasted this from Line 2596 in 34f6bcf
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... but you're right, it seems unnecessary. Fixed with commit 4143136. |
||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| for (var x in WasmFSNodeLibrary) { | ||||||||||||||||||||||||
| makeStub(x, WasmFSNodeLibrary); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| addToLibrary(WasmFSNodeLibrary); | ||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9301,6 +9301,26 @@ def test_noderawfs_access_abspath(self): | |
| ''') | ||
| self.do_runf('access.c', cflags=['-sNODERAWFS'], args=[os.path.abspath('foo')]) | ||
|
|
||
| def test_wasmfs_nodefs_stubs(self): | ||
| # This is equivalent to building with `-sWASMFS -sNODERAWFS`, except that the Wasm | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I under stand that the
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment should probably be part of the |
||
| # binary can also be used on the web. Ensure that this use case is supported. | ||
| create_file('main.c', r''' | ||
| #include <emscripten/emscripten.h> | ||
| #include <emscripten/wasmfs.h> | ||
|
|
||
| EM_JS(bool, is_node, (), { return ENVIRONMENT_IS_NODE; }); | ||
|
|
||
| backend_t wasmfs_create_root_dir() { | ||
| return is_node() ? wasmfs_create_node_backend("") | ||
| : wasmfs_create_memory_backend(); | ||
| } | ||
|
|
||
| int main(int argc, char** argv) { | ||
| return 0; | ||
| } | ||
| ''') | ||
| self.run_process([EMCC, 'main.c', '-sWASMFS', '-sENVIRONMENT=web']) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I understand what this test is doing exactly. Its not actually running the result so what is it supposed to show? Also, when
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was a test for the linker issue mentioned in comment #26608 (comment), but since commit d30f7de it's probably no longer relevant, as we can now be sure that these stubs are always in sync. Commit d0c6c63 removes this test.
I just checked this, but
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ... PR #26624 reinstates this test in |
||
|
|
||
| def test_noderawfs_readfile_prerun(self): | ||
| create_file('foo', 'bar') | ||
| self.add_pre_run("console.log(FS.readFile('foo', { encoding: 'utf8' }));") | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about simply not allowing this file to be included at all it
!ENVIRONMENT_MAY_BE_NODE?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That would lead to linker failures. For example, if I remove all these stubs and run
./test/runner other.test_wasmfs_nodefs_stubs, I see:Details
I also thought about moving these stubs to native code and using weak linkage (like how
wasmfs_create_root_dir()is handled), but this seemed easier.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough. I guess we should abort/assert in debug builds there though.