Open2
Rust 勉強ログ
- wasm + libc => 現状無理
- wasi
- 移植 https://github.com/aidenybai/tiny-vdom/blob/main/src/vdom.ts#L20
- nostd https://rahul-thakoor.github.io/using-no-standard-library-crates-with-webassembly/
- wasm + feature promise
- GoogleChromeLabs/wasm-bindgen-rayon: An adapter for enabling Rayon-based concurrency on the Web with WebAssembly.
Rust の wasi ビルドを javascript から実行する
cargo new で生成される println するだけのコードを wasi ビルドしてみる。
# wasi とwasmtime の準備
$ cargo install wasi
$ curl https://wasmtime.dev/install.sh -sSf | bash
$ cargo new try-wasi
$ cd try-wasi
$ cargo wasi run
info: downloading component 'rust-std' for 'wasm32-wasi'
info: installing component 'rust-std' for 'wasm32-wasi'
Compiling try-wasi v0.1.0 (/Users/mizchi/mizchi/study-rust/try-wasi)
Finished dev [unoptimized + debuginfo] target(s) in 0.29s
Running `/Users/mizchi/.cargo/bin/cargo-wasi target/wasm32-wasi/debug/try-wasi.wasm`
Running `target/wasm32-wasi/debug/try-wasi.wasm`
Hello, world!
$ cargo wasi build
wasi binary を実行する
元の記事を参考に deno で書いた。deno なのはプリミティブな操作しかしないのと、環境構築が楽だから
import { join, dirname } from "https://deno.land/std@0.107.0/path/mod.ts";
const wasmFile = join(
dirname(new URL(import.meta.url).pathname),
"target/wasm32-wasi/debug/try-wasi.wasm"
);
const run = async () => {
const buffer = await Deno.readFile(wasmFile);
const module = await WebAssembly.compile(buffer);
let memory: WebAssembly.Memory = null as any;
const wasiImpl = {
fd_write: (fd: number, iovs: number, iovsLen: number, nwritten: number) => {
console.log(
`*** call fd_write: fd=${fd}, iovs=${iovs}, iovsLen=${iovsLen}, nwritten=${nwritten}`
);
const mem = memory.buffer;
const view = new DataView(mem);
const sizeList = Array.from(Array(iovsLen), (_, i) => {
const ptr = iovs + i * 8;
const bufStart = view.getUint32(ptr, true);
const bufLen = view.getUint32(ptr + 4, true);
const buf = new Uint8Array(mem, bufStart, bufLen);
const msg = new TextDecoder().decode(buf);
console.log(msg);
return buf.byteLength;
});
const totalSize = sizeList.reduce((acc, v) => acc + v);
view.setUint32(nwritten, totalSize, true);
return 0;
},
proc_exit: () => {},
fd_prestat_get: () => {},
fd_prestat_dir_name: () => {},
environ_sizes_get: () => {},
environ_get: () => {},
};
const imports = {
wasi_snapshot_preview1: wasiImpl,
};
const instance = await WebAssembly.instantiate(module, imports);
memory = instance.exports.memory as unknown as WebAssembly.Memory;
(instance.exports as any).main();
};
run().catch((err) => console.error(err));
$ deno run --allow-read run.ts
*** call fd_write: fd=1, iovs=1048320, iovsLen=1, nwritten=1048300
Hello, world!