WASM High Level¶
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:
The
.wat
text format (called wat for “WebAssembly Text”) uses S-expressions, and bears some resemblance to the Lisp family of languages like Scheme and Clojure.The
.wasm
binary format is lower-level and intended for consumption directly by wasm virtual machines. It is conceptually similar to ELF and Mach-O.
WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable target for compilation of high-level languages like C/C++/Rust, enabling deployment on the web for client and server applications.
Supported Browsers:
Firefox
Chrome
Safari
Edge
Note: older browsers can be supported by ``wasm2js``, a tool for converting WASM to JS
Safety¶
WebAssembly describes a memory-safe, sandboxed execution environment that may even be implemented inside existing JavaScript virtual machines. When embedded in the web, WebAssembly will enforce the same-origin and permissions security policies of the browser.
Integration¶
Rust and WebAssembly integrates with existing JavaScript tooling. It supports ECMAScript modules and you can continue using the tooling you already love, like npm, Webpack, and Greenkeeper.
typescript
Linear Memory¶
WebAssembly has a very simple memory model. A wasm module has access to a single “linear memory”, which is essentially a flat array of bytes. This memory can be grown by a multiple of the page size (64K). It cannot be shrunk.
Rust High Level¶
wasm-pack is currently one of the best cross
compilers. cargo
packages mostly work! Currently, as of 6/3/2019, requires
Rust 1.30 or newer.
Interfacing Rust and JavaScript¶
JavaScript’s garbage-collected heap — where Objects, Arrays, and DOM nodes are allocated — is distinct from WebAssembly’s linear memory space, where our Rust values live. WebAssembly currently has no direct access to the garbage-collected heap
As a general rule of thumb, a good JavaScript↔WebAssembly interface design is often one where large, long-lived data structures are implemented as Rust types that live in the WebAssembly linear memory, and are exposed to JavaScript as opaque handles
What WASM + Rust Can Do¶
Algorithms and Data Structures
Parsers
Text Processing
Rust Patterns
What WASM cannot Do¶
File I/O
WebAssembly does not have access to a file system, so crates that assume the existence of a file system — and don’t have wasm-specific workarounds — will not work.
C and System Lib Dependencies There are no system libraries in wasm, so any crate that tries to bind to a system library won’t work.
Using C libraries will also probably fail to work, since wasm doesn’t have a stable ABI for cross-language communication, and cross-language linking for wasm is very finicky
Deploying Rust + WASM¶
To deploy a Web application that uses Rust-generated WebAssembly on the client, copy the built Web application’s files to your production server’s file system and configure your HTTP server to make them accessible.
Ensure that Your HTTP Server Uses the application/wasm MIME Type¶
For the fastest page loads, you’ll want to use the
WebAssembly.instantiateStreaming
function to pipeline wasm compilation and instantiation with network transfer
(or make sure your bundler is able to use that function). However,
instantiateStreaming requires that the HTTP response has the application/wasm
MIME type set, or else it will throw an error.
Python WASM Modules¶
It’s not really supported well since python is interpreted. So a whole interpreter has to be compiled to Wasm. Be that as it may, there are some really cool projects in this space.
C++¶
There are two options for compilers, emscripten and cheerp. I’m covering emscripten… If these did not exist.
https://developers.google.com/web/updates/2018/08/embind https://developers.google.com/web/updates/2019/01/emscripten-npm#docker
Conclusion¶
If there is an algorithmically complex portion of JS code or a section of code that could be simplified if rewritten in Rust then use WASM