-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Make js library functions compatible with LEGALIZE_JS_FFI=0 #7679
Comments
while trying to use LEGALIZE_JS_FFI with the following flags main.cpp -O3 --profiling -s ASSERTIONS=1 -s WASM=1 -s DISABLE_EXCEPTION_CATCHING=0 and code below
yields this error
if i change float safeY = fmax((float) x / ran , y); to float safeY = fmax( x / ran , y); what should be the expected behaviour? |
Looks like the same issue, yes - f32/f64 differences with that flag. |
Sorry @kripken , I didn't really understand the crash. From what I see, there is an implementation of rintf in musl that uses float: I also didn't manage to see the hardcoded doubles in library.js: Did I miss something here? |
I think the double comes in on the return. Stuff like |
@kripken so if we removed -s BINARYEN_TRAP_MODE='js' from the link flags we were able to make the build pass because likely it didnt perform the checks, but this gave us problems at runtime. consider this and code below
this was crashing at runtime with error
this seemed to be harmless and i expected a direct call to the getbigint function, but it ended up generating an invoke_j function. do we need to LEGALIZE invoke functions as well? |
@waterlike86 I think you're right, thanks. I opened WebAssembly/binaryen#1883 , does that fix things for you? |
@kripken no unfortunately no. now i get a different call stack
seems like original invoke_j call got turned into a $legalfunc$invoke_j
but shouldnt $legalfunc$invoke_j result type be i32? eventually this calls into dynCall_j where i dont see it being legalized as well. am i missing something? |
Ah, must be emscripten needs to legalize the invokes on the JS side too. I was hoping that would just work, but I guess not. |
@kripken , are you referring to the cases whereby we call the invokes from Wasm? |
I believe we always call invokes from wasm - wasm calls the invoke, which is in JS, and the invoke uses JS try-finally around a call back into wasm. I think the issue is that that binaryen PR legalizes the invoke functions, but emscripten's JS is not yet aware of that and is calling the wrong ones back. Not sure though. |
Thanks for your clarification @kripken :) Do you happen to have the bandwidth to help us resolve this issue? I believe this would most probably be the last one that's blocking us from using LEGALIZE_JS_FFI=0. Please let us know if you need more info or enhancement on the test case. Thanks :) |
@kripken to get the legalstub generated, we made a change to this line -> does this make sense? after this we got
Is our understanding of this flow correct? If so, do you have an idea how we can point |
I don't think I don't think the binaryen side needs to be changed - my guess is the issue is on the emscripten side. Running your testcase, it looks like the error happens on
The problem is that we call into the table from JS, and that is only possible if the type is legal for JS. So all the legalization we did does not help here. To solve this, we should use dynCalls normally - that is, have a Avoiding the ftCall approach also makes sense for perf, I think we discussed in the past - table calls are not that optimized for code size currently. To do this, emscripten.py is where we emit ftCalls etc. This probably isn't a tiny change, but hopefully it's mostly just making dynamic linking do what normal code does (it might not be dynamic linking directly - perhaps it's emulated function pointers, which is enabled by dynamic linking - looking for where ftCalls are emitted in emscripten.py should show). |
I see that the invoke calls in this case were a result of handling exceptions in fastcomp how would the later passes know to generate a dynCall_j for the function replaced by invoke? |
In the normal way, I think? Maybe I misunderstood your question. But this should work normally, that is, without dynamic linking (see #7953 as mentioned earlier). I think we just need to make dynamic linking do the same thing, by not using the custom ftCall mechanism. |
just to set the context right, this is the state of 1.38.22 with your binaryen patch from WebAssembly/binaryen#1883
it doesnt seem that dyncalls are legalized anywhere, is this output expected? |
How are you checking if something is legalized or not? See the last 2 files in this PR for an example of legalized dynCalls https://github.com/WebAssembly/binaryen/pull/1824/files |
I actually created the test app for all 4 scenarios and built it, ran it and inspected the wast result, and index.js to look at how getbigint was called from _main |
Thanks, the testcase was very helpful. So I think, as I commented there, that we should land my PR that legalizes invokes, and we should also make the ftCall change i suggested here (to stop using them). I might not have time for that part myself. |
I wrote up a quick patch to show what I mean, That seems to pass most tests, but e.g. |
Thanks @kripken I think we are getting closer. it seems that the testcase works only if i set EMULATED_FUNCTION_POINTERS=0 with WASM=1. still trying to understand why if we need EMULATED_FUNCTION_POINTERS and why is it set to 2 by default when WASM=1 is set |
Do not use ftCall in wasm. instead, just use dynCalls normally (in asm.js, each module has a table, so we need a special mechanism to call between them all; in wasm, they all share a single Table) see issue #7679
@kripken Theres another case we didnt handle, when the side module tries to call into a main module function which contains a 64bit param, when legalization turned off it errors out with |
This issue has been automatically marked as stale because there has been no activity in the past year. It will be closed automatically if no further activity occurs in the next 7 days. Feel free to re-open at any time if this issue is still relevant. |
The
LEGALIZE_JS_FFI
flag can't be used in many cases, e.g.crashes. The reason is that e.g. for
rintf
we emit f32 calls in the backend, since we are not legalizing. But the js library implementation for rintf has hardcoded doubles insrc/library.js
. So we end up with the wrong type. That method and others would need to be ifdefed for the non-legalizing case, or we could implement them in C.cc @awtcode
The text was updated successfully, but these errors were encountered: