目錄

WasmEdge 0.16.1 版本 C API 簡單看過

正文

參考 C API 0.16.1 Documentation

WebAssembly 是一個開放標準,所以有很多不同的團隊開發了各自的 Runtime(執行環境),它們就像是瀏覽器界的 Chrome、Firefox 和 Safari。

目前主流的非瀏覽器 Runtime 包括:

  • Wasmtime: 由 Bytecode Alliance(字節碼聯盟,成員包括 Fastly, Intel, Mozilla 等)開發,非常強調安全性與標準符合
  • Wasmer: 標榜「能在任何地方執行」,且支援多種不同的編譯後端(LLVM, Cranelift, Singlepass)
  • WAMR (WebAssembly Micro Runtime): 由 Intel 開發,專門為資源極其有限的物聯網(IoT)或嵌入式設備設計,體積非常小
  • Bun / Node.js: 它們內部也都有整合 WASM 引擎(如 V8),讓你在 JS 環境中跑 WASM

所有的 WebAssembly Runtime 都必須遵守 W3C WebAssembly Specification。這份規範定義了執行 WASM 的四個標準階段。

Configuration

Config 會有不同的設定像是

  • BulkMemoryOperations: 批次記憶體操作
  • SIMD: 單指令流多資料流(加速運算,如影像處理)
  • MultiMemories: 支援一個模組有多個記憶體區塊
  • Threads: 支援多線程
WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate();

在 WasmEdge 中,大部分的物件(如 Loader、Validator、Executor)在建立時,都可以傳入這個 ConfigureContext 來決定不同設定。

VM

如果你不使用 VM,你得手動建立 Loader(讀取檔案)、Validator(檢查正確性)和 Executor(執行)。但有了 VM,你只需要把 Configuration 丟進去,它內部會自動幫你準備好這一切。

文件有幾個用 VM 的例子:

  • WasmEdge_VMRunWasmFromFile 主要用這個 API 執行,他就是一次性包含載入、驗證、實例化、執行,缺點是只能執行一次
  • 第二種是你真的一個一個執行,先 Load -> Validate -> Instantiate -> Execute,優點是可以執行很多次
    • WasmEdge_VMLoadWasmFromFile: Load
    • WasmEdge_VMValidate: Validate
    • WasmEdge_VMInstantiate: Instantiate
    • WasmEdge_VMExecute: Execute

/0-16-api/image.png

你甚至可以 VM 客製化:

// 1. 準備工具
WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate();
WasmEdge_StoreContext *StoreCxt = WasmEdge_StoreCreate();

// 2. 組裝 VM (把工具裝進去)
WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(ConfCxt, StoreCxt);

// 3. 獲取效能數據 (這只是個「觀察窗」,所有權還是在 VM 身上)
WasmEdge_StatisticsContext *StatCxt = WasmEdge_VMGetStatisticsContext(VMCxt);

// 4. 清理現場 (順序很重要)
WasmEdge_VMDelete(VMCxt);         // 先刪 VM
WasmEdge_StoreDelete(StoreCxt);     // 再刪你當初借給它的 Store
WasmEdge_ConfigureDelete(ConfCxt); // 最後刪配置

Built-in Module

WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate();
// 關鍵 API:增加主機註冊項目
WasmEdge_ConfigureAddHostRegistration(ConfCxt, WasmEdge_HostRegistration_Wasi);

如上可以直接設定,你不需要另外下載檔案,這些功能已經寫在 WasmEdge 的核心裡了,你只需要在建立 VM 前「打勾」說你要用就好。

註冊模組

// 1. 建立一個空的 VM
WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(NULL, NULL);

// 2. 手動建立一個 WASI 模組實例 (這只是一個範例,也可以是你自定義的模組)
WasmEdge_ModuleInstanceContext *WasiModule = WasmEdge_ModuleInstanceCreateWASI(...);

// 3. 重點:將模組註冊進 VM
WasmEdge_Result Res = WasmEdge_VMRegisterModuleFromImport(VMCxt, WasiModule);

// ... 執行 WASM ...

// 4. 清理現場:兩邊都要手動刪除
WasmEdge_VMDelete(VMCxt);
WasmEdge_ModuleInstanceDelete(WasiModule); // 這一行不能漏掉!

如上,用 WasmEdge_VMRegisterModuleFromImport 將模組註冊進 VM。


你也可以使用不同函式註冊模組:

  • WasmEdge_VMRegisterModuleFromFile(從檔案)
  • WasmEdge_VMRegisterModuleFromBytes(從記憶體)
  • WasmEdge_VMRegisterModuleFromASTModule(從編譯後的 AST 物件)

使用 WasmEdge_VMExecuteRegistered 指定「模組名 + 函式名」來執行函式。

Asynchronous Execution

之前的 Execute 函式都是 Blocking 的,WasmEdge 也提供 Async 的執行,當你發起非同步執行時,API 會立即回傳一個 WasmEdge_Async 指標。

拿到他你可以:

  1. WasmEdge_AsyncWait
  2. WasmEdge_AsyncWaitFor
  3. WasmEdge_AsyncCancel
  4. WasmEdge_AsyncGetReturns

獲得 VM 的模組

  1. WasmEdge_VMGetRegisteredModule: 根據名稱拿到模組
  2. WasmEdge_VMGetActiveModule: 只拿到正在跑的 Active Module

Runtime

可以參考文件他有一個例子完全使用自己的東西跑 WASM - WASM Execution Example Step-By-Step

Loader

它是把二進位檔案(.wasm)翻譯成 WasmEdge 內部看得懂的數據結構(叫做 AST Module)。

常見 API 像是 WasmEdge_LoaderParseFromFileWasmEdge_LoaderParseFromBytes

Validator

Validator 讓 WASM 可以在不需要作業系統層級防護(如進程隔離)的情況下,保證執行過程是 100% 安全的。

Executor

真正會動到 CPU 指令、處理運算邏輯、並管理呼叫棧(Call Stack)的地方。

AST Module

它是 WASM 二進位碼在記憶體中的結構化表現。它還不是一個「活的」程式,只是一份詳盡的說明書,紀錄了有哪些函式、哪些變數。

Serializer

這是 Loader 的反向操作,把記憶體中的 AST Module 重新轉回二進位的 .wasm 格式,如果你對 WASM 進行了 AOT(Ahead-of-Time)編譯優化,你可以用 Serializer 把優化後的結果存成檔案,下次讀取就極快。

Store

Store 是 WasmEdge 的運行時數據庫。它紀錄了所有已經實例化(Instantiated)的物件。

並且紀錄模組資訊,像是:

  • Module Instances:已經跑起來的模組
  • Global Variables:現在這些全域變數的值是多少
  • Memory:目前的記憶體數據
  • Tables:函式索引表

Instance

介紹 WASM 的五大基本元件在運行時的 Context:

  • Module Instance:整個模組的運行實體
  • Function Instance:一個可以被呼叫的函式
  • Table / Memory / Global Instance:運行中的表格、記憶體、全域變數

Host Functions (主機函式)

教你如何定義一個 C 函式,並把它包裝成 WASM 看得懂的 WasmEdge_FunctionInstance

當 WASM 呼叫你的 C 函式時,會傳入一個 CallingFrameContext,透過這個「框架」,你的 C 函式可以反過來去讀取 WASM 的記憶體,WASM 傳一個記憶體地址給你,你的 C 函式透過 Calling Frame 找到那塊地址,把字串印出來。

WasmEdge 內部已經實現了一套標準的 Host Functions (Built-in Modules)。當你在 Rust 或 C 編譯 WASM 時,只要使用了 printf 或 println!,編譯器就會自動把它連結到 WASM 的 import “wasi_snapshot_preview1” 裡。

Plug-ins (插件)

如果你想讓你的 WasmEdge 支援 TensorFlow、OpenCV 或 HTTPS,但你不想自己動手寫一堆 Host Functions,這就是為你準備的。

  • 你把插件檔案放到特定的資料夾
  • 程式啟動時呼叫 WasmEdge_PluginLoadWithDefaultPaths()
  • WasmEdge 會自動掃描並載入這些功能

你可以直接使用官方提供的 wasmedge_rustls(網路)、wasmedge_process(系統指令)或 wasmedge_nn(AI 推理)插件。