WASM 文本格式有結構嗎?
(module
(type (; can a type be a `struct` like in C or rust? ;) )
(; rest of module ;)
)
我已經使用這個 WasmExplorer 工具將以下 c 編譯為 wasm
struct MyStruct {
int MyField;
long MyOtherField;
};
MyStruct returnMyStruct(int myField){
return MyStruct {
MyField: myField,
MyOtherField: myField * 2
};
}
它輸出以下內容,但我無法理解 WASM 在做什么。
(module
(table 0 anyfunc)
(memory $0 1)
(export "memory" (memory $0))
(export "_Z14returnMyStructi" (func $_Z14returnMyStructi))
(func $_Z14returnMyStructi (; 0 ;) (param $0 i32) (param $1 i32)
(i32.store
(get_local $0)
(get_local $1)
)
(i32.store offset=4
(get_local $0)
(i32.shl
(get_local $1)
(i32.const 1)
)
)
)
)
生成的函式沒有回傳型別,它使用i32.store
和i32.shl
以及偏移量。它是否將結構存盤在記憶體中的某處?
將非常感謝解釋如何以及為什么會這樣。
uj5u.com熱心網友回復:
WASM 文本格式有結構嗎?
它不是。與其他低級匯編語言一樣,wasm 只有少數整數資料型別,并將記憶體視為一大塊位元組。這是一種簡化,但是當像 C 這樣的高級語言被編譯為匯編語言時,結構變數會在記憶體中分配一個位置,每個欄位位于不同的地址。當您寫入欄位時,它:
- 獲取結構體變數的地址
- 添加欄位與結構根的偏移量
- 寫入結果地址
生成的函式沒有回傳型別,它使用 i32.store 和 i32.shl 以及偏移量。它是否將結構存盤在記憶體中的某處?
您觀察到的是 C 特性,回傳值優化 (RVO)。從 C 11 開始就需要編譯器來避免制作從函式回傳的 PR 值結構(例如臨時運算式)的額外副本。雖然標準沒有規定如何做到這一點,但許多編譯器通過將回傳值轉換為輸出引數來實作這一點,例如:
MyStruct myFunc(int);
MyStruct myStruct;
myStruct = myFunc(42);
轉換為:
void myFunc(MyStruct&, int);
MyStruct myStruct;
myFunc(myStruct, 42);
現在再看一下函式簽名:
(func $_Z14returnMyStructi (; 0 ;) (param $0 i32) (param $1 i32)
有兩個引數:
$0
是一個 MyStruct 的地址,回傳值將被寫入其中$1
是myField
。
所以這個指令:
(i32.store
(get_local $0)
(get_local $1)
)
寫入myField
輸出地址。在這種情況下,MyField
成員MyStruct
位于偏移量零處,并且正在被寫入。
這條指令:
(i32.store offset=4
(get_local $0)
(i32.shl
(get_local $1)
(i32.const 1)
)
)
i32.shl
移myField
向左1位,由兩個有效相乘。結果寫入輸出地址后 4 個位元組的地址。由于MyOtherField
從 的根開始布置 4 個位元組MyStruct
,因此這是寫入MyOtherField
.
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/387772.html
上一篇:Union的默認建構式被隱式洗掉