San*_*ale 1 c++ llvm clang llvm-c++-api webassembly
情况:我目前在 LLVM IR 中解析前端语言并生成函数定义。
我可以使用 LLVM12 C++ API 将函数定义编译为 WebAssembly 文件。
但是,生成的 wasm 代码不会“导出”任何已编译的函数,因此无法从加载 wasm 文件的 javascript 访问。
问题:有人可以让我知道我可能遗漏了什么吗?如何告诉 llvm 编译器为定义的函数创建导出。我尝试将函数可见性设置为 llvm::GlobalValue::DefaultVisibility。但这似乎没有帮助。
为函数生成的 IR(具有默认可见性)看起来像
define double @f(double %x) #0 {
entry:
%multmp = fmul double %x, 2.000000e+00
ret double %multmp
}
attributes #0 = { "target-features" }
Run Code Online (Sandbox Code Playgroud)
将包含函数定义的模块编译到 Wasm 目标的函数如下所示:
define double @f(double %x) #0 {
entry:
%multmp = fmul double %x, 2.000000e+00
ret double %multmp
}
attributes #0 = { "target-features" }
Run Code Online (Sandbox Code Playgroud)
这会输出一个看起来像的 wasm 文件
(module
(type $t0 (func (param f64) (result f64)))
(import "env" "__linear_memory" (memory $env.__linear_memory 0))
(import "env" "__indirect_function_table" (table $env.__indirect_function_table 0 funcref))
(func $f0 (type $t0) (param $p0 f64) (result f64)
local.get $p0
local.get $p0
f64.add))
Run Code Online (Sandbox Code Playgroud)
但是,这个生成的文件有问题。它没有添加“export”语句来使函数 f0 对外界可见,这将允许加载 wasm 模块的 javascript 调用函数 f0。理想情况下,生成的文件应该有函数定义行看起来像
func $f0 (export "f") (type $t0) (param $p0 f64) (result f64)
local.get $p0
local.get $p0
f64.add))
Run Code Online (Sandbox Code Playgroud)
这样加载 javascript 就可以访问一个名为“f”的函数,它可以从 wasm 调用。
有没有办法向 LLVM C++ API 指定应该导出函数?
您可以通过设置wasm-export-name和wasm-export-name属性来触发给定符号的导出。
在 C/C++ 中,这些对应于export_name和export_moduleclang 属性。
有关llvm/test/CodeGen/WebAssembly/export-name.ll此示例,请参见llvm 树。
您还可以要求链接器使用--export命令行标志导出给定符号。请参阅https://lld.llvm.org/WebAssembly.html#exports。