I think I can add one more option to my last post about VMs. With Chrome, Google released a new virtual machine for Javascript called V8. I’ve spent some sweet time playing with it and browsing through the code in the past two days and thought some would be interested in my findings.

First it’s not really a “classic” VM. There’s no usable intermediate representation or higher level opcode that you can program at the VM level. The only thing V8 understands is Javascript and the only target representation is native assembler (Intel and ARM for now). So in some respect it’s closer to a compiler than a traditional VM even though the line is blurry for most modern VMs. There’s no interpretation whatsoever.

But it’s also more than just a compiler. It includes a generational, accurate garbage collector and the assembler generation is reworked at runtime depending on execution paths. What they’re calling hidden classes allows the generalization of some calls to optimize them as much as possible. Once you know for sure the address that’s being called, there’s a lot of clever things to make that very fast. As Javascript is fairly dynamic as class structures go (classes are basically hashes, you can add, remove, or update functions whenever you feel like), those hidden classes can also be recalculated which triggers new assembler generation. A fairly cute machinery.

So for those who would want to reuse the VM only to implement their own languages on top of it, they’re out of luck. V8 isn’t like the JVM or Mono, where you can generate intermedate bytecode, it’s straight Javascript to assembler. On the other hand, it makes cross-compiling to Javascript an interesting option. Theoretically and with enough optimizations, this thing could be as fast as C at least on some benchmarks. It’s only going to take time to get to the level of maturity of gcc.

Other than that, as C++ code goes it’s as clean as you get. The API is pretty nice, with specialized higher level classes to wrap Javascript datatypes like String or Number all wrapped in handles for garbage collection. If you wanted to provide a readfile(f) function for example here’s what the code would look like:

v8::Handle ReadFile(const v8::Arguments& args) {
if (args.Length() != 1)
return v8::ThrowException(v8::String::New(“Read expecting a single string argument”));
v8::HandleScope handle_scope;
v8::String::AsciiValue file(args[0]);
v8::Handle source = ReadFile(*file);
if (source.IsEmpty()) {
return v8::ThrowException(v8::String::New(“Error loading file”));
}
return source;
}

Ah, a couple more things. Some standard libraries are written in Javascript. So to package everything in one executable, they translate them to big C arrays containing each char and compile that. Sounds to me like something others could reuse to build their own executables from Javascript, all bundled with V8. Another goodie is snapshotting. When you build V8 from source, you can have it generate a snapshot of the memory state once the libraries are loaded and this gets packaged in the executable. It makes it slightly bigger but the load time is blazingly fast. Pretty sweet.

I think I covered most of what was interesting. So what do you think? For me V8 is a keeper. We’ll see how it evolves and where the benchmark war leads it but the bases are definitely sound. After all, it’s just a first release.