A Taste Of WASM
The Browser as a Virtual Machine
@m4d_zhttps://talks.m4dz.net/a-taste-of-wasm/en/short/Back In History
We are developping
(Progressive Web) Apps!
We need:
An Experiment: ASM.js
Need to Compile!
Emscripten
What if we could compile
all our apps’ logics?
WebAssembly is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.
WASM Binary Format
0200 20 00
0202 42 00
0204 51
0205 04 7e
0207 42 01
020A 05
020B 20 00
020D 20 00
0210 42 01
0211 7d
0212 10 00
0214 7e
0217 0b
Is this a… language?
WASM Text Format
get_local 0
i64.const 0
i64.eq
if i64
i64.const 1
else
get_local 0
get_local 0
i64.const 1
i64.sub
call 0
i64.mul
end
🍀 static types
Problem:
I need more than numbers!
Rust Do it!
WASM Rust Hello World, Web version
pub fn greet(name: &str) {
alert(&format!("Hello {}!", name));
}
Why Rust?
WASM Modules
The Security Model
Browser-side: Instantiate
let importObject = {
imports: {
alert: window.alert
}
}
WebAssembly
.instantiateStreaming(fetch('my-module.wasm'), importObject)
.then(mod => mod.instance.exports.greet('Hello World'))
Remember:
I need more than numbers!
I need Strings
💩 UTF-8
A number could be…
a memory pointer!
Linear Memory
const pointer = 0
const LM = new WebAssembly.Memory({ initial: 1 })
const sharedMem = new Uint8Array(LM.buffer)
const str = "Hello World"
[].forEach.call(
btoa(str),
(char, idx) => sharedMem[pointer + idx] = char.charCodeAt(0)
)
// Uint8Array(65536) [ 83, 71, 86, 115, 98, 71, 56, 103, 86, 50, … ]
📦✨ your favorite rust -> wasm workflow tool!
Easy to use
$ cd my-module
$ wasm-pack build --target web --release
Ready to publish
$ tree
├── bridge.js
├── Cargo.toml
├── pkg
│ ├── my-module_bg.d.ts
│ ├── my-module_bg.wasm
│ ├── my-module.d.ts
│ ├── my-module.js
│ ├── package.json
│ └── snippets
│ └── my-module-91b01578bc1ce6c0
│ └── bridge.js
└── src
└── lib.rs
Facilitating high-level interactions between wasm modules and JavaScript.
window
, document
, fetch
, canvas
…)use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
}
#[wasm_bindgen(module = "/bindings.js")]
extern "C" {
fn updateState(state: &JsValue);
}
pub fn greet(name: &str) {
alert(&format!("Hello {}!", name));
let state = State { name }
updateState(JsValue::from_serde(&state).unwrap());
}
Embind is used to bind C++ functions and classes to JavaScript, so that the compiled code can be used in a natural way by JavaScript.
WebAssembly isn’t only for the Web
WASM outside of the browser
Running on the Server: The System Interface
Portability
Security
Glue them: WASM Standard Interfaces
Passing values from WASM to JS
is easy but tedious
Passing values from WASM
to anything else
is way more complex
$ wasmer run cowsay.wasm Hello World!
________________
< Hello World! >
----------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
The Future of FaaS
$ curl --location --request POST 'https://[::]/api/executables' \
--header 'Content-Type: application/octet-stream' \
--header 'SSVM_Description: say hello' \
--data-binary 'pkg/hello_lib_bg.wasm'
$ curl --location --request POST 'https://[::]/api/run/123/say' \
--header 'Content-Type: text/plain' \
--data-raw 'World'
Hello World!
Production-Proof
Coming from JS? Try AssemblyScript.
AssemblyScript compiles a strict variant of TypeScript to WebAssembly using Binaryen.
export function fib(n: i32): i32 {
var a = 0, b = 1
if (n > 0) {
while (--n) {
let t = a + b
a = b
b = t
}
return b
}
return a
}
Coming from OS language?
Check LLVM support.
Comming Soon
Open Standard
→ Build The Ecosystem
Paranoïd Web Dino · Tech Evangelist
https://talks.m4dz.net/a-taste-of-wasm/en/short/ Available under licence CC BY-SA 4.0
m4dz, CC BY-SA 4.0
Courtesy of Unsplash and Pexels contributors
Powered by Reveal.js
Source code available at
https://git.madslab.net/talks