如何在 WebAssembly 数据段中存储十六进制值(即原始字节)

How to Store Hex Values (i.e. Raw Bytes) in WebAssembly Data Segment

我遇到这种情况:

(module 
  (memory (import "js" "mem") 1)
  (data (i32.const 0) "\aa"))

fetch('index.wasm').then(function(response){
  return response.arrayBuffer()
}).then(function(bytes){
  return WebAssembly.instantiate(bytes, {
    js: {
      mem: memory
    }
  })
})

我正在尝试根据 docs 将 "raw bytes" 放入 WebAssembly 的数据段中。但是在浏览器中得到这个错误(没有得到 wat2wasm 的编译错误):

Uncaught (in promise) CompileError: AsyncCompile: Wasm decoding failed: expected section length @+37

我已经尝试过不同的变体,例如这个,它不会引发错误,但是当我记录输出时没有输出(我希望它说“0”或其他东西:

(data (i32.const 0) "[=12=]")

我尝试其他类似的东西:

(data (i32.const 0) "\a0")

但它给出了同样的错误。任何帮助将不胜感激。

作为进一步演示如何使用原始字节功能的示例,了解如何表示 123 这样的数字会很有帮助。当我序列化为 Uint8Array -> String in JavaScript:

时,我执行了以下操作并得到了奇怪的结果
(data (i32.const 0) "123")

所以想知道在十六进制代码方面应该是什么样子。 123 在十六进制中是 0x7B,所以可能:

(data (i32.const 0) "b")

不过我觉得需要是两个十六进制数,不然不太确定。无论如何,如果这太复杂或分散了问题第一部分的注意力,则无需解决。

我已经用您的示例进行了测试,它似乎在最新的 Chrome (67.0.3396.99) 和 FF (61.0.1) 中对我来说工作正常。

index.wat

(module
    (memory (import "js" "mem") 1)
    (data (i32.const 0) "\aa"))

然后我用 wat2wasm index.wat 生成了一个二进制文件,它匹配你在上面评论中提到的字节:

index.wasm

00 61 73 6D 01 00 00 00 02 0B 01 02 6A 73 03 6D 65 6D 02 00 01 0B 07 01 00 41 00 0B 01 AA

然后我通过一个简单的 HTML 页面加载了它:

index.wasm

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
    <script>

        fetch('index.wasm').then((response) => response.arrayBuffer())
        .then((bytes) => {

            const memory = new WebAssembly.Memory({
                initial:10,
                maximum:100
            });

            return WebAssembly.instantiate(bytes, {
                js: { mem: memory }
            });
        })
        .then(function (module) {

            console.log(module);
        })
        .catch((err) => {

            console.log(err);
        });
    </script>
</body>
</html>

控制台输出看起来正确,因为它正确解析并加载了 WebAssembly 模块:

控制台截图

关于你问题的第二部分,你可以使用你所说的表达式在内存中对 123 进行编码 "b"。这是一个例子:

index.wat

(module
    (memory (import "js" "mem") 1)
    (data (i32.const 0) "b"))

如果我们在 JS 中注销内存中的第一个索引,我们可以看到它是 123:

index.html

const memory = new WebAssembly.Memory({
    initial:1,
    maximum:1
});

fetch('index.wasm').then((response) => response.arrayBuffer())
.then((bytes) => {

    return WebAssembly.instantiate(bytes, {
        js: { mem: memory }
    });
})
.then(function (module) {

    console.log(new Uint8Array(memory.buffer));
})
.catch((err) => {

    console.log(err);
});

控制台输出

希望对您有所帮助!