函式
函式是一段執行特定功能的指令集合,WebAssembly 的函式可以傳入若干個數值當作區域變數、定義屬於函式自己的區域變數,以及在結束時傳回一個數值。尤其在瀏覽器上更是 WebAssembly 和網頁的 JavaScript 程式碼互動的重要角色
函式的運作機制和 block 差不多,會在堆疊裡放進一個框架 (Frame),這個 frame 會記錄目前在哪個模組,以及函式的區域變數。同樣的,frame 會像遮罩一樣把先前的數值和 label 遮住,讓函式裏面的指令看不到先前的數值和 label,等到函式結束的時候再把 frame 取出,回到先前的狀態
函式執行的時候自帶一個 block,所以也會有和 block 差不多的行為,結束時一樣要把堆疊清空,或是在有指定回傳值的情況下剩下一個相對應的回傳值

宣告函式

函式的宣告非常簡單,像全域變數和記憶體一樣宣告在模組裡,裏面放入要在函式裡執行的指令
1
(module
2
(func
3
i32.const 3
4
drop
5
)
6
(start 0)
7
)
Copied!
可以幫函式加上名稱,像之前的範例就有幫函式加上 $main
1
(module
2
(func $main
3
i32.const 3
4
drop
5
)
6
(start $main)
7
)
Copied!
函式和全域變數一樣會有一個從 0 開始的編號,因此在 module 裡從上到下分別是 0, 1, 2 ...,之後呼叫函式的時候也是用編號來區分

呼叫函式

  • call
    • 後面接編號。呼叫之後會執行被呼叫的函式,直到被呼叫的函式返回之後,才會繼續執行接下來的指令
1
(module
2
(func
3
i32.const 2
4
unreachable
5
)
6
(func $main
7
call 0
8
i32.const 3
9
unreachable
10
)
11
(start $main)
12
)
Copied!

參數 (Parameter)

如果要傳遞一些數值到函式裡,可以用 param 加上參數,參數會被當作函式的區域變數
有寫在 start 裡的函式不能加參數,在模組章節會有詳細說明
1
(module
2
(func $aaa (param i32 f32 i32)
3
get_local 0
4
get_local 2
5
i32.add
6
get_local 1
7
unreachable
8
)
9
(func $main
10
i32.const 5
11
f32.const 3.14
12
i32.const 8
13
call $aaa
14
i32.const 3
15
unreachable
16
)
17
(start $main)
18
)
Copied!
執行結果
1
Values in the stack:
2
Type: f32, Value: 3.14
3
Type: i32, Value: 13
4
Values in the stack:
5
Type: i32, Value: 3
Copied!
和區域變數一樣,可以幫參數加上名稱,不過也是一樣要分開寫
1
(module
2
(func $aaa (param $a i32) (param f32) (param $b i32)
3
get_local $a
4
get_local $b
5
i32.add
6
get_local 1
7
unreachable
8
)
9
(func $main
10
i32.const 5
11
f32.const 3.14
12
i32.const 8
13
call $aaa
14
i32.const 3
15
unreachable
16
)
17
(start $main)
18
)
Copied!
同時使用 param 和 local 時,local 必須在 param 之後,當然區域變數的編號也會排在 param 的後面
1
(module
2
(func $aaa (param $a i32) (local $b i32)
3
get_local $a
4
i32.const 8
5
set_local 1
6
get_local $b
7
i32.add
8
unreachable
9
)
10
(func $main
11
i32.const 5
12
call $aaa
13
i32.const 3
14
unreachable
15
)
16
(start $main)
17
)
Copied!

回傳值 (Return value)

如果要在函式結束時傳遞數值給上一層函式,可以用 result 加上一個回傳值。這樣在函式結束的時候會從堆疊拿出一個對應的數值,在回到上一層函數時放回堆疊裡
有寫在 start 裡的函式不能加回傳值,在模組章節會有詳細說明
1
(module
2
(func $add (param $a i32) (param $b i32) (result i32)
3
get_local $a
4
get_local $b
5
i32.add
6
)
7
(func $main
8
i32.const 5
9
i32.const 4
10
call $add
11
unreachable
12
)
13
(start $main)
14
)
Copied!
執行結果
1
Values in the stack:
2
Type: i32, Value: 9
Copied!
使用 param、result 和 local 時,必須按照 param
\rightarrow
result
\rightarrow
local 的順序排列
Last modified 3yr ago