- En Go 1.24 se ampliaron las capacidades relacionadas con WebAssembly (Wasm)
- Se agregó la directiva
go:wasmexport, lo que permite llamar funciones de Go desde fuera del módulo Wasm - También se da soporte al modo de compilación “reactor” para WASI, lo que permite ejecutar código y mantenerlo activo durante largos periodos
- Con esto, se abre la posibilidad de ampliar con mayor flexibilidad las aplicaciones de Go en entornos Wasm
WebAssembly and the WebAssembly System Interface
- WebAssembly es un formato binario creado para ejecutar código de bajo nivel y alto rendimiento en navegadores web
- Actualmente también se usa ampliamente fuera del navegador, y mediante WebAssembly System Interface (WASI) puede interactuar con recursos del sistema
- Go comenzó a soportar compilación a Wasm en la versión 1.11 mediante el puerto js/wasm, y en la versión 1.21 añadió un nuevo puerto orientado a la API de llamadas al sistema de WASI Preview 1 mediante
GOOS=wasip1
Exportar funciones de Go a Wasm con go:wasmexport
- Con la directiva
go:wasmexport, incorporada en Go 1.24, ahora es posible exponer funciones de Go como exportaciones para que puedan ser llamadas desde fuera del módulo Wasm - Ejemplo: si se declara
//go:wasmexport addy luego se escribe la función, el host de Wasm podrá llamarla - Esto es similar a la directiva
exportde cgo, pero está implementado con un mecanismo más simple
Building a WASI Reactor
- Un WASI “reactor” se refiere a un módulo WebAssembly que permanece activo y puede responder a eventos o solicitudes
- En Go 1.24 se soporta la compilación de WASI reactor usando la opción
-buildmode=c-shared - Esta bandera de compilación le indica al linker que no genere la función
_start(punto de entrada de un módulo de comandos), sino que en su lugar genere la función_initialize- El reactor se inicializa mediante la función
_initialize, y esta debe llamarse primero en lugar de la funciónmain
- El reactor se inicializa mediante la función
- Si se usa junto con runtimes como Wazero, después de llamar a
_initializese pueden volver a invocar las funciones exportadas tantas veces como se quiera - Este enfoque es útil en entornos donde Wasm se utiliza como mecanismo de plugins o extensiones de una aplicación
Soporte de tipos más rico entre host y cliente
- En Go 1.24 se flexibilizaron las restricciones sobre los parámetros y tipos de retorno de las funciones llamadas con
go:wasmimport - Por ejemplo, se pueden pasar bool, string, punteros a int32 y punteros a estructuras
- Aun así, siguen existiendo limitaciones por diferencias entre entornos de 64 y 32 bits, entre otras
- Esto permite escribir aplicaciones Go Wasm de una manera más natural y cómoda, eliminando conversiones de tipos innecesarias
Limitaciones
- Wasm es una arquitectura de un solo hilo, sin procesamiento paralelo
- Las funciones
go:wasmexportpueden crear nuevas goroutines, pero las funciones que crean goroutines en segundo plano no continúan ejecutándose después de que la funcióngo:wasmexportretorna, hasta que el módulo Wasm basado en Go sea invocado nuevamente - Aunque algunas restricciones de tipos se relajaron, todavía hay limitaciones sobre los tipos que pueden usarse con funciones
go:wasmimportygo:wasmexport- Sigue habiendo restricciones al pasar tipos compuestos que incluyan punteros
Conclusión
- La incorporación de la compilación WASI reactor y de
go:wasmexporten Go 1.24 es una mejora que amplía de forma importante el ecosistema Wasm de Go - Esto permite a los desarrolladores crear una mayor variedad de aplicaciones Wasm basadas en Go, abriendo nuevas posibilidades para Go dentro del ecosistema Wasm
3 comentarios
Antes de que
Wasm/gcse adopte de forma generalizada, creo que será mejor desarrollar para el target de wasm con lenguajes que no tengan gc.En el lanzamiento de Go 1.24 lo explican brevemente, pero es una actualización mucho más importante.
Opiniones en Hacker News
Los binarios WASM generados con Go tienen el gran problema de ser muy grandes. TinyGo lo supera, pero la compilación es lenta y hay que elegir con cuidado las librerías. Superar ambos problemas requiere mucha paciencia
hello-worldpudo ejecutarse, pero algo más complejo superó el límite de tamañoEs sorprendente. Algo para tener en cuenta:
No recuerdo bien si antes de Go 1.24 ya era posible exportar funciones de Go a JS. Recuerdo haber llamado desde JS funciones exportadas de Go sin problemas anteriormente
goos=wasip1sigue siendo válidaHabría sido más "Go" exportar todas las funciones que empiezan con mayúscula en el paquete principal. Como la exportación normalmente funciona así en el lenguaje, parecería mejor usar una directiva del compilador solo cuando se quiera nombrar explícitamente algo que empieza con minúscula
No se menciona nada sobre trabajar con el modelo de componentes de WASM
Me pregunto cómo funciona el garbage collection de Go con WASM
Ojalá existiera un lenguaje de bajo nivel con tipado fuerte y un soporte excelente para WASM
Me pregunto cómo se depura un módulo WASM ejecutándose dentro de un programa host
Me preocupa que el deseo de tener más funciones en WASM termine dañando irreversiblemente este ecosistema joven. La mayoría de las funciones que Go agregó a WASM podrían haberse hecho de forma nativa si la propuesta del modelo de componentes ya se hubiera integrado