web-dev-qa-db-fra.com

Accès au Wasm DOM

Existe-t-il un moyen d'obtenir un accès en lecture/écriture au DOM et/ou aux WebAPI (c'est-à-dire l'API plein écran) sans JavaScript?

J'essaie de construire une application de base en C (la source C étant en fait le résultat d'une transpilation à partir d'un langage GC). L'application que je crée s'exécutera en tant qu'application de bureau (elle n'est pas encore censée fonctionner dans les "vrais" navigateurs) afin que je puisse modifier l'environnement (c'est-à-dire le moteur de disposition) si nécessaire.

17
themihai

Dans le produit WebAssembly Minimal Viable, le seul moyen d'appeler dans et hors de WebAssembly est via les importations et les exportations. À l'avenir, WebAssembly peut gagner des capacités qui permettent à l'embedder d'exposer directement les API , dans un navigateur incorporant cela pourrait inclure le DOM.

Imports et exports ne sont cependant pas très compliqués: du point de vue de votre code C, ils ressemblent simplement à un appel extern, semblable à un DLL sur la plate-forme Windows. Vous compilerez probablement le code C à l'aide d'Emscripten, voir sa documentation "Appeler les fonctions JavaScript depuis C/C++" pour plus de détails sur la façon dont cela fonctionne (depuis ce n'est pas la question que vous posez, mais je suppose que c'est la question suivante).


Votre question ne précise pas si vous:

  1. Vous voulez compiler du code C et l'exécuter dans WebAssembly à l'intérieur d'un navigateur.
  2. Vous voulez compiler du code C et l'exécuter dans WebAssembly en dehors d'un navigateur.

Ou les deux.

13
JF Bastien

Tout dépend des capacités du compilateur.

Actuellement, il n'y a aucun moyen d'accéder directement au DOM ou à toute autre API de navigateur. Il n'est pas non plus possible de stocker des références JavaScript à l'intérieur de la mémoire linéaire Wasm ou des tables Wasm. Il n'est pas non plus possible d'utiliser des références JavaScript comme arguments de fonction ou valeurs de retour. Ils n'existent tout simplement pas dans le système de type MVP. Cependant, il existe la proposition de type de référence, qui pourrait un jour faire partie de l'exécution de Wasm, mais aucune date de sortie officielle n'est disponible.

Alors, comment peut-on réaliser l'interaction Wasm to Host Environment? Eh bien, il s'avère que le système de modules Wasm avec des importations et des exportations peut être utilisé pour créer une couche d'émulation. La création de cette couche à la main est pénible, c'est donc une bonne tâche pour un compilateur de la créer. Mais comment?

Par exemple, nous voulons définir le titre du document dans la fenêtre actuelle du navigateur. Le Wasm doit accéder à l'instance de fenêtre actuelle, sélectionner le document et définir la propriété title de celui-ci. Comme le runtime Wasm ne peut pas accéder aux références, nous devons créer une table de mappage côté JS et certaines fonctions JS avec une logique de mappage et les importer dans le module Wasm.

Donc, nous créons une fonction appelée getWindow. Cette fonction prend la référence de fenêtre globale, la place dans une table de mappage et renvoie l'index dans la table. Cet index sera accessible en tant que I32 côté Wasm. Cette fonction est importée dans le module Wasm.

Maintenant, nous créons une fonction appelée getDocumentFromWindow. Cette fonction prend un index dans la table de mappage et renvoie un autre index. L'implémentation recherche la référence de fenêtre à partir de la table de mappage et résout sa propriété de document, et place ce document dans la table de mappage et renvoie cet index à Wasm. Cette fonction est également importée dans le module Wasm.

Du côté de Wasm, nous pouvons maintenant manipuler indirectement les références de l'hôte Wasm par nos fonctions importées. Notre table de mappage émule les références JS par des indices entiers. Il s'agit d'une version plus lente de ce qui pourrait accompagner la proposition de type de référence Wasm.

Donc, toute cette logique de mappage peut être créée par le compilateur. Une fois les types de référence disponibles, le compilateur peut être modifié et utiliser le nouveau système de types pour un code plus efficace.

Si vous voulez voir ce genre de compilateur en action, jetez un œil à https://github.com/mirkosertic/Bytecoder . Il peut compiler le bytecode JVM en JavaScript et WebAssembly et fournit un moyen transparent pour l'interaction DOM et API du navigateur dans les deux sens. Il est possible d'appeler DOM à partir de Wasm, et il est également possible d'appeler Wasm à partir de DOM, par exemple pour implémenter des écouteurs de clics et d'autres trucs sympas comme l'interaction avec des cadres de haut niveau comme vue.js.

Avertissement: je suis l'inventeur de Bytecoder, mais la logique décrite peut être adaptée à tout autre compilateur.

3
Mirko Sertic

Les gens de WebAssembly n'ont pas encore d'idée solide à quoi ressembleront les objets JS dans WebAssembly, semble-t-il.

Je regarderais à travers PR # 108 , qui concerne la spécification de Garbage Collection qui est filée dans son propre référentiel pour l'instant. Mais pendant ce temps, ils suppriment les seules mentions de la plate-forme Web et interagissent avec les objets JS qui existent dans la spécification, qui est décrite comme:

It's more aspirational that concrete,
1
rektide