标签: webassembly

Wasm访问DOM

有没有办法在没有JavaScript的情况下获得对DOM和/或WebAPI(即全屏API)的读/写访问权限?

我正在尝试用C构建一个基本的应用程序(C源实际上是从GC语言转换的结果).我正在构建的应用程序将作为桌面应用程序运行(它不打算在"真正的"浏览器中运行)所以我可以根据需要调整环境(即布局引擎).

webidl webassembly

14
推荐指数
2
解决办法
9363
查看次数

WASM可以用来检查JS方法的完整性吗?

我正在尝试使用webAssembly并尝试找出一种验证webAssembly模块使用的JS方法的完整性的方法.

出于讨论的目的,让我们假设二进制模块不是hackable(我知道情况并非如此),但JS方面是.

给出以下C代码:

#include <emscripten.h>

//js method to validate
void validateMe();

int validateMethods(){
    // check validateMe integrity.
    // return 1 if validation succeeded.
}

EMSCRIPTEN_KEEPALIVE
void doStuff(){
    if (validateMethods()){
       // do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

我想doStuff()从JS方面打电话,doStuff()只有在完整性检查成功后才会运行.我想做一些完整性检查,类似于Subresource,检查方法的toString表示.但是,如果我想获得当前(内存中)JS方法toString,我将不得不调用可能被泄露的JS.

问:我可以以某种方式以不同的方式获取toString吗?任何其他方法也将不胜感激.

更新:深入挖掘后,阅读本文,似乎没有办法访问共享数组以外的JS内存.因此,任何验证技术将不胜感激.


更新2(目标):我的最终目标是确保WASM部分仅适用于特定的JS,或者至少使得与操纵的JS交互更加困难.

小提琴实施例:下列小提琴,是一种幼稚功能验证,通过炭比较功能炭的的toString.如果更改validateMe函数,则验证失败.我试图"防弹"它.

javascript c security emscripten webassembly

14
推荐指数
1
解决办法
341
查看次数

对大量数据进行硬编码而不引起内存峰值

因此,我正在探索将 WebAssembly 存储在 JavaScript 文件中的概念,以便将其全部捆绑在一个可交付文件中。我确实设法制作了一个工作示例,它将 wasm 文件存储在 base64 的大文字字符串中,并在运行时转换为 Uint8Array,然后再处理为模块和实例。

await Deno.writeTextFile(
    './static/wasm/bundle.js',
    `import { initSync } from './app.js'\ninitSync(new WebAssembly.Module(Uint8Array.from(atob('${btoa(
        [ ...await Deno.readFile('./static/wasm/app_bg.wasm') ]
            .map(byte => String.fromCharCode(byte))
            .join('')
    )}').split('').map(char => char.charCodeAt(0)))))`
)
Run Code Online (Sandbox Code Playgroud)

上述片段的来源

但我一直想知道,在 wasm 文件非常大的情况下,JavaScript 在处理这个文字字符串时是否可能会出现问题。在此代码片段中,base64 文字字符串在开始时只需要一次,我想它会被垃圾收集器处理掉,因为它不再可访问。

我想知道人们是否对如何存储这种相同类型的数据有任何想法,这些数据硬编码在 JavaScript 中,它只运行一次,但不会在运行时开始时导致任何巨大的内存峰值。增加处理时间以减少峰值内存使用量是一个可以接受的权衡,但获取任何外部资源会破坏问题的重点。

javascript webassembly deno

14
推荐指数
1
解决办法
736
查看次数

如何使用Rust将带有JavaScript的文件读取到WebAssembly?

如何File在WebAssembly内存上下文中传递要读取的内容?

使用JavaScript在浏览器中读取文件很简单:

<input class="file-selector" type="file" id="files" name="files[]" />
Run Code Online (Sandbox Code Playgroud)

我能够使用crate stdweb来引导用Rust编写的WebAssembly代码,向DOM元素添加一个事件监听器并启动FileReader:

let reader = FileReader::new();
let file_input_element: InputElement = document().query_selector(".file-selector").unwrap().unwrap().try_into().unwrap();
file_input_element.add_event_listener(enclose!( (reader, file_input_element) move |event: InputEvent| {
    // mystery part
}));
Run Code Online (Sandbox Code Playgroud)

在JavaScript中,我会从元素中获取文件并将其传递给阅读器,但是,stdweb的API需要以下签名:

pub fn read_as_array_buffer<T: IBlob>(&self, blob: &T) -> Result<(), TODO>
Run Code Online (Sandbox Code Playgroud)

我不知道如何实现IBlob,我确信我遗漏了一些明显的东西,无论是使用stdweb API还是我对WebAssembly/Rust的理解.我希望有一些东西比将东西转换为UTF-8更简洁.

javascript rust webassembly

13
推荐指数
1
解决办法
1476
查看次数

为什么我不能在浏览器中构造`WebAssembly.Memory`?

我在我试过的所有浏览器中偶然发现了一些奇怪的行为:

  • Chromium 69.0.3497.92(官方版)Arch Linux(64位)
  • Chrome 69.0.3497.100(官方版)(64位)
  • Firefox 62.0(64位)

当我尝试通过实例化WebAssembly.Memory对象来为WebAssembly分配内存时,例如:

new WebAssembly.Memory({ initial: 1 })
Run Code Online (Sandbox Code Playgroud)

在Chrome/Chromium中,我得到:

VM274:1 Uncaught RangeError: WebAssembly.Memory(): could not allocate memory
    at <anonymous>:1:1
(anonymous) @ VM274:1
Run Code Online (Sandbox Code Playgroud)

在Firefox中,我得到:

Error: out of memory 
Run Code Online (Sandbox Code Playgroud)

Node.js中的分配工作正常,但出于某种原因,我的所有浏览器都失败了.我不知道该怎么做,所有依赖WebAssembly的网站都因此无法使用.

我怀疑Linux正在阻止浏览器(但不是node.js?)分配内存,但这只是一个疯狂的猜测.另一台计算机上几乎相同的安装工作正常,但在这台特定的机器上,浏览器的每次分配都会失败.

有谁知道发生了什么?

这是我的输出ulimit -a:

-t: cpu time (seconds)              unlimited
-f: file size (blocks)              unlimited
-d: data seg size (kbytes)          unlimited
-s: stack size (kbytes)             8192
-c: core file size (blocks)         unlimited
-m: resident set size (kbytes)      unlimited
-u: processes                       31215
-n: file …
Run Code Online (Sandbox Code Playgroud)

javascript browser linux memory webassembly

13
推荐指数
1
解决办法
1128
查看次数

使用 webpack 将 Wasm + JS 文件打包成一个文件

我目前正在使用 Emscripten 将我们的 C++ 代码编译成 Wasm。通过这样做,我输出了两个文件 *.js 和 *.wasm。后来我使用我们的实现在上面写了更多的 Javascript 代码,这导致我们得到 3 个文件:

 index.js
 wasmFile.js
 wasmFile.wasm
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用 webpack 创建一个文件,该文件将在构建时而不是运行时使用这段代码打包所有内容:

function loadScript(url = "wasmFile.js") {
    var script = document.createElement( "script" );
    script.src = url;
    document.getElementsByTagName( "head" )[0].appendChild( script );
    await new Promise<void>((res) => {
        Module.onRuntimeInitialized = () => res();
    });
}
Run Code Online (Sandbox Code Playgroud)

我已经查看了https://github.com/ballercat/wasm-loader但是,看起来我需要为我的所有函数创建一个 WebAssembly.Instance - 并且 Wasm 文件有很多函数来创建一个实例每个。

这就是我们的 WebPack 配置目前的样子:

module.exports = {
    entry: './src/index.ts',
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            },
            {
                test: …
Run Code Online (Sandbox Code Playgroud)

javascript emscripten webpack webassembly

13
推荐指数
1
解决办法
1129
查看次数

Blazor Wasm PWA 未更新

我有一个 Blazor WASM PWA 应用程序,已在 IIS 上的托管服务上发布。我遇到的问题是有时应用程序不会在访问者的浏览器中更新。即他们看到的是旧版本的应用程序。

我知道应用程序缓存应该由 Service Worker 更新,因此您可能需要访问该网站一次,然后关闭浏览器并再次访问它才能获取更新的版本。然而,有时看起来缓存只是被搞乱了,无论如何,应用程序都不会更新。我找到的唯一解决方案是按 F12,转到“应用程序”选项卡并删除其中的所有内容 -> 这将强制再次下载应用程序的最新版本。

有谁知道发生了什么事以及我该如何解决这个问题?

webassembly progressive-web-apps asp.net-core blazor

13
推荐指数
1
解决办法
6990
查看次数

如何从WebAssembly中的Rust返回一个字符串(或类似的)?

我从这个Rust代码创建了一个小的WASM文件:

#[no_mangle]
pub fn hello() -> &'static str {
    "hello from rust"
}
Run Code Online (Sandbox Code Playgroud)

它构建并且hello可以从JS调用该函数:

<!DOCTYPE html>
<html>
<body>
  <script>
    fetch('main.wasm')
    .then(response => response.arrayBuffer())
    .then(bytes => WebAssembly.instantiate(bytes, {}))
    .then(results => {
      alert(results.instance.exports.hello());
    });
  </script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

我的问题是alert显示"未定义".如果我返回a i32,它可以工作并显示i32.我也尝试返回String但是它不起作用(它仍然显示"未定义").

有没有办法从WebAssembly中的Rust返回一个字符串?我应该使用什么类型的?

rust webassembly

12
推荐指数
3
解决办法
4759
查看次数

在chrome扩展中使用WebAssembly

我有一个chrome扩展,包括一个复杂的功能comp_func(data),通过执行许多按位操作需要大量的CPU.因此,我正在尝试使用WebAssembly.

我已经尝试过几个教程,例如这个教程.

第一个链接说:

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

但是我收到一个错误:

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

我已经尝试了很多使用这种方法,但它没有用.我无法理解如何使用从.wasm文件加载的WebAssembly .

所以我尝试了一种更简单的方法:第二个链接说将该行放在html文件中:

<script src="index.js"></script>
Run Code Online (Sandbox Code Playgroud)

然后只使用导出的函数:

var result = _roll_dice();
Run Code Online (Sandbox Code Playgroud)

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

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

如果我打电话,chrome.extension.getBackgroundPage()我可以访问模块,但我无法将其发送给工人:

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

如果我先尝试一下stringify:

未捕获的TypeError:将循环结构转换为JSON

(我试图解开它,没有用......)

我无法chrome.extension.getBackgroundPage()从工作人员打电话,因为我无法从那里访问chrome API.

所以我的问题是:

  1. 有人厌倦了加载.wasmchrome扩展文件并且它有效吗?第二种方法(加载js文件)听起来更简单,但如果你有一个这种方法的工作示例,它将是伟大的.

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

或者3.如何将我需要的函数从js文件传递给Worker(via postMessage)?

总结一下,有人试图在chrome扩展中使用WebAssembly并幸存下来吗?

编辑:我最终离开了WebAssembly的方法.我也在bugs-chromium发布了这个问题,几个月后得到了答案.不确定这是否真的有效,但也许这一点,以及明确的答案,将有助于某人.

javascript web-worker google-chrome-extension webassembly

12
推荐指数
1
解决办法
3204
查看次数

是否可以使用WebAssembly提交HTTP请求?

我正在尝试在WebAssembly中提交一个简单的HTTP GET请求.为此,我编写了这个程序(从Emscripten网站复制,稍作修改):

#include <stdio.h>
#include <string.h>
#ifdef __EMSCRIPTEN__
#include <emscripten/fetch.h>
#include <emscripten.h>
#endif


void downloadSucceeded(emscripten_fetch_t *fetch) {
  printf("Finished downloading %llu bytes from URL %s.\n", fetch->numBytes, fetch->url);
  // The data is now available at fetch->data[0] through fetch->data[fetch->numBytes-1];
  emscripten_fetch_close(fetch); // Free data associated with the fetch.
}

void downloadFailed(emscripten_fetch_t *fetch) {
  printf("Downloading %s failed, HTTP failure status code: %d.\n", fetch->url, fetch->status);
  emscripten_fetch_close(fetch); // Also free data on failure.
}

unsigned int EMSCRIPTEN_KEEPALIVE GetRequest() {
  emscripten_fetch_attr_t attr;
  emscripten_fetch_attr_init(&attr);
  strcpy(attr.requestMethod, "GET");
  attr.attributes …
Run Code Online (Sandbox Code Playgroud)

c http xmlhttprequest emscripten webassembly

11
推荐指数
2
解决办法
3272
查看次数