WebAssembly ( Wasm ) define un formato de código binario portátil y un formato de texto correspondiente para programas ejecutables [2] así como interfaces de software para facilitar la comunicación entre dichos programas y su entorno host. [3] [4] [5] [6]
El objetivo principal de WebAssembly es facilitar aplicaciones de alto rendimiento en páginas web , pero también está diseñado para ser utilizable en entornos no web. [7] Es un estándar abierto [8] [9] destinado a soportar cualquier lenguaje en cualquier sistema operativo, [10] y en la práctica muchos de los lenguajes más populares ya tienen al menos algún nivel de soporte.
Anunciado en 2015 y lanzado por primera vez en marzo de 2017 , WebAssembly se convirtió en una recomendación del Consorcio World Wide Web el 5 de diciembre de 2019 [11] [12] [13] y recibió el Premio de Software de Lenguajes de Programación de ACM SIGPLAN en 2021. [14] El Consorcio World Wide Web (W3C) mantiene el estándar con contribuciones de Mozilla , Microsoft , Google , Apple , Fastly , Intel y Red Hat . [15] [16]
El nombre WebAssembly pretende parecer sinónimo del lenguaje ensamblador . El nombre sugiere llevar la programación similar al lenguaje ensamblador a la Web , donde se ejecutará del lado del cliente , por la computadora del usuario del sitio web a través del navegador web del usuario . Para lograr esto, WebAssembly debe ser mucho más independiente del hardware que un verdadero lenguaje ensamblador.
WebAssembly se anunció por primera vez en 2015, [17] y la primera demostración fue la ejecución de Angry Bots de Unity en Firefox , [18] Google Chrome , [19] y Microsoft Edge . [20] Las tecnologías precursoras fueron asm.js de Mozilla y Google Native Client , [21] [22] y la implementación inicial se basó en el conjunto de características de asm.js. [23] El archivo asm.js ya proporciona velocidades de ejecución de código casi nativas [24] [25] y puede considerarse una alternativa viable para los navegadores que no admiten WebAssembly o lo tienen deshabilitado por razones de seguridad.
En marzo de 2017, se declaró que el diseño del producto mínimo viable (MVP) estaba terminado y la fase de vista previa finalizó. [26] A fines de septiembre de 2017, se lanzó Safari 11 con soporte. En febrero de 2018, el grupo de trabajo de WebAssembly publicó tres borradores de trabajo públicos para la especificación principal, la interfaz de JavaScript y la API web. [27] [28] [29] [30]
En junio de 2019, se lanzó Chrome 75 con subprocesos WebAssembly habilitados de forma predeterminada. [31]
Desde abril de 2022, [actualizar]WebAssembly 2.0 estaba en estado de borrador, [32] [33] que agregó muchas instrucciones relacionadas con SIMD y un nuevo tipo de datos v128, con la capacidad de que las funciones devuelvan múltiples valores e inicialicen/copien memoria masiva.
Aunque WebAssembly fue diseñado inicialmente para permitir una velocidad de ejecución de código casi nativa en el navegador web, se ha considerado valioso fuera de este, en contextos más generalizados. [34] [35] Dado que los entornos de ejecución (RE) de WebAssembly son máquinas de pila virtuales de bajo nivel (similares a JVM o Flash VM ) que pueden estar integradas en aplicaciones host, algunas implementaciones crean entornos de ejecución independientes como Wasmtime y Wasmer . [9] [10] Los entornos de ejecución de WebAssembly están integrados en servidores de aplicaciones para alojar aplicaciones WebAssembly "del lado del servidor" y en otras aplicaciones para admitir arquitecturas de extensión de software basadas en complementos , por ejemplo, "WebAssembly para Proxies" (proxy-wasm) que especifica una ABI basada en WebAssembly para extender servidores proxy . [36] [37]
En noviembre de 2017, Mozilla declaró el soporte "en todos los navegadores principales", [38] después de que WebAssembly se habilitara de forma predeterminada en Edge 16. [39] Este soporte también incluye navegadores web móviles para iOS y Android. A marzo de 2024, [actualizar]el 99% de los navegadores web rastreados admiten WebAssembly (versión 1.0), [40] más que para su predecesor asm.js. [41] Para algunas extensiones, a partir del borrador estándar 2.0, el soporte puede ser menor, pero aún así, más del 90% de los navegadores web ya pueden admitir, por ejemplo, para extensiones de tipos de referencia. [ 42]
Las implementaciones de WebAssembly suelen utilizar compilación anticipada (AOT) o compilación justo a tiempo (JIT), pero también pueden utilizar un intérprete . Si bien las primeras implementaciones han llegado a los navegadores web , también existen implementaciones que no son de navegador para uso general, como Wasmer, [10] Wasmtime [43] o WAMR, [16] wasm3, WAVM y muchas otras. [44]
Debido a que los ejecutables de WebAssembly están precompilados, es posible utilizar una variedad de lenguajes de programación para crearlos. [45] Esto se logra ya sea mediante la compilación directa a Wasm o mediante una implementación de sus correspondientes máquinas virtuales en Wasm. Se informa que unos 40 lenguajes de programación admiten Wasm como destino de compilación. [46]
Emscripten compila C y C++ a Wasm [26] usando Binaryen y LLVM como backend. [47] El SDK de Emscripten puede compilar el código fuente de cualquier lenguaje compatible con LLVM (como C , C++ o Rust , entre otros) en un archivo binario que se ejecuta en el mismo entorno limitado que el código JavaScript. [nota 1] Emscripten proporciona enlaces para varias interfaces de entorno de uso común como WebGL .
A partir de la versión 8, un Clang independiente puede compilar C y C++ a Wasm. [52] Su objetivo inicial era soportar la compilación desde C y C++ , [53] aunque también está surgiendo soporte para otros lenguajes fuente como Rust , lenguajes .NET [54] [55] [46] y AssemblyScript [56] ( similar a TypeScript ).
Después del lanzamiento de MVP, WebAssembly agregó soporte para subprocesos múltiples y recolección de basura , [57] lo que permitió una compilación más eficiente para lenguajes de programación de recolección de basura como C# (compatible a través de Blazor ), F# (compatible a través de Bolero [58] con la ayuda de Blazor) y Python . [59]
Varios otros lenguajes tienen cierto soporte, incluidos Python , [60] Julia , [61] [62] [63] Ruby [64] y Ring . [65] [66]
Varios sistemas pueden compilar Java y otros lenguajes JVM en JavaScript y WebAssembly. Entre ellos se incluyen CheerpJ, [67] JWebAssembly [68] y TeaVM. [69] Kotlin admite WebAssembly directamente. [70] [71]
Los navegadores web no permiten que el código WebAssembly manipule directamente el Modelo de objetos del documento . El código Wasm debe respetar a JavaScript para esto. [nota 2]
En una encuesta realizada a desarrolladores en octubre de 2023, menos de la mitad de los 303 participantes estaban satisfechos con el estado de WebAssembly. Una gran mayoría mencionó la necesidad de mejoras en cuatro áreas: WASI, soporte de depuración, integración con JavaScript y API de navegador, y herramientas de compilación. [74]
Para las asignaciones de memoria intensiva en WebAssembly, existen "graves limitaciones que hacen que muchas aplicaciones no puedan implementarse de manera confiable en navegadores móviles [...] Actualmente, asignar más de ~300 MB de memoria no es confiable en Chrome en Android sin recurrir a soluciones alternativas específicas de Chrome, ni en Safari en iOS". [75]
Todos los navegadores principales permiten WebAssembly si no se especifica Content-Security-Policy o si se utiliza "unsafe-eval", pero se comportan de manera diferente en caso contrario. [76] Chrome requiere "unsafe-eval", [77] [78] aunque un hilo de trabajo puede ser una solución alternativa. [78]
En junio de 2018, un investigador de seguridad presentó la posibilidad de usar WebAssembly para eludir las mitigaciones del navegador para las vulnerabilidades de seguridad de Spectre y Meltdown una vez que se agregue soporte para subprocesos con memoria compartida. Debido a esta preocupación, los desarrolladores de WebAssembly suspendieron la función. [79] [80] [81] Sin embargo, para explorar estas futuras extensiones de lenguaje, Google Chrome agregó soporte experimental para la propuesta de subprocesos de WebAssembly en octubre de 2018. [82]
WebAssembly ha sido criticado por permitir una mayor facilidad para ocultar la evidencia a los escritores de malware , estafadores y atacantes de phishing ; WebAssembly está presente en la máquina del usuario solo en su forma compilada, lo que "dificulta la detección de malware". [83] La velocidad y la fácil capacidad de ocultarse en WebAssembly han llevado a su uso en la minería de criptomonedas oculta dentro del dispositivo del visitante del sitio web. [83] [84] [79] Coinhive , un servicio ahora desaparecido que facilita la minería de criptomonedas en los navegadores de los visitantes del sitio web, afirma que su "minero usa WebAssembly y se ejecuta con aproximadamente el 65% del rendimiento de un minero nativo". [79] Un estudio de junio de 2019 de la Technische Universität Braunschweig analizó el uso de WebAssembly en el millón de sitios web principales de Alexa y descubrió que el uso predominante era para la minería de criptomonedas maliciosa, y que el malware representaba más de la mitad de los sitios web que usaban WebAssembly estudiados. [85] [86] Un estudio de abril de 2021 de la Universidad de Stuttgart descubrió que, desde entonces, la minería de criptomonedas ha quedado marginada y ha caído a menos del 1 % de todos los módulos de WebAssembly recopilados de una amplia gama de fuentes, incluido también el millón de sitios web principales de Alexa. [87]
Como WebAssembly sólo admite flujo de control estructurado , es apto para técnicas de verificación de seguridad, incluida la ejecución simbólica . [88]
WebAssembly System Interface (WASI) es una interfaz simple ( ABI y API ) diseñada por Mozilla con la intención de ser portable a cualquier plataforma. [89] Proporciona características similares a POSIX como E/S de archivos restringida por seguridad basada en capacidad . [90] [91] Hay ABI/API propuestas adicionales. [92] [93]
WASI está influenciado por CloudABI y Capsicum . [ ¿según quién? ]
Solomon Hykes, cofundador de Docker , escribió en 2019: "Si WASM+WASI hubiera existido en 2008, no habríamos necesitado crear Docker. Así de importante es. WebAssembly en el servidor es el futuro de la informática". [94]
El estándar general proporciona especificaciones básicas para la API de JavaScript y detalles sobre la incrustación. [5]
El código Wasm (código binario, es decir, código de bytes) está pensado para ejecutarse en una máquina virtual portátil (VM). [95] La VM está diseñada para que sea más rápida de analizar y ejecutar que JavaScript y para tener una representación de código compacta. [53] El estándar no estipula ninguna funcionalidad externa (como llamadas al sistema ) que se pueda esperar del código binario Wasm. En cambio, proporciona una forma de ofrecer interconexión a través de módulos mediante el entorno host en el que se ejecuta la VM. [96] [9]
Un programa Wasm está diseñado como un módulo independiente que contiene colecciones de varios valores definidos por Wasm y definiciones de tipos de programas. Estos se proporcionan en formato binario o textual (ver a continuación) que tienen una estructura común. [97] Un módulo de este tipo puede proporcionar una función de inicio que se ejecuta al crear una instancia de un binario wasm.
El estándar básico para el formato binario de un programa Wasm define una arquitectura de conjunto de instrucciones (ISA) que consiste en codificaciones binarias específicas de tipos de operaciones que son ejecutadas por la VM (sin especificar exactamente cómo deben ejecutarse). [98] La lista de instrucciones incluye instrucciones estándar de carga/almacenamiento de memoria, numéricas, paramétricas, de control de tipos de instrucciones de flujo e instrucciones de variables específicas de Wasm. [99]
El número de códigos de operación utilizados en el estándar original (MVP) era un poco menos de 200 de los 256 códigos de operación posibles. Las versiones posteriores de WebAssembly elevaron el número de códigos de operación a un poco más de 200. La propuesta SIMD de WebAssembly (para procesamiento paralelo) introduce un prefijo de código de operación alternativo (0xfd) para SIMD de 128 bits . La concatenación del prefijo SIMD, más un código de operación que es válido después del prefijo SIMD, forma un código de operación SIMD. Los códigos de operación SIMD aportan 236 instrucciones adicionales para la capacidad SIMD de "producto mínimo viable" (MVP) (para un total de alrededor de 436 instrucciones). [100] [101] Esas instrucciones, los "códigos de operación finalizados" [102] están habilitados de forma predeterminada en V8 de Google (en Google Chrome), el motor SpiderMonkey en Mozilla Firefox y el motor JavaScriptCore en Safari de Apple [103] y también hay algunas propuestas adicionales de instrucciones para un "MVP posterior a SIMD" posterior, y también hay una propuesta "simd relajada" separada sobre la mesa. [104]
Estos códigos de operación SIMD también son portables y se traducen a conjuntos de instrucciones nativos como x64 y ARM. Por el contrario, ni la JVM de Java ni CIL admiten SIMD, en su nivel de código de operación , es decir, en el estándar; ambos tienen algunas API paralelas que proporcionan aceleración de SIMD. Hay una extensión para Java que agrega intrínsecos para SIMD x64, [105] que no es portable, es decir, no se puede usar en ARM o teléfonos inteligentes. Los teléfonos inteligentes pueden admitir SIMD llamando al código ensamblador con SIMD, y C# tiene un soporte similar.
En marzo de 2017, el grupo comunitario WebAssembly llegó a un consenso sobre el formato binario inicial (MVP), la API de JavaScript y el intérprete de referencia. [106] Define un formato binario WebAssembly ( .wasm
), que no está diseñado para ser utilizado por humanos, así como un formato de texto WebAssembly legible por humanos ( .wat
) que se asemeja a un cruce entre expresiones S y lenguajes ensambladores tradicionales.
La siguiente tabla muestra un ejemplo de una función factorial escrita en C y su código WebAssembly correspondiente después de la compilación, mostrado tanto en formato de texto .wat (una representación textual legible por humanos de WebAssembly) como en formato binario .wasm (el código de bytes sin formato , expresado a continuación en hexadecimal ), que se ejecuta mediante un navegador web o un entorno de ejecución que admite WebAssembly.
Todas las constantes enteras se codifican utilizando una codificación LEB128 de longitud variable y eficiente en términos de espacio . [107]
El formato de texto de WebAssembly se escribe de manera más canónica en un formato plegado utilizando S-expresiones . Para instrucciones y expresiones, este formato es puramente sintáctico y no tiene diferencias de comportamiento con el formato lineal. [108] A través de wasm2wat
, el código anterior se descompila a:
( módulo ( tipo $t0 ( func ( parámetro i64 ) ( resultado i64 ))) ( func $f0 ( tipo $t0 ) ( parámetro $p0 i64 ) ( resultado i64 ) ( si $I0 ( resultado i64 ) ;; $I0 es un nombre de etiqueta no utilizado ( i64.eqz ( local.get $p0 )) ;; el nombre $p0 es el mismo que 0 aquí ( entonces ( i64.const 1 )) ( de lo contrario ( i64.mul ( local.get $p0 ) ( llamar a $f0 ;; el nombre $f0 es el mismo que 0 aquí ( i64.sub ( local.get $p0 ) ( i64.const 1 ))))))))
El compilador genera implícitamente un módulo. La función se referencia mediante una entrada de la tabla de tipos en el binario, por lo tanto, una sección de tipos y la type
emite el descompilador. [109] Se puede acceder al compilador y al descompilador en línea. [110]
.wasm
archivos que luego se pueden ejecutar en un navegador web. [48] [49] [50] Aunque Emscripten puede consumir varios idiomas al usar Clang , pueden surgir algunos problemas. [51]El código de WebAssembly puede considerarse una máquina de pila estructurada ; una máquina en la que la mayoría de los cálculos utilizan una pila de valores, pero el flujo de control se expresa en construcciones estructuradas como bloques, ifs y bucles. En la práctica, las implementaciones no necesitan mantener una pila de valores real ni estructuras de datos reales para el control; solo necesitan comportarse como si lo hicieran.
WebAssembly es un estándar abierto...
WebAssembly es un ... formato de código
WebAssembly es un lenguaje de programación que tiene múltiples representaciones concretas (su formato binario y el formato de texto). Ambos se asignan a una estructura común.
... esta especificación se complementa con documentos adicionales que definen interfaces para entornos de incrustación específicos, como la Web. Cada uno de ellos definirá una interfaz de programación de aplicaciones (API) de WebAssembly adecuada para un entorno determinado.
Su objetivo principal es permitir aplicaciones de alto rendimiento en la Web, pero no hace suposiciones específicas de la Web ni proporciona funciones específicas de la Web, por lo que también se puede utilizar en otros entornos.
Si bien la Web es la motivación principal de WebAssembly, nada en su diseño depende de la Web o de un entorno JavaScript. Es un estándar abierto diseñado específicamente para su integración en múltiples contextos, y esperamos que en el futuro estén disponibles implementaciones independientes.
Compila todo en WebAssembly. Ejecútalo en cualquier SO o incorpóralo en otros lenguajes.
Incluso descartando la única puntuación en la que asm.js obtuvo mejores resultados, se ejecuta a alrededor del 70 % de la velocidad del código C++ nativo.
{{cite book}}
: CS1 maint: varios nombres: lista de autores ( enlace )El objetivo de este paquete es proporcionar enlaces de Rust a las API web y permitir un alto grado de interoperabilidad entre Rust y JavaScript.
Enlaces de API sin procesar para API web. Se trata de un paquete generado de manera procedimental desde el WebIDL del navegador que proporciona un enlace a todas las API que el navegador proporciona en la web.
Este artículo incorpora texto de un trabajo de contenido libre . Licencia Apache 2.0 (declaración de licencia/permiso). Texto tomado de Text Format, jfbastien; rossberg-chromium; kripken; titzer; s3ththompson; sunfishcode; lukewagner; flagxor; enricobacis; c3d; binji; andrewosh, GitHub. WebAssembly/design.