WASM 可以在没有任何 JavaScript 的情况下访问 DOM 吗?

问题描述 投票:0回答:4

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

我正在尝试用 C 语言构建一个基本应用程序(C 源代码实际上是 GC 语言转译的结果)。我正在构建的应用程序将作为桌面应用程序运行(它还不意味着在“真正的”浏览器中运行),因此我可以根据需要调整环境(即布局引擎)。

webassembly webidl
4个回答
17
投票

在 WebAssembly 最小可行产品中,调入和调出 WebAssembly 的唯一方法是通过导入和导出。将来,WebAssembly 可能会获得允许嵌入器直接公开 API 的功能,在浏览器中嵌入这可能包括 DOM。

不过,

Importsexports 并不是很复杂:从 C 代码的角度来看,它们只是看起来像一个

extern
调用,类似于 Windows 平台上的 DLL。您可能会使用 Emscripten 编译 C 代码,请参阅 其文档“从 C/C++ 调用 JavaScript 函数”,了解其工作原理的详细信息(因为这不是您要问的问题,但我猜它是下一个问题)。


从您的问题中不清楚您是否:

  1. 想要编译 C 代码并在 WebAssembly inside 浏览器中运行它。
  2. 想要编译 C 代码并在 WebAssembly 外部浏览器中运行它。

或两者兼而有之。


8
投票

这一切都取决于编译器的能力。

目前还没有办法直接访问 DOM 或任何其他浏览器 API。也不可能将 JavaScript 引用存储在 Wasm 线性内存或 Wasm 表中。也不可能使用 JavaScript 引用作为函数参数或返回值。它们只是不存在于 MVP 类型系统中。然而,有一个参考类型提案,有一天它可能会成为 Wasm 运行时的一部分,但没有可用的官方发布日期。

那么,Wasm 与宿主环境的交互如何进行呢?事实证明,具有导入和导出功能的 Wasm 模块系统可用于创建模拟层。手动创建这一层是很痛苦的,因此编译器创建它是一项很好的任务。但如何呢?

例如,我们要设置当前浏览器窗口中的文档标题。 Wasm 需要访问当前窗口实例,选择文档,并设置它的 title 属性。由于 Wasm 运行时无法访问引用,因此我们需要在 JS 端创建一个映射表以及一些具有映射逻辑的 JS 函数并将它们导入到 Wasm 模块中。

因此,我们创建一个名为 getWindow 的函数。该函数获取全局窗口引用,将其放入映射表中并返回表中的索引。该索引将在 Wasm 端作为 I32 进行访问。该函数被导入到 Wasm 模块中。

现在,我们创建一个名为 getDocumentFromWindow 的函数。该函数将一个索引放入映射表中,并返回另一个索引。该实现从映射表中查找窗口引用并解析其文档属性,并将该文档放入映射表中并将该索引返回给 Wasm。该函数也被导入到 Wasm 模块中。

在 Wasm 方面,我们现在可以通过导入的函数间接操作 Wasm 主机引用。我们的映射表通过整数索引模拟 JS 引用。这是 Wasm 参考类型提案可能附带的较慢版本。

因此整个映射逻辑可以由编译器创建。一旦引用类型可用,就可以更改编译器并使用新的类型系统来获得更高效的代码。

如果您想查看此类编译器的运行情况,请查看 https://github.com/mirkosertic/Bytecoder。它可以将 JVM 字节码编译为 JavaScript 和 WebAssembly,并为 DOM 和浏览器 API 交互提供透明的方式。可以从 Wasm 调用 DOM,也可以从 DOM 调用 Wasm,例如实现点击监听器和其他很酷的东西,比如与 vue.js 等高级框架交互。

免责声明:我是Bytecoder的发明者,但所描述的逻辑可以适用于任何其他编译器。


4
投票

WebAssembly 的人们似乎还不太清楚 WebAssembly 中的 JS 对象会是什么样子。

我会查看 PR #1080,它是关于垃圾收集规范现在被剥离到它自己的存储库中的。但在这种情况发生的同时,他们删除了规范中唯一提及的 Web 平台和与 JS 对象的互操作,其描述为:

比具体更令人向往,


3
投票

我刚刚遇到了js_ffi
https://github.com/richardanaya/js_ffi
不确定它是否也适用于 C,但它是这样宣传的。

© www.soinside.com 2019 - 2024. All rights reserved.