1. 27
  1. 2

    That was very interesting and well explained, I’ve always wondered how does a JIT compiler actually work but never bothered to find out.

    You got me excited for the second part!

    1. 6

      Here are two other great intros I always fall back on:

      1. 3

        Well it’s your lucky day! I got bored this morning and wrote about compiling integers.

        1. 1

          struct ASTNode;

          typedef struct ASTNode ASTNode;

          The first line is redundant given the second one; struct ASTNode already names the incomplete type. So you can just keep the second line and elide the first.

          1. 1

            Thanks! This was cut & pasted from a more advanced version of the compiler which had some intermediate datatypes in the middle (cons, etc) that referenced struct ASTNode *.

            Why did you remove your other comment? Sorry, I hadn’t gotten around to reading & replying yet.

      2. 2

        This series is off to a good start. I’m interested to follow it… most Build Your Own Lisp type projects use a virtual machine instead of compiling down to native code.

        1. 2

          I wrote a series last year on compiling a lisp to amd64 assembly in JavaScript. Unlike this series mine is on AOT, not JIT compilation. In the series I explored simple register-based usage of amd64, LLVM, and ultimately another variant of amd64 using it more solely as a stack machine.

          You may be interested: https://notes.eatonphil.com/compiler-basics-lisp-to-assembly.html

          1. 2

            Thanks for this! I’ll definitely be reading this later today.

            1. 1

              I think we solved basically the same problem except that you are using an external assembler and linker to generate the ELF file for you.

              1. 1

                Well fundamentally I’m not JIT compiling (writing and executing memory in the same process) but yeah other than that the two are similar.

                1. 1

                  Oh, I think there’s our linguistic difference. I draw the line in a different place:

                  AOT: Compile the whole program to the target architecture. May or may not include disk I/O.

                  JIT: Compile the pieces you need, when you need them, and probably have some kind of inline caching and inlining.

              2. 1

                Indeed I am interested. Thank you, will look at your series too.

              3. 1

                Where do you get all these Lisps with VMs? I seem to find only tree-walking interpreters.

                1. 2

                  Lisp in Small Pieces was the one I had greatest hopes for.

                  1. 1

                    The Lisp System Implementation book similarly targets a vm.

              4. 2

                Good start! Looking forward to the rest.

                1. [Comment removed by author]

                  1. 1

                    You can find decent amount of info from existing languages. Just look up “object representation” in Chicken Scheme, Python, OCaml, V8, etc. I was always told though that the memory scheme doesn’t actually matter a whole lot overall so you can just do whatever reasonable representation you think of. Then again, there’s a lot of discussion you can find on optimizing OCaml’s number representation so of course you can optimize too.

                  2. 1

                    Future picolisp implementation on LLVM-IR — https://github.com/picolisp/pil21