Allow synchronous proxying of async JS functions#26000
Allow synchronous proxying of async JS functions#26000sbc100 merged 1 commit intoemscripten-core:mainfrom
Conversation
4c77b8f to
9ba3164
Compare
|
I found that combining |
9ba3164 to
15b8332
Compare
Non-function change split out from emscripten-core#26000.
Non-function change split out from #26000.
d17af1e to
dbc51db
Compare
b9db5cb to
9cb65fc
Compare
89b2776 to
e30484e
Compare
1f6e95c to
89a5526
Compare
89a5526 to
252e00b
Compare
…H-136988) Basic support for pyrepl in Emscripten. Limitations: * requires JSPI * no signal handling implemented As followup work, it would be nice to implement a webworker variant for when JSPI is not available and proper signal handling. Because it requires JSPI, it doesn't work in Safari. Firefox requires setting an experimental flag. All the Chromiums have full support since May. Until we make it work without JSPI, let's keep the original web_example around. (cherry picked from commit c933a6b) Co-authored-by: Hood Chatham <roberthoodchatham@gmail.com> Co-authored-by: Łukasz Langa <lukasz@langa.pl> Co-authored-by: Éric <merwok@netwok.org>
|
@dschuff @kripken @tlively would you mind taking a look at this? This is the piece that finally allows blocking calls to proxied async functions when called from threads. I'd like to land this before the next release because it actually restores the |
252e00b to
0e54b4a
Compare
src/jsifier.mjs
Outdated
| if (oneliner) { | ||
| body = `return ${body}`; | ||
| } | ||
| let sync = 0; |
There was a problem hiding this comment.
What do these numbers 0,1,2 mean - where are they documented?
There was a problem hiding this comment.
I added some docs in proxyToMainThread. This is internal-only so the docs only, so the docs don't need to be public in that sense.
There was a problem hiding this comment.
Might be worth extracting into named const anyway, it doesn't cost anything but would make it a bit more readable.
There was a problem hiding this comment.
I added some docs in proxyToMainThread.
Are those not pushed to the branch perhaps? I can't see them.
There was a problem hiding this comment.
See proxyToMainThread changes in src/lib/libpthread.js
There was a problem hiding this comment.
Here is that diff:
diff --git a/src/lib/libpthread.js b/src/lib/libpthread.js
index 4ecbb2d63754e..f95fd8c8e3f0e 100644
--- a/src/lib/libpthread.js
+++ b/src/lib/libpthread.js
@@ -935,7 +935,7 @@ var LibraryPThread = {
$proxyToMainThread__deps: ['$stackSave', '$stackRestore', '$stackAlloc', '_emscripten_run_js_on_main_thread'],
$proxyToMainThread__docs: '/** @type{function(number, (number|boolean), ...number)} */',
- $proxyToMainThread: (funcIndex, emAsmAddr, sync, ...callArgs) => {
+ $proxyToMainThread: (funcIndex, emAsmAddr, proxyMode, ...callArgs) => {
// EM_ASM proxying is done by passing a pointer to the address of the EM_ASM
// content as `emAsmAddr`. JS library proxying is done by passing an index
// into `proxiedJSCallArgs` as `funcIndex`. If `emAsmAddr` is non-zero then
@@ -944,8 +944,11 @@ var LibraryPThread = {
// function arguments.
// The serialization buffer contains the number of call params, and then
// all the args here.
- // We also pass 'sync' to C separately, since C needs to look at it.
- // Allocate a buffer, which will be copied by the C code.
+ //
+ // We also pass 'proxyMode' to C separately, since C needs to look at it.
+ //
+ // Allocate a buffer (on the stack), which will be copied if necessary by
+ // the C code.
//
// First passed parameter specifies the number of arguments to the function.
// When BigInt support is enabled, we must handle types in a more complex
@@ -972,7 +975,7 @@ var LibraryPThread = {
HEAPF64[b++] = arg;
#endif
}
- var rtn = __emscripten_run_js_on_main_thread(funcIndex, emAsmAddr, bufSize, args, sync);
+ var rtn = __emscripten_run_js_on_main_thread(funcIndex, emAsmAddr, bufSize, args, proxyMode);
stackRestore(sp);
return rtn;
},I don't see an explanation of the values 0, 1, 2?
There was a problem hiding this comment.
Sorry they were added initially to that function but now I've moved the docs in the C source code alongside __emscripten_run_js_on_main_thread which actually uses the values.
The values are not used here in the JS it turns out
0372b26 to
e76d10a
Compare
tlively
left a comment
There was a problem hiding this comment.
Unfortunately I don't really follow anything else going on here.
src/jsifier.mjs
Outdated
| if (oneliner) { | ||
| body = `return ${body}`; | ||
| } | ||
| let sync = 0; |
There was a problem hiding this comment.
I added some docs in proxyToMainThread.
Are those not pushed to the branch perhaps? I can't see them.
7cea7a6 to
36a6491
Compare
This new mode allows the proxied work itself to be asynchronous (i.e. return a promise). The new behaviour is triggered by marking a functions as both `__proxy: 'sync'` and also `__async`. We can use this new mode to replace the bespoke proxying code that exists for `dlsync` as well as the `poll` system call. For the poll system call this bespoke code was added in emscripten-core#25523 and emscripten-core#25990, but can now be completely removed. In addition to this, because the `poll` syscall is now marked as `__async` it automatically works under ASYNCIFY/JSPI too. One downside of this new mode is that the proxied work requires the main thread event loop to run. Unlike the synchronous proxied work that can complete even when we are deeply nested. Fixes: emscripten-core#25970
36a6491 to
556f71f
Compare
dschuff
left a comment
There was a problem hiding this comment.
Given that this is a fairly significant capability already, and this change makes it much more useful, I think we should expand the section on proxying docs/porting/pthreads.rst with more information on what proxying is, why and how you would want to use it, and maybe a couple of examples.
| #endif | ||
| const callingThread = PThread.currentProxiedOperationCallerThread; | ||
| if (callingThread) { | ||
| return dlsyncThreadsAsync() |
There was a problem hiding this comment.
| return dlsyncThreadsAsync() | |
| return dlsyncThreadsAsync(); |
| "a.out.js.gz": 4056, | ||
| "a.out.nodebug.wasm": 19730, | ||
| "a.out.nodebug.wasm.gz": 9140, | ||
| "total": 27973, |
There was a problem hiding this comment.
I guess the extra size is to support the new proxying mode? edit: at least it's a small change.
|
Sorry, will follow up with docs and feedback |
Non-function change split out from emscripten-core#26000.
This new mode allows the proxied work itself to be asynchronous (i.e. return a promise). The new behaviour is triggered by marking a functions as both `__proxy: 'sync'` and also `__async`. We can use this new mode to replace the bespoke proxying code that exists for `dlsync` as well as the `poll` system call. For the poll system call this bespoke code was added in emscripten-core#25523 and emscripten-core#25990, but can now be completely removed. In addition to this, because the `poll` syscall is now marked as `__async` it automatically works under ASYNCIFY/JSPI too. One downside of this new mode is that the proxied work requires the main thread event loop to run. Unlike the synchronous proxied work that can complete even when we are deeply nested. Fixes: emscripten-core#25970
This new mode allows the proxied work itself to be asynchronous (i.e.
return a promise). The new behaviour is triggered by marking a
functions as both
__proxy: 'sync'and also__async.We can use this new mode to replace the bespoke proxying code that
exists for
dlsyncas well as thepollsystem call. For the pollsystem call this bespoke code was added in #25523 and #25990, but can
now be completely removed.
In addition to this, because the
pollsyscall is now marked as__asyncit automatically works under ASYNCIFY/JSPI too.One downside of this new mode is that the proxied work requires the main
thread event loop to run. Unlike the synchronous proxied work that can
complete even when we are deeply nested.
Fixes: #25970