Merge pull request #686 from fitzgen/guide-supported-types-example-usage

guide: Start adding example usage to "supported types" section
This commit is contained in:
Sendil Kumar N 2018-08-11 07:45:47 +02:00 committed by GitHub
commit 6457f64a43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 307 additions and 19 deletions

View File

@ -55,6 +55,7 @@ members = [
"examples/comments",
"examples/console_log",
"examples/dom",
"examples/guide-supported-types-examples",
"examples/hello_world",
"examples/import_js",
"examples/julia_set",

View File

@ -0,0 +1,3 @@
package-lock.json
guide_supported_types_examples.js
guide_supported_types_examples_bg.wasm

View File

@ -0,0 +1,10 @@
[package]
name = "guide-supported-types-examples"
version = "0.1.0"
authors = ["Nick Fitzgerald <fitzgen@gmail.com>"]
[lib]
crate-type = ["cdylib"]
[dependencies]
wasm-bindgen = { path = "../.." }

View File

@ -0,0 +1,61 @@
# Adding Numbers
[View this example online](https://webassembly.studio/?f=612vwsrmwft)
This directory is an example of using the `#[wasm_bindgen]` macro to simply add
two numbers. The neat part about this is that it's an example of how to generate
the smallest wasm-bindgen binary.
You can build the example with:
```
$ ./build.sh
```
(or running the commands on Windows manually)
Currently this generates a 651 byte wasm binary:
```
$ ls -alh add_bg.wasm
-rw-rw-r-- 1 alex alex 651 Apr 20 22:16 add_bg.wasm
```
If you run [wasm-opt], a C++ tool for optimize WebAssembly, you can make it even
smaller too!
```
$ wasm-opt -Os add_bg.wasm -o add.wasm
$ ls -alh add.wasm
-rw-rw-r-- 1 alex alex 100 Apr 20 22:19 add.wasm
```
And sure enough, using the [wasm2wat] tool it's quite small!
```
$ wasm2wat add.wasm
(module
(type (;0;) (func (param i32 i32) (result i32)))
(func (;0;) (type 0) (param i32 i32) (result i32)
get_local 1
get_local 0
i32.add)
(memory (;0;) 2)
(export "memory" (memory 0))
(export "add" (func 0))
(data (i32.const 1545) "invalid malloc request"))
```
Note that it's important to point out that the size reductions here are because
the wasm is compiled in release mode by the build script and this crate's
workspace has the following configuration
```toml
[profile.release]
lto = true
opt-level = 's'
panic = 'abort'
```
[wasm2wat]: https://github.com/webassembly/wabt
[wasm-opt]: https://github.com/webassembly/binaryen

View File

@ -0,0 +1,2 @@
import * as imported_types from './imported_types.js';
import * as exported_types from './exported_types.js';

View File

@ -0,0 +1,12 @@
#!/bin/sh
# For more coments about what's going on here, see the `hello_world` example
set -ex
cargo +nightly build --target wasm32-unknown-unknown --release
cargo +nightly run --manifest-path ../../crates/cli/Cargo.toml \
--bin wasm-bindgen -- \
../../target/wasm32-unknown-unknown/release/guide_supported_types_examples.wasm --out-dir .
npm install
npm run serve

View File

@ -0,0 +1 @@
console.log("todo")

View File

@ -0,0 +1,26 @@
import {
imported_type_by_value,
imported_type_by_shared_ref,
return_imported_type,
take_option_imported_type,
return_option_imported_type,
} from './guide_supported_types_examples';
imported_type_by_value(new SomeJsType());
imported_type_by_shared_ref(new SomeJsType());
let x = return_imported_type();
console.log(x instanceof SomeJsType);
// true
take_option_imported_type(null);
take_option_imported_type(undefined);
take_option_imported_type(new SomeJsType());
let y = return_option_imported_type();
if (y == null) {
// ...
} else {
console.log(y instanceof SomeJsType);
// true
}

View File

@ -0,0 +1,8 @@
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
</head>
<body>
<script src='./index.js'></script>
</body>
</html>

View File

@ -0,0 +1,5 @@
// For more comments about what's going on here, check out the `hello_world`
// example
import('./bootstrap').then(() => {
console.log("done");
});

View File

@ -0,0 +1,10 @@
{
"scripts": {
"serve": "webpack-dev-server"
},
"devDependencies": {
"webpack": "^4.11.1",
"webpack-cli": "^2.0.10",
"webpack-dev-server": "^3.1.0"
}
}

View File

@ -0,0 +1,6 @@
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub struct RustType {
inner: u32,
}

View File

@ -0,0 +1,25 @@
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern {
pub type SomeJsType;
}
#[wasm_bindgen]
pub fn imported_type_by_value(x: SomeJsType) { /* ... */ }
#[wasm_bindgen]
pub fn imported_type_by_shared_ref(x: &SomeJsType) { /* ... */ }
#[wasm_bindgen]
pub fn return_imported_type() -> SomeJsType {
unimplemented!()
}
#[wasm_bindgen]
pub fn take_option_imported_type(x: Option<SomeJsType>) { /* ... */ }
#[wasm_bindgen]
pub fn return_option_imported_type() -> Option<SomeJsType> {
unimplemented!()
}

View File

@ -0,0 +1,7 @@
#![feature(use_extern_macros)]
#![allow(unused_variables, dead_code)]
extern crate wasm_bindgen;
pub mod imported_types;
pub mod exported_types;

View File

@ -0,0 +1,10 @@
const path = require('path');
module.exports = {
entry: './index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'index.js',
},
mode: 'development'
};

View File

@ -1,21 +1,122 @@
# Supported Types
# Supported Rust Types and their JavaScript Representations
The table below provides an overview of all the types that `wasm-bindgen` can
send and receive across the WebAssembly ABI boundary.
This section provides an overview of all the types that `wasm-bindgen` can send
and receive across the WebAssembly ABI boundary, and how they translate into
JavaScript.
| Type | `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value |
|:---:|:---:|:---:|:---:|:---:|:---:|
| Imported `extern Whatever;` JavaScript Types | Yes | Yes | Yes | Yes | Yes | Yes |
| Exported `struct Whatever` Rust Types | Yes | Yes | Yes | Yes | Yes | Yes |
| `str` | No | Yes | No | Yes | Yes | No |
| `String` | Yes | No | No | Yes | Yes | Yes |
| `char` | Yes | No | No | Yes | No | No |
| `bool` | Yes | No | No | Yes | No | No |
| `JsValue` | Yes | Yes | Yes | Yes | No | No |
| `Box<[JsValue]>` | Yes | No | No | Yes | Yes | yes |
| `*const T` | Yes | No | No | Yes | No | No |
| `*mut T` | Yes | No | No | Yes | No | No |
| `u8` `i8` `u16` `i16` `u64` `i64` `isize` `size` | Yes | No | No | Yes | No | No |
| `u32` `i32` `f32` `f64` | Yes | Yes | Yes | Yes | No | No |
| `Box<[u8]>` `Box<[i8]>` `Box<[u16]>` `Box<[i16]>` `Box<[u32]>` `Box<[i32]>` `Box<[u64]>` `Box<[i64]>` `Box<[f32]>` `Box<[f64]`> | Yes | No | No | Yes | Yes | Yes |
| `[u8]` `[i8]` `[u16]` `[i16]` `[u32]` `[i32]` `[u64]` `[i64]` `[f32]` `[f64]` | No | Yes | Yes | No | Yes | No |
## Imported `extern Whatever;` JavaScript Types
| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | Yes | No | Yes | Yes | Yes | Instances of the extant `Whatever` JavaScript class / prototype constructor |
### Example Rust Usage
```rust
{{#include ../../../examples/guide-supported-types-examples/src/imported_types.rs}}
```
### Example JavaScript Usage
```js
{{#include ../../../examples/guide-supported-types-examples/imported_types.js}}
```
## Exported `struct Whatever` Rust Types
| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | Yes | Yes | Yes | Yes | Yes | Instances of a `wasm-bindgen`-generated JavaScript `class Whatever { ... }` |
### Example Rust Usage
```rust
{{#include ../../../examples/guide-supported-types-examples/src/exported_types.rs}}
```
### Example JavaScript Usage
```js
{{#include ../../../examples/guide-supported-types-examples/exported_types.js}}
```
## `str`
| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| No | Yes | No | Yes | Yes | No | JavaScript string value |
Copies the string's contents back and forth between the JavaScript
garbage-collected heap and the Wasm linear memory with `TextDecoder` and
`TextEncoder`. If you don't want to perform this copy, and would rather work
with handles to JavaScript string values, use the `js_sys::JsString` type.
## `String`
| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | No | No | Yes | Yes | Yes | JavaScript string value |
Copies the string's contents back and forth between the JavaScript
garbage-collected heap and the Wasm linear memory with `TextDecoder` and
`TextEncoder`
## `char`
| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | No | No | Yes | No | No | A JavaScript string value |
## `bool`
| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | No | No | Yes | No | No | A JavaScript boolean value |
## `wasm_bindgen::JsValue`
| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | Yes | Yes | Yes | No | No | Any JavaScript value |
## `Box<[JsValue]>`
| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | No | No | Yes | Yes | Yes | A JavaScript `Array` object |
## `*const T` `*mut T`
| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | No | No | Yes | No | No | A JavaScript number value |
## `u8` `i8` `u16` `i16` `u64` `i64` `isize` `size`
| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | No | No | Yes | No | No | A JavaScript number value |
## `u32` `i32` `f32` `f64`
| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | Yes | Yes | Yes | No | No | A JavaScript number value |
## `Box<[u8]>` `Box<[i8]>` `Box<[u16]>` `Box<[i16]>` `Box<[u32]>` `Box<[i32]>` `Box<[u64]>` `Box<[i64]>` `Box<[f32]>` `Box<[f64]>`
| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| Yes | No | No | Yes | Yes | Yes | A JavaScript `TypedArray` view of the Wasm memory for the boxed slice of the appropriate type (`Int32Array`, `Uint8Array`, etc) |
Note that this does ***not*** copy the whole slice of memory back and forth into
the JavaScript heap from the Wasm linear memory.
## `[u8]` `[i8]` `[u16]` `[i16]` `[u32]` `[i32]` `[u64]` `[i64]` `[f32]` `[f64]`
| `T` parameter | `&T` parameter | `&mut T` parameter | `T` return value | `Option<T>` parameter | `Option<T>` return value | JavaScript representation |
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
| No | Yes | Yes | No | Yes | No | A JavaScript `TypedArray` view of the Wasm memory for the boxed slice of the appropriate type (`Int32Array`, `Uint8Array`, etc) |
Note that this does ***not*** copy the whole slice of memory back and forth into
the JavaScript heap from the Wasm linear memory.