use std::cell::{Cell, OnceCell}; use std::rc::Rc; use crate::bytecode::Func as BFunc; use crate::env::VmEnv; use crate::error::Result; use crate::ir; use crate::jit::JITFunc; use crate::ty::internal::Value; use crate::vm::VM; #[derive(Debug, Clone)] pub enum Param { Ident(usize), Formals { formals: Vec<(usize, Option)>, ellipsis: bool, alias: Option, }, } impl From for Param { fn from(value: ir::Param) -> Self { match value { ir::Param::Ident(ident) => Param::Ident(ident), ir::Param::Formals { formals, ellipsis, alias, } => Param::Formals { formals: formals .into_iter() .map(|(sym, default)| (sym, default.map(|default| default.idx))) .collect(), ellipsis, alias, }, } } } pub struct Func<'gc> { pub func: &'gc BFunc, pub env: Rc>, pub compiled: OnceCell>, pub count: Cell, } impl<'gc> Func<'gc> { pub fn new(func: &'gc BFunc, env: Rc>) -> Self { Self { func, env, compiled: OnceCell::new(), count: Cell::new(0), } } pub fn call_compile(&self, arg: Value<'gc>, vm: &'gc VM<'gc>) -> Result> { let env = self.env.clone().enter_arg(arg); let compiled = self.compiled.get_or_init(|| vm.compile_func(self.func)); let ret = unsafe { compiled(env.as_ref() as *const VmEnv) }; Ok(ret.into()) } } impl PartialEq for Func<'_> { fn eq(&self, _: &Self) -> bool { false } }