mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-12-14 20:11:37 +03:00
Create wasm-in-wasm-imports example (#2229)
This commit is contained in:
parent
e372596bc9
commit
17950202ca
@ -79,6 +79,7 @@ members = [
|
||||
"examples/request-animation-frame",
|
||||
"examples/todomvc",
|
||||
"examples/wasm-in-wasm",
|
||||
"examples/wasm-in-wasm-imports",
|
||||
"examples/wasm2js",
|
||||
"examples/webaudio",
|
||||
"examples/webgl",
|
||||
|
13
examples/wasm-in-wasm-imports/Cargo.toml
Normal file
13
examples/wasm-in-wasm-imports/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "wasm-in-wasm-imports"
|
||||
version = "0.1.0"
|
||||
authors = ["The wasm-bindgen Developers"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
wasm-bindgen = "0.2.64"
|
||||
js-sys = "0.3.41"
|
||||
wasm-bindgen-futures = "0.4.14"
|
15
examples/wasm-in-wasm-imports/README.md
Normal file
15
examples/wasm-in-wasm-imports/README.md
Normal file
@ -0,0 +1,15 @@
|
||||
# js-sys: WebAssembly in WebAssembly
|
||||
|
||||
[View documentation for this example online][dox] or [View compiled example
|
||||
online][compiled]
|
||||
|
||||
[compiled]: https://rustwasm.github.io/wasm-bindgen/exbuild/wasm-in-wasm/
|
||||
[dox]: https://rustwasm.github.io/docs/wasm-bindgen/examples/wasm-in-wasm.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
examples/wasm-in-wasm-imports/index.html
Normal file
8
examples/wasm-in-wasm-imports/index.html
Normal file
@ -0,0 +1,8 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html;charset=utf-8" http-equiv="Content-Type"/>
|
||||
</head>
|
||||
<body>
|
||||
<p>The developer console should have messages in it</p>
|
||||
</body>
|
||||
</html>
|
4
examples/wasm-in-wasm-imports/index.js
Normal file
4
examples/wasm-in-wasm-imports/index.js
Normal file
@ -0,0 +1,4 @@
|
||||
// For more comments about what's going on here, check out the `hello_world`
|
||||
// example
|
||||
import('./pkg')
|
||||
.catch(console.error);
|
14
examples/wasm-in-wasm-imports/package.json
Normal file
14
examples/wasm-in-wasm-imports/package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build": "webpack",
|
||||
"serve": "webpack-dev-server"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@wasm-tool/wasm-pack-plugin": "1.0.1",
|
||||
"text-encoding": "^0.7.0",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"webpack": "^4.29.4",
|
||||
"webpack-cli": "^3.1.1",
|
||||
"webpack-dev-server": "^3.1.0"
|
||||
}
|
||||
}
|
86
examples/wasm-in-wasm-imports/src/lib.rs
Normal file
86
examples/wasm-in-wasm-imports/src/lib.rs
Normal file
@ -0,0 +1,86 @@
|
||||
use js_sys::{Function, Map, Object, Reflect, WebAssembly};
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_futures::{spawn_local, JsFuture};
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
pub(crate) fn log(a: &str);
|
||||
|
||||
#[wasm_bindgen(js_namespace = console)]
|
||||
pub(crate) fn error(a: &str);
|
||||
|
||||
}
|
||||
|
||||
#[macro_use]
|
||||
macro_rules! console_log {
|
||||
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
|
||||
}
|
||||
|
||||
#[macro_use]
|
||||
macro_rules! console_error {
|
||||
($($t:tt)*) => (log(&format_args!($($t)*).to_string()))
|
||||
}
|
||||
|
||||
const WASM: &[u8] = include_bytes!("native_add.wasm");
|
||||
|
||||
async fn run_async() -> Result<(), JsValue> {
|
||||
console_log!("instantiating a new wasm module directly");
|
||||
|
||||
let imports = make_imports()?;
|
||||
let a = JsFuture::from(WebAssembly::instantiate_buffer(WASM, &imports)).await?;
|
||||
|
||||
let instance: WebAssembly::Instance = Reflect::get(&a, &"instance".into())?.dyn_into()?;
|
||||
|
||||
let exports = instance.exports();
|
||||
|
||||
let add = Reflect::get(&exports, &"add".into())?
|
||||
.dyn_into::<Function>()
|
||||
.expect("add export wasn't a function");
|
||||
|
||||
let three = add.call2(&JsValue::undefined(), &1.into(), &2.into())?;
|
||||
console_log!("1 + 2 = {:?}", three);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn bind(this: &JsValue, func_name: &str) -> Result<(), JsValue> {
|
||||
let property_key = JsValue::from(func_name);
|
||||
let orig_func = Reflect::get(this, &property_key)?.dyn_into::<Function>()?;
|
||||
let func = orig_func.bind(this);
|
||||
if !Reflect::set(this, &property_key, &func)? {
|
||||
return Err(JsValue::from("failed to set property"));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn make_imports() -> Result<Object, JsValue> {
|
||||
let map = Map::new();
|
||||
let imports: JsValue = Imports.into();
|
||||
|
||||
bind(&imports, "native_add")?;
|
||||
|
||||
map.set(&JsValue::from("env"), &imports);
|
||||
Object::from_entries(&map.into())
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub struct Imports;
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl Imports {
|
||||
pub fn native_add(&self, a: i32, b: i32) -> i32 {
|
||||
a + b
|
||||
}
|
||||
}
|
||||
|
||||
#[wasm_bindgen(start)]
|
||||
pub fn run() {
|
||||
spawn_local(async {
|
||||
match run_async().await {
|
||||
Ok(_) => console_log!("Finished"),
|
||||
Err(e) => console_error!("{:?}", e),
|
||||
}
|
||||
});
|
||||
}
|
BIN
examples/wasm-in-wasm-imports/src/native_add.wasm
Normal file
BIN
examples/wasm-in-wasm-imports/src/native_add.wasm
Normal file
Binary file not shown.
27
examples/wasm-in-wasm-imports/webpack.config.js
Normal file
27
examples/wasm-in-wasm-imports/webpack.config.js
Normal file
@ -0,0 +1,27 @@
|
||||
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, ".")
|
||||
}),
|
||||
// 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'
|
||||
};
|
Loading…
Reference in New Issue
Block a user