
Liftoff: a new baseline compiler for WebAssembly in V8 - titzer
https://v8project.blogspot.com/2018/08/liftoff.html
======
cdetrio
This is exciting for the Ewasm team (Ethereum WebAssembly). We're hoping this
new single-pass compilation in Liftoff won't be vulnerable to JIT bombs, which
are wasm modules that take a lot longer to compile than they do to execute.
JIT bombs would be DoS attack vectors on Ethereum clients using JIT wasm
engines, and we found some v8 JIT bombs through fuzz testing some months ago.

I gave a talk about it back in June. Slides:
[https://docs.google.com/presentation/d/1n75Mo09HmyruV5S7q0cH...](https://docs.google.com/presentation/d/1n75Mo09HmyruV5S7q0cHWuq-
UorrvdG1bRAYTNydBcY/edit?usp=sharing) video:
[https://youtu.be/2eISBAbT3GM?t=1h22m3s](https://youtu.be/2eISBAbT3GM?t=1h22m3s)

~~~
miohtama
Aa EOS is already leveraging WASM, do you know if they implement any hardening
against these? I know they use wall clock measurements for some operations.

~~~
cdetrio
I mention in the talk that our fuzz tester, Guido Vranken, moved on to fuzzing
WAVM (the wasm jit engine used in EOS) after v8. He earned some bounties (only
some of them were related to WAVM) and several articles were written about it.
I believe WAVM has some constants that can be set low enough to prevent JIT
bombs, but I didn't follow the details so I'm not sure. Check out this commit,
in particular the changes to WASMSerialization.cpp:
[https://github.com/EOSIO/eos/commit/af02ebba5d5797b6dcc2f06b...](https://github.com/EOSIO/eos/commit/af02ebba5d5797b6dcc2f06befcfc584b07dc75f)

------
cbarrick
I'm amused by the "Lift" naming trend for code generators. Mozilla's next gen
code generator for wasm will be called "Cranelift" [1]. Probably coincidence.

[1]:
[https://github.com/CraneStation/cranelift](https://github.com/CraneStation/cranelift)

~~~
tlb
"lifting" is a common optimization -- moving a computation from inside a loop
to outside. It can make a huge difference in numerical functions. For
instance, consider the JS code:

    
    
      for (let i=0; i<a.length; i++) {
        a[i] = a[i]*2
      }
    

Without lifting, every time through the loop it has to check that a is an
array and (i >= 0 && i < a.length). Lifting lets the compiler move all the
checks before the loop and do them once. It's nontrivial to check that the
truth value of the check can't possibly change during the loop.

~~~
otras
I may be missing something here. Given that i is incremented in the loop,
wouldn't the truth value of (i < a.length) change? Or do you mean the two
other checks (a is an array and i>= 0)?

~~~
Jasper_
For a[i] to be valid, i has to be < a.length. This invariant is never
invalidated during the loop body itself.

~~~
otras
I think I'm following, but I'm not sure I completely understand. From the GP:

> Without lifting, every time through the loop it has to check that a is an
> array and (i >= 0 && i < a.length).

It sounds like these checks are being performed once. Does that mean that
instead of it checking in the loop, it's checked prior to and outside of the
loop body? Otherwise, I'm not sure how the value of (i < a.length) wouldn't
change as the loop is performed multiple times, as the increment expression is
called after every loop.

Thanks for your help!

~~~
codefined

      for (let i = 0; i < a.length; i++) {
        a[i] = a[i]*2
      }
    

Has to be converted into something that can be run onto a machine that won't
cause a fatal error if the array `a` doesn't have an item at index `i` (e.g.
negative index). It can be converted to the following by a naive compiler:

    
    
      for (let i = 0; i < a.length; i++) {
        if (i > 0 && a < a.length) { // safe to access
          a[i] = a[i] * 2
        } else {
          throw('in a safe way')
        }
      }
    

Or, to avoid repetitive checks to a.length:

    
    
      const temp = a.length
      for (let i = 0; i < temp; i++) {
        if (i > 0 && a < temp) { // safe to access
          a[i] = a[i] * 2
        }
      }
    

A more advanced compiler might realise that the if statement is irrelevant,
we've defined it in the loop that we'll never have a negative `i` or one above
the length of the array, so we can just avoid those checks entirely and
actually revert back to the original code to compile. This is not always the
case:

    
    
      const temp = a.length
      for (let i = 0; i < temp; i++) {
        a[i] = a[i]*2
      }
    

This comes up in interesting places, like why it is faster to go through an
array backwards than forwards[0].

[0] [https://stackoverflow.com/questions/8689573/why-is-
iterating...](https://stackoverflow.com/questions/8689573/why-is-iterating-
through-an-array-backwards-faster-than-forwards)

------
styfle
I'm very excited to see how wasm is getting 1st class treatment from most
browser vendors.

Does anyone know of projects that ship wasm files (preferably via npm)?

I would like to try out the streaming API but I don't want to compile C++
right now

    
    
        const module = await WebAssembly.compileStreaming(fetch('foo.wasm'));

~~~
sbjs
I would love to see a wasm repl online. Something that's focused on teaching
the language, not for people who are going to write compilers that target it,
but for people who are confused about what it is and how it works, as a way of
demystifying wasm so that they have more confidence in choosing to adopt it.
Maybe something that really visualizes the ins and outs of a wasm program, and
maybe some kind of dynamic visualization of how the s-expressions transform
into stack-based code. Just an idea, but I think it could be useful and fun
for someone to make for those of us who want to play around with wasm without
installing anything :)

~~~
giancarlostoro
The best you can get for now:

[https://webassembly.studio/](https://webassembly.studio/)

It's from Mozilla iirc.

~~~
some_account
It has rust!!

------
akmittal
It should make chrome on par with Firefox performance.

------
nojvek
Browsers optimizing wasm and providing a somewhat predictable performance is a
major boon for the web.

Love to see liftoff making wasm immediately executable, secure and performant
(albeit small delay)

Wasm is the Java applets and flash swf of our generation

