- Dans Go 1.24, les fonctionnalités liées à WebAssembly (Wasm) ont été étendues
- La directive
go:wasmexporta é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
exportde 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
- Le reactor est initialisé via la fonction
- 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:wasmimportont été assouplies - Il est par exemple possible de transmettre des bool, des string, des pointeurs vers
int32ou 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:wasmexportpeuvent 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 fonctiongo:wasmexporttant 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:wasmimportetgo: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:wasmexportdans 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
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.
Dans la sortie de Go 1.24, c’est seulement brièvement évoqué, mais c’est une mise à jour bien plus importante que ça.
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
C’est surprenant. À garder en tête :
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
goos=wasip1reste valableIl 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
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