In theory, you can take any interpreter for a language and turn it into a compiler that creates its own code in that language. This is due to a series of equations called Futamura forecasts . A high-level idea is to “trick” the way you define the compiler. Suppose that for some language L I have an interpreter I (p), which, given the program p written in the language L, interprets this program. Now I assume that the interpreter I am represented directly in machine code. Suppose I have a program called mix , which, given the machine code program and the input sequence of this program, creates a new machine code program, which is the source program, while its input is fixed as the given input. For example, if I compiled this program in C ++:
#include <iostream> using namespace std; int main() { string message; cin >> message; cout << message << endl; }
And then I used mix to mix the program with the input "Hello", I would get a program that always prints the message "Hello". In other words, it would be as if I wrote this program:
#include <iostream> using namespace std; int main() { cout << "Hello" << endl; }
It turns out it's possible to build this program. I could do this, for example, by looking at the machine code, looking at every place that you are trying to read at the input from the console, and then replace it with the code that calls the function instead to read from the hard line.
Now consider what happens if you have to run this mix program, taking the interpreter I and some program p as input. Then the result will be a machine code program equivalent to program I running at input p. In other words, you just created a machine code program that mimics what happens if you have to start a program interpreter - it is a machine code program that runs p!
Of course, this design is completely impractical. As far as I know, no one wrote a mix , and if they did, any program that you did, turning the interpreter into a compiler, would be extremely inefficient, because it would not be optimized.
As for your initial question about whether you can take the JVM JIT and use it to create the source machine code for a Java program, I'm not sure, since I did not look at the source code, but I strongly doubt that the Machine code almost certainly contains interceptors. which will go to the JVM to perform certain tasks (for example, garbage collection, loading classes, etc.), which will make the generated code inoperative in a standalone environment. However, it is a really cool idea to try to do it, and I hope this answer will illuminate some light on the theory behind it!