1 points par GN⁺ 2025-02-16 | 3 commentaires | Partager sur WhatsApp
  • Dans Go 1.24, les fonctionnalités liées à WebAssembly (Wasm) ont été étendues
  • La directive go:wasmexport a été ajoutée, ce qui permet d’appeler des fonctions Go depuis l’extérieur d’un module Wasm
  • Un mode de build « reactor » pour WASI est également pris en charge, ce qui permet d’exécuter du code en restant actif sur une longue durée
  • Cela ouvre la voie à une extension plus souple des applications Go dans les environnements Wasm

WebAssembly and the WebAssembly System Interface

  • WebAssembly est un format binaire conçu pour exécuter du code bas niveau à hautes performances dans les navigateurs web
  • Il est désormais largement utilisé en dehors du navigateur, et peut interagir avec les ressources système via la WebAssembly System Interface (WASI)
  • Go a commencé à prendre en charge la compilation vers Wasm avec le port js/wasm dans la version 1.11, puis a ajouté dans la version 1.21 un nouveau port ciblant l’API des appels système WASI Preview 1 via GOOS=wasip1

Export de fonctions Go en Wasm avec go:wasmexport

  • Grâce à la directive go:wasmexport, ajoutée dans Go 1.24, il est possible d’exposer des fonctions Go en export afin qu’elles puissent être appelées depuis l’extérieur du module Wasm
  • Exemple : après une déclaration comme //go:wasmexport add, la fonction peut être appelée par l’hôte Wasm
  • Cela ressemble à la directive export de cgo, mais avec un mécanisme plus simple

Building a WASI Reactor

  • Un « reactor » WASI désigne un module WebAssembly qui reste actif en continu et peut réagir à des événements ou à des requêtes
  • Dans Go 1.24, la construction d’un reactor WASI est prise en charge via l’option -buildmode=c-shared
  • Ce drapeau de build indique à l’éditeur de liens de ne pas générer la fonction _start (point d’entrée d’un module de commande), mais de générer à la place une fonction _initialize
    • Le reactor est initialisé via la fonction _initialize, qui doit être appelée avant toute chose à la place de la fonction main
  • Utilisé avec un runtime comme Wazero, il devient possible d’appeler _initialize, puis de réappeler autant de fois que souhaité les fonctions exportées
  • Cette approche est utile dans les environnements qui exploitent Wasm comme mécanisme de plugin ou d’extension applicative

Prise en charge de types enrichie entre l’hôte et le client

  • Dans Go 1.24, les contraintes sur les paramètres et les types de retour des fonctions appelées via go:wasmimport ont été assouplies
  • Il est par exemple possible de transmettre des bool, des string, des pointeurs vers int32 ou des pointeurs vers des structures
    • Des limitations subsistent toutefois, notamment en raison des différences entre environnements 64 bits et 32 bits
  • Cela permet d’écrire des applications Go Wasm de manière plus naturelle et plus pratique, en supprimant des conversions de types inutiles

Limitations

  • Wasm repose sur une architecture monothread sans traitement parallèle
  • Les fonctions go:wasmexport peuvent créer de nouvelles goroutines, mais si elles lancent des goroutines en arrière-plan, celles-ci ne continueront pas à s’exécuter après le retour de la fonction go:wasmexport tant que le module Wasm Go n’aura pas été rappelé
  • Même si certaines restrictions de types ont été assouplies, il existe encore des limites sur les types utilisables avec les fonctions go:wasmimport et go:wasmexport
    • La transmission de types composites incluant des pointeurs reste encore contrainte

Conclusion

  • L’ajout de la construction de reactors WASI et de la fonctionnalité go:wasmexport dans Go 1.24 constitue une amélioration importante de l’écosystème Wasm de Go
  • Cela permet aux développeurs de créer une plus grande variété d’applications Wasm basées sur Go et ouvre de nouvelles possibilités pour Go dans l’écosystème Wasm

3 commentaires

 
click 2025-02-16

Avant l’adoption généralisée de Wasm/gc, il me semble préférable de développer pour la cible wasm avec un langage sans gc.

 
xguru 2025-02-16

Dans la sortie de Go 1.24, c’est seulement brièvement évoqué, mais c’est une mise à jour bien plus importante que ça.

 
GN⁺ 2025-02-16
Avis Hacker News
  • Les binaires WASM générés par Go ont le gros défaut d’être très volumineux. TinyGo contourne ce problème, mais la compilation est lente et il faut faire attention au choix des bibliothèques. Pour surmonter les deux, il faut beaucoup de patience

    • Pour essayer Go WASM sur Cloudflare Workers, un abonnement est nécessaire à cause de la taille du binaire
    • Lors de la dernière tentative, le hello-world fonctionnait, mais tout ce qui était plus complexe dépassait la limite de taille
    • C’est regrettable
  • C’est surprenant. À garder en tête :

    • Le travail sur WebAssembly dans Go a été conçu et implémenté par des bénévoles, et non par l’équipe Go. Le calendrier dépend donc de la disponibilité des bénévoles
  • Je ne me souviens plus très bien s’il n’était pas déjà possible, avant Go 1.24, d’exporter des fonctions Go vers JS. Il me semble me souvenir avoir appelé depuis JS des fonctions Go exportées sans problème auparavant

    • Ce serait utile d’expliquer en quoi les nouvelles fonctionnalités WASI constituent une amélioration par rapport à avant (au-delà de la prise en charge de davantage de types via la FFI)
    • Deuxième question : il était possible de convertir des pointeurs en entiers pour extraire des chaînes et des types complexes depuis la mémoire d’instance du module WASM. Si la représentation binaire de mes types en Go est garantie stable, je me demande si cette méthode de passage de pointeurs vers un module WASM généré avec goos=wasip1 reste valable
  • Il aurait été plus « Go » d’exporter toutes les fonctions du package principal qui commencent par une majuscule. Comme l’export fonctionne déjà ainsi dans le langage, il vaudrait mieux n’utiliser une directive du compilateur que lorsqu’on veut nommer explicitement quelque chose qui commence par une minuscule

    • C’est identique à la méthode d’export existante de cgo. Cela suit les exemples précédents. L’ergonomie reste malgré tout en dehors du langage
  • Aucune mention du travail avec le modèle de composants WASM

  • Je me demande comment fonctionnent les garbage collectors de Go et de WASM

  • J’aimerais qu’il existe un langage de bas niveau avec un typage fort et un excellent support de WASM

  • Je me demande comment on débogue un module WASM en cours d’exécution depuis le programme hôte

  • Je crains que la volonté d’ajouter toujours plus de fonctionnalités à WASM n’endommage irrémédiablement un écosystème encore jeune. La plupart des fonctionnalités que Go a ajoutées à WASM auraient pu être réalisées nativement si la proposition du modèle de composants avait déjà été fusionnée

    • Le standard évolue lentement, et avec l’augmentation de l’adoption, il existe un risque de devoir prendre en charge indéfiniment des fonctionnalités non standard comme WASI