Video details

JavaScript: Introduction to WebAssembly | Guy Royse


Guy Royse

Want to write a web application? Better get familiar with JavaScript. JavaScript has long been the king of front-end. While there have been various attempts to dethrone it, they have typically involved treating JavaScript as an assembly-language analog that you transpile your code to. This has led to complex build pipelines that produce JavaScript which the browser has to parse and *you* still have to debug. But what if there were an actual byte-code language you could compile your non-JavaScript code to instead? That is what WebAssembly is.
In this session we will explain how WebAssembly works and how to use it. We'll cover what it is, how it fits into your application, and how to build and use your own WebAssembly modules. And, we'll demo how to build and use those modules with both Rust and the WebAssembly Text Format. That's right, we'll be live coding in an assembly language. We'll also go over some online resources for other languages and tools that make use of WebAssembly.
When we're done, you'll have the footing you need to start building applications featuring WebAssembly. So grab a non-JavaScript language, a modern browser, and let's get started!
PUBLICATION PERMISSIONS: Original video was published with the Creative Commons Attribution license (reuse allowed). Link:


My name is Guy Royse, I'm a developer advocate at Red Labs, so what the heck is a Web assembly? That's probably the first question you would ask, right? What's Web assembly? Well, in truth, SpongeBob fashion. I asked my computer wife, Karen, that be the SpongeBob Karren, not the Internet, Karen. And she told me that it was 50 percent Web and 50 percent assembly, which is kind of funny. Not really, but it's kind of weak joke. But it's also kind of true, right? Because it is assembly language for the Web browser. It's also kind of not true because it's moving beyond the Web to command line tools. And it's not actually assembly. It's bytecode. Assembly is a language that renders down the machine code or bytecode. And so it's both true and false at the same time. But more than anything, Web assembly is a solution to a problem like any good technology. Right. And that problem is JavaScript. What the hell, JavaScript? I mean, look, I mean, OK, so before I sit here in this JavaScript, I want to say that I'm a fan of JavaScript. I run the Columbus JavaScript user group. I do like JavaScript. I like it unironically, but it's got some really challenged corners. Right. Look at some of these examples. A number of men value is greater than zero. Wow. I wish that was true of my bank account. Right. My favorite here is permanent fire truck. This is actually a very reasonable statement. Fire truck, it turns out it's not a number. And so that's what it returns. If you say permanent fire truck, comma 16. Well, then that's 15, which is not a fire truck. What's going on here, of course, is that when you say a 16 four percent, you're you're saying make us Headspaces to make this. This is a hexadecimal number. So, you know, JavaScript dutifully goes and starts parsing. The string firetruck finds the digit F, which is 15, finds the digit IE, which is not a number. And so it's so old to stop here and 15. So you might also be wondering why I chose the word fire truck here. And it's because my my son, my oldest son, who's 19 now, but it's time he was about six or seven. He tells me this joke. He says, Dad, I'm thinking of a word. And it starts with the letter F and it ends in UK. And he's kind of smiling and he's like a fire truck. So. So I thought that was a funny example. Right? It's not totally not a passive way of me explaining my frustration with JavaScript sometimes. So the nice thing about JavaScript, though, is if you don't like it, you can pick a different language as long as it's JavaScript. Now, I know there's things like TypeScript and there's typescript now and you've got these tools will transpire, JavaScript, non JavaScript languages into JavaScript. But that's not really picking another language because it's still JavaScript under the covers. The previous talk. Mike, I was kind of talking about how we need to compile that JavaScript. These right. Compiling is what we want. We don't want to transport. I think the fact that we made up a word, made up the word transpired to describe what we're doing when we're converting S6 JavaScript to, you know, to something will run on Internet Explorer is a hint that we're doing something weird. But, you know, but we can transport and use different languages, we're not stuck with JavaScript, although our errors often come back to us in JavaScript. But there's actually kind of another flaw with JavaScript, aside from its weird syntax, not weird syntax, but it's weird edge cases and the lack of linguistic diversity that you can have for fun and work. And that's this is fundamentally a scripting language for JavaScript. We have to download the JavaScript file and we can minifie that and that helps. But there's still kind of big we have to tokenized that. We've got to you know, we've got to find all the tokens and all the syntactical tokens in there. Then we've got to take those tokens and pass them into an abstract syntax, a syntax tree. And then once we have that, we can execute it and we're going to do that every time. Now, there is caching that happens there, and VA does provide as much capability as it can. But this is an expensive process and it's just affects the performance of JavaScript and browsers. And so but what if there was some way that we could compile code to run in the browser? If we could compile code to run in the browser, we can pick whatever language we wanted so we wouldn't be stuck with JavaScript. We could. Make it small and tight and compiled into some sort of bytecode and so we wouldn't have this parsing problem, that this performance issue and that is what Web assembly is, Web assembly is code that has been compiled for the browser. And it's kind of cool. It's it's a virtual machine that runs in your browser, runs a web assembly by code. So I thought it might be really kind of make it crystal. The idea behind Web assembly is, is we might wanna talk a little bit about the run up that gets us to Web assembly. How did we what is Web assembly work? And so, I mean, how how does Web assembly do what it does? How does that fit into the bigger picture? And in order to do that, I'm going to start all the way back at the beginning with microprocessors. So with microprocessors that we all know, you've got a series of bits, ones and zeros, high voltage and low voltage that represent instructions that come in. And so an instructor might say to move this value from, you know, register X to register Y or put this value in a particular register. So we've got these instructions that come in. And early on, this is how you programed computers. You just wrote machine code that represented these instructions and very early on flipping such as a hit a button and hitting a button, very, very tedious. And to make that problem, make programing, these microprocessors less painful. We came up with the idea of assembly language. So here I've got on the on the left we've got, you know, just an arbitrary address and memory. We've got the binary representation, the bits that represent the sports machine, language instruction, machine, language four sixty five two microprocessor. Actually this was the code for my first machine machine language work, the first code I ever wrote in machine language back in the eighties. We've got those same numbers translated actually. You see, hacks is a little easier to work with, but you still get a zero zero zero. What does that mean? In assembly you can write a little text documents and use mnemonic things to make it easy for humans to understand. If you like ldi for load Y and then zero zero four zero. So load zero into the Y register and and then the assembler would go through this code and turn it into four bytes. You know, the symbol means this hex code and this symbol means this code. So there's a one to one correlation from the assembly to the machine code. And that was a great innovation. It made programing much easier, but it did mean that you had to learn a different assembly language for every species, the microprocessor. And it was also kind of hard to work with. And so we introduced higher level languages like C, this is, you know, some sample C-code here. It does the same thing at that assembly code does, but it's in C and with C we can take that code and compile it as opposed to assembling it. And we'll get a binary that's similar to the binary that we, you know, coded in assembly and then we can run that on our 675000 two microprocessor and life is Grande's. But there's a problem with this. I write it and see and I compile it for this processor. There's a lot of processors and so I need to compile for all the processors. And sometimes I can't take advantage of all the processors capabilities because I want to preserve backwards compatibility. I want to make sure my code will run on the most number of machines because I'm selling my software right. And so we solve this problem the way that we solve all the problems in computer science, which is we added a layer of abstraction. We added a we added a virtual microprocessor. And so instead of having a physical microprocessor, we got a virtual microprocessor that has a bytecode, it has an assembly language of its own. And we can compile to that bytecode. And then it will in turn, interprets the code into something that the microprocessor can see. So here we've got it's no longer C-code, it's Java code. And you can tell it's Java code because it's identical. Actually, you can tell us Java code because it's got that Kafe babe at the very beginning of it. And then that Java code runs on the virtual machine and then the virtual machine hands off instructions to the microprocessor in an interpretive fashion and these can get smarter and more sophisticated for performance. And you can actually get faster performance out of these virtual machines than you can the, the, the physical ones because you can optimize, you can do just in time compilation and optimized for exactly the specific hardware you have. So you crank a lot of power out of these things. It's actually pretty cool. Web assembly is exactly the same idea for the browser. So now we can take the C-code or whatever language you want, compile it to bytecode to web assembly by code and then create a file that all the major browsers can read and work with. So that's what Web assembly is. It's this idea of a virtual microprocessor in the browser. Pretty cool. I think it's cool. So let's get into the nuts and bolts of Web assembly and see how we can actually do this. And I'm going a little fast. They want to have time for my demo because I want to show off this stuff is real and you can actually use it today. A Web assembly module is literally just a file. It's a dot wasm file specifically. And I kind of think of them as like DL's. If you've got a Windows background at all, if you did in the early Windows development, because they're basically a bag of functions. And so here we've got, say, a simple calculator module that has five functions for doing basic mathematics, for doing basic basic arithmetic. And so that's all a Web assembly model is, is bytecode in a file with WASM extension, it's just a binary file, but then exposes these these functions in the browser you have it becomes just another file that you download. So on the left here we have our success or indexed e-mail and our app. Yes. And these are sort of the, you know, the classic trifecta of web front end web development. You know, you get your, you know, wonderful site, Texases for display none got a really basic HTML. We got some Naftogaz and then we've assembled just another file that the Web browser can download. And we've got some little code here that shows you how that works. But I got better slides for that. The interesting part here is the arrows. So your APJ, yes, of course, can interact with your dom and manipulate it. Right. That's that's the essence of Web apps. But you can also it can also interact with Web assembly and web assembly can interact with it. So my JavaScript code on the front end becomes something that Web assembly can talk to and it can talk to Web assembly. Now, you'll notice there's not an arrow connecting Web assembly to the DOM right up here. Right? Right up here. I'm airwing. I'm pointing out the wrong screen and that's true. Web assembly cannot talk to the DOM yet. It's being worked on. It's a hard problem, but I can't talk to JavaScript, which can talk to the DOM so you can write Gildo code to solve that problem. But this is just sort of the ecosystem these modules live in, to use it from JavaScript. We've got a really simple bit of code here that includes a callback and everything. The key thing here is to create a web assembly module. You call fetch and then just the path to the file and then you you feed that fetch call into instantiate streaming and that will asynchronously retrieve your module. Once you have the module, you can just call methods on it. The module has an instance, the instance has exports, the exports are water, all your functions are at and you just call them and use them like you would any JavaScript function. So actually really easy to use it once you have one. If you want to import some functions that Websense Web Assembly can call back against, then you can create this little this little object structure up here that has all your callback functions in it and pass that in or when you instantiate the Web assembly module. And so that provides functions that Web assembly can then use to call back. The idea here is, is this perhaps when we call, add, subtract and multiply, it also calls a callback reporting the value in addition to returning it. So that's the idea here. And so that would allow us to like log out all our answers in addition to having code to it in sort of an infinite model, in a way from the Web assembly side of things. I'm going to show you Web assembly text format, which is the assembly language for Web assembly. And whether somebody's text format looks like this, it has a module. The module declares everything starts with the module. It's the container for everything. If you want to declare some functions, you just declare them using the syntax here. Func dollar ad, you give it a couple of parameters. If you need them, you give it a return of value if you need it. These are both thirty two integers and it returns a 32 bit integer and then you've got your implementation of that function and same thing for subtracting in other functions. To export those functions, you just have to have an export statement and give it a string right here, then, you know, it's an externally facing aliased to the internal function. So you can affect have private functions and whether simply by not exporting them to imports it to access that math callback that I showed you on the JavaScript side, you just use this import syntax here and you just use this two keywords that were there in that object hierarchy and you just give it a name internal. So this is just mapping it internally. Whether assembly is stack based, so a stack based virtual machine. So what that means is that when you call a function, there are no intermediate variables. You just use a stack and stack. So local get dollar means get the first parameter that was passed into this function and put it on the stack. That means get the second one. So now we have two items on our stack, five and 10 when we call ADD and we'll pop those two values off the stack because at wants to values, if they're not there, the total error and then it will add them together and push the answer back onto the stack. Then when we're at the end of the function, well then there's one item on the stack. That's the return value. So that's that's how these work. This is how a stack based assembly language works. Here's a slightly fancier example that shows the callbacks in action. And this is interesting because you've got a mind. You've got to be mindful of how the stack works here. So after we you know, I find a local variable up here, you can actually define locals. And then after we add them, I set that local. And then in order to return, in order to call the callback, I got to put something on the stack for its arguments. So I get the local that I created. And then in order to have a return value, I got to get that again. So I end up having to get that local value a couple of times in order to return it and do the callback. So the attacks are a little clunky and weird. Sometimes, however, you can use expressions to clean up your code and to make sure what was in my text format with a little more lisp, shall we say. And so that's it's kind of fun, too. It makes it makes it actually a little more pleasant. The program in a lot of other stuff in the syntax here, you've got a shared memory, which means it's a shared block of memory that JavaScript and Web assembly can both see. You've got Global's, which are like shared memory, but they're just an individual value that JavaScript and Web assembly can again both see. And you've got tables which are, again, JavaScript, Web assembly, both see, those tables are a way of doing like list of functions so that you can dynamically bind functions in languages like for polymorphism and C++ and stuff like that. So this is some other more advanced stuff that I'm not going to go into. If you want to program of assembling something other than web assembly text format, which you might want to do, these are the two go to languages that are have the deepest supports at C and C++ and Rust. And I think of the two. Ruff's actually has the better support rust out of the box. Just install rust and you have Web assembly support. It just works. I mean, you have to do stuff, but there's nothing extra that you have to install other than a particular target. And there's a lot of others go out to this link here at Austin WASM Languages, I was looking at the The Day and Kobol was even on the list of all things. So there's a lot of a lot of stuff happening in the Web assembly space. Coming down the pike, you know, I've just been showing stuff with numbers and there's a reason for that, and that's because Weber simply doesn't know what a string is. And that's because what is a string, right? What a C mean. When it says a string, what does it mean when it says a string that UTF encoded? Is that what's the encoding on that? And so one of the things that are coming down the pike is interface types that allow to create some common types that Web assembly modules can export. And that's like the browser would understand how to make use of their super bleeding edge. There's some polyphenols that make them work. I was playing with them. And then newer code says we've turned that off for the time being until the standard stabilizes. So it's super bleeding edge, but this will solve this problem. Threads are I believe friends work in Firefox. Now, I haven't looked at them yet, but the thing I think is particularly interesting is Wasey or YRC, this is the Web assembly systems interface and that allows you to file IO and network IO outside of the browser. So if you're doing something with a command line tool, like with WASM Time, then you could use waisting. And I'm actually going to get a demo that along with some other things here really quick. So excuse me, let me let me grab a drink here really quick. OK, it's water, but it had root beer in it nowadays, kind of root beer like. So let's get on with the demo here. So I did want to do that, but that's OK. So I've got I've created fizz buzz in Web assembly. And I've created it three different ways I've created in Java for the browser once in Web assembly, text formats, once in Rust, and once I created a buzz that runs on the command line, the two that run on the browser. I'm using Jasmine because it's convenient embeddable sort of testing framework. I just had to drop some files in there. I'd have to install anything. And it runs. And hits looks for the fishbowls wasm. And the rest of his boast that wasm and test them both and I have this up and running now, so if we bring this up and I hit refresh, you see that it does indeed run all the test pass. Now, I want to prove that this is real, not vaporware. So I am going to actually compile something here. So here we have Sizz Buzzacott whatt. And so this is the code that does fizz buzz returns minus one, furphies, minus two for buzz and minus three for fizz buzz. And so I'm not going to go with the code to mushier, but I'm going to go and change the constants. So for Fizz Buzz, I'm going to return 30, 20 and 10 instead of negative versions of those, and then I'm going to compile it using web assembly, binary toolkits. Whether have binary toolkit or wabbits has a tool called whack to ASM, so Abbott has to assume, which is kind of funny, and then I pass it my white file so we get to WASM is muskat and that will spit out a new ways and file for me. And if we do a little less here, you'll see that the time stamps change to 205, which is my local time, and if we do a hex dump on the Facebook, not WASM, you'll see that that is the entire file. It is one hundred eleven bytes that is compact AF, isn't it. So I've changed this stuff. Other things. Let's see it fail. Ronke combination now we now all of them failed. Well, not all of them, but all almost all of them failed, and the last one, I didn't touch them, it didn't fail. And I can actually go out and pull these from me, from the consulate. So let's say let's am for module equal awaits. And I have a little helper function at called load wasm and I say load whatt. Fizz, buzz wasm, and then I've got a function amnot fizz, buzz it even out of Texas and let's pass it like 15. It returns minus 30. Let's pass it 10. So that broken version is there. I can also go out and get the rust version. Which I'm actually I'm not going to show the restoration type in the restoration because the past long and complicated, but you can see that it's actually doing things. The restoration here is a lot simpler because it's rust and it's a higher level language. And so I'm just doing a modulus and doing some mashing and returning it here. But if I want to build it, I can just do I can do. I've got a cargo thommo set up for this new cargo, build socialite's targets. And then I got to say wasm thirty two unknown on my own. And then I want to do a release bill because that will make it about two hundred bytes. If I do a debug build I'll get like one and a half megabytes because like everything from Ross will be in there. So that creates the new file. If I do an LS. Targets WASM 30 to release. We can see that we have the physicians not wasm that is eight bytes by the hex dump. You see that that is. Yeah, I got to get an actual filing, Tony. You can see that it's very, very short and that, of course, will run as well. The really cool thing is that I think is the fizbo as I wait and I hear I have written a fully string running everything using the sort of temporary version of Web assembly interface types. So here we're importing something from WASM Time from Waza Unstable and. Right. So we can write out the standard IYO. And this is actually a lot of code that defines strings and does the fizbo calculation and writes new lines, and then in order to take numbers and turn them into strings, we had to take strings and turn numbers, tournament strings. We had to do loops and all kinds of crazy stuff. And all this code is out and get help for you to explore. But the cool thing is, is that I can do to ASRM. Fizbo biodata whatt, and it just compiles it, it just works, and so here we see that all of that code is six hundred nine bytes and we do wasm time. Which is the command line tool. This code loops from one to 50 and computes this buzz for everything, and if it's not a No. And then it just skips it and so this is a little command line version of is so kind of cool, it's real stuff. You can do real things with it. I think some time is kind of like, no, just to Web assembly. That's sort of, I think, a proper analogy for it. So, yeah, that's pretty much what I got. Here's a good little list of resources here to check out what was on my GitHub dotcom slash web assemblies. That's the official stuff. Mozilla Developer Network has great documentation on using the Web assembly, JavaScript side stuff in the browser, the web assembly, binary toolkit. Wabbits is here. Well, sometimes the command line tool you just saw me use, it's great. There's another thing similar to it called Lasama, which even has a package called WAP them waza. The website specs are at last. You got Dev. If you want to build something big. Rust is probably the best language to choose at the moment. And of course, there's link to awesome WASM languages. Here's a link to the code slides. You can hit that QR code and that will take you out to my GitHub and you can go get all that stuff. And worth noting, I work for it a slab. So please go check out our stuff. We've got a Dischord server and some community forums, and if you want to sign up for a free class at Rutgers University, we'd love to have you. And that's pretty much all I got. Thanks a lot for listening. My talk. Give me a follow. And are there any questions? We have time for questions.