In this introduction, we show a simple WebAssembly function that returns the square root of a number. To create this function we load up WebAssembly Explorer (https://mbebenita.github.io/WasmExplorer/), writing the native WAST code to create and export the function. We compile and download the resulting WebAssembly binary, loading this with the Fetch API and WebAssembly JavaScript API to call the function in the browser.
Demo Repo: https://github.com/guybedford/wasm-intro
[00:00] In this lesson, we're going to look at how to create a very simple WebAssembly function. In this example, a function that'll take the square root of a number. As you can see here, this function is running as native WebAssembly code in the browser, and we can call it to get the square root.
[00:17] I'm going to be using a project called WebAssembly Explorer. This allows us to write pure WebAssembly code, directly in the browser, to get a binary that we can use in our application.
[00:29] Let's jump straight in. Every WebAssembly file starts with a module declaration. We then need to create our square_root function itself. We can do this through a function declaration. We give the function a name and then inside of the function, we have to say what parameters and return values the function has.
[00:48] For our square_root function, we're going to have a single parameter, which we can label num. The type of this parameter is a decimal type, so we're going to use the float32 number representation in memory. This means it's a 32-bit floating point number.
[01:02] The result type is also going to be the same float32 output of the square root value. The parameter's written. We can now write the body of the function. We want to take the float32 square root of the number parameter. The way we read that parameter is by using the get_local function.
[01:19] We can then reference the number parameter by the label we gave it. We're reading the parameter value, passing it the square_root function, and the result is going to just sit over here at the end of the function and will naturally become the return value. It's the correct type because it's already a float32.
[01:38] To actually be able to use this function, we want to expose it to JavaScript. The way we do this is with an export declaration in the WebAssembly module. We can give the export a name, say, square_root. Then we reference the function by the function label we gave it further down, just like you would exporting a function in JavaScript.
[01:57] Now we can assemble the binary using the in-browser tool, and then we can also download the binary to our file system. Moving this downloaded WebAssembly file to our main project folder, we can then edit our html file to load the WebAssembly binary.
[02:14] In order to load the WebAssembly in the browser, we're going to need to fetch and compile it ourselves. We're going to use the fetch function in the browser to fetch the WebAssembly binary. That gives us back a promise for the response. We need to check that the response is OK and if so, we can return the array buffer from the response.
[02:31] This is because WebAssembly is a binary format, so we want to use the raw binary bytes. Let's also add a nice error message if the response is not OK. This returns back those raw bytes, which we can then use the JavaScript WebAssembly API to compile into a WebAssembly module.
[02:47] The promise for the module comes back, and we then need to actually instantiate this to get a WebAssembly module instance, so we use WebAssembly.instantiate. The instance then contains an exports property, which contains all our exports and bindings from the WebAssembly module.
[03:04] I'm going to pick out square_root function off the exports and write it to the window object. We can now see our WebAssembly function in the browser.
Everything works fine when test.wasm is served, but when locally referenced, the test file is not able to be acquired.
Are you running a local server to serve the files? This is necessary for the loading to work.
Whoa it's Guy Bedford!