38 lines
1.1 KiB
Rust
38 lines
1.1 KiB
Rust
use prometeu_bytecode::{HeapRef, Value};
|
|
|
|
/// Visitor for GC roots. Implementors receive every `HeapRef` discovered
|
|
/// during root traversal. No marking/sweeping semantics here.
|
|
pub trait RootVisitor {
|
|
fn visit_heap_ref(&mut self, r: HeapRef);
|
|
}
|
|
|
|
/// Helper: if `val` is a `Value::HeapRef`, call the visitor.
|
|
pub fn visit_value_for_roots<V: RootVisitor + ?Sized>(val: &Value, visitor: &mut V) {
|
|
if let Value::HeapRef(r) = val {
|
|
visitor.visit_heap_ref(*r);
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::VirtualMachine;
|
|
|
|
struct CollectVisitor { pub seen: Vec<HeapRef> }
|
|
impl RootVisitor for CollectVisitor {
|
|
fn visit_heap_ref(&mut self, r: HeapRef) { self.seen.push(r); }
|
|
}
|
|
|
|
#[test]
|
|
fn visits_heapref_on_operand_stack() {
|
|
let mut vm = VirtualMachine::default();
|
|
// Place a HeapRef on the operand stack
|
|
vm.push_operand_for_test(Value::HeapRef(HeapRef(123)));
|
|
|
|
let mut v = CollectVisitor { seen: vec![] };
|
|
vm.visit_roots(&mut v);
|
|
|
|
assert_eq!(v.seen, vec![HeapRef(123)]);
|
|
}
|
|
}
|