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,74 +1,84 @@
use std::rc::Rc;
use derive_more::Constructor;
use gc_arena::Mutation;
use gc_arena::Collect;
use crate::error::Result;
use crate::vm::VM;
use super::Value;
use super::CoW;
#[derive(Debug, Clone, Constructor)]
pub struct PrimOp<'jit: 'vm, 'vm> {
#[derive(Debug, Clone, Constructor, Collect)]
#[collect(require_static)]
pub struct PrimOp<'gc> {
pub name: &'static str,
arity: usize,
func: fn(&'vm VM<'jit>, Vec<Value<'jit, 'vm>>) -> Result<Value<'jit, 'vm>>,
func: fn(Vec<Value<'gc>>, &VM, &Mutation<'gc>) -> Result<Value<'gc>>,
}
impl PartialEq for PrimOp<'_, '_> {
impl PartialEq for PrimOp<'_> {
fn eq(&self, _: &Self) -> bool {
false
}
}
impl<'jit, 'vm> PrimOp<'jit, 'vm> {
pub fn call(&self, vm: &'vm VM<'jit>, arg: Value<'jit, 'vm>) -> Result<Value<'jit, 'vm>> {
impl<'gc> PrimOp<'gc> {
pub fn call(&self, arg: Value<'gc>, vm: &VM, mc: &Mutation<'gc>) -> Result<Value<'gc>> {
let mut args = Vec::with_capacity(self.arity);
args.push(arg);
if self.arity > 1 {
Value::PartialPrimOp(
PartialPrimOp {
CoW::new(PartialPrimOp {
name: self.name,
arity: self.arity - 1,
args,
func: self.func,
}
.into(),
}, mc)
)
.ok()
} else {
(self.func)(vm, args)
(self.func)(args, vm, mc)
}
}
}
#[derive(Debug, Clone)]
pub struct PartialPrimOp<'jit: 'vm, 'vm> {
#[derive(Clone)]
pub struct PartialPrimOp<'gc> {
pub name: &'static str,
arity: usize,
args: Vec<Value<'jit, 'vm>>,
func: fn(&'vm VM<'jit>, Vec<Value<'jit, 'vm>>) -> Result<Value<'jit, 'vm>>,
args: Vec<Value<'gc>>,
func: fn(Vec<Value<'gc>>, &VM, &Mutation<'gc>) -> Result<Value<'gc>>,
}
impl PartialEq for PartialPrimOp<'_, '_> {
unsafe impl<'jit: 'vm, 'vm, 'gc> Collect for PartialPrimOp<'gc> {
fn trace(&self, cc: &gc_arena::Collection) {
for v in self.args.iter() {
v.trace(cc);
}
}
}
impl PartialEq for PartialPrimOp<'_> {
fn eq(&self, _: &Self) -> bool {
false
}
}
impl<'jit: 'vm, 'vm> PartialPrimOp<'jit, 'vm> {
impl<'gc> PartialPrimOp<'gc> {
pub fn call(
self: &mut Rc<Self>,
vm: &'vm VM<'jit>,
arg: Value<'jit, 'vm>,
) -> Result<Value<'jit, 'vm>> {
let self_mut = Rc::make_mut(self);
self: &mut CoW<'gc, Self>,
arg: Value<'gc>,
vm: &VM,
mc: &Mutation<'gc>
) -> Result<Value<'gc>> {
let func = self.func;
let self_mut = self.make_mut(mc);
self_mut.args.push(arg);
self_mut.arity -= 1;
if self_mut.arity > 0 {
Value::PartialPrimOp(self.clone()).ok()
} else {
let args = std::mem::take(&mut self_mut.args);
(self.func)(vm, args)
func(std::mem::take(&mut self_mut.args), vm, mc)
}
}
}