Kiesel Devlog #4: The biggest update yet!
It's been two weeks and 108 commits since the last devlog, and I'm really happy with the progress I made! Let's take a look at all those shiny new features :^)
A quick check of test262.fyi reveals that Kiesel now scores exactly 33%.
ArrayBuffer
First up, ArrayBuffer
. They're not very capable and mostly serve as memory storage for other kinds of objects (DataView
, typed arrays), and are thus fairly easy to implement. The resizable ArrayBuffer
proposal will make things slightly more complicated, but I chose a std.ArrayList(u8)
for the underlying buffer, which already is resizable.
I also added a non-standard detachArrayBuffer()
function to the Kiesel
namespace object, which exposes the abstract operation of the same name — primarily for test262. Here is it in action, along with the REPL's pretty-printing:
I haven't started working on the aforementioned typed arrays yet, but I think Zig has a nice way of writing a generic implementation that handles all the different integer types.
Promise
I previously implemented promises in LibJS, and it basically took me a year to finish — luckily doing it again in Kiesel was much quicker :^)
I recorded most of the process in a two-part video series, first adding Promise
objects and then implementing promise reaction jobs:
RegExp
To keep scope creep under control I decided to not write a JS-flavored regular expression library at this point, the same way I opted to use an existing library for GC. Both of these are fairly decoupled from everything else and easy to replace later on if desired.
I ended up using quickjs's libregexp:
libregexp: small and fast regexp library fully compliant with the Javascript ES 2019 specification.
I also briefly considered using SerenityOS's LibRegex, which is what LibJS uses, but adding C wrappers for a C++ library is a can of worms I wasn't keen to open.
However, choosing to not write this myself comes at a cost: C code is compiled with much less safety than Zig code, and I already found a bug that I had to patch (and at least one other crash I still need to investigate). These flaws aside, using C libraries from Zig is one of its major selling points, so the actual integration took me less than a day!
And a quick demo:
Other Builtins
Lastly I implemented a few remaining Math
functions, parseInt()
, a half-assed version of parseFloat()
, and bound function objects via Function.prototype.bind()
.
Expand to see the full list of newly implemented builtins 📝
ArrayBuffer()
ArrayBuffer.isView()
ArrayBuffer.prototype.byteLength
ArrayBuffer.prototype.slice()
ArrayBuffer.prototype[@@toStringTag]
Function.prototype.bind()
Math.atan2()
Math.fround()
Math.imul()
parseFloat()
, somewhatparseInt()
Promise()
Promise.prototype.catch()
Promise.prototype.finally()
Promise.prototype.then()
Promise.prototype[@@toStringTag]
Promise.reject()
Promise.resolve()
RegExp()
RegExp.prototype.dotAll
RegExp.prototype.exec()
RegExp.prototype.flags
RegExp.prototype.global
RegExp.prototype.hasIndices
RegExp.prototype.ignoreCase
RegExp.prototype.multiline
RegExp.prototype.source
RegExp.prototype.sticky
RegExp.prototype.test()
RegExp.prototype.toString()
RegExp.prototype.unicode
RegExp.prototype.unicodeSets
New Language Features
I continue to favor working on runtime, but I've made some progress with language features as well:
Regular expression literals (effectively syntactic sugar for the
RegExp()
constructor)Hashbang comments [MDN]
The
new.target
meta property [MDN]Mapped
arguments
objects [Spec]An arguments exotic object is an exotic object whose array index properties map to the formal parameters bindings of an invocation of its associated ECMAScript function.
Parsing and basic bytecode generation for more function types:
- Async arrow functions
- Async function expressions/declarations
- Async generator expressions/declarations
- Generator expressions/declarations
However, they cannot run their function bodies in a meaningful way yet.
Windows Build
I personally haven't used Windows for anything in a long time, but I aim for Kiesel to work on all major operating systems. Thanks to Zig's amazing cross-compilation capabilities testing that doesn't even involve VMs or dual-booting!
Someone on the Zig Discord server gave me a hint how to fix one of the issues I encountered when trying to build a Windows executable, so I went ahead and fixed a few more. And now we have a working Windows build!
SyntaxError Source Hints
Syntax errors are edge cases and thus I haven't spent much effort on making them nice so far. Many of the error messages are not very useful, especially with the parser backtracking on unknown tokens and then telling you this nonsense:
$ cat file.js
function foo() { # }
$ kiesel file.js
SyntaxError: Unexpected token 'function' (file.js:1:1)
For the cases where the location is accurate this kind of line/column output is still not super helpful though, so I added source hints:
$ cat file.js
/[a-z]/x
$ kiesel file.js
/[a-z]/x
^
Uncaught exception: SyntaxError: Invalid RegExp flags (file.js:1:8)
Much better!
Recordings Are Back!
As mentioned above: I started recording some of the work I do on Kiesel, and there will definitely be more of that!
Videos are uploaded to both PeerTube and YouTube, and will be as irregular as ever :^)