monkey-gc 0.15.1

QuickJS-style GC runtime for Monkey (bytecode VM with cycle collector)
Documentation

monkey-gc

QuickJS-style GC runtime for the Monkey programming language.

This crate is a GC-backed runtime that runs the same bytecode produced by monkey-compiler, but stores Monkey runtime values in a GcHeap instead of using Rc<Object> directly. It combines reference counting with a three-phase cycle collector so cyclic object graphs can be reclaimed.

For the full design notes, see docs/gc.md.

Usage

Parse, compile, and execute Monkey source:

let result = gc::eval_source("let add = fn(a, b) { a + b }; add(1, 2);").unwrap();
assert_eq!(result, object::Object::Integer(3));

Run an already parsed program:

let program = parser::parse("[1, 2, 3][1]").unwrap();
let result = gc::eval(&program).unwrap();
assert_eq!(result, object::Object::Integer(2));

Use the lower-level VM when you need direct access to the heap:

let program = parser::parse("let double = fn(x) { x * 2 }; double(21)").unwrap();
let bytecode = gc::compile(&program).unwrap();
let mut vm = gc::GcVM::new(bytecode);

vm.run();
vm.heap_mut().run_gc();

let result = vm.export_last_result().expect("no result on stack");
assert_eq!(result, object::Object::Integer(42));

Public API

  • eval_source parses, compiles, and runs Monkey source.
  • eval runs a parsed AST node through the bytecode compiler and GC VM.
  • compile reuses monkey-compiler to produce bytecode.
  • GcVM executes Monkey bytecode with GC-managed values.
  • GcHeap exposes allocation, dup/free, GC triggering, and heap inspection.
  • Value, GcClosure, import_object, and export_object bridge between GC-managed values and object::Object.

Runtime Model

monkey-gc is designed as a parallel runtime for the existing pipeline:

lexer -> parser -> compiler -> gc::GcVM

The crate does not replace the default compiler::VM, wasm, or playground runtime. Instead, it reuses the same Bytecode and opcode definitions while testing an alternate heap implementation.

Modules

  • heap.rs provides the high-level GcHeap and opaque GcRef handle.
  • runtime.rs implements reference counting and three-phase cycle collection.
  • header.rs, list.rs, and malloc.rs hold GC object metadata and allocator accounting.
  • value.rs defines GC-managed Monkey values plus import/export helpers.
  • frame.rs and vm.rs implement the bytecode VM runtime.

Development

Run the crate tests from the workspace root:

cargo test -p monkey-gc

Run the whole Rust workspace when changing shared compiler, object, or parser behavior:

cargo test