使用 wavm 運行 wasi wasm 程序
wasi 介紹
WASI 是一個新的 API 體系, 由 Wasmtime 項目設計, 目的是爲 WASM 設計一套引擎無關 (engine-indepent), 面向非 Web 系統(non-Web system-oriented) 的 API 標準. 目前, WASI 核心 API(WASI Core)在做覆蓋文件, 網絡等等模塊的 API, 但這些實現都是剛剛開始實現, 離實用還是有很長路要走.
目前支持 wasi 的運行時有以下幾種:
-
wasmer
-
wasmtime
-
wavm
wavm 介紹
WAVM 是 WebAssembly 虛擬機,設計用於非 Web 應用程序。
特點
- 快速
WAVM 使用 LLVM 將 WebAssembly 代碼編譯爲具有接近本機性能的機器代碼。在某些情況下,它甚至可以勝過本機性能,這要歸功於它能夠生成針對運行代碼的確切 CPU 進行了調整的機器代碼。
WAVM 還利用虛擬內存和信號處理程序來執行 WebAssembly 的邊界檢查的內存訪問,其成本與本機的未經檢查的內存訪問相同。
- 安全
WAVM 阻止 WebAssembly 代碼訪問 WebAssembly 虛擬機 * 之外的狀態,或調用未與 WebAssembly 模塊明確鏈接的本機代碼。
安裝
對於 centos 可以使用官方預編譯 rpm 包進行安裝
yum install -y https://github.com/WAVM/WAVM/releases/download/nightly%2F2020-05-28/wavm-0.0.0-prerelease-linux.rpm
複製代碼
用法示例
clone 官方庫
git clone https://github.com/WAVM/WAVM
cd Examples
複製代碼
運行官方示例程序
wavm run helloworld.wast
wavm run zlib.wasm
wavm run trap.wast
wavm run echo.wast "Hello, world!"
wavm run helloworld.wast | wavm run tee.wast
wavm run --enable simd blake2b.wast
複製代碼
拆解 wasm 爲 wast
disassemble 通過 disassemble 可以將 wasm 拆解爲 wast 可讀格式
wavm disassemble zlib.wasm zlib.wast
複製代碼
設置 cache
WAVM_OBJECT_CACHE_DIR 環境變量爲 wavm 設置運行時緩存
export WAVM_OBJECT_CACHE_DIR=/path/to/existing/directory
wavm run huge.wasm # Slow
wavm run huge.wasm # Fast
複製代碼
使用 rust 實現 wasi 規範的 wasm 程序
查看 rust 支持的目標
通過執行
rustup target list
複製代碼
-
asmjs-unknown-emscripten 通過 emscripten 工具鏈編譯爲 asmjs,asmjs 也是爲了解決 js 性能問題
-
wasm32-unknown-unknown。此目標直接使用 llvm 後端編譯成 wasm。 它適合純 rust 代碼編譯,譬如你沒有 C 依賴的時候。 跟 emscripten 目標比起來,它默認就生成更加洗練的代碼, 而且也便於設置搭建。此處查看如何設置搭建.
-
wasm32-unknown-emscripten。此目標利用 emscripten 工具鏈編譯成 wasm。 當你具有 C 依賴的時候就得使用它了,包括 libc
-
wasm32-wasi wasi 規範的目標
創建 rust lib 項目
創建項目
cargo new --lib testwasi
複製代碼
項目配置
Cargo.toml 中 lib 的配置如下
[lib]
name = "testwasi"
path = "src/lib.rs"
crate-type =["cdylib"]
複製代碼
代碼實現
// # 直接把把名字作爲符號寫到目標文件中
#[no_mangle]
pub extern fn test(a: i32, b: i32) {
let z = a + b;
println!("The value of x is: {}", z);
}
複製代碼
編譯
.cargo/config 添加以下內容,制定編譯結果爲 wasi 格式
[build]
target = "wasm32-wasi"
複製代碼
執行cargo build
或執行cargo build --target=wasm32-wasi
使用 wavm 運行 rust 編譯的 wasm 程序
# wavm run --function=test --abi=wasi target/wasm32-wasi/debug/testwasi.wasm 1 2
The value of x is: 3
複製代碼
總結
wasm 雖然一開始是爲了解決 js 的性能問題,但是由於其高性能,跨平臺,衆多運行時支持,已經不侷限於 web 端,走向服務端,現在已經應用於 servicemesh、serverless 等方向, 個人認爲其可能成爲下一代的 container,相信其未來必定有更廣泛的應用場景。
歡迎關注微信公衆號:有點技術
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://xie.infoq.cn/article/c4753b42dde09a6940657e963