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.
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
Recently, we've taken the idea of a malleable implementation further. The
desugaring function produces large S5 programs in order to match the standard
with as much fidelity as possible. However, not all analyses or tool-writers
want or need all that detail – if an analysis assumes lexical scope, for
example, S5 provides more detail than the analysis needs. Assuming lexical
scope in the context of (nonstrict)
eval is an unsound assumption,
so removing this detail needs to be done with that in mind, but it also may may
some analyses more tractable. With this in mind, we investigated semantics-altering
transformations to the generated code that produce much smaller resulting
S5 programs, at the cost of some semantic fidelity (measured by test
S5 is built on λJS, but extends it in three significant ways:
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.
S5 is open source and lives in a Github repository.