Low-level Virtual Machine for compiler backends
- November 2019
- www.c-sachdeva.github.io/C0VM (private)
Overview
Built a Virtual Machine for C0 (C-like language developed at CMU) influenced by JVM and LLVM.
The C0VM is a stack machine, similar in design the JVM. Arithmetic operations and other instructions pop their operands from an operand stack and push their
result back onto the operand stack.
The C0VM has a call stack consisting of frames, each one containing local variables, a local
operand stack, and a return address. The call stack grows when a function is called and
shrinks when a function returns, deallocating the frame during the return.
Every frame consists of the four components that represent the current state of some
function call that got interrupted in order to call another function. It contains the operand
stack S for computing expression values, a pointer P to the function's byte code, a return
address pc, which is the address of the next instruction in the interrupted function, and an
array of locals V. At any point during the execution there is a current frame as well as a
calling frame. The latter becomes the current frame when a function returns to its caller.
Numerical constants requiring more than 8 bits and all string constants occurring in the
programa are allocated in constant pools, called the integer pool and the string pool. They
never change during program execution.
Functions, either C0 functions defined in a source file or library functions, are kept in pools
called the function pool and the native pool, respectively. Functions in the function pool are
stored with their bytecode instructions, while functions in the native pool store an index into
a table of C function pointers that the C0VM implementation can dereference and invoke.