WebAssembly というのは、WebAP のフロントエンド開発において高速さと堅牢さを実現するために生み出された技術です。
これを利用して、WebAP 以外でも WebAssembly を利用してポータビリティを向上させるための技術が WASI (WebAssembly System Interface) です。
WASI の参照実装として wasmtime が公開されています。
wasmtime を用いて、Python から WebAssembly のメソッドを呼び出します。
動作環境
- Windows 11
- WSL Ubuntu 20.04
- Python 3.10.6
- wasmtime 11.0.0
事前準備
事前準備として、各種パッケージをインストールします。
Ubuntu パッケージ更新
$ sudo apt update
$ sudo apt upgrade
pip をインストール
$ sudo apt install python3-pip
wasmtime のインストール
$ pip install wasmtime
WebAssembly サンプルコード
今回使用する WebAssembly のサンプルコードです。sample.wat
のファイル名で保存しておきます。
wat
は、WebAssembly のテキストフォーマットに対する拡張子です。
バイトコードフォーマットの拡張子は wasm
になります。
(module
(func (export "add_int")
(param $value_1 i32) (param $value_2 i32)
(result i32)
local.get $value_1
local.get $value_2
i32.add
)
)
2つの整数を足し合わせる add_int メソッドを定義しています。
3行目の param
句が引数を定義しています。
4行目の result
で戻り値の型を指定しています。
5~6行目の local.get
では、それぞれの引数の値をスタックに積んでいます。
7行目の i32.add
でスタックから整数を2つポップして足し算し、この結果を再度スタックに積んでいます。
最終的にスタックに残った整数値が result として返却されます。
Python から WebAssembly 呼び出し
Python コードから wasmtime を利用して WebAssembly を呼び出すには、2つの手法があります。
- wasm ファイルを直接インポートする
- wasmtime API で wasm ファイルをロードする
特に弊害がなければ、前者の方がシンプルで直観的で良いと思います。
それぞれの手法を以下に紹介します。
① wasm ファイルを直接インポートする
wasmtime.loader をインポートすることで、wat
ファイル(または wasm
ファイル)を直接インポートすることができます。
import wasmtime.loader
import sample
print(sample.add_int(3, 5))
2行目で WebAssembly をインポートしています。
今回は sample.wat
としてファイルを保存しており、ここから拡張子を除いた sample
をインポートします。
メインのコードは4行目のみです。sample.add_int
を呼び出し、3 + 5 の演算をさせます。
$ python3 main_directly.py
8
② wasmtime API で wasm ファイルをロードする
次に wasmtime の API を利用したサンプルコードです。
カスタマイズが必要なケースでは、こちらの手法を用いることになります。
from wasmtime import Store, Module, Instance
store = Store()
module = Module.from_file(store.engine, "sample.wat")
instance = Instance(store, module, [])
add_int = instance.exports(store)["add_int"]
print(add_int(store, 3, 5))
実行結果はシンプルな呼び出し方法と同じです。
3 + 5 の結果が返却されます。
$ python3 main_api.py
8
コメント