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

时间:2018-07-21 00:00:35

标签: javascript webassembly

我有这种情况:

(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将“原始字节”放入WebAssembly中的数据段。但是在浏览器中出现此错误(wat2wasm中未出现编译错误):

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

我尝试了诸如此类的不同变体,它不会引发错误,但是当我记录输出时没有输出(我希望它说“ 0”之类的东西:

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

我尝试其他类似方法:

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

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

作为进一步说明如何使用原始字节功能的示例,了解如何表示类似123的数字将很有帮助。当我序列化为Uint8Array-> JavaScript中的String时,我执行以下操作并得到奇怪的结果:

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

所以想知道应该如何使用十六进制代码。十六进制的1230x7B,所以也许:

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

但是我认为它必须是两个十六进制数字,或者不太清楚。无论如何,如果这太复杂或分散了问题的第一部分,则无需解决。

1 个答案:

答案 0 :(得分:1)

我已经对您的示例进行了测试,在最新的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模块:

控制台屏幕截图

enter image description here

关于问题的第二部分,您可以使用与"\7b"完全相同的表达式在内存中编码123。这是一个示例:

index.wat

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

如果我们注销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);
});

控制台输出

enter image description here

希望这对您有所帮助!