Рассмотрим следующий 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"))
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
глобальный как указатель, как и любой другой 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];
});
Других решений пока нет …