如何从JS访问WebAssembly中的内存

How do I access compiled memory in WebAssembly from js

本文关键字:内存 WebAssembly 访问 JS      更新时间:2023-10-16

考虑以下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) "8000"))

MyVar将在JS调用时将指针曝光到变量。

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

初始化时,内存构造函数似乎删除了条目,但是我不确定我是否正确解释了此内容。

作为旁注,该模块没有规格中指定的导出属性,但这再次可能是误解。

游乐场:

<!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>

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

您似乎正在尝试访问内存部分。您确实可以将i32 Global用作指针,因为您可以使用任何其他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) "8000"))

和:

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];
 });