Skip to content

Commit ae1f6d6

Browse files
committed
Add "Our Vision for Rust and WebAssembly" post
1 parent b0b39c8 commit ae1f6d6

File tree

7 files changed

+257
-3
lines changed

7 files changed

+257
-3
lines changed

_config.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
1414
# You can create any custom variable you would like, and they will be accessible
1515
# in the templates via {{ site.myvariable }}.
16-
title: This week in Rust and WebAssembly
17-
email: sendilkumarn@live.com
16+
title: Rust and WebAssembly
1817
description: >- # this means to ignore newlines until "baseurl:"
1918
Stay up to date with events, learning resources, and recent developments in Rust and WebAssembly community.
2019
baseurl: "" # the subpath of your site, e.g. /blog
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
---
2+
title: Our Vision for Rust and WebAssembly
3+
---
4+
5+
<meta charset="utf-8" />
6+
7+
**Surgically inserting Rust compiled to WebAssembly should be the best choice
8+
for speeding up the most performance-sensitive JavaScript code paths.** Do *not*
9+
throw away your existing code base, because Rust [plays well with
10+
others][better-for-all]. Regardless if you are a Rust or Web developer, your
11+
natural workflow shouldn't change because Rust compiled to wasm integrates
12+
seamlessly into your preferred tools.
13+
14+
This blog post will expand on these aspirations and describe where we stand in
15+
relation to them right now. In a series of follow up posts, we will talk about
16+
the next steps for each major component of the Rust and WebAssembly ecosystem.
17+
18+
<style>
19+
hr {
20+
margin-top: 2em;
21+
margin-bottom: 2em;
22+
}
23+
</style>
24+
25+
--------------------------------------------------------------------------------
26+
27+
> [Are you interested in helping us make these ideals into reality? Join the Rust
28+
and WebAssembly domain working group!][get-involved]
29+
30+
--------------------------------------------------------------------------------
31+
32+
## Why Focus on Performance-Sensitive Code?
33+
34+
In the most performance-sensitive contexts, JavaScript hinders rather than
35+
helps. Its dynamic type system and non-deterministic garbage collection pauses
36+
get in the way. Seemingly small code changes can result in drastic performance
37+
regressions if you accidentally wander off the JIT's happy path.
38+
39+
On the other hand, Rust gives programmers low-level control and reliable
40+
performance. It is free from the non-deterministic garbage collection
41+
pauses. Programmers have control over indirection, monomorphization, and memory
42+
layout.
43+
44+
With Rust, we don't need to be a performance gurus who are intimately familiar
45+
with the inner workings of each JavaScript implementation's JIT. We can have
46+
[speed without wizardry][].
47+
48+
## Do <u>Not</u> Rewrite — Integrate
49+
50+
Rust compiled to WebAssembly doesn't have a runtime. This enables both small
51+
`.wasm` binary sizes and `.wasm` binary sizes that are proportional to the
52+
amount of Rust code that is being compiled to WebAssembly. Binary size is of
53+
huge importance since the `.wasm` must be downloaded over the network. The
54+
proportionality means you only pay (in code size) for what you use, and enables
55+
incremental and partial adoption of Rust into existing JavaScript code bases.
56+
Existing code bases don't need to be thrown away: we can port only our most
57+
performance-sensitive JavaScript functions to Rust to gain immediate benefits.
58+
59+
## Keep Your Workflow
60+
61+
If you are a JavaScript hacker and want to use a library that is written in Rust
62+
and WebAssembly, you shouldn't have to change your workflow at all. We can
63+
publish `.wasm` packages to npm, and you can depend on them in `package.json`
64+
just like you normally would any other JavaScript library. They can be imported
65+
as ECMAScript modules, CommonJS-style `require`s, or added as a new object
66+
property to the JavaScript global. [Bundlers will understand Rust and
67+
WebAssembly][webpack-rust-plugin] just as well as they understand JavaScript.
68+
69+
If you are a Rust hacker and want to compile your crate to `.wasm` and share it
70+
on npm, you shouldn't have to change your workflow either. In fact, you
71+
shouldn't even need to install npm, Node.js, and a whole JavaScript development
72+
environment. `wasm-pack` will compile, optimize, and generate JavaScript
73+
bindings for your crate. And then it will upload it to npm for you too!
74+
75+
## Current Status
76+
77+
This section provides a snapshot of our current ecosystem, the tools that are
78+
available right now, and how this compares to the vision described above.
79+
80+
### The Rust and WebAssembly Book
81+
82+
Everything we build is for naught if people can't learn how to use it
83+
themselves. So we are writing [The Rust and WebAssembly Book][book].
84+
85+
Right now, it already has a lot of great content:
86+
87+
* Getting up and running
88+
* Designing and implementing a non-trivial example (the Game of Life) that
89+
integrates Rust and JavaScript
90+
* Tips for debugging, time profiling, and code size profiling
91+
* How to publish to npm with `wasm-pack`
92+
93+
But it doesn't have a lot of continuity. It feels like a collection of
94+
appendices and random tutorials. We will have a follow up blog post detailing
95+
its specific needs, and how to help if you're interested.
96+
97+
### wasm-bindgen
98+
99+
[`wasm-bindgen` facilitates communication between Rust and
100+
JavaScript.][wasm-bindgen] You can import JavaScript things into Rust, and
101+
export Rust things to JavaScript. It allows you to send rich types like strings
102+
and structs between wasm and JavaScript, rather than only the simple integers
103+
and floats defined by the WebAssembly standard.
104+
105+
Here is "Hello, World!" between Rust and JavaScript with `wasm-bindgen`. First,
106+
we import the `alert` function into Rust and export the `greet` function to
107+
JavaScript:
108+
109+
```rust
110+
extern crate wasm_bindgen;
111+
use wasm_bindgen::prelude::*;
112+
113+
#[wasm_bindgen]
114+
extern {
115+
fn alert(s: &str);
116+
}
117+
118+
#[wasm_bindgen]
119+
pub fn greet(name: &str) {
120+
alert(&format!("Hello, {}!", name));
121+
}
122+
```
123+
124+
Then, we import the wasm as an ECMAScript module in JavaScript, and call the
125+
`greet` function:
126+
127+
```js
128+
import { greet } from "./hello_world";
129+
130+
greet("World!");
131+
```
132+
133+
<a href="/images/wasm-bindgen-architecture-current.png">
134+
<img src="/images/wasm-bindgen-architecture-current.png" alt="wasm-bindgen architecture" style="float:right;width:50%;min-width:200px;max-width:400px;margin:1em"/>
135+
</a>
136+
137+
How does `wasm-bindgen` work? Simplifying a bit, it is a procedural macro that
138+
takes in Rust source code annotated with `#[wasm_bindgen]` attributes,
139+
constructs an abstract syntax tree (AST), and then it emits two artifacts:
140+
141+
1. Rust bindings that import JavaScript things and export Rust things.
142+
143+
2. JavaScript bindings that expose a nice interface to Rust-exported things to
144+
other JavaScript code and provide the Rust's desired imports.
145+
146+
`wasm-bindgen`'s approach to JavaScript binding allows you to pay only for the
147+
imports that you use. Just because you imported the `window.alert` function, you
148+
don't end up with glue code for `window.document`.
149+
150+
The big downside is that, right now, you always have to declare imports
151+
yourself. There are common imports for JavaScript functions and types and the
152+
Web platform APIs that will undoubtedly be repeated by many people many times
153+
over. Importing these by-hand is both boring and mechanical. We have a plan for
154+
fixing this, but you'll have to wait for a follow up blog post to learn more.
155+
156+
<div style="clear: both"/>
157+
158+
### wasm-pack
159+
160+
[`wasm-pack` seeks to be a one-stop shop for building, optimizing, and
161+
publishing Rust-generated WebAssembly that you would like to interoperate with
162+
JavaScript, in the browser, or with Node.js.][wasm-pack] `wasm-pack` helps you
163+
build and publish Rust-generated WebAssembly to the npm registry to be used
164+
alongside any other JavaScript package in workflows that you already use, such
165+
as a bundler like [webpack][] or [greenkeeper][].
166+
167+
[![wasm-pack cartoon](/images/wasm-pack-cartoon.png)](/images/wasm-pack-cartoon.png)
168+
169+
*Drawing by Lin Clark in [Making WebAssembly better for Rust & for all
170+
languages][better-for-all]*
171+
172+
The intention is that if you are a Rust developer and want to publish a crate
173+
compiled to wasm on npm, `wasm-pack` will
174+
175+
1. compile the crate to WebAssembly with the `wasm32-unknown-unknown` target,
176+
2. run the `wasm-bindgen` CLI tool on the `.wasm` to generate its JavaScript
177+
interface,
178+
3. run any other post-build tools such as `wasm-snip` and `wasm-opt`,
179+
4. collate any and all npm dependencies your crate and/or its JavaScript
180+
bindings might have,
181+
5. and publish the resulting package on npm.
182+
183+
All without you, the Rust developer, needing to have a JavaScript toolchain up
184+
and running.
185+
186+
Right now, steps 1, 2, and 5 are in place, but you still need to have `npm`
187+
installed locally. There are also some more things planned for `wasm-pack`, and
188+
our story for orchestrating builds, dependencies, and publishing coming down the
189+
pipe, but you'll have to wait for the dedicated follow up blog post.
190+
191+
### Wait, There's More!
192+
193+
<a href="/images/twiggy.png">
194+
<img src="/images/twiggy.png" alt="Twiggy!" style="float:right;width:40%;min-width:100px;max-width:500px;margin:1em"/>
195+
</a>
196+
197+
* [Twiggy is a code size profiler for `.wasm` binaries.][twiggy] It helps you
198+
answer questions like "why did this function even end up in here -- who calls
199+
it?" and "how much space would be saved if I stopped using this function,
200+
removed it, and removed all the functions that become dead code after its
201+
removal?"
202+
203+
* [`wee_alloc` is a tiny allocator designed for WebAssembly that has a (pre
204+
compression) code size footprint of only a single kilobyte.][wee_alloc] It is
205+
geared towards code that makes a handful of initial dynamically sized
206+
allocations, and then performs its heavy lifting without any further
207+
allocations. This scenario requires *some* allocator to exist, but we are more
208+
than happy to trade allocation performance for small code size.
209+
210+
<div style="clear: both"/>
211+
212+
<a href="/images/console_error_panic_hook.png">
213+
<img src="/images/console_error_panic_hook.png" alt="Twiggy!" style="float:left;width:60%;min-width:100px;max-width:800px;margin:1em"/>
214+
</a>
215+
216+
* [The `console_error_panic_hook` crate provides a panic hook for wasm that logs
217+
panics to the developer console via the `console.error`
218+
function.][console_error_panic_hook] No more opaque "RuntimeError: unreachable
219+
executed" messages! Get the proper assertion failure message or index
220+
out-of-bounds information you expect. It makes debugging panics a whole lot
221+
easier.
222+
223+
* [The `wasm-snip` tool lets you forcibly replace a function's body with a
224+
single `unreachable` instruction.][wasm-snip] Maybe you know that some
225+
function will never be called at runtime, but the compiler can't prove that at
226+
compile time? Snip it! Then run wasm-gc again and all the functions it
227+
transitively called (which could also never be called at runtime) will get
228+
removed too. This is particularly helpful for removing Rust's panicking and
229+
formatting infrastructure when you intend to ship small `.wasm` binaries with
230+
`panic=abort`.
231+
232+
<div style="clear: both"/>
233+
234+
## Coming Soon: The Future
235+
236+
As mentioned throughout this post, we'll be following up with more blog posts
237+
detailing specific goals we have for the Rust 2018 edition and how you can
238+
help. In the meantime, don't hesitate to [join the Rust and WebAssembly domain
239+
working group and help build the future of Rust and WebAssembly now!][get-involved]
240+
241+
242+
[better-for-all]: https://hacks.mozilla.org/2018/03/making-webassembly-better-for-rust-for-all-languages/
243+
[get-involved]: https://github.com/rustwasm/team#get-involved
244+
[speed without wizardry]: http://fitzgeraldnick.com/2018/02/26/speed-without-wizardry.html
245+
[webpack-rust-plugin]: https://github.com/xtuc/rust-plugin
246+
[book]: https://rustwasm.github.io/book/
247+
[host-bindings]: https://github.com/WebAssembly/host-bindings/blob/master/proposals/host-bindings/Overview.md
248+
[wasm-bindgen]: https://github.com/rustwasm/wasm-bindgen
249+
[wasm-pack]: https://github.com/rustwasm/wasm-pack
250+
[wasm-snip]: https://github.com/rustwasm/wasm-snip
251+
[console_error_panic_hook]: https://github.com/rustwasm/console_error_panic_hook
252+
[twiggy]: https://github.com/rustwasm/twiggy
253+
[wee_alloc]: https://github.com/rustwasm/wee_alloc
254+
[webpack]: https://webpack.js.org/
255+
[greenkeeper]: https://greenkeeper.io/

assets/main.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
# Only the main Sass file needs front matter (the dashes are enough)
33
---
44

5-
@import "minima";
5+
@import "minima";

images/console_error_panic_hook.png

55.6 KB
Loading

images/twiggy.png

42.7 KB
Loading
21 KB
Loading

images/wasm-pack-cartoon.png

246 KB
Loading

0 commit comments

Comments
 (0)