HELLO WEBASSEMBLY - A BEGINNERS TUTORIAL TO CODING WEBASSEMBLY (WASM) BY HAND.

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey welcome to this first video in a series where we're going to deep dive into webassembly now of course in this first video we're going to understand what web assembly is and why it's important and then we will actually be hand coding our first webassembly module now in reality you're probably never gonna hand code webassembly for real world projects you will always use a high-level language such as c or c plus plus or rust or assembly script to create that web assembly for you but if you don't understand what web assembly is and you don't understand the instructions and the code that underpins webassembly then you're not going to know what the compilers are doing to translate that high-level source code into webassembly so really by gaining that in-depth understanding of web assembly under the hood and be able to hand code it yourself then you're going to have a deeper understanding of what's going on in the browser or in the back end and therefore you're going to be able to write your higher level language source code much much better and then that's what we're going to focus in on this video series so the first question you're probably asking is what is web assembly if we think about the world that we've been living in for the last 25 years or so there's really only been one programming language that the web and the web browser support and that is javascript so if i want to write a piece of code and i want that to run in the browser i have to write it in javascript now there are other languages that of course that you can create to target browsers but at the end of the day they are going to be transpiling the code back down into javascript so typescript is a perfect example of that where a lot of people are writing typescript today but underneath the hood when you want that to run in a browser it needs to get transpiled back down into javascript to be able to run webassembly changes the game because now javascript isn't the only language that can be run in a browser there is a second language and that language is webassembly so what does that mean for the web and the average web developer well the first thing to think about is webassembly is fast because it's a byte code because it's not dynamically compiled and it's a statically compiled code base and because it's a bytecode language which is very close to what the machine will be executing then therefore it's going to run fast think of it as near native performance and also if you have a much smaller compilation steps which i'll go through in a second the second thing is it's very efficient it creates very very small code bases so it's really transportable and then the third thing that's really important there is it's actually really interoperable with javascript so it's not a situation where you can say i'm going to choose javascript or i'll choose webassembly they're really easy to interrupt between each other because you can think of web assembly modules as being equivalent to es6 modules so therefore you can sort of call functions from webassembly or webassembly functions can call functions in javascript so we've got great interoperability between the two languages and ecosystems the next thing that is really important is because webassembly is so low level it actually enables other languages to utilize and target it so for example as i said there are compilers to webassembly from rust from c plus plus and c and obviously there is one called assemblyscript which is like typescript that compiles down into webassembly so that opens up lots and lots of other ecosystems and languages to be able to utilize the web now that's important because there's lots of companies who've got old code bases maybe 25 years 30 years plus which are built in a different language and therefore they can reuse and liberate that source code to create really fast efficient code that can be running in a browser and that's super cool and there's lots of examples and demos of that today and then probably the last thing that i think is super important is that it's secure it runs in a sandbox environment and therefore it doesn't have access to things like your file system or anything else on your machine that you wouldn't want webassembly code to be able to access now you can give permission to access these things right and there's lots of very cool stuff in in progress just now but by default it doesn't have it it's a sandboxed environment now as exciting as webassembly is for the browser it's actually super exciting for the back end as well because it's sandbox and secure and efficient and it's essentially a portable byte code then actually a lot of people are thinking about this as a replacement for containers in the future if i want to run executable code and my backend solutions are really secure and tiny then guess what web assembly is going to provide that capability as well so that's really really exciting stuff and then we'll talk about how that could work in the back end systems and a lot of companies are doing that just now as well so if you look at things like blockchain for example things that are powering smart contracts is essentially web assembly code and that's not the only example of that i've seen companies like shopify for example allow you to give web custom webassembly code that you can run in the back end to execute your operation so webassembly is going to be huge and again it's probably going to challenge things like container stock or containers uh in the future so to give that even smaller sandbox environments for you to run your code so what we're going to do now is just before we start coding our own webassembly modules and deep diving into that i thought it might be fun just to show a webassembly application that someone else has written um i think it's really cool it's a it's an old zx spectrum which somebody has converted into running in web assembly so essentially you have a zx spectrum running in a browser actually let me just bring that up in my machine so if we just run that i'm going to hit the reset button here so you can kind of see the the cool startup sequence so we'll just hit soft reset and cool right and then it's got a kind of this 1982 sinclair research so really retro etc and actually you can even code against this so we could do a hello world but within webassembly uh in a basic programming language right let's show you what i mean so if i just type in 10 print and then we'll just do hello world uh and then we'll do the the classic spectrum thing which is 20 uh go to 10 and then we'll just hit run and then you can see hello world all the way down and you can just keep scrolling and scrolling and scrolling so that's a little bit of a different hello world what we've done in this case is within a browser we are running a zx spectrum machine with the power of webassembly and then we've written hello world and basic language and ran that within the spectrum running within the browser really cool but loads of other peoples have been doing amazing stuff as well with that they've been running things like game boys or taking dos or windows running all versions of windows in in browsers which is kind of cool so if you want to improve backwards combat that ability of all machines you know you can you can start to translate that old code and then run it in your web browser and you can imagine where that's going as well right you can then start to run docker containers or linux containers within your browser as well so i think the uh the possibilities are endless in this case so now that we know what webassembly is and why it's important why don't we just go ahead and start hand coding our very first webassembly file so in order to do that the first thing we're going to do is bring up vs code so if we just go into my machine for a second and we will just open up vs code in order for us to hand code webassembly it makes sense for us to use one of the visual code extensions so if we go into our extensions palette for a second vs code and we just type in web assembly and you're going to see this webassembly toolkit for vs code and it's published by the webassembly foundation so if you just click install for that that will download and install that and that's all you need to be able to get things like syntax highlighting um as you start creating your webassembly modules so now that we have the vs code webassembly extension installed let's create our first module so i'm going to open up terminal for a second uh i want to just create a working area for us to create a coding so we'll just uh make dir we'll call it wasm play 2 in my case and we'll just cd into that and what we're going to do is create a new file and we'll call it empty module so this is going to be the most boring file you can imagine right it's just going to be an empty module so we'll just call that empty dash module now when you're hand coding webassembly files the file extension you should use is what w18 that stands for webassembly text format and that's a textual representation of a webassembly binary which we'll produce a little bit later on so we'll call this emptymodule.what which is a great name so we'll touch that and then now i've created my empty file i'm just going to open this up in vs code so i'll just type in code space dot and that will launch vs code into the directory that we have specified so let's just make this a little bit bigger we'll clear that and to create our very first module in webassembly text format we are going to type open parenthesis module and that's it that is the most basic module you can create in webassembly format so it literally is a empty module and that is in webassembly text format so what we'll do now is compile that module see what the bytecode looks like and then we will make it a little bit more interesting maybe add some numbers etc to that so unfortunately so unfortunately i can't take that webassembly text format file that i just created i can't take that and just plonk it in the browser and run it because the browsers only understand the binary format the dot wasn't format or webassembly module format so what i'm going to have to do is run it through some sort of compiler which will take that webassembly text format and convert it into bytecode into the webassembly module bytecode and there is actually a tool that does that uh it's part of the webassembly binary toolkit or as it's otherwise known as is wabbit so a little bit more funny there webbit w abt and there is a tool within that toolkit uh which is called what to wassum and you can kind of guess what that does right wac as in webassembly text format to wasm webassembly module and all you would do is pass in the name of the web file and then output the name of the wasm file that you would want and then it would create it so we can actually just draw that up on the ipad for a second so if i have a first box here and we'll call that empty module dot what and then i'm going to pass that into what to wasm and it's going to output my empty module dot awesome so now we need to understand how that works what we're going to do is download the toolkit and then compile it so to install the webbit toolkit the first thing you need to do is just understand where it lives so if we go on to github.com you will see under the webassembly organization there is a wabit repository and that's really what we are going to download and install and and if you've got time you feel free to have a look at it uh there's lots of interesting stuff within there you can get but the tool we're going to use is what's on my screen there which is the what to lasso file and as you as you can see there it translates from webassembly text format to website blade binary so again feel free to go and spend some time and have a look at this toolkit is really really cool so what we're going to do just now though is download that onto our local machine so that we can therefore convert our wat file to a wesson format so to do that i'm just going to bring up my terminal so my terminal uh we need to get cloner into here so i'm just going to do a git clone dash dash recursive and then i'm going to pull that wabbit repository that we saw there a second ago so i'm just going to return that and whilst that clones it'll take a few seconds to do that so now it's on my machine if i just do an ls you will see i have got a folder called wabit so let's just cd into wabbit and then you can see there's lots and lots of interesting stuff in there the big thing that i'm interested in is i'm going to run cmic to compile the wattawasam converter so in order to do that i need to install cmate on my local machine so i will just do brew install cmake if you haven't installed brew already go download brew it's going to make things a little bit easier for you but i'm just going to run that just next i've pre-installed that and then again it'll take a few minutes for install cmake so we'll just give it a little bit of time and then it will install that on my local machine and then we can run the build okay now that i've got cmake installed what i'm going to need to do is create a build directory so that i can build the what to wear some uh binaries so i'll just create a folder called build so make directory build i'm going to cd into that and then what i'm going to do is run cmake within there so i've done that so i've run my cmake and then what now what i'm going to do is run my make command also so now that i've done that i'm just going to run make and it's going to sit and build up for me it's going to take a little bit of time and once that's done then we will have the white to wire some converter and then we can convert that web assembly text file into our wasm format so now what i want to do is convert the empty module.what file that i created earlier to that dot wasn't format so to do that i'm gonna use that binary that i created two seconds ago and i'll just do a dot dot and it was in the wabit folder and it was in the bin and the name was what to lasso so that's the executable of that i'm going to run i'm going to put an empty module dot what because that's the text format file that i want to convert to wasm format and to do that i need to put minus o minus so just basically means minus output so give me the name of the output file that we're going to create and in this case we'll call it empty module dot wassum and if i just run that it's going to take that file and convert it to wasm okay so now as you can see there is now an empty module dot wasn't file created on my local machine now that the wason file is actually created we can actually just inspect the contents of the wason file to see what it looks like so if i just type in a xxd which is a linux command and then put in empty module dot wasom and i'll just run that you can kind of see there's the the binary code that's uh been generated and there really isn't much to it you can kind of see a zero zero sixty one and it's set uh 73 60 and then this zero one zero zero and we'll go into the details of what that means a little bit later on but you can see it's a very very small file and of course it isn't binary format now if you wanted to see what the binary although in this case it's really hexadecimal but if you wanted to see what the file looked like prior to generating it you can actually do that with the watt to wiresome converter as well so let me just bring up the what to assume again and then this time rather than doing a minus o on empty module.wasm what we can do is type in minus v and that is basically verbose mode and then that will show you what the outputted version of the file would look like so if i just run that you can get a little bit more details here so actually as you see here this zero zero six one seven three six d look at the translation on the right hand side so it gives you a sort of an understanding of the op codes underneath that so you can see here that this is wasm binary magic that's all that stands for is zero six one seven three six d stands for this wasn't binary magic and then underneath that as well you see zero one zero zero and that is wasm binary version so this is an empty module and essentially every webassembly module that you ever create will have this header because it must be present and everything that you do alrighty so now that we've created our very first webassembly module we probably figured that it's not very useful because i can't do anything with it in browser what i really want to do is actually be able to call that from within my browser load up that webassembly module and execute that so to do that what we'll do is we'll just create a very quick function that will maybe uh square a number and then we'll call that and then see executing within the browser all righty let's do this let's create our first useful function so the first thing i'm going to do is create another one file and what we're going to do is we'll call this math.what so this is where we're going to store our square function so we've got another watt file and again i need to create a module as i did before i'm just going to hit return and you can kind of see the bracketing mechanism there but i've got this module next thing i need to do is declare my function that i'm going to create and this is just like creating any other function that you might create in any other language whether it's javascript c c sharp whatever right you just define what your function's going to be so in this case we're going to call it the definition for a function is called thunk and you see it lights up there um we're going to call our function square so the dollar before that's just signifying what the name is going to be we're going to have some parameters so what we will do into the square function is we're going to pass in a number as a parameter and then we will just essentially multiply that parameter by itself and then give the output of that so we'll have a param um in this case so that's the that's the sort of webassembly text format code for parameter and and it's expecting a number of i32 so it's expecting a 32-bit integer value now this is kind of where javascript and webassembly differ because in javascript world i can dynamically create variables i don't need to define what their type is but in in webassembly world it's statically compiled right so therefore i need to know what the type of my parameter is in advance so in this case i have to specify there's going to be a 32-bit integer and then of course the next thing i need is i need a result so the way you define what a result is in uh webassembly text format is by calling a result and again you have to specify the output type so in this case it's going to be an i32 so it's i'm going to return a 32 bit integer so now that i've got that um i'm not going to deep dive in this video what everything means in this webassembly text format um and the reason i'm not going to do that is we're going to cover that in some other videos because it's going to get a little bit weird because the way webassembly works is it essentially runs as a stacked machine and what i will do is explain what that is and how that works in another video but for just now just kind of bear with me a little bit on what's going on so the the next command that i need to sort of run so this is the first sort of instruction is i want to get access to that parameter and the way that i do that is i need to pull the parameter and and and then essentially take that value and pop it onto the stack again i'm not going to go into the details too much in this video and the way i do that is i run a local.get and then i want zero so i want parameter zero so that parami 32 whatever number i'm passing in that local dot get is going to pull that value and then it's gonna push it onto the stack again in a future video i'll explain what that means and then i'm just gonna do it twice i'm being super lazy on this case um because i i essentially need to multiply the same number by itself so and i need that to appear on a stack so i'm just going to do a local.get0 twice and essentially what is happening is i've pulled this number twice and put it onto the stack and then the last thing i'm going to do is i'm going to multiply those two numbers that i pulled onto the stack together so i do this by doing i32 dot mul and all that essentially means is i32 is again is an integer 32 32-bit integer it's the multiplication operation and then to do the multiplication it is expecting two numbers from the stack right and then whatever two numbers the last two numbers that are on the stack is going to pull them and then it's going to multiply them together so you can kind of see what's happening is so i put the number that i passed in as a parameter onto the stack i've done it twice so i put it a second time so if you can imagine the stack let's say i'm multiplying 10 by 10 so i'm squaring the number 10 i would put 10 on the stack as the first item on the stack and then i would put 10 on the stack again because i've got it twice and then the multiplication operation is going to pull the last two numbers which is 10 and 10 and then it's going to multiply those two numbers together that's the key thing and then once it's multiplied that together it's going to take the result which in this case would be 100 and then it's going to put that onto the stack now remember what i've done with these two items is because i put them on the stack in order to do the multiplication i've taken them off of the stack and then what will be left on the stack is the number 100 after the multiplication that's going to be a hundred and then the result is really simple what happens is a function in webassembly world will just return whatever the last item is in the stack in this case it's going to be a hundred and then it will return that now this is pretty complicated i went through really quickly there but don't worry in my next video i'm going to spend a lot of time and we're going to draw out the stack and we're going to explain what the stack is doing etc so that you understand completely what's going on but for just now all i want you to see is essentially that i'm passing in a value it's going to multiply those items together and then it's going to return it and we're going to get into a lot of depth on how that works underneath the hood in my next video okay so now that i've done that we've saved that the last thing i need to do is just to export that function so that javascript can access it so we'll just do export and we're going to call it square and and i want it to return the function square so there we go so that's basically the equivalent of an export in javascript so i'm just going to save that i've created mymath.what and now what i'm going to do is i'm going to compile that from webassemblytext format back into wasm exactly in the same way as i did earlier so let's just come back on to my terminal we'll bring up the screen and what we will do is in fact let's let's just do a rather than let's do what to was some verbose again so that we can just see the binary and i'm just gonna put my math.what in there so let's just run that and then you can see oh my goodness it's generated a lot of code there right um i'm not going to go into the detail there but you can kind of get the idea that it's generated the equivalent of my webassembly text format into binary format so again if if you were to kind of look at this you see in here that it's doing a local.get it's doing a local.get it's doing a multiplication so it's the same sort of stuff there i'm not going to go into the details too much here but i just kind of want you to see that so what we will now do is do the actual uh conversion so as i did before i'm going to call what to assume and this time rather than putting empty module i'm going to put my math.y and then i'm going to output so my minus 0 and i'm going to put uh math.wasm because i want to call it math.wassum uh we'll just run that and you will see it has created mymath.wason file and then i can do my xsd math.wasm as i did before and there you go right here's our binary it's really small do you see that it's like really really tiny and you can kind of see square there and but it's a it's a really really tiny file in fact if i do an ls minus la you you'll see that that that file is like 151 bytes super super tiny so what we'll do now now that we've created our wason file we're going to execute it in two places so the first one will run it in node.js and then we'll actually execute it on a browser as well so so the first thing i'll do is i'll just create a new node.js file so we'll just type in npm mini i don't really care what it's called i'm just going to hit return lots uh that'll go create that let's open up uh visual studio code uh i want this to be a module because i'm going to be super lazy and i'm going to cut and paste this into the browser so we'll just uh make that as a type module and therefore that will allow us to use the uh the import statement and then i'm just going to create a new file and we'll call it index.js and then what i'm going to do is load the wason file and then we'll execute it so we'll to do that i just need to import fs from uh fs so that's given us access to the file system and what we're going to do is just load the math.wasm file that we created earlier so we'll just put const and we'll call it math [Music] equals so we'll just type in cons then we'll put in math wasm uh equals fs dot read file synchronously and then all i want to do is load it from the uh math.wasm location which will do that and then just for a bit of fun we might as well just do a console.log on this and see what it looks like so mathwa some uh i'll put my semicolon there and then if we come back to my terminal and we just run nodeindex.js and you can see that it's returning the exact same bytecode as we have before now that we've loaded our wasm file into a buffer we're just gonna instantiate that buffer as a webassembly file so uh to do that uh there's a command called uh webassembly.instantiate as you can kind of see there i know you're going to pass into the parameter is an unsight integer array using the math wasn't buffer that we created and then you can see it's going to do an export and it was going to return me a module called math so if i then just do a console.log math.square and then pass in the number i want to square then it's going to execute that out so if i just run that go to my terminal and then just type in at nodeindex.js again and you'll see it returns a hundred so and i can put any value i want in there so 50 and it run returns 2500. the key thing is as as i sort of said before is all i'm really doing is doing this webassembly instantiate i'm passing in the wasm file that i loaded up here and then i'm exporting out whatever my exports are from my webassembly file so in my particular case i exported a function called square and as you can see that square function that i created in wasm is available it's been exported and it works just like any other module or any other exported function that you would have in es6 and so therefore i just call math.square and it works and that's super cool because as i said at the beginning of this video this interoperability between javascript and web assembly where i can call uh webassembly from javascript and i can call javascript from webassembly becomes key so there we go we have created our very first uh webassembly file by hand and we've then executed that within node.js that's kind of cool now just to complete the loop what we're going to do is we're going to do the exact same thing but we're going to do it within browser so the first thing we need to do to make that work in a browser is actually create yourself a very quick server so i'm going to create myself an express server very quickly so we will call that server.js so what i'm going to do is very quickly is just paste a an express server into the server.js file so you can kind of see it's important express it's going to use port 3000 and then what i'm going to do is just serve up anything that is in the public folder so let's just create a new folder called public i'm going to take a copy of my math.wasm and i'm just going to stick that in the public folder so that we can serve that up as well and then it's essentially gonna return anything that is in that folder so we're gonna do quickly is just check that the web server works okay so if we just type in no server.js you'll see it's returned a module not found so i need to obviously do an npm install minus one is save express that's just gonna install for a second there that's now working and then i can run nodeserver.js again and you'll see it's listening on port 3000 and now if i bring up my browser for a second and i uh just go to localhost 3000 you should see that is now returning hello world so what i'm going to do now is i'm quickly going to create a new html file we'll call it test.html and what i'm going to do is i'm just going to paste in the code very quickly it's a standard sort of html file and all i'm going to do is call my square function and then output the result to the console so if you look here you can see i'm just running the script which is script type is module i'm calling webassembly.essentia screaming and i'm fetching the math.wasm that i just put into my public folder there and then within that on the return you're seeing i'm essentially calling the square function passing in the value 10 and then i'm just outputting the result to the console so if i come to my browser for a second we'll just put in localhost 3000 and test.html and then if i go to the developer console so if we hit developer tools you'll see 100 is returned and if i just go back into this and i change that value maybe i put in 20 uh we'll just hit a refresh over here and you'll see it's 400 and then if i change this to a big number maybe 100 then i would expect that to be something like 10 000 or whatever and you can see 10 000. so what you're now seeing is that i'm running my watson file i can run it on the back end with no js but i can also run it in the front end by the browser and that wasn't file is callable just like any other es6 module there and we can call the functions that we export get the result back and that is javascript and webassembly working together so this is the end of our first um so this is the end of this first video i hope you enjoyed it i hope it gives you a bit of a deep insight to how webassembly works and in future videos as i said we're really going to get into a lot of the depth so the next video in particular we're going to focus on what the stack machine is we're going to really look at some of the more complicated uh functions and what else you can do underneath the hood and what the various assembly instructions will be so anyway i hope this has been useful and i look forward to speaking to you in the next video speak soon bye
Info
Channel: Chris Hay
Views: 5,055
Rating: undefined out of 5
Keywords: chris hay, chrishayuk, web assembly, webassembly language, webassembly tutorial, wasm, wasm tutorial
Id: ojYEfRye6aE
Channel Id: undefined
Length: 32min 47sec (1967 seconds)
Published: Mon Jun 14 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.