Comment on page
位元格式
大家也許會很好奇,用 wat2wasm 把文字轉成 wasm 檔的時候,跑出一大堆數字的部份是代表什麼意思?其實那就是轉換之後檔案裡實際的內容,也就是我們接下來要介紹的位元格式
雖然整數通常會有固定長度,像是 8, 16, 32, 64 bits,但是以 32 bits 來說,實際上常常不需要用到 32 bits 來表示。為了精減大小,WebAssembly 在位元格式上常常會使用 LEB128 格式來表示整數。

每個 byte 只用 7 bits 表示數值,剩下的 1 bit 表示是否結束
如果長度不夠,照有號/無號整數的方式補足長度,得到有號/無號整數的數值
- 負數
- 正數
以 32 位元整數來說,最多用到 5 個 byte,如果全都是 1 開頭的話表示錯誤;64 位元整數最多 10 個,16 位元最多 3 個,也是用這種方法檢查錯誤
雖然在數值接近最大值的時候,是用更多位元表示相同的數,不過大部分的狀況數值不會那麼大,所以用 LEB128 可以有效的降低檔案大小
型別 | 數值 |
i32 | 0x7f |
i64 | 0x7e |
f32 | 0x7d |
f64 | 0x7c |
接下來講解模組中各部份的位元格式,大家可以對照 wat2wasm 的輸出結果做印證
這部份固定佔 8 bytes,大部分的位元格式中幾乎都會有前文,用來區別不同的位元格式
- 魔術數字 (Magic number) 4 bytes
- 0x00 0x61 0x73 0x6d,用字碼轉換成文字之後就是 "\0asm",表示這是 wasm 格式
- 版本 (Version) 4 bytes
- 0x01 0x00 0x00 0x00,表示這是 0x01 版的 WebAssembly,在之前也有 0x0a, 0x0b, 0x0c, 0x0d的先行版本,之後如果推出新版的 WebAssembly,這邊就會變動
每個部份在依開始都會有個標頭 (header),標示各個部份的代碼還有長度
- 代碼 (Section code)用來區分是哪個部份
英文名稱 | 代碼 |
Type | 1 |
Import | 2 |
Function | 3 |
Table | 4 |
Memory | 5 |
Global | 6 |
Export | 7 |
Start | 8 |
Element | 9 |
Code | 10 |
Data | 11 |
- 長度 (Section size)用一個 LEB128 32 位元無號整數,表示整個部份的長度 (不包括標頭)在 wat2wasm 的輸出裡會看到這邊是 section size (guess),既然是guess,表示這的值是亂猜的,不用理會,也不會被編進檔案裡真正的值在下面 FIXUP section size 的地方,在編進檔案的時候也是這個真正值會被寫到section size (guess)的位置上
- 數量 (num types)
- 用一個 LEB128 32 位元無號整數,表示總共有多少函式型別
- 函式型別
欄位 | 數值或格式 | 補充說明 |
格式 | 0x60 (func) | 表示這是函數 |
參數總數 | LEB128 32 位元無號整數 | |
參數型別 | 數值型別格式 | 可能沒有,也可能有多個 |
回傳值總數 | LEB128 32 位元無號整數 | 目前只會是 0 或 1 |
回傳值型別 | 數值型別格式 | 0 ~ 1 個 |
- 數量 (num imports)
- 用一個 LEB128 32 位元無號整數,表示總共有多少引入物件
- 引入物件:
欄位 | 數值或格式 | 補充說明 |
字串長度 | LEB128 32 位元無號整數 | 模組名稱的字串長度 |
模 組名稱 | 字串 | 以字碼表示 |
字串長度 | LEB128 32 位元無號整數 | 輸出名稱的字串長度 |
輸出名稱 | 字串 | 以字碼表示 |
引入種類 | 8 位元無號整數 | 0: 函式, 1:函式表, 2:記憶體, 3:全域變數 |
在引入物件中,接下來的部份會依據不同的引入種類,而有不同的格式:
- 函式
- 一個 LEB128 32 位元無號整數,表示函式型別的編號
- 函式表
欄位 | 數值或格式 | 補充說明 |
元素型別 | 0x70 (anyfunc) | 目前函式表只支援這個型別 |
標記 | 0 或 1 | 0:沒有最大值, 1:有最大值 |
起始大小 | LEB128 32 位元無號整數 | |
最大值 | LEB128 32 位元無號整數 | 有最大值才有 |
- 記憶體
欄位 | 數值或格式 | 補充說明 |
標記 | 0 或 1 | 0:沒有最大值, 1:有最大值 |
起始大小 | LEB128 32 位元無號整數 | 以 page 為單位 |
最大值 | LEB128 32 位元無號整數 | 有最大值才有 |
- 全域變數
欄位 | 數值或格式 | 補充說明 |
數值型別 | 數值型別格式 | |
可變動性 | 0 或 1 | 0:不可變動, 1:可變動 |
- 數量 (num functions)
- 用一個 LEB128 32 位元無號整數,表示總共有多少函式
- 編號
- 一個或多個 LEB128 32 位元無號整數,表示該函式使用的函式型別編號
- 數量 (num tables)
- 用一個 LEB128 32 位元無號整數,表示總共有多少函式表 (目前只會是 1)
- 函式表
欄位 | 數值或格式 | 補充說明 |
元素型別 | 0x70 (anyfunc) | 目前函式表只支援這個型別 |
標記 | 0 或 1 | 0:沒有最大值, 1:有最大值 |
起始大小 | LEB128 32 位元無號整數 | |
最大值 | LEB128 32 位元無號整數 | 有最大值才有 |