This page is a collection of my favorite resources for people getting started
writing programming languages. I hope to keep it updated as long as I continue
to find great stuff.
Compilers
Lisp specific
Runtimes
Runtime optimization
Here are some resources I have found useful for understanding the ideas and
research around optimizing dynamic languages.
And here are runtime optimization resources that I wrote!
- Inline caching, a post containing a small demo of
how to speed up attribute lookups in an interpreter
- Inline caching: quickening, a post about
speeding up interpreters using self-modifying bytecode (“bytecode rewriting”
or “quickening”)
- Small objects and pointer tagging, a post about
speeding up interpreters using pointer tagging and encoding small objects
inside pointers
Pointer tagging and NaN boxing
Resources on representing small values efficiently.
Just-In-Time compilers
Small JITs to help understand the basics. Note that these implementations tend
to focus on the compiling ASTs or IRs to machine code, rather than the parts of
the JIT that offer the most performance: inline caching and code inlining.
Compiling is great but unless you’re producing good machine code, it may not do
a whole lot.
Assembler libraries
Sometimes you want to generate assembly from a host language. Common use cases
include compilers, both ahead-of-time and just-in-time. Here are some libraries
that can help with that.
For more inspiration, check out some of the assemblers in runtimes I mention in
my Compiling a Lisp post.
Little low-level JIT IR libraries
Things I want to write about
I have not written much about runtime optimization yet, but I would like to
write about:
- Assembly interpreters (known to the JDK folks as a “template interpreter”)
- Inline caching for attribute lookup
- Including actually-inline assembly caches with
cmp
/jmp
and stub, and a
C++ wrapper
(How does V8 do it?
Hotspot?
Dart (maybe)? JSC?)
- Object shapes / hidden classes / layouts
- Compact objects
- Attaching intrinsic functions or assembly stubs to well-known functions
- Garbage collectors
- Fast paths for common cases (“do less”)
- JIT intermediate representations and how they help solve problems around
megamorphic call sites, inlining, etc
- The GDB JIT interface & maintaining a parseable stack for unwinding
- Exception handling side-tables instead of block stacks
- Debugging mindsets
- Ways to think about debugging that make the process less stressful and
thrashy
- Code transformations and analysis
- Definite assignment analysis
- Static Single Assignment (SSA)
- Writing JITs without writing assembly
- Precise native stack roots
- Type lattices
Papers I want to read
SystemV ABI
This is mostly a reminder for myself because I can never remember the order of
registers. Sourced from the AMD64 ABI Draft
1.0
(PDF).
Caller-saved: rax
, rcx
, rdx
, rsi
, rdi
, r8
-r11
, xmm0
-xmm15
.
Callee-saved: rbx
, rsp
, rbp
, r12
-r15
.
For integers
Return values in rax
and rdx
.
Parameter |
Register |
1 |
rdi |
2 |
rsi |
3 |
rdx |
4 |
rcx |
5 |
r8 |
6 |
r9 |
Once registers are assigned, the arguments passed in memory are pushed on
the stack in reversed (right-to-left) order
For doubles
Return values in xmm0
and xmm1
.
Parameter |
Register |
1 |
xmm0 |
2 |
xmm1 |
3 |
xmm2 |
4 |
xmm3 |
5 |
xmm4 |
6 |
xmm5 |
7 |
xmm6 |
8 |
xmm7 |
This is a sort of grab-bag for helpful or interesting tools for programming
language implementation.
(wow, this is turning into a Justine Section)
Right now this is probably going to just be a section on Ninja clones.
- Ninja, the original version
- n2, another implementation by the original
author (Rust)
- samurai (C99)
- Turtle, a version focused on
high-level languages (Rust)
Game Boy Emulators
- The Pan Docs, which give technical data about
the Game Boy hardware, I/O ports, flags, cartridges, memory map, etc
- This excellent explanation
of the boot ROM
- This opcode table
that details the full instruction set, including CB opcodes
- This full opcode reference for
the GBZ80
- The Game Boy CPU manual (PDF)
- The GameBoy memory map
- This blog post that gives a
pretty simple state machine for the different rendering steps
- The Ultimate Game Boy Talk
(video) by Michael Steil at CCC
- This ROM generator for custom logos
- This sample DAA implementation
- This awesome-gbdev list
- This excellent emulator and debugger
- Another emulator and debugger
- The Game Boy complete technical reference (PDF)
- This Gameboy Overview
- blargg’s test ROMs
which have instruction tests, sound tests, etc
- gekkio’s emulator
and his test ROMs
- This fairly readable Go emulator,
which has helped me make sense of some features
- This fairly readable C emulator
- This fairly readable C++ implementation
- This helpful GPU implementation in Rust
- This reference
for decoding GameBoy instructions.
- NOTE: This has one bug
that someone and I independently found. The original repo
has fixed the bug but not the page linked above.
- This summary blog post
explaining GPU modes
- And of course /r/emudev
- DIY emulator/VM resources
This is a potentially fun way to
render the screen without SDL, but only for non-interactive purposes.
This YouTube
playlist looks like it could be worth a watch, but it’s a lot of hours.
Lists
I should probably pick and choose some great stuff from these lists to copy
onto this page.
Communities