 I hope you're having a great time. You're still awake at 5 o'clock at night. My name is Alex Danlow. I do a lot of work on the web. I've been doing web stuff for a couple of decades, I suppose. I actually edited the HTML spec at W3C, and I'm very excited about WebAssembly. So even though I love JavaScript as much as I'm sure most of you do, I have to confess I'm a real performance freak. So I love native code just as much. The beauty about WebAssembly is that it lets developers compile from C and C++, or other statically typed languages, into a format that we can load into a web browser. It lets you build high-performance web apps. And that's what we're going to go through today, what it's about, how it works. OK, so why? Why do we even have WebAssembly? I can tell you're probably wondering that's why you're at this session. The thing about JavaScript is because it's a dynamically typed language, there's a limit to how far you can push optimization. So over the past few years, V8 and SpiderMonkey and all the other JavaScript engines have done amazing things to push the envelope of performance. But at some point, you hit a kind of brick wall where you get smaller and smaller improvements. And we look for another way to get high performance on the web. When we also think about progressive web apps, there's a session going on about progressive web apps in parallel with me. That's the other Alex. One of us is the evil one. But when you think about progressive web apps as a kind of switch towards a native app-like experience, it's about better UI. It's about higher performance. One of the things, one of the bottlenecks is the JavaScript. So are there any abnormal native app developers in the crowd? Can I have a little show of hands maybe? One or two? Not too many. Well, one of the things is that there are lots of app developers out in the world. Many, many, many millions of them. And they write in C and C++. They use libraries. There are plenty of great libraries for image processing, video compression, machine learning, all this kind of thing. Now, imagine how it would be if you could take your existing application code for your Android app or whatever and cross-compile it to deploy in a browser. And that's what WebAssembly is. It lets you take existing C++ code, deploy it in the browser, and have it run performately. What's really exciting about this is that all the browser engines are doing it. And I'll go into a bit more detail there. It means you don't have to ever rewrite your code just because you want to run on a web browser. OK, so I just want to start with a kind of little introduction to how JavaScript works and how the JavaScript engines work. Now, take this tiny little function here. It's just adding two things together and returning it. This is some simple JavaScript. Now, can anyone here guess what happens when the JavaScript engine sees that plus? It horrifies me whenever I look at it because it looks something like this. This is the ECMAScript standard for plus. This is like, these are the semantics that the JavaScript engine has to deal with whenever it sees A plus B. Because JavaScript's a human-written language, it's kind of designed to be easy to write and convenient, you have to do all these type coercions, you have to do all these lookups. I might be adding a double to a string. I might be adding an object to an integer. All these things have to be dealt with by the JavaScript engine. And so what happens in modern engines is they try really, really hard to shorten this path to as small as possible. But it's really hard to do. So what we're really looking for is a way to get closer to the metal, to build a good compiler target. WebAssembly is not about writing code in WebAssembly. It's nobody writes in assembly. On a normal computer, people wrote assembly in the 60s, and then they invented high-level languages. So it's a compiler target. I won't go into all this messy because it scares the hell out of me. All right, so basic principle of mine, if you want your code to run faster, do less. It's very obvious, very simple. But when it comes down to it, what I would like, ultimately, is to write A plus B in my code and have the plus convert to a single CPU instruction. That's the ultimate aim. That gives you the limit of optimization. And that's what WebAssembly can do. You can actually add things together. It ends up with a single machine instruction. So it's basically at the limit of what's possible. This kind of portable code idea of running on different architectures and being portable has a long history that predates the web. So I'll just run through a few early attempts to set the stage for how WebAssembly does what it does. So way back in the 1970s, we had a thing called P-code. And P-code ran underneath Pascal. And it was an idea of an abstraction of a machine that could then generate P-code. And this intermediate code would compile down to the particular architecture on which you were running. Fast forward a few years later, we ended up with bytecode like the Java Virtual Machine, or the .NET Runtime, which was a great example of a multi-language intermediate format. If you look around in the Google Play Store, for example, we've actually done a lot of analysis of native apps, native apps that are actually in the store. If you look at the top 1,000 apps, the vast majority of them are using the native development kit or the NDK. So they're compiling from C++. The majority of their app logic is in C++. They're not using very much Java at all. So this is a bit of a telltale where we should try and support C++ on the web to get higher performance. And the reason these people on Android are doing this is for performance. But these kind of devices, we've installed apps or a closed system. And what we have is the open web. And so that brings a whole new set of challenges, like security and privacy. There were plenty of previous attempts to run native code in the browser. And I'll kind of run through them for you, because it gives you a good idea about where we're coming from and also show you how V8 works to integrate WebAssembly inside it and what you can do with it as well. OK, so current WebAssembly, as it stands today, runs at 1.2 times the speed of native code, which is an astonishing number when you think about it. This is a format that is compiled into a sandbox-safed environment, runs within a whole lot of constraints to make sure it has no security vulnerabilities or is very hardened against them. And yet, it's only a small slowdown compared to true native code. This is probably like two weeks of Moore's Law in the evolution of computers. Now, the teams are working really, really hard to speed that up a little bit more. But the most important point I want to get home to you right now is that this is not one browser. All the four browser engines have done this, and they are seeing very similar execution times. And so this is really exciting. But anyway, before we go into the details, what did we learn from the past that got us to where we are? Well, many years ago, the only way to get high performance on the web was with plugins. We had lots of plugins for different things. We had Flash with its JIT. We also had Java with its virtual machine, and its JIT as well, and the hotspot optimizer. There were lots of things like that. Plugins were great in their day. However, plugins aren't very good for today. And the reason is that even when we put a plugin into a sandbox environment, we still cop security holes. It's just really hard to control. The other thing is that plugins just do not play nicely with the web APIs. We have lots of web APIs. We have motion detection. We have stuff you can do with a camera. There's a lot of web APIs that are native to the browser, but you can't get that from the plugins. So this kind of this disjoint model that doesn't work very well. But I think the single most important reason plugins aren't a great idea for the modern web is these things. They just don't run on mobile. And so it's very hard to give your users a performance experience from a plugin that doesn't exist. And on top of that, people have to install plugins. And so you're not actually using the browser out of the box. You have to do a whole lot of extra work just to use it. So that was a very early thing. And then we moved on later to this thing that we had Google built called Native Client. So what Native Client was, it was a target for compiled code to run in the web browser. But initially, it only targeted a single architecture. So it was a sandboxed compiler target. So it was safer than proper native code. It ran pretty fast. But again, it had the limitations that it didn't talk to other web APIs. So it really didn't work with your DOM objects. And also, it only ran in Chrome, which was one browser. We tried for a few years to evolve this. We developed Portable Native Client. If you remember Portable Native Client, that actually let you target an intermediate code that could be compiled on the client side to a number of different architectures. But that happens up its own set of problems. Because once you have the compiler in the browser, then that compiler could be vulnerable to security holes. And so you have to put the compiler itself into a sandbox. So it was an incredibly complex architecture. And none of the other browsers wanted to do it because it was just too difficult. So along came a few smart guys over at Mozilla with a research project initially that's called asm.js. It was a very interesting thing. The early evolution of asm.js, it was running incredibly slow as a proof of concept. But over the years, they refined this to be a really great way to create a compiler target that was compatible with plain JavaScript. So what asm.js does is it takes C++, compiles it down into a tiny, tiny subset of JavaScript that contains a bunch of annotations. And then the JavaScript engines attempt to compile that into fast native code. However, one of the limitations of asm.js is that the different JavaScript engines all ran with different performance. And so you couldn't rely on a cross-browser performance story. So let's just see how asm.js and web assembly differ in the real world. So let's have a look. This here is an example of an asm.js piece of output. So if you compiled your C++ code, you might get this. And so this first line of the function x equals x or 0, that's a hint telling the JavaScript engine that that is an integer. So that can help the just-in-time compiler to generate machine code for an integer because it's explicitly annotated. But to understand why a web assembly is a better model than this or a faster model, we have to look at how a JavaScript engine works and what it does when it sees this. So within V8, any JavaScript program you write, this is kind of the first thing that happens. On the left, we have some JavaScript source containing a bunch of JavaScript functions. The first thing we need to do is parse it. So that converts all of the strings and things or whatever in the source gate into tokens and generates this thing that's called an abstract syntax tree. Now the abstract syntax tree is an in-memory representation of the logic of your program. So here we have an if then else thing drawn up as a tree. So once you've generated this internal representation, you then, at least in V8, go straight to machine code. You basically walk the tree, spit out machine code, and there you have your compiled function. But that's a very fast operation and there is no real attempt made to speed that up. Now if we take all of that and squish it up and go to the next stage, this is what the V8 pipeline does. We have this thing called turbofan. And so what happens is that the steps in the beginning there, to the left where the first red blob is with the unoptimized code, while your JavaScript application is running, there's a lot of code inside V8 and all the other engines do similar things, looking at what's running slow, looking at the hot functions, going, oh, this one's bad. And when we identify slow functions, we then re-optimize them. So we push them through this back end here, which is an optimized JIT that creates much faster code for those functions that are chewing on your CPU. But the one thing I really want to emphasize here is that this action of analyzing the code and then deciding what to optimize, that will cost CPU cycles. And that means users battery on a mobile device. So in the asm.js case, it comes in through the parse stage. So all the work of parsing, generating the abstract syntax tree, generating the code, realizing it's hot, re-optimizing it, is all CPU cycles that you don't really need to burn. Because if you use WebAssembly, it hooks in like this. So what happens is that the WebAssembly has already gone through optimization during the compile phase. There is no parse as such. So we've seen with loading large asm.js programs, there can be 10 or 12 seconds of load time for a reasonably sized application. So you eliminate that parse time. And what you actually have is optimized binary that can hook directly into the JIT back end, which will generate the machine code. And all the optimizations have already pretty much been done by the compiler at the front end. So this particular picture within V8 shows that what happens is when you load the JavaScript engine and load the WebAssembly module, we can compile the whole thing in one hit, and we're ready to go, and everything runs at full speed. Some other JavaScript engines, like Chakra in Edge, they take a different approach. And what they do is they lazy compile. So they actually leave the module in memory. And the first time a function is called, they compile it at that point. So they're kind of trading ahead of time compile delay with kind of small hiccups on the way. Anyhow, moving on. I'll just kind of try and explain WebAssembly as a concept now. So what actually is it? And the one thing I've been asked multiple times in the last few days is, does this mean we don't have to write JavaScript anymore? And the answer is no. It's a complement to JavaScript. It's a way for people to take C++ or C or Rust code or any other statically typed language and compile it down to a module that you can call from JavaScript. So they work together. One of the things is also when we were developing this was that people realized the shortcomings of Native Client and the shortcomings of asm.js. And it was actually developed by the same people. So the people that built Native Client and the people that built asm.js and people from Microsoft and Apple all worked together to build what we have today. So what we actually do with it is it's tightly integrated into the web platform. It's a new capability. You have to think of it as that. It's not meant to replace JavaScript. That also means you can talk to all the web APIs. So you can call all the standard DOM functions or all the APIs from your web assembly code via JavaScript. It does have a few differences, like 32-bit floats and 64-bit integers. And in the future, there's a plan to add threading and multiple instruction at the same time, SIMD primitives. So that's kind of it in a small nutshell. But I'm about to go through a few technical slides that are very dry and boring, so feel free to go to sleep for about the next four slides if you're not a total geek. But this is just pretty much what the goals of the design of WebAssembly were. The first thing was to be smaller than asm.js. And right now, a WebAssembly module is smaller than the GZipped asm.js equivalent. So it's smaller over the wire. It wanted to be easy to verify. When I talk about verify, what that means is verifying that the program is safe. This is actually designed to be run in a kind of sandbox environment. And so one of those things with running in a sandbox is that you can't let stray accesses out of the memory of the executing program happen. So effectively, you can run through the WebAssembly binary code in the file in one go and validate that there are no accesses outside of the bounds of the memory block it's contained in. You don't have to do it that way, but it is possible in the design. Same thing for the compilation. You should be able to compile it with one pass through the file. And as I said before, other JavaScript engines have chosen to compile piece by piece for their own design reasons. The other thing is also it needs to be extensible. So right now, there are a very small number of primitives, which I'll show you in a minute. But the whole design was built around adding new things later. So let's take a look at the basics of the memory model. This is a little bit of a scary slide. That's why I warned you in advance. But basically, the memory for a C++ program compiled into WebAssembly looks like a typed array to JavaScript. So it's a contiguous block of memory with no holes in it. But one of the features of WebAssembly that helps with security is this concept of an execution stack, which is separate from the linear memory. So if you think about a normal C++ program, you have a heap. And you allocate memory from the bottom of the heap, and you grow the stack from the top of the heap. And it's possible to take a pointer and then look up into the stack memory and start playing with variables you're not supposed to be playing with and do all sorts of nefarious things. And this is a wonderful malware attack vector. But WebAssembly has a completely different model. The execution stack is isolated from the WebAssembly program itself. So there is no way you can actually poke into it and change things. That's a really cool security feature. Also, the functions themselves use integer offset. So they don't actually have pointers. The functions are numbered functions, which point into an indirection table. And then those indirect calculated numbers jump into the functions themselves inside the module. And the reason it's built that way is so that you can load multiple modules side by side. So you just offset all the indexes, and everything works beautifully. But one of the things that is very important to point out here as well is that the WebAssembly module has no access to any platform APIs. So right back in the bad old days of plug-ins, you could call any platform API you wanted. WebAssembly has no such access. And so everything is mediated through JavaScript, which means you're in control and basically JavaScript is the boss. And WebAssembly just does the job it's told to. I think someone missed my click. All right, so here's what we look at the memory when we compile. Since there is no direct addressing, all the pointer addresses can be bound checked. So what that means is that you don't actually have a big address, a number. You have an offset. And since we know that the block of memory, the WebAssembly module is running, and is this big, we can very quickly check that that number falls in that range to guarantee that we're not outside our memory block. That also means that that check is cheap. When you're jumping into a function, to do that little bounds check is really, really trivial. And also one of the other features of this is that the moment WebAssembly is a 32-bit address space. So if you're running on a 64-bit device, what you can actually do is load the WebAssembly module into RAM, into memory, put two hardware guards on each set of the 32-bit address space. And if anything was possibly going to escape the 32-bit address space, would trigger a hardware exception, which means you get that safety at zero runtime costs, which is a fantastic, fantastic ability. OK, so this is pretty much WebAssembly in a nutshell. This is all we have, one page, one slide. So quickly run through what's there. So we have voids, 32 and 64-bit integers, 32 and 64-bit floating points. As I pointed out before, the 64-bit integers are a great thing for C++. Lots of C++ programs use this. It's not available in JavaScript. The functions are in a big table. Everything's bound statically. I've talked about the indirection for the calling. And we have a bunch of standard operations there on the right. All the standard operations you'd expect on integers, adding, subtraction, multiplication, shifting on ints, also contains square root and float and ceiling for floating point. And it's pretty much, you know, it's conversions to do casting, of course, from C and C++. It's kind of a load store model. The actual WebAssembly virtual machine model is a stack machine. So if people have heard of virtual machines, there are two types. They're stack machines, and they're a register-based virtual machine. So it's actually a stack machine-based model. And there's a bunch of structure control flow at the bottom for your if loops and your for loops and your yada, yada, yada. All right. And the status. This is what you're all here for, right? Can you use this stuff? And the answer is a resounding yes. Right now, four engines have implementations in various stages. And this is monumental to get four large browser engines to work together to bring something to market. It's really amazing. And at the moment, these engines, like Chrome, implements the binary format. So all of the browser engines implement just the binary format. But at the moment, there's a lot of work going on about integrating with post message for WebAssembly modules and being able to store them in index DB. There's also, in the works, there's a streaming API. And of course, threads are high on the priority list as well. And as far as tools. Now, you people who are developers love developer tools. I'm hoping, anyway. In any case, LLVM is the compiler of choice today. You can actually, there are actually a lot of tools. There's a thing called M-scripten, which people may be familiar with. But it generates WebAssembly code. And it can generate asm.js as well. There's another tool called Binarian. And Binarian works with M-scripten to generate the WebAssembly itself. But it's a standalone tool. So it could be used with other compilers such as GCC. There are other tools as well that take the binary format and disassemble it into something that's human readable and vice versa. So there are lots of things you can play with if you want to experiment. If you're a really hardcore developer, you might want to have a look at the reference implementation, which is written in a stand-up markup language. And also, right now, there's a working group at the W3C that's working on formalizing the spec. Now that this standard was originally developed in a W3C community group, which isn't a very kind of an easy forum to get started with new features in the browsers with. So now that we've progressed to implementations, it's moving to a working group for proper formalization. OK, so I'm going to just do a couple of brief demos. I'm going to start with 101. Conway's Game of Life is one of these classic, classic games. And what's cool about it is it's one of the first things you learn in computer science. But the reason I wanted to show it to you is because I had a good friend of mine, an engineer called Sam, who decided he'd try and make it as small as possible as a WebAssembly module to prove something. So he compiled this without the standard C library, without memory allocation. And the WebAssembly module is two kilobytes. So I'll just switch over to my laptop here, and I'll show you it running. So this is basically a simple game of life. It's running here in Chrome. And as you can see, the performance is nice and fast. It's running. The little glider is flying down the bottom there. You get a rough idea how fast that runs. So that's pretty good. Now, of course, if this was a one browser story, it would be not a very interesting story. So we'll load up Firefox here. And so Firefox is loading up the WebAssembly module, running exactly the same code. It's done its own jitting. And the performance is basically identical. Two browser engines. All right. Where are we? Come on, Doc. There we go. All right. OK. So here we have WebKit in the Safari technology preview. And lo and behold, it's running as well. The same module. Running beautifully, not a problem whatsoever. So you'll notice here that the execution speed is basically identical between all of them. And just to round out the four, I'll run it in a virtual machine in Edge. Now, this runs a little bit slower only because it's within a virtual machine. But it is Edge, and it works. So this, I just want to bring home the point. Thank you. So I just wanted to show that this is a real thing and it actually does run in all browsers. OK. So can we just switch back to the slide for one second? All right. So this is my another demo. This is another classic computer science 101, which is a Mandelbrot set. So I literally was modifying this code on the plane on the way over here. And a friend of mine wrote the original, in fact. But the reason I bring this one up is because this is your perfect example of something that uses an incredibly large amount of floating point. And it's the perfect candidate for a WebAssembly module. This is actually in C++. It's bigger. Can we switch to the laptop again, please? And so this is your classic Mandelbrot. But what I'll do is I'll just click through and start zooming in on it to give you an idea how fast the computation is. I mean, that is calculating 4 million pixels every time I click the mouse. And this is how fast I can run it using WebAssembly. It'd be nice to compare to JavaScript, but in any case, if anyone's played with this kind of stuff before, they would understand. That looks like an interesting spot. Let's have a look. Just for fun. There you go. All right. We'll switch back to the slides again. All right. And I've one more little demo for you. And this is fantastic. This is a wonderful open source community project. It's by someone whose GitHub name is Shamadi. And it's called WebDSP. And what this actually is, is a video editor in the browser. So rather than showing you little toy things, this will kind of showcase what you can really do with WebAssembly. So can we hit the laptop again, please? So what this is, this is live video. We just played in the browser. Now, on the right-hand side, it has these nice little graphs that show JavaScript implementation versus the WebAssembly. Right now, we're just playing the video. But if we put on a grayscale effect, say, once the graphs catch up, you see we're pulling 63 frames a second with WebAssembly and only four using JavaScript. So this is amazing. It has a whole lot of little effects. So he is doing edge detection. So these are like convolutions and things. This is all running in a WebAssembly module, which is quite amazing. And to prove it's not a can demo, we can actually switch to the webcam. Hello, Google I.O. How are you, everyone? So I can do horrible things to myself. I can invert the color, make myself look really strange, like bacteria. Sunset's not very interesting. You can do kind of edge detection. And here, so if we're looking at this, the frame rates, you can see that's a lot more taxing on the CPU, but we're still pulling 58 frames a second with WebAssembly versus five with JavaScript. Or I could even turn myself into an alien. Evil of Earth, we come from the planet wasm to help you with performance. Fantastic. Back to the slides. OK, so I just wanted to show you this brief video as well. So the WebAssembly video editor, great piece of work. Jump on that GitHub address and have a look if you like. Also, we have an open source project at Google, which is all about compressing 3D point measures. So it's a great thing to use with WebGL and stuff like that. And the team that was building it have done a whole lot of benchmarking. And so what you're seeing at the top is their WebAssembly code compiled. And the bottom is asm.js. So it's not JavaScript, it's asm.js. And the whole point of showing you this is that this is actually quite a really intense compute like really amazing compression. And WebAssembly decodes the model in 12 seconds. But asm.js takes 18 seconds. So the whole point of this is that WebAssembly runs in 2 thirds of the time of the equivalent asm.js. And so WebAssembly is kind of an improvement on top of asm.js. And this is just the runtime. The actual parse time for asm.js is not counted here. And that's much, much higher. All right, so I guess enough of my talking and demoing. I guess you all probably want to work out how you can build a WebAssembly module for your application. And if you want to get set up on your developed machine, one thing is that the Mandelbrot demo and the Game of Life demo are both available over in the code lab area. So if you want to get started straight away, while you're here at Google I.O., you can go straight over there and have a go. Otherwise, when you get home, you can get it set up on your own machine. So right now, the LLVM compiler from the M script and repository is your best friend, as I say. So if you visit this link, basically, download the compilers, build the tool chain. Once you've installed it and build it all, you probably want to do something with C++ code and build your own WebAssembly module. And so once you've done this, it's pretty easy. Here are two command lines, one to build a C file and one to build a C++ file. It's as easy as that. It's all you have to do. The minus s, wasm equals 1 in the command line there, that is the thing that tells M script and to generate WebAssembly modules. Now, the output of this will be two files. It will be hello.js and it will hello.wasm. So hello.js contains all the glue code to call your module. So it makes it all very simple. And I'll show you how you call the module. So here is what you put inside your C++ code, something like this. If you want to pass data in and out, you can use a thing called embind. In this case, we're exporting a function called myfunction. And from that function, we're returning a typed memory view. And so to JavaScript, that will look like a typed array. Now, the beauty of this is that when you pass the memory from C++ back into JavaScript land, there's no copying. The typed array is mapped directly to the WebAssembly module heap memory. So there's no copying. It's just a direct access. It's a reference. So inside your actual HTML file, you'll put a bit of script like this. So hello.js contains the magical glue logic. And it also creates a thing called module. And so when you're calling your function, you go module.myfunction. In this case, I pass in the width and height. And that data variable is returned the typed array reference that I can work with. Of course, you might want to do the opposite. Because of course, this is part of the web platform. And one of the beauties of WebAssembly is that you can interact with all of the web APIs that already exist. So here's a fairly simple example using emasm, which is literally a chunk of JavaScript that gets called from the C++ code. You can also directly map your C++ classes to JavaScript objects. And you can even import JavaScript function names into the C++ code. It just requires a little bit more boilerplate code, but that's perfectly possible. So there are a bunch of really cool resources here. If you want to follow up a little bit more, the main site is webassembly.org, which contains the tools, documentation, examples, lots of stuff, some great demos. If you want to be involved in the design, know a little bit more about the nitty-gritty technical detail, you can go to the design repository, which is quite scary, believe me. But you might find that interesting. And if you want to get involved with it, you can get involved with the community. Because the community is where it was originally developed. And it's a friendly environment. You can go in and ask questions and get answers or make suggestions for future changes. In any case, when you first build yourself a nice web assembly module and you import it into your app, whether it's a progressive web app or not, if it's a progressive web app and starts running really fast, you know what your users are going to say to you? I can't believe that's not a native app. Anyway, with that, I'll open the floor for a few questions. And thank you.