This repository has been archived by the owner on Mar 23, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 66
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WebAssembly chapter in english (#51)
* WebAssembly chapter in english * Speeling
- Loading branch information
Andrew Hobden
authored
May 16, 2017
1 parent
e525e83
commit df95695
Showing
21 changed files
with
382 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,198 @@ | ||
# WebAssembly | ||
[Table of Contents](toc/english.html) | ||
|
||
--- | ||
|
||
## What? | ||
|
||
WebAssembly enables running Rust (among others) in Javascript environments like the web browser. | ||
|
||
It is the successor to asm.js in many ways. | ||
|
||
It is currently a developing standard and is often not enabled by default. | ||
|
||
--- | ||
|
||
## Gotcha | ||
|
||
WebAssembly is still not widely supported and has a number of rough edges. | ||
|
||
--- | ||
|
||
## Installing | ||
|
||
Setup is a bit unrefined at this moment, but it should improve in the future. | ||
|
||
* Fetch `emsdk` from [emscripten](http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html). | ||
* Unpack it somewhere sensible. | ||
* Navigate to the directory in your terminal. | ||
|
||
--- | ||
|
||
## Installing: `emcc` | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/1.bash" data-trim="hljs bash"></code></pre> | ||
|
||
The output of the third command will offer instructions for what to add to `$PATH` if desired. | ||
|
||
> We use `incoming` to utilize the latest refinements. | ||
|
||
--- | ||
|
||
## Installing: `emcc` | ||
|
||
The versions of the toolchain are quite important. Verify there are no errors running the following: | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/2.bash" data-trim="hljs bash"></code></pre> | ||
|
||
--- | ||
|
||
## Installing: `rustup` Target | ||
|
||
`rustup` allows installing multiple compilation targets. | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/3.bash" data-trim="hljs bash"></code></pre> | ||
|
||
--- | ||
|
||
# Standalone Executable | ||
|
||
--- | ||
|
||
## Standalone Executable | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/4.bash" data-trim="hljs bash"></code></pre> | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/5.rs" data-trim="hljs rust"></code></pre> | ||
|
||
--- | ||
|
||
## Standalone Executable | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/6.bash" data-trim="hljs bash"></code></pre> | ||
|
||
This will create a directory structure like so: | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/7.output" data-trim="hljs bash"></code></pre> | ||
|
||
--- | ||
|
||
## Standalone Executable | ||
|
||
Once we generate the `wasm` and `js` we want to place them in with a `site` folder. We can use a `Makefile` for this. | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/8.makefile" data-trim="hljs makefile"></code></pre> | ||
|
||
--- | ||
|
||
## Standalone Executable | ||
|
||
Create `site/index.html`: | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/9.html" data-trim="hljs html"></code></pre> | ||
|
||
--- | ||
|
||
## Standalone Executable | ||
|
||
Running `python -m SimpleHTTPServer` or equivalent, browsing to `localhost:8000/site`, and opening the console yield the following output: | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/10.output" data-trim="hljs bash"></code></pre> | ||
|
||
--- | ||
|
||
# Rust from JS | ||
|
||
--- | ||
|
||
## Rust from JS | ||
|
||
Exporting functions for use in Javascript is a bit more complicated. | ||
|
||
Additionally, interactions must be handled like interactions to C. | ||
|
||
--- | ||
|
||
## Rust from JS | ||
|
||
The nightly channel is currently necessary to get this to work properly: | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/11.bash" data-trim="hljs bash"></code></pre> | ||
|
||
--- | ||
|
||
## Rust from JS | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/12.bash" data-trim="hljs bash"></code></pre> | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/13.rs" data-trim="hljs rust"></code></pre> | ||
|
||
--- | ||
|
||
## Rust from JS | ||
|
||
We can use the same Makefile as before. | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/8.makefile" data-trim="hljs makefile"></code></pre> | ||
|
||
--- | ||
|
||
## Rust from JS | ||
|
||
The `onRuntimeInitialized` hook for `Module` defines what is called after the WebAssembly is loaded. | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/14.html" data-trim="hljs html"></code></pre> | ||
|
||
--- | ||
|
||
## Rust from JS | ||
|
||
Running `python -m SimpleHTTPServer` or equivalent, browsing to `localhost:8000/site`, and opening the console yield the following output: | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/15.output" data-trim="hljs bash"></code></pre> | ||
|
||
--- | ||
|
||
# JS from Rust | ||
|
||
--- | ||
|
||
## JS from Rust | ||
|
||
Calling JS code from Rust has similar complications. | ||
|
||
It is done primarily through passing the `--js-library` flag at link time, which requires the nightly channel of rust. | ||
|
||
Passing numerics is relatively simple, but passing more complex things like strings requires extra effort. | ||
|
||
--- | ||
|
||
## JS from Rust | ||
|
||
Returning a string for Rust code: | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/17.js" data-trim="hljs javascript"></code></pre> | ||
|
||
--- | ||
|
||
## JS from Rust | ||
|
||
Calling the Javascript function: | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/18.rs" data-trim="hljs rust"></code></pre> | ||
|
||
--- | ||
|
||
## DOM Interaction | ||
|
||
There is a [WebPlatform crate](https://github.com/tcr/rust-webplatform) to explore and contribute to. | ||
|
||
<pre><code data-source="chapters/shared/code/wasm/19.rs" data-trim="hljs rust"></code></pre> | ||
|
||
--- | ||
|
||
## Future | ||
|
||
WebAssembly is rapidly becoming more refined and mature. Rust's integration is also under active work. | ||
|
||
Keep your eyes peeled for more, better support! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
./emsdk update | ||
./emsdk install sdk-incoming-64bit | ||
./emsdk activate sdk-incoming-64bit | ||
source ./emsdk_env.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
trying binaryen method: native-wasm | ||
asynchronously preparing wasm | ||
binaryen method succeeded. | ||
run() called, but dependencies remain, so not running | ||
pre-main prep time: 108 ms | ||
South | ||
false |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
rustup override set nightly | ||
rustup target add wasm32-unknown-emscripten |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
cargo init wasm-demo --bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
use std::os::raw::c_char; | ||
use std::ffi::CString; | ||
use std::collections::HashMap; | ||
|
||
#[no_mangle] | ||
pub fn get_data() -> *mut c_char { | ||
let mut data = HashMap::new(); | ||
data.insert("Alice", "send"); | ||
data.insert("Bob", "receive"); | ||
data.insert("Carol", "intercept"); | ||
|
||
let descriptions = data.iter() | ||
.map(|(p,a)| format!("{} likes to {} messages", p, a)) | ||
.collect::<Vec<_>>(); | ||
|
||
CString::new(descriptions.join(", ")) | ||
.unwrap() | ||
.into_raw() | ||
} | ||
|
||
fn main() { | ||
// Deliberately blank. | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<html> | ||
<head> | ||
<script> | ||
// This is read and used by `site.js` | ||
var Module = { | ||
wasmBinaryFile: "site.wasm", | ||
onRuntimeInitialized: main, | ||
} | ||
function main() { | ||
let get_data = Module.cwrap('get_data', 'string', []); | ||
console.log(get_data()); | ||
} | ||
</script> | ||
<script src="site.js"></script> | ||
</head> | ||
<body></body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
trying binaryen method: native-wasm | ||
asynchronously preparing wasm | ||
binaryen method succeeded. | ||
Bob likes to receive messages, Alice likes to send messages, Carol likes to intercept messages |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
'use strict'; | ||
|
||
var library = { | ||
get_data: function() { | ||
var str = "Hello from JS."; | ||
alert(str); | ||
|
||
// Not needed for numerics. | ||
var len = lengthBytesUTF8(str); | ||
var buffer = Module._malloc(len); | ||
Module.stringToUTF8(str, buffer, len); | ||
|
||
return buffer; | ||
}, | ||
}; | ||
|
||
mergeInto(LibraryManager.library, library); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#![feature(link_args)] | ||
|
||
#[cfg_attr(target_arch="wasm32", link_args = "\ | ||
--js-library site/utilities.js\ | ||
")] | ||
extern {} | ||
|
||
use std::os::raw::c_char; | ||
use std::ffi::CStr; | ||
|
||
extern { | ||
fn get_data() -> *mut c_char; | ||
} | ||
|
||
fn get_data_safe() -> String { | ||
let data = unsafe { | ||
CStr::from_ptr(get_data()) | ||
}; | ||
data.to_string_lossy() | ||
.into_owned() | ||
} | ||
|
||
fn main() { | ||
let data = get_data_safe(); | ||
println!("{:?}", data); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
extern crate webplatform; | ||
|
||
fn main() { | ||
let document = webplatform::init(); | ||
let body = document.element_query("body") | ||
.unwrap(); | ||
body.html_append("\ | ||
<h1>This header brought to you by Rust</h1>\ | ||
<button>Click me!</button>\ | ||
"); | ||
|
||
let button = document.element_query("button") | ||
.unwrap(); | ||
button.on("mouseenter", move |_| { | ||
println!("Mouse entered!"); | ||
body.html_append("<p>Mouse entered!</p>"); | ||
}); | ||
button.on("click", |_| { | ||
println!("Clicked!"); | ||
webplatform::alert("Clicked!"); | ||
}); | ||
|
||
webplatform::spin(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
$ emcc -v | ||
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 1.37.9 | ||
clang version 4.0.0 (emscripten 1.37.9 : 1.37.9) | ||
Target: x86_64-apple-darwin16.4.0 | ||
Thread model: posix | ||
InstalledDir: /Users/$USER/emsdk/clang/e1.37.9_64bit | ||
INFO:root:(Emscripten: Running sanity checks) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
rustup target add wasm32-unknown-emscripten |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
cargo init wasm-demo --bin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#[derive(Debug)] | ||
pub enum Direction { North, South, East, West } | ||
|
||
fn is_north(dir: Direction) -> bool { | ||
match dir { | ||
Direction::North => true, | ||
_ => false, | ||
} | ||
} | ||
|
||
fn main() { | ||
let points = Direction::South; | ||
println!("{:?}", points); | ||
let compass = is_north(points); | ||
println!("{}", compass); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
cargo build --target=wasm32-unknown-emscripten --release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
target | ||
└── wasm32-unknown-emscripten | ||
└── release | ||
├── build | ||
├── deps | ||
│ ├── wasm_demo-9c23ae9a241f12fa.asm.js | ||
│ ├── wasm_demo-9c23ae9a241f12fa.js | ||
│ └── wasm_demo-9c23ae9a241f12fa.wasm | ||
├── examples | ||
├── incremental | ||
├── native | ||
├── wasm-demo.d | ||
└── wasm-demo.js |
Oops, something went wrong.