Wasm访问DOM

时间:2017-03-06 14:37:52

标签: webassembly webidl

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

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

4 个答案:

答案 0 :(得分:9)

在WebAssembly Minimal Viable Product中,调用和调出WebAssembly的唯一方法是通过导入和导出。将来,WebAssembly可能会gain capabilities which allow the embedder expose APIs directly,在嵌入此浏览器的浏览器中可能包含DOM。

Importsexports并不是很复杂:从C代码的角度来看,它们看起来像extern调用,类似于Windows平台上的DLL。您可能使用Emscripten编译C代码,请参阅its documentation "Call JavaScript functions from C/C++"了解其工作原理的详细信息(因为这不是您要问的问题,但我猜这是下一个问题)。

你的问题不清楚你是否:

  1. 想要编译C代码并在WebAssembly 内部浏览器中运行。
  2. 想要编译C代码并在WebAssembly 外部浏览器中运行。
  3. 或两者兼而有之。

答案 1 :(得分:2)

这完全取决于编译器功能。

当前无法直接访问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的发明者,但是所描述的逻辑可以适合任何其他编译器。

答案 2 :(得分:2)

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

答案 3 :(得分:1)

WebAssembly人员对于WebAssembly中的JS对象看起来似乎没有任何强烈的想法,似乎。

我会查看PR #1080,这是关于垃圾收集规范现在被分拆到它自己的回购中。但是,虽然这种情况正在发生,但他们正在删除网络平台和网络平台的唯一提及。与规范中存在的JS对象互操作,描述为:

It's more aspirational that concrete,