以 WASM 文本格式实现一个结构
Implement a struct in WASM text format
WASM 文本格式有结构吗?
(module
(type (; can a type be a `struct` like in C or rust? ;) )
(; rest of module ;)
)
将以下 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 [=12=] 1)
(export "memory" (memory [=12=]))
(export "_Z14returnMyStructi" (func $_Z14returnMyStructi))
(func $_Z14returnMyStructi (; 0 ;) (param [=12=] i32) (param i32)
(i32.store
(get_local [=12=])
(get_local )
)
(i32.store offset=4
(get_local [=12=])
(i32.shl
(get_local )
(i32.const 1)
)
)
)
)
生成的函数没有 return 类型,它使用 i32.store
和 i32.shl
以及偏移量。它是否将结构存储在内存中的某个地方?
如能解释其工作原理和原因,我们将不胜感激。
Does WASM text format have structs?
没有。与其他低级汇编语言一样,wasm 只有少数整数数据类型,并将内存视为一大块字节。这是一种简化,但是当像 C 这样的高级语言被编译为汇编时,结构变量会在内存中分配一个位置,每个字段都位于不同的地址。当您写入字段时,它:
- 取结构变量的地址
- 添加字段相对于结构根的偏移量
- 写入结果地址
The function generated does not have a return type, it uses i32.store and i32.shl along with an offset. Is it storing the struct in memory somewhere?
您观察到的是一个 C++ 特性,Return Value Optmization (RVO)。自 C++11 以来,编译器是必需的,以避免从函数中获取 returned 的 PR 值结构(例如临时表达式)的额外副本。虽然标准没有规定 如何 做到这一点,但许多编译器通过将 return 值转换为输出参数来实现这一点,例如这个:
MyStruct myFunc(int);
MyStruct myStruct;
myStruct = myFunc(42);
转换为:
void myFunc(MyStruct&, int);
MyStruct myStruct;
myFunc(myStruct, 42);
现在再看看函数签名:
(func $_Z14returnMyStructi (; 0 ;) (param [=12=] i32) (param i32)
有两个参数:
[=15=]
是一个MyStruct的地址,return值会写入
</code> 是 <code>myField
.
所以这条指令:
(i32.store
(get_local [=13=])
(get_local )
)
将 myField
写入输出地址。在这种情况下,MyStruct
的 MyField
成员位于偏移量零处,并且正在写入。
这条指令:
(i32.store offset=4
(get_local [=14=])
(i32.shl
(get_local )
(i32.const 1)
)
)
i32.shl
将 myField
左移 1 位,有效地乘以 2。结果写入输出地址后 4 个字节的地址。由于 MyOtherField
从 MyStruct
的根开始布局 4 个字节,这是写入 MyOtherField
.
WASM 文本格式有结构吗?
(module
(type (; can a type be a `struct` like in C or rust? ;) )
(; rest of module ;)
)
将以下 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 [=12=] 1)
(export "memory" (memory [=12=]))
(export "_Z14returnMyStructi" (func $_Z14returnMyStructi))
(func $_Z14returnMyStructi (; 0 ;) (param [=12=] i32) (param i32)
(i32.store
(get_local [=12=])
(get_local )
)
(i32.store offset=4
(get_local [=12=])
(i32.shl
(get_local )
(i32.const 1)
)
)
)
)
生成的函数没有 return 类型,它使用 i32.store
和 i32.shl
以及偏移量。它是否将结构存储在内存中的某个地方?
如能解释其工作原理和原因,我们将不胜感激。
Does WASM text format have structs?
没有。与其他低级汇编语言一样,wasm 只有少数整数数据类型,并将内存视为一大块字节。这是一种简化,但是当像 C 这样的高级语言被编译为汇编时,结构变量会在内存中分配一个位置,每个字段都位于不同的地址。当您写入字段时,它:
- 取结构变量的地址
- 添加字段相对于结构根的偏移量
- 写入结果地址
The function generated does not have a return type, it uses i32.store and i32.shl along with an offset. Is it storing the struct in memory somewhere?
您观察到的是一个 C++ 特性,Return Value Optmization (RVO)。自 C++11 以来,编译器是必需的,以避免从函数中获取 returned 的 PR 值结构(例如临时表达式)的额外副本。虽然标准没有规定 如何 做到这一点,但许多编译器通过将 return 值转换为输出参数来实现这一点,例如这个:
MyStruct myFunc(int);
MyStruct myStruct;
myStruct = myFunc(42);
转换为:
void myFunc(MyStruct&, int);
MyStruct myStruct;
myFunc(myStruct, 42);
现在再看看函数签名:
(func $_Z14returnMyStructi (; 0 ;) (param [=12=] i32) (param i32)
有两个参数:
[=15=]
是一个MyStruct的地址,return值会写入</code> 是 <code>myField
.
所以这条指令:
(i32.store
(get_local [=13=])
(get_local )
)
将 myField
写入输出地址。在这种情况下,MyStruct
的 MyField
成员位于偏移量零处,并且正在写入。
这条指令:
(i32.store offset=4
(get_local [=14=])
(i32.shl
(get_local )
(i32.const 1)
)
)
i32.shl
将 myField
左移 1 位,有效地乘以 2。结果写入输出地址后 4 个字节的地址。由于 MyOtherField
从 MyStruct
的根开始布局 4 个字节,这是写入 MyOtherField
.