A bytecode interpeter for JavaScript, written in Golang.
We're striving for minimal dependencies, though there's a couple to help with specific things:
We use golang.org/x/text/unicode/norm for String.normalize. This is relatively small.
We use libregexp, libunicode, and cutils from QuickJS. By using QuickJS's regexp engine, we get great ECMAScript compatibility out of the box. This is a shortcut, ideally we'll write our own regexp engine to replace this in the future.
There's some decisions we've made in order to simplify the engine, which represent departures from the ECMAScript specification.
- Only support up to Unicode 15.0.0 - waiting for golang/go#77266 (Go 1.27)
- We use WTF-8 for the internal representation of strings instead of UTF-16. This gives us a way to support UTF-16 without paying an extra byte per character for ASCII. This does mean we have to be careful when using Go stdlib functions on our strings.
I'm not super happy with how the scoping system turned out, particularly around how the with
statement and eval work. Some of that is just due to inherit complexity in the with statement.
The current Value struct is bigger than I'd like. I think it'd be worth figuring out how to NaN-box ValueType into num to shrink it to a float64 and a interface{} (24 bytes total).