What I wanted to suggest is that they didn't have to wait for WebAssembly. Even if it's now presented as "a small wrapper around the WebAssembly" it was possible to do that since Mozilla introduced asm.js, as in the "ams.js" block is exactly enough information that enables for what they did now.
Maybe I'm dumb, but wouldn't a sufficiently clever optimizer compile the quoted function into the quoted output, even if the "use asm" tag was omitted? What is the significance of asm.js here?
In theory yes, a smart enough JIT could figure this out. That was in fact v8's strategy for a while. But in practice, it's just not as effective. In a small function like that things are fairly simple, but with large code it takes time and resources for the optimizer to figure out all the types. That leads to noticeable slowness and pauses for recompilation etc. Instead of that, asm.js gives you the option to just receive the types up front.
"Q. Why not just keep optimizing JavaScript JIT compilers instead?
A. No need to stop! But JIT compilers have less predictable performance based on complicated heuristics. The asm.js model provides a model closer to C/C++ by eliminating dynamic type guards, boxed values, and garbage collection.
Q. Isn't it inefficient to have to run the code through a JavaScript interpreter before compiling?
A. Because of the directive prologue, a JavaScript engine can immediately recognize asm.js code at compile-time and immediately compile it to assembly language, with no need to ever run the code through an interpreter."