 Is everyone feeling full? Full of food? Good. I will fill you full of knowledge. Knowledge of WebAssembly. So, this talk is called WebAssembly, Birth of a Virtual ISA. But I don't really like this name actually, so I came up with some other ones. Is this one? Maybe WeBeAssembling? Get it? We? Web? Okay. Moving on. The right to peaceably assemble. Any First Amendment? United States First Amendment? Okay. Simply assembling. I like it. It's a lot of s's. No? Make WebAssembly... Okay, no. On Mars. Okay, we'll go with On Mars. WebAssembly on Mars. So, some things that I've worked on. I've worked on a number of games for the Nintendo. Incredibles 2? No, there was not a movie. It was just a game. Cars, right, a 2E boom blocks. Really fun game. I worked on Overwatch before it was Overwatch. Yeah, I'm that much of a hipster. Thank you. Thank you. Okay. At Google, I work on Chrome. I also work on Native Client, which you may or may not have heard of. And now I work on WebAssembly. I also do some... I sort of help out a little on V8. Okay, so what is WebAssembly? This is what you all want to know. I've spoken to a number of the speakers, and people ask a lot of questions. They're like, well, what... Is it going to do this? Is it going to do that? Okay, well, I'll just... Let me tell you what it is. So, it's a new text in binary format spec. Okay, that doesn't mean a lot. So, it's designed to be fast to load and execute. So, it's an alternative to JavaScript. The idea is it's a compilation target, not a programming language. So, you would use something like C or C++ or Rust, statically typed languages, and you can pile to WebAssembly, and then you'd run that inside the browser. So, here are the last three points I really, really like. These are the most important in my mind. Safe. So, safe meaning you aren't going to be worried about crashing the browser. It's not going to happen. It's the same as JavaScript. It's going to be safe. Portable? Again, extremely important. It will run on any browser. This is the idea, you know, running on your ARM64. Do you have MIPS devices? Any MIPS devices out here? Okay. Well, it would run on that, too. And this last point is incredibly exciting to me. Many, many people have tried to solve this problem, how to run native code on the Web. And they've come up with any number of technologies, and they're almost never supported by all the browsers. And I know, because I worked on Native Client, and that was one of the biggest issues. WebAssembly, from the start, we have been working with all the major browser vendors. So, we have Mozilla, Edge, Chrome, and Safari on board. And very, very excited about that. So, this is the point that I like to make about WebAssembly. It's the shortcut to the JavaScript engine's optimizer. So, your JavaScript engine already does optimize a lot of code for you. That's why it runs so fast. But there are issues. So, let's talk about that a little bit. Who knows exactly how JavaScript optimization works? You probably have sort of a fuzzy notion, but maybe you haven't delved into the source code of SpiderMonkey or V8 or Chakra. Well, okay, so apologies to any of the JavaScript engine developers here, but I'm going to sort of... I'm going to describe it a little bit. So, it's tiered. The idea is that there are multiple levels of optimization. You initially don't have the code running at full speed because you don't need it, right? Hotter code is the code that you need to have optimized. And so, what the JavaScript engine will do is it'll start to run your code, right? And then it looks at the types flowing through the system and it says, okay, this looks like an int. And then if it's confident that's an int, then it will say, okay, I'm going to recompile this assuming that it's an int. It doesn't know that the next time you call it, you could pass on an object or whatever, right? If it makes a wrong assumption, it de-optimizes, and then you go back to the slow version of the code. I assume everybody kind of has an idea about how this works. So, WebAssembly is basically just short-cutting that, right? Why try and figure out what the types are? Why not just say, hey, here's my types, you know? So, okay, that's a sort of brief explanation of what WebAssembly is, compilation target, short-cut to your JavaScript engine's optimizer. What is WebAssembly not? It is not a replacement for JavaScript. A lot of people think this. They think, oh, well, you're just going to take my JavaScript and make it run faster, right? No, no, that's not what it is. Your JavaScript engine is already an extremely fast JavaScript runner, right? Execution engine. Converting it to WebAssembly and then running it is not going to make it any faster. It would make it slower. And there's issues with garbage collection as well. So that's not the purpose. It's also not a compilation target for languages that compile to JavaScript. So this one's a little bit fuzzy because there are languages that maybe could work, right? But if your language relies on certain aspects of JavaScript, let's say, the object model or things like that, WebAssembly is maybe not going to map perfectly, right? If your language is statically typed, and in the future, when we have garbage collection in WebAssembly, you can maybe compile WebAssembly or compile your language to WebAssembly in that case. But for now, just think probably not. Probably not. And the last point I want to make here is not a programming language. It's a compilation target. Now, some people might disagree with me here because, you know, you can compile assembly. You can write assembly. Anyone written assembly? Okay. It's not fun. You can do it, but the primary use case we're talking about here is taking code like C, C++, Rust, D, that kind of thing and compiling down. Okay. So why WebAssembly? Oh, there's a whole big list of things here. I'll let you read them. I won't read them out to you. But the important thing to think here is if you have code that is CPU bound, right? If you have code where you're doing a lot of computation, right? If you're doing code like, say, some things that you might see here like encryption, that's something that actually might work very well for WebAssembly compression. Platform simulation, that's one that I like quite a bit. VR and low latency, that's actually a very interesting point to make because for VR, you probably, and actually the next speaker will talk about this more and hopefully he agrees. It's important to be able to run extremely fast, right? Faster than 60 frames per second, if you can. Do you want GC pauses? Probably not, right? So being able to have consistent performance, which is what WebAssembly gives, that's very important. Video augmentation, being able to manipulate audio and video, all very important things. And so the link here is to the WebAssembly GitHub page where you can read all about that stuff when I give you the slides. Okay, so a demo. This is a Game Boy emulator that I wrote native code for. I did it in my spare time. And I actually compiled this to WebAssembly. Yeah, do you remember this game? Anybody? I thought with the 80s theme, this is in 1989, you can see that there. I compiled this into WebAssembly actually in my hotel. I never tried it before and I was just like, okay, let's give it a shot. I think it's pretty cool. So you might say, okay, well, we could have already done that with JavaScript. Why do we care? Well, so here's the thing. When you're running code that is CPU bound like an emulator often is, there's two points to consider. There's the one issue of how much CPU you use, right? But there's also how much battery you use. And so using less CPU is using less battery. So especially in a mobile device, that's very important, right? We want to be sure that we're not sucking up, you know, I mean, your phones don't last very long as it is. I know mine doesn't. Isn't it better to say let's use less of that and give people the same amount of power? Okay, so now let's go with some technical deep dives. Everyone ready for this? I know I am. Okay, so we have a simple function. You probably were looking at already. This is the Fibonacci function. I wrote it in C because I like C. I know this is a front-end conference and so maybe that's not the right perspective to have, but it's the truth. Okay, and in C++. Oh, right, it didn't change. C++ 14, yeah, look at that. You see the autos? Pretty cool. Okay, so it's a little bit of a joke, but the point I'm trying to make here is actually, we support modern C++. So okay, maybe auto is not the most modern C++, but anything you can imagine. Templates, unique pointer, shared pointer, all that kind of stuff. It's in there. I want to delve into. So, how do we compile it? Well, you may have seen this before. This is Inscripten. So, Inscripten is a compiler that takes C and C++ and compiles to JavaScript, to azim.js. But it turns out that that's actually also a useful compiler for compiling the WebAssembly. And so there's actually a function. Well, currently, this is how you do it. It'll be better in the future, but currently this is how you do it. You compile and you pass in binarian, which is the name of the WebAssembly sort of back end for Inscripten. And then you would say the functions that you want to export. In this case, underscore fib, and that's the C mangling of the name. Right, and so I just talked about those, too. Okay, so what's happening here? We're compiling C code using clang, VMscripten. Inscripten generates azim.js. So, who's heard of azim.js? Okay, yeah, good number of people. Who's used azim.js? Very few. Okay, well, so azim.js, it's kind of the history of WebAssembly. It's a low-level, optimizable subset of JavaScript. The idea is that you use type annotations on your JavaScript to be able to tell the JavaScript engine, no, no, this is an int. It's not an object. It's not a number. It's an int. I know it's an int. Make it an int. You have linear memory, so the idea is to use an array buffer, which is kind of a weird thing. A lot of people don't use them, but it's extremely useful for emulating memory for azim.js. And it basically represents the C address space. It's done via a linear memory array buffer. And you have import functions and expert functions. And as I mentioned, you have type annotations. So, let's look at how the Fibonacci function is converted into azim.js. So, what you can see here is it actually looks very much like the C code. And it actually looks JavaScript-y, right? You know, there's a little bit of weird stuff, but, like, there's the module there. The module is a function that's closing over the Fibonacci function there. And then you have the exports at the bottom. You see where it says return Fib-Fib. Yeah. So, at the very top, you see this use azim. That's the note to the JavaScript engine to say compile this as azim.js. And then you have these annotations here. So, this n equals n or zero. That's one of these JavaScript tricks you probably all know. When you or something with zero, it says, okay, make an integer. If it was a float, make an integer. Right? So, this annotation lets you run azim.js as basically as JavaScript, right? And so, you can see a plus b or zero. It's the same sort of thing there. It's doing an annotation that says make this an integer. Okay. So, wow, azim.js. It runs fast, right? You've probably seen it run in Firefox. And it's actually pretty good speed. Why not just use azim.js? Like I said, it's azim.js where engines can actually make it run quite fast. And it's just JavaScript, right? This is the quote that people say. When you run it, if you run it in an engine that doesn't support azim.js, it actually runs just like JavaScript does, because all the type annotations are what JavaScript already would do, right? But there's a number of problems. Parsing can be very expensive. So, when you take a giant blob of C code and you compile it, you can end up with azim.js modules that are megabytes large, right? And you have to use your JavaScript engine to parse that. It's very, very slow. Or it can be. Validation failure. So, this is another issue. When you fail validation, because all those annotations are required by azim.js, as soon as you get to the point of failing validation, it has to say, oh, actually you probably wanted this to be JavaScript, and it has to run as JavaScript. And the issue with that is it means it's hard to extend functionality. So, now imagine that we want to add shared memory. Okay, I know kind of a dirty word, but imagine you wanted to do that. Well, how do you do that, right? Now you have to add shared memory to JavaScript to be able to support it in azim.js, even though, ostensibly, they should be separate things, right? And this last one is a big one for me. There's no 64-bit integers, right? I mean, it's crazy. I mean, we're all running 64-bit phones, and we can't do 64-bit integers? Okay, so maybe we can do better. Okay, so we're going to take our azim.js, and we're going to do the next step. What is the next step? We're going to convert it to the WebAssembly text format. So you look at this, and if you're a closure fan, you probably go, oh, wow, that looks like Lisp. Wow, cool. It's kind of like Lisp, but there's a reason for that. The reason we have it look like this is because, originally, it was just in AST. It was just an abstract syntax tree representation of the structure of your program. So the reason that we like that is that it's very easy to parse. It's very easy to manipulate, right? And so you can see that here. It's very verbose, but it's not too hard to read. So what we have here is these two locals, right, A and B, and they, by default, are set to zero because we don't want non-determinism. And then we have set local, and we say set local B, I32 const 1. You never want to write that, but that's how it's represented so that you can very easily parse it and say this is an int. Okay, so now we have a loop. This is equivalent to what I have on the side here. It's kind of like a do while zero. Now, that seems weird, right, because that's not a loop. That's nothing if you fall through the bottom of it, right? The reason why it's represented that way is because a loop in WebAssembly is really just a label that is the top. You're just saying, if you ever do a branch, branch to the top, okay? And so you can see that here. We have exit and next. Exit is branching to the end. Next is branching to the top. You can think of it as break and continue, right? So we have this statement here, BRF. BRF stands for branch if, right? It's a very common thing to want to be able to generate if you're generating code. So in this case, it's equivalent to something like if n is less than or equal to zero break. And so what you see here is this LES. That stands for less than or equal to signed. So it's doing a signed integer comparison, right? Okay, so now we have a little bit of a tricky one here. This is set local, I32 add, get local, T local, get local. Does everyone get that? So what's happening here is we're actually doing a bit of a trick. T local is an operation that can take a value, store it, and then return that value as an expression. And that's what C will do for you as well. But we do it in a safe way. If you know C, you'll know that there's an issue with sequence points, right? And if you do an operation like that and you modify a value and then you use it elsewhere, it'll be illegal. But in WebAssembly, it's not the case because we have a strict evaluation order that's required. It must evaluate all of its operands from left to right. Okay. So then this is n equals n minus one, and this is returning the final value. Cool. But I kind of lied because really what WebAssembly is is a stack machine. So now if we have any fourth fans here, they might be happy, no? Oh, there's one! Hello! Okay, so what actually is happening here is we convert our function from pre-order, which is a pre-order representation, which is what I was showing before, into more of like a stack machine. And so now we can do the fun thing that you've seen maybe in your CS classes. Let's just run through it a little bit. I won't do the whole thing, but let's just step through a bit so we can understand it. So we have this i32 cons one. We push that onto our stack. We do a set local. Okay, that sets our value. We do a get local. We do another get local. Then we do our comparison. You can see what that does is it actually returns a value, right? It pops those two values and then it pushes back on the result. Then we do a brf that does our comparison. We do some get locals. We do our t local. And so what you see here is that it actually just sets the a, but it leaves the stack the same. Then we do our add. We do our set. Now it pops the value off the stack. So that's the difference between the t and the set. And then we finally do our subtraction. We set our n again. And then we branch back to the top. So you can see we iterate through the execution like so, right? And so this isn't just me sort of like yam and are up to you guys to explain stack machines. This is actually potentially a way that your WebAssembly engine would execute, say when you're debugging, because it's actually very convenient. This is exactly the way the WebAssembly is represented in the code, in the binary format. So you will actually be able to look at what's actually generated and step through in a very nice way like this. Okay. So now we have our text format. What's the next step? We generate our binary format. This is actually what's going to be loaded by the engines. All right. So who likes reading binary? I know I do. So what we have here is the asm binary format. We have the header, a type section. This type represents a function that's in the binary format. Then we have the function section that represents... It specifies that there is one function that has the previous type. Then we represent our exports, right? And then the code section, which has a lot of bytes here. Oh, why not? Okay, let's look at it. See? You see? Looks good, right? So the only point that I want to make here is that you can see this is the stack, the code that I showed you before, and this is actually what it ends up turning into. It's a very little bit of code. Very, very fast departs as well. Okay. So now we load it via our JavaScript API. And so what you can see here is we've got our array buffer, right? And that's going to be our WebAssembly module. And you get that, you know, maybe via fetch or something like that. And then you compile, and this is a...it returns a promise. So then when you get your value back, that's the compiled module, right? But a compiled module needs to be instantiated. So that's what we're doing here. We say new WebAssembly instance module, and then we pass in a collection of import functions. I can get into that later if you guys are interested. And so then finally what we do is we call our Fibonacci function, and that's all we have to do. So this is one thing that I want to point out to you that I think is very important. The name of the top level is WebAssembly. And yeah, that was all me. That was my claim to fame. So if you ever want to know who came up with the stupidly long name, it's because I suggested, why not just use WebAssembly? They were all suggesting, well, let's call it Wasm. Okay, so finally, what does your JavaScript engine do? It takes that binary format, it loads it, and... No, I'm going to skip this slide. Okay. But I'm going to stick with this slide. So it's actually going to generate code that looks like this. Okay, so maybe you don't read X64 assembly for fun. But I'll walk you through a little bit of it, because I... This is the stuff that I love, you know? This is just... Ah, it's so great. Like, okay, so look at this. XOR, RDX, RDX, right? So XOR... This is the XOR trick. A lot of people know this. It's a way to set a value to zero. Okay, so RDX is RA. RBX is R1, right? So now we do a comparison and we do a potential branch. Hey, so there's our if break, right? Okay, so now this one's a bit weird. This is an X64 thing. There's this LEA instruction. It's kind of like a way to do addition. Okay, so moving on. And then we have our sub, and then we have a swap, basically, that's happening here, right? And then we have our branch back to the top and a return. So look, that whole thing turned into this. It's like it's just... It's just that. You guys don't... I think that's great. Oh, man. So excited. Okay, so there's a lot more to mention. I'm not going to go into all of this. I just wanted to kind of give you an idea of what exactly we're talking about here when we're talking about WebAssembly. We're talking about taking something that's very simple, very low level, and compiling it directly down so that you know you're executing something quickly on your target architecture. So like I said, there's a lot more to talk about. There's linear memory, very similar as MGS. There's other control flow operators. BRTable is kind of like a jump table instruction. There's indirect function calls. You can import functions. That would be the way that you actually access JavaScript. There's export functions. That's how you basically would expose a function to JavaScript that you can call into. 32 and 64, but floating point operations with a full suite of operations that you might like. Start function, that's sort of like an initialization. So if you know much about the JavaScript module format, it's sort of like having that initializer function. And global variables, which, I mean, who doesn't like global variables? So if you want to know more or if you want to follow along because we do it all the development out in the open, you can go to github.com. You probably want to take a look at the design repo or the spec repo or the repo that I work on, which is called sexper wasm prototype. Say that three times fast. Thank you very much. Lots of questions from the audience. Great. This sounds a bit like Java applets. Why is this better? Java applets. Well, so that's interesting because here's a big difference. Java is a plug-in, right? This is running directly inside the browser. It's the same JavaScript engine, right? That's a very important thing to note about this. Also, it shares the same stack. So when you call a function out from JavaScript into WebAssembly, you can call back and forth out back and forth between WebAssembly and JavaScript, and there's no issues. Now, you could do that with JavaScript, but there are, sorry, with Java, but I believe that there are complications there. And again, that's a plug-in. It's disconnected from the browser. This is integrated. Excellent. Thank you. A couple of nichey questions, maybe. Will we be able to run some of the node modules with C++ add-ons in the browser with WebAssembly? I think that's likely. I'm not going to speak for what the Node.js developers do, but V8 has a WebAssembly backend built into it. So if Node.js decides that they want to include WebAssembly, then yes, of course, you could take a module, import it, and then you won't have to write platform-specific or even architecture-specific modules. So I think it's quite likely, yeah. Excellent. And a similar one. Would WebAssembly be useful to run scripting language on the client, e.g. compiling MRI Ruby to WebAssembly? So that's a good question. That's something that you can do, but there's a question as to whether or not it will give you the benefits that you want, right? So, for example, compiling Python or Ruby to WebAssembly, what you really would be doing there is you would be compiling the interpreter, right? The Ruby engine or the Python, like C Python to WebAssembly and then running that, which means that it has its own GC disconnected from the JavaScript GC, and there are issues there. So now, the future versions of WebAssembly, where we do have GC integration, maybe. By GC, you mean garbage collection. Sorry, garbage collection, yeah. Excellent, thank you. A couple of old guy questions from me, because I'm MC, so I claim MC rights. Do it. What's the backwards compatibility story? I mean, this is lightweight, it's gonna go down the wire very fast, it's gonna execute very fast, so I can expect lots of people to start delivering traditional websites this way. What happens if I view it in IE 10? So that's a great question. So, a lot of work we did originally was to make it so that it was polyfillable, and as you saw, it actually is very similar to AsmJS. AsmJS, you can already run, as I said, on older JavaScript engines. The issue with WebAssembly is that we will like to start diverging from JavaScript. And so, yeah, what is the story there? I think the initial story will be you compile an AsmJS module and a WebAssembly module, right? Later, you might have to say, okay, well, certain features we can't provide, and that's, you know, we have to move forward, right? Indeed. Does WebAssembly run in a VM in the browser? In a VM? Well, I mean, I guess if you want to call it the JavaScript VM, but like I said, it's generating actual assembly code, so it's jitted. Yeah, it depends on what you mean by VM. Is it the web if the source code for a page is not human readable? That's a good question, but so... This is a problem that already exists, right? People minify their JavaScript, and you could argue that, okay, well, but I can unminify it and I can read it, right? But it's, I mean, have you tried to read the Google homepage code on min... It's horrible. I mean, okay, well, it's hard to read, is all I'm saying. So WebAssembly, I don't think is going to make anything worse. Like, the point is that it's very important to us that you can actually read this code, and there is a text format, right? There's a one-to-one mapping between the binary format and the text format. So what you should be able to do is say, yeah, I can view the source. Here it is, here's this binary blob, convert it to text, and now I can step through and I can read everything, right? It's not going to be pretty, but it wasn't pretty in JavaScript either, right? So for people like me, because this will surprise you, but I'm actually turned 30. Thank you. Only last week. For people like me who ages ago realized that you could view source in a browser and look through all these weird angle brackets and HTML stuff, actually, then, that HTML was barely readable to me because I didn't know what it was. So what you're saying is this is just a similar problem. Nobody's going to be read... Nobody's able to read WebAssembly without some knowledge, and no one would gain that knowledge just in the same way that you've gained the knowledge of reading CSS and HTML. Yeah, that would be the hope. I mean, again, it's low-level, so it's not going to be super easy, but hey, you guys learned some already, so how hard could it be? Right? So the era of view source and people learning that way is not dead? I think we have a really smart audience and a really smart group of front-end developers, I'm asking and I'm stupid. You're very smart as well, Bruce. Yes, we're all very smart and I think we'll be able to... You'll be able to view the source. Ben Smith.