hashBits() is used to generate a hash code from the same 64 bits used
to represent a Wren number as a double. When building a map containing
a large number of integer keys, it's important for this to do a good
job scattering the bits across the 32-bit key space.
Alas, it does not. Worse, the benchmark to test this happens to stop
just before the performance falls off a cliff, so this was easy to
overlook.
This replaces it with the hash function V8 uses, which has much better
performance across the numeric range.
This is a breaking change because existing imports in user Wren code
that assume the path is relative to the entrypoint file will now likely
fail.
Also, stack trace output and host API calls that take a module string
now need the resolved module string, not the short name that appears in
the import.
This is just for the VM's own internal use, for resolving relative
imports.
Also added a tiny unit test framework for writing tests of low-level
C functionality that isn't exposed directly by the language or VM.
I've got some ideas on how to tweak the embedding API, but I want to
see what performance impact they have first, so this adds a little
benchmark that just calls a foreign method a ton of times.