Cómo funcionan los compiladores online: código en tu navegador

Los compiladores que funcionan en el navegador ejecutan tu código dentro de la propia página web, mediante WebAssembly: un formato binario compacto y aislado en un entorno seguro (sandbox) que los navegadores traducen a código máquina rápido. Compiladores e intérpretes reales como Clang, CPython, R y SQLite se compilan a su vez a WebAssembly, se descargan una sola vez y después compilan o ejecutan tu programa en tu propio dispositivo, sin enviar nada a un servidor. Los compiladores online tradicionales funcionan al revés: suben tu código a un servidor que lo ejecuta y te devuelve la salida.

Puntos clave
  • WebAssembly es un destino de compilación portable que todos los navegadores principales ejecutan a una velocidad cercana a la del código nativo, dentro del mismo entorno aislado de seguridad que JavaScript.
  • Nuestros compiladores de C y C++ ejecutan Clang en la pestaña: convierte tu código en un módulo WebAssembly, que luego se ejecuta con una pequeña capa WASI que se encarga de la entrada y la salida.
  • Python, R, SQL, Ruby, PHP, Lua y Prolog se ejecutan como compilaciones a WebAssembly de sus intérpretes oficiales; los lenguajes de la familia JavaScript usan el motor del propio navegador.
  • Ejecutar en local significa privacidad, ninguna cola de servidor y uso sin conexión una vez que el entorno de ejecución está en caché.
  • A cambio hay una descarga inicial, no hay hilos ni sockets de red, el sistema de archivos es temporal y está en memoria y, en nuestra compilación de C++, no hay excepciones.

Qué es WebAssembly

WebAssembly (a menudo abreviado como Wasm) es un formato de instrucciones de bajo nivel diseñado como destino de compilación. Normalmente no se escribe a mano. En su lugar, un compilador como Clang o el compilador de Rust genera un archivo .wasm a partir de código fuente corriente, igual que generaría un ejecutable para un procesador x86 o ARM. El formato es un estándar abierto desarrollado en el W3C, documentado en webassembly.org, y es compatible con Chrome, Edge, Firefox y Safari.

Tres propiedades lo hacen útil para ejecutar código en un navegador:

  • Portable. El mismo archivo .wasm funciona en Windows, macOS, Linux, Android e iOS, en cualquier procesador, porque el navegador lo traduce al código máquina local.
  • Rápido. WebAssembly tiene tipos y está cerca del hardware, así que los motores del navegador pueden compilarlo antes de la ejecución a código máquina eficiente. El código que exige mucha CPU suele ejecutarse bastante más rápido que el JavaScript equivalente y en el mismo orden de magnitud que el código nativo, aunque normalmente algo más lento.
  • Aislado. Un módulo WebAssembly recibe un bloque de memoria privada y solo puede llamar a las funciones que se le entregan de forma explícita. No puede leer tus archivos, abrir conexiones de red ni tocar el resto de la página a menos que el código anfitrión le dé una forma de hacerlo.

WASI: una interfaz de sistema para WebAssembly

Un programa en C espera un sistema operativo: algo de donde leer la entrada estándar, donde escribir la salida, con lo que abrir archivos y obtener la hora. WebAssembly no incluye nada de eso. La WebAssembly System Interface (WASI) define un conjunto estándar de esas funciones que un programa WebAssembly puede importar. Fuera del navegador, entornos como Wasmtime implementan WASI sobre un sistema operativo real. Dentro de un navegador, una pequeña biblioteca de JavaScript llamada WASI shim implementa esas funciones sobre datos en memoria.

Cómo funcionan los compiladores online tradicionales

La mayoría de los compiladores online veteranos y de los sitios de ejercicios de programación ejecutan tu código en sus servidores:

  1. Tu navegador envía el código fuente (y cualquier entrada) al servidor del sitio web.
  2. El servidor lo coloca en un entorno aislado, normalmente un contenedor o una máquina virtual ligera, con límites de tiempo, memoria y procesos.
  3. El compilador o intérprete real instalado allí compila y ejecuta el programa.
  4. La salida se captura y se devuelve a tu navegador, y el entorno se descarta.

Este modelo tiene ventajas reales. El servidor puede ofrecer casi cualquier lenguaje y versión, funciones completas del sistema operativo como hilos y procesos y, a veces, acceso a la red y bibliotecas grandes. Pero tu código sale de tu dispositivo, los servicios muy concurridos pueden poner las peticiones en cola, cada ejecución depende de un viaje de ida y vuelta por la red y el operador tiene que pagar la potencia de cálculo de cada ejecución, por lo que muchos limitan el número de ejecuciones o exigen una cuenta.

Cómo funcionan nuestros compiladores en el navegador

En nuestros compiladores online, el entorno de ejecución de cada lenguaje se descarga en tu navegador y se ejecuta dentro de un Web Worker, un hilo en segundo plano que mantiene la página receptiva mientras tu programa se ejecuta. Un límite de tiempo y un botón Detener permiten que la página termine el worker si un programa tarda demasiado, por ejemplo por un bucle infinito. Los archivos del entorno de ejecución están fijados a versiones exactas y la mayoría se comprueba con un hash criptográfico antes de ejecutarse.

C y C++: un compilador real en la pestaña

El compilador de C online y el compilador de C++ online usan Clang 21, el compilador basado en LLVM, empaquetado como WebAssembly por el proyecto YoWASP. Cada ejecución se realiza en dos fases:

  1. Compilar. Clang, que a su vez se ejecuta como WebAssembly, compila tu main.c o main.cpp con la optimización y los avisos activados (C17 o C++20). Su resultado no es un ejecutable x86 o ARM, sino un nuevo módulo WebAssembly que tiene WASI como destino. Los avisos y errores del compilador se muestran tal como los imprime Clang.
  2. Ejecutar. El navegador compila ese módulo a código máquina y lo inicia con un WASI shim. El shim conecta la entrada estándar con el texto del cuadro de entrada y envía la salida estándar y el error estándar al panel de salida.

Dicho de otro modo, un compilador compilado a WebAssembly produce tu programa compilado a WebAssembly, y ambos se ejecutan en la misma pestaña.

Intérpretes compilados a WebAssembly

LenguajeEntorno de ejecuciónQué es
PythonPyodideCPython, el intérprete de referencia de Python, compilado a WebAssembly. También hay paquetes como NumPy y pandas ya compilados para él.
RwebRLa compilación oficial de R a WebAssembly, con los gráficos base incluidos.
SQLsql.jsEl motor de base de datos SQLite compilado a WebAssembly, con la base de datos guardada en memoria.
Rubyruby.wasmEl intérprete oficial CRuby compilado para WASI, con su biblioteca estándar.
PHPphp-wasmEl intérprete de PHP compilado a WebAssembly.
LuawasmoonEl intérprete de referencia de Lua 5.4 compilado a WebAssembly.
Prologswipl-wasmSWI-Prolog compilado a WebAssembly.

Como son los mismos intérpretes que la gente instala en sus ordenadores, el comportamiento y los mensajes de error coinciden en gran medida con los de las versiones de escritorio. Puedes probarlos en el compilador de Python online, el compilador de R online y el compilador de SQL online.

Lenguajes que usan el motor del propio navegador

Algunos lenguajes no necesitan WebAssembly en absoluto. El compilador de JavaScript online ejecuta el código directamente en el motor de JavaScript del navegador. TypeScript y CoffeeScript se traducen a JavaScript con sus compiladores oficiales, que se distribuyen como JavaScript, y el resultado se ejecuta de la misma manera. Scheme usa BiwaScheme y Clojure usa SCI (el Small Clojure Interpreter), dos intérpretes que a su vez se ejecutan como JavaScript.

Ventajas de ejecutar código en el navegador

  • Privacidad. Tu código fuente y tu entrada se quedan en tu dispositivo. No se suben a nuestro servidor, que tampoco los almacena ni los registra, porque nunca los recibe.
  • Sin cola y sin cuenta. Cada visitante usa su propio procesador, así que no hay una cola de ejecución compartida ni hace falta racionar las ejecuciones.
  • Funciona sin conexión tras la carga. Una vez descargados y guardados en caché la página y el entorno de ejecución, puedes seguir editando y ejecutando código si se corta la conexión, siempre que la pestaña siga abierta. Los paquetes adicionales que se cargan bajo demanda, como algunas bibliotecas de Python, siguen necesitando conexión la primera vez.
  • Ejecuciones repetidas rápidas. Después de la primera carga, los lenguajes interpretados arrancan casi al instante y no hay viaje de ida y vuelta por la red entre pulsar Ejecutar y ver la salida.

Límites y compromisos

LímitePor qué existeQué significa en la práctica
Tamaño de descargaEl compilador o intérprete completo tiene que llegar a tu navegador.Clang, R y Ruby pesan decenas de megabytes; Lua y SQLite, menos de uno. Las visitas posteriores usan la caché del navegador.
Sin hilosNuestros entornos de ejecución son de un solo hilo; los hilos de WebAssembly requieren ajustes de aislamiento adicionales en el navegador y compatibilidad en el entorno de ejecución.pthread, std::thread o threading de Python para paralelismo real no funcionarán como en un ordenador de escritorio.
Sin sockets de redEl sandbox no da a los programas ninguna forma de abrir conexiones de red directas.El código que abra sockets o haga peticiones HTTP desde C, Python o R fallará. El JavaScript del navegador sí puede seguir usando fetch.
Sin sistema de archivos realLos entornos de ejecución reciben, como mucho, un sistema de archivos virtual en memoria, nunca tu disco.Python y algunos otros entornos pueden crear archivos durante una sesión, pero desaparecen al cerrar la página; nuestros programas de C y C++ solo disponen de entrada y salida estándar.
Sin excepciones de C++Nuestra compilación de C++ se hace con las excepciones desactivadas (-fno-exceptions).El código que use try, catch o throw no compilará; usa valores de retorno o códigos de error en su lugar.
MemoriaWebAssembly de 32 bits puede direccionar como máximo 4 GiB, y los navegadores o dispositivos pueden permitir menos.Los arrays o conjuntos de datos muy grandes pueden fallar con errores de memoria agotada, sobre todo en móviles.
La entrada no es interactivaLa entrada estándar se proporciona antes de que arranque el programa.Escribe antes toda la entrada en el cuadro de entrada; las peticiones de datos no pueden esperarte a mitad de la ejecución.

Para aprender, probar algoritmos y hacer trabajos de clase, estos límites rara vez importan. Para programas que necesiten red, varios procesos o mucha memoria, usa una instalación local o un entorno basado en servidor.

El modelo de seguridad

Ejecutar código arbitrario suena arriesgado, pero los compiladores en el navegador se apoyan en protecciones que los navegadores ya aplican a todos los sitios web.

  • Aislamiento de WebAssembly. Un módulo solo puede leer y escribir su propia memoria lineal, con comprobación de límites, y solo puede llamar a las funciones que se le importan de forma explícita. Un programa en C con un desbordamiento de búfer puede corromper su propia memoria, pero no puede escapar al navegador ni al sistema operativo.
  • El sandbox del navegador. Todo el código de la página, incluidos WebAssembly y los Web Workers, se ejecuta dentro del sandbox de procesos del navegador y de las reglas de mismo origen, así que no puede leer datos de otros sitios ni tus archivos.
  • Workers y límites de tiempo. Ejecutar en un worker significa que un programa descontrolado se puede terminar sin congelar ni recargar la página.
  • Entornos de ejecución verificados. Fijar versiones exactas del entorno de ejecución, y comprobar los hashes cuando el método de carga lo permite, protege frente a que una red de distribución de contenido sirva en silencio un archivo distinto o modificado.

Una salvedad: el JavaScript que ejecutas en el compilador de JavaScript tiene las mismas capacidades que cualquier script de una página web, incluida la de hacer peticiones de red. Como con cualquier código, ejecuta solo fragmentos que entiendas, sobre todo si los has copiado de desconocidos.

Cuándo usar cada tipo de compilador online

  1. Si tu código es privado, por ejemplo trabajos de clase o código del trabajo, elige un compilador en el navegador para que nunca salga de tu dispositivo.
  2. Si necesitas hilos, sockets, una biblioteca concreta del sistema o un lenguaje sin compilación a WebAssembly, usa un servicio basado en servidor o una instalación local.
  3. Si tienes una conexión lenta o con datos limitados, empieza por los entornos de ejecución más ligeros; la primera carga de uno grande es el principal coste.

Preguntas frecuentes

¿Se envía mi código a un servidor cuando uso estos compiladores online?

No. La página descarga el compilador o intérprete, y tu código y tu entrada se compilan y ejecutan en tu propio dispositivo. El servidor solo entrega la página y los archivos del entorno de ejecución.

¿WebAssembly es tan rápido como el código nativo?

Suele acercarse, pero es algo más lento, y la diferencia depende de la carga de trabajo y del navegador. En ejercicios y algoritmos típicos la diferencia no se nota; la descarga de la primera vez es el retraso mayor.

¿Por qué la primera ejecución tarda más?

La primera ejecución descarga e inicializa el entorno de ejecución, lo que en el caso de Clang, R o Ruby son decenas de megabytes. El navegador guarda esos archivos en caché, así que las visitas posteriores arrancan mucho más rápido.

¿Por qué no compila mi código C++ con try y catch?

Nuestra compilación de C++ se hace con las excepciones desactivadas, porque el manejo de excepciones en WebAssembly necesita un soporte adicional de la cadena de herramientas y del entorno de ejecución que esta configuración no utiliza. Reescribe el manejo de errores con valores de retorno, std::optional o códigos de error, o compila en local si necesitas excepciones.

¿Puede un programa de un compilador online dañar mi ordenador?

El código que se ejecuta como WebAssembly en el navegador queda confinado a su propia memoria y a las funciones que ofrece la página, y el sandbox del navegador añade otra capa. No puede leer tus archivos ni instalar software. El código JavaScript sí puede hacer peticiones web como cualquier script de página, así que evita ejecutar código en el que no confíes.

Pruébalo tú mismo

Pon en práctica esta guía con nuestras herramientas gratuitas.

Sigue leyendo

Copiado al portapapeles