Description
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
1
ECE 522 | Software Construction, Verification and Evolution
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 Rust-generated
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
“wasm-is-prime”
3- Then take a look at the project contents:
cd wasm-is-prime
wasm-is-prime/
├── Cargo.toml
├── LICENSE_APACHE
├── LICENSE_MIT
├── README.md
└── src
├── lib.rs
└── utils.rs
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 wasm-bindgen to interface with JavaScript. It imports the window.alert JavaScript function, and
exports the greet Rust function, which alerts a greeting message.
#[wasm_bindgen]
pub fn greet() {
2
ECE 522 | Software Construction, Verification and Evolution
alert(“Hello, wasm-is-prime!”);
}
5- To build the project, we use wasm-pack to do the following task
● 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:
pkg/
├── package.json
├── README.md
├── wasm_is_prime_bg.wasm
├── wasm_is_prime.d.ts
└── wasm_is_prime.js
7- Now, to build into a web page, you can use the create-wasm-app JavaScript project template by running
the following command within the project directory:
npm init wasm-app www
Here’s what our new wasm-is-prime/www subdirectory contains:
wasm-is-prime/www/
├── bootstrap.js
├── index.html
├── index.js
├── LICENSE-APACHE
├── LICENSE-MIT
├── package.json
├── README.md
└── webpack.config.js
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-is-prime
Do that by opening up wasm-is-prime/www/package.json and editing the “dependencies” to add
a “wasm-is-prime “: “file:../pkg” entry:
{
// …
“dependencies”: {
“wasm-is-prime”: “file:../pkg”, // Add this line!
// …
}
}
3
ECE 522 | Software Construction, Verification and Evolution
10- Next, modify wasm-is-prime/www/index.js to import wasm-is-prime instead of
the hello-wasm-pack package:
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 wasm-pack
build command within the wasm-is-prime directory.
For more tutorials refer to the online book:
https://rustwasm.github.io/book/game-of-life/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.”
4
ECE 522 | Software Construction, Verification and Evolution
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)){
alert(“Input is Prime”);
}
else{
alert(“Input is Prime”);
}
}
pub fn is_prime(s: String)->bool
{
// add your code here:
return true;
}
2- Now, let’s update the wasm-is-prime/www/index.html file to add a text input and a button as follows:
3- Finally, let’s glue everything together using javascript. So, edit wasm-is-prime/www/index.js to
import to read user input and calls the CheckNumber function in rust:
import * as wasm from “wasm-is-prime”;
const textbox1= document.getElementById(“PrimeNumber”);
document.getElementById(“CheckNumber”).addEventListener(“click”, event => {
wasm.CheckPrime(textbox1.value);
});
4- Remember that you need to rebuild your project and then run it using, you can find more
information about npm at https://www.npmjs.com/
npm run start
5
ECE 522 | Software Construction, Verification and Evolution
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. (Hint: you can use any crate that performs primality
tests which you may have used in Lab1).
DEMO this deliverable to the lab instructor.
6