Wasm access DOM

烂漫一生 提交于 2020-07-17 03:52:12

问题


Is there any way to get read/write access to DOM and/or the WebAPIs(i.e. fullscreen API) without JavaScript?

I'm trying to build a basic application in C(C source being actually the result of transpilation from a GC language). 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(i.e. the layout engine) if necessary.


回答1:


In the WebAssembly Minimal Viable Product the only way to call into and out of WebAssembly is through imports and exports. In the future, WebAssembly may gain capabilities which allow the embedder expose APIs directly, in a browser embedding this could include the 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. 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).


It's not clear from your question if you:

  1. Want to compile C code and run it within WebAssembly inside a browser.
  2. Want to compile C code and run it within WebAssembly outside a browser.

Or both.




回答2:


WebAssembly folks haven't any strong idea yet for what JS objects in WebAssembly are going to look like, it seems.

I'd look through PR #1080, which is about the Garbage Collection spec being spun off into it's own repo for now. 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:

It's more aspirational that concrete,



回答3:


It all depends on compiler capabilities.

Currently there is no way to access the DOM or any other browser API directly. It is also not possible to store JavaScript references inside of Wasm linear memory or Wasm tables. It is also not possible to use JavaScript references as function arguments or return values. They just do not exists in the MVP type system. However, there is the Reference Type Proposal, which might someday become part of the Wasm runtime, but there is no official release date available.

So, how can Wasm to Host Environment interaction be done? Well, it turns out that the Wasm module system with imports and exports can be used to create an emulation layer. 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. 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.

So, we create a function called 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. This function is imported into the Wasm module.

Now, we create a function called 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. This function is also imported into the Wasm module.

On the Wasm side, we can now indirectly manipulate Wasm host references by our imported functions. Our mapping table emulates JS references by integer indices. This is a slower version of what might come with the Wasm Reference Type proposal.

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. It can compile JVM bytecode to JavaScript and WebAssembly and provides a transparent way for DOM and Browser API interaction in both ways. 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.

Disclaimer: I am the inventor of Bytecoder, but the described logic can be adapted to any other compiler.




回答4:


I just came across js_ffi
https://github.com/richardanaya/js_ffi
Not sure if it works for C as well, but it is advertised as such.



来源:https://stackoverflow.com/questions/42628328/wasm-access-dom

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!