rustでwasmを実行してみた

rustのプログラムでプラグイン機構を組み込むにはどうしたら良いか調べていたところ、rustでwasmを実行する方法が出てきたので試しに実装してみた。

開発環境構築

wasmをビルドするために、Scoopでllvmをインストール

scoop install llvm

clangと一緒にwasm用リンカとか色々一緒に入ってくる

wasmプログラムの開発

llvmのインストールが終わったらcでプログラム作成

#include <stdint.h>

__attribute__((visibility("default"))) // clangに関数をエクスポートするように指定
int add(int32_t a, int32_t b) {
    return a + b;
}

int型2つ受け取って足し算した結果を返すだけの関数。
ビルドするためのMakefileも

all: wasm.wasm

wasm.wasm: wasm.o
	clang -Wl,--no-entry -Wl,--export-dynamic -nostdlib --target=wasm32 -o wasm.wasm wasm.o

wasm.o: wasm.c
	clang --target=wasm32 -c wasm.c -o wasm.o

あとはmakeでwasm.wasmを作成してwasmファイルの準備は完了。

rust側の開発

実際にwasmファイルを読んで実行するプログラムの開発。まずはcargoでプロジェクトの準備

cargo new --bin wasm_rt

次にCargo.tomlの準備。

[package]
name = "wasm_rt"
version = "0.1.0"
authors = ["mattyan <mattyan.mail@gmail.com>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
wasmer = "1.0.0-alpha"

最初はwasmer 0.16を使ってたんだけど、どうしてもビルドができなかったので、1.0.0-alpha5に変更。

extern crate wasmer;
use wasmer::{Store, Module, Instance, imports, Value};
use std::fs::File;
use std::io::Read;

fn main() {
    // wasmファイル読み込み
    let mut wasm_file = File::open("./wasm.wasm").unwrap();
    let mut wasm_file_buf = Vec::new();
    let _ = wasm_file.read_to_end(&mut wasm_file_buf).unwrap();
    // wasmファイル実行準備
    let store = Store::default();
    let module = Module::new(&store, &wasm_file_buf).unwrap();
    let import_object = imports! {};

    let instance = Instance::new(&module, &import_object).unwrap();
    let add = instance.exports.get_function("add").unwrap();
    // wasmの関数実行
    let response = add.call(&[Value::I32(1), Value::I32(2)]).unwrap();
    println!("1 + 2 = {}", response[0].to_string().parse::<i32>().unwrap());
}

wasm.wasmを読み込んでadd関数を取得。
それを呼び出して結果を取得している。

PS wasm_rt> cargo run
   Compiling wasm_rt v0.1.0 (wasm_rt)
    Finished dev [unoptimized + debuginfo] target(s) in 5.60s
     Running `target\debug\wasm_rt.exe`
1 + 2 = 3

cargo runでビルドしてcargo runしたら、無事に実行できた。

おまけ: 今回からプログラムのシンタックスハイライトに APH Prism Syntax Highlighterを導入してみた。
少し書くのが面倒だけど、対応言語が多いからこっち優先にしようと思う。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください