feat(env): move env out of vm,

This commit is contained in:
2025-05-23 19:19:20 +08:00
parent 5291e49313
commit b41fd38bcc
10 changed files with 62 additions and 41 deletions

View File

@@ -2,9 +2,10 @@ use std::rc::Rc;
use hashbrown::HashMap; use hashbrown::HashMap;
use crate::env::VmEnv;
use crate::ty::common::Const; use crate::ty::common::Const;
use crate::ty::internal::{AttrSet, PrimOp, Value}; use crate::ty::internal::{AttrSet, PrimOp, Value};
use crate::vm::{VM, VmEnv}; use crate::vm::VM;
pub fn env<'jit, 'vm>(vm: &'vm VM<'jit>) -> VmEnv<'jit, 'vm> { pub fn env<'jit, 'vm>(vm: &'vm VM<'jit>) -> VmEnv<'jit, 'vm> {
let primops = [ let primops = [
@@ -50,7 +51,6 @@ pub fn env<'jit, 'vm>(vm: &'vm VM<'jit>) -> VmEnv<'jit, 'vm> {
env_map.insert(vm.new_sym("true"), Value::Const(Const::Bool(true))); env_map.insert(vm.new_sym("true"), Value::Const(Const::Bool(true)));
env_map.insert(vm.new_sym("false"), Value::Const(Const::Bool(false))); env_map.insert(vm.new_sym("false"), Value::Const(Const::Bool(false)));
let mut map = HashMap::new(); let mut map = HashMap::new();
for primop in primops { for primop in primops {
let primop = Rc::new(primop); let primop = Rc::new(primop);

View File

@@ -1,8 +1,8 @@
use std::fmt::Debug; use std::fmt::Debug;
use std::hash::Hash; use std::hash::Hash;
use hashbrown::{DefaultHashBuilder, HashMap};
use bumpalo::Bump; use bumpalo::Bump;
use hashbrown::{DefaultHashBuilder, HashMap};
use crate::ty::internal::Value; use crate::ty::internal::Value;
@@ -70,7 +70,7 @@ impl<'bump, K: Hash + Eq + Clone, V: Clone> Env<'bump, K, V> {
map: None, map: None,
last: None, last: None,
}), }),
last: None last: None,
} }
} }
@@ -85,7 +85,7 @@ impl<'bump, K: Hash + Eq + Clone, V: Clone> Env<'bump, K, V> {
&*bump.alloc(Env { &*bump.alloc(Env {
let_: self.let_.enter_arg(ident, val, bump), let_: self.let_.enter_arg(ident, val, bump),
with: self.with, with: self.with,
last: Some(self) last: Some(self),
}) })
} }
@@ -93,7 +93,7 @@ impl<'bump, K: Hash + Eq + Clone, V: Clone> Env<'bump, K, V> {
&*bump.alloc(Env { &*bump.alloc(Env {
let_: self.let_.enter_let(map, bump), let_: self.let_.enter_let(map, bump),
with: self.with, with: self.with,
last: Some(self) last: Some(self),
}) })
} }
@@ -101,7 +101,7 @@ impl<'bump, K: Hash + Eq + Clone, V: Clone> Env<'bump, K, V> {
&*bump.alloc(Env { &*bump.alloc(Env {
let_: self.let_, let_: self.let_,
with: self.with.enter(map, bump), with: self.with.enter(map, bump),
last: Some(self) last: Some(self),
}) })
} }
@@ -138,14 +138,14 @@ impl<'bump, K: Hash + Eq + Clone, V: Clone> LetEnv<'bump, K, V> {
pub fn enter_arg(&'bump self, ident: K, val: V, bump: &'bump Bump) -> &'bump Self { pub fn enter_arg(&'bump self, ident: K, val: V, bump: &'bump Bump) -> &'bump Self {
&*bump.alloc(Self { &*bump.alloc(Self {
map: LetNode::SingleArg(ident, val), map: LetNode::SingleArg(ident, val),
last: Some(self) last: Some(self),
}) })
} }
pub fn enter_let(&'bump self, map: &'bump Map<'bump, K, V>, bump: &'bump Bump) -> &'bump Self { pub fn enter_let(&'bump self, map: &'bump Map<'bump, K, V>, bump: &'bump Bump) -> &'bump Self {
&*bump.alloc(Self { &*bump.alloc(Self {
map: LetNode::Let(map), map: LetNode::Let(map),
last: Some(self) last: Some(self),
}) })
} }
} }
@@ -161,7 +161,7 @@ impl<'bump, K: Hash + Eq + Clone, V: Clone> With<'bump, K, V> {
pub fn enter(&'bump self, map: &'bump Map<'bump, K, V>, bump: &'bump Bump) -> &'bump Self { pub fn enter(&'bump self, map: &'bump Map<'bump, K, V>, bump: &'bump Bump) -> &'bump Self {
&*bump.alloc(Self { &*bump.alloc(Self {
map: Some(map), map: Some(map),
last: Some(self) last: Some(self),
}) })
} }
} }

View File

@@ -5,9 +5,10 @@ use inkwell::module::Module;
use inkwell::types::{FloatType, FunctionType, IntType, PointerType, StructType}; use inkwell::types::{FloatType, FunctionType, IntType, PointerType, StructType};
use inkwell::values::{BasicValueEnum, FunctionValue}; use inkwell::values::{BasicValueEnum, FunctionValue};
use crate::env::VmEnv;
use crate::jit::JITValueData; use crate::jit::JITValueData;
use crate::ty::internal::{Thunk, Value}; use crate::ty::internal::{Thunk, Value};
use crate::vm::{VM, VmEnv}; use crate::vm::VM;
use super::{JITValue, ValueTag}; use super::{JITValue, ValueTag};
@@ -91,11 +92,7 @@ impl<'ctx> Helpers<'ctx> {
let call = module.add_function( let call = module.add_function(
"call", "call",
value_type.fn_type( value_type.fn_type(
&[ &[value_type.into(), value_type.into(), ptr_type.into()],
value_type.into(),
value_type.into(),
ptr_type.into(),
],
false, false,
), ),
None, None,
@@ -311,11 +308,7 @@ extern "C" fn helper_or(lhs: JITValue, rhs: JITValue) -> JITValue {
} }
} }
extern "C" fn helper_call<'jit>( extern "C" fn helper_call<'jit>(func: JITValue, arg: JITValue, vm: *const VM<'jit>) -> JITValue {
func: JITValue,
arg: JITValue,
vm: *const VM<'jit>,
) -> JITValue {
use ValueTag::*; use ValueTag::*;
match func.tag { match func.tag {
Function => { Function => {

View File

@@ -8,11 +8,12 @@ use inkwell::module::Module;
use inkwell::values::{BasicValueEnum, FunctionValue, PointerValue}; use inkwell::values::{BasicValueEnum, FunctionValue, PointerValue};
use crate::bytecode::{Func, OpCode, UnOp}; use crate::bytecode::{Func, OpCode, UnOp};
use crate::env::VmEnv;
use crate::error::*; use crate::error::*;
use crate::stack::Stack; use crate::stack::Stack;
use crate::ty::common::Const; use crate::ty::common::Const;
use crate::ty::internal::{Thunk, Value}; use crate::ty::internal::{Thunk, Value};
use crate::vm::{VM, VmEnv}; use crate::vm::VM;
mod helpers; mod helpers;
@@ -408,11 +409,7 @@ impl<'vm, 'ctx: 'vm> JITContext<'ctx> {
.builder .builder
.build_direct_call( .build_direct_call(
self.helpers.call, self.helpers.call,
&[ &[func.into(), arg.into(), self.new_ptr(vm).into()],
func.into(),
arg.into(),
self.new_ptr(vm).into(),
],
"call", "call",
)? )?
.try_as_basic_value() .try_as_basic_value()

View File

@@ -4,6 +4,7 @@
mod builtins; mod builtins;
mod bytecode; mod bytecode;
mod env;
mod stack; mod stack;
mod ty; mod ty;

View File

@@ -5,8 +5,9 @@ use hashbrown::{HashMap, HashSet};
use derive_more::Constructor; use derive_more::Constructor;
use itertools::Itertools; use itertools::Itertools;
use crate::env::VmEnv;
use crate::error::Result; use crate::error::Result;
use crate::vm::{VM, VmEnv}; use crate::vm::VM;
use super::super::public as p; use super::super::public as p;
use super::Value; use super::Value;

View File

@@ -6,11 +6,12 @@ use inkwell::execution_engine::JitFunction;
use itertools::Itertools; use itertools::Itertools;
use crate::bytecode::Func as BFunc; use crate::bytecode::Func as BFunc;
use crate::env::VmEnv;
use crate::error::Result; use crate::error::Result;
use crate::ir; use crate::ir;
use crate::jit::JITFunc; use crate::jit::JITFunc;
use crate::ty::internal::{Thunk, Value}; use crate::ty::internal::{Thunk, Value};
use crate::vm::{VM, VmEnv}; use crate::vm::VM;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Param { pub enum Param {
@@ -63,7 +64,8 @@ impl<'vm, 'jit: 'vm> Func<'jit, 'vm> {
alias, alias,
} => { } => {
let arg = arg.unwrap_attr_set(); let arg = arg.unwrap_attr_set();
let mut new = HashMap::with_capacity_in(formals.len() + alias.iter().len(), &vm.bump); let mut new =
HashMap::with_capacity_in(formals.len() + alias.iter().len(), &vm.bump);
if !ellipsis if !ellipsis
&& arg && arg
.as_inner() .as_inner()

View File

@@ -10,8 +10,9 @@ use super::common::*;
use super::public as p; use super::public as p;
use crate::bytecode::OpCodes; use crate::bytecode::OpCodes;
use crate::env::VmEnv;
use crate::error::*; use crate::error::*;
use crate::vm::{VM, VmEnv}; use crate::vm::VM;
mod attrset; mod attrset;
mod func; mod func;
@@ -241,7 +242,7 @@ impl<'jit, 'vm> Value<'jit, 'vm> {
(_, x @ Value::Catchable(_)) => { (_, x @ Value::Catchable(_)) => {
*self = x; *self = x;
return; return;
}, }
_ => todo!(), _ => todo!(),
})) }))
} }

View File

@@ -5,6 +5,7 @@ use std::cell::{Cell, OnceCell, RefCell};
use crate::builtins::env; use crate::builtins::env;
use crate::bytecode::{BinOp, Func as F, OpCode, OpCodes, Program, UnOp}; use crate::bytecode::{BinOp, Func as F, OpCode, OpCodes, Program, UnOp};
use crate::env::VmEnv;
use crate::error::*; use crate::error::*;
use crate::jit::{JITContext, JITFunc}; use crate::jit::{JITContext, JITFunc};
use crate::stack::Stack; use crate::stack::Stack;
@@ -14,9 +15,6 @@ use crate::ty::public::{self as p, Symbol};
use derive_more::Constructor; use derive_more::Constructor;
use ecow::EcoString; use ecow::EcoString;
pub use env::VmEnv;
mod env;
#[cfg(test)] #[cfg(test)]
mod test; mod test;
@@ -156,7 +154,7 @@ impl<'vm, 'jit: 'vm> VM<'jit> {
Sub => { Sub => {
rhs.neg(); rhs.neg();
lhs.add(rhs); lhs.add(rhs);
}, }
Mul => lhs.mul(rhs), Mul => lhs.mul(rhs),
Div => lhs.div(rhs)?, Div => lhs.div(rhs)?,
And => lhs.and(rhs), And => lhs.and(rhs),
@@ -187,7 +185,17 @@ impl<'vm, 'jit: 'vm> VM<'jit> {
} }
OpCode::FinalizeRec => { OpCode::FinalizeRec => {
let new = self.bump.alloc(HashMap::new_in(&self.bump)); let new = self.bump.alloc(HashMap::new_in(&self.bump));
*env = env.enter_let(stack.tos().as_ref().unwrap_attr_set().as_inner().iter().map(|(&k, v)| (k, v.clone())).collect_into(new), &self.bump); *env = env.enter_let(
stack
.tos()
.as_ref()
.unwrap_attr_set()
.as_inner()
.iter()
.map(|(&k, v)| (k, v.clone()))
.collect_into(new),
&self.bump,
);
stack.tos_mut().as_mut().unwrap_attr_set().capture(env); stack.tos_mut().as_mut().unwrap_attr_set().capture(env);
} }
OpCode::PushStaticAttr { name } => { OpCode::PushStaticAttr { name } => {
@@ -249,12 +257,30 @@ impl<'vm, 'jit: 'vm> VM<'jit> {
} }
OpCode::EnterLetEnv => { OpCode::EnterLetEnv => {
let new = self.bump.alloc(HashMap::new_in(&self.bump)); let new = self.bump.alloc(HashMap::new_in(&self.bump));
*env = env.enter_let(stack.pop().unwrap_attr_set().into_inner().iter().map(|(&k, v)| (k, v.clone())).collect_into(new), &self.bump); *env = env.enter_let(
stack
.pop()
.unwrap_attr_set()
.into_inner()
.iter()
.map(|(&k, v)| (k, v.clone()))
.collect_into(new),
&self.bump,
);
} }
OpCode::LeaveLetEnv => *env = env.leave(), OpCode::LeaveLetEnv => *env = env.leave(),
OpCode::EnterWithEnv => { OpCode::EnterWithEnv => {
let new = self.bump.alloc(HashMap::new_in(&self.bump)); let new = self.bump.alloc(HashMap::new_in(&self.bump));
*env = env.enter_with(stack.pop().unwrap_attr_set().into_inner().iter().map(|(&k, v)| (k, v.clone())).collect_into(new), &self.bump); *env = env.enter_with(
stack
.pop()
.unwrap_attr_set()
.into_inner()
.iter()
.map(|(&k, v)| (k, v.clone()))
.collect_into(new),
&self.bump,
);
} }
OpCode::LeaveWithEnv => *env = env.leave(), OpCode::LeaveWithEnv => *env = env.leave(),
OpCode::Assert => { OpCode::Assert => {