mica_language/value/
traits.rs

1use std::rc::Rc;
2
3use crate::bytecode::{DispatchTable, Environment, Opr24};
4use crate::gc::{GcRaw, Memory};
5
6use super::Closure;
7
8/// Instance of a trait.
9pub struct Trait {
10   pub(crate) id: Opr24,
11   pub(crate) dtable: GcRaw<DispatchTable>,
12}
13
14impl Trait {
15   pub fn dtable(&self) -> &DispatchTable {
16      // SAFETY: This operation is safe, because the dtable of a trait can never be modified.
17      unsafe { self.dtable.get() }
18   }
19}
20
21/// Creates a new instance of a trait inside the given GC memory.
22pub fn create_trait(env: &mut Environment, gc: &mut Memory, trait_id: Opr24) -> GcRaw<Trait> {
23   let prototype = env.get_trait(trait_id).expect("trait with given ID does not exist");
24   let name = &prototype.name;
25   let mut dispatch_table = DispatchTable::new_for_type(Rc::clone(name));
26   dispatch_table.pretty_name = Rc::from(format!("trait {name}"));
27   for &(method_id, function_id) in &prototype.shims {
28      let closure = gc.allocate(Closure {
29         function_id,
30         captures: vec![],
31      });
32      dispatch_table.set_method(method_id, closure);
33   }
34   let dispatch_table = gc.allocate(dispatch_table);
35   gc.allocate(Trait {
36      id: trait_id,
37      dtable: dispatch_table,
38   })
39}