系統程式設計的前沿

WebAssembly(網頁組譯,Wasm)

/ WEB-uh-SEM-blee /

想像你希望同一個程式能在網頁上、在伺服器上、在使用者附近的小型邊緣裝置上都快速執行——而不必為每一種環境重新編譯,也不必信任它在你的機器上自由遊走。WebAssembly(幾乎總是簡稱 Wasm)就是一種把已編譯程式碼打包成單一可攜、低階格式的方式,任何符合規範的執行環境都能安全又快速地執行它。你用 C、C++、Rust 或其他語言撰寫,編譯成一個 .wasm 檔,那一個檔案就能在任何有 Wasm 執行環境的地方執行。

Wasm 是一種給簡單抽象堆疊機(stack machine)使用的二進位指令格式:它不像真實 CPU 那樣有暫存器,多數指令是在一個運算元堆疊上推入與彈出數值(例如 i32.const 2、i32.const 3、i32.add 會在堆疊上留下 5)。它既不是原始碼也不是最終機器碼——它是介於兩者之間的緊湊位元組碼(bytecode),設計成可被快速驗證,然後在執行前或執行時才編譯成主機真正的機器碼。它的設計固定了一小組值型別(32 與 64 位元整數與浮點數,外加參考),採用結構化的流程控制(區塊、迴圈與 if,而非任意跳躍),並刻意設計成執行環境能在執行任何一條指令之前就先證明模組格式正確。

它之所以重要,是因為它兼具接近原生的速度、強固的沙箱與真正的可攜性,這也是它為何從瀏覽器擴散到伺服器、外掛系統與無伺服器平台。不過要誠實面對它的邊界:Wasm 很快,但通常比完全原生的程式碼略慢;核心規範本身無法存取檔案、網路或執行緒——那些功能來自疊加在其上的介面(見 WASI);而「可攜」指的是在各個 Wasm 執行環境之間可攜,並不代表任何一個隨手的二進位檔就免費變成 Wasm。它在瀏覽器中已經成熟,在瀏覽器之外則正在快速成熟,但仍在演進中。

(func $add (param $a i32) (param $b i32) (result i32) local.get $a local.get $b i32.add) ;; 堆疊機的函式本體:推入 a、推入 b,i32.add 在運算元堆疊上留下總和

以文字形式(.wat)寫成的一個微小 Wasm 函式。這裡沒有暫存器;數值經由運算元堆疊流動,執行環境會把它編譯成真正的機器碼。

儘管名字裡有「web」與「assembly」,WebAssembly 既不是任何真實 CPU 的組合語言,也不綁定於網頁;它是給抽象堆疊機使用的可攜位元組碼。它本身碰不到檔案、通訊端或時鐘——那種能力是由主機透過匯入(imports)授予(或保留),而這正是讓沙箱有意義的關鍵。

又稱
Wasm網頁組合語言