2017-10-21 11 views
2

私は、WebAssemblyバッファのメモリアドレスを取得してJavascriptに戻そうとしています。そのため、JavascriptのArrayBufferとしてメモリをインストールし、適切なアドレスのモジュールのメモリに配列を直接書き込むことができます。WebAssemblyバッファのアドレスを見つけてJavascriptに戻すにはどうしたらいいですか?

Cコード:

#include <stdint.h> 

uint8_t buff[10][100]; 

uint64_t addr(int buffer_index){ 
    return (uint64_t)&buff[buffer_index]; 
} 

私はそれをコンパイル:

emcc project.c -Os -s WASM=1 -s SIDE_MODULE=1 -o project.wasm 

HTML:

<script> 
var importObject = { 
     env: { 
      memoryBase: 0, 
      tableBase: 0, 
      setTempRet0:(x)=>{}, 
      memory: new WebAssembly.Memory({ initial:256 }), 
      table: new WebAssembly.Table({ initial:0, element:'anyfunc' }) 
     } 
    }; 

    fetch('http://localhost:9000/assets/wasm/project.wasm').then(
     response => response.arrayBuffer() 
    ).then(
     bytes => WebAssembly.instantiate(bytes, importObject) 
    ).then(
     results => { 
      let module=results.instance 
      let exports=module.exports 
      let addr=exports._addr 
      console.log(addr(0)) 
      console.log(addr(1)) 
      console.log(addr(2)) 
     } 
    ) 
</script> 

実行の結果:

project.html:21 5242880 
project.html:22 5242980 
project.html:23 5243080 

バッファに100バイトのチャンクがあり、返されるアドレスが100バイト離れているため、これは正常に見えます。

これらのアドレスがモジュールのメモリ内でどこを指しているかはどのようにして知ることができますか?

答えて

2

importObject.env.memory経由でメモリにモジュールを提供しています。あなたは、単にあなたのCコードであなたのbuff変数に割り当てられたメモリを検査するために提供さオフセット/アドレスを使用する必要があります。

// create a Uint8Array as a 'view' on the module linear memory 
// starting at _addr(0), and with a length of 100 elements. 
var buffer = new Uint8Array(importObject.env.memory.buffer, exports._addr(0), 100); 

for (var i=0; i<buffer.length; i++) { 
    var foo = buffer[i]; 
    // do something with foo here! 
} 

あなたはmy project that renders a Mandelbrot fractalでより完全な例を参照することができます。

+1

この回答をありがとう、私の問題を解決しました。しかし、メモリの代わりにメモリバッファを見なければならないので、正しい行は 'var buffer = new Uint8Array(importObject.env.memory.buffer、exports._addr(0)、100);'です。マンデルブロフラクタルのあなたのプロジェクトも好きです。 – sbtpr

+0

良い点、私はコードを更新しました! – ColinE

+0

'(exports._addr || exports.addr)(0)' - アンダーラインはemccによってのみ追加され、llvmは名前をそのままエクスポートします。 – Vitaly

関連する問題