web-dev-qa-db-ja.com

chrome拡張機能でのWebAssemblyの使用

chrome拡張機能が含まれていて、複雑な関数comp_func(data)が含まれているため、多くのビット単位の操作を実行するために大量のCPUを必要とします。そのため、WebAssemblyを使用しようとしています。

this oneや this oneなど、いくつかのチュートリアルを試してみました。

最初のリンクは言う:

fetch('simple.wasm').then(response =>
  response.arrayBuffer()
).then(bytes =>
  WebAssembly.instantiate(bytes, importObject)
).then(results => {
  results.instance.exports.exported_func();
});

しかし、エラーが発生します:

捕捉されなかった(約束された)TypeError:WebAssembly Instantiation:Import#0 module = "env" error:module is not a object or function

私はこのアプローチを使用するために多くのことを試みましたが、うまくいきませんでした。 .wasmファイルからロードされたWebAssemblyの使用方法を理解できません。

だから私はより簡単なアプローチを試しました:2番目のリンクはその行をhtmlファイルに入れるように言っています:

<script src="index.js"></script>

次に、エクスポートされた関数を使用します。

var result = _roll_dice();

しかし、私は拡張機能を使用しているので、background.htmlファイルしかありません。だから私はバックグラウンドファイルにロードされたモジュールにアクセスする方法を探しています。そして、物事は複雑になります、関数comp_func(data)Workerから呼び出されるためです

これは私がこれまでに試したことです:

chrome.extension.getBackgroundPage()を呼び出すと、モジュールにアクセスできますが、ワーカーに送信できません。

「ワーカー」で「postMessage」を実行できませんでした:#を複製できませんでした。

そして、最初にstringifyを試してみると:

Uncaught TypeError:循環構造をJSONに変換する

(私はそれを非循環にしようとしました、動作しませんでした...)

そこからchrome APIにアクセスできないため、ワーカーからchrome.extension.getBackgroundPage()を呼び出すことができません。

だから私の質問は

  1. 誰かが.wasmファイルをchrome拡張子でロードするのにうんざりしましたが、うまくいきましたか?2番目のアプローチ(jsファイルをロードする)は簡単に聞こえますが、このアプローチの実用的な例があればそれは素晴らしいでしょう。

または2. background.htmlにロードされたモジュールにアクセスする方法(2番目の例から)?

または3. jsファイルからワーカーに(postMessageを介して)必要な関数を渡す方法は?

要約すると、誰かがchrome拡張機能でWebAssemblyを使用しようとしましたが、生き残って教えましたか?

[〜#〜] edit [〜#〜]:最終的にWebAssemblyのアプローチを離れました。私もこの質問を bugs-chromium に投稿し、数か月後に回答を得ました。これが実際に機能しているかどうかはわかりませんが、マークされた回答とともに、これが誰かを助けるでしょう。

17
Nagmon

私は最近WebAssemblyをいじっていて、それを機能させる方法を見つけました。スクリプトファイルは次のとおりです。

main.js

chrome.browserAction.onClicked.addListener(function(tab) {
 chrome.tabs.executeScript(null, {file: "content_script.js"});
});

content_script.js

  var importObject = { imports: { imported_func: arg => console.log(arg) } };
  url = 'data:application/wasm;base64,' + "AGFzbQEAAAABCAJgAX8AYAAAAhkBB2ltcG9ydHMNaW1wb3J0ZWRfZnVuYwAAAwIBAQcRAQ1leHBvcnRlZF9mdW5jAAEKCAEGAEEqEAAL";
  WebAssembly.instantiateStreaming(fetch(url), importObject)
  .then(obj => obj.instance.exports.exported_func());

データURLは、コンソールに42を書き込む一般的なチュートリアルwasmサンプル(simple.wasm)に属しています。


var importObject = {
   imports: {
    imported_func: function(arg) {
    console.log(arg);
    }
   }
 };

var response = null;
var bytes = null;
var results = null;


var wasmPath = chrome.runtime.getURL("simple.wasm");
fetch(wasmPath).then(response =>
    response.arrayBuffer()
    ).then(bytes =>
       WebAssembly.instantiate(bytes, importObject)
        ).then(results => {
        results.instance.exports.exported_func();
  });

ただし、manifest.jsonのweb_accessible_resourcesセクションにコードファイルを含める場合のみ:

    ...
    "web_accessible_resources": [
     "content_script.js",
     "main.js",
     "simple.wasm"
    ],
    ...
17
Nautilus