The story so far is easy enough to understand. At one end of the
spectrum of language implementations we have the pure compiler,
which generates nothing but machine code and uses no run time
library or package. At the other end we have the interpreter,
which generates no machine code and is all run time package in
the form of a complete VM for the language. Of course, in the
real world these really are two ends of the spectrum and real
compilers use different amounts of run time library, so slowly
sliding towards the interpreter end of the spectrum. But what
about interpreters? Do they have a way of sliding towards the
compiler end of the spectrum? An interpreter can generate some
machine code to get a job done quicker if this is important. A
modern VM will use all sorts of techniques to make it faster and
more efficient. For example, for each instruction in the
intermediate language the VM could ask which is going to be
quicker: to call a routine or to generate machine code to get
the job done. This approach