Presentamos Lucet: compilador y motor en tiempo de ejecución nativos de Fastly para WebAssembly

Nos hace mucha ilusión anunciar que abrimos el código de Lucet, compilador y motor en tiempo de ejecución nativos de Fastly para WebAssembly. WebAssembly es una tecnología que está diseñada para permitir que los navegadores web ejecuten programas en condiciones de seguridad a velocidades aproximadamente iguales a las nativas. Desde principios de 2017 viene incluido en los cuatro principales navegadores.

Lucet está concebido para impulsar a WebAssembly más allá de los límites del navegador y para diseñar una plataforma que permita una ejecución más rápida y segura en edge cloud de Fastly. Muchos lenguajes, como Rust, TypeScript, C y C++, ya son compatibles con WebAssembly, y muchos más están desarrollando esta compatibilidad. Nuestro objetivo es posibilitar que nuestros clientes trasciendan la versión de VCL que Fastly ha desarrollado, que acerquen todavía más lógica al edge y que utilicen el lenguaje que les apetezca. Lucet es el motor que hay detrás de Terrarium, nuestra plataforma experimental de computación en edge que utiliza WebAssembly. Pronto también lo pondremos a disposición en edge cloud de Fastly.

De entre los requisitos de diseño de Lucet, destacaba ser capaz de ejecutarse con cada una de las solicitudes que gestiona Fastly. Esto significa crear una instancia de WebAssembly por cada una de las decenas de miles de solicitudes por segundo en un único proceso, lo cual exige una un tiempo de ejecución que sea lo más reducido posible con un motor JavaScript para navegadores. Lucet puede crear una instancia de módulos de WebAssembly en menos de 50 microsegundos, con una sobrecarga de memoria de tan solo unos pocos kilobytes. En comparación, el motor V8 de Chromium tarda unos 5 milisegundos y decenas de megabytes de sobrecarga de memoria para crear una instancia de programas de JavaScript o WebAssembly.

Lucet permite a la nube de borde de Fastly ejecutar decenas de miles de programas de WebAssembly de forma simultánea, en el mismo proceso y sin poner en peligro la seguridad. El compilador y el tiempo de ejecución de Lucet se asocian para garantizar que a todos los programas de WebAssembly se les permita acceder únicamente a sus propios recursos. Esto quiere decir que los clientes de Fastly podrán escribir y ejecutar programas en lenguajes más habituales y aptos para fines generales sin arriesgar la seguridad y la protección que siempre hemos ofrecido.

Lucet divide la responsabilidad de ejecutar WebAssembly en dos componentes: un compilador, que compila módulos de WebAssembly a código nativo, y un motor en tiempo de ejecución, que gestiona recursos e intercepta fallos de tiempo de ejecución. Lucet está diseñado para compilaciones anticipadas o "ahead-of-time" (AOT) de WebAssembly a código nativo, lo cual simplifica profundamente el diseño y la sobrecarga del motor en tiempo de ejecución en comparación con la estrategia de compilaciones en tiempo de ejecución o "just-in-time" (JIT) que se emplea en los motores de los navegadores.

Cómo diseñamos Lucet

Lucet está diseñado a partir del  generador de códigos Cranelift. Mozilla creó el proyecto Cranelift para su uso con los motores JIT WebAssembly y JavaScript de Firefox; en la actualidad, Cranelift puede habilitarse por medio de una  marca de preferencia con Firefox Nightly. Nosotros contribuimos al diseño y la implementación de Cranelift y nos entusiasma constatar que nuestra labor también contribuye a mejorar la web para los usuarios de Firefox.

Lucet es compatible con WebAssembly System Interface (WASI) , nueva propuesta de norma destinada a exponer en condiciones de seguridad interfaces de bajo nivel que comunican el sistema de archivos, las funciones de red y otras instalaciones del sistema con programas de WebAssembly. El equipo de Lucet ha forjado alianzas con Mozilla y otros respecto del diseño, la implementación y la normalización de esta interfaz del sistema.

Llevamos trabajando en este proyecto entre bastidores desde 2017, de modo que nos embarga la emoción por hacerlo público finalmente. Además, da la casualidad de que Lucet es el primer proyecto que se inicia en Fastly con el lenguaje de programación Rust, medio que, nos complace anunciar, ha resultado ser un éxito arrollador. Constatamos que los nuevos usuarios de Rust lograban ser productivos con rapidez en el uso del lenguaje y que el ecosistema de bibliotecas proporciona muchas bibliotecas maduras para trabajar con WebAssembly. En las fases tempranas del desarrollo de Lucet, implementamos la primera versión del motor en tiempo de ejecución en C. Sin embargo, recientemente reanudamos el trabajo y tradujimos a Rust el tiempo en ejecución en C, proceso en el que descubrimos y solucionamos varios errores de seguridad y simultaneidad.

Puesto que se trata del motor del proyecto Terrarium, Lucet se ha beneficiado de meses de pruebas de producción y ha ejecutado varios miles de programas de WebAssembly diferentes desde su lanzamiento a finales de 2018. Además, su seguridad ha sido sometida a una evaluación en profundidad por terceros.

Rápida demostración de Lucet

En primer lugar, clona el repositorio de Lucet desde GitHub.

$ git clone --recurse-submodules https://github.com/fastly/lucet

El fichero README contiene instrucciones para usar Docker para configurar un entorno de desarrollo. Si ya tienes Docker, el proceso de instalación solo tiene un paso. Quizás te lleve unos minutos terminar de instalar todo.

$ cd lucet
$ source devenv_setenv.sh

En segundo lugar, crea un sencillo programa en C y utiliza Clang para compilarlo a WebAssembly:

$ mkdir demo
$ cd demo
$ cat > hello.c <<EOT
#include <stdio.h>
int main(int argc, char* argv[])
{
if (argc > 1) {
printf("Hello from Lucet, %s!\n", argv[1]);
} else {
puts("Hello, world!");
}
return 0;
}
EOT
$ wasm32-unknown-wasi-clang hello.c -o hello.wasm

En tercer lugar, podemos compilar el código de WebAssembly a código nativo mediante el compilador de Lucet, que estará configurado para su uso con WASI:

$ lucetc-wasi hello.wasm -o hello.so

En último lugar, podemos ejecutar el código nativo mediante el motor en tiempo de ejecución de Lucet configurado para su uso con WASI:

$ lucet-wasi hello.so
Hello, world!
$ lucet-wasi hello.so world
Hello from Lucet, world!

Encontrarás documentación y más ejemplos en el repositorio de Lucet.

Más allá de edge cloud

Nos emociona ofrecer Lucet en código abierto por todas las posibilidades que WebAssembly atesora más allá de los navegadores web y de la edge cloud. Por ejemplo, la compatibilidad con WASI que presenta Lucet es un paso gigantesco hacia la consecución de programas de WebAssembly que puedan ejecutarse en cualquier plataforma que desee el usuario —en la nube, en el borde, en el navegador o de forma nativa en tu portátil o móvil—, al tiempo que se cumplen las mismas sólidas garantías sobre la implementación de seguridad. Queremos hacer realidad que WebAssembly prospere dentro de cualquier programa que permita scripting o extensiones y, en paralelo, utilizar menos recursos que las soluciones actuales diseñadas con lenguajes dinámicos, intérpretes y compiladores JIT.

Lo más importante de todo es que queremos colaborar con la comunidad de código abierto respecto de Lucet, Cranelift, WASI y otras tecnologías que habilitan a WebAssembly. Fastly está diseñado con código abierto y ha asumido el compromiso de respaldarlo. Sin el código abierto, nunca habríamos podido diseñar Lucet. Esperamos que Lucet te permita crear cosas que a nosotros ni siquiera se nos hubiera pasado por la imaginación.

Pat Hickey
Principal Software Engineer
Fecha de publicación:

5 min de lectura

Comparte esta entrada
Pat Hickey
Principal Software Engineer

Pat Hickey es Principal Software Engineer en el equipo de aislamiento de Fastly. Anteriormente, trabajó en sistemas operativos y compiladores para sistemas de seguridad crítica.

¿List@ para empezar?

Ponte en contacto o crea una cuenta.