Mecanografiado transpira a JS. Luego está el temblor de árboles, "menos" (opcional) y qué más en el proceso de realizar una implementación. Pero nada de eso (afaik) tiene nada que ver con "compilar". Todo se incluye y optimiza en gran medida, pero en realidad no está compilado, ¿verdad?
La compilación significa transformar un programa escrito en un lenguaje A en un programa semánticamente equivalente escrito en el lenguaje B de tal manera que evaluar el programa compilado de acuerdo con las reglas del lenguaje B (por ejemplo, interpretarlo con un intérprete para B ) produce el mismo resultado y tiene la los mismos efectos secundarios que evaluar el programa original de acuerdo con las reglas del lenguaje A (por ejemplo, interpretarlo con un intérprete para A ).
Compilación significa simplemente traducir un programa de lenguaje A a la lengua B . Eso es todo lo que significa. (Tenga en cuenta también que es perfectamente posible que A y B sean el mismo idioma).
En algunos casos, tenemos nombres más especializados para ciertos tipos de compiladores, dependiendo de qué son A y B , y qué hace el compilador:
- si A se percibe como lenguaje ensamblador y B se percibe como lenguaje máquina, entonces lo llamamos ensamblador ,
- si se percibe que A es lenguaje de máquina y B se percibe como lenguaje ensamblador, entonces lo llamamos desensamblador ,
- si se percibe que A es de un nivel más bajo que B , entonces lo llamamos descompilador ,
- si A y B son el mismo lenguaje, y el programa resultante es de alguna manera más rápido o más ligero, entonces lo llamamos optimizador ,
- si A y B son los mismos lenguajes, y el programa resultante es más pequeño, lo llamamos minificador ,
- si A y B son los mismos lenguajes y el programa resultante es menos legible, entonces lo llamamos ofuscador ,
- si se percibe que A y B se encuentran aproximadamente en el mismo nivel de abstracción, entonces lo llamamos transpilador , y
- si se percibe que A y B se encuentran aproximadamente en el mismo nivel de abstracción y el programa resultante conserva el formato, los comentarios y la intención del programador de manera que sea posible mantener el programa resultante de la misma manera que el programa original, entonces llamamos es una herramienta de reingeniería .
Además, tenga en cuenta que las fuentes más antiguas pueden utilizar los términos "traducción" y "traductor" en lugar de "compilación" y "compilador". Por ejemplo, C habla de "unidades de traducción".
También puede tropezar con el término "procesador de idiomas". Esto puede significar un compilador, un intérprete o tanto compiladores como intérpretes, según la definición.
Javascript en sí todavía se interpreta, ¿verdad?
JavaScript es un idioma. Los idiomas son un conjunto de reglas y restricciones lógicas. Los idiomas no se interpretan ni compilan. Los idiomas simplemente son .
La compilación y la interpretación son características de un compilador o intérprete (¡obvio!). Cada idioma se puede implementar con un compilador y cada idioma se puede implementar con un intérprete. Muchos lenguajes tienen compiladores e intérpretes. Muchos motores de ejecución modernos de alto rendimiento tienen al menos un compilador y al menos un intérprete.
Estos dos términos pertenecen a diferentes capas de abstracción. Si el inglés fuera un idioma escrito, "interpreted-language" sería un error de tipo.
Tenga en cuenta también que algunos lenguajes no tienen ni un intérprete ni un compilador. Hay lenguajes que no tienen implementación alguna. Aún así, son idiomas y puedes escribir programas en ellos. Simplemente no puedes ejecutarlos.
Además, ten en cuenta que todo se interpreta en algún momento : si quieres ejecutar algo, debes interpretarlo. La compilación simplemente traduce el código de un idioma a otro. No lo ejecuta. La interpretación lo ejecuta. (A veces, cuando se implementa un intérprete en hardware, lo llamamos "CPU", pero sigue siendo un intérprete).
Caso en cuestión: cada implementación de JavaScript convencional existente actualmente tiene un compilador.
V8 comenzó como un compilador puro: compilaba JavaScript directamente en código de máquina nativo moderadamente optimizado. Posteriormente, se agregó un segundo compilador. Ahora, hay dos compiladores: un compilador liviano que produce código moderadamente optimizado pero el compilador en sí es muy rápido y usa poca RAM. Este compilador también inyecta código de creación de perfiles en el código compilado. El segundo compilador es un compilador más pesado, más lento y más caro, que, sin embargo, produce un código mucho más ajustado y mucho más rápido. También utiliza los resultados del código de generación de perfiles inyectado por el primer compilador para tomar decisiones de optimización dinámica. Además, la decisión de qué código volver a compilar utilizando el segundo compilador se toma en función de esa información de perfil. Tenga en cuenta que en ningún momento hay un intérprete involucrado. V8 nunca interpreta, siempre compila. No lo hace Incluso contiene un intérprete. (En realidad, creo que hoy en día sí, estoy describiendo las dos primeras iteraciones).
SpiderMonkey compila JavaScript en el código de bytes de SpiderMonkey, que luego interpreta. El intérprete también perfila el código, y luego el código que se ejecuta con más frecuencia es compilado por un compilador en código de máquina nativo. Entonces, SpiderMonkey contiene dos compiladores: uno de JavaScript al código de bytes de SpiderMonkey y otro del código de bytes de SpiderMonkey al código de máquina nativo.
Casi todos los motores de ejecución de JavaScript (con la excepción de V8) siguen este modelo de un compilador AOT que compila JavaScript en código de bytes, y un motor de modo mixto que cambia entre interpretar y compilar ese código de bytes.
Escribiste en un comentario:
Realmente estaba pensando que el código de máquina está involucrado en algún lugar.
¿Qué significa "código máquina"?
¿Qué es el lenguaje de máquina de un hombre? ¿El lenguaje intermedio de otro hombre y viceversa? Por ejemplo, hay CPU que pueden ejecutar de forma nativa el código de bytes de JVM, en tal CPU, el código de bytes de JVM es un código de máquina nativo. Y hay intérpretes para el código de máquina x86, cuando se ejecuta ese código de máquina x86 se interpreta el código de bytes.
Hay un intérprete x86 llamado JPC escrito en Java. Si ejecuto código de máquina x86 en JPC que se ejecuta en una CPU JVM nativa ... ¿cuál es el código de bytes y cuál es el código nativo? Si compilo código de máquina x86 en JavaScript (sí, hay herramientas que pueden hacer eso) y lo ejecuto en un navegador en mi teléfono (que tiene una CPU ARM), ¿cuál es el código de bytes y cuál es el código de máquina nativo? ¿Qué pasa si el programa que estoy compilando es un emulador SPARC y lo uso para ejecutar código SPARC?
Tenga en cuenta que cada lenguaje induce una máquina abstracta y es lenguaje de máquina para esa máquina. Entonces, todos los idiomas (incluidos los de muy alto nivel) son códigos de máquina nativos. Además, puede escribir un intérprete para cada idioma. Por lo tanto, todos los idiomas (incluido el código de máquina x86) no son nativos.