¿Cómo ejecuta Java Virtual Machine el código escrito en otros idiomas?

12

Desde Java 1.6, la JVM puede ejecutar una miríada de lenguajes de programación además de en lugar de solo Java. Conceptualmente entiendo cómo se ejecuta Java en Java VM, pero no cómo otros lenguajes también pueden ejecutarse en él. Para mí, todo parece magia negra. ¿Tiene algún artículo para señalarme para que pueda entender mejor cómo encaja todo esto?

Pomario
fuente
2
De la misma manera que su procesador Intel / AMD / Solaris (??) puede ejecutar "cualquier idioma" (aunque realmente no ejecuta idiomas, sino que sigue el flujo aquí) que puede compilarse en su código de ensamblaje nativo.
Apoorv Khurasia
13
La cuestión es que la JVM no ejecuta Java. Ejecuta un lenguaje de bajo nivel distinto (aunque relacionado e intencionalmente fácil de crear para los compiladores de Java).
Eso es verdad. Pero la JVM comenzó a ejecutar otros idiomas desde la versión 6; no podría (o nadie lo hizo) ejecutar python o Groovy en la versión 1.4.2. ¿Por qué es así? ¿Que ha cambiado?
Pomario
@delnan O más bien "un modelo de ejecución de más bajo nivel, que el programa javac sabe construir a partir de código Java".
Apoorv Khurasia
99
@Pomario Jython ha existido por un tiempo ahora. Y esta página parece sugerir que los scripts Jython podrían ejecutarse en 1.4.2.
Apoorv Khurasia

Respuestas:

23

La clave es el idioma nativo de la JVM: el código de bytes de Java. Cualquier lenguaje puede compilarse en bytecode que la JVM entiende; todo lo que necesita para esto es un compilador que emite bytecode. A partir de entonces, no hay diferencia desde el punto de vista de la JVM. Tanto es así que puede tomar un archivo compilado de clase Scala, Clojure, Jython, etc. y descompilarlo (usando, por ejemplo, JAD ) en un código fuente Java de aspecto normal.

Puede encontrar más detalles sobre esto en los siguientes artículos / hilos:

No conozco ningún cambio fundamental en las JVM de Java 5 o 6 que hubieran hecho posible o más fácil (código compilado desde) otros idiomas para ejecutarse en él. En mi opinión, la JVM 1.4 era más o menos tan capaz en ese aspecto como la JVM 6 (aunque puede haber diferencias; no soy un experto en JVM). Fue solo que las personas comenzaron a desarrollar otros lenguajes y / o compiladores de código de bytes en la primera mitad de la década, y los resultados comenzaron a aparecer (y se hicieron más conocidos) alrededor de 2006 cuando se publicó Java 6.

Sin embargo, todas estas versiones de JVM comparten algunas limitaciones: la JVM está tipicamente estática por naturaleza, y hasta la versión 7, no soportaba lenguajes dinámicos. Esto ha cambiado con la introducción de invokedynamicuna nueva instrucción de código de bytes que permite la invocación de métodos basándose en la verificación dinámica de tipos.

Péter Török
fuente
8
No es exactamente cierto que la JVM no "admite" lenguajes dinámicos. Solo tenían que usar soluciones que tenían graves inconvenientes.
Michael Borgwardt
3
@MichaelBorgwardt, ¿podemos estar de acuerdo en que JVM pre v7 toleraba lenguajes dinámicos (hasta cierto punto)? :-)
Péter Török
1
Esa es una buena manera de decirlo :)
Michael Borgwardt
3

Una máquina virtual, como JVM, es un programa que acepta como entrada, generalmente archivos, un conjunto de instrucciones simples (que generalmente son fáciles de convertir en instrucciones reales de CPU), y en realidad las compila y ejecuta como instrucciones de CPU nativas (generalmente usando un compilador a pedido como HotSpot o JIT).

Es esencialmente una capa de abstracción. Por lo general, es mucho más fácil portar implementaciones de conjuntos de instrucciones de VM a diferentes arquitecturas de procesador, debido a varias similitudes (como estar basado en la pila). También es mucho más fácil portar diferentes lenguajes de programación a las instrucciones de VM, ya que está más orientado hacia los lenguajes de programación modernos que las instrucciones primitivas de la CPU. Muchas máquinas virtuales, como JVM y CLR (.NET) contienen instrucciones para llamar a métodos virtuales y crear instancias de objetos.

Así que tomemos un idioma por ejemplo. Llámalo MyLanguage. Como es un lenguaje de programación, en última instancia, se compila en un conjunto de instrucciones de arquitectura de CPU. Eso significa que, dado un conjunto de instrucciones de máquina virtual flexible y compatible, también es posible compilar MyLanguage a un conjunto de instrucciones de esa VM.

Siempre hay una cuestión de eficiencia, ya que es posible que necesite hackear algunas soluciones en los conjuntos de instrucciones de VM que no tendría que hacer de forma nativa, pero aún es posible.

Ñame Marcovic
fuente
3

Una JVM es una máquina de cómputo completa de Turing (excepto para la memoria limitada), y cualquier máquina completa de Turing (física o virtual) puede ejecutar cualquier lenguaje de programación (excepto la memoria, el rendimiento y las limitaciones físicas de E / S).

hotpaw2
fuente
Erm ... ¿por qué necesitamos compiladores entonces? ;-)
Péter Török
Los compiladores e intérpretes, ellos mismos, pueden ejecutarse en máquinas Turing (tal vez lentamente). ¿Quizás algunos pasos de precompilación / traducción pueden mejorar el rendimiento de ejecutar un programa determinado en un idioma determinado?
hotpaw2
1
Mi punto fue que su afirmación "cualquier máquina completa de Turing (física o virtual) puede ejecutar cualquier lenguaje de programación" literalmente significa que la CPU x86 de mi computadora portátil puede ejecutar directamente este agradable archivo fuente de Java en el que estoy trabajando en este momento. O código de máquina para procesadores PowerPC. Sin compiladores: las CPU no contienen compiladores, ¿verdad? :-)
Péter Török
Su "máquina" es más que solo la CPU.
hotpaw2
1
@ PéterTörök veo tu punto. No dio más detalles sobre las máquinas virtuales como lo hicimos nosotros. Pero creo que su respuesta todavía responde brevemente a la pregunta del OP. La JVM puede "ejecutar" otros lenguajes de programación porque puede "ejecutar" cualquier lenguaje de programación, porque está completa. Quizás no sea elaborado, pero sigue siendo un punto conciso y válido. :)
Yam Marcovic
2

Por un momento, piense en la JVM como un procesador con su propio conjunto de instrucciones, como quizás el x86. El procesador puede ejecutar, por ejemplo, el código C que se ha compilado en su lenguaje de máquina. Aplicando la misma analogía a la JVM, se pueden ejecutar otros idiomas en la JVM al igual que en otros procesadores si esos idiomas se compilan según las instrucciones de la máquina de la JVM. La JVM puede ejecutar estas instrucciones para el lenguaje X.

cobie
fuente
su analogía es buena
cobi