and in fact the VM pretty much has to be written in C (or C++, or you could get away with unsafe rust) since efficient function dispatch (not to mention JIT) are difficult without wildeyed pointer manipulation (you want to emit instructions to somewhere in memory and then jump to them, something inherently unsafe)
> and in fact the VM pretty much has to be written in C
What makes you think that you need C/C++ for this? Compilers were and still are written in many languages, and you can always come up with a compiler written in an "arbitrary" language which outputs e.g. an executable ELF file containing your VM runtime code.
There are a few examples of this in the wild btw, look at e.g. the GraalVM and its SubstrateVM sub-project.
I'm not familiar with the way GraalVM is implemented but I do know that at some point it has to have access to raw memory and registers in order to do JIT. There's no getting around that (and you can't do that with just java).
A compiler is different from a JIT engine since yeah you can just write whatever binary you want to disk, hell you could write an x86 compiler in javascript. but if you want to emit instructions to memory and send the CPU there to consume them, you need a smidge of native code.
We're literally saying the same thing. Java compiled into a native code library for each target with intrinsics that give access to things like CPU registers is just another way of implementing intrinsics in native code
And native code is not C or C++? How do you think the very first C compiler were written? Spoiler, it was bootstrapped with assembly which was bootstrapped with machine code.
> you want to emit instructions to somewhere in memory and then jump to them, something inherently unsafe
Isn't this only for JIT? My understanding was that non-JIT VMs basically function as emulators of a non-existent CPU, so they interpret each bytecode instruction rather than asking the CPU proper to do a jump.
even a bytecode vm has to emit bytecode and then move an instruction pointer around. You can do it without using C pointer manipulation but it will always be less than ideal. This is a nice little blog post about it: https://pliniker.github.io/post/dispatchers/
You can't bootstrap an interpreted language like JavaScript or even WebAssembly, the VM has to be written in something.