lucia_lang/objects/
closure.rs

1use std::hash::{Hash, Hasher};
2
3use gc_arena::{lock::Lock, Collect, Gc, Mutation};
4
5use crate::{compiler::code::Code, objects::Value};
6
7#[derive(Debug, Clone, Copy, Collect)]
8#[collect(no_drop)]
9pub struct Closure<'gc>(pub Gc<'gc, ClosureState<'gc>>);
10
11impl<'gc> PartialEq for Closure<'gc> {
12    fn eq(&self, other: &Closure<'gc>) -> bool {
13        Gc::ptr_eq(self.0, other.0)
14    }
15}
16
17impl<'gc> Eq for Closure<'gc> {}
18
19impl<'gc> Hash for Closure<'gc> {
20    fn hash<H: Hasher>(&self, state: &mut H) {
21        Gc::as_ptr(self.0).hash(state)
22    }
23}
24
25impl<'gc> Closure<'gc> {
26    pub fn new(mc: &Mutation<'gc>, function: Code, base_closure: Option<Closure<'gc>>) -> Self {
27        Closure(Gc::new(
28            mc,
29            ClosureState {
30                upvalues: vec![Gc::new(mc, Lock::new(Value::Null)); function.def_upvalue_count],
31                function,
32                base_closure,
33            },
34        ))
35    }
36}
37
38#[derive(Debug, Collect)]
39#[collect(no_drop)]
40pub struct ClosureState<'gc> {
41    pub function: Code,
42    pub base_closure: Option<Closure<'gc>>,
43    pub upvalues: Vec<Gc<'gc, Lock<Value<'gc>>>>,
44}