指向本地结构的指针如何被翻译成 webassembly?
How do pointer to local structures get translated to webassembly?
不幸的是,我无法获得一个有效的工具链来将 C/C++ 编译成 wasm 文件,但我希望好心人可以帮助我。给定程序片段:
struct foo {
int a;
float b;
};
void function(foo * p);
void my_program() {
struct foo my_foo;
my_foo.a = 1;
my_foo.b = -3.0F;
foo(&my_foo);
}
my_program
的 wasm 代码是什么样的?
我假设你的意思是浪费的文本格式是什么样的?
我在你的代码中做了一些调整,以便它可以编译:
struct foo {
int a;
float b;
};
extern void bar(struct foo * p);
void my_program() {
struct foo my_foo;
my_foo.a = 1;
my_foo.b = -3.0F;
bar(&my_foo);
}
使用 emscripten/binaryen 编译它,然后使用 wasm2wast:
emcc -s WASM=1 -s SIDE_MODULE=1 -O2 str.c -o str.js
wasm-dis str.wasm -o str.wast
请注意,如果没有 -s SIDE_MODULE=1 -O2
,emscripten 会引入一堆标准库(malloc 等),而垃圾文件有 10,000 行长。我假设您可能只想要相当简单的 wasm/wast 结果,而不需要所有 linkages/inclusions.
这导致以下垃圾文件:
(module
(type [=12=] (func (param i32)))
(type (func))
(import "env" "memoryBase" (global $import[=12=] i32))
(import "env" "_bar" (func $import (param i32)))
(import "env" "memory" (memory [=12=] 256))
(import "env" "table" (table 0 anyfunc))
(import "env" "tableBase" (global $import i32))
(global $global[=12=] (mut i32) (i32.const 0))
(global $global (mut i32) (i32.const 0))
(export "_my_program" (func [=12=]))
(export "__post_instantiate" (func ))
(export "runPostSets" (func ))
(func [=12=] (type )
(local $var[=12=] i32)
(local $var i32)
(block $label[=12=]
(set_local $var[=12=]
(get_global $global[=12=])
)
(set_global $global[=12=]
(i32.add
(get_global $global[=12=])
(i32.const 16)
)
)
(i32.store
(tee_local $var
(get_local $var[=12=])
)
(i32.const 1)
)
(f32.store offset=4
(get_local $var)
(f32.const -3)
)
(call $import
(get_local $var)
)
(set_global $global[=12=]
(get_local $var[=12=])
)
)
)
(func (type )
(nop)
)
(func (type )
(block $label[=12=]
(set_global $global[=12=]
(get_global $import[=12=])
)
(set_global $global
(i32.add
(get_global $global[=12=])
(i32.const 5242880)
)
)
(call )
)
)
;; custom section "dylink", size 5
)
请注意,memoryBase
、tableBase
、__post_instantiate
和 runPostSets
是平台内存的 emscripten 添加 integration/initialization。 memoryBase
基本上是 C 堆栈的开始,值由 __post_instantiate
复制到 $global[=20=]
(对于该模块中的所有函数都是全局的)。当调用 my_program
时,首先发生的事情是我们将堆栈指针调整 16 以指向编译器在堆栈上为 my_foo 结构设置 "allocated" space 的位置。我们现在使用 offset=X
执行几个 i32.store
操作来更新 foo
中的字段。当函数 returns 我们将堆栈指针 ($global[=20=]
) 恢复到我们进入函数时的位置。
不幸的是,我无法获得一个有效的工具链来将 C/C++ 编译成 wasm 文件,但我希望好心人可以帮助我。给定程序片段:
struct foo {
int a;
float b;
};
void function(foo * p);
void my_program() {
struct foo my_foo;
my_foo.a = 1;
my_foo.b = -3.0F;
foo(&my_foo);
}
my_program
的 wasm 代码是什么样的?
我假设你的意思是浪费的文本格式是什么样的?
我在你的代码中做了一些调整,以便它可以编译:
struct foo {
int a;
float b;
};
extern void bar(struct foo * p);
void my_program() {
struct foo my_foo;
my_foo.a = 1;
my_foo.b = -3.0F;
bar(&my_foo);
}
使用 emscripten/binaryen 编译它,然后使用 wasm2wast:
emcc -s WASM=1 -s SIDE_MODULE=1 -O2 str.c -o str.js
wasm-dis str.wasm -o str.wast
请注意,如果没有 -s SIDE_MODULE=1 -O2
,emscripten 会引入一堆标准库(malloc 等),而垃圾文件有 10,000 行长。我假设您可能只想要相当简单的 wasm/wast 结果,而不需要所有 linkages/inclusions.
这导致以下垃圾文件:
(module
(type [=12=] (func (param i32)))
(type (func))
(import "env" "memoryBase" (global $import[=12=] i32))
(import "env" "_bar" (func $import (param i32)))
(import "env" "memory" (memory [=12=] 256))
(import "env" "table" (table 0 anyfunc))
(import "env" "tableBase" (global $import i32))
(global $global[=12=] (mut i32) (i32.const 0))
(global $global (mut i32) (i32.const 0))
(export "_my_program" (func [=12=]))
(export "__post_instantiate" (func ))
(export "runPostSets" (func ))
(func [=12=] (type )
(local $var[=12=] i32)
(local $var i32)
(block $label[=12=]
(set_local $var[=12=]
(get_global $global[=12=])
)
(set_global $global[=12=]
(i32.add
(get_global $global[=12=])
(i32.const 16)
)
)
(i32.store
(tee_local $var
(get_local $var[=12=])
)
(i32.const 1)
)
(f32.store offset=4
(get_local $var)
(f32.const -3)
)
(call $import
(get_local $var)
)
(set_global $global[=12=]
(get_local $var[=12=])
)
)
)
(func (type )
(nop)
)
(func (type )
(block $label[=12=]
(set_global $global[=12=]
(get_global $import[=12=])
)
(set_global $global
(i32.add
(get_global $global[=12=])
(i32.const 5242880)
)
)
(call )
)
)
;; custom section "dylink", size 5
)
请注意,memoryBase
、tableBase
、__post_instantiate
和 runPostSets
是平台内存的 emscripten 添加 integration/initialization。 memoryBase
基本上是 C 堆栈的开始,值由 __post_instantiate
复制到 $global[=20=]
(对于该模块中的所有函数都是全局的)。当调用 my_program
时,首先发生的事情是我们将堆栈指针调整 16 以指向编译器在堆栈上为 my_foo 结构设置 "allocated" space 的位置。我们现在使用 offset=X
执行几个 i32.store
操作来更新 foo
中的字段。当函数 returns 我们将堆栈指针 ($global[=20=]
) 恢复到我们进入函数时的位置。