4

我正在尝试在 WebAssembly 中执行计算阶乘的基本 C 代码,当我在 Google Chrome (57.0.2987.98)中加载 WASM 文件时,我得到了

CompileError:WebAssembly.compile():
Wasm 解码失败结果 = 预期的魔法字 00 61 73 6d,
找到 30 30 36 31 @+0`

C代码:

double fact(int i) {
  long long n = 1;
  for (;i > 0; i--) {
    n *= i;
  }
  return (double)n;
}

浪费:

(module
  (table 0 anyfunc)
  (memory $0 1)
  (export "memory" (memory $0))
  (export "_Z4facti" (func $_Z4facti))
  (func $_Z4facti (param $0 i32) (result f64)
    (local $1 i64)
    (local $2 i64)
    (block $label$0
      (br_if $label$0
        (i32.lt_s
          (get_local $0)
          (i32.const 1)
        )
      )
      (set_local $1
        (i64.add
          (i64.extend_s/i32
            (get_local $0)
          )
          (i64.const 1)
        )
      )
      (set_local $2
        (i64.const 1)
      )
      (loop $label$1
        (set_local $2
          (i64.mul
            (get_local $2)
            (tee_local $1
              (i64.add
                (get_local $1)
                (i64.const -1)
              )
            )
          )
        )
        (br_if $label$1
          (i64.gt_s
            (get_local $1)
            (i64.const 1)
          )
        )
      )
      (return
        (f64.convert_s/i64
          (get_local $2)
        )
      )
    )
    (f64.const 1)
  )
) 

WASM 编译代码:

0061 736d 0100 0000 0186 8080 8000 0160
017f 017c 0382 8080 8000 0100 0484 8080
8000 0170 0000 0583 8080 8000 0100 0106
8180 8080 0000 0795 8080 8000 0206 6d65
6d6f 7279 0200 085f 5a34 6661 6374 6900
000a c380 8080 0001 bd80 8080 0001 027e
0240 2000 4101 480d 0020 00ac 4201 7c21
0142 0121 0203 4020 0220 0142 7f7c 2201
7e21 0220 0142 0155 0d00 0b20 02b9 0f0b
4400 0000 0000 00f0 3f0b 
`

在 Chrome 中执行的代码:

 async function load(){
        let binary = await fetch('https://flinkhub.com/t.wasm');
        let bytes = await binary.arrayBuffer();
        console.log(bytes);

        let module = await WebAssembly.compile(bytes);
        let instance = await WebAssembly.Instance(module);
    }
    load().then(instance => console.log(instance.exports.fact(3)));

任何人都可以帮助我,我已经坚持了一整天,无法理解出了什么问题。我使用WebAssembly Explorer来获取 WAST 和 WASM 代码。

4

5 回答 5

6

使用您引用的WebAssembly Explorer的下载功能,我得到以下文件(如 hexdump 所示):

0000000 00 61 73 6d 01 00 00 00 01 86 80 80 80 00 01 60
0000010 01 7f 01 7c 03 82 80 80 80 00 01 00 04 84 80 80
0000020 80 00 01 70 00 00 05 83 80 80 80 00 01 00 01 06
0000030 81 80 80 80 00 00 07 95 80 80 80 00 02 06 6d 65
0000040 6d 6f 72 79 02 00 08 5f 5a 34 66 61 63 74 69 00
0000050 00 0a c3 80 80 80 00 01 bd 80 80 80 00 01 02 7e
0000060 02 40 20 00 41 01 48 0d 00 20 00 ac 42 01 7c 21
0000070 01 42 01 21 02 03 40 20 02 20 01 42 7f 7c 22 01
0000080 7e 21 02 20 01 42 01 55 0d 00 0b 20 02 b9 0f 0b
0000090 44 00 00 00 00 00 00 f0 3f 0b                  
000009a

这是一个以魔法aka.wasm开头的有效二进制文件。根据您收到的错误消息,您的文件开头无效。00 61 73 6d\0asm30 30 36 31

仔细检查.wasm您拥有的文件。

解码30 30 36 31为 ASCII 给出了0061这似乎是你的问题:你正在加载你的十六进制文件的文本版本。果然,您提供的 URL(https://flinkhub.com/t.wasm)包含以下内容(我没有 hexdump !它是 ASCII ):

0061 736d 0100 0000 0186 8080 8000 0160
017f 017c 0382 8080 8000 0100 0484 8080
8000 0170 0000 0583 8080 8000 0100 0106
8180 8080 0000 0795 8080 8000 0206 6d65
6d6f 7279 0200 085f 5a34 6661 6374 6900
000a c380 8080 0001 bd80 8080 0001 027e
0240 2000 4101 480d 0020 00ac 4201 7c21
0142 0121 0203 4020 0220 0142 7f7c 2201
7e21 0220 0142 0155 0d00 0b20 02b9 0f0b
4400 0000 0000 00f0 3f0b

我猜你覆盖了从资源管理器中保存的文件。

于 2017-03-13T18:01:12.253 回答
1

我不确定您的系统,但我正在使用 react 和 esbuild.wasm 在运行以下代码时出现错误。

const service = await esbuild.startService({
     worker: true,
     wasmURL: "/esbuild.wasm/esbuild.wasm"
 })

esbuild.wasm 与 node_module 一起位于我的公共文件夹中。

所以我更正了现在的网址, wasmURL: "https://unpkg.com/esbuild-wasm@0.8.27/esbuild.wasm"现在它正在工作。

于 2021-05-16T07:23:43.203 回答
0

我通过在生成 wasm 对象之前在 mac 的 zsh shell 中正确设置 GOARCH 和 GOOS 环境变量来解决这个问题。看起来 go 编译器无法识别这两个变量,除非您在父 shell 中将它们爆炸性地导出为全局变量。我只是导出了两个变量并运行编译器。

% export GOARCH=wasm
% export GOOS=js
% go build -o hello.wasm hello.go
于 2020-12-17T15:42:33.137 回答
0

30 30 36 31是字符串的十六进制转储,"0061"它是您的 wasm 二进制文件的十六进制转储的开始。您是否以某种方式获取了文本的 hexdump 而不是实际的二进制文件?

于 2017-03-13T19:45:38.207 回答
0

一般来说,这个错误意味着您的浏览器收到的不是二进制 .wasm 文件。这可能是由 Web 服务器生成的错误页面或相同的 .wasm 但以某种方式损坏。我建议打开浏览器的开发者工具,转到网络选项卡,刷新页面并查看 .wasm 资源请求和响应。

于 2017-06-07T18:49:07.477 回答