11

I am guessing that a Wasm binary is usually JIT-compiled to native code, but given a Wasm source, is there a tool to see the actual generated x86-64 machine code? Or asked in a different way, is there a tool that consumes Wasm and outputs native code?

Andreas Rossberg
  • 34,518
  • 3
  • 61
  • 72
Erik
  • 4,268
  • 5
  • 33
  • 49
  • 1
    What about something like WebAssembly Explorer? Example: https://medium.freecodecamp.org/get-started-with-webassembly-using-only-14-lines-of-javascript-b37b6aaca1e4 – Rudy Velthuis Aug 31 '18 at 20:45
  • WebAssembly can be [compiled to C](https://github.com/WebAssembly/wabt/tree/main/wasm2c), so it can be compiled to any architecture that a C compiler supports. – Anderson Green Aug 16 '21 at 21:08

1 Answers1

4

The online WasmExplorer compiles C code to both WebAssembly and FireFox x86, using the SpiderMonkey compiler. Given the following simple function:

int testFunction(int* input, int length) {
  int sum = 0;
  for (int i = 0; i < length; ++i) {
    sum += input[i];
  }
  return sum;
}

Here is the x86 output:

wasm-function[0]:
  sub rsp, 8                            ; 0x000000 48 83 ec 08
  cmp esi, 1                            ; 0x000004 83 fe 01
  jge 0x14                              ; 0x000007 0f 8d 07 00 00 00
 0x00000d:                              
  xor eax, eax                          ; 0x00000d 33 c0
  jmp 0x26                              ; 0x00000f e9 12 00 00 00
 0x000014:                              
  xor eax, eax                          ; 0x000014 33 c0
 0x000016:                              ; 0x000016 from: [0x000024]
  mov ecx, dword ptr [r15 + rdi]        ; 0x000016 41 8b 0c 3f
  add eax, ecx                          ; 0x00001a 03 c1
  add edi, 4                            ; 0x00001c 83 c7 04
  add esi, -1                           ; 0x00001f 83 c6 ff
  test esi, esi                         ; 0x000022 85 f6
  jne 0x16                              ; 0x000024 75 f0
 0x000026:                              
  nop                                   ; 0x000026 66 90
  add rsp, 8                            ; 0x000028 48 83 c4 08
  ret 

You can view this example online.

WasmExplorer compiles code into wasm / x86 via a service - you can see the scripts that are run on Github - you should be able to use these to construct a command-line tool yourself.

ColinE
  • 68,894
  • 15
  • 164
  • 232
  • Correction: Chrome didn't update its compiler, it *added* an additional compiler. Whether V8's source code is the easiest to follow is another question. – Andreas Rossberg Sep 02 '18 at 07:42
  • Thanks @AndreasRossberg good point - although I updated the answer, I just remembered that WasmExplorer outputs x86 assembly – ColinE Sep 02 '18 at 07:43
  • That's pretty inefficient! Aren't there any better ahead-of-time compilers to produce WASM? It can't even get the loop down to 4 or fewer uops so it can run at 1 per clock on Haswell / Skylake? This is 5. Using `add eax, [r15+rdi]` would save a uop (except on Sandybridge), and `test esi,esi` is also useless after `add esi, -1` already set flags according to the result. – Peter Cordes Sep 02 '18 at 15:45
  • Not to mention that this could auto-vectorize easily, and run 4x faster with SSE2 `paddd xmm0, [r15+rdi]` for arrays that aren't tiny, with just a bit of extra code for loop startup / end. – Peter Cordes Sep 02 '18 at 15:47
  • 1
    `WasmExplorer compiles C code to both WebAssembly and FireFox x86` Really? The x86 assembly is compiled straight from the C and not from the wasm? That's disappointing. Or is it just the wording isn't clear? – hippietrail Oct 15 '19 at 17:31
  • 1
    Are you sure? I've been looking through the code and I can't find anything invoking spidermonkey or firefox. In the .sh files in your link I can only find code that invokes LLVM for C->wasm and LLVM for C->x86. I can't seem to find the code in the repo that does wasm->x86. – hippietrail Oct 16 '19 at 13:57