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
Too many local (according to nodejs) in generated Wasm module #21847
Comments
"Too many locals" is common in unoptimized builds of machine-generated code - it is very easy for such code to end up with more locals than wasm VMs will allow, unfortunately. Optimizing is what fixes it. If you see incorrect behavior in optimized builds please reduce it as much as possible and provide that. It may also be useful to use sanitizers like UBSan to make sure you are not seeing different results due to undefined behavior. |
Sorry for the late reply. Adding the If I compile with
The offending function is this unsigned long long get_boxed_ordinal(value $v)
{
return (unsigned long long) *((unsigned long long *) $v + -1LL) & 255LL;
} I think it is a similar issue to what I described in my latest comment in this issue, except it doesn't pretty print the correct result, even with the A little background: CertiCoq translates Coq inductive values to in-memory data structures using pointers, and it seems to only happen inductive types with more than 3 arguments. Here is a zip of a 'reduced' exampled (Still CertiCoq, which includes a bunch of extra stuff for the runtime, I'm sorry, but most of the files are probably not relevant for this issue) Expected output is With
and it doesn't print anything. |
I wonder was there a Binaryen pass that would have split too large functions to smaller ones that would not exceed the local count? Recently I've been struggling with some wasm builds that also generate too many locals, and was thinking it would be nice to be able to split the files up, instead of having to -O2 it (in my case -O1 wasn't oddly enough).. and in this scenario I was looking to debug the generated code in browser debugger, so the -O2 flag was a bit problematic. |
@mkarup which I don't know enough about UB to tell if that line return (unsigned long long) *((unsigned long long *) $v + -1LL) & 255LL; has UB or not. I agree a tool for this could be useful. Splitting might not always be easy to do though, if the locals all have huge live ranges. Another option might be to define another wasm memory (thanks to multimemory) and use space there instead of locals, basically translate local operations to ones on that memory, but that would require maintaining a stack on that memory. A way without a stack could be to use Wasm GC: allocate a struct on function entry and use that (or rather a bunch of structs, because there is a limit on struct size). |
I have some C code generated through the CertiCoq project, specifically a verified implementation of sha256.
Emscripten produces a Wasm module that contains a function that fails when trying to run the module via the generated js scaffolding and nodejs (v.20.12.2).
I have attached a zip containing the C files needed for running the
emcc
command:sha_fast.zip
Error message:
I haven't tested other Wasm runtimes (so disregard this if it is a nodejs related issue).
If i add the
-O1
optimization flag, the module instantiates and runs, but the behavior (printed result) differs from that of the x86-binary, similar to this issue (let me know if you need the details for this specific instance of the difference in behavior)Emscripten Version
Full command:
Output:
The text was updated successfully, but these errors were encountered: