Building a javascript runtime in one month
27 points by themackabu
27 points by themackabu
why does this use a link shortener to link the actual post?: https://themackabu.dev/blog/js-in-one-month?utm_medium=social&utm_campaign=slashfurry
it also goes through several redirects on the way, which seems quite suspicious.
I was bored when creating my site, and when I made this blog post I liked how my domain tail.so looked, so I decided to have it redirect
Why add another redirect in between to https://slash.furry.win/s/js-in-one-month? The multiple redirects makes it feel sketchy.
I can’t seem to edit the link so here is the original for everyone https://themackabu.dev/blog/js-in-one-month
The standards of 25 years ago aren’t actually really relevant because like many web standards of the era they were garbage and did not actually say what you needed to do to be a correct (as in compatible with actual content) implementation. It was really only at ES3.1 and then to a more complete extreme ES5 that simply following the spec would give you an engine that passed.
A large percentage of the validity tests you see today are derived from the many many test cases different engines had to write to reverse engineer the correct (as in “will work on the web”) behaviour that was unspecified, ambiguously specified, or incorrectly specified. While the standards are much much larger today, actually creating a correct implementation of them is much easier - there’s just more work to do. It’s why engines like ladybird are even possible.
That said: of course automatic semicolon insertion is in the standard - why would it not be? It’s also not that complex to implement, there’s a relatively small number of places where it applies and the logic itself is simple.
I was around (very much on the fringes) when Microsoft was trying to write their first ECMAScript draft (which was submitted to Netscape's surprise — I guess they expected ECMA to just rubber-stamp their sole submission). Apparently this required all-nighters of probing Netscape's interpreter with test cases, accompanied by frustrated screams echoing down the hallway when someone tried a bit of JS code to clarify a point of Netscape's intended behavior, and instead it crashed the Netscape interpreter, so they had no idea what to write down.
(edited for clarity)
Yuuuup, that was me and JavaScriptcore but I was trying to thread the compatibility requirements of spider monkey and jscript (I’ve actually forgotten the real engine name), and whatever was happening in ie4mac (though that was mostly dom,css etc as it was using Tasman rather than trident)
I mostly went for ES1 because the javascript-zoo conformance had them, I had no other reason to be exactly accurate with ES1
Oh yeah you want the full set of all versions.
Did you enjoy implementing blink() etc? :D
I did not add blink :( I couldn’t get it working in stdout properly, I only added what javascript-zoo categorized as es1
of course automatic semicolon insertion is in the standard - why would it not be? It’s also not that complex to implement, there’s a relatively small number of places where it applies and the logic itself is simple.
It is crazy to me that many languages require semicolons, since single line expressions/statements are the norm not the exception. The one language that should require semicolons is the one designed to be embedded in an another document and sent over the internet where line ending conventions are still split between \n and \r\n (and back in the 90s \r on Mac). Of all languages, JavaScript is the one language that ought to require semicolons!
Most statements vs all statements is a big difference. The canonical way you hit this is with things that don’t get asi in js, like return statements, break, continue etc
E.g Return 1+3 Return 1+ 3 Return 1 + 3 Break foo Break foo
You could put indentation rules in place but that’s less explicit, and much harder to read, then explicit statement termination.
did you know that
thisbinding changes depending on context, and that hoisting means variables declared withvarexist before they're assigned? evenwindow.window.windowis valid...
I don't want to sound snobby, but yes? Aren't these things that working JavaScript programmers all know? I can't say that I know about all the ins and outs of JavaScript, but the difference between function and arrow funcs is important to understand as a working programmer. var vs. let is also important to know even if the takeaway is just "always use let".
Fun examples. This works:
function a() {
b(); // b is hoisted from below
function b() { console.log("b"); }
}
The first of these fails with TypeError: b is not a function. because b is undefined but the second fails with ReferenceError: Can't find variable: b:
function a() {
b(); // b exists but is undefined
var b = function b() { console.log("b"); }
}
function a() {
b(); // b does not exist
let b = function b() { console.log("b"); }
}
I personally did not know until I experimented around, and maybe even some other people did not either.
There are a lot of details of JS that developers don’t necessarily know. I would strongly suggest looking through the Ecma 262 spec, and the test 262 test suite, if you haven’t already as part of making your engine. There are lots of awkward corners, but everyone involved in writing and reviewing that spec tries really hard to make sure that it is clear and complete. There are a bunch of minor details that have changed since ES5, and other places where a lot of work has been done to simplify and clarify things without changing behavior.
Like I would not say that I "know" the rules of how precisely this works, so much as that I know that this is context dependent, and if it's not doing the expected thing, you have to look up the rules or do an experiment.
I think it probably also helps that I was programming in JS before ES6 fixed everything, so I was acquainted with the old rules from when I read JS: The Good Parts and whatnot.
Modules and realms make some of the this handling quite tricky. There are a bunch of things old engines did that suddenly needed to be refactored.