El sitio de retos de programación dailyprog.club empezó con JavaScript, sumó después Python (vía Pyodide) y C (con PicoC compilado a WASM), y abordó la integración de Go como cuarto lenguaje. El autor probó primero la ruta convencional: compilar con GOOS=js GOARCH=wasm y apoyarse en wasm_exec.js. Esa vía asume un navegador completo, pero dailyprog ejecuta el código de los usuarios dentro de isolated-vm, un aislado de V8 sin DOM ni bucle de eventos. La inicialización basada en WebAssembly.instantiate() nunca termina porque nada en el aislado conduce la promesa, y el puente syscall/js captura un globalThis distinto del que ve el código.
La solución adoptada fue cambiar a GOOS=wasip1 GOARCH=wasm, disponible desde Go 1.21. WASI define un conjunto pequeño de importaciones (fd_write, args_get, clock_time_get, random_get, proc_exit) que el anfitrión implementa sobre memoria lineal, sin promesas ni objetos globales. El autor escribió un shim de unas cincuenta líneas en JavaScript que implementa fd_write para capturar la salida de fmt.Println, devuelve ENOSYS o EBADF para el resto y distingue salidas limpias de caídas con un prefijo centinela en proc_exit.
El intérprete elegido es Yaegi, compilado a WASI, lo que produce un binario WASM de 38 MB. Como WASI es de un solo disparo, se almacena en caché el WebAssembly.Module compilado y se crea una instancia nueva por ejecución, actualizando la referencia de memoria en los shims. El resultado: añadir Go requirió siete archivos nuevos y apenas veinte líneas en el servidor (GoSandbox replica CSandbox) más un módulo de 130 líneas en el navegador. Cualquier lenguaje con intérprete que compile a WASM puede sumarse ya siguiendo el mismo patrón.
