En teoría, es posible tomar cualquier intérprete para un idioma y convertirlo en un compilador que produce código nativo en ese idioma. Esto está relacionado con una serie de ecuaciones llamadas Futamura projections. La idea de alto nivel es esencialmente "engañar" a la hora de definir un compilador. Supongamos que para un lenguaje L tengo un intérprete I (p) que, dado un programa p escrito en el lenguaje L, interpreta ese programa. Ahora, supongo que el intérprete I está representado directamente en el código máquina. Supongamos además que tengo un programa llamado mix
que, dado un programa de código de máquina y una secuencia de entrada a ese programa, produce un nuevo programa de código de máquina que es el programa inicial con su entrada fija para ser la entrada especificada. Por ejemplo, si he realizado este programa en C++:
#include <iostream>
using namespace std;
int main() {
string message;
cin >> message;
cout << message << endl;
}
y luego se usa para mezclar mix
el programa con la entrada "Hola", que tendría un programa que siempre se imprime el mensaje "Hola". En otras palabras, sería como si hubiera escrito este programa:
#include <iostream>
using namespace std;
int main() {
cout << "Hello" << endl;
}
Resulta que es posible construir este programa. Podría hacer esto, por ejemplo, mirando el código máquina, mirando cada lugar en el que intente leer la entrada desde la consola y luego reemplazándolo con un código que llame a una función para leer en cambio desde una cadena codificada.
Ahora, considere qué pasaría si ejecutara este programa mix
tomando como entrada un intérprete I y algún programa p. Entonces, el resultado de esto sería un programa de código máquina que es equivalente al programa I que se ejecuta en la entrada p. En otras palabras, acaba de construir un programa de código máquina que simula lo que sucedería si ejecutara el intérprete en el programa, que es un programa de código máquina que ejecuta el programa p!
Por supuesto, esta construcción es completamente impráctica. Que yo sepa, nadie ha escrito mix
, y si lo hicieran, cualquier programa que hagas convirtiendo un intérprete en un compilador sería tremendamente ineficiente porque no se optimizaría del todo.
En cuanto a su pregunta original sobre si podría tomar el JIT de la JVM y usarlo para producir código máquina sin formato para un programa Java, no estoy seguro ya que no he buscado el código fuente, pero dudo mucho eso. El código de máquina casi con certeza contiene ganchos que volverían a llamar a la JVM para tareas específicas (por ejemplo, recolección de basura, carga de clases, etc.), lo que haría que el código generado no funcionara en un entorno independiente. Sin embargo, es una buena idea tratar de hacer esto, y espero que esta respuesta arroje algo de luz sobre la teoría detrás de esto.
¿Necesita usar la construcción Class.forName()? –
Puede entregar un código compilado y se ejecutará en cualquier sistema con la versión correcta de Java instalada. No importa cómo lo haga en cualquier idioma, asumirá que se instaló algún sistema operativo/software. –
Un tiempo de ejecución de Java puede manejar Class.forName() en código nativo simplemente cortando el circuito a clases precompiladas, pero por supuesto también debe incluir un JIT o intérprete para las clases que no fueron precompiladas (proxies dinámicos, complementos de terceros , etc.) –