RPM build fix (reverted CI changes which will need to be un-reverted or made conditional) and vendor Rust dependencies to make builds much faster in any CI system.
This commit is contained in:
1
zeroidc/vendor/wasm-bindgen/.cargo-checksum.json
vendored
Normal file
1
zeroidc/vendor/wasm-bindgen/.cargo-checksum.json
vendored
Normal file
File diff suppressed because one or more lines are too long
1854
zeroidc/vendor/wasm-bindgen/CHANGELOG.md
vendored
Normal file
1854
zeroidc/vendor/wasm-bindgen/CHANGELOG.md
vendored
Normal file
File diff suppressed because it is too large
Load Diff
4
zeroidc/vendor/wasm-bindgen/CONTRIBUTING.md
vendored
Normal file
4
zeroidc/vendor/wasm-bindgen/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# Contributing
|
||||
|
||||
See the ["Contributing" section of the `wasm-bindgen`
|
||||
guide](https://rustwasm.github.io/docs/wasm-bindgen/contributing/index.html).
|
||||
68
zeroidc/vendor/wasm-bindgen/Cargo.toml
vendored
Normal file
68
zeroidc/vendor/wasm-bindgen/Cargo.toml
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
|
||||
#
|
||||
# When uploading crates to the registry Cargo will automatically
|
||||
# "normalize" Cargo.toml files for maximal compatibility
|
||||
# with all versions of Cargo and also rewrite `path` dependencies
|
||||
# to registry (e.g., crates.io) dependencies.
|
||||
#
|
||||
# If you are reading this file be aware that the original Cargo.toml
|
||||
# will likely look very different (and much more reasonable).
|
||||
# See Cargo.toml.orig for the original contents.
|
||||
|
||||
[package]
|
||||
edition = "2018"
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.80"
|
||||
authors = ["The wasm-bindgen Developers"]
|
||||
description = "Easy support for interacting between JS and Rust.\n"
|
||||
homepage = "https://rustwasm.github.io/"
|
||||
documentation = "https://docs.rs/wasm-bindgen"
|
||||
readme = "README.md"
|
||||
categories = ["wasm"]
|
||||
license = "MIT/Apache-2.0"
|
||||
repository = "https://github.com/rustwasm/wasm-bindgen"
|
||||
[package.metadata.docs.rs]
|
||||
features = ["serde-serialize"]
|
||||
|
||||
[lib]
|
||||
test = false
|
||||
[dependencies.cfg-if]
|
||||
version = "1.0.0"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0"
|
||||
optional = true
|
||||
|
||||
[dependencies.serde_json]
|
||||
version = "1.0"
|
||||
optional = true
|
||||
|
||||
[dependencies.wasm-bindgen-macro]
|
||||
version = "=0.2.80"
|
||||
|
||||
[features]
|
||||
default = ["spans", "std"]
|
||||
enable-interning = ["std"]
|
||||
nightly = []
|
||||
serde-serialize = ["serde", "serde_json", "std"]
|
||||
spans = ["wasm-bindgen-macro/spans"]
|
||||
std = []
|
||||
strict-macro = ["wasm-bindgen-macro/strict-macro"]
|
||||
xxx_debug_only_print_generated_code = ["wasm-bindgen-macro/xxx_debug_only_print_generated_code"]
|
||||
[target."cfg(target_arch = \"wasm32\")".dev-dependencies.js-sys]
|
||||
version = "0.3.57"
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dev-dependencies.serde_derive]
|
||||
version = "1.0"
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dev-dependencies.wasm-bindgen-futures]
|
||||
version = "=0.4.30"
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dev-dependencies.wasm-bindgen-test]
|
||||
version = "=0.3.30"
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dev-dependencies.wasm-bindgen-test-crate-a]
|
||||
version = "0.1"
|
||||
|
||||
[target."cfg(target_arch = \"wasm32\")".dev-dependencies.wasm-bindgen-test-crate-b]
|
||||
version = "0.1"
|
||||
201
zeroidc/vendor/wasm-bindgen/LICENSE-APACHE
vendored
Normal file
201
zeroidc/vendor/wasm-bindgen/LICENSE-APACHE
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
25
zeroidc/vendor/wasm-bindgen/LICENSE-MIT
vendored
Normal file
25
zeroidc/vendor/wasm-bindgen/LICENSE-MIT
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
Copyright (c) 2014 Alex Crichton
|
||||
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
113
zeroidc/vendor/wasm-bindgen/README.md
vendored
Normal file
113
zeroidc/vendor/wasm-bindgen/README.md
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
<div align="center">
|
||||
|
||||
<h1><code>wasm-bindgen</code></h1>
|
||||
|
||||
<p>
|
||||
<strong>Facilitating high-level interactions between Wasm modules and JavaScript.</strong>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="https://dev.azure.com/rustwasm/wasm-bindgen/_build/latest?definitionId=1&branchName=master"><img src="https://img.shields.io/azure-devops/build/rustwasm/wasm-bindgen/1.svg?style=flat-square" alt="Build Status" /></a>
|
||||
<a href="https://crates.io/crates/wasm-bindgen"><img src="https://img.shields.io/crates/v/wasm-bindgen.svg?style=flat-square" alt="Crates.io version" /></a>
|
||||
<a href="https://crates.io/crates/wasm-bindgen"><img src="https://img.shields.io/crates/d/wasm-bindgen.svg?style=flat-square" alt="Download" /></a>
|
||||
<a href="https://docs.rs/wasm-bindgen"><img src="https://img.shields.io/badge/docs-latest-blue.svg?style=flat-square" alt="docs.rs docs" /></a>
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
<a href="https://rustwasm.github.io/docs/wasm-bindgen/">Guide</a>
|
||||
<span> | </span>
|
||||
<a href="https://docs.rs/wasm-bindgen">API Docs</a>
|
||||
<span> | </span>
|
||||
<a href="https://github.com/rustwasm/wasm-bindgen/blob/master/CONTRIBUTING.md">Contributing</a>
|
||||
<span> | </span>
|
||||
<a href="https://discord.gg/xMZ7CCY">Chat</a>
|
||||
</h3>
|
||||
|
||||
<sub>Built with 🦀🕸 by <a href="https://rustwasm.github.io/">The Rust and WebAssembly Working Group</a></sub>
|
||||
</div>
|
||||
|
||||
## Example
|
||||
|
||||
Import JavaScript things into Rust and export Rust things to JavaScript.
|
||||
|
||||
```rust
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
// Import the `window.alert` function from the Web.
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
fn alert(s: &str);
|
||||
}
|
||||
|
||||
// Export a `greet` function from Rust to JavaScript, that alerts a
|
||||
// hello message.
|
||||
#[wasm_bindgen]
|
||||
pub fn greet(name: &str) {
|
||||
alert(&format!("Hello, {}!", name));
|
||||
}
|
||||
```
|
||||
|
||||
Use exported Rust things from JavaScript with ECMAScript modules!
|
||||
|
||||
```js
|
||||
import { greet } from "./hello_world";
|
||||
|
||||
greet("World!");
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
* **Lightweight.** Only pay for what you use. `wasm-bindgen` only generates
|
||||
bindings and glue for the JavaScript imports you actually use and Rust
|
||||
functionality that you export. For example, importing and using the
|
||||
`document.querySelector` method doesn't cause `Node.prototype.appendChild` or
|
||||
`window.alert` to be included in the bindings as well.
|
||||
|
||||
* **ECMAScript modules.** Just import WebAssembly modules the same way you would
|
||||
import JavaScript modules. Future compatible with [WebAssembly modules and
|
||||
ECMAScript modules integration][wasm-es-modules].
|
||||
|
||||
* **Designed with the ["Web IDL bindings" proposal][webidl-bindings] in mind.**
|
||||
Eventually, there won't be any JavaScript shims between Rust-generated wasm
|
||||
functions and native DOM methods. Because the wasm functions are statically
|
||||
type checked, some of those native methods' dynamic type checks should become
|
||||
unnecessary, promising to unlock even-faster-than-JavaScript DOM access.
|
||||
|
||||
[wasm-es-modules]: https://github.com/WebAssembly/esm-integration
|
||||
[webidl-bindings]: https://github.com/WebAssembly/proposals/issues/8
|
||||
|
||||
## Guide
|
||||
|
||||
[**📚 Read the `wasm-bindgen` guide here! 📚**](https://rustwasm.github.io/docs/wasm-bindgen/)
|
||||
|
||||
You can find general documentation about using Rust and WebAssembly together
|
||||
[here](https://rustwasm.github.io/docs).
|
||||
|
||||
## API Docs
|
||||
|
||||
- [wasm-bindgen](https://docs.rs/wasm-bindgen)
|
||||
- [js-sys](https://docs.rs/js-sys)
|
||||
- [web-sys](https://docs.rs/web-sys)
|
||||
- [wasm-bindgen-futures](https://docs.rs/wasm-bindgen-futures)
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under either of
|
||||
|
||||
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
||||
http://www.apache.org/licenses/LICENSE-2.0)
|
||||
* MIT license ([LICENSE-MIT](LICENSE-MIT) or
|
||||
http://opensource.org/licenses/MIT)
|
||||
|
||||
at your option.
|
||||
|
||||
## Contribution
|
||||
|
||||
**[See the "Contributing" section of the guide for information on
|
||||
hacking on `wasm-bindgen`!][contributing]**
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in this project by you, as defined in the Apache-2.0 license,
|
||||
shall be dual licensed as above, without any additional terms or conditions.
|
||||
|
||||
[contributing]: https://rustwasm.github.io/docs/wasm-bindgen/contributing/index.html
|
||||
14
zeroidc/vendor/wasm-bindgen/_package.json
vendored
Normal file
14
zeroidc/vendor/wasm-bindgen/_package.json
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build": "webpack",
|
||||
"serve": "webpack serve"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@wasm-tool/wasm-pack-plugin": "1.5.0",
|
||||
"html-webpack-plugin": "^5.3.2",
|
||||
"text-encoding": "^0.7.0",
|
||||
"webpack": "^5.49.0",
|
||||
"webpack-cli": "^4.7.2",
|
||||
"webpack-dev-server": "^3.11.2"
|
||||
}
|
||||
}
|
||||
4
zeroidc/vendor/wasm-bindgen/build.rs
vendored
Normal file
4
zeroidc/vendor/wasm-bindgen/build.rs
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
// Empty `build.rs` so that `[package] links = ...` works in `Cargo.toml`.
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
}
|
||||
7
zeroidc/vendor/wasm-bindgen/examples/README.md
vendored
Normal file
7
zeroidc/vendor/wasm-bindgen/examples/README.md
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# Examples
|
||||
|
||||
This directory contains a number of Cargo projects that are all examples of how
|
||||
to use `wasm-bindgen` in various contexts. More documentation can be [found
|
||||
online][dox]
|
||||
|
||||
[dox]: https://rustwasm.github.io/docs/wasm-bindgen/examples/index.html
|
||||
15
zeroidc/vendor/wasm-bindgen/examples/import_js/README.md
vendored
Normal file
15
zeroidc/vendor/wasm-bindgen/examples/import_js/README.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Importing non-browser JS
|
||||
|
||||
[View documentation for this example online][dox] or [View compiled example
|
||||
online][compiled]
|
||||
|
||||
[compiled]: https://rustwasm.github.io/wasm-bindgen/exbuild/import_js/
|
||||
[dox]: https://rustwasm.github.io/docs/wasm-bindgen/examples/import-js.html
|
||||
|
||||
You can build the example locally with:
|
||||
|
||||
```
|
||||
$ npm run serve
|
||||
```
|
||||
|
||||
and then visiting http://localhost:8080 in a browser should run the example!
|
||||
8
zeroidc/vendor/wasm-bindgen/examples/import_js/index.html
vendored
Normal file
8
zeroidc/vendor/wasm-bindgen/examples/import_js/index.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
|
||||
</head>
|
||||
<body>
|
||||
<p>Open up the developer console and you should see "Hello from Rust!"</p>
|
||||
</body>
|
||||
</html>
|
||||
4
zeroidc/vendor/wasm-bindgen/examples/import_js/index.js
vendored
Normal file
4
zeroidc/vendor/wasm-bindgen/examples/import_js/index.js
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
// For more comments about what's going on here, check out the `hello_world`
|
||||
// example
|
||||
import('./crate/pkg')
|
||||
.catch(console.error);
|
||||
14
zeroidc/vendor/wasm-bindgen/examples/import_js/package.json
vendored
Normal file
14
zeroidc/vendor/wasm-bindgen/examples/import_js/package.json
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build": "webpack",
|
||||
"serve" : "webpack serve"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@wasm-tool/wasm-pack-plugin": "1.5.0",
|
||||
"text-encoding": "^0.7.0",
|
||||
"html-webpack-plugin": "^5.3.2",
|
||||
"webpack": "^5.49.0",
|
||||
"webpack-cli": "^4.7.2",
|
||||
"webpack-dev-server": "^3.11.2"
|
||||
}
|
||||
}
|
||||
30
zeroidc/vendor/wasm-bindgen/examples/import_js/webpack.config.js
vendored
Normal file
30
zeroidc/vendor/wasm-bindgen/examples/import_js/webpack.config.js
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
const path = require('path');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const webpack = require('webpack');
|
||||
const WasmPackPlugin = require("@wasm-tool/wasm-pack-plugin");
|
||||
|
||||
module.exports = {
|
||||
entry: './index.js',
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'index.js',
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebpackPlugin({
|
||||
template: 'index.html'
|
||||
}),
|
||||
new WasmPackPlugin({
|
||||
crateDirectory: path.resolve(__dirname, "crate")
|
||||
}),
|
||||
// Have this example work in Edge which doesn't ship `TextEncoder` or
|
||||
// `TextDecoder` at this time.
|
||||
new webpack.ProvidePlugin({
|
||||
TextDecoder: ['text-encoding', 'TextDecoder'],
|
||||
TextEncoder: ['text-encoding', 'TextEncoder']
|
||||
})
|
||||
],
|
||||
mode: 'development',
|
||||
experiments: {
|
||||
asyncWebAssembly: true
|
||||
}
|
||||
};
|
||||
10
zeroidc/vendor/wasm-bindgen/guide/book.toml
vendored
Normal file
10
zeroidc/vendor/wasm-bindgen/guide/book.toml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
[book]
|
||||
authors = ["Nick Fitzgerald"]
|
||||
multilingual = false
|
||||
src = "src"
|
||||
title = "The `wasm-bindgen` Guide"
|
||||
|
||||
[build]
|
||||
build-dir = "book/html"
|
||||
|
||||
[output.html]
|
||||
125
zeroidc/vendor/wasm-bindgen/guide/src/SUMMARY.md
vendored
Normal file
125
zeroidc/vendor/wasm-bindgen/guide/src/SUMMARY.md
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
# Summary
|
||||
|
||||
[Introduction](./introduction.md)
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
- [Examples](./examples/index.md)
|
||||
- [Hello, World!](./examples/hello-world.md)
|
||||
- [Using `console.log`](./examples/console-log.md)
|
||||
- [Small wasm files](./examples/add.md)
|
||||
- [Without a Bundler](./examples/without-a-bundler.md)
|
||||
- [Converting WebAssembly to JS](./examples/wasm2js.md)
|
||||
- [Importing functions from JS](./examples/import-js.md)
|
||||
- [Working with `char`](./examples/char.md)
|
||||
- [js-sys: WebAssembly in WebAssembly](./examples/wasm-in-wasm.md)
|
||||
- [web-sys: DOM hello world](./examples/dom.md)
|
||||
- [web-sys: Closures](./examples/closures.md)
|
||||
- [web-sys: `performance.now`](./examples/performance.md)
|
||||
- [web-sys: using `fetch`](./examples/fetch.md)
|
||||
- [web-sys: `canvas` hello world](./examples/2d-canvas.md)
|
||||
- [web-sys: `canvas` Julia set](./examples/julia.md)
|
||||
- [web-sys: WebAudio](./examples/web-audio.md)
|
||||
- [web-sys: WebGL](./examples/webgl.md)
|
||||
- [web-sys: WebSockets](./examples/websockets.md)
|
||||
- [web-sys: WebRTC DataChannel](./examples/webrtc_datachannel.md)
|
||||
- [web-sys: `requestAnimationFrame`](./examples/request-animation-frame.md)
|
||||
- [web-sys: A Simple Paint Program](./examples/paint.md)
|
||||
- [web-sys: WASM in Web Worker](./examples/wasm-in-web-worker.md)
|
||||
- [Parallel Raytracing](./examples/raytrace.md)
|
||||
- [web-sys: A TODO MVC App](./examples/todomvc.md)
|
||||
- [Reference](./reference/index.md)
|
||||
- [Deployment](./reference/deployment.md)
|
||||
- [JS snippets](./reference/js-snippets.md)
|
||||
- [Passing Rust Closures to JS](./reference/passing-rust-closures-to-js.md)
|
||||
- [Receiving JS Closures in Rust](./reference/receiving-js-closures-in-rust.md)
|
||||
- [`Promise`s and `Future`s](./reference/js-promises-and-rust-futures.md)
|
||||
- [Iterating over JS Values](./reference/iterating-over-js-values.md)
|
||||
- [Arbitrary Data with Serde](./reference/arbitrary-data-with-serde.md)
|
||||
- [Accessing Properties of Untyped JS Values](./reference/accessing-properties-of-untyped-js-values.md)
|
||||
- [Working with Duck-Typed Interfaces](./reference/working-with-duck-typed-interfaces.md)
|
||||
- [Command Line Interface](./reference/cli.md)
|
||||
- [Optimizing for Size](./reference/optimize-size.md)
|
||||
- [Supported Rust Targets](./reference/rust-targets.md)
|
||||
- [Supported Browsers](./reference/browser-support.md)
|
||||
- [Support for Weak References](./reference/weak-references.md)
|
||||
- [Support for Reference Types](./reference/reference-types.md)
|
||||
- [Supported Types](./reference/types.md)
|
||||
- [Imported JavaScript Types](./reference/types/imported-js-types.md)
|
||||
- [Exported Rust Types](./reference/types/exported-rust-types.md)
|
||||
- [`JsValue`](./reference/types/jsvalue.md)
|
||||
- [`Box<[JsValue]>`](./reference/types/boxed-jsvalue-slice.md)
|
||||
- [`*const T` and `*mut T`](./reference/types/pointers.md)
|
||||
- [Numbers](./reference/types/numbers.md)
|
||||
- [`bool`](./reference/types/bool.md)
|
||||
- [`char`](./reference/types/char.md)
|
||||
- [`str`](./reference/types/str.md)
|
||||
- [`String`](./reference/types/string.md)
|
||||
- [Number Slices](./reference/types/number-slices.md)
|
||||
- [Boxed Number Slices](./reference/types/boxed-number-slices.md)
|
||||
- [`Result<T, JsValue>`](./reference/types/result.md)
|
||||
- [`#[wasm_bindgen]` Attributes](./reference/attributes/index.md)
|
||||
- [On JavaScript Imports](./reference/attributes/on-js-imports/index.md)
|
||||
- [`catch`](./reference/attributes/on-js-imports/catch.md)
|
||||
- [`constructor`](./reference/attributes/on-js-imports/constructor.md)
|
||||
- [`extends`](./reference/attributes/on-js-imports/extends.md)
|
||||
- [`getter` and `setter`](./reference/attributes/on-js-imports/getter-and-setter.md)
|
||||
- [`final`](./reference/attributes/on-js-imports/final.md)
|
||||
- [`indexing_getter`, `indexing_setter`, and `indexing_deleter`](./reference/attributes/on-js-imports/indexing-getter-setter-deleter.md)
|
||||
- [`js_class = "Blah"`](./reference/attributes/on-js-imports/js_class.md)
|
||||
- [`js_name`](./reference/attributes/on-js-imports/js_name.md)
|
||||
- [`js_namespace`](./reference/attributes/on-js-imports/js_namespace.md)
|
||||
- [`method`](./reference/attributes/on-js-imports/method.md)
|
||||
- [`module = "blah"`](./reference/attributes/on-js-imports/module.md)
|
||||
- [`raw_module = "blah"`](./reference/attributes/on-js-imports/raw_module.md)
|
||||
- [`static_method_of = Blah`](./reference/attributes/on-js-imports/static_method_of.md)
|
||||
- [`structural`](./reference/attributes/on-js-imports/structural.md)
|
||||
- [`variadic`](./reference/attributes/on-js-imports/variadic.md)
|
||||
- [`vendor_prefix`](./reference/attributes/on-js-imports/vendor_prefix.md)
|
||||
- [On Rust Exports](./reference/attributes/on-rust-exports/index.md)
|
||||
- [`constructor`](./reference/attributes/on-rust-exports/constructor.md)
|
||||
- [`js_name = Blah`](./reference/attributes/on-rust-exports/js_name.md)
|
||||
- [`readonly`](./reference/attributes/on-rust-exports/readonly.md)
|
||||
- [`skip`](./reference/attributes/on-rust-exports/skip.md)
|
||||
- [`start`](./reference/attributes/on-rust-exports/start.md)
|
||||
- [`typescript_custom_section`](./reference/attributes/on-rust-exports/typescript_custom_section.md)
|
||||
- [`getter` and `setter`](./reference/attributes/on-rust-exports/getter-and-setter.md)
|
||||
- [`inspectable`](./reference/attributes/on-rust-exports/inspectable.md)
|
||||
- [`skip_typescript`](./reference/attributes/on-rust-exports/skip_typescript.md)
|
||||
- [`typescript_type`](./reference/attributes/on-rust-exports/typescript_type.md)
|
||||
- [`getter_with_clone`](./reference/attributes/on-rust-exports/getter_with_clone.md)
|
||||
|
||||
- [`web-sys`](./web-sys/index.md)
|
||||
- [Using `web-sys`](./web-sys/using-web-sys.md)
|
||||
- [Cargo Features](./web-sys/cargo-features.md)
|
||||
- [Function Overloads](./web-sys/function-overloads.md)
|
||||
- [Type Translations](./web-sys/type-translations.md)
|
||||
- [Inheritance](./web-sys/inheritance.md)
|
||||
- [Unstable APIs](./web-sys/unstable-apis.md)
|
||||
|
||||
- [Testing with `wasm-bindgen-test`](./wasm-bindgen-test/index.md)
|
||||
- [Usage](./wasm-bindgen-test/usage.md)
|
||||
- [Writing Asynchronous Tests](./wasm-bindgen-test/asynchronous-tests.md)
|
||||
- [Testing in Headless Browsers](./wasm-bindgen-test/browsers.md)
|
||||
- [Continuous Integration](./wasm-bindgen-test/continuous-integration.md)
|
||||
|
||||
- [Contributing to `wasm-bindgen`](./contributing/index.md)
|
||||
- [Testing](./contributing/testing.md)
|
||||
- [Internal Design](./contributing/design/index.md)
|
||||
- [JS Objects in Rust](./contributing/design/js-objects-in-rust.md)
|
||||
- [Exporting a function to JS](./contributing/design/exporting-rust.md)
|
||||
- [Exporting a struct to JS](./contributing/design/exporting-rust-struct.md)
|
||||
- [Importing a function from JS](./contributing/design/importing-js.md)
|
||||
- [Importing a class from JS](./contributing/design/importing-js-struct.md)
|
||||
- [Rust Type conversions](./contributing/design/rust-type-conversions.md)
|
||||
- [Types in `wasm-bindgen`](./contributing/design/describe.md)
|
||||
- [`js-sys`](./contributing/js-sys/index.md)
|
||||
- [Testing](./contributing/js-sys/testing.md)
|
||||
- [Adding More APIs](./contributing/js-sys/adding-more-apis.md)
|
||||
- [`web-sys`](./contributing/web-sys/index.md)
|
||||
- [Overview](./contributing/web-sys/overview.md)
|
||||
- [Testing](./contributing/web-sys/testing.md)
|
||||
- [Logging](./contributing/web-sys/logging.md)
|
||||
- [Supporting More Web APIs](./contributing/web-sys/supporting-more-web-apis.md)
|
||||
- [Publishing](./contributing/publishing.md)
|
||||
- [Team](./contributing/team.md)
|
||||
3
zeroidc/vendor/wasm-bindgen/guide/src/_headers
vendored
Normal file
3
zeroidc/vendor/wasm-bindgen/guide/src/_headers
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
/*
|
||||
Cross-Origin-Opener-Policy: same-origin
|
||||
Cross-Origin-Embedder-Policy: require-corp
|
||||
57
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/describe.md
vendored
Normal file
57
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/describe.md
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
# Communicating types to `wasm-bindgen`
|
||||
|
||||
The last aspect to talk about when converting Rust/JS types amongst one another
|
||||
is how this information is actually communicated. The `#[wasm_bindgen]` macro is
|
||||
running over the syntactical (unresolved) structure of the Rust code and is then
|
||||
responsible for generating information that `wasm-bindgen` the CLI tool later
|
||||
reads.
|
||||
|
||||
To accomplish this a slightly unconventional approach is taken. Static
|
||||
information about the structure of the Rust code is serialized via JSON
|
||||
(currently) to a custom section of the wasm executable. Other information, like
|
||||
what the types actually are, unfortunately isn't known until later in the
|
||||
compiler due to things like associated type projections and typedefs. It also
|
||||
turns out that we want to convey "rich" types like `FnMut(String, Foo,
|
||||
&JsValue)` to the `wasm-bindgen` CLI, and handling all this is pretty tricky!
|
||||
|
||||
To solve this issue the `#[wasm_bindgen]` macro generates **executable
|
||||
functions** which "describe the type signature of an import or export". These
|
||||
executable functions are what the `WasmDescribe` trait is all about:
|
||||
|
||||
```rust
|
||||
pub trait WasmDescribe {
|
||||
fn describe();
|
||||
}
|
||||
```
|
||||
|
||||
While deceptively simple this trait is actually quite important. When you write,
|
||||
an export like this:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
fn greet(a: &str) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
In addition to the shims we talked about above which JS generates the macro
|
||||
*also* generates something like:
|
||||
|
||||
```
|
||||
#[no_mangle]
|
||||
pub extern "C" fn __wbindgen_describe_greet() {
|
||||
<dyn Fn(&str)>::describe();
|
||||
}
|
||||
```
|
||||
|
||||
Or in other words it generates invocations of `describe` functions. In doing so
|
||||
the `__wbindgen_describe_greet` shim is a programmatic description of the type
|
||||
layouts of an import/export. These are then executed when `wasm-bindgen` runs!
|
||||
These executions rely on an import called `__wbindgen_describe` which passes one
|
||||
`u32` to the host, and when called multiple times gives a `Vec<u32>`
|
||||
effectively. This `Vec<u32>` can then be reparsed into an `enum Descriptor`
|
||||
which fully describes a type.
|
||||
|
||||
All in all this is a bit roundabout but shouldn't have any impact on the
|
||||
generated code or runtime at all. All these descriptor functions are pruned from
|
||||
the emitted wasm file.
|
||||
149
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/exporting-rust-struct.md
vendored
Normal file
149
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/exporting-rust-struct.md
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
# Exporting a struct to JS
|
||||
|
||||
So far we've covered JS objects, importing functions, and exporting functions.
|
||||
This has given us quite a rich base to build on so far, and that's great! We
|
||||
sometimes, though, want to go even further and define a JS `class` in Rust. Or
|
||||
in other words, we want to expose an object with methods from Rust to JS rather
|
||||
than just importing/exporting free functions.
|
||||
|
||||
The `#[wasm_bindgen]` attribute can annotate both a `struct` and `impl` blocks
|
||||
to allow:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
pub struct Foo {
|
||||
internal: i32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Foo {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(val: i32) -> Foo {
|
||||
Foo { internal: val }
|
||||
}
|
||||
|
||||
pub fn get(&self) -> i32 {
|
||||
self.internal
|
||||
}
|
||||
|
||||
pub fn set(&mut self, val: i32) {
|
||||
self.internal = val;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This is a typical Rust `struct` definition for a type with a constructor and a
|
||||
few methods. Annotating the struct with `#[wasm_bindgen]` means that we'll
|
||||
generate necessary trait impls to convert this type to/from the JS boundary. The
|
||||
annotated `impl` block here means that the functions inside will also be made
|
||||
available to JS through generated shims. If we take a look at the generated JS
|
||||
code for this we'll see:
|
||||
|
||||
```js
|
||||
import * as wasm from './js_hello_world_bg';
|
||||
|
||||
export class Foo {
|
||||
static __construct(ptr) {
|
||||
return new Foo(ptr);
|
||||
}
|
||||
|
||||
constructor(ptr) {
|
||||
this.ptr = ptr;
|
||||
}
|
||||
|
||||
free() {
|
||||
const ptr = this.ptr;
|
||||
this.ptr = 0;
|
||||
wasm.__wbg_foo_free(ptr);
|
||||
}
|
||||
|
||||
static new(arg0) {
|
||||
const ret = wasm.foo_new(arg0);
|
||||
return Foo.__construct(ret)
|
||||
}
|
||||
|
||||
get() {
|
||||
const ret = wasm.foo_get(this.ptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
set(arg0) {
|
||||
const ret = wasm.foo_set(this.ptr, arg0);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
That's actually not much! We can see here though how we've translated from Rust
|
||||
to JS:
|
||||
|
||||
* Associated functions in Rust (those without `self`) turn into `static`
|
||||
functions in JS.
|
||||
* Methods in Rust turn into methods in wasm.
|
||||
* Manual memory management is exposed in JS as well. The `free` function is
|
||||
required to be invoked to deallocate resources on the Rust side of things.
|
||||
|
||||
To be able to use `new Foo()`, you'd need to annotate `new` as `#[wasm_bindgen(constructor)]`.
|
||||
|
||||
One important aspect to note here, though, is that once `free` is called the JS
|
||||
object is "neutered" in that its internal pointer is nulled out. This means that
|
||||
future usage of this object should trigger a panic in Rust.
|
||||
|
||||
The real trickery with these bindings ends up happening in Rust, however, so
|
||||
let's take a look at that.
|
||||
|
||||
```rust
|
||||
// original input to `#[wasm_bindgen]` omitted ...
|
||||
|
||||
#[export_name = "foo_new"]
|
||||
pub extern "C" fn __wasm_bindgen_generated_Foo_new(arg0: i32) -> u32
|
||||
let ret = Foo::new(arg0);
|
||||
Box::into_raw(Box::new(WasmRefCell::new(ret))) as u32
|
||||
}
|
||||
|
||||
#[export_name = "foo_get"]
|
||||
pub extern "C" fn __wasm_bindgen_generated_Foo_get(me: u32) -> i32 {
|
||||
let me = me as *mut WasmRefCell<Foo>;
|
||||
wasm_bindgen::__rt::assert_not_null(me);
|
||||
let me = unsafe { &*me };
|
||||
return me.borrow().get();
|
||||
}
|
||||
|
||||
#[export_name = "foo_set"]
|
||||
pub extern "C" fn __wasm_bindgen_generated_Foo_set(me: u32, arg1: i32) {
|
||||
let me = me as *mut WasmRefCell<Foo>;
|
||||
wasm_bindgen::__rt::assert_not_null(me);
|
||||
let me = unsafe { &*me };
|
||||
me.borrow_mut().set(arg1);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn __wbindgen_foo_free(me: u32) {
|
||||
let me = me as *mut WasmRefCell<Foo>;
|
||||
wasm_bindgen::__rt::assert_not_null(me);
|
||||
(*me).borrow_mut(); // ensure no active borrows
|
||||
drop(Box::from_raw(me));
|
||||
}
|
||||
```
|
||||
|
||||
As with before this is cleaned up from the actual output but it's the same idea
|
||||
as to what's going on! Here we can see a shim for each function as well as a
|
||||
shim for deallocating an instance of `Foo`. Recall that the only valid wasm
|
||||
types today are numbers, so we're required to shoehorn all of `Foo` into a
|
||||
`u32`, which is currently done via `Box` (like `std::unique_ptr` in C++).
|
||||
Note, though, that there's an extra layer here, `WasmRefCell`. This type is the
|
||||
same as [`RefCell`] and can be mostly glossed over.
|
||||
|
||||
The purpose for this type, if you're interested though, is to uphold Rust's
|
||||
guarantees about aliasing in a world where aliasing is rampant (JS).
|
||||
Specifically the `&Foo` type means that there can be as much aliasing as you'd
|
||||
like, but crucially `&mut Foo` means that it is the sole pointer to the data
|
||||
(no other `&Foo` to the same instance exists). The [`RefCell`] type in libstd
|
||||
is a way of dynamically enforcing this at runtime (as opposed to compile time
|
||||
where it usually happens). Baking in `WasmRefCell` is the same idea here,
|
||||
adding runtime checks for aliasing which are typically happening at compile
|
||||
time. This is currently a Rust-specific feature which isn't actually in the
|
||||
`wasm-bindgen` tool itself, it's just in the Rust-generated code (aka the
|
||||
`#[wasm_bindgen]` attribute).
|
||||
|
||||
[`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html
|
||||
120
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/exporting-rust.md
vendored
Normal file
120
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/exporting-rust.md
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
# Exporting a function to JS
|
||||
|
||||
Alright now that we've got a good grasp on JS objects and how they're working,
|
||||
let's take a look at another feature of `wasm-bindgen`: exporting functionality
|
||||
with types that are richer than just numbers.
|
||||
|
||||
The basic idea around exporting functionality with more flavorful types is that
|
||||
the wasm exports won't actually be called directly. Instead the generated
|
||||
`foo.js` module will have shims for all exported functions in the wasm module.
|
||||
|
||||
The most interesting conversion here happens with strings so let's take a look
|
||||
at that.
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
pub fn greet(a: &str) -> String {
|
||||
format!("Hello, {}!", a)
|
||||
}
|
||||
```
|
||||
|
||||
Here we'd like to define an ES module that looks like
|
||||
|
||||
```ts
|
||||
// foo.d.ts
|
||||
export function greet(a: string): string;
|
||||
```
|
||||
|
||||
To see what's going on, let's take a look at the generated shim
|
||||
|
||||
```js
|
||||
import * as wasm from './foo_bg';
|
||||
|
||||
function passStringToWasm(arg) {
|
||||
const buf = new TextEncoder('utf-8').encode(arg);
|
||||
const len = buf.length;
|
||||
const ptr = wasm.__wbindgen_malloc(len);
|
||||
let array = new Uint8Array(wasm.memory.buffer);
|
||||
array.set(buf, ptr);
|
||||
return [ptr, len];
|
||||
}
|
||||
|
||||
function getStringFromWasm(ptr, len) {
|
||||
const mem = new Uint8Array(wasm.memory.buffer);
|
||||
const slice = mem.slice(ptr, ptr + len);
|
||||
const ret = new TextDecoder('utf-8').decode(slice);
|
||||
return ret;
|
||||
}
|
||||
|
||||
export function greet(arg0) {
|
||||
const [ptr0, len0] = passStringToWasm(arg0);
|
||||
try {
|
||||
const ret = wasm.greet(ptr0, len0);
|
||||
const ptr = wasm.__wbindgen_boxed_str_ptr(ret);
|
||||
const len = wasm.__wbindgen_boxed_str_len(ret);
|
||||
const realRet = getStringFromWasm(ptr, len);
|
||||
wasm.__wbindgen_boxed_str_free(ret);
|
||||
return realRet;
|
||||
} finally {
|
||||
wasm.__wbindgen_free(ptr0, len0);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Phew, that's quite a lot! We can sort of see though if we look closely what's
|
||||
happening:
|
||||
|
||||
* Strings are passed to wasm via two arguments, a pointer and a length. Right
|
||||
now we have to copy the string onto the wasm heap which means we'll be using
|
||||
`TextEncoder` to actually do the encoding. Once this is done we use an
|
||||
internal function in `wasm-bindgen` to allocate space for the string to go,
|
||||
and then we'll pass that ptr/length to wasm later on.
|
||||
|
||||
* Returning strings from wasm is a little tricky as we need to return a ptr/len
|
||||
pair, but wasm currently only supports one return value (multiple return values
|
||||
[is being standardized](https://github.com/WebAssembly/design/issues/1146)).
|
||||
To work around this in the meantime, we're actually returning a pointer to a
|
||||
ptr/len pair, and then using functions to access the various fields.
|
||||
|
||||
* Some cleanup ends up happening in wasm. The `__wbindgen_boxed_str_free`
|
||||
function is used to free the return value of `greet` after it's been decoded
|
||||
onto the JS heap (using `TextDecoder`). The `__wbindgen_free` is then used to
|
||||
free the space we allocated to pass the string argument once the function call
|
||||
is done.
|
||||
|
||||
Next let's take a look at the Rust side of things as well. Here we'll be looking
|
||||
at a mostly abbreviated and/or "simplified" in the sense of this is what it
|
||||
compiles down to:
|
||||
|
||||
```rust
|
||||
pub extern "C" fn greet(a: &str) -> String {
|
||||
format!("Hello, {}!", a)
|
||||
}
|
||||
|
||||
#[export_name = "greet"]
|
||||
pub extern "C" fn __wasm_bindgen_generated_greet(
|
||||
arg0_ptr: *const u8,
|
||||
arg0_len: usize,
|
||||
) -> *mut String {
|
||||
let arg0 = unsafe {
|
||||
let slice = ::std::slice::from_raw_parts(arg0_ptr, arg0_len);
|
||||
::std::str::from_utf8_unchecked(slice)
|
||||
};
|
||||
let _ret = greet(arg0);
|
||||
Box::into_raw(Box::new(_ret))
|
||||
}
|
||||
```
|
||||
|
||||
Here we can see again that our `greet` function is unmodified and has a wrapper
|
||||
to call it. This wrapper will take the ptr/len argument and convert it to a
|
||||
string slice, while the return value is boxed up into just a pointer and is
|
||||
then returned up to was for reading via the `__wbindgen_boxed_str_*` functions.
|
||||
|
||||
So in general exporting a function involves a shim both in JS and in Rust with
|
||||
each side translating to or from wasm arguments to the native types of each
|
||||
language. The `wasm-bindgen` tool manages hooking up all these shims while the
|
||||
`#[wasm_bindgen]` macro takes care of the Rust shim as well.
|
||||
|
||||
Most arguments have a relatively clear way to convert them, bit if you've got
|
||||
any questions just let me know!
|
||||
|
||||
206
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/importing-js-struct.md
vendored
Normal file
206
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/importing-js-struct.md
vendored
Normal file
@@ -0,0 +1,206 @@
|
||||
# Importing a class from JS
|
||||
|
||||
Just like with functions after we've started exporting we'll also want to
|
||||
import! Now that we've exported a `class` to JS we'll want to also be able to
|
||||
import classes in Rust as well to invoke methods and such. Since JS classes are
|
||||
in general just JS objects the bindings here will look pretty similar to the JS
|
||||
object bindings describe above.
|
||||
|
||||
As usual though, let's dive into an example!
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(module = "./bar")]
|
||||
extern "C" {
|
||||
type Bar;
|
||||
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new(arg: i32) -> Bar;
|
||||
|
||||
#[wasm_bindgen(js_namespace = Bar)]
|
||||
fn another_function() -> i32;
|
||||
|
||||
#[wasm_bindgen(method)]
|
||||
fn get(this: &Bar) -> i32;
|
||||
|
||||
#[wasm_bindgen(method)]
|
||||
fn set(this: &Bar, val: i32);
|
||||
|
||||
#[wasm_bindgen(method, getter)]
|
||||
fn property(this: &Bar) -> i32;
|
||||
|
||||
#[wasm_bindgen(method, setter)]
|
||||
fn set_property(this: &Bar, val: i32);
|
||||
}
|
||||
|
||||
fn run() {
|
||||
let bar = Bar::new(Bar::another_function());
|
||||
let x = bar.get();
|
||||
bar.set(x + 3);
|
||||
|
||||
bar.set_property(bar.property() + 6);
|
||||
}
|
||||
```
|
||||
|
||||
Unlike our previous imports, this one's a bit more chatty! Remember that one of
|
||||
the goals of `wasm-bindgen` is to use native Rust syntax wherever possible, so
|
||||
this is mostly intended to use the `#[wasm_bindgen]` attribute to interpret
|
||||
what's written down in Rust. Now there's a few attribute annotations here, so
|
||||
let's go through one-by-one:
|
||||
|
||||
* `#[wasm_bindgen(module = "./bar")]` - seen before with imports this is declare
|
||||
where all the subsequent functionality is imported from. For example the `Bar`
|
||||
type is going to be imported from the `./bar` module.
|
||||
* `type Bar` - this is a declaration of JS class as a new type in Rust. This
|
||||
means that a new type `Bar` is generated which is "opaque" but is represented
|
||||
as internally containing a `JsValue`. We'll see more on this later.
|
||||
* `#[wasm_bindgen(constructor)]` - this indicates that the binding's name isn't
|
||||
actually used in JS but rather translates to `new Bar()`. The return value of
|
||||
this function must be a bare type, like `Bar`.
|
||||
* `#[wasm_bindgen(js_namespace = Bar)]` - this attribute indicates that the
|
||||
function declaration is namespaced through the `Bar` class in JS.
|
||||
* `#[wasm_bindgen(static_method_of = SomeJsClass)]` - this attribute is similar
|
||||
to `js_namespace`, but instead of producing a free function, produces a static
|
||||
method of `SomeJsClass`.
|
||||
* `#[wasm_bindgen(method)]` - and finally, this attribute indicates that a
|
||||
method call is going to happen. The first argument must be a JS struct, like
|
||||
`Bar`, and the call in JS looks like `Bar.prototype.set.call(...)`.
|
||||
|
||||
With all that in mind, let's take a look at the JS generated.
|
||||
|
||||
```js
|
||||
import * as wasm from './foo_bg';
|
||||
|
||||
import { Bar } from './bar';
|
||||
|
||||
// other support functions omitted...
|
||||
|
||||
export function __wbg_s_Bar_new() {
|
||||
return addHeapObject(new Bar());
|
||||
}
|
||||
|
||||
const another_function_shim = Bar.another_function;
|
||||
export function __wbg_s_Bar_another_function() {
|
||||
return another_function_shim();
|
||||
}
|
||||
|
||||
const get_shim = Bar.prototype.get;
|
||||
export function __wbg_s_Bar_get(ptr) {
|
||||
return shim.call(getObject(ptr));
|
||||
}
|
||||
|
||||
const set_shim = Bar.prototype.set;
|
||||
export function __wbg_s_Bar_set(ptr, arg0) {
|
||||
set_shim.call(getObject(ptr), arg0)
|
||||
}
|
||||
|
||||
const property_shim = Object.getOwnPropertyDescriptor(Bar.prototype, 'property').get;
|
||||
export function __wbg_s_Bar_property(ptr) {
|
||||
return property_shim.call(getObject(ptr));
|
||||
}
|
||||
|
||||
const set_property_shim = Object.getOwnPropertyDescriptor(Bar.prototype, 'property').set;
|
||||
export function __wbg_s_Bar_set_property(ptr, arg0) {
|
||||
set_property_shim.call(getObject(ptr), arg0)
|
||||
}
|
||||
```
|
||||
|
||||
Like when importing functions from JS we can see a bunch of shims are generated
|
||||
for all the relevant functions. The `new` static function has the
|
||||
`#[wasm_bindgen(constructor)]` attribute which means that instead of any
|
||||
particular method it should actually invoke the `new` constructor instead (as
|
||||
we see here). The static function `another_function`, however, is dispatched as
|
||||
`Bar.another_function`.
|
||||
|
||||
The `get` and `set` functions are methods so they go through `Bar.prototype`,
|
||||
and otherwise their first argument is implicitly the JS object itself which is
|
||||
loaded through `getObject` like we saw earlier.
|
||||
|
||||
Some real meat starts to show up though on the Rust side of things, so let's
|
||||
take a look:
|
||||
|
||||
```rust
|
||||
pub struct Bar {
|
||||
obj: JsValue,
|
||||
}
|
||||
|
||||
impl Bar {
|
||||
fn new() -> Bar {
|
||||
extern "C" {
|
||||
fn __wbg_s_Bar_new() -> u32;
|
||||
}
|
||||
unsafe {
|
||||
let ret = __wbg_s_Bar_new();
|
||||
Bar { obj: JsValue::__from_idx(ret) }
|
||||
}
|
||||
}
|
||||
|
||||
fn another_function() -> i32 {
|
||||
extern "C" {
|
||||
fn __wbg_s_Bar_another_function() -> i32;
|
||||
}
|
||||
unsafe {
|
||||
__wbg_s_Bar_another_function()
|
||||
}
|
||||
}
|
||||
|
||||
fn get(&self) -> i32 {
|
||||
extern "C" {
|
||||
fn __wbg_s_Bar_get(ptr: u32) -> i32;
|
||||
}
|
||||
unsafe {
|
||||
let ptr = self.obj.__get_idx();
|
||||
let ret = __wbg_s_Bar_get(ptr);
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
fn set(&self, val: i32) {
|
||||
extern "C" {
|
||||
fn __wbg_s_Bar_set(ptr: u32, val: i32);
|
||||
}
|
||||
unsafe {
|
||||
let ptr = self.obj.__get_idx();
|
||||
__wbg_s_Bar_set(ptr, val);
|
||||
}
|
||||
}
|
||||
|
||||
fn property(&self) -> i32 {
|
||||
extern "C" {
|
||||
fn __wbg_s_Bar_property(ptr: u32) -> i32;
|
||||
}
|
||||
unsafe {
|
||||
let ptr = self.obj.__get_idx();
|
||||
let ret = __wbg_s_Bar_property(ptr);
|
||||
return ret
|
||||
}
|
||||
}
|
||||
|
||||
fn set_property(&self, val: i32) {
|
||||
extern "C" {
|
||||
fn __wbg_s_Bar_set_property(ptr: u32, val: i32);
|
||||
}
|
||||
unsafe {
|
||||
let ptr = self.obj.__get_idx();
|
||||
__wbg_s_Bar_set_property(ptr, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl WasmBoundary for Bar {
|
||||
// ...
|
||||
}
|
||||
|
||||
impl ToRefWasmBoundary for Bar {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
In Rust we're seeing that a new type, `Bar`, is generated for this import of a
|
||||
class. The type `Bar` internally contains a `JsValue` as an instance of `Bar`
|
||||
is meant to represent a JS object stored in our module's stack/slab. This then
|
||||
works mostly the same way that we saw JS objects work in the beginning.
|
||||
|
||||
When calling `Bar::new` we'll get an index back which is wrapped up in `Bar`
|
||||
(which is itself just a `u32` in memory when stripped down). Each function then
|
||||
passes the index as the first argument and otherwise forwards everything along
|
||||
in Rust.
|
||||
75
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/importing-js.md
vendored
Normal file
75
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/importing-js.md
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
# Importing a function from JS
|
||||
|
||||
Now that we've exported some rich functionality to JS it's also time to import
|
||||
some! The goal here is to basically implement JS `import` statements in Rust,
|
||||
with fancy types and all.
|
||||
|
||||
First up, let's say we invert the function above and instead want to generate
|
||||
greetings in JS but call it from Rust. We might have, for example:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(module = "./greet")]
|
||||
extern "C" {
|
||||
fn greet(a: &str) -> String;
|
||||
}
|
||||
|
||||
fn other_code() {
|
||||
let greeting = greet("foo");
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
The basic idea of imports is the same as exports in that we'll have shims in
|
||||
both JS and Rust doing the necessary translation. Let's first see the JS shim in
|
||||
action:
|
||||
|
||||
```js
|
||||
import * as wasm from './foo_bg';
|
||||
|
||||
import { greet } from './greet';
|
||||
|
||||
// ...
|
||||
|
||||
export function __wbg_f_greet(ptr0, len0, wasmretptr) {
|
||||
const [retptr, retlen] = passStringToWasm(greet(getStringFromWasm(ptr0, len0)));
|
||||
(new Uint32Array(wasm.memory.buffer))[wasmretptr / 4] = retlen;
|
||||
return retptr;
|
||||
}
|
||||
```
|
||||
|
||||
The `getStringFromWasm` and `passStringToWasm` are the same as we saw before,
|
||||
and like with `__wbindgen_object_drop_ref` far above we've got this weird export
|
||||
from our module now! The `__wbg_f_greet` function is what's generated by
|
||||
`wasm-bindgen` to actually get imported in the `foo.wasm` module.
|
||||
|
||||
The generated `foo.js` we see imports from the `./greet` module with the `greet`
|
||||
name (was the function import in Rust said) and then the `__wbg_f_greet`
|
||||
function is shimming that import.
|
||||
|
||||
There's some tricky ABI business going on here so let's take a look at the
|
||||
generated Rust as well. Like before this is simplified from what's actually
|
||||
generated.
|
||||
|
||||
```rust
|
||||
extern "C" fn greet(a: &str) -> String {
|
||||
extern "C" {
|
||||
fn __wbg_f_greet(a_ptr: *const u8, a_len: usize, ret_len: *mut usize) -> *mut u8;
|
||||
}
|
||||
unsafe {
|
||||
let a_ptr = a.as_ptr();
|
||||
let a_len = a.len();
|
||||
let mut __ret_strlen = 0;
|
||||
let mut __ret_strlen_ptr = &mut __ret_strlen as *mut usize;
|
||||
let _ret = __wbg_f_greet(a_ptr, a_len, __ret_strlen_ptr);
|
||||
String::from_utf8_unchecked(
|
||||
Vec::from_raw_parts(_ret, __ret_strlen, __ret_strlen)
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here we can see that the `greet` function was generated but it's largely just a
|
||||
shim around the `__wbg_f_greet` function that we're calling. The ptr/len pair
|
||||
for the argument is passed as two arguments and for the return value we're
|
||||
receiving one value (the length) indirectly while directly receiving the
|
||||
returned pointer.
|
||||
67
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/index.md
vendored
Normal file
67
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/index.md
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
# Design of `wasm-bindgen`
|
||||
|
||||
This section is intended to be a deep-dive into how `wasm-bindgen` internally
|
||||
works today, specifically for Rust. If you're reading this far in the future it
|
||||
may no longer be up to date, but feel free to open an issue and we can try to
|
||||
answer questions and/or update this!
|
||||
|
||||
## Foundation: ES Modules
|
||||
|
||||
The first thing to know about `wasm-bindgen` is that it's fundamentally built on
|
||||
the idea of ES Modules. In other words this tool takes an opinionated stance
|
||||
that wasm files *should be viewed as ES modules*. This means that you can
|
||||
`import` from a wasm file, use its `export`-ed functionality, etc, from normal
|
||||
JS files.
|
||||
|
||||
Now unfortunately at the time of this writing the interface of wasm interop
|
||||
isn't very rich. Wasm modules can only call functions or export functions that
|
||||
deal exclusively with `i32`, `i64`, `f32`, and `f64`. Bummer!
|
||||
|
||||
That's where this project comes in. The goal of `wasm-bindgen` is to enhance the
|
||||
"ABI" of wasm modules with richer types like classes, JS objects, Rust structs,
|
||||
strings, etc. Keep in mind, though, that everything is based on ES Modules! This
|
||||
means that the compiler is actually producing a "broken" wasm file of sorts. The
|
||||
wasm file emitted by rustc, for example, does not have the interface we would
|
||||
like to have. Instead it requires the `wasm-bindgen` tool to postprocess the
|
||||
file, generating a `foo.js` and `foo_bg.wasm` file. The `foo.js` file is the
|
||||
desired interface expressed in JS (classes, types, strings, etc) and the
|
||||
`foo_bg.wasm` module is simply used as an implementation detail (it was
|
||||
lightly modified from the original `foo.wasm` file).
|
||||
|
||||
As more features are stabilized in WebAssembly over time (like host bindings)
|
||||
the JS file is expected to get smaller and smaller. It's unlikely to ever
|
||||
disappear, but `wasm-bindgen` is designed to follow the WebAssembly spec and
|
||||
proposals closely to optimize JS/Rust as much as possible.
|
||||
|
||||
## Foundation #2: Unintrusive in Rust
|
||||
|
||||
On the more Rust-y side of things the `wasm-bindgen` crate is designed to
|
||||
ideally have as minimal impact on a Rust crate as possible. Ideally a few
|
||||
`#[wasm_bindgen]` attributes are annotated in key locations and otherwise you're
|
||||
off to the races. The attribute strives to both not invent new syntax and work
|
||||
with existing idioms today.
|
||||
|
||||
For example a library might exposed a function in normal Rust that looks like:
|
||||
|
||||
```rust
|
||||
pub fn greet(name: &str) -> String {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
And with `#[wasm_bindgen]` all you need to do in exporting it to JS is:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
pub fn greet(name: &str) -> String {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Additionally the design here with minimal intervention in Rust should allow us
|
||||
to easily take advantage of the upcoming [host bindings][host] proposal. Ideally
|
||||
you'd simply upgrade `wasm-bindgen`-the-crate as well as your toolchain and
|
||||
you're immediately getting raw access to host bindings! (this is still a bit of
|
||||
a ways off though...)
|
||||
|
||||
[host]: https://github.com/WebAssembly/host-bindings
|
||||
237
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/js-objects-in-rust.md
vendored
Normal file
237
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/js-objects-in-rust.md
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
# Polyfill for "JS objects in wasm"
|
||||
|
||||
One of the main goals of `wasm-bindgen` is to allow working with and passing
|
||||
around JS objects in wasm, but that's not allowed today! While indeed true,
|
||||
that's where the polyfill comes in.
|
||||
|
||||
The question here is how we shoehorn JS objects into a `u32` for wasm to use.
|
||||
The current strategy for this approach is to maintain a module-local variable
|
||||
in the generated `foo.js` file: a `heap`.
|
||||
|
||||
### Temporary JS objects on the "stack"
|
||||
|
||||
The first slots in the `heap` in `foo.js` are considered a stack. This stack,
|
||||
like typical program execution stacks, grows down. JS objects are pushed on the
|
||||
bottom of the stack, and their index in the stack is the identifier that's passed
|
||||
to wasm. A stack pointer is maintained to figure out where the next item is
|
||||
pushed.
|
||||
|
||||
JS objects are then only removed from the bottom of the stack as well. Removal
|
||||
is simply storing null then incrementing a counter. Because of the "stack-y"
|
||||
nature of this scheme it only works for when wasm doesn't hold onto a JS object
|
||||
(aka it only gets a "reference" in Rust parlance).
|
||||
|
||||
Let's take a look at an example.
|
||||
|
||||
```rust
|
||||
// foo.rs
|
||||
#[wasm_bindgen]
|
||||
pub fn foo(a: &JsValue) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Here we're using the special `JsValue` type from the `wasm-bindgen` library
|
||||
itself. Our exported function, `foo`, takes a *reference* to an object. This
|
||||
notably means that it can't persist the object past the lifetime of this
|
||||
function call.
|
||||
|
||||
Now what we actually want to generate is a JS module that looks like (in
|
||||
TypeScript parlance)
|
||||
|
||||
```ts
|
||||
// foo.d.ts
|
||||
export function foo(a: any);
|
||||
```
|
||||
|
||||
and what we actually generate looks something like:
|
||||
|
||||
```js
|
||||
// foo.js
|
||||
import * as wasm from './foo_bg';
|
||||
|
||||
const heap = new Array(32);
|
||||
heap.push(undefined, null, true, false);
|
||||
let stack_pointer = 32;
|
||||
|
||||
function addBorrowedObject(obj) {
|
||||
stack_pointer -= 1;
|
||||
heap[stack_pointer] = obj;
|
||||
return stack_pointer;
|
||||
}
|
||||
|
||||
export function foo(arg0) {
|
||||
const idx0 = addBorrowedObject(arg0);
|
||||
try {
|
||||
wasm.foo(idx0);
|
||||
} finally {
|
||||
heap[stack_pointer++] = undefined;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here we can see a few notable points of action:
|
||||
|
||||
* The wasm file was renamed to `foo_bg.wasm`, and we can see how the JS module
|
||||
generated here is importing from the wasm file.
|
||||
* Next we can see our `heap` module variable which is to store all JS values
|
||||
reference-able from wasm.
|
||||
* Our exported function `foo`, takes an arbitrary argument, `arg0`, which is
|
||||
converted to an index with the `addBorrowedObject` object function. The index
|
||||
is then passed to wasm so wasm can operate with it.
|
||||
* Finally, we have a `finally` which frees the stack slot as it's no longer
|
||||
used, popping the value that was pushed at the start of the function.
|
||||
|
||||
It's also helpful to dig into the Rust side of things to see what's going on
|
||||
there! Let's take a look at the code that `#[wasm_bindgen]` generates in Rust:
|
||||
|
||||
```rust
|
||||
// what the user wrote
|
||||
pub fn foo(a: &JsValue) {
|
||||
// ...
|
||||
}
|
||||
|
||||
#[export_name = "foo"]
|
||||
pub extern "C" fn __wasm_bindgen_generated_foo(arg0: u32) {
|
||||
let arg0 = unsafe {
|
||||
ManuallyDrop::new(JsValue::__from_idx(arg0))
|
||||
};
|
||||
let arg0 = &*arg0;
|
||||
foo(arg0);
|
||||
}
|
||||
```
|
||||
|
||||
And as with the JS, the notable points here are:
|
||||
|
||||
* The original function, `foo`, is unmodified in the output
|
||||
* A generated function here (with a unique name) is the one that's actually
|
||||
exported from the wasm module
|
||||
* Our generated function takes an integer argument (our index) and then wraps it
|
||||
in a `JsValue`. There's some trickery here that's not worth going into just
|
||||
yet, but we'll see in a bit what's happening under the hood.
|
||||
|
||||
### Long-lived JS objects
|
||||
|
||||
The above strategy is useful when JS objects are only temporarily used in Rust,
|
||||
for example only during one function call. Sometimes, though, objects may have a
|
||||
dynamic lifetime or otherwise need to be stored on Rust's heap. To cope with
|
||||
this there's a second half of management of JS objects, naturally corresponding
|
||||
to the other side of the JS `heap` array.
|
||||
|
||||
JS Objects passed to wasm that are not references are assumed to have a dynamic
|
||||
lifetime inside of the wasm module. As a result the strict push/pop of the stack
|
||||
won't work and we need more permanent storage for the JS objects. To cope with
|
||||
this we build our own "slab allocator" of sorts.
|
||||
|
||||
A picture (or code) is worth a thousand words so let's show what happens with an
|
||||
example.
|
||||
|
||||
```rust
|
||||
// foo.rs
|
||||
#[wasm_bindgen]
|
||||
pub fn foo(a: JsValue) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Note that the `&` is missing in front of the `JsValue` we had before, and in
|
||||
Rust parlance this means it's taking ownership of the JS value. The exported ES
|
||||
module interface is the same as before, but the ownership mechanics are slightly
|
||||
different. Let's see the generated JS's slab in action:
|
||||
|
||||
```js
|
||||
import * as wasm from './foo_bg'; // imports from wasm file
|
||||
|
||||
const heap = new Array(32);
|
||||
heap.push(undefined, null, true, false);
|
||||
let heap_next = 36;
|
||||
|
||||
function addHeapObject(obj) {
|
||||
if (heap_next === heap.length)
|
||||
heap.push(heap.length + 1);
|
||||
const idx = heap_next;
|
||||
heap_next = heap[idx];
|
||||
heap[idx] = obj;
|
||||
return idx;
|
||||
}
|
||||
|
||||
export function foo(arg0) {
|
||||
const idx0 = addHeapObject(arg0);
|
||||
wasm.foo(idx0);
|
||||
}
|
||||
|
||||
export function __wbindgen_object_drop_ref(idx) {
|
||||
heap[idx ] = heap_next;
|
||||
heap_next = idx;
|
||||
}
|
||||
```
|
||||
|
||||
Unlike before we're now calling `addHeapObject` on the argument to `foo` rather
|
||||
than `addBorrowedObject`. This function will use `heap` and `heap_next` as a
|
||||
slab allocator to acquire a slot to store the object, placing a structure there
|
||||
once it's found. Note that this is going on the right-half of the array, unlike
|
||||
the stack which resides on the left half. This discipline mirrors the stack/heap
|
||||
in normal programs, roughly.
|
||||
|
||||
Another curious aspect of this generated module is the
|
||||
`__wbindgen_object_drop_ref` function. This is one that's actually imported to
|
||||
wasm rather than used in this module! This function is used to signal the end of
|
||||
the lifetime of a `JsValue` in Rust, or in other words when it goes out of
|
||||
scope. Otherwise though this function is largely just a general "slab free"
|
||||
implementation.
|
||||
|
||||
And finally, let's take a look at the Rust generated again too:
|
||||
|
||||
```rust
|
||||
// what the user wrote
|
||||
pub fn foo(a: JsValue) {
|
||||
// ...
|
||||
}
|
||||
|
||||
#[export_name = "foo"]
|
||||
pub extern "C" fn __wasm_bindgen_generated_foo(arg0: u32) {
|
||||
let arg0 = unsafe {
|
||||
JsValue::__from_idx(arg0)
|
||||
};
|
||||
foo(arg0);
|
||||
}
|
||||
```
|
||||
|
||||
Ah that looks much more familiar! Not much interesting is happening here, so
|
||||
let's move on to...
|
||||
|
||||
### Anatomy of `JsValue`
|
||||
|
||||
Currently the `JsValue` struct is actually quite simple in Rust, it's:
|
||||
|
||||
```rust
|
||||
pub struct JsValue {
|
||||
idx: u32,
|
||||
}
|
||||
|
||||
// "private" constructors
|
||||
|
||||
impl Drop for JsValue {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
__wbindgen_object_drop_ref(self.idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Or in other words it's a newtype wrapper around a `u32`, the index that we're
|
||||
passed from wasm. The destructor here is where the `__wbindgen_object_drop_ref`
|
||||
function is called to relinquish our reference count of the JS object, freeing
|
||||
up our slot in the `slab` that we saw above.
|
||||
|
||||
If you'll recall as well, when we took `&JsValue` above we generated a wrapper
|
||||
of `ManuallyDrop` around the local binding, and that's because we wanted to
|
||||
avoid invoking this destructor when the object comes from the stack.
|
||||
|
||||
### Working with `heap` in reality
|
||||
|
||||
The above explanations are pretty close to what happens today, but in reality
|
||||
there's a few differences especially around handling constant values like
|
||||
`undefined`, `null`, etc. Be sure to check out the actual generated JS and the
|
||||
generation code for the full details!
|
||||
117
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/rust-type-conversions.md
vendored
Normal file
117
zeroidc/vendor/wasm-bindgen/guide/src/contributing/design/rust-type-conversions.md
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
# Rust Type conversions
|
||||
|
||||
Previously we've been seeing mostly abridged versions of type conversions when
|
||||
values enter Rust. Here we'll go into some more depth about how this is
|
||||
implemented. There are two categories of traits for converting values, traits
|
||||
for converting values from Rust to JS and traits for the other way around.
|
||||
|
||||
## From Rust to JS
|
||||
|
||||
First up let's take a look at going from Rust to JS:
|
||||
|
||||
```rust
|
||||
pub trait IntoWasmAbi: WasmDescribe {
|
||||
type Abi: WasmAbi;
|
||||
fn into_abi(self, extra: &mut Stack) -> Self::Abi;
|
||||
}
|
||||
```
|
||||
|
||||
And that's it! This is actually the only trait needed currently for translating
|
||||
a Rust value to a JS one. There's a few points here:
|
||||
|
||||
* We'll get to `WasmDescribe` later in this section
|
||||
* The associated type `Abi` is what will actually be generated as an argument to
|
||||
the wasm export. The bound `WasmAbi` is only implemented for types like `u32`
|
||||
and `f64`, those which can be placed on the boundary and transmitted
|
||||
losslessly.
|
||||
* And finally we have the `into_abi` function, returning the `Abi` associated
|
||||
type which will be actually passed to JS. There's also this `Stack` parameter,
|
||||
however. Not all Rust values can be communicated in 32 bits to the `Stack`
|
||||
parameter allows transmitting more data, explained in a moment.
|
||||
|
||||
This trait is implemented for all types that can be converted to JS and is
|
||||
unconditionally used during codegen. For example you'll often see `IntoWasmAbi
|
||||
for Foo` but also `IntoWasmAbi for &'a Foo`.
|
||||
|
||||
The `IntoWasmAbi` trait is used in two locations. First it's used to convert
|
||||
return values of Rust exported functions to JS. Second it's used to convert the
|
||||
Rust arguments of JS functions imported to Rust.
|
||||
|
||||
## From JS to Rust
|
||||
|
||||
Unfortunately the opposite direction from above, going from JS to Rust, is a bit
|
||||
more complicated. Here we've got three traits:
|
||||
|
||||
```rust
|
||||
pub trait FromWasmAbi: WasmDescribe {
|
||||
type Abi: WasmAbi;
|
||||
unsafe fn from_abi(js: Self::Abi, extra: &mut Stack) -> Self;
|
||||
}
|
||||
|
||||
pub trait RefFromWasmAbi: WasmDescribe {
|
||||
type Abi: WasmAbi;
|
||||
type Anchor: Deref<Target=Self>;
|
||||
unsafe fn ref_from_abi(js: Self::Abi, extra: &mut Stack) -> Self::Anchor;
|
||||
}
|
||||
|
||||
pub trait RefMutFromWasmAbi: WasmDescribe {
|
||||
type Abi: WasmAbi;
|
||||
type Anchor: DerefMut<Target=Self>;
|
||||
unsafe fn ref_mut_from_abi(js: Self::Abi, extra: &mut Stack) -> Self::Anchor;
|
||||
}
|
||||
```
|
||||
|
||||
The `FromWasmAbi` is relatively straightforward, basically the opposite of
|
||||
`IntoWasmAbi`. It takes the ABI argument (typically the same as
|
||||
`IntoWasmAbi::Abi`) and then the auxiliary stack to produce an instance of
|
||||
`Self`. This trait is implemented primarily for types that *don't* have internal
|
||||
lifetimes or are references.
|
||||
|
||||
The latter two traits here are mostly the same, and are intended for generating
|
||||
references (both shared and mutable references). They look almost the same as
|
||||
`FromWasmAbi` except that they return an `Anchor` type which implements a
|
||||
`Deref` trait rather than `Self`.
|
||||
|
||||
The `Ref*` traits allow having arguments in functions that are references rather
|
||||
than bare types, for example `&str`, `&JsValue`, or `&[u8]`. The `Anchor` here
|
||||
is required to ensure that the lifetimes don't persist beyond one function call
|
||||
and remain anonymous.
|
||||
|
||||
The `From*` family of traits are used for converting the Rust arguments in Rust
|
||||
exported functions to JS. They are also used for the return value in JS
|
||||
functions imported into Rust.
|
||||
|
||||
## Global stack
|
||||
|
||||
Mentioned above not all Rust types will fit within 32 bits. While we can
|
||||
communicate an `f64` we don't necessarily have the ability to use all the bits.
|
||||
Types like `&str` need to communicate two items, a pointer and a length (64
|
||||
bits). Other types like `&Closure<dyn Fn()>` have even more information to
|
||||
transmit.
|
||||
|
||||
As a result we need a method of communicating more data through the signatures
|
||||
of functions. While we could add more arguments this is somewhat difficult to do
|
||||
in the world of closures where code generation isn't quite as dynamic as a
|
||||
procedural macro. Consequently a "global stack" is used to transmit extra
|
||||
data for a function call.
|
||||
|
||||
The global stack is a fixed-sized static allocation in the wasm module. This
|
||||
stack is temporary scratch space for any one function call from either JS to
|
||||
Rust or Rust to JS. Both Rust and the JS shim generated have pointers to this
|
||||
global stack and will read/write information from it.
|
||||
|
||||
Using this scheme whenever we want to pass `&str` from JS to Rust we can pass
|
||||
the pointer as the actual ABI argument and the length is then placed in the next
|
||||
spot on the global stack.
|
||||
|
||||
The `Stack` argument to the conversion traits above looks like:
|
||||
|
||||
```rust
|
||||
pub trait Stack {
|
||||
fn push(&mut self, bits: u32);
|
||||
fn pop(&mut self) -> u32;
|
||||
}
|
||||
```
|
||||
|
||||
A trait is used here to facilitate testing but typically the calls don't end up
|
||||
being virtually dispatched at runtime.
|
||||
26
zeroidc/vendor/wasm-bindgen/guide/src/contributing/index.md
vendored
Normal file
26
zeroidc/vendor/wasm-bindgen/guide/src/contributing/index.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# Contributing to `wasm-bindgen`
|
||||
|
||||
This section contains instructions on how to get this project up and running for
|
||||
development. You may want to browse the [unpublished guide documentation] for
|
||||
`wasm-bindgen` as well as it may have more up-to-date information.
|
||||
|
||||
[unpublished documentation]: https://rustwasm.github.io/wasm-bindgen/
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. Rust. [Install Rust]. Once Rust is installed, run
|
||||
|
||||
```shell
|
||||
rustup target add wasm32-unknown-unknown
|
||||
```
|
||||
|
||||
[install Rust]: https://www.rust-lang.org/en-US/install.html
|
||||
|
||||
2. The tests for this project use Node. Make sure you have node >= 10 installed,
|
||||
as that is when WebAssembly support was introduced. [Install Node].
|
||||
|
||||
[Install Node]: https://nodejs.org/en/
|
||||
|
||||
## Code Formatting
|
||||
|
||||
Although formatting rules are not mandatory, it is encouraged to run `cargo run` (`rustfmt`) with its default rules within a PR to maintain a more organized code base. If necessary, a PR with a single commit that formats the entire project is also welcome.
|
||||
35
zeroidc/vendor/wasm-bindgen/guide/src/contributing/js-sys/adding-more-apis.md
vendored
Normal file
35
zeroidc/vendor/wasm-bindgen/guide/src/contributing/js-sys/adding-more-apis.md
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
# Adding Support for More JavaScript Global APIs
|
||||
|
||||
As of 2018-09-24 we've [added all APIs][issue] in the current ECMAScript
|
||||
standard (yay!). To that end you'll hopefully not find a missing API, but if you
|
||||
do please feel free to file an issue!
|
||||
|
||||
We currently add new APIs added to ECMAScript that are in [TC39 stage 4][tc39]
|
||||
to this crate. If there's a new API in stage 4, feel free to file an issue as
|
||||
well!
|
||||
|
||||
### Instructions for adding an API
|
||||
|
||||
* [ ] Find the `wasm-bindgen` issue for the API you'd like to add. If this
|
||||
doesn't exist, feel free to open one! Afterwards be sure to comment on the
|
||||
issue to avoid duplication of work.
|
||||
|
||||
* [ ] Open the [MDN
|
||||
page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects)
|
||||
for the relevant JS API.
|
||||
|
||||
* [ ] Open `crates/js-sys/src/lib.rs` in your editor; this is the file where we
|
||||
are implementing the bindings.
|
||||
|
||||
* [ ] Follow the instructions in the top of `crates/js-sys/src/lib.rs` about how
|
||||
to add new bindings.
|
||||
|
||||
* [ ] Add a test for the new binding to `crates/js-sys/tests/wasm/MyType.rs`
|
||||
|
||||
* [ ] Run the [JS global API bindings tests][test]
|
||||
|
||||
* [ ] Send a pull request!
|
||||
|
||||
[issue]: https://github.com/rustwasm/wasm-bindgen/issues/275
|
||||
[tc39]: https://tc39.github.io/process-document/
|
||||
[test]: testing.html
|
||||
45
zeroidc/vendor/wasm-bindgen/guide/src/contributing/js-sys/index.md
vendored
Normal file
45
zeroidc/vendor/wasm-bindgen/guide/src/contributing/js-sys/index.md
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# `js-sys`
|
||||
|
||||
The [`js-sys` crate][js-sys] provides raw bindings to all the global APIs
|
||||
guaranteed to exist in every JavaScript environment by the ECMAScript standard,
|
||||
and its source lives at [`wasm-bindgen/crates/js-sys`][src]. With the `js-sys`
|
||||
crate, we can work with `Object`s, `Array`s, `Function`s, `Map`s, `Set`s,
|
||||
etc... without writing the `#[wasm_bindgen]` imports by hand.
|
||||
|
||||
Documentation for the published version of this crate is available on
|
||||
[docs.rs][docsrs] but you can also check out the [master branch
|
||||
documentation][masterdoc] for the crate.
|
||||
|
||||
[docsrs]: https://docs.rs/js-sys
|
||||
[masterdoc]: https://rustwasm.github.io/wasm-bindgen/api/js_sys/
|
||||
[src]: https://github.com/rustwasm/wasm-bindgen/tree/master/crates/js-sys
|
||||
|
||||
For example, we can invoke JavaScript [`Function`][mdn-function] callbacks and
|
||||
time how long they take to execute with [`Date.now()`][mdn-date-now], and we
|
||||
don't need to write any JS imports ourselves:
|
||||
|
||||
```rust
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn timed(callback: &js_sys::Function) -> f64 {
|
||||
let then = js_sys::Date::now();
|
||||
callback.apply(JsValue::null(), &js_sys::Array::new()).unwrap();
|
||||
let now = js_sys::Date::now();
|
||||
now - then
|
||||
}
|
||||
```
|
||||
|
||||
The `js-sys` crate doesn't contain bindings to any Web APIs like
|
||||
[`document.querySelectorAll`][mdn-qsa]. These will be part of the
|
||||
[`web-sys`][web-sys] crate.
|
||||
|
||||
[MDN]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
|
||||
[js-sys]: https://crates.io/crates/js-sys
|
||||
[issue]: https://github.com/rustwasm/wasm-bindgen/issues/275
|
||||
[mdn-function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function
|
||||
[mdn-qsa]: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
|
||||
[web-sys]: https://crates.io/crates/web-sys
|
||||
[web-sys-contributing]: https://rustwasm.github.io/wasm-bindgen/web-sys.html
|
||||
[web-sys-issues]: https://github.com/rustwasm/wasm-bindgen/issues?q=is%3Aissue+is%3Aopen+label%3Aweb-sys
|
||||
[mdn-date-now]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now
|
||||
13
zeroidc/vendor/wasm-bindgen/guide/src/contributing/js-sys/testing.md
vendored
Normal file
13
zeroidc/vendor/wasm-bindgen/guide/src/contributing/js-sys/testing.md
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Testing
|
||||
|
||||
You can test the `js-sys` crate by running `cargo test --target
|
||||
wasm32-unknown-unknown` within the `crates/js-sys` directory in the
|
||||
`wasm-bindgen` repository:
|
||||
|
||||
```sh
|
||||
cd wasm-bindgen/crates/js-sys
|
||||
cargo test --target wasm32-unknown-unknown
|
||||
```
|
||||
|
||||
These tests are largely executed in Node.js right now via the
|
||||
[`wasm-bindgen-test` framework](../../wasm-bindgen-test/index.html)
|
||||
24
zeroidc/vendor/wasm-bindgen/guide/src/contributing/publishing.md
vendored
Normal file
24
zeroidc/vendor/wasm-bindgen/guide/src/contributing/publishing.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# Publishing New `wasm-bindgen` Releases
|
||||
|
||||
1. <input type="checkbox"/> Compile the `publish.rs` script:
|
||||
|
||||
```
|
||||
rustc publish.rs
|
||||
```
|
||||
|
||||
2. <input type="checkbox"/> Bump every crate's minor version:
|
||||
|
||||
```
|
||||
# Make sure you are in the root of the wasm-bindgen repo!
|
||||
./publish bump
|
||||
```
|
||||
|
||||
3. <input type="checkbox"/> Send a pull request for the version bump.
|
||||
|
||||
4. <input type="checkbox"/> After the pull request's CI is green and it has been
|
||||
merged, publish to cargo:
|
||||
|
||||
```
|
||||
# Make sure you are in the root of the wasm-bindgen repo!
|
||||
./publish publish
|
||||
```
|
||||
36
zeroidc/vendor/wasm-bindgen/guide/src/contributing/team.md
vendored
Normal file
36
zeroidc/vendor/wasm-bindgen/guide/src/contributing/team.md
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
# Team
|
||||
|
||||
`wasm-bindgen` follows the [`rustwasm` organization's governance described
|
||||
here][governance]:
|
||||
|
||||
* All pull requests (including those made by a team member) must be approved by
|
||||
at least one other team member.
|
||||
|
||||
* Larger, more nuanced decisions about design, architecture, breaking changes,
|
||||
trade offs, etc are made by team consensus.
|
||||
|
||||
[governance]: https://github.com/rustwasm/team/blob/master/GOVERNANCE.md#repositories
|
||||
|
||||
## Members
|
||||
|
||||
<style>
|
||||
img {
|
||||
max-width: 117px;
|
||||
max-height: 117px;
|
||||
}
|
||||
</style>
|
||||
|
||||
| [][alexcrichton] | [][fitzgen] | [][spastorino] | [][ohanar] | [][jonathan-s] |
|
||||
|:---:|:---:|:---:|:---:|
|
||||
| [`alexcrichton`][alexcrichton] | [`fitzgen`][fitzgen] | [`spastorino`][spastorino] | [`ohanar`][ohanar] | [`jonathan-s`][jonathan-s] |
|
||||
| [][sendilkumarn] | [][belfz] | [][afdw] | | |
|
||||
| [`sendilkumarn`][sendilkumarn] | [`belfz`][belfz] | [`afdw`][afdw] | | |
|
||||
|
||||
[alexcrichton]: https://github.com/alexcrichton
|
||||
[fitzgen]: https://github.com/fitzgen
|
||||
[spastorino]: https://github.com/spastorino
|
||||
[ohanar]: https://github.com/ohanar
|
||||
[jonathan-s]: https://github.com/jonathan-s
|
||||
[sendilkumarn]: https://github.com/sendilkumarn
|
||||
[belfz]: https://github.com/belfz
|
||||
[afdw]: https://github.com/afdw
|
||||
47
zeroidc/vendor/wasm-bindgen/guide/src/contributing/testing.md
vendored
Normal file
47
zeroidc/vendor/wasm-bindgen/guide/src/contributing/testing.md
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
# Running `wasm-bindgen`'s Tests
|
||||
|
||||
## Wasm Tests on Node and Headless Browsers
|
||||
|
||||
These are the largest test suites, and most common to run in day to day
|
||||
`wasm-bindgen` development. These tests are compiled to Wasm and then run in
|
||||
Node.js or a headless browser via the WebDriver protocol.
|
||||
|
||||
```bash
|
||||
cargo test --target wasm32-unknown-unknown
|
||||
```
|
||||
|
||||
See [the `wasm-bindgen-test` crate's
|
||||
`README.md`](https://github.com/rustwasm/wasm-bindgen/blob/master/crates/test/README.md)
|
||||
for details and configuring which headless browser is used.
|
||||
|
||||
## Sanity Tests for `wasm-bindgen` on the Native Host Target
|
||||
|
||||
This small test suite just verifies that exported `wasm-bindgen` methods can
|
||||
still be used on the native host's target.
|
||||
|
||||
```
|
||||
cargo test
|
||||
```
|
||||
|
||||
## The Web IDL Frontend's Tests
|
||||
|
||||
```
|
||||
cargo test -p webidl-tests --target wasm32-unknown-unknown
|
||||
```
|
||||
|
||||
## The Macro UI Tests
|
||||
|
||||
These tests assert that we have reasonable error messages that point to the
|
||||
right source spans when the `#[wasm_bindgen]` proc-macro is misused.
|
||||
|
||||
```
|
||||
cargo test -p ui-tests
|
||||
```
|
||||
|
||||
## The `js-sys` Tests
|
||||
|
||||
See [the `js-sys` testing page](js-sys/testing.html).
|
||||
|
||||
## The `web-sys` Tests
|
||||
|
||||
See [the `web-sys` testing page](web-sys/testing.html).
|
||||
17
zeroidc/vendor/wasm-bindgen/guide/src/contributing/web-sys/index.md
vendored
Normal file
17
zeroidc/vendor/wasm-bindgen/guide/src/contributing/web-sys/index.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# `web-sys`
|
||||
|
||||
The `web-sys` crate provides raw bindings to all of the Web's APIs, and its
|
||||
source lives at `wasm-bindgen/crates/web-sys`.
|
||||
|
||||
The `web-sys` crate is **entirely** mechanically generated inside `build.rs`
|
||||
using `wasm-bindgen`'s WebIDL frontend and the WebIDL interface definitions for
|
||||
Web APIs. This means that `web-sys` isn't always the most ergonomic crate to
|
||||
use, but it's intended to provide verified and correct bindings to the web
|
||||
platform, and then better interfaces can be iterated on crates.io!
|
||||
|
||||
Documentation for the published version of this crate is available on
|
||||
[docs.rs][docsrs] but you can also check out the [master branch
|
||||
documentation][masterdoc] for the crate.
|
||||
|
||||
[docsrs]: https://docs.rs/web-sys
|
||||
[masterdoc]: https://rustwasm.github.io/wasm-bindgen/api/web_sys/
|
||||
23
zeroidc/vendor/wasm-bindgen/guide/src/contributing/web-sys/logging.md
vendored
Normal file
23
zeroidc/vendor/wasm-bindgen/guide/src/contributing/web-sys/logging.md
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
# Logging
|
||||
|
||||
The `wasm_bindgen_webidl` crate (used by `web-sys`'s `build.rs`) uses
|
||||
[`env_logger`][env_logger] for logging, which can be enabled by setting the
|
||||
`RUST_LOG=wasm_bindgen_webidl` environment variable while building the `web-sys`
|
||||
crate.
|
||||
|
||||
Make sure to enable "very verbose" output during `cargo build` to see these logs
|
||||
within `web-sys`'s build script output.
|
||||
|
||||
```sh
|
||||
cd crates/web-sys
|
||||
RUST_LOG=wasm_bindgen_webidl cargo build -vv
|
||||
```
|
||||
|
||||
If `wasm_bindgen_webidl` encounters WebIDL constructs that it doesn't know how
|
||||
to translate into `wasm-bindgen` AST items, it will emit warn-level logs.
|
||||
|
||||
```
|
||||
WARN 2018-07-06T18:21:49Z: wasm_bindgen_webidl: Unsupported WebIDL interface: ...
|
||||
```
|
||||
|
||||
[env_logger]: https://crates.io/crates/env_logger
|
||||
44
zeroidc/vendor/wasm-bindgen/guide/src/contributing/web-sys/overview.md
vendored
Normal file
44
zeroidc/vendor/wasm-bindgen/guide/src/contributing/web-sys/overview.md
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
# `web-sys` Overview
|
||||
|
||||
The `web-sys` crate has this file and directory layout:
|
||||
|
||||
```text
|
||||
.
|
||||
├── build.rs
|
||||
├── Cargo.toml
|
||||
├── README.md
|
||||
├── src
|
||||
│ └── lib.rs
|
||||
└── webidls
|
||||
└── enabled
|
||||
└── ...
|
||||
```
|
||||
|
||||
### `webidls/enabled/*.webidl`
|
||||
|
||||
These are the WebIDL interfaces that we will actually generate bindings for (or
|
||||
at least bindings for *some* of the things defined in these files).
|
||||
|
||||
### `build.rs`
|
||||
|
||||
The `build.rs` invokes `wasm-bindgen`'s WebIDL frontend on all the WebIDL files
|
||||
in `webidls/enabled`. It writes the resulting bindings into the cargo build's
|
||||
out directory.
|
||||
|
||||
### `src/lib.rs`
|
||||
|
||||
The only thing `src/lib.rs` does is include the bindings generated at compile
|
||||
time in `build.rs`. Here is the whole `src/lib.rs` file:
|
||||
|
||||
```rust
|
||||
{{#include ../../../../crates/web-sys/src/lib.rs}}
|
||||
```
|
||||
|
||||
### Cargo features
|
||||
|
||||
When compiled the crate is almost empty by default, which probably isn't what
|
||||
you want! Due to the very large number of APIs, this crate uses features to
|
||||
enable portions of its API to reduce compile times. The list of features in
|
||||
`Cargo.toml` all correspond to types in the generated functions. Enabling a
|
||||
feature enables that type. All methods should indicate what features need to be
|
||||
activated to use the method.
|
||||
39
zeroidc/vendor/wasm-bindgen/guide/src/contributing/web-sys/supporting-more-web-apis.md
vendored
Normal file
39
zeroidc/vendor/wasm-bindgen/guide/src/contributing/web-sys/supporting-more-web-apis.md
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
# Supporting More Web APIs in `web-sys`
|
||||
|
||||
1. Ensure that the `.webidl` file describing the
|
||||
interface exists somewhere within the `crates/web-sys/webidls/enabled`
|
||||
directory.
|
||||
|
||||
First, check to see whether we have the WebIDL definition file for
|
||||
your API:
|
||||
|
||||
```sh
|
||||
grep -rn MyWebApi crates/web-sys/webidls
|
||||
```
|
||||
|
||||
* If your interface is defined in a `.webidl` file that is inside the
|
||||
`crates/web-sys/webidls/enabled` directory, skip to step (3).
|
||||
|
||||
* If your interface isn't defined in any file yet, find the WebIDL definition
|
||||
in the relevant standard and add it as a new `.webidl` file in
|
||||
`crates/web-sys/webidls/enabled`. Make sure that it is a standard Web API!
|
||||
We don't want to add non-standard APIs to this crate.
|
||||
|
||||
* If your interface is defined in a `.webidl` file within any of the
|
||||
`crates/web-sys/webidls/unavailable_*` directories, you need to move it into
|
||||
`crates/web-sys/webidls/enabled`, e.g.:
|
||||
|
||||
```sh
|
||||
cd crates/web-sys
|
||||
git mv webidls/unavailable_enum_ident/MyWebApi.webidl webidls/enabled/MyWebApi.webidl
|
||||
```
|
||||
|
||||
2. Regenerate the `web-sys` crate auto-generated bindings, which you can do with
|
||||
the following commands:
|
||||
|
||||
```sh
|
||||
cd crates/web-sys
|
||||
cargo run --release --package wasm-bindgen-webidl -- webidls src/features
|
||||
```
|
||||
|
||||
You can then use `git diff` to ensure the bindings look correct.
|
||||
14
zeroidc/vendor/wasm-bindgen/guide/src/contributing/web-sys/testing.md
vendored
Normal file
14
zeroidc/vendor/wasm-bindgen/guide/src/contributing/web-sys/testing.md
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# Testing
|
||||
|
||||
You can test the `web-sys` crate by running `cargo test` within the
|
||||
`crates/web-sys` directory in the `wasm-bindgen` repository:
|
||||
|
||||
```sh
|
||||
cd wasm-bindgen/crates/web-sys
|
||||
cargo test --target wasm32-unknown-unknown --all-features
|
||||
```
|
||||
|
||||
The Wasm tests all run within a headless browser. See [the `wasm-bindgen-test`
|
||||
crate's
|
||||
`README.md`](https://github.com/rustwasm/wasm-bindgen/blob/master/crates/test/README.md)
|
||||
for details and configuring which headless browser is used.
|
||||
31
zeroidc/vendor/wasm-bindgen/guide/src/examples/2d-canvas.md
vendored
Normal file
31
zeroidc/vendor/wasm-bindgen/guide/src/examples/2d-canvas.md
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# 2D Canvas
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/canvas/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/canvas
|
||||
|
||||
Drawing a smiley face with the 2D canvas API. This is a port of part of [this
|
||||
MDN
|
||||
tutorial](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes#Moving_the_pen)
|
||||
to `web-sys`.
|
||||
|
||||

|
||||
|
||||
## `Cargo.toml`
|
||||
|
||||
The `Cargo.toml` enables features necessary to query the DOM and work with 2D
|
||||
canvas.
|
||||
|
||||
```toml
|
||||
{{#include ../../../examples/canvas/Cargo.toml}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
Gets the `<canvas>` element, creates a 2D rendering context, and draws the
|
||||
smiley face.
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/canvas/src/lib.rs}}
|
||||
```
|
||||
BIN
zeroidc/vendor/wasm-bindgen/guide/src/examples/2d-canvas.png
vendored
Normal file
BIN
zeroidc/vendor/wasm-bindgen/guide/src/examples/2d-canvas.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.7 KiB |
66
zeroidc/vendor/wasm-bindgen/guide/src/examples/add.md
vendored
Normal file
66
zeroidc/vendor/wasm-bindgen/guide/src/examples/add.md
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
# Small wasm files
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/add/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/add
|
||||
|
||||
One of `wasm-bindgen`'s core goals is a pay-only-for-what-you-use philosophy, so
|
||||
if we don't use much then we shouldn't be paying much! As a result
|
||||
`#[wasm_bindgen]` can generate super-small executables
|
||||
|
||||
Currently this code...
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/add/src/lib.rs}}
|
||||
```
|
||||
|
||||
generates a 710 byte wasm binary:
|
||||
|
||||
```
|
||||
$ ls -l add_bg.wasm
|
||||
-rw-rw-r-- 1 alex alex 710 Sep 19 17:32 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 -l add.wasm
|
||||
-rw-rw-r-- 1 alex alex 172 Sep 19 17:33 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)
|
||||
(table (;0;) 1 1 anyfunc)
|
||||
(memory (;0;) 17)
|
||||
(global (;0;) i32 (i32.const 1049118))
|
||||
(global (;1;) i32 (i32.const 1049118))
|
||||
(export "memory" (memory 0))
|
||||
(export "__indirect_function_table" (table 0))
|
||||
(export "__heap_base" (global 0))
|
||||
(export "__data_end" (global 1))
|
||||
(export "add" (func 0))
|
||||
(data (i32.const 1049096) "invalid malloc request"))
|
||||
```
|
||||
|
||||
Also don't forget to compile in release mode for the smallest binaries! For
|
||||
larger applications you'll likely also want to turn on LTO to generate the
|
||||
smallest binaries:
|
||||
|
||||
```toml
|
||||
[profile.release]
|
||||
lto = true
|
||||
```
|
||||
|
||||
[wasm2wat]: https://github.com/webassembly/wabt
|
||||
[wasm-opt]: https://github.com/webassembly/binaryen
|
||||
31
zeroidc/vendor/wasm-bindgen/guide/src/examples/char.md
vendored
Normal file
31
zeroidc/vendor/wasm-bindgen/guide/src/examples/char.md
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# Working with the `char` type
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/char/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/char
|
||||
|
||||
The `#[wasm_bindgen]` macro will convert the rust `char` type to a single
|
||||
code-point js `string`, and this example shows how to work with this.
|
||||
|
||||
Opening this example should display a single counter with a random character
|
||||
for it's `key` and 0 for its `count`. You can click the `+` button to increase a
|
||||
counter's count. By clicking on the "add counter" button you should see a new
|
||||
counter added to the list with a different random character for it's `key`.
|
||||
|
||||
Under the hood javascript is choosing a random character from an Array of
|
||||
characters and passing that to the rust Counter struct's constructor so the
|
||||
character you are seeing on the page has made the full round trip from js to
|
||||
rust and back to js.
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/char/src/lib.rs}}
|
||||
```
|
||||
|
||||
## `index.js`
|
||||
|
||||
```js
|
||||
{{#include ../../../examples/char/index.js}}
|
||||
```
|
||||
16
zeroidc/vendor/wasm-bindgen/guide/src/examples/closures.md
vendored
Normal file
16
zeroidc/vendor/wasm-bindgen/guide/src/examples/closures.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# web-sys: Closures
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/closures/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/closures
|
||||
|
||||
One of the features of `#[wasm_bindgen]` is that you can pass closures defined
|
||||
in Rust off to JS. This can be a bit tricky at times, though, so the example
|
||||
here shows how to interact with some standard web APIs with closures.
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/closures/src/lib.rs}}
|
||||
```
|
||||
15
zeroidc/vendor/wasm-bindgen/guide/src/examples/console-log.md
vendored
Normal file
15
zeroidc/vendor/wasm-bindgen/guide/src/examples/console-log.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# `console.log`
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/console_log/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/console_log
|
||||
|
||||
This example shows off how to use `console.log` in a variety of ways, all the
|
||||
way from bare-bones usage to a `println!`-like macro with `web_sys`.
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/console_log/src/lib.rs}}
|
||||
```
|
||||
26
zeroidc/vendor/wasm-bindgen/guide/src/examples/dom.md
vendored
Normal file
26
zeroidc/vendor/wasm-bindgen/guide/src/examples/dom.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# web-sys: DOM hello world
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/dom/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/dom
|
||||
|
||||
Using `web-sys` we're able to interact with all the standard web platform
|
||||
methods, including those of the DOM! Here we take a look at a simple "Hello,
|
||||
world!" which manufactures a DOM element in Rust, customizes it, and then
|
||||
appends it to the page.
|
||||
|
||||
## `Cargo.toml`
|
||||
|
||||
You can see here how we depend on `web-sys` and activate associated features to
|
||||
enable all the various APIs:
|
||||
|
||||
```toml
|
||||
{{#include ../../../examples/dom/Cargo.toml}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/dom/src/lib.rs}}
|
||||
```
|
||||
25
zeroidc/vendor/wasm-bindgen/guide/src/examples/fetch.md
vendored
Normal file
25
zeroidc/vendor/wasm-bindgen/guide/src/examples/fetch.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# The `fetch` API
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/fetch/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/fetch
|
||||
|
||||
This example uses the `fetch` API to make an HTTP request to the GitHub API and
|
||||
then parses the resulting JSON.
|
||||
|
||||
## `Cargo.toml`
|
||||
|
||||
The `Cargo.toml` enables a number of features related to the `fetch` API and
|
||||
types used: `Headers`, `Request`, etc. It also enables `wasm-bindgen`'s `serde`
|
||||
support.
|
||||
|
||||
```toml
|
||||
{{#include ../../../examples/fetch/Cargo.toml}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/fetch/src/lib.rs}}
|
||||
```
|
||||
59
zeroidc/vendor/wasm-bindgen/guide/src/examples/hello-world.md
vendored
Normal file
59
zeroidc/vendor/wasm-bindgen/guide/src/examples/hello-world.md
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
# Hello, World!
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/hello_world/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/hello_world
|
||||
|
||||
This is the "Hello, world!" example of `#[wasm_bindgen]` showing how to set up
|
||||
a project, export a function to JS, call it from JS, and then call the `alert`
|
||||
function in Rust.
|
||||
|
||||
## `Cargo.toml`
|
||||
|
||||
The `Cargo.toml` lists the `wasm-bindgen` crate as a dependency.
|
||||
|
||||
Also of note is the `crate-type = ["cdylib"]` which is largely used for wasm
|
||||
final artifacts today.
|
||||
|
||||
```toml
|
||||
{{#include ../../../examples/hello_world/Cargo.toml}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
Here we define our Rust entry point along with calling the `alert` function.
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/hello_world/src/lib.rs}}
|
||||
```
|
||||
|
||||
## `index.js`
|
||||
|
||||
Our JS entry point is quite small!
|
||||
|
||||
```js
|
||||
{{#include ../../../examples/hello_world/index.js}}
|
||||
```
|
||||
|
||||
## Webpack-specific files
|
||||
|
||||
> **Note**: Webpack is not required for this example, and if you're interested
|
||||
> in options that don't use a JS bundler [see other examples][wab].
|
||||
|
||||
[wab]: without-a-bundler.html
|
||||
|
||||
And finally here's the Webpack configuration and `package.json` for this
|
||||
project:
|
||||
|
||||
**webpack.config.js**
|
||||
|
||||
```js
|
||||
{{#include ../../../examples/hello_world/webpack.config.js}}
|
||||
```
|
||||
|
||||
**package.json**
|
||||
|
||||
```json
|
||||
{{#include ../../../examples/hello_world/package.json}}
|
||||
```
|
||||
27
zeroidc/vendor/wasm-bindgen/guide/src/examples/import-js.md
vendored
Normal file
27
zeroidc/vendor/wasm-bindgen/guide/src/examples/import-js.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# Importing non-browser JS
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/import_js/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/import_js
|
||||
|
||||
The `#[wasm_bindgen]` attribute can be used on `extern "C" { .. }` blocks to import
|
||||
functionality from JS. This is how the `js-sys` and the `web-sys` crates are
|
||||
built, but you can also use it in your own crate!
|
||||
|
||||
For example if you're working with this JS file:
|
||||
|
||||
```js
|
||||
// defined-in-js.js
|
||||
{{#include ../../../examples/import_js/crate/defined-in-js.js}}
|
||||
```
|
||||
|
||||
you can use it in Rust with:
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/import_js/crate/src/lib.rs}}
|
||||
```
|
||||
|
||||
You can also [explore the full list of ways to configure imports][attr]
|
||||
|
||||
[attr]: ../reference/attributes/on-js-imports/index.html
|
||||
24
zeroidc/vendor/wasm-bindgen/guide/src/examples/index.md
vendored
Normal file
24
zeroidc/vendor/wasm-bindgen/guide/src/examples/index.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# Examples of using `wasm-bindgen`, `js-sys`, and `web-sys`
|
||||
|
||||
This subsection contains examples of using the `wasm-bindgen`, `js-sys`, and
|
||||
`web-sys` crates. Each example should have more information about what it's
|
||||
doing.
|
||||
|
||||
These examples all assume familiarity with `wasm-bindgen`, `wasm-pack`, and
|
||||
building a Rust and WebAssembly project. If you're unfamiliar with these check
|
||||
out the [Game of Life tutorial][gol] or [wasm pack tutorials][wpt] to help you
|
||||
get started.
|
||||
|
||||
The source code for all examples can also be [found online][code] to download
|
||||
and run locally. Most examples are configured with Webpack/`wasm-pack` and can
|
||||
be built with `npm run serve`. Other examples which don't use Webpack are
|
||||
accompanied with instructions or a `build.sh` showing how to build it.
|
||||
|
||||
Note that most examples currently use Webpack to assemble the final output
|
||||
artifact, but this is not required! You can review the [deployment
|
||||
documentation][deploy] for other options of how to deploy Rust and WebAssembly.
|
||||
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples
|
||||
[gol]: https://rustwasm.github.io/docs/book/
|
||||
[deploy]: ../reference/deployment.html
|
||||
[wpt]: https://rustwasm.github.io/docs/wasm-pack/tutorials/index.html
|
||||
25
zeroidc/vendor/wasm-bindgen/guide/src/examples/julia.md
vendored
Normal file
25
zeroidc/vendor/wasm-bindgen/guide/src/examples/julia.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# Julia Set
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/julia_set/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/julia_set
|
||||
|
||||
While not showing off a lot of `web_sys` API surface area, this example shows a
|
||||
neat fractal that you can make!
|
||||
|
||||
## `index.js`
|
||||
|
||||
A small bit of glue is added for this example
|
||||
|
||||
```js
|
||||
{{#include ../../../examples/julia_set/index.js}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
The bulk of the logic is in the generation of the fractal
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/julia_set/src/lib.rs}}
|
||||
```
|
||||
26
zeroidc/vendor/wasm-bindgen/guide/src/examples/paint.md
vendored
Normal file
26
zeroidc/vendor/wasm-bindgen/guide/src/examples/paint.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# Paint Example
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/paint/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/paint
|
||||
|
||||
A simple painting program.
|
||||
|
||||
## `Cargo.toml`
|
||||
|
||||
The `Cargo.toml` enables features necessary to work with the DOM, events and
|
||||
2D canvas.
|
||||
|
||||
```toml
|
||||
{{#include ../../../examples/paint/Cargo.toml}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
Creates the `<canvas>` element, applies a CSS style to it, adds it to the document,
|
||||
get a 2D rendering context and adds listeners for mouse events.
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/paint/src/lib.rs}}
|
||||
```
|
||||
16
zeroidc/vendor/wasm-bindgen/guide/src/examples/performance.md
vendored
Normal file
16
zeroidc/vendor/wasm-bindgen/guide/src/examples/performance.md
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# web-sys: `performance.now`
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/performance/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/performance
|
||||
|
||||
Want to profile some Rust code in the browser? No problem! You can use the
|
||||
`performance.now()` API and friends to get timing information to see how long
|
||||
things take.
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/performance/src/lib.rs}}
|
||||
```
|
||||
127
zeroidc/vendor/wasm-bindgen/guide/src/examples/raytrace.md
vendored
Normal file
127
zeroidc/vendor/wasm-bindgen/guide/src/examples/raytrace.md
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
# Parallel Raytracing
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://wasm-bindgen.netlify.app/exbuild/raytrace-parallel/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/raytrace-parallel
|
||||
|
||||
This is an of using threads with WebAssembly, Rust, and `wasm-bindgen`,
|
||||
culminating in a parallel raytracer demo. There's a number of moving pieces to
|
||||
this demo and it's unfortunately not the easiest thing to wrangle, but it's
|
||||
hoped that this'll give you a bit of a taste of what it's like to use threads
|
||||
and wasm with Rust on the web.
|
||||
|
||||
### Building the demo
|
||||
|
||||
One of the major gotchas with threaded WebAssembly is that Rust does not ship a
|
||||
precompiled target (e.g. standard library) which has threading support enabled.
|
||||
This means that you'll need to recompile the standard library with the
|
||||
appropriate rustc flags, namely `-C target-feature=+atomics,+bulk-memory`.
|
||||
|
||||
To do this you can use the `RUSTFLAGS` environment variable that Cargo reads:
|
||||
|
||||
```sh
|
||||
export RUSTFLAGS='-C target-feature=+atomics,+bulk-memory'
|
||||
```
|
||||
|
||||
To recompile the standard library it's recommended to use Cargo's
|
||||
[`-Zbuild-std`](https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#build-std)
|
||||
feature:
|
||||
|
||||
```sh
|
||||
cargo build --target wasm32-unknown-unknown -Z build-std=panic_abort,std
|
||||
```
|
||||
|
||||
Note that you can also configure this via `.cargo/config.toml`:
|
||||
|
||||
```toml
|
||||
[unstable]
|
||||
build-std = ['std', 'panic_abort']
|
||||
|
||||
[build]
|
||||
target = "wasm32-unknown-unknown"
|
||||
rustflags = '-Ctarget-feature=+atomics,+bulk-memory'
|
||||
```
|
||||
|
||||
After this `cargo build` should produce a WebAssembly file with threading
|
||||
enabled, and the standard library will be appropriately compiled as well.
|
||||
|
||||
The final step in this is to run `wasm-bindgen` as usual, and `wasm-bindgen`
|
||||
needs no extra configuration to work with threads. You can continue to run it
|
||||
through `wasm-pack`, for example.
|
||||
|
||||
### Running the demo
|
||||
|
||||
Currently it's required to use the `--target no-modules` flag with
|
||||
`wasm-bindgen` to run threaded code. This is because the WebAssembly file
|
||||
imports memory instead of exporting it, so we need to hook initialization of the
|
||||
wasm module at this time to provide the appropriate memory object.
|
||||
|
||||
With `--target no-modules` you'll be able to use `importScripts` inside of each
|
||||
web worker to import the shim JS generated by `wasm-bindgen` as well as calling
|
||||
the `wasm_bindgen` initialization function with the shared memory instance from
|
||||
the main thread. The expected usage is that WebAssembly on the main thread will
|
||||
post its memory object to all other threads to get instantiated with.
|
||||
|
||||
### Caveats
|
||||
|
||||
Unfortunately at this time running wasm on the web with threads has a number of
|
||||
caveats, although some are specific to just `wasm-bindgen`. These are some
|
||||
pieces to consider and watch out for, although we're always looking for
|
||||
improvements to be made so if you have an idea please file an issue!
|
||||
|
||||
* The main thread in a browser cannot block. This means that if you run
|
||||
WebAssembly code on the main thread you can *never* block, meaning you can't
|
||||
do so much as acquire a mutex. This is an extremely difficult limitation to
|
||||
work with on the web, although one workaround is to run wasm exclusively in
|
||||
web workers and run JS on the main thread. It is possible to run the same wasm
|
||||
across all threads, but you need to be extremely vigilant about
|
||||
synchronization with the main thread.
|
||||
|
||||
* Setting up a threaded environment is a bit wonky and doesn't feel smooth
|
||||
today. For example `--target no-modules` is required with `wasm-bindgen` and
|
||||
very specific shims are required on both the main thread and worker threads.
|
||||
These are possible to work with but are somewhat brittle since there's no
|
||||
standard way to spin up web workers as wasm threads.
|
||||
|
||||
* There is no standard notion of a "thread". For example the standard library
|
||||
has no viable route to implement the `std::thread` module. As a consequence
|
||||
there is no concept of thread exit and TLS destructors will never run.
|
||||
We do expose a helper, `__wbindgen_thread_destroy`, that deallocates
|
||||
the thread stack and TLS. If you invoke it, it *must* be the last function
|
||||
you invoke from the wasm module for a given thread.
|
||||
|
||||
* Any thread launched after the first one _might attempt to block_ implicitly
|
||||
in its initialization routine. This is a constraint introduced by the way
|
||||
we set up the space for thread stacks and TLS. This means that if you attempt
|
||||
to run a wasm module in the main thread _after_ you are already running it
|
||||
in a worker, it might fail.
|
||||
|
||||
* Web Workers executing WebAssembly code cannot receive events from JS. A Web
|
||||
Worker has to fully return back to the browser (and ideally should do so
|
||||
occasionally) to receive JS messages and such. This means that common
|
||||
paradigms like a rayon thread pool do not apply straightforward-ly to the web.
|
||||
The intention of the web is that all long-term blocking happens in the browser
|
||||
itself, not in each thread, but many crates in the ecosystem leveraging
|
||||
threading are not necessarily engineered this way.
|
||||
|
||||
These caveats are all largely inherited from the web platform itself, and
|
||||
they're important to consider when designing an application for threading. It's
|
||||
highly unlikely that you can pull a crate off the shelf and "just use it" due to
|
||||
these limitations. You'll need to be sure to carefully plan ahead and ensure
|
||||
that gotchas such as these don't cause issues in the future. As mentioned before
|
||||
though we're always trying to actively develop this support so if folks have
|
||||
ideas about how to improve, or if web standards change, we'll try to update this
|
||||
documentation!
|
||||
|
||||
### Browser Requirements
|
||||
|
||||
This demo should work in the latest Firefox and Chrome versions at this time,
|
||||
and other browsers are likely to follow suit. Note that threads and
|
||||
`SharedArrayBuffer` require HTTP headers to be set to work correctly. For more
|
||||
information see the [documentation on
|
||||
MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer)
|
||||
under "Security requirements" as well as [Firefox's rollout blog
|
||||
post](https://hacks.mozilla.org/2020/07/safely-reviving-shared-memory/). This
|
||||
means that during local development you'll need to configure your web server
|
||||
appropriately or enable a workaround in your browser.
|
||||
26
zeroidc/vendor/wasm-bindgen/guide/src/examples/request-animation-frame.md
vendored
Normal file
26
zeroidc/vendor/wasm-bindgen/guide/src/examples/request-animation-frame.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# `web-sys`: A `requestAnimationFrame` Loop
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/request-animation-frame/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/request-animation-frame
|
||||
|
||||
This is an example of a `requestAnimationFrame` loop using the `web-sys` crate!
|
||||
It renders a count of how many times a `requestAnimationFrame` callback has been
|
||||
invoked and then it breaks out of the `requestAnimationFrame` loop after 300
|
||||
iterations.
|
||||
|
||||
## `Cargo.toml`
|
||||
|
||||
You can see here how we depend on `web-sys` and activate associated features to
|
||||
enable all the various APIs:
|
||||
|
||||
```toml
|
||||
{{#include ../../../examples/request-animation-frame/Cargo.toml}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/request-animation-frame/src/lib.rs}}
|
||||
```
|
||||
25
zeroidc/vendor/wasm-bindgen/guide/src/examples/todomvc.md
vendored
Normal file
25
zeroidc/vendor/wasm-bindgen/guide/src/examples/todomvc.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# TODO MVC using wasm-bingen and web-sys
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/todomvc/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/todomvc
|
||||
[element]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/todomvc/src/element.rs
|
||||
[scheduler]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/todomvc/src/scheduler.rs
|
||||
|
||||
[wasm-bindgen](https://github.com/rustwasm/wasm-bindgen) and [web-sys](https://rustwasm.github.io/wasm-bindgen/api/web_sys/) coded [TODO MVC](http://todomvc.com/)
|
||||
|
||||
The code was rewritten from the [ES6 version](http://todomvc.com/examples/vanilla-es6/).
|
||||
|
||||
The core differences are:
|
||||
- Having an [Element wrapper][element] that takes care of dyn and into refs in web-sys,
|
||||
- A [Scheduler][scheduler] that allows Controller and View to communicate to each other by emulating something similar to the JS event loop.
|
||||
|
||||
|
||||
## Size
|
||||
|
||||
The size of the project hasn't undergone much work to make it optimised yet.
|
||||
|
||||
- ~96kb release build
|
||||
- ~76kb optimised with binaryen
|
||||
- ~28kb brotli compressed
|
||||
15
zeroidc/vendor/wasm-bindgen/guide/src/examples/wasm-in-wasm.md
vendored
Normal file
15
zeroidc/vendor/wasm-bindgen/guide/src/examples/wasm-in-wasm.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# js-sys: WebAssembly in WebAssembly
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/wasm-in-wasm/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/wasm-in-wasm
|
||||
|
||||
Using the `js-sys` crate we can get pretty meta and instantiate `WebAssembly`
|
||||
modules from inside `WebAssembly` modules!
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/wasm-in-wasm/src/lib.rs}}
|
||||
```
|
||||
71
zeroidc/vendor/wasm-bindgen/guide/src/examples/wasm-in-web-worker.md
vendored
Normal file
71
zeroidc/vendor/wasm-bindgen/guide/src/examples/wasm-in-web-worker.md
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
# WASM in Web Worker
|
||||
|
||||
[View full source code][code]
|
||||
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/wasm-in-web-worker
|
||||
|
||||
A simple example of parallel execution by spawning a web worker with `web_sys`,
|
||||
loading WASM code in the web worker and interacting between the main thread and
|
||||
the worker.
|
||||
|
||||
## Building & compatibility
|
||||
|
||||
At the time of this writing, only Chrome supports modules in web workers, e.g.
|
||||
Firefox does not. To have compatibility across browsers, the whole example is
|
||||
set up without relying on ES modules as target. Therefore we have to build
|
||||
with `--target no-modules`. The full command can be found in `build.sh`.
|
||||
|
||||
## `Cargo.toml`
|
||||
|
||||
The `Cargo.toml` enables features necessary to work with the DOM, log output to
|
||||
the JS console, creating a worker and reacting to message events.
|
||||
|
||||
```toml
|
||||
{{#include ../../../examples/wasm-in-web-worker/Cargo.toml}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
Creates a struct `NumberEval` with methods to act as stateful object in the
|
||||
worker and function `startup` to be launched in the main thread. Also includes
|
||||
internal helper functions `setup_input_oninput_callback` to attach a
|
||||
`wasm_bindgen::Closure` as callback to the `oninput` event of the input field
|
||||
and `get_on_msg_callback` to create a `wasm_bindgen::Closure` which is triggered
|
||||
when the worker returns a message.
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/wasm-in-web-worker/src/lib.rs}}
|
||||
```
|
||||
|
||||
## `index.html`
|
||||
|
||||
Includes the input element `#inputNumber` to type a number into and a HTML
|
||||
element `#resultField` were the result of the evaluation even/odd is written to.
|
||||
Since we require to build with `--target no-modules` to be able to load WASM
|
||||
code in in the worker across browsers, the `index.html` also includes loading
|
||||
both `wasm_in_web_worker.js` and `index.js`.
|
||||
|
||||
```html
|
||||
{{#include ../../../examples/wasm-in-web-worker/www/index.html}}
|
||||
```
|
||||
|
||||
## `index.js`
|
||||
|
||||
Loads our WASM file asynchronously and calls the entry point `startup` of the
|
||||
main thread which will create a worker.
|
||||
|
||||
```js
|
||||
{{#include ../../../examples/wasm-in-web-worker/www/index.js}}
|
||||
```
|
||||
|
||||
## `worker.js`
|
||||
|
||||
Loads our WASM file by first importing `wasm_bindgen` via
|
||||
`importScripts('./pkg/wasm_in_web_worker.js')` and then awaiting the Promise
|
||||
returned by `wasm_bindgen(...)`. Creates a new object to do the background
|
||||
calculation and bind a method of the object to the `onmessage` callback of the
|
||||
worker.
|
||||
|
||||
```js
|
||||
{{#include ../../../examples/wasm-in-web-worker/www/worker.js}}
|
||||
```
|
||||
38
zeroidc/vendor/wasm-bindgen/guide/src/examples/wasm2js.md
vendored
Normal file
38
zeroidc/vendor/wasm-bindgen/guide/src/examples/wasm2js.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
# Converting WebAssembly to JS
|
||||
|
||||
[View full source code][code]
|
||||
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/wasm2js
|
||||
|
||||
Not all browsers have support for `WebAssembly` at this time (although all major
|
||||
ones do). If you'd like to support older browsers, you probably want a method
|
||||
that doesn't involve keeping two codebases in sync!
|
||||
|
||||
Thankfully there's a tool from [binaryen] called `wasm2js` to convert a wasm
|
||||
file to JS. This JS file, if successfully produced, is equivalent to the wasm
|
||||
file (albeit a little bit larger and slower), and can be loaded into practically
|
||||
any browser.
|
||||
|
||||
This example is relatively simple (cribbing from the [`console.log`
|
||||
example](console-log.md)):
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/wasm2js/src/lib.rs}}
|
||||
```
|
||||
|
||||
The real magic happens when you actually build the app. Just after
|
||||
`wasm-bindgen` we see here how we execute `wasm2js` in our build script:
|
||||
|
||||
```sh
|
||||
{{#include ../../../examples/wasm2js/build.sh}}
|
||||
```
|
||||
|
||||
Note that the `wasm2js` tool is still pretty early days so there's likely to be
|
||||
a number of bugs to run into or work around. If any are encountered though
|
||||
please feel free to report them upstream!
|
||||
|
||||
Also note that eventually this will ideally be automatically done by your
|
||||
bundler and no action would be needed from you to work in older browsers via
|
||||
`wasm2js`!
|
||||
|
||||
[binaryen]: https://github.com/WebAssembly/binaryen
|
||||
18
zeroidc/vendor/wasm-bindgen/guide/src/examples/weather_report.md
vendored
Normal file
18
zeroidc/vendor/wasm-bindgen/guide/src/examples/weather_report.md
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
# web-sys: Weather report
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/weather_report/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/weather_report
|
||||
|
||||
This example makes an HTTP request to [OpenWeather API](https://openweathermap.org/),
|
||||
parses response in JSON and render UI from that JSON. It also shows the usage of
|
||||
`spawn_local` function for handling asynchronous tasks.
|
||||
|
||||
Please add your api key in *get_response()* before running this application.
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/weather_report/src/lib.rs}}
|
||||
```
|
||||
38
zeroidc/vendor/wasm-bindgen/guide/src/examples/web-audio.md
vendored
Normal file
38
zeroidc/vendor/wasm-bindgen/guide/src/examples/web-audio.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
# WebAudio
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/webaudio/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/webaudio
|
||||
|
||||
This example creates an [FM
|
||||
oscillator](https://en.wikipedia.org/wiki/Frequency_modulation_synthesis) using
|
||||
the [WebAudio
|
||||
API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) and
|
||||
`web-sys`.
|
||||
|
||||
## `Cargo.toml`
|
||||
|
||||
The `Cargo.toml` enables the types needed to use the relevant bits of the
|
||||
WebAudio API.
|
||||
|
||||
```toml
|
||||
{{#include ../../../examples/webaudio/Cargo.toml}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
The Rust code implements the FM oscillator.
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/webaudio/src/lib.rs}}
|
||||
```
|
||||
|
||||
## `index.js`
|
||||
|
||||
A small bit of JavaScript glues the rust module to input widgets and translates
|
||||
events into calls into wasm code.
|
||||
|
||||
```js
|
||||
{{#include ../../../examples/webaudio/index.js}}
|
||||
```
|
||||
27
zeroidc/vendor/wasm-bindgen/guide/src/examples/webgl.md
vendored
Normal file
27
zeroidc/vendor/wasm-bindgen/guide/src/examples/webgl.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# WebGL Example
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/webgl/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/webgl
|
||||
|
||||
This example draws a triangle to the screen using the WebGL API.
|
||||
|
||||
## `Cargo.toml`
|
||||
|
||||
The `Cargo.toml` enables features necessary to obtain and use a WebGL
|
||||
rendering context.
|
||||
|
||||
```toml
|
||||
{{#include ../../../examples/webgl/Cargo.toml}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
This source file handles all of the necessary logic to obtain a rendering
|
||||
context, compile shaders, fill a buffer with vertex coordinates, and draw a
|
||||
triangle to the screen.
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/webgl/src/lib.rs}}
|
||||
```
|
||||
25
zeroidc/vendor/wasm-bindgen/guide/src/examples/webrtc_datachannel.md
vendored
Normal file
25
zeroidc/vendor/wasm-bindgen/guide/src/examples/webrtc_datachannel.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
# WebRTC DataChannel Example
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/webrtc_datachannel/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/webrtc_datachannel/
|
||||
|
||||
This example creates 2 peer connections and 2 data channels in single browser tab.
|
||||
Send ping/pong between `peer1.dc` and `peer2.dc`.
|
||||
|
||||
## `Cargo.toml`
|
||||
|
||||
The `Cargo.toml` enables features necessary to use WebRTC DataChannel and its negotiation.
|
||||
|
||||
```toml
|
||||
{{#include ../../../examples/webrtc_datachannel/Cargo.toml}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
The Rust code connects WebRTC data channel.
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/webrtc_datachannel/src/lib.rs}}
|
||||
```
|
||||
29
zeroidc/vendor/wasm-bindgen/guide/src/examples/websockets.md
vendored
Normal file
29
zeroidc/vendor/wasm-bindgen/guide/src/examples/websockets.md
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# WebSockets Example
|
||||
|
||||
[View full source code][code] or [view the compiled example online][online]
|
||||
|
||||
[online]: https://rustwasm.github.io/wasm-bindgen/exbuild/websockets/
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/websockets/
|
||||
|
||||
This example connects to an echo server on `wss://echo.websocket.org`,
|
||||
sends a `ping` message, and receives the response.
|
||||
|
||||
## `Cargo.toml`
|
||||
|
||||
The `Cargo.toml` enables features necessary to create a `WebSocket` object and
|
||||
to access events such as `MessageEvent` or `ErrorEvent`.
|
||||
|
||||
```toml
|
||||
{{#include ../../../examples/websockets/Cargo.toml}}
|
||||
```
|
||||
|
||||
## `src/lib.rs`
|
||||
|
||||
This code shows the basic steps required to work with a `WebSocket`.
|
||||
At first it opens the connection, then subscribes to events `onmessage`, `onerror`, `onopen`.
|
||||
After the socket is opened it sends a `ping` message, receives an echoed response
|
||||
and prints it to the browser console.
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/websockets/src/lib.rs}}
|
||||
```
|
||||
53
zeroidc/vendor/wasm-bindgen/guide/src/examples/without-a-bundler.md
vendored
Normal file
53
zeroidc/vendor/wasm-bindgen/guide/src/examples/without-a-bundler.md
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
# Without a Bundler
|
||||
|
||||
[View full source code][code]
|
||||
|
||||
[code]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/without-a-bundler
|
||||
|
||||
This example shows how the `--target web` flag can be used load code in a
|
||||
browser directly. For this deployment strategy bundlers like Webpack are not
|
||||
required. For more information on deployment see the [dedicated
|
||||
documentation][deployment].
|
||||
|
||||
First let's take a look at the code and see how when we're using `--target web`
|
||||
we're not actually losing any functionality!
|
||||
|
||||
```rust
|
||||
{{#include ../../../examples/without-a-bundler/src/lib.rs}}
|
||||
```
|
||||
|
||||
Otherwise the rest of the deployment magic happens in `index.html`:
|
||||
|
||||
```html
|
||||
{{#include ../../../examples/without-a-bundler/index.html}}
|
||||
```
|
||||
|
||||
And that's it! Be sure to read up on the [deployment options][deployment] to see
|
||||
what it means to deploy without a bundler.
|
||||
|
||||
[deployment]: ../reference/deployment.html
|
||||
|
||||
## Using the older `--target no-modules`
|
||||
|
||||
[View full source code][code-no-modules]
|
||||
|
||||
[code-no-modules]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/without-a-bundler-no-modules
|
||||
|
||||
The older version of using `wasm-bindgen` without a bundler is to use the
|
||||
`--target no-modules` flag to the `wasm-bindgen` CLI.
|
||||
|
||||
While similar to the newer `--target web`, the `--target no-modules` flag has a
|
||||
few caveats:
|
||||
|
||||
* It does not support [local JS snippets][snippets]
|
||||
* It does not generate an ES module
|
||||
|
||||
With that in mind the main difference is how the wasm/JS code is loaded, and
|
||||
here's an example of loading the output of `wasm-pack` for the same module as
|
||||
above.
|
||||
|
||||
```html
|
||||
{{#include ../../../examples/without-a-bundler-no-modules/index.html}}
|
||||
```
|
||||
|
||||
[snippets]: ../reference/js-snippets.html
|
||||
43
zeroidc/vendor/wasm-bindgen/guide/src/introduction.md
vendored
Normal file
43
zeroidc/vendor/wasm-bindgen/guide/src/introduction.md
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# Introduction
|
||||
|
||||
This book is about `wasm-bindgen`, a Rust library and CLI tool that facilitate
|
||||
high-level interactions between wasm modules and JavaScript. The `wasm-bindgen`
|
||||
tool and crate are only one part of the [Rust and WebAssembly
|
||||
ecosystem][rustwasm]. If you're not familiar already with `wasm-bindgen` it's
|
||||
recommended to start by reading the [Game of Life tutorial][gol]. If you're
|
||||
curious about `wasm-pack`, you can find that [documentation here][wasm-pack].
|
||||
|
||||
The `wasm-bindgen` tool is sort of half polyfill for features like the [host
|
||||
bindings proposal][host] and half features for empowering high-level
|
||||
interactions between JS and wasm-compiled code (currently mostly from Rust).
|
||||
More specifically this project allows JS/wasm to communicate with strings, JS
|
||||
objects, classes, etc, as opposed to purely integers and floats. Using
|
||||
`wasm-bindgen` for example you can define a JS class in Rust or take a string
|
||||
from JS or return one. The functionality is growing as well!
|
||||
|
||||
Currently this tool is Rust-focused but the underlying foundation is
|
||||
language-independent, and it's hoping that over time as this tool stabilizes
|
||||
that it can be used for languages like C/C++!
|
||||
|
||||
Notable features of this project includes:
|
||||
|
||||
* Importing JS functionality in to Rust such as [DOM manipulation][dom-ex],
|
||||
[console logging][console-log], or [performance monitoring][perf-ex].
|
||||
* Exporting Rust functionality to JS such as classes, functions, etc.
|
||||
* Working with rich types like strings, numbers, classes, closures, and objects
|
||||
rather than simply `u32` and floats.
|
||||
* Automatically generating TypeScript bindings for Rust code being consumed by
|
||||
JS.
|
||||
|
||||
With the addition of [`wasm-pack`][wasm-pack] you can run the gamut from running Rust on
|
||||
the web locally, publishing it as part of a larger application, or even
|
||||
publishing Rust-compiled-to-WebAssembly on NPM!
|
||||
|
||||
[host]: https://github.com/WebAssembly/host-bindings
|
||||
[dom-ex]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/dom
|
||||
[console-log]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/console_log
|
||||
[perf-ex]: https://github.com/rustwasm/wasm-bindgen/tree/master/examples/performance
|
||||
[hello-online]: https://webassembly.studio/?f=gzubao6tg3
|
||||
[rustwasm]: https://rustwasm.github.io/
|
||||
[gol]: https://rustwasm.github.io/docs/book/
|
||||
[wasm-pack]: https://rustwasm.github.io/docs/wasm-pack/
|
||||
82
zeroidc/vendor/wasm-bindgen/guide/src/reference/accessing-properties-of-untyped-js-values.md
vendored
Normal file
82
zeroidc/vendor/wasm-bindgen/guide/src/reference/accessing-properties-of-untyped-js-values.md
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
# Accessing Properties of Untyped JavaScript Values
|
||||
|
||||
To read and write arbitrary properties from any untyped JavaScript value
|
||||
regardless if it is an `instanceof` some JavaScript class or not, use [the
|
||||
`js_sys::Reflect` APIs][js-sys-reflect]. These APIs are bindings to the
|
||||
[JavaScript builtin `Reflect` object][mdn-reflect] and its methods.
|
||||
|
||||
You might also benefit from [using duck-typed
|
||||
interfaces](./working-with-duck-typed-interfaces.html) instead of working with
|
||||
untyped values.
|
||||
|
||||
## Reading Properties with `js_sys::Reflect::get`
|
||||
|
||||
[API documentation for `js_sys::Reflect::get`.](https://docs.rs/js-sys/0.3.39/js_sys/Reflect/fn.get.html)
|
||||
|
||||
A function that returns the value of a property.
|
||||
|
||||
#### Rust Usage
|
||||
|
||||
```rust
|
||||
let value = js_sys::Reflect::get(&target, &property_key)?;
|
||||
```
|
||||
|
||||
#### JavaScript Equivalent
|
||||
|
||||
```js
|
||||
let value = target[property_key];
|
||||
```
|
||||
|
||||
## Writing Properties with `js_sys::Reflect::set`
|
||||
|
||||
[API documentation for `js_sys::Reflect::set`.](https://docs.rs/js-sys/0.3.39/js_sys/Reflect/fn.set.html)
|
||||
|
||||
A function that assigns a value to a property. Returns a boolean that is true if
|
||||
the update was successful.
|
||||
|
||||
#### Rust Usage
|
||||
|
||||
```rust
|
||||
js_sys::Reflect::set(&target, &property_key, &value)?;
|
||||
```
|
||||
|
||||
#### JavaScript Equivalent
|
||||
|
||||
```js
|
||||
target[property_key] = value;
|
||||
```
|
||||
|
||||
## Determining if a Property Exists with `js_sys::Reflect::has`
|
||||
|
||||
[API documentation for `js_sys::Reflect::has`.](https://docs.rs/js-sys/0.3.39/js_sys/Reflect/fn.has.html)
|
||||
|
||||
The JavaScript `in` operator as function. Returns a boolean indicating whether
|
||||
an own or inherited property exists on the target.
|
||||
|
||||
#### Rust Usage
|
||||
|
||||
```rust
|
||||
if js_sys::Reflect::has(&target, &property_key)? {
|
||||
// ...
|
||||
} else {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
#### JavaScript Equivalent
|
||||
|
||||
```js
|
||||
if (property_key in target) {
|
||||
// ...
|
||||
} else {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## But wait — there's more!
|
||||
|
||||
See [the `js_sys::Reflect` API documentation][js-sys-reflect] for the full
|
||||
listing of JavaScript value reflection and introspection capabilities.
|
||||
|
||||
[js-sys-reflect]: https://docs.rs/js-sys/latest/js_sys/Reflect/index.html
|
||||
[mdn-reflect]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect
|
||||
116
zeroidc/vendor/wasm-bindgen/guide/src/reference/arbitrary-data-with-serde.md
vendored
Normal file
116
zeroidc/vendor/wasm-bindgen/guide/src/reference/arbitrary-data-with-serde.md
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
# Serializing and Deserializing Arbitrary Data Into and From `JsValue` with Serde
|
||||
|
||||
It's possible to pass arbitrary data from Rust to JavaScript by serializing it
|
||||
to JSON with [Serde](https://github.com/serde-rs/serde). `wasm-bindgen` includes
|
||||
the `JsValue` type, which streamlines serializing and deserializing.
|
||||
|
||||
## Enable the `"serde-serialize"` Feature
|
||||
|
||||
To enable the `"serde-serialize"` feature, do two things in `Cargo.toml`:
|
||||
|
||||
1. Add the `serde` and `serde_derive` crates to `[dependencies]`.
|
||||
2. Add `features = ["serde-serialize"]` to the existing `wasm-bindgen`
|
||||
dependency.
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
wasm-bindgen = { version = "0.2", features = ["serde-serialize"] }
|
||||
```
|
||||
|
||||
## Derive the `Serialize` and `Deserialize` Traits
|
||||
|
||||
Add `#[derive(Serialize, Deserialize)]` to your type. All of your type's
|
||||
members must also be supported by Serde, i.e. their types must also implement
|
||||
the `Serialize` and `Deserialize` traits.
|
||||
|
||||
For example, let's say we'd like to pass this `struct` to JavaScript; doing so
|
||||
is not possible in `wasm-bindgen` normally due to the use of `HashMap`s, arrays,
|
||||
and nested `Vec`s. None of those types are supported for sending across the wasm
|
||||
ABI naively, but all of them implement Serde's `Serialize` and `Deserialize`.
|
||||
|
||||
Note that we do not need to use the `#[wasm_bindgen]` macro.
|
||||
|
||||
```rust
|
||||
use serde::{Serialize, Deserialize};
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Example {
|
||||
pub field1: HashMap<u32, String>,
|
||||
pub field2: Vec<Vec<f32>>,
|
||||
pub field3: [f32; 4],
|
||||
}
|
||||
```
|
||||
|
||||
## Send it to JavaScript with `JsValue::from_serde`
|
||||
|
||||
Here's a function that will pass an `Example` to JavaScript by serializing it to
|
||||
`JsValue`:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
pub fn send_example_to_js() -> JsValue {
|
||||
let mut field1 = HashMap::new();
|
||||
field1.insert(0, String::from("ex"));
|
||||
let example = Example {
|
||||
field1,
|
||||
field2: vec![vec![1., 2.], vec![3., 4.]],
|
||||
field3: [1., 2., 3., 4.]
|
||||
};
|
||||
|
||||
JsValue::from_serde(&example).unwrap()
|
||||
}
|
||||
```
|
||||
|
||||
## Receive it from JavaScript with `JsValue::into_serde`
|
||||
|
||||
Here's a function that will receive a `JsValue` parameter from JavaScript and
|
||||
then deserialize an `Example` from it:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
pub fn receive_example_from_js(val: &JsValue) {
|
||||
let example: Example = val.into_serde().unwrap();
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## JavaScript Usage
|
||||
|
||||
In the `JsValue` that JavaScript gets, `field1` will be an `Object` (not a
|
||||
JavaScript `Map`), `field2` will be a JavaScript `Array` whose members are
|
||||
`Array`s of numbers, and `field3` will be an `Array` of numbers.
|
||||
|
||||
```js
|
||||
import { send_example_to_js, receive_example_from_js } from "example";
|
||||
|
||||
// Get the example object from wasm.
|
||||
let example = send_example_to_js();
|
||||
|
||||
// Add another "Vec" element to the end of the "Vec<Vec<f32>>"
|
||||
example.field2.push([5, 6]);
|
||||
|
||||
// Send the example object back to wasm.
|
||||
receive_example_from_js(example);
|
||||
```
|
||||
|
||||
## An Alternative Approach: `serde-wasm-bindgen`
|
||||
|
||||
[The `serde-wasm-bindgen`
|
||||
crate](https://github.com/cloudflare/serde-wasm-bindgen) serializes and
|
||||
deserializes Rust structures directly to `JsValue`s, without going through
|
||||
temporary JSON stringification. This approach has both advantages and
|
||||
disadvantages.
|
||||
|
||||
The primary advantage is smaller code size: going through JSON entrenches code
|
||||
to stringify and parse floating point numbers, which is not a small amount of
|
||||
code. It also supports more types than JSON does, such as `Map`, `Set`, and
|
||||
array buffers.
|
||||
|
||||
There are two primary disadvantages. The first is that it is not always
|
||||
compatible with the default JSON-based serialization. The second is that it
|
||||
performs more calls back and forth between JS and Wasm, which has not been fully
|
||||
optimized in all engines, meaning it can sometimes be a speed
|
||||
regression. However, in other cases, it is a speed up over the JSON-based
|
||||
stringification, so — as always — make sure to profile your own use
|
||||
cases as necessary.
|
||||
6
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/index.md
vendored
Normal file
6
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/index.md
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
# `#[wasm_bindgen]` Attributes
|
||||
|
||||
The `#[wasm_bindgen]` macro supports a good amount of configuration for
|
||||
controlling precisely how exports are exported, how imports are imported, and
|
||||
what the generated JavaScript glue ends up looking like. This section is an
|
||||
exhaustive reference of the possibilities!
|
||||
29
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/catch.md
vendored
Normal file
29
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/catch.md
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# `catch`
|
||||
|
||||
The `catch` attribute allows catching a JavaScript exception. This can be
|
||||
attached to any imported function or method, and the function must return a
|
||||
`Result` where the `Err` payload is a `JsValue`:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
// `catch` on a standalone function.
|
||||
#[wasm_bindgen(catch)]
|
||||
fn foo() -> Result<(), JsValue>;
|
||||
|
||||
// `catch` on a method.
|
||||
type Zoidberg;
|
||||
#[wasm_bindgen(catch, method)]
|
||||
fn woop_woop_woop(this: &Zoidberg) -> Result<u32, JsValue>;
|
||||
}
|
||||
```
|
||||
|
||||
If calling the imported function throws an exception, then `Err` will be
|
||||
returned with the exception that was raised. Otherwise, `Ok` is returned with
|
||||
the result of the function.
|
||||
|
||||
> By default `wasm-bindgen` will take no action when wasm calls a JS function
|
||||
> which ends up throwing an exception. The wasm spec right now doesn't support
|
||||
> stack unwinding and as a result Rust code **will not execute destructors**.
|
||||
> This can unfortunately cause memory leaks in Rust right now, but as soon as
|
||||
> wasm implements catching exceptions we'll be sure to add support as well!
|
||||
24
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/constructor.md
vendored
Normal file
24
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/constructor.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# `constructor`
|
||||
|
||||
The `constructor` attribute is used to indicate that the function being bound
|
||||
should actually translate to calling the `new` operator in JavaScript. The final
|
||||
argument must be a type that's imported from JavaScript, and it's what will get
|
||||
used in the generated glue:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
type Shoes;
|
||||
|
||||
#[wasm_bindgen(constructor)]
|
||||
fn new() -> Shoes;
|
||||
}
|
||||
```
|
||||
|
||||
This will attach a `new` static method to the `Shoes` type, and in JavaScript
|
||||
when this method is called, it will be equivalent to `new Shoes()`.
|
||||
|
||||
```rust
|
||||
// Become a cobbler; construct `new Shoes()`
|
||||
let shoes = Shoes::new();
|
||||
```
|
||||
49
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/extends.md
vendored
Normal file
49
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/extends.md
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
# `extends = Class`
|
||||
|
||||
The `extends` attribute can be used to say that an imported type extends (in the
|
||||
JS class hierarchy sense) another type. This will generate `AsRef`, `AsMut`, and
|
||||
`From` impls for converting a type into another given that we statically know
|
||||
the inheritance hierarchy:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
type Foo;
|
||||
|
||||
#[wasm_bindgen(extends = Foo)]
|
||||
type Bar;
|
||||
}
|
||||
|
||||
let x: &Bar = ...;
|
||||
let y: &Foo = x.as_ref(); // zero cost cast
|
||||
```
|
||||
|
||||
The trait implementations generated for the above block are:
|
||||
|
||||
```rust
|
||||
impl From<Bar> for Foo { ... }
|
||||
impl AsRef<Foo> for Bar { ... }
|
||||
impl AsMut<Foo> for Bar { ... }
|
||||
```
|
||||
|
||||
|
||||
The `extends = ...` attribute can be specified multiple times for longer
|
||||
inheritance chains, and `AsRef` and such impls will be generated for each of
|
||||
the types.
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
type Foo;
|
||||
|
||||
#[wasm_bindgen(extends = Foo)]
|
||||
type Bar;
|
||||
|
||||
#[wasm_bindgen(extends = Foo, extends = Bar)]
|
||||
type Baz;
|
||||
}
|
||||
|
||||
let x: &Baz = ...;
|
||||
let y1: &Bar = x.as_ref();
|
||||
let y2: &Foo = y1.as_ref();
|
||||
```
|
||||
156
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/final.md
vendored
Normal file
156
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/final.md
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
# `final`
|
||||
|
||||
The `final` attribute is the converse of the [`structural`
|
||||
attribute](structural.html). It configures how `wasm-bindgen` will generate JS
|
||||
imports to call the imported function. Notably a function imported by `final`
|
||||
never changes after it was imported, whereas a function imported by default (or
|
||||
with `structural`) is subject to runtime lookup rules such as walking the
|
||||
prototype chain of an object. Note that `final` is not suitable for accessing
|
||||
data descriptor properties of JS objects; to accomplish this, use the `structural`
|
||||
attribute.
|
||||
|
||||
[host-bindings]: https://github.com/WebAssembly/host-bindings
|
||||
[reference-types]: https://github.com/WebAssembly/reference-types
|
||||
|
||||
The `final` attribute is intended to be purely related to performance. It
|
||||
ideally has no user-visible effect, and `structural` imports (the default)
|
||||
should be able to transparently switch to `final` eventually.
|
||||
|
||||
The eventual performance aspect is that with the [host bindings
|
||||
proposal][host-bindings] then `wasm-bindgen` will need to generate far fewer JS
|
||||
function shims to import than it does today. For example, consider this import
|
||||
today:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
type Foo;
|
||||
#[wasm_bindgen(method)]
|
||||
fn bar(this: &Foo, argument: &str) -> JsValue;
|
||||
}
|
||||
```
|
||||
|
||||
**Without the `final` attribute** the generated JS looks like this:
|
||||
|
||||
```js
|
||||
// without `final`
|
||||
export function __wbg_bar_a81456386e6b526f(arg0, arg1, arg2) {
|
||||
let varg1 = getStringFromWasm(arg1, arg2);
|
||||
return addHeapObject(getObject(arg0).bar(varg1));
|
||||
}
|
||||
```
|
||||
|
||||
We can see here that this JS function shim is required, but it's all relatively
|
||||
self-contained. It does, however, execute the `bar` method in a duck-type-y
|
||||
fashion in the sense that it never validates `getObject(arg0)` is of type `Foo`
|
||||
to actually call the `Foo.prototype.bar` method.
|
||||
|
||||
If we instead, however, write this:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
type Foo;
|
||||
#[wasm_bindgen(method, final)] // note the change here
|
||||
fn bar(this: &Foo, argument: &str) -> JsValue;
|
||||
}
|
||||
```
|
||||
|
||||
it generates this JS glue (roughly):
|
||||
|
||||
```js
|
||||
const __wbg_bar_target = Foo.prototype.bar;
|
||||
|
||||
export function __wbg_bar_a81456386e6b526f(arg0, arg1, arg2) {
|
||||
let varg1 = getStringFromWasm(arg1, arg2);
|
||||
return addHeapObject(__wbg_bar_target.call(getObject(arg0), varg1));
|
||||
}
|
||||
```
|
||||
|
||||
The difference here is pretty subtle, but we can see how the function being
|
||||
called is hoisted out of the generated shim and is bound to always be
|
||||
`Foo.prototype.bar`. This then uses the `Function.call` method to invoke that
|
||||
function with `getObject(arg0)` as the receiver.
|
||||
|
||||
But wait, there's still a JS function shim here even with `final`! That's true,
|
||||
and this is simply a fact of future WebAssembly proposals not being implemented
|
||||
yet. The semantics, though, match the future [host bindings
|
||||
proposal][host-bindings] because the method being called is determined exactly
|
||||
once, and it's located on the prototype chain rather than being resolved at
|
||||
runtime when the function is called.
|
||||
|
||||
## Interaction with future proposals
|
||||
|
||||
If you're curious to see how our JS function shim will be eliminated entirely,
|
||||
let's take a look at the generated bindings. We're starting off with this:
|
||||
|
||||
```js
|
||||
const __wbg_bar_target = Foo.prototype.bar;
|
||||
|
||||
export function __wbg_bar_a81456386e6b526f(arg0, arg1, arg2) {
|
||||
let varg1 = getStringFromWasm(arg1, arg2);
|
||||
return addHeapObject(__wbg_bar_target.call(getObject(arg0), varg1));
|
||||
}
|
||||
```
|
||||
|
||||
... and once the [reference types proposal][reference-types] is implemented then
|
||||
we won't need some of these pesky functions. That'll transform our generated JS
|
||||
shim to look like:
|
||||
|
||||
```js
|
||||
const __wbg_bar_target = Foo.prototype.bar;
|
||||
|
||||
export function __wbg_bar_a81456386e6b526f(arg0, arg1, arg2) {
|
||||
let varg1 = getStringFromWasm(arg1, arg2);
|
||||
return __wbg_bar_target.call(arg0, varg1);
|
||||
}
|
||||
```
|
||||
|
||||
Getting better! Next up we need the host bindings proposal. Note that the
|
||||
proposal is undergoing some changes right now so it's tough to link to reference
|
||||
documentation, but it suffices to say that it'll empower us with at least two
|
||||
different features.
|
||||
|
||||
First, host bindings promises to provide the concept of "argument conversions".
|
||||
The `arg1` and `arg2` values here are actually a pointer and a length to a utf-8
|
||||
encoded string, and with host bindings we'll be able to annotate that this
|
||||
import should take those two arguments and convert them to a JS string (that is,
|
||||
the *host* should do this, the WebAssembly engine). Using that feature we can
|
||||
futher trim this down to:
|
||||
|
||||
```js
|
||||
const __wbg_bar_target = Foo.prototype.bar;
|
||||
|
||||
export function __wbg_bar_a81456386e6b526f(arg0, varg1) {
|
||||
return __wbg_bar_target.call(arg0, varg1);
|
||||
}
|
||||
```
|
||||
|
||||
And finally, the second promise of the host bindings proposal is that we can
|
||||
flag a function call to indicate the first argument is the `this` binding of the
|
||||
function call. Today the `this` value of all called imported functions is
|
||||
`undefined`, and this flag (configured with host bindings) will indicate the
|
||||
first argument here is actually the `this`.
|
||||
|
||||
With that in mind we can further transform this to:
|
||||
|
||||
```js
|
||||
export const __wbg_bar_a81456386e6b526f = Foo.prototype.bar;
|
||||
```
|
||||
|
||||
and voila! We, with [reference types][reference-types] and [host
|
||||
bindings][host-bindings], now have no JS function shim at all necessary to call
|
||||
the imported function. Additionally future wasm proposals to the ES module
|
||||
system may also mean that don't even need the `export const ...` here too.
|
||||
|
||||
It's also worth pointing out that with all these wasm proposals implemented the
|
||||
default way to import the `bar` function (aka `structural`) would generate a JS
|
||||
function shim that looks like:
|
||||
|
||||
```js
|
||||
export function __wbg_bar_a81456386e6b526f(varg1) {
|
||||
return this.bar(varg1);
|
||||
}
|
||||
```
|
||||
|
||||
where this import is still subject to runtime prototype chain lookups and such.
|
||||
78
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/getter-and-setter.md
vendored
Normal file
78
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/getter-and-setter.md
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
# `getter` and `setter`
|
||||
|
||||
These two attributes can be combined with `method` to indicate that this is a
|
||||
getter or setter method. A `getter`-tagged function by default accesses the
|
||||
JavaScript property with the same name as the getter function. A `setter`'s
|
||||
function name is currently required to start with `set_` and the property it
|
||||
accesses is the suffix after `set\_`.
|
||||
|
||||
Consider the following JavaScript class that has a getter and setter for the
|
||||
`white_russians` property:
|
||||
|
||||
```js
|
||||
class TheDude {
|
||||
get white_russians() {
|
||||
...
|
||||
}
|
||||
set white_russians(val) {
|
||||
...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
We would import this with the following `#[wasm_bindgen]` attributes:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
type TheDude;
|
||||
|
||||
#[wasm_bindgen(method, getter)]
|
||||
fn white_russians(this: &TheDude) -> u32;
|
||||
|
||||
#[wasm_bindgen(method, setter)]
|
||||
fn set_white_russians(this: &TheDude, val: u32);
|
||||
}
|
||||
```
|
||||
|
||||
Here we're importing the `TheDude` type and defining the ability to access each
|
||||
object's `white_russians` property. The first function here is a getter and will
|
||||
be available in Rust as `the_dude.white_russians()`, and the latter is the
|
||||
setter which is accessible as `the_dude.set_white_russians(2)`. Note that both
|
||||
functions have a `this` argument as they're tagged with `method`.
|
||||
|
||||
Finally, you can also pass an argument to the `getter` and `setter`
|
||||
properties to configure what property is accessed. When the property is
|
||||
explicitly specified then there is no restriction on the method name. For
|
||||
example the below is equivalent to the above:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
type TheDude;
|
||||
|
||||
#[wasm_bindgen(method, getter = white_russians)]
|
||||
fn my_custom_getter_name(this: &TheDude) -> u32;
|
||||
|
||||
#[wasm_bindgen(method, setter = white_russians)]
|
||||
fn my_custom_setter_name(this: &TheDude, val: u32);
|
||||
}
|
||||
```
|
||||
|
||||
Heads up! `getter` and `setter` functions are found on the constructor's
|
||||
prototype chain once at load time, cached, and then the cached accessor is
|
||||
invoked on each access. If you need to dynamically walk the prototype chain on
|
||||
every access, add the `structural` attribute!
|
||||
|
||||
```js
|
||||
// This is the default function Rust will invoke on `the_dude.white_russians()`:
|
||||
const white_russians = Object.getOwnPropertyDescriptor(
|
||||
TheDude.prototype,
|
||||
"white_russians"
|
||||
).get;
|
||||
|
||||
// This is what you get by adding `structural`:
|
||||
const white_russians = function(the_dude) {
|
||||
return the_dude.white_russians;
|
||||
};
|
||||
```
|
||||
5
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/index.md
vendored
Normal file
5
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/index.md
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# `#[wasm_bindgen]` on JavaScript Imports
|
||||
|
||||
This section enumerates the attributes available for customizing bindings for
|
||||
JavaScript functions and classes imported into Rust within an `extern "C" { ... }`
|
||||
block.
|
||||
@@ -0,0 +1,82 @@
|
||||
# `indexing_getter`, `indexing_setter`, and `indexing_deleter`
|
||||
|
||||
These three attributes indicate that a method is an dynamically intercepted
|
||||
getter, setter, or deleter on the receiver object itself, rather than a direct
|
||||
access of the receiver's properties. It is equivalent calling the Proxy handler
|
||||
for the `obj[prop]` operation with some dynamic `prop` variable in JavaScript,
|
||||
rather than a normal static property access like `obj.prop` on a normal
|
||||
JavaScript `Object`.
|
||||
|
||||
This is useful for binding to `Proxy`s and some builtin DOM types that
|
||||
dynamically intercept property accesses.
|
||||
|
||||
* `indexing_getter` corresponds to `obj[prop]` operation in JavaScript. The
|
||||
function annotated must have a `this` receiver parameter, a single parameter
|
||||
that is used for indexing into the receiver (`prop`), and a return type.
|
||||
|
||||
* `indexing_setter` corresponds to the `obj[prop] = val` operation in
|
||||
JavaScript. The function annotated must have a `this` receiver parameter, a
|
||||
parameter for indexing into the receiver (`prop`), and a value parameter
|
||||
(`val`).
|
||||
|
||||
* `indexing_deleter` corresponds to `delete obj[prop]` operation in
|
||||
JavaScript. The function annotated must have a `this` receiver and a single
|
||||
parameter for indexing into the receiver (`prop`).
|
||||
|
||||
These must always be used in conjunction with the `structural` and `method`
|
||||
flags.
|
||||
|
||||
For example, consider this JavaScript snippet that uses `Proxy`:
|
||||
|
||||
```js
|
||||
const foo = new Proxy({}, {
|
||||
get(obj, prop) {
|
||||
return prop in obj ? obj[prop] : prop.length;
|
||||
},
|
||||
set(obj, prop, value) {
|
||||
obj[prop] = value;
|
||||
},
|
||||
deleteProperty(obj, prop) {
|
||||
delete obj[prop];
|
||||
},
|
||||
});
|
||||
|
||||
foo.ten;
|
||||
// 3
|
||||
|
||||
foo.ten = 10;
|
||||
foo.ten;
|
||||
// 10
|
||||
|
||||
delete foo.ten;
|
||||
foo.ten;
|
||||
// 3
|
||||
```
|
||||
|
||||
To bind that in `wasm-bindgen` in Rust, we would use the `indexing_*` attributes
|
||||
on methods:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
type Foo;
|
||||
static foo: Foo;
|
||||
|
||||
#[wasm_bindgen(method, structural, indexing_getter)]
|
||||
fn get(this: &Foo, prop: &str) -> u32;
|
||||
|
||||
#[wasm_bindgen(method, structural, indexing_setter)]
|
||||
fn set(this: &Foo, prop: &str, val: u32);
|
||||
|
||||
#[wasm_bindgen(method, structural, indexing_deleter)]
|
||||
fn delete(this: &Foo, prop: &str);
|
||||
}
|
||||
|
||||
assert_eq!(foo.get("ten"), 3);
|
||||
|
||||
foo.set("ten", 10);
|
||||
assert_eq!(foo.get("ten"), 10);
|
||||
|
||||
foo.delete("ten");
|
||||
assert_eq!(foo.get("ten"), 3);
|
||||
```
|
||||
20
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/js_class.md
vendored
Normal file
20
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/js_class.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# `js_class = "Blah"`
|
||||
|
||||
The `js_class` attribute can be used in conjunction with the `method` attribute
|
||||
to bind methods of imported JavaScript classes that have been renamed on the
|
||||
Rust side.
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
// We don't want to import JS strings as `String`, since Rust already has a
|
||||
// `String` type in its prelude, so rename it as `JsString`.
|
||||
#[wasm_bindgen(js_name = String)]
|
||||
type JsString;
|
||||
|
||||
// This is a method on the JavaScript "String" class, so specify that with
|
||||
// the `js_class` attribute.
|
||||
#[wasm_bindgen(method, js_class = "String", js_name = charAt)]
|
||||
fn char_at(this: &JsString, index: u32) -> JsString;
|
||||
}
|
||||
```
|
||||
87
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/js_name.md
vendored
Normal file
87
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/js_name.md
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
# `js_name = blah`
|
||||
|
||||
The `js_name` attribute can be used to bind to a different function in
|
||||
JavaScript than the identifier that's defined in Rust.
|
||||
|
||||
Most often, this is used to convert a camel-cased JavaScript identifier into a
|
||||
snake-cased Rust identifier:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_name = jsOftenUsesCamelCase)]
|
||||
fn js_often_uses_camel_case() -> u32;
|
||||
}
|
||||
```
|
||||
|
||||
Sometimes, it is used to bind to JavaScript identifiers that are not valid Rust
|
||||
identifiers, in which case `js_name = "some string"` is used instead of `js_name
|
||||
= ident`:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_name = "$$$")]
|
||||
fn cash_money() -> u32;
|
||||
}
|
||||
```
|
||||
However, you can also use `js_name` to define multiple signatures for
|
||||
polymorphic JavaScript functions:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console, js_name = log)]
|
||||
fn console_log_str(s: &str);
|
||||
|
||||
#[wasm_bindgen(js_namespace = console, js_name = log)]
|
||||
fn console_log_u32(n: u32);
|
||||
|
||||
#[wasm_bindgen(js_namespace = console, js_name = log)]
|
||||
fn console_log_many(a: u32, b: &JsValue);
|
||||
}
|
||||
```
|
||||
|
||||
All of these functions will call `console.log` in JavaScript, but each
|
||||
identifier will have only one signature in Rust.
|
||||
|
||||
Note that if you use `js_name` when importing a type you'll also need to use the
|
||||
[`js_class` attribute][jsclass] when defining methods on the type:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_name = String)]
|
||||
type JsString;
|
||||
#[wasm_bindgen(method, getter, js_class = "String")]
|
||||
pub fn length(this: &JsString) -> u32;
|
||||
}
|
||||
```
|
||||
|
||||
The `js_name` attribute can also be used in situations where a JavaScript module uses
|
||||
`export default`. In this case, setting the `js_name` attribute to "default" on the
|
||||
`type` declaration, and the [`js_class` attribute][jsclass] to "default" on any methods
|
||||
on the exported object will generate the correct imports.
|
||||
|
||||
|
||||
For example, a module that would be imported directly in JavaScript:
|
||||
|
||||
```javascript
|
||||
import Foo from "bar";
|
||||
|
||||
let f = new Foo();
|
||||
```
|
||||
|
||||
Could be accessed using this definition in Rust:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(module = "bar")]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_name = default)
|
||||
type Foo;
|
||||
#[wasm_bindgen(constructor, js_class = default)]
|
||||
pub fn new() -> Foo;
|
||||
}
|
||||
```
|
||||
|
||||
[jsclass]: js_class.html
|
||||
41
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/js_namespace.md
vendored
Normal file
41
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/js_namespace.md
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
# `js_namespace = blah`
|
||||
|
||||
This attribute indicates that the JavaScript type is accessed through the given
|
||||
namespace. For example, the `WebAssembly.Module` APIs are all accessed through
|
||||
the `WebAssembly` namespace. `js_namespace` can be applied to any import
|
||||
(function or type) and whenever the generated JavaScript attempts to reference a
|
||||
name (like a class or function name) it'll be accessed through this namespace.
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
fn log(s: &str);
|
||||
|
||||
type Foo;
|
||||
#[wasm_bindgen(constructor, js_namespace = Bar)]
|
||||
fn new() -> Foo;
|
||||
}
|
||||
|
||||
log("hello, console!");
|
||||
Foo::new();
|
||||
```
|
||||
|
||||
This is an example of how to bind namespaced items in Rust. The `log` and `Foo::new` functions will
|
||||
be available in the Rust module and will be invoked as `console.log` and `new Bar.Foo` in
|
||||
JavaScript.
|
||||
|
||||
It is also possible to access the JavaScript object under the nested namespace.
|
||||
`js_namespace` also accepts the array of the string to specify the namespace.
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = ["window", "document"])]
|
||||
fn write(s: &str);
|
||||
}
|
||||
|
||||
write("hello, document!");
|
||||
```
|
||||
|
||||
This example shows how to bind `window.document.write` in Rust.
|
||||
26
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/method.md
vendored
Normal file
26
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/method.md
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
# `method`
|
||||
|
||||
The `method` attribute allows you to describe methods of imported JavaScript
|
||||
objects. It is applied on a function that has `this` as its first parameter,
|
||||
which is a shared reference to an imported JavaScript type.
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
type Set;
|
||||
|
||||
#[wasm_bindgen(method)]
|
||||
fn has(this: &Set, element: &JsValue) -> bool;
|
||||
}
|
||||
```
|
||||
|
||||
This generates a `has` method on `Set` in Rust, which invokes the
|
||||
`Set.prototype.has` method in JavaScript.
|
||||
|
||||
```rust
|
||||
let set: Set = ...;
|
||||
let elem: JsValue = ...;
|
||||
if set.has(&elem) {
|
||||
...
|
||||
}
|
||||
```
|
||||
38
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/module.md
vendored
Normal file
38
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/module.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
# `module = "blah"`
|
||||
|
||||
The `module` attributes configures the module from which items are imported. For
|
||||
example,
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(module = "wu/tang/clan")]
|
||||
extern "C" {
|
||||
type ThirtySixChambers;
|
||||
}
|
||||
```
|
||||
|
||||
generates JavaScript import glue like:
|
||||
|
||||
```js
|
||||
import { ThirtySixChambers } from "wu/tang/clan";
|
||||
```
|
||||
|
||||
If a `module` attribute is not present, then the global scope is used
|
||||
instead. For example,
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
fn illmatic() -> u32;
|
||||
}
|
||||
```
|
||||
|
||||
generates JavaScript import glue like:
|
||||
|
||||
```js
|
||||
let illmatic = this.illmatic;
|
||||
```
|
||||
|
||||
Note that if the string specified with `module` starts with `./`, `../`, or `/`
|
||||
then it's interpreted as a path to a [local JS snippet](../../js-snippets.html).
|
||||
If this doesn't work for your use case you might be interested in the
|
||||
[`raw_module` attribute](raw_module.html)
|
||||
24
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/no_deref.md
vendored
Normal file
24
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/no_deref.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# `no_deref`
|
||||
|
||||
The `no_deref` attribute can be used to say that no `Deref` impl should be
|
||||
generated for an imported type. If this attribute is not present, a `Deref` impl
|
||||
will be generated with a `Target` of the type's first `extends` attribute, or
|
||||
`Target = JsValue` if there are no `extends` attributes.
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
type Foo;
|
||||
|
||||
#[wasm_bindgen(method)]
|
||||
fn baz(this: &Foo)
|
||||
|
||||
#[wasm_bindgen(extends = Foo, no_deref)]
|
||||
type Bar;
|
||||
}
|
||||
|
||||
fn do_stuff(bar: &Bar) {
|
||||
bar.baz() // Does not compile
|
||||
}
|
||||
|
||||
```
|
||||
19
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/raw_module.md
vendored
Normal file
19
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/raw_module.md
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# `raw_module = "blah"`
|
||||
|
||||
This attribute performs exactly the same purpose as the [`module`
|
||||
attribute](module.html) on JS imports, but it does not attempt to interpret
|
||||
paths starting with `./`, `../`, or `/` as JS snippets. For example:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(raw_module = "./some/js/file.js")]
|
||||
extern "C" {
|
||||
fn the_function();
|
||||
}
|
||||
```
|
||||
|
||||
Note that if you use this attribute with a relative or absolute path, it's
|
||||
likely up to the final bundler or project to assign meaning to that path. This
|
||||
typically means that the JS file or module will be resolved relative to the
|
||||
final location of the wasm file itself. That means that `raw_module` is likely
|
||||
unsuitable for libraries on crates.io, but may be usable within end-user
|
||||
applications.
|
||||
28
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/static_method_of.md
vendored
Normal file
28
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/static_method_of.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# `static_method_of = Blah`
|
||||
|
||||
The `static_method_of` attribute allows one to specify that an imported function
|
||||
is a static method of the given imported JavaScript class. For example, to bind
|
||||
to JavaScript's `Date.now()` static method, one would use this attribute:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
type Date;
|
||||
|
||||
#[wasm_bindgen(static_method_of = Date)]
|
||||
pub fn now() -> f64;
|
||||
}
|
||||
```
|
||||
|
||||
The `now` function becomes a static method of the imported type in the Rust
|
||||
bindings as well:
|
||||
|
||||
```rust
|
||||
let instant = Date::now();
|
||||
```
|
||||
|
||||
This is similar to the `js_namespace` attribute, but the usage from within Rust
|
||||
is different since the method also becomes a static method of the imported type.
|
||||
Additionally this attribute also specifies that the `this` parameter when
|
||||
invoking the method is expected to be the JS class, e.g. always invoked as
|
||||
`Date.now()` instead of `const x = Date.now; x()`.
|
||||
48
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/structural.md
vendored
Normal file
48
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/structural.md
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
# `structural`
|
||||
|
||||
> **Note**: As of [RFC 5] this attribute is the default for all imported
|
||||
> functions. This attribute is largely ignored today and is only retained for
|
||||
> backwards compatibility and learning purposes.
|
||||
>
|
||||
> The inverse of this attribute, [the `final`
|
||||
> attribute](final.html) is more functionally interesting than
|
||||
> `structural` (as `structural` is simply the default)
|
||||
|
||||
[RFC 5]: https://rustwasm.github.io/rfcs/005-structural-and-deref.html
|
||||
|
||||
The `structural` flag can be added to `method` annotations, indicating that the
|
||||
method being accessed (or property with getters/setters) should be accessed in a
|
||||
structural, duck-type-y fashion. Rather than walking the constructor's prototype
|
||||
chain once at load time and caching the property result, the prototype chain is
|
||||
dynamically walked on every access.
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
type Duck;
|
||||
|
||||
#[wasm_bindgen(method, structural)]
|
||||
fn quack(this: &Duck);
|
||||
|
||||
#[wasm_bindgen(method, getter, structural)]
|
||||
fn is_swimming(this: &Duck) -> bool;
|
||||
}
|
||||
```
|
||||
|
||||
The constructor for the type here, `Duck`, is not required to exist in
|
||||
JavaScript (it's not referenced). Instead `wasm-bindgen` will generate shims
|
||||
that will access the passed in JavaScript value's `quack` method or its
|
||||
`is_swimming` property.
|
||||
|
||||
```js
|
||||
// Without `structural`, get the method directly off the prototype at load time:
|
||||
const Duck_prototype_quack = Duck.prototype.quack;
|
||||
function quack(duck) {
|
||||
Duck_prototype_quack.call(duck);
|
||||
}
|
||||
|
||||
// With `structural`, walk the prototype chain on every access:
|
||||
function quack(duck) {
|
||||
duck.quack();
|
||||
}
|
||||
```
|
||||
15
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/typescript_type.md
vendored
Normal file
15
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/typescript_type.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# `typescript_type = "Blah"`
|
||||
|
||||
The `typescript_type` attribute is used to specify the TypeScript type for an
|
||||
imported type. This type will be used in the generated `.d.ts`.
|
||||
|
||||
Right now only identifiers are supported, but eventually we'd like to support
|
||||
all TypeScript types.
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(typescript_type = "Foo")]
|
||||
type Foo;
|
||||
}
|
||||
```
|
||||
38
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/variadic.md
vendored
Normal file
38
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/variadic.md
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
# Variadic Parameters
|
||||
|
||||
In javascript, both the types of function arguments, and the number of function arguments are
|
||||
dynamic. For example
|
||||
|
||||
```js
|
||||
function sum(...rest) {
|
||||
let i;
|
||||
// the old way
|
||||
let old_way = 0;
|
||||
for (i=0; i<arguments.length; i++) {
|
||||
old_way += arguments[i];
|
||||
}
|
||||
// the new way
|
||||
let new_way = 0;
|
||||
for (i=0; i<rest.length; i++) {
|
||||
new_way += rest[i];
|
||||
}
|
||||
// both give the same answer
|
||||
assert(old_way === new_way);
|
||||
return new_way;
|
||||
}
|
||||
```
|
||||
|
||||
This function doesn't translate directly into rust, since we don't currently support variadic
|
||||
arguments on the wasm target. To bind to it, we use a slice as the last argument, and annotate the
|
||||
function as variadic:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(variadic)]
|
||||
fn sum(args: &[i32]) -> i32;
|
||||
}
|
||||
```
|
||||
|
||||
when we call this function, the last argument will be expanded as the javascript expects.
|
||||
|
||||
24
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/vendor_prefix.md
vendored
Normal file
24
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-js-imports/vendor_prefix.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# Vendor-prefixed APIs
|
||||
|
||||
On the web new APIs often have vendor prefixes while they're in an experimental
|
||||
state. For example the `AudioContext` API is known as `webkitAudioContext` in
|
||||
Safari at the time of this writing. The `vendor_prefix` attribute indicates
|
||||
these alternative names, which are used if the normal name isn't defined.
|
||||
|
||||
For example to use `AudioContext` you might do:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(vendor_prefix = webkit)]
|
||||
type AudioContext;
|
||||
|
||||
// methods on `AudioContext` ...
|
||||
}
|
||||
```
|
||||
|
||||
Whenever `AudioContext` is used it'll use `AudioContext` if the global namespace
|
||||
defines it or alternatively it'll fall back to `webkitAudioContext`.
|
||||
|
||||
Note that `vendor_prefix` cannot be used with `module = "..."` or
|
||||
`js_namespace = ...`, so it's basically limited to web-platform APIs today.
|
||||
34
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/constructor.md
vendored
Normal file
34
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/constructor.md
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# `constructor`
|
||||
|
||||
When attached to a Rust "constructor" it will make the generated JavaScript
|
||||
bindings callable as `new Foo()`.
|
||||
|
||||
For example, consider this exported Rust type and `constructor` annotation:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
pub struct Foo {
|
||||
contents: u32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Foo {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new() -> Foo {
|
||||
Foo { contents: 0 }
|
||||
}
|
||||
|
||||
pub fn get_contents(&self) -> u32 {
|
||||
self.contents
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This can be used in JavaScript as:
|
||||
|
||||
```js
|
||||
import { Foo } from './my_module';
|
||||
|
||||
const f = new Foo();
|
||||
console.log(f.get_contents());
|
||||
```
|
||||
64
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/getter-and-setter.md
vendored
Normal file
64
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/getter-and-setter.md
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
# `getter` and `setter`
|
||||
|
||||
The `getter` and `setter` attributes can be used in Rust `impl` blocks to define
|
||||
properties in JS that act like getters and setters of a field. For example:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
pub struct Baz {
|
||||
field: i32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Baz {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(field: i32) -> Baz {
|
||||
Baz { field }
|
||||
}
|
||||
|
||||
#[wasm_bindgen(getter)]
|
||||
pub fn field(&self) -> i32 {
|
||||
self.field
|
||||
}
|
||||
|
||||
#[wasm_bindgen(setter)]
|
||||
pub fn set_field(&mut self, field: i32) {
|
||||
self.field = field;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Can be combined in `JavaScript` like in this snippet:
|
||||
|
||||
```js
|
||||
const obj = new Baz(3);
|
||||
assert.equal(obj.field, 3);
|
||||
obj.field = 4;
|
||||
assert.equal(obj.field, 4);
|
||||
```
|
||||
|
||||
You can also configure the name of the property that is exported in JS like so:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
impl Baz {
|
||||
#[wasm_bindgen(getter = anotherName)]
|
||||
pub fn field(&self) -> i32 {
|
||||
self.field
|
||||
}
|
||||
|
||||
#[wasm_bindgen(setter = anotherName)]
|
||||
pub fn set_field(&mut self, field: i32) {
|
||||
self.field = field;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Getters are expected to take no arguments other than `&self` and return the
|
||||
field's type. Setters are expected to take one argument other than `&mut self`
|
||||
(or `&self`) and return no values.
|
||||
|
||||
The name for a `getter` is by default inferred from the function name it's
|
||||
attached to. The default name for a `setter` is the function's name minus the
|
||||
`set_` prefix, and if `set_` isn't a prefix of the function it's an error to not
|
||||
provide the name explicitly.
|
||||
17
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/getter_with_clone.md
vendored
Normal file
17
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/getter_with_clone.md
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# `getter_with_clone`
|
||||
|
||||
By default, Rust exports exposed to JavaScript will generate getters that require fields to implement `Copy`. The `getter_with_clone` attribute can be used to generate getters that require `Clone` instead. This attribute can be applied per struct or per field. For example:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
pub struct Foo {
|
||||
#[wasm_bindgen(getter_with_clone)]
|
||||
pub bar: String,
|
||||
}
|
||||
|
||||
#[wasm_bindgen(getter_with_clone)]
|
||||
pub struct Foo {
|
||||
pub bar: String,
|
||||
pub baz: String,
|
||||
}
|
||||
```
|
||||
4
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/index.md
vendored
Normal file
4
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/index.md
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# `#[wasm_bindgen]` on Rust Exports
|
||||
|
||||
This section enumerates the attributes available for customizing bindings for
|
||||
Rust functions and `struct`s exported to JavaScript.
|
||||
53
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/inspectable.md
vendored
Normal file
53
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/inspectable.md
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
# `inspectable`
|
||||
|
||||
By default, structs exported from Rust become JavaScript classes with a single `ptr` property. All other properties are implemented as getters, which are not displayed when calling `toJSON`.
|
||||
|
||||
The `inspectable` attribute can be used on Rust structs to provide a `toJSON` and `toString` implementation that display all readable fields. For example:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(inspectable)]
|
||||
pub struct Baz {
|
||||
pub field: i32,
|
||||
private: i32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Baz {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(field: i32) -> Baz {
|
||||
Baz { field, private: 13 }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Provides the following behavior as in this JavaScript snippet:
|
||||
|
||||
```js
|
||||
const obj = new Baz(3);
|
||||
assert.deepStrictEqual(obj.toJSON(), { field: 3 });
|
||||
obj.field = 4;
|
||||
assert.strictEqual(obj.toString(), '{"field":4}');
|
||||
```
|
||||
|
||||
One or both of these implementations can be overridden as desired. Note that the generated `toString` calls `toJSON` internally, so overriding `toJSON` will affect its output as a side effect.
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
impl Baz {
|
||||
#[wasm_bindgen(js_name = toJSON)]
|
||||
pub fn to_json(&self) -> i32 {
|
||||
self.field
|
||||
}
|
||||
|
||||
#[wasm_bindgen(js_name = toString)]
|
||||
pub fn to_string(&self) -> String {
|
||||
format!("Baz: {}", self.field)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note that the output of `console.log` will remain unchanged and display only the `ptr` field in browsers. It is recommended to call `toJSON` or `JSON.stringify` in these situations to aid with logging or debugging. Node.js does not suffer from this limitation, see the section below.
|
||||
|
||||
## `inspectable` Classes in Node.js
|
||||
|
||||
When the `nodejs` target is used, an additional `[util.inspect.custom]` implementation is provided which calls `toJSON` internally. This method is used for `console.log` and similar functions to display all readable fields of the Rust struct.
|
||||
28
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/js_class.md
vendored
Normal file
28
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/js_class.md
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# `js_class = Blah`
|
||||
|
||||
The `js_class` attribute is used to indicate that all the methods inside an
|
||||
`impl` block should be attached to the specified JS class instead of inferring
|
||||
it from the self type in the `impl` block. The `js_class` attribute is most
|
||||
frequently paired with [the `js_name` attribute](js_name.html) on structs:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(js_name = Foo)]
|
||||
pub struct JsFoo { /* ... */ }
|
||||
|
||||
#[wasm_bindgen(js_class = Foo)]
|
||||
impl JsFoo {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new() -> JsFoo { /* ... */ }
|
||||
|
||||
pub fn foo(&self) { /* ... */ }
|
||||
}
|
||||
```
|
||||
|
||||
which is accessed like:
|
||||
|
||||
```rust
|
||||
import { Foo } from './my_module';
|
||||
|
||||
const x = new Foo();
|
||||
x.foo();
|
||||
```
|
||||
54
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/js_name.md
vendored
Normal file
54
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/js_name.md
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
# `js_name = Blah`
|
||||
|
||||
The `js_name` attribute can be used to export a different name in JS than what
|
||||
something is named in Rust. It can be applied to both exported Rust functions
|
||||
and types.
|
||||
|
||||
For example, this is often used to convert between Rust's snake-cased
|
||||
identifiers into JavaScript's camel-cased identifiers:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(js_name = doTheThing)]
|
||||
pub fn do_the_thing() -> u32 {
|
||||
42
|
||||
}
|
||||
```
|
||||
|
||||
This can be used in JavaScript as:
|
||||
|
||||
```js
|
||||
import { doTheThing } from './my_module';
|
||||
|
||||
const x = doTheThing();
|
||||
console.log(x);
|
||||
```
|
||||
|
||||
Like imports, `js_name` can also be used to rename types exported to JS:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(js_name = Foo)]
|
||||
pub struct JsFoo {
|
||||
// ..
|
||||
}
|
||||
```
|
||||
|
||||
to be accessed like:
|
||||
|
||||
```js
|
||||
import { Foo } from './my_module';
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
Note that attaching methods to the JS class `Foo` should be done via the
|
||||
[`js_class` attribute](js_class.html):
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(js_name = Foo)]
|
||||
pub struct JsFoo { /* ... */ }
|
||||
|
||||
#[wasm_bindgen(js_class = Foo)]
|
||||
impl JsFoo {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
39
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/readonly.md
vendored
Normal file
39
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/readonly.md
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
# `readonly`
|
||||
|
||||
When attached to a `pub` struct field this indicates that it's read-only from
|
||||
JavaScript, and a setter will not be generated and exported to JavaScript.
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen]
|
||||
pub fn make_foo() -> Foo {
|
||||
Foo {
|
||||
first: 10,
|
||||
second: 20,
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct Foo {
|
||||
pub first: u32,
|
||||
|
||||
#[wasm_bindgen(readonly)]
|
||||
pub second: u32,
|
||||
}
|
||||
```
|
||||
|
||||
Here the `first` field will be both readable and writable from JS, but the
|
||||
`second` field will be a `readonly` field in JS where the setter isn't
|
||||
implemented and attempting to set it will throw an exception.
|
||||
|
||||
```js
|
||||
import { make_foo } from "./my_module";
|
||||
|
||||
const foo = make_foo();
|
||||
|
||||
// Can both get and set `first`.
|
||||
foo.first = 99;
|
||||
console.log(foo.first);
|
||||
|
||||
// Can only get `second`.
|
||||
console.log(foo.second);
|
||||
```
|
||||
46
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/skip.md
vendored
Normal file
46
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/skip.md
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
# `skip`
|
||||
|
||||
When attached to a `pub` struct field this indicates that field will not be exposed to JavaScript,
|
||||
and neither getter nor setter will be generated in ES6 class.
|
||||
|
||||
```rust
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct Foo {
|
||||
pub bar: u32,
|
||||
|
||||
#[wasm_bindgen(skip)]
|
||||
pub baz: u32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Foo {
|
||||
pub fn new() -> Self {
|
||||
Foo {
|
||||
bar: 1,
|
||||
baz: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Here the `bar` field will be both readable and writable from JS, but the
|
||||
`baz` field will be `undefined` in JS.
|
||||
|
||||
```js
|
||||
import('./pkg/').then(rust => {
|
||||
let foo = rust.Foo.new();
|
||||
|
||||
// bar is accessible by getter
|
||||
console.log(foo.bar);
|
||||
// field marked with `skip` is undefined
|
||||
console.log(foo.baz);
|
||||
|
||||
// you can shadow it
|
||||
foo.baz = 45;
|
||||
// so accessing by getter will return `45`
|
||||
// but it won't affect real value in rust memory
|
||||
console.log(foo.baz);
|
||||
});
|
||||
```
|
||||
42
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/skip_typescript.md
vendored
Normal file
42
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/skip_typescript.md
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
# `skip_typescript`
|
||||
|
||||
By default, Rust exports exposed to JavaScript will generate TypeScript definitions (unless `--no-typescript` is used). The `skip_typescript` attribute can be used to disable type generation per function, enum, struct, or field. For example:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(skip_typescript)]
|
||||
pub enum MyHiddenEnum {
|
||||
One,
|
||||
Two,
|
||||
Three
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct MyPoint {
|
||||
pub x: u32,
|
||||
|
||||
#[wasm_bindgen(skip_typescript)]
|
||||
pub y: u32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl MyPoint {
|
||||
|
||||
#[wasm_bindgen(skip_typescript)]
|
||||
pub fn stringify(&self) -> String {
|
||||
format!("({}, {})", self.x, self.y)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Will generate the following `.d.ts` file:
|
||||
|
||||
```ts
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export class MyPoint {
|
||||
free(): void;
|
||||
x: number;
|
||||
}
|
||||
```
|
||||
|
||||
When combined with [the `typescript_custom_section` attribute](typescript_custom_section.html), this can be used to manually specify more specific function types instead of using the generated definitions.
|
||||
31
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/start.md
vendored
Normal file
31
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/start.md
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# `start`
|
||||
|
||||
When attached to a `pub` function this attribute will configure the `start`
|
||||
section of the wasm executable to be emitted, executing the tagged function as
|
||||
soon as the wasm module is instantiated.
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn main() {
|
||||
// executed automatically ...
|
||||
}
|
||||
```
|
||||
|
||||
The `start` section of the wasm executable will be configured to execute the
|
||||
`main` function here as soon as it can. Note that due to various practical
|
||||
limitations today the start section of the executable may not literally point to
|
||||
`main`, but the `main` function here should be started up automatically when the
|
||||
wasm module is loaded.
|
||||
|
||||
There's a few caveats to be aware of when using the `start` attribute:
|
||||
|
||||
* The `start` function must take no arguments and must either return `()` or
|
||||
`Result<(), JsValue>`
|
||||
* Only one `start` function can be placed into a module, including its
|
||||
dependencies. If more than one is specified then `wasm-bindgen` will fail when
|
||||
the CLI is run. It's recommended that only applications use this attribute.
|
||||
* The `start` function will not be executed when testing.
|
||||
* If you're experimenting with WebAssembly threads, the `start` function is
|
||||
executed *once per thread*, not once globally!
|
||||
* Note that the `start` function is relatively new, so if you find any bugs with
|
||||
it, please feel free to report an issue!
|
||||
@@ -0,0 +1,34 @@
|
||||
# `typescript_custom_section`
|
||||
|
||||
When added to a `const` `&'static str`, it will append the contents of the
|
||||
string to the `.d.ts` file exported by `wasm-bindgen-cli` (when the
|
||||
`--typescript` flag is enabled).
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(typescript_custom_section)]
|
||||
const TS_APPEND_CONTENT: &'static str = r#"
|
||||
|
||||
export type Coords = { "latitude": number, "longitude": number, };
|
||||
|
||||
"#;
|
||||
```
|
||||
|
||||
The primary target for this feature is for code generation. For example, you
|
||||
can author a macro that allows you to export a TypeScript definition alongside
|
||||
the definition of a struct or Rust type.
|
||||
|
||||
```rust
|
||||
#[derive(MyTypescriptExport)]
|
||||
struct Coords {
|
||||
latitude: u32,
|
||||
longitude: u32,
|
||||
}
|
||||
```
|
||||
|
||||
The proc_derive_macro "MyTypescriptExport" can export its own
|
||||
`#[wasm_bindgen(typescript_custom_section)]` section, which would then be
|
||||
picked up by wasm-bindgen-cli. This would be equivalent to the contents of
|
||||
the TS_APPEND_CONTENT string in the first example.
|
||||
|
||||
This feature allows plain data objects to be typechecked in Rust and in
|
||||
TypeScript by outputing a type definition generated at compile time.
|
||||
56
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/typescript_type.md
vendored
Normal file
56
zeroidc/vendor/wasm-bindgen/guide/src/reference/attributes/on-rust-exports/typescript_type.md
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
# typescript_type
|
||||
|
||||
The `typescript_type` allows us to use typescript declarations in `typescript_custom_section` as arguments for rust functions! For example:
|
||||
|
||||
```rust
|
||||
#[wasm_bindgen(typescript_custom_section)]
|
||||
const ITEXT_STYLE: &'static str = r#"
|
||||
interface ITextStyle {
|
||||
bold: boolean;
|
||||
italic: boolean;
|
||||
size: number;
|
||||
}
|
||||
"#;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(typescript_type = "ITextStyle")]
|
||||
pub type ITextStyle;
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
#[derive(Default)]
|
||||
pub struct TextStyle {
|
||||
pub bold: bool,
|
||||
pub italic: bool,
|
||||
pub size: i32,
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl TextStyle {
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new(_i: ITextStyle) -> TextStyle {
|
||||
// parse JsValue
|
||||
TextStyle::default()
|
||||
}
|
||||
|
||||
pub fn optional_new(_i: Option<ITextStyle>) -> TextStyle {
|
||||
// parse JsValueo
|
||||
TextStyle::default()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
We can write our `typescript` code like:
|
||||
|
||||
```ts
|
||||
import { ITextStyle, TextStyle } from "./my_awesome_module";
|
||||
|
||||
const style: TextStyle = new TextStyle({
|
||||
bold: true,
|
||||
italic: true,
|
||||
size: 42,
|
||||
});
|
||||
|
||||
const optional_style: TextStyle = TextStyle.optional_new();
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user