Boa release v0.21 - a new release of Boa, a JavaScript engine written in Rust
42 points by nekevss
42 points by nekevss
Hi all! If you have any questions about Boa, feel free to ask.
In this release, our conformance has grown to 94.12% in the official ECMAScript Test Suite (Test262).
Highlights
Polished our implementation of the Temporal proposal to reach ~97% conformance on Temporal-related tests.
Added support for span nodes and error backtraces.
Enhanced Boa's compatibility with async Rust by revamping JobQueue and asyncifying ModuleLoader.
Introduced a new set of macros to facilitate creating ECMAScript values, classes and modules from Rust code.
Implemented several runtime features in boa_runtime, including fetch, setTimeout, and queueMicrotask.
Added some support for conformance testing runtime features against the Web Platform Tests (WPT).
JsValue now uses a Nan-boxing representation, reducing the memory footprint of the engine.
Migrated from a stack-based VM to a register based VM.
New built-ins
Implemented Atomics.waitAsync.
Implemented new Set methods.
Implemented Float16 support in TypedArray, Dataview and Math built-ins.
Implemented Error.isError.
Implemented Math.sumPrecise.
Implemented Array.fromAsync.
The space of "Javascript Engine" seems reasonably diverse to me already. Even if you limit it to the FOSS engines, you've got V8, SpiderMonkey, JavascriptCore, Rhino, LibJS, GraalJS, Hermes, QuickJS, Escargot, Otto, and I'm sure I'm missing a few.
Naively, I would have included Deno on the list, but I see that they're calling themselves a "runtime" rather than an "engine".
This is the first I've heard of Boa, and when I visit the homepage, it just tells me that it is "An ECMAScript engine written in Rust".
Can you point me to a primer on Boa's strong points relative to the rest, and why someone might pick it out of this zoo? And maybe also how it's different from Deno, which I thought was an "engine" too.
(The release notes look like you've done a very nice release! I'm just trying to identify where this fits in the world and what conditions might make me want to use it, and I haven't found that on the homepage yet.)
Understanding the difference between an engine and a runtime would probably do a lot to clear things up for you. In brief, an engine is what parses and evaluates JavaScript code. A runtime provides the means by which JavaScript can be loaded into an engine, as well as other practical APIs such as the standard web API or file system APIs. Most applications need a runtime such as a web browser or a server-side runtime like Node, Deno, or Bun. The engine is at the next layer down and is mostly invisible to JavaScript application developers except in terms of language coverage and performance. If you’re still interested in engines and Boa in particular, check out the about page, which does a much better job than I could to describe the project’s motivations and intended use.
Thanks, that's helpful. A few dayjobs ago, we built up some tooling around spidermonkey. I guess we were mostly using it as an engine, but it provided low-rent versions of some runtime facilities and we provided not-quite-as-low-rent versions of other things that are probably more on the runtime side of the line.
We used it to de-obfuscate malware without either letting it run somewhere or needing to hand-roll our de-obfuscator. Oddly, it was a fun thing to work on, and I'd like to never touch it again. But if I needed to, reviving it in wasm with boa sounds like it would be an appealing path.
The about section would probably be where I would typically point you, so it's good that was mentioned.
The first thing that typically gets asked is: why write a JavaScript engine? And part of the truth is that a lot of us work on it because we find it fun and interesting! Another goal is to have a ECMAScript implementation that is written in Rust and brings along with it Rust's memory safety guarantees. Most of the primary engines are large C++ codebases that have to be used by Rust projects via FFI binding crates (rusty_v8 or mozjs).
The difference between an engine and runtime was already covered briefly above, but to expand, JavaScript engines (or some of us, primarily me, likes to refer to them as ECMAScript engines) implement the ECMAScript specification, which is the ECMA specified language features. The runtime implements the web API alongside other runtime concerns that are not in the core specification. That is why if you used Boa directly without registering any runtime features, then you would not be able to use console or setTimeout. How does this make us different from Deno? Deno maintains bindings to V8 in their rusty_v8 crate, so that is their core ECMAScript implementation. Deno could, if they wanted to, switch to Boa under the hood one day and still be Deno.
Boa as an engine that implements the ECMAScript specification is still fairly young. While we are probably the older and most "mature" / conformant of the newer ECMAScript implementations, we still have a ways to go in respect to the primary browser JavaScript engines (V8, SpiderMonkey, and JavaScriptCore).
But the project is starting to reach a point though that we are having some positive impact on other implementations. Our temporal_rs library is being used in V8 and Kiesel for their temporal implementations.
Deno could, if they wanted to, switch to Boa under the hood one day and still be Deno.
That's neat, and that is a thing I was definitely missing, even after @adamshaylor's explanation above and reading the about page.
Thank you for taking the time to help me put Boa in context.
Deno could, if they wanted to, switch to Boa
Do you think Servo or some other browser would ever switch to Boa ? I know performance will be a make-or-break criteria and it'll take a lot of work to catch up to the likes of v8, but what would be the other pros and cons ?
I think that it would be nice to get Boa to a state where it is a viable option for those projects to choose. There will be a lot of work needed to catch up to V8, but there's potential to improve Boa's performance to the point that it is viable.
The pros would probably be to have a native Rust engine and not have to manage FFI bindings to the C++ libraries. I think there are some genuine benefits in just that change alone. But we would need to improve our performance.
Cons would be that SpiderMonkey and V8 are well tested and maintained software alongside the current performance cost. It would be hard to switch from either of those options, but I don't think that should necessarily be a blocker.
I'd be interested to see how the newer releases are tracking on https://github.com/khvzak/script-bench-rs
I haven't taken a glance at that specific bench myself, so it will definitely be interesting to see! We've made some performance improvements on this release vs. the previous release, but we still do have some more progress that can be made in terms of performance.
We are shifting more and more into focusing on our performance as our conformance is starting to reach a cap. So that number will hopefully start to drop with this release and more in the future.
I ran the benchmark on my system (it used Boa 0.20 and 0.21). It looks like the performance improvements are relatively significant and Boa has overtaken Rhai in this benchmark. Before/after image of results.
Wow! Thanks for running this! Good to see we've made progress. Still a long way to go though :)
Hi! Super cool project. Thank you for sharing. Given that the project has connections to TC39, is it conceivable that TC39 proposals could one day be implemented in forks of Boa so they could be used to try them out to better understand their implications before adoption? Or is that well outside the project’s design goals?
Thanks!
We try to implement proposals at around stage 3 when engines are roughly meant to pick up the proposals for implementation.
We do actually have a feature flag mechanism for implementing experimental features, so proposals could be implemented early in Boa if a proposal champion wants to implement it in an engine. Personally, I think there's even benefits to implement a feature in Boa because you have access to Rust's type system. But I'm not a member of tc39, so that decision for them and any proposal champion.
So, stage 4 already requires
- Two compatible implementations which pass the Test262 acceptance tests
- Significant in-the-field experience with shipping implementations, such as that provided by two independent VMs
And you can expect some engine devs to be experimenting from at least stage 2.7 onwards.
In terms of really early implementation and feedback engine262 is the easiest. Obviously it won’t give you much in terms of feedback on tread world performance, but it will help you find places where some crucial bit of information isn’t readily available or something like that, and it’s great for getting a feel for the sharp edges.