The period before Spring Festival is usually relatively relaxing. The new OKR has not been set yet, and many big guys are preparing for the promotion defense, so I can draw water as a small transparent workplace. So in recent weeks, I’ve written a javascript interpreter from scratch:

zhuzilin/es

Why write such a project?

During the two years of learning the framework of deep learning, I have added a lot of knowledge related to compilation, so I have thought about whether to write a compiler by myself for many times. But on the one hand, I personally don’t like to write toy language, because the language I designed is easy to make a lot of compromises for the sake of writing without using scenarios, and I don’t do tests. On the other hand, JIT compiler is a daunting goal.

As a coincidence, I saw Filip Pizlo’s web Speculation in JavaScriptCore at the end of last year, which gave a pretty deep introduction to the current JSC framework, including the interpreter and three-tier JIts. And how dynamic languages accumulate type information as they run to switch between layers of JIts (i.e., Speculation in the title). Having such a general guide suddenly gave me the illusion that I could write JIT Compiler myself.

RednaxelaFX: Beginners on the road to JavaScript engine implementation

Constellation’s large LV5 JavaScript engine (Constellation/ IV · GitHub) is an inspiring and positive story that feeds back to each other. The JS engine has seen Constellation’s learning curve from a very small, very simple, intuitive implementation of ECMAScript 5 to a fairly complete, level of sophistication, modern implementation. He is constantly practicing in his own small projects, learning from the existing high performance JavaScript engines and getting good feedback.

It says that implementing an ES5-based JavaScript engine can start “very small and very simple.” So how easy can it be? Try it.

Finally, a very small reason was to see the Mold project accepted into GCC (GCC12 added support for Linker Mold, compared to other existing linker products, what’s your comment?) Rui Ueyama, author of Mold, also started out lifting 8cc on his own (I’m not sure if he wrote LLD first or 8CC…). With Constellation mentioned above, we are now also a REVIEWER of JSC. Give me the feeling that if you want to be a big guy at this level, you have to write your own compiler.

So back to the ES project. At present, it is in the state of intuitive implementation of ES5 standard. It has implemented all ES5 syntax and passed most non-ES6 tests in QuickJS projects. There are still some ES5 built-in functions and relatively independent modules such as Regex and JSON that are not implemented. The built-in functions are lazy to fill in when they are used, and the last two I think are relatively independent of the language itself, so I expect them to be deferred.

Theoretically, the technical details of the interpreter should follow. But as R said, implementing such a thing is very simple. The front end is a top-to-bottom Parser, and for the runtime part I thought it was enough to read the first few chapters of Essentials of Programming Languages (as an aside, EOPL was really the most enjoyable technical book I’ve read in two years). Therefore, in order to improve the technical content of this paper, let’s talk about the planning after this project.

First, near-term goals (a few months) :

  • Garbage collection: There is no garbage collection in this project yet. While it would be easy to simply put in a Mark and sweep, I wanted to do a bit of extensive research on the major JS engines (V8, JSC, SpiderMonkey, Hermes, QuickJS) and pick a solution that could handle the workload. If the research is good should also write a zhihu article to share;
  • Module: There is no modular support in the ES5 standard, so consider supporting modules in ES6 or CommonJS. The advantage of the former is that ES6, like ES5, has very standard standards, while the latter may need to be written according to node.js. The latter has the advantage of making it easier to support Babel later, since Babel seems to translate ES6 into ES5importintorequire. With Modules, it is also possible to support simple native modules such as Console (currently just one by hand)console.logEasy to use), FS, etc.

Medium-term goals (one to two years) :

  • Designing Bytecode for the interpreter: An efficient interpreter must have a Bytecode. This part is also to learn the design of all parties. I plan to learn JSC as a register based for the time being. But the JSC seems to be doing the JIT for frame control, the interpreter is written in an assembler like language of my own design, not sure if I’m going to do that…
  • Interpreter acceleration experiments: With bytecode, you can do all kinds of interpreter optimizations. At the moment, I’d like to try inline caching and various dispatch schemes.

Long-term Goals (3 to 5 years) :

  • JIT Compiler: it is supposed to implement a single-layer JIT, in which the optimization estimation is limited to the mir project pass or the SCOPE of THE JSC DFG JIT, that is, it will not do things with high complexity and long compilation time like LICM. The specific design is still completely unknown, there are still too many things to fix.

Some Optinal goals that probably won’t be done:

  • Node.js binding: We tried to write a simple Node binding for the test. However, I found a QuickJS test to replace it, so I gave it up for now. A brief investigation of Node.js on ChakraCore and SpiderNode seems to involve writing a V8 wrapper, so the workload is confusing. It would be nice if I could simply bind part of it so THAT I could run an Express or something;
  • JVM Bytecode: If the last design of bytecode is easy to offload onto the JVM, you can try it. It is convenient to do the benchmark, and also learn the most famous stack based Bytecode design.

I have always liked things that need to be accumulated over a long period of time. Whether it is learning a language or exercising, I believe in the great power of time, just like the story of hitting a boulder with a small hammer. For programmers, this accumulation may be limited to a Side project. So I hope I can have the good fortune to keep this project going.

By the way, even though es is still in its early stages, get a wave of STAR! If there is any problem in the process of running, please feel free to issue it