Design and implement a register-based bytecode format and a compiler that transforms the AST into bytecode.
Scope#
Define the bytecode instruction set designed for JIT compilation (per CLAUDE.md: register-based, not stack-based). Implement a compiler that walks the AST and emits bytecode.
Bytecode Instruction Set#
Register operations:
- LoadConst(reg, const_idx) — load constant into register
- LoadNull(reg), LoadUndefined(reg), LoadTrue(reg), LoadFalse(reg)
- Move(dst, src) — copy register to register
- LoadGlobal(reg, name_idx), StoreGlobal(name_idx, reg)
Arithmetic/logic:
- Add(dst, lhs, rhs), Sub, Mul, Div, Mod, Exp
- BitAnd, BitOr, BitXor, ShiftLeft, ShiftRight, UShiftRight
- Neg(dst, src), BitNot(dst, src), LogicalNot(dst, src)
Comparison:
- Eq(dst, lhs, rhs), StrictEq, NotEq, StrictNotEq
- LessThan, GreaterThan, LessEq, GreaterEq
- TypeOf(dst, src), InstanceOf(dst, lhs, rhs)
Control flow:
- Jump(offset), JumpIfTrue(reg, offset), JumpIfFalse(reg, offset)
- Call(dst, func_reg, args_start, arg_count)
- Return(reg)
- Throw(reg)
Object/property:
- GetProperty(dst, obj_reg, key_reg)
- SetProperty(obj_reg, key_reg, val_reg)
- CreateObject(dst), CreateArray(dst)
Compiler#
- AST → bytecode function objects
- Constant pool per function (numbers, strings)
- Register allocator (simple linear scan or greedy)
- Scope analysis: resolve local variables to register slots
- Compile control flow (if/else, loops) to jump instructions
- Compile function literals to nested bytecode functions
Bytecode Module#
- Function header: register count, parameter count, constant pool
- Bytecode is a
Vec<u8>orVec<u32>with instruction encoding - Debug info: source map (bytecode offset → source line)
Acceptance Criteria#
- Bytecode instruction enum with binary encoding
- Bytecode disassembler for debugging
- Compiler handles arithmetic/logical expressions
- Compiler handles variable declarations and assignments
- Compiler handles if/else, for, while, do-while
- Compiler handles function declarations and calls
- Register allocation for local variables
- Constant pool for literals
- Unit tests: compile simple programs and verify bytecode output
Phase 10 — JavaScript Engine (issue 3 of 15). Depends on: JS Parser.