To this end, we've developed S5, an ECMAScript 5 runtime, built on λJS, with the explicit goal of helping people understand and tinker with the language. We built it to understand the features in the new standard, building on our previous efforts for the older standard. We've now begun building analyses for this semantics, and are learning more about it as we do so. We're making it available with the hope that you can join us in playing with ES5, extending it with new features, and building tools for it.
S5 implements the core features of ES5 strict mode. How do we know this? We've tested S5 against Test262 to measure our progress. We are, of course, not feature complete, but we're happy with our progress, which you can check out here.
A Malleable Implementation
This separation of concerns is what makes our implementation so amenable to
exploration. If you want to try something out, you can edit the environment
file and rerun whatever tests you care to learn about. Want to try a different
implementation of the
== operator? Just change the definition, as
it was pulled from the spec, at line
300. Want a more expressive
Object.toString() that doesn't
"[object Object]"? That's right
here. No changing an interpreter, no recompiling a desugaring function
More than λJS
S5 is built on λJS, but extends it in three significant ways:
- Explicit getters and setters;
- Object fields with attributes, like
- Support for
Attributes on objects weren't treated directly in the original
In 5th Edition, they are crucial to several security-relevant operations on
objects. For example, the standard specifies
which makes an object's properties forever unwritable. S5 directly models the
configurable attributes that make this
operation possible, and make its implementation in S5 easy to understand.
λJS explicitly elided
eval() from its semantics. S5
eval() by performing desugaring within the
interpreter and then interpreting the desugared code. We implement only
the strict mode version of
eval, which restricts the environment
eval'd code can affect. With these restrictions, we can
eval in a straightforward way within our interpreter.
We'll cover the details of how we do this, and why it works, in another post.
Building on S5There's a ton we can do with S5. More, in fact, than we can do by ourselves:
- Experiment with Harmony features: ECMAScript 6, or Harmony, as it is often called, is being designed right now. Proxies, string interpolation, syntactic sugar for classes, and modules are just a few of the upcoming features. Modeling them in S5 would help us understand these features better as they get integrated into the language.
- Build Verification Tools: Verification based on objects' attributes is an interesting research problem―what can we prove about interacting programs if we know about unwritable fields and inextensible objects? Building this knowledge into a type-checker or a program analysis could give interesting new guarantees.
- Abstract Our Machine: Matt Might and David van Horn wrote about abstracting λJS for program analysis. We've added new constructs to the language since then. Do they make abstraction any harder?
- Complete the Implementation: We've made a lot of progress, but there's still more ground to cover. We need support for more language features, like JSON and regular expressions, that would move our implementation along immensely. We'll work on this more, but anyone who wants to get involved is welcome to help.
If any of this sounds interesting, or if you're just curious, go ahead and check out S5! It's open source and lives in a Github repository. Let us know what you do with it!