My AEC-to-WebAssembly compiler often outputs WebAssembly code doing unaligned access, which is valid in WebAssembly (it's just not guaranteed to be as fast as aligned access, and, on ARM, it usually isn't). I am interested, is the C code that the wasm2c tool from WebAssembly Binary Toolkit outputs when I ask it to convert my WebAssembly to C valid then? If so, how does wasm2c accomplish that (supporting unaligned access when compiling to a programming language supporting only aligned access)?
-
$\begingroup$ Is this “I’ve looked at the output code and I don’t understand how it works”, or about C specification limits? $\endgroup$Michael Homer– Michael Homer ♦2025-03-06 17:02:39 +00:00Commented Mar 6 at 17:02
-
$\begingroup$ @MichaelHomer Dude, the outputted C code is absolutely massive. A simple 4-line AEC program doing unaligned access gets transpiled into a 1000-lines-long C code. I cannot hope to analyze all that. $\endgroup$FlatAssembler– FlatAssembler2025-03-06 17:13:43 +00:00Commented Mar 6 at 17:13
-
2$\begingroup$ @FlatAssembler have you considered using ctrl+f with "load" $\endgroup$ratchet freak– ratchet freak2025-03-06 19:47:28 +00:00Commented Mar 6 at 19:47
1 Answer
By searching for "load" in c-writer.cc and interpreting the C it's writing, it's emitting a function call for each load instruction.
Then looking for that function leads me to a macro definition which defines all the loads which includes a memcpy to/from a local temporary.
This is legal in C because memcpy is explicitly specified as reinterpreting the arguments as char* which doesn't have any alignment restrictions and is allowed to alias with everything.
-
3$\begingroup$ Note that the C compiler will typically optimize those memcpy calls right back into unaligned load instructions, assuming the target supports that. $\endgroup$Nate Eldredge– Nate Eldredge2025-03-07 00:01:58 +00:00Commented Mar 7 at 0:01