LLVM IR-> WebAssembly。装入浏览器的WASM返回空模块实例

问题描述 投票:0回答:1

我正在尝试生成有效的wasm文件,WebBrowser(Firefox)会正确理解该wasm文件,但是我不确定在这里做错了什么

这里是Main.ll文件

define i32 @main() {
  ret i32 42
}

然后我正在使用llc(Linux):

./ llc -mtriple = wasm32-未知-未知-O3 -filetype = obj main.ll -o main.o

然后我正在使用wasm-ld(Linux):

./ wasm-ld main.o -o main.wasm --no-entry -allow-undefined

然后将main.wasm复制到Windows,然后打开此本地文件页面:

|-- fille.html
|-- main.wasm

<div id="test">
</div>

<style>
    #test
    {
        border: 3px solid red;
        width: 100%;
        height: 100%;
    }
</style>

<script>
    fetch("main.wasm")
        .then(response => response.arrayBuffer())
        .then(bytes => WebAssembly.instantiate(bytes, {}))
        .then(results => {
          window.alert(results.instance.exports.main());
        });
</script>

但是

TypeError:results.instance.exports.main不是函数

怎么了?

这里的结果:

console.log(JSON.stringify(results));

{"module":{},"instance":{}}

版本:

./ llc --version

LLVM (http://llvm.org/):
LLVM version 10.0.0

./ wasm-ld --version

LLD 10.0.0
llvm webassembly
1个回答
0
投票

原因是您在链接期间没有导出任何符号。

您可能想查看the Exports section of wasm-ld docs了解详细信息,但这是他们对默认值的描述:

[构建可执行文件时,默认情况下仅导出入口点(the Exports section of wasm-ld docs)和带有_start标志的符号。

您有几个选择:

  1. WASM_SYMBOL_EXPORTED重命名为main-这将确保已导出_start,并且从环境中正确导入了其任何依赖项,而不是像现在一样完全从GCd导入。
  2. 使用_start标志调用wasm-ld-这将导出目标文件中的所有符号。通常不建议使用此选项,因为您可能会阻止进行有用的尺寸优化,并暴露出您本不想暴露的东西,但可能适合原型制作。
  3. --export-all调用wasm-ld-这将导出所有在IR级别标记为可见的符号。
  4. 例如,当调用--export-dynamic时明确列出符号wasm-ld

除了(1)之外,所有选项中还有一个需要注意的注意事项是,--export=main被以一种特殊的方式处理,并且使用您当前的代码,它将导致两个不同的符号:

  1. [main-一个自动生成的函数包装器,带有两个用于mainargc的参数,调用您的函数。
  2. [argv-您实际定义的功能的符号。

[为确保您不会遇到此问题,请按照选项1进行操作,然后将__original_main重命名为[W0],这是Wasm特定的入口点,不接受任何参数,或者更改main的签名功能正确,并像C中一样接受_startmain

希望这一切都能帮助您前进。

© www.soinside.com 2019 - 2024. All rights reserved.