Rust and the Web Platform
Hugo Zapata
Concepts
WASM (WebAssembly) | Low level bytecode format |
asm.js | low level strict JavaScript subset |
emscriptem | Compile from C,C++ or any language compatible with LLVM to JavaScript . C++ => LLVM => JavaScript |
var buffer = new ArrayBuffer(32768); // JavaScript
var HEAPF32 = new Float32Array(buffer);
function main() {
var a = 0, b = 0;
do {
a = (8 + (b << 2)) | 0;
HEAPF32[a >> 2] = +HEAPF32[a >> 2] + 1.0;
b = (b + 1) | 0;
} while ((b | 0) < 5000);
}
asm.js is still JavaScript
Still has some performance benefits (depending on the engine):
A JavaScript engine can immediately recognize asm.js code at compile-time and immediately compile it to assembly language, with no need to ever run the code through an interpreter.
http://asmjs.org/faq.html
WebAssembly is not JavaScript
(module
(func $i (import "imports" "imported_func") (param i32))
(func (export "exported_func")
i32.const 42
call $i
)
)
Text representation (.wat) of a function that receives a reference to a JavaScript function and calls it with the value 42
https://developer.mozilla.org/en-US/docs/WebAssembly/Text_format_to_wasm#A_first_look_at_the_text_format
( The final format is binary .wasm )
Using the compiled WebAssembly code from JavaScript
fetch('simple.wasm').then(response =>
response.arrayBuffer()
).then(bytes =>
WebAssembly.instantiate(bytes, importObject)
).then(results => {
results.instance.exports.my_cool_method();
});
Steps:
- Fetch the code
- Convert to a byte array
- Use WebAssembly.instantiate API
- Call the public method
Rust properties
Safety and Control
- Compile time validation of (data) race conditions and other memory problems.
- By default variables are immutable.
- Modern syntax
- standard library
- Unsafe mode
- No garbage collection
- Rust uses 'lifetimes' to keep track of usage scope and object destruction
fn main() {
let x = 5;
println!("The value of x is: {}", x);
x = 6;
println!("The value of x is: {}", x);
}
This code won't compile
error[E0384]: re-assignment of immutable variable `x`
--> src/main.rs:4:5
|
2 | let x = 5;
| - first assignment to `x`
3 | println!("The value of x is: {}", x);
4 | x = 6;
| ^^^^^ re-assignment of immutable variable
Compiling from Rust to
It's easy to compile directly from the rust compile to .wasm ( Since a few weeks ago )
rustup update
rustup target add wasm32-unknown-unknown --toolchain nightly
rustc +nightly --target wasm32-unknown-unknown
-O --crate-type=cdylib add.rs -o add.big.wasm
Announcement of a new compilation target for WASM: (wasm32-unknown-unknown)
Example
#[no_mangle]
pub fn add_one(x: i32) -> i32 {
x + 1
}
Rust
(module
(type (;0;) (func (param i32) (result i32)))
(type (;1;) (func))
(func (;0;) (type 0) (param i32) (result i32)
get_local 0
i32.const 1
i32.add)
(func (;1;) (type 1))
(table (;0;) 0 anyfunc)
(memory (;0;) 17)
(export "memory" (memory 0))
(export "add_one" (func 0))
(export "rust_eh_personality" (func 1))
(data (i32.const 4) "\10\00\10\00"))
Readable WebAssembly
https://www.hellorust.com/demos/add/index.html
deck
By hugo zapata
deck
- 326