【问题标题】:How do I access compiled memory in WebAssembly from js如何从 js 访问 WebAssembly 中的编译内存
【发布时间】:2017-09-04 20:24:09
【问题描述】:

考虑以下 C++:

int MYVAR = 8;

它将从 Clang/LLVM 编译为插入到下面操场中的 WASM 字节码。

WAST 可读性:

(module
(table (;0;) 0 anyfunc)
(memory (;0;) 1)
(global (;0;) i32 (i32.const 0))
(export "MYVAR" (global 0))
(data (i32.const 0) "\08\00\00\00"))

当从 js 调用时,MYVAR 会暴露一个指向变量的指针。

但是如何使用新的 js API 访问实际内存呢?

内存构造函数似乎在初始化时擦除条目,但我不确定我是否正确解释了这一点。

作为旁注,Module 没有 specs 中指定的 export 属性,但这又可能是一种误解。

游乐场:

<!doctype html>
<html>

<head>
<meta charset="utf-8">
<title>MEMORY ACCESS TEST</title>
</head> 
<div>
<h1 style="display: inline;">MEMORY LOCATION : </h1>
<h1 id='POINTER' style="display: inline;"></h1>
</div> 
<div>
<h1 style="display: inline;">VALUE : </h1>
<h1 id='VALUE' style="display: inline;"></h1>
</div>
<body>
<script>
 var bytecode = new Uint8Array([
 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x04, 0x84,
 0x80, 0x80, 0x80, 0x00, 0x01, 0x70, 0x00, 0x00, 0x05, 0x83,
 0x80, 0x80, 0x80, 0x00, 0x01, 0x00, 0x01, 0x06, 0x86, 0x80,
 0x80, 0x80, 0x00, 0x01, 0x7F, 0x00, 0x41, 0x00, 0x0B, 0x07,
 0x89, 0x80, 0x80, 0x80, 0x00, 0x01, 0x05, 0x4D, 0x59, 0x56,
 0x41, 0x52, 0x03, 0x00, 0x0B, 0x8A, 0x80, 0x80, 0x80, 0x00,
 0x01, 0x00, 0x41, 0x00, 0x0B, 0x04, 0x08, 0x00, 0x00, 0x00,
 0x00, 0x96, 0x80, 0x80, 0x80, 0x00, 0x07, 0x6C, 0x69, 0x6E,
 0x6B, 0x69, 0x6E, 0x67, 0x03, 0x81, 0x80, 0x80, 0x80, 0x00,
 0x04, 0x04, 0x81, 0x80, 0x80, 0x80, 0x00, 0x04
 ]);
 WebAssembly.instantiate(bytecode).then(function(wasm) {
 console.log(wasm.module);
 console.log(wasm.instance);
 let pointer = wasm.instance.exports.MYVAR;
 document.getElementById('POINTER').innerHTML = pointer; 
 let memory = new WebAssembly.Memory({initial : 1});
 let intView = new Uint32Array(memory.buffer);
 document.getElementById('VALUE').innerHTML = intView[pointer];
 });
 </script>
 </body>

 </html>

【问题讨论】:

    标签: javascript c++ webassembly


    【解决方案1】:

    MYVAR 是一个全局变量。这是与内存部分完全分开的可寻址单元。它包含单独的标量值。

    您似乎正在尝试访问“内存”部分。您确实可以使用 i32 全局作为指针,就像您可以使用任何其他 i32 一样,但它不能自动访问内存。你也要导出你的记忆!

    试试:

    (module
    (table (;0;) 0 anyfunc)
    (memory (;0;) 1)
    (global (;0;) i32 (i32.const 0))
    (export "MYVAR" (global 0))
    (export "MYMEM" (memory 0)) ;; New!
    (data (i32.const 0) "\08\00\00\00"))
    

    还有:

    WebAssembly.instantiate(bytecode).then(function(wasm) {
     console.log(wasm.module);
     console.log(wasm.instance);
     let pointer = wasm.instance.exports.MYVAR;
     document.getElementById('POINTER').innerHTML = pointer; 
     let memory = wasm.instance.exports.MYMEM; // New!!
     let intView = new Uint32Array(memory.buffer);
     document.getElementById('VALUE').innerHTML = intView[pointer];
     });
    

    【讨论】:

    • 有效。谢谢。我得出结论,wasm 的 LLVM 后端仍然是 WIP ;) 另一个观察结果:如果你 wasm2was 来自问题的字节,然后 wast2wasm 结果你得到一个不同的和更小的字节码。 wabt 应该是一对一的。是吗?
    • 是的,WebAssembly LLVM 后端仍处于 WIP 中,但大部分应该可以正常工作。导出内存似乎应该可行。你应该提交一个错误。
    猜你喜欢
    • 2018-03-26
    • 1970-01-01
    • 2020-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多