简体   繁体   English

Wasm 访问 DOM

[英]Wasm access DOM

Is there any way to get read/write access to DOM and/or the WebAPIs(ie fullscreen API) without JavaScript?有没有办法在没有 JavaScript 的情况下获得对 DOM 和/或 WebAPI(即全屏 API)的读/写访问权限?

I'm trying to build a basic application in C(C source being actually the result of transpilation from a GC language).我正在尝试用 C 构建一个基本应用程序(C 源代码实际上是从 GC 语言转换的结果)。 The app I'm building will run as Desktop app(it's not meant to run in "real" browsers yet) so I can tweak the environment(ie the layout engine) if necessary.我正在构建的应用程序将作为桌面应用程序运行(它还不是要在“真正的”浏览器中运行),因此我可以在必要时调整环境(即布局引擎)。

In the WebAssembly Minimal Viable Product the only way to call into and out of WebAssembly is through imports and exports.在 WebAssembly 最小可行产品中,调用和调用 WebAssembly 的唯一方法是通过导入和导出。 In the future, WebAssembly may gain capabilities which allow the embedder expose APIs directly , in a browser embedding this could include the DOM.将来,WebAssembly 可能会获得允许嵌入器直接公开 API 的功能,在浏览器嵌入中这可能包括 DOM。

Imports and exports aren't very complicated though: from your C code's point of view they just look like an extern call, similar to a DLL on the Windows platform.不过,导入导出并不是很复杂:从您的 C 代码的角度来看,它们只是看起来像一个extern调用,类似于 Windows 平台上的 DLL。 You'd likely compile the C code using Emscripten, see its documentation "Call JavaScript functions from C/C++" for details on how this works (since this isn't the question you're asking, but I'm guessing it's the next question).您可能会使用 Emscripten 编译 C 代码,请参阅其文档“从 C/C++ 调用 JavaScript 函数”以获取有关其工作原理的详细信息(因为这不是您要问的问题,但我猜这是下一个题)。


It's not clear from your question if you:从您的问题中不清楚您是否:

  1. Want to compile C code and run it within WebAssembly inside a browser.想要编译 C 代码并浏览器中的 WebAssembly 中运行它。
  2. Want to compile C code and run it within WebAssembly outside a browser.想要编译 C 代码并在浏览器的 WebAssembly 中运行它。

Or both.或两者。

It all depends on compiler capabilities.这一切都取决于编译器的能力。

Currently there is no way to access the DOM or any other browser API directly.目前无法直接访问 DOM 或任何其他浏览器 API。 It is also not possible to store JavaScript references inside of Wasm linear memory or Wasm tables.也不可能在 Wasm 线性内存或 Wasm 表中存储 JavaScript 引用。 It is also not possible to use JavaScript references as function arguments or return values.也不能使用 JavaScript 引用作为函数参数或返回值。 They just do not exists in the MVP type system.它们只是不存在于 MVP 类型系统中。 However, there is the Reference Type Proposal, which might someday become part of the Wasm runtime, but there is no official release date available.然而,有参考类型提案,它可能有朝一日成为 Wasm 运行时的一部分,但没有可用的官方发布日期。

So, how can Wasm to Host Environment interaction be done?那么,Wasm 与宿主环境的交互如何完成? Well, it turns out that the Wasm module system with imports and exports can be used to create an emulation layer.好吧,事实证明,具有导入和导出功能的 Wasm 模块系统可用于创建仿真层。 Creating this layer by hand is painful, so it is a good task for a compiler to create it.手动创建这一层是痛苦的,因此编译器创建它是一项很好的任务。 But how?但是如何?

For instance, we want to set the document title in the current browser window.例如,我们要在当前浏览器窗口中设置文档标题。 The Wasm needs to access the current window instance, select the document, and set the title property of it. Wasm 需要访问当前窗口实例,选择文档,并设置它的标题属性。 As the Wasm runtime cannot access the references, we need to create a mapping table on JS side and some JS functions with mapping logic and import them into the Wasm module.由于 Wasm 运行时无法访问引用,我们需要在 JS 端创建一个映射表和一些带有映射逻辑的 JS 函数,并将它们导入到 Wasm 模块中。

So, we create a function called getWindow.因此,我们创建了一个名为 getWindow 的函数。 This function takes the global window reference, puts it into a mapping table and returns the index in the table.该函数获取全局窗口引用,将其放入映射表并返回表中的索引。 This index will be accessible as an I32 on Wasm side.该索引可以作为 Wasm 端的 I32 访问。 This function is imported into the Wasm module.这个函数被导入到 Wasm 模块中。

Now, we create a function called getDocumentFromWindow.现在,我们创建一个名为 getDocumentFromWindow 的函数。 This function takes an index into the mapping table, and returns another index.该函数将一个索引放入映射表,并返回另一个索引。 The implementation looks up the window reference from the mapping table and resolves its document property, and puts this document into the mapping table and returns that index to Wasm.该实现从映射表中查找窗口引用并解析其文档属性,然后将此文档放入映射表并将该索引返回给 Wasm。 This function is also imported into the Wasm module.该函数也被导入到 Wasm 模块中。

On the Wasm side, we can now indirectly manipulate Wasm host references by our imported functions.在 Wasm 方面,我们现在可以通过导入的函数间接操作 Wasm 主机引用。 Our mapping table emulates JS references by integer indices.我们的映射表通过整数索引模拟 JS 引用。 This is a slower version of what might come with the Wasm Reference Type proposal.这是 Wasm 引用类型提案可能附带的较慢版本。

So this whole mapping logic can be created by the compiler.所以整个映射逻辑可以由编译器创建。 Once reference types are available, the compiler can be changed and use the new type system for more efficient code.一旦引用类型可用,就可以更改编译器并使用新的类型系统来提高代码效率。

It you want to see such kind if compiler in action, take a look at https://github.com/mirkosertic/Bytecoder .如果您想看到这样的编译器在运行,请查看https://github.com/mirkosertic/Bytecoder It can compile JVM bytecode to JavaScript and WebAssembly and provides a transparent way for DOM and Browser API interaction in both ways.它可以将 JVM 字节码编译为 JavaScript 和 WebAssembly,并以两种方式为 DOM 和浏览器 API 交互提供透明的方式。 It is possible to call DOM from Wasm, and it is also possible to call Wasm from DOM, for instance to implement click-listeners and other cool stuff like interaction with high level frameworks like vue.js.可以从 Wasm 调用 DOM,也可以从 DOM 调用 Wasm,例如实现点击侦听器和其他很酷的东西,例如与 vue.js 等高级框架的交互。

Disclaimer: I am the inventor of Bytecoder, but the described logic can be adapted to any other compiler.免责声明:我是 Bytecoder 的发明者,但所描述的逻辑可以适用于任何其他编译器。

WebAssembly folks haven't any strong idea yet for what JS objects in WebAssembly are going to look like, it seems. WebAssembly 的人似乎对 WebAssembly 中的 JS 对象会是什么样子还没有任何强烈的想法。

I'd look through PR #1080 , which is about the Garbage Collection spec being spun off into it's own repo for now.我会查看 PR #1080 ,这是关于现在将垃圾收集规范分拆到它自己的回购中的内容。 But while that's happening they're removing the only mentions of the web platform & interop with JS objects that exist in the spec, which is described as:但是,在发生这种情况时,他们正在删除规范中存在的 Web 平台和与 JS 对象互操作的唯一提及,其描述为:

It's more aspirational that concrete,更令人向往的是混凝土,

I just came across js_ffi我刚遇到 js_ffi
https://github.com/richardanaya/js_ffi https://github.com/richardanaya/js_ffi
Not sure if it works for C as well, but it is advertised as such.不确定它是否也适用于 C,但它是这样宣传的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM