在Chrome扩展程序中使用WebAssembly [英] using WebAssembly in chrome extension

查看:309
本文介绍了在Chrome扩展程序中使用WebAssembly的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个chrome扩展程序,其中包含一个复杂的函数 comp_func(data),该函数通过执行许多按位运算会占用大量CPU.因此,我正在尝试使用WebAssembly.

I have a chrome extension that includes a complicated function comp_func(data) which takes a lot of CPU by performing many bitwise operations. Because of that, I'm trying to use WebAssembly.

我尝试遵循一些教程,例如一个和这个一个.

I've tried to follow several tutorials, for example this one and this one.

第一个链接说:

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

但是我得到一个错误:

未捕获(承诺)TypeError:WebAssembly实例化:导入#0 module ="env"错误:模块不是对象或函数

Uncaught (in promise) TypeError: WebAssembly Instantiation: Import #0 module="env" error: module is not an object or function

我已经尝试了很多使用这种方法的方法,但是没有用.我不明白如何使用从 .wasm 文件加载的WebAssembly.

I've tried a lot to use this approach, but it didn't work. I can't understand how to use WebAssembly that is loaded from the .wasm file.

因此,我尝试了一种更简单的方法:第二个链接说要把这一行放在html文件中:

So I've tried an easier approach: The second link says to put that line in the html file:

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

,然后只使用导出的功能:

and then just use the function exported:

var result = _roll_dice();

但是,我的扩展名是,所以我只有一个 background.html 文件.因此,我正在寻找一种方法来访问在后台文件中加载的模块.事情变得复杂了,因为是因为函数 comp_func(data)是从

BUT, I'm in extension so I only have a background.html file. So I'm looking for a way to access the Module which was loaded in the background file. And things get complicated, because the function comp_func(data) is called from a Worker.

这是我到目前为止尝试过的:

This is what I've tried so far:

如果我调用 chrome.extension.getBackgroundPage(),则可以访问模块但我无法将其发送给工作人员:

If I call chrome.extension.getBackgroundPage() I can access the Module but I can't send it to the Worker:

无法在'Worker'上执行'postMessage':#无法克隆.

Failed to execute 'postMessage' on 'Worker': # could not be cloned.

如果我先尝试字符串化:

未捕获到的TypeError:将圆形结构转换为JSON

Uncaught TypeError: Converting circular structure to JSON

(我试图取消公开,没有用...)

(I tried to un-circular it, didn't work...)

而且我无法从Worker调用 chrome.extension.getBackgroundPage(),因为我无法从那里访问chrome API.

And I can't call chrome.extension.getBackgroundPage() from the Worker because I can't access chrome API from there.

所以我的问题是:

  1. 有人不愿意在chrome扩展程序中加载 .wasm 文件,并且可以正常工作吗?第二种方法(加载 js 文件)听起来更简单,但是如果您有使用该方法的可行示例,那就更好了.
  1. Did someone tired to load .wasm file in chrome extension and it worked? The second approach (loading the js file) is sound simpler but if you have a working example for this approach it will be great.

或2.如何访问已在 background.html 中加载的模块(来自第二个示例)?

or 2. how to access the Module that has been loaded in background.html (from the second example)?

或3.如何将我需要的功能从js文件传递给Worker(通过 postMessage )?

or 3. how to pass the functions that I needed from the js file to the Worker (via postMessage)?

总而言之,有人尝试过在Chrome扩展程序中使用WebAssembly并幸存下来吗?

编辑:我最终离开了WebAssembly的方法.我还将这个问题发布在 bugs-chromium 上,几个月后得到了答案.不知道这是否真的有效,但是也许,加上标记的答案,将对某人有所帮助.

EDIT: I eventually left the approach of WebAssembly. I also posted this question at bugs-chromium, and after few month got an answer. Not sure if this is really working, but maybe this, along with the marked answer, will help someone.

推荐答案

我最近一直在摆弄WebAssembly,并找到了使其工作的方法.这是脚本文件:

I've been fiddling with WebAssembly recently, and found a way to make it work. Here are the script files:

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属于通用教程wasm示例(simple.wasm),该示例在控制台上写入42.

The data URL belongs to the common tutorial wasm sample (simple.wasm), which writes 42 on the console.

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 部分中时,

Only if you include the code files in the web_accessible_resources section in manifest.json, though:

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

Github: https://github.com/inflatablegrade/Extension-with-WASM

这篇关于在Chrome扩展程序中使用WebAssembly的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆