Reorganize and rewrite examples

This commit is a large-ish scale reorganization of our examples. The
main goal here is to have a dedicated section of the guide for example,
and all examples will be listed there. Each example's `README` is now
just boilerplate pointing at the guide along with a blurb about how to
run it.

Some examples like `math` and `smorgasboard` have been deleted as they
didn't really serve much purpose, and others like `closures` have been
rewritten with `web-sys` instead of hand-bound bindings.

Overall it's hoped that this puts us in a good and consistent state for
our examples, with all of them being described in the guide, excerpts
are in the guide, and they're all relatively idiomatically using
`web-sys`.
This commit is contained in:
Alex Crichton
2018-09-20 16:20:42 -07:00
parent a85e49a2b4
commit 3efe51eb8b
128 changed files with 939 additions and 1304 deletions

View File

@ -8,3 +8,4 @@ crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = { path = "../.." }
js-sys = { path = "../../crates/js-sys" }

View File

@ -1,10 +1,10 @@
# WASM in WASM!
# js-sys: WebAssembly in WebAssembly
This directory is an example of using the `#[wasm_bindgen]` macro to interact
with namespaced APIs like `WebAssembly.Module` and friends. This example
instantiates a wasm module (from Rust!) and then interacts with it.
[View documentation for this example online][dox]
You can build the example with:
[dox]: https://rustwasm.github.io/wasm-bindgen/examples/wasm-in-wasm.html
You can build the example locally with:
```
$ ./build.sh
@ -12,10 +12,4 @@ $ ./build.sh
(or running the commands on Windows manually)
and then opening up `index.html` in a web browser should show a hello message on
the web page generated by the wasm.
For more information about this example be sure to check out
[`hello_world`][hello] which also has more comments about caveats and such.
[hello]: https://github.com/alexcrichton/wasm-bindgen/tree/master/examples/hello_world
and then visiting http://localhost:8080 in a browser should run the example!

View File

@ -3,7 +3,6 @@
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
</head>
<body>
<script src='./index.js'></script>
<p>The developer console should have messages in it</p>
</body>
</html>

View File

@ -1,52 +1,57 @@
extern crate wasm_bindgen;
extern crate js_sys;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use js_sys::{WebAssembly, Object, Reflect, Function, Uint8Array};
// Like with the `dom` example this block will eventually be auto-generated, but
// for now we can write it by hand to get by!
// lifted from the `console_log` example
#[wasm_bindgen]
extern "C" {
type Module;
#[wasm_bindgen(constructor, js_namespace = WebAssembly)]
fn new(data: &[u8]) -> Module;
type Instance;
#[wasm_bindgen(constructor, js_namespace = WebAssembly)]
fn new(module: Module) -> Instance;
#[wasm_bindgen(method, getter, js_namespace = WebAssembly)]
fn exports(this: &Instance) -> Exports;
type Exports;
#[wasm_bindgen(method, structural)]
fn add(this: &Exports, a: u32, b: u32) -> u32;
#[wasm_bindgen(method, getter, structural)]
fn memory(this: &Exports) -> Memory;
type Memory;
#[wasm_bindgen(method, js_namespace = WebAssembly)]
fn grow(this: &Memory, amt: u32) -> u32;
#[wasm_bindgen(js_namespace = console)]
fn log(a: &str);
}
macro_rules! println {
macro_rules! console_log {
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
}
const WASM: &[u8] = include_bytes!("add.wasm");
#[wasm_bindgen]
pub fn run() {
println!("instantiating a new wasm module directly");
let a = Module::new(WASM);
let b = Instance::new(a);
pub fn run() -> Result<(), JsValue> {
console_log!("instantiating a new wasm module directly");
let my_memory = wasm_bindgen::memory()
.dyn_into::<WebAssembly::Memory>()
.unwrap();
// Note that this is somewhat dangerous, once we look at our
// `WebAssembly.Memory` buffer then if we allocate more pages for ourself
// (aka do a memory allocation in Rust) it'll cause the buffer to change.
// That means we can't actually do any memory allocations after we do this
// until we pass it back to JS.
let my_memory = Uint8Array::new(&my_memory.buffer())
.subarray(
WASM.as_ptr() as u32,
WASM.as_ptr() as u32 + WASM.len() as u32,
);
let a = WebAssembly::Module::new(my_memory.as_ref())?;
let b = WebAssembly::Instance::new(&a, &Object::new())?;
let c = b.exports();
println!("1 + 2 = {}", c.add(1, 2));
let mem = c.memory();
println!("created module has {} pages of memory", mem.grow(0));
println!("giving the module 4 more pages of memory");
let add = Reflect::get(c.as_ref(), &"add".into())
.dyn_into::<Function>()
.expect("add export wasn't a function");
let three = add.call2(&JsValue::undefined(), &1.into(), &2.into())?;
console_log!("1 + 2 = {:?}", three);
let mem = Reflect::get(c.as_ref(), &"memory".into())
.dyn_into::<WebAssembly::Memory>()
.expect("memory export wasn't a `WebAssembly.Memory`");
console_log!("created module has {} pages of memory", mem.grow(0));
console_log!("giving the module 4 more pages of memory");
mem.grow(4);
println!("now the module has {} pages of memory", mem.grow(0));
console_log!("now the module has {} pages of memory", mem.grow(0));
Ok(())
}