Part 1: Starting Web Assembly
Rust gives programmers low-level control and reliable performance. It is free from the non-deterministic garbage collection pauses that plague JavaScript. Programmers have control over indirection, monomorphization, and memory layout.
WebAssembly in action
As of now, you might have imagined what WebAssembly can do. Now let me show you some great examples that can motivate you further. The developers at wasm have developed a demo game using unity, which has been exported to the web using web assembly. Go ahead, try it.
Tanks Demo: (https://wasm.bootcss.com/demo/)
WebAssembly (wasm)
WebAssembly (wasm) is a simple machine model and executable format with an extensive specification. It is designed to be portable, compact, and execute at or near-native speeds.
As a programming language, WebAssembly is comprised of two formats that represent the same structures, albeit in different ways:
1- The .wat text format (called wat for "WebAssembly Text") uses S-expressions.
2- The .wasm binary format is lower-level and intended for consumption directly by wasm virtual machines.
For reference, here is a factorial function in wat:
(module
(func $fac (param f64) (result f64)
get_local 0 f64.const 1
f64.lt
if (result f64)
f64.const 1
else
get_local 0 get_local 0 f64.const 1
f64.sub
call $fac
f64.mul
end)
(export "fac" (func $fac)))
For more information about the webAssembly syntax and text format, please refer to : https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format
To transform the above wat code to wasm, you can use the wat2wasm
(https://webassembly.github.io/wabt/demo/wat2wasm/) demo with the above code. Question 1: Change the above code as follows:
1- Change the function name into RecursiveCount
2- Change the function argument and return type to i32
3- Change the logic of the function, so instead of returning the factorial of a number, it returns the sum of all the integers in a range between any number (between 1 and 9) and the number 10.
For example RecursiveCount(9)=9+10 =19
RecursiveCount(7)= 7+8+9+10=34
Transform the code after these changes to .wasm and DEMO this deliverable to the lab instructor. (Hint: all you need to write is already in the program)
Part 2: Hello, World!
To set up the toolchain for compiling Rust programs to WebAssembly and integrate them into JavaScript, you have to follow the following steps:
1- You need the rust toolchain (rustup, rustc, and cargo), you should already have it installed in your machine. For more information, review Lab 1.
2- You need wasm-pack, which is your one-stop-shop for building, testing, and publishing Rustgenerated WebAssembly. Get it from here: https://rustwasm.github.io/wasm-pack/installer/
3- You need cargo-generate to helps you get up and running quickly with a new Rust project by leveraging a pre-existing git repository as a template. To install cargo-generate run the following command:
cargo install cargo-generate
4- Finally, you need npm, which is a package manager for JavaScript. We will use it to install and run a JavaScript bundler and development server. To install npm, follow the instruction from here: https://www.npmjs.com/get-npm
Now, let’s create our first WebAssembly project, a web page that alerts “Hello World!”.
1- To start the project, you can clone a project template which comes pre-configured with sane defaults, so you can quickly build, integrate, and package your code for the web. To clone the project template, use the following command:
cargo generate --git https://github.com/rustwasm/wasm-pack-template
2- Running the command should prompt you for the new project’s name. Name your project “wasmis-prime”
3- Then take a look at the project contents:
4- Let's take a look at a /src/lib.rs
The src/lib.rs file is the root of the Rust crate that we are compiling to WebAssembly. It uses wasmbindgen to interface with JavaScript. It imports the window.alert JavaScript function, and exports the greet Rust function, which alerts a greeting message.
• Ensure that we have Rust 1.30 or newer and the wasm32-unknown-unknown target installed via rustup,
• Compile our Rust sources into a WebAssembly .wasm binary via cargo,
• Use wasm-bindgen to generate the JavaScript API for using our Rust-generated WebAssembly. To do all of that, run this command inside the project directory:
wasm-pack build
6- When the build has completed, we can find its artifacts in the pkg directory, and it should have
these contents:
running the following command within the project directory:
npm init wasm-app www
Here's what our new wasm-is-prime/www subdirectory contains:
8- To ensure that the local development server and its dependencies are installed, run npm install within the wasm-is-prime/www subdirectory:
npm install
Note that this command only needs to be run once, and will install the webpack JavaScript bundler and its development server.
9- To incrementally develop our project, we need to specify the dependencies to include wasm-isprime
Do that by opening up wasm-is-prime/www/package.json and editing the "dependencies" to add a "wasm-is-prime ": "file:../pkg" entry:
import * as wasm from "wasm-is-prime"; wasm.greet();
11- Since we declared a new dependency, we need to install it:
npm install
12- Finally, open a new terminal for the development server. Running the server in a new terminal lets
us leave it running in the background, and doesn't block us from running other commands in the meantime. In the new terminal, run this command from within the wasm-is-prime/www directory:
npm run start
Navigate your Web browser to http://localhost:8080/, and you should be greeted with an alert message:
Anytime you make changes and want them reflected on http://localhost:8080/, just re-run the wasmpack build command within the wasm-is-prime directory.
For more tutorials refer to the online book: https://rustwasm.github.io/book/game-oflife/introduction.html#tutorial-conways-game-of-life • DEMO this deliverable to the lab instructor.
Part 3: Implementing is-prime app
is-prime app is a small application that takes input from the user (the input must be an integer). Then, it checks if this input is prime and alerts the user with the results of the check. For example, if the user inputs a prime number, the application should show an alert message that says, “your input is a prime number.” Otherwise, the app should display a message that says, “your input is NOT a prime number.”
1- In the last part, we cloned an initial project template. We will modify that project template now. Let's begin by modifying the wasm-is-prime/src/lib.rs by adding the following two functions as follows:
#[wasm_bindgen]
pub fn CheckPrime(s: &JsValue) {
let mut input: String = s.as_string().unwrap();
if(is_prime(input)){
npm run start
5- The app should be up and running now. However, it does not apply a primality test. Instead, it returns true regardless of the value of the input. Therefore, you need to add the code in lib.rs that checks if the user input is prime or not