feat: gc-arena (WIP, does not compile)

This commit is contained in:
2025-05-25 17:18:54 +08:00
parent b41fd38bcc
commit cc06369c5e
17 changed files with 882 additions and 585 deletions

View File

@@ -1,59 +1,72 @@
use std::rc::Rc;
use gc_arena::{Gc, Mutation};
use hashbrown::HashMap;
use crate::env::VmEnv;
use crate::ty::common::Const;
use crate::ty::internal::{AttrSet, PrimOp, Value};
use crate::ty::internal::{AttrSet, CoW, PrimOp, Value};
use crate::vm::VM;
pub fn env<'jit, 'vm>(vm: &'vm VM<'jit>) -> VmEnv<'jit, 'vm> {
let primops = [
PrimOp::new("add", 2, |_, args| {
let [mut first, second]: [Value; 2] = args.try_into().unwrap();
pub fn env<'gc>(vm: &VM<'gc>, mc: &Mutation<'gc>) -> Gc<'gc, VmEnv<'gc>> {
let primops: [PrimOp<'gc>; 7] = [
PrimOp::new("add", 2, |args, _, _| {
let Ok([mut first, second]): Result<[Value; 2], _> = args.try_into() else {
unreachable!()
};
first.add(second);
first.ok()
}),
PrimOp::new("sub", 2, |_, args| {
let [mut first, mut second]: [Value; 2] = args.try_into().unwrap();
PrimOp::new("sub", 2, |args, _, _| {
let Ok([mut first, mut second]): Result<[Value; 2], _> = args.try_into() else {
unreachable!()
};
second.neg();
first.add(second);
first.ok()
}),
PrimOp::new("mul", 2, |_, args| {
let [mut first, second]: [Value; 2] = args.try_into().unwrap();
PrimOp::new("mul", 2, |args, _, _| {
let Ok([mut first, second]): Result<[Value; 2], _> = args.try_into() else {
unreachable!()
};
first.mul(second);
first.ok()
}),
PrimOp::new("div", 2, |_, args| {
let [mut first, second]: [Value; 2] = args.try_into().unwrap();
PrimOp::new("div", 2, |args, _, _| {
let Ok([mut first, second]): Result<[Value; 2], _> = args.try_into() else {
unreachable!()
};
first.div(second)?;
first.ok()
}),
PrimOp::new("lessThan", 2, |_, args| {
let [mut first, second]: [Value; 2] = args.try_into().unwrap();
PrimOp::new("lessThan", 2, |args, _, _| {
let Ok([mut first, second]): Result<[Value; 2], _> = args.try_into() else {
unreachable!()
};
first.lt(second);
first.ok()
}),
PrimOp::new("seq", 2, |vm, args| {
let [mut first, second]: [Value; 2] = args.try_into().unwrap();
first.force(vm).unwrap();
PrimOp::new("seq", 2, |args, vm, mc| {
let Ok([mut first, second]): Result<[_; 2], _> = args.try_into() else {
unreachable!()
};
first.force(vm, mc).unwrap();
second.ok()
}),
PrimOp::new("deepSeq", 2, |vm, args| {
let [mut first, second]: [Value; 2] = args.try_into().unwrap();
first.force_deep(vm).unwrap();
PrimOp::new("deepSeq", 2, |args, vm, mc| {
let [mut first, second] = *args.into_boxed_slice() else {
unreachable!()
};
first.force_deep(vm, mc).unwrap();
second.ok()
}),
];
let mut env_map = HashMap::new_in(&vm.bump);
let mut env_map = HashMap::new();
env_map.insert(vm.new_sym("true"), Value::Const(Const::Bool(true)));
env_map.insert(vm.new_sym("false"), Value::Const(Const::Bool(false)));
let mut map = HashMap::new();
for primop in primops {
let primop = Rc::new(primop);
let primop = Gc::new(mc, primop);
env_map.insert(
vm.new_sym(format!("__{}", primop.name)),
Value::PrimOp(primop.clone()),
@@ -61,12 +74,12 @@ pub fn env<'jit, 'vm>(vm: &'vm VM<'jit>) -> VmEnv<'jit, 'vm> {
map.insert(vm.new_sym(primop.name), Value::PrimOp(primop));
}
let sym = vm.new_sym("builtins");
let attrs = Rc::new_cyclic(|weak| {
map.insert(sym, Value::Builtins(weak.clone()));
let attrs = CoW::new_cyclic(|this| {
map.insert(sym, Value::AttrSet(this));
AttrSet::from_inner(map)
});
}, mc);
let builtins = Value::AttrSet(attrs);
env_map.insert(sym, builtins);
VmEnv::new(vm.bump.alloc(env_map), &vm.bump)
VmEnv::new(Gc::new(mc, env_map.into()), mc)
}