feat(env): move env out of vm,
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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 => {
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
mod builtins;
|
mod builtins;
|
||||||
mod bytecode;
|
mod bytecode;
|
||||||
|
mod env;
|
||||||
mod stack;
|
mod stack;
|
||||||
mod ty;
|
mod ty;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -231,7 +232,7 @@ impl<'jit, 'vm> Value<'jit, 'vm> {
|
|||||||
|
|
||||||
pub fn lt(&mut self, other: Self) {
|
pub fn lt(&mut self, other: Self) {
|
||||||
use Const::*;
|
use Const::*;
|
||||||
*self = VmConst(Bool(match (&*self, other) {
|
*self = VmConst(Bool(match (&*self, other) {
|
||||||
(VmConst(Int(a)), VmConst(Int(b))) => *a < b,
|
(VmConst(Int(a)), VmConst(Int(b))) => *a < b,
|
||||||
(VmConst(Int(a)), VmConst(Float(b))) => (*a as f64) < b,
|
(VmConst(Int(a)), VmConst(Float(b))) => (*a as f64) < b,
|
||||||
(VmConst(Float(a)), VmConst(Int(b))) => *a < b as f64,
|
(VmConst(Float(a)), VmConst(Int(b))) => *a < b as f64,
|
||||||
@@ -241,7 +242,7 @@ impl<'jit, 'vm> Value<'jit, 'vm> {
|
|||||||
(_, x @ Value::Catchable(_)) => {
|
(_, x @ Value::Catchable(_)) => {
|
||||||
*self = x;
|
*self = x;
|
||||||
return;
|
return;
|
||||||
},
|
}
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,6 @@ impl<'jit: 'vm, 'vm> PartialPrimOp<'jit, 'vm> {
|
|||||||
} else {
|
} else {
|
||||||
let args = std::mem::take(&mut self_mut.args);
|
let args = std::mem::take(&mut self_mut.args);
|
||||||
(self.func)(vm, args)
|
(self.func)(vm, args)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 => {
|
||||||
|
|||||||
Reference in New Issue
Block a user