RustでWebassemblyが出来るとハッピーだなーと思い、mir2wasm を使って、
現時点でのRust+Webassemblyを調査してみました。
環境
- OSX Yosemite
- Chrome バージョン53.0.2785.101
用意するもの
- rustup(nightlyが必要)
- Webassemblyを有効にしているChrome
- mir2wasm(Rustからwastをつくるやつ)
- sexpr-wasm(wastからwasmに変えるやつ)
- HTTPサーバー(python2 -m SimpleHTTPServerなどなど)
開発準備
mir2wasm
git clone https://github.com/brson/mir2wasm.git
cd mir2wasm
rustup override set nightly-2016-06-04
cargo build
sexpr-wasm
git clone https://github.com/WebAssembly/sexpr-wasm-prototype
cd sexpr-wasm-prototype
git submodule update --init
make
適当にMakefile
WASM_DIR := $(CURDIR)/wasm
MIR2WASM_DIR := $(CURDIR)/mir2wasm
SEXPR_WASM_DIR := $(CURDIR)/sexpr-wasm-prototype/out
WAST := main.wast
WASM := main.wasm
# mir2wasmについているexampleを利用。
RS := $(MIR2WASM_DIR)/rust-examples/fibonacci.rs
$(WASM_DIR)/$(WASM): $(WASM_DIR) $(WASM_DIR)/$(WAST)
$(SEXPR_WASM_DIR)/sexpr-wasm $(WASM_DIR)/$(WAST) -o $(@)
$(WASM_DIR)/$(WAST): $(WASM_DIR)
cd $(MIR2WASM_DIR) && \
cargo run -q -- $(RS) > $(@)
$(WASM_DIR):
mkdir -p $(@)
構成はこんな感じ。
.
├── Makefile
├── mir2wasm
└── sexpr-wasm-prototype
ブラウザで確認
makeするとRustのコードがwasmになるので、それをJSで読み込みましょう。
(ローカルファイルだと実行されないので、サーバーからアクセスできるにしましょう)
<!doctype html>
<html>
<head><title>WebAssembly</title></head>
<body>
<script>
fetch("/wasm/main.wasm")
.then(res => res.arrayBuffer())
.then(buffer => {
let ffi = {
spectest : {
print: function(ptr) {
console.log(ptr);
},
}
};
let module = Wasm.instantiateModule(new Uint8Array(buffer), ffi);
console.log(module.exports.fibonacci_recursive(10))
});
</script>
</body>
</html>
で、ブラウザで確認すると、
WasmModule::CompileFunctions(): Compiling WASM function #4:> failed:Result = arity mismatch in return @+42
みたいなエラーがでると思います。
wastを修正して、wasmを再作成
でどうしたらいいかというと、mir2wasmで吐き出されているwast(S式みたいなやつ)を
直接修正して、もう一度wasmにしてあげましょう。
fibonacci.rsがwastだと、↓の関数の式の
- $i32_as_AddAssign::add_assign
- $wasm::print_i32
- $main
- (return
- (get_local $<数値>)
- )
返り値がないのに、値を返しているっぽいところを削除する。(mir2wasmのバグ?)
再度sexpr-wasmでwastからwasmを作って、エラーが表示されない場合は大丈夫です。
まとめ
頑張ればmir2wasmを利用してRustからWebassemblyのバイナリがつくれます。
まだ完全じゃないけど、なんとなく雰囲気は掴めたとおもいます。
将来、RustでWebassemblyが簡単にできるようになればいいですね。