feat(jit): fix segfault

This commit is contained in:
2025-05-18 17:07:49 +08:00
parent f98d623c13
commit af5a312e1e
10 changed files with 115 additions and 111 deletions

View File

@@ -5,7 +5,7 @@ use crate::ty::internal::{AttrSet, PrimOp, Value};
use crate::ty::common::Const; use crate::ty::common::Const;
use crate::vm::{Env, VM}; use crate::vm::{Env, VM};
pub fn env<'vm>(vm: &'vm VM) -> Env<'vm> { pub fn env<'jit, 'vm>(vm: &'vm VM<'jit>) -> Env<'jit, 'vm> {
let mut env = Env::empty(); let mut env = Env::empty();
env.insert(vm.new_sym("true"), Value::Const(Const::Bool(true))); env.insert(vm.new_sym("true"), Value::Const(Const::Bool(true)));
env.insert(vm.new_sym("false"), Value::Const(Const::Bool(false))); env.insert(vm.new_sym("false"), Value::Const(Const::Bool(false)));

View File

@@ -1,7 +1,7 @@
use inkwell::AddressSpace; use inkwell::AddressSpace;
use inkwell::context::Context; use inkwell::context::Context;
use inkwell::execution_engine::ExecutionEngine; use inkwell::execution_engine::ExecutionEngine;
use inkwell::module::{Linkage, Module}; 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};
@@ -194,7 +194,9 @@ extern "C" fn helper_add(lhs: JITValue, rhs: JITValue) -> JITValue {
} }
#[unsafe(no_mangle)] #[unsafe(no_mangle)]
extern "C" fn helper_call(vm: *const VM<'_>, env: *const Env<'_>, func_ptr: *const (), arg: JITValue) -> JITValue { extern "C" fn helper_call<'jit, 'vm>(vm: *const VM<'jit>, env: *const Env<'jit, 'vm>, func_ptr: *const (), arg: JITValue) -> JITValue {
let func: JITFunc = unsafe { std::mem::transmute(func_ptr) }; let func: JITFunc = unsafe { std::mem::transmute(func_ptr) };
func(vm, env, arg) unsafe {
func(vm, env, arg)
}
} }

View File

@@ -2,7 +2,7 @@ use std::rc::Rc;
use inkwell::builder::Builder; use inkwell::builder::Builder;
use inkwell::context::Context; use inkwell::context::Context;
use inkwell::execution_engine::ExecutionEngine; use inkwell::execution_engine::{ExecutionEngine, JitFunction};
use inkwell::module::Module; use inkwell::module::Module;
use inkwell::values::{BasicValueEnum, PointerValue}; use inkwell::values::{BasicValueEnum, PointerValue};
use inkwell::OptimizationLevel; use inkwell::OptimizationLevel;
@@ -52,8 +52,8 @@ pub union JITValueData {
ptr: *const () ptr: *const ()
} }
impl<'vm> Into<Value<'vm>> for JITValue { impl<'jit: 'vm, 'vm> Into<Value<'jit, 'vm>> for JITValue {
fn into(self) -> Value<'vm> { fn into(self) -> Value<'jit, 'vm> {
use ValueTag::*; use ValueTag::*;
match self.tag { match self.tag {
Int => Value::Const(Const::Int(unsafe { self.data.int })), Int => Value::Const(Const::Int(unsafe { self.data.int })),
@@ -63,8 +63,8 @@ impl<'vm> Into<Value<'vm>> for JITValue {
} }
} }
impl From<Value<'_>> for JITValue { impl From<Value<'_, '_>> for JITValue {
fn from(value: Value<'_>) -> Self { fn from(value: Value<'_, '_>) -> Self {
match value { match value {
Value::Const(Const::Int(int)) => JITValue { tag: ValueTag::Int, data: JITValueData { int } }, Value::Const(Const::Int(int)) => JITValue { tag: ValueTag::Int, data: JITValueData { int } },
_ => todo!() _ => todo!()
@@ -72,7 +72,7 @@ impl From<Value<'_>> for JITValue {
} }
} }
pub type JITFunc<'vm> = fn(*const VM<'_>, *const Env<'vm>, JITValue) -> JITValue; pub type JITFunc<'jit, 'vm> = unsafe extern "C" fn(*const VM<'jit>, *const Env<'jit, 'vm>, JITValue) -> JITValue;
pub struct JITContext<'ctx> { pub struct JITContext<'ctx> {
context: &'ctx Context, context: &'ctx Context,
@@ -108,7 +108,7 @@ impl<'vm, 'ctx: 'vm> JITContext<'ctx> {
self.builder.build_int_to_ptr(self.helpers.int_type.const_int(ptr as _, false), self.helpers.ptr_type, "ptrconv").unwrap() self.builder.build_int_to_ptr(self.helpers.int_type.const_int(ptr as _, false), self.helpers.ptr_type, "ptrconv").unwrap()
} }
pub fn compile_function(&self, func: &Func, vm: &'vm VM<'_>) -> Result<&'vm JITFunc> { pub fn compile_function(&self, func: &Func, vm: &'vm VM<'_>) -> Result<JitFunction<'ctx, JITFunc<'ctx, 'vm>>> {
let mut stack = Stack::<_, STACK_SIZE>::new(); let mut stack = Stack::<_, STACK_SIZE>::new();
let mut iter = func.opcodes.iter().copied(); let mut iter = func.opcodes.iter().copied();
let func_ = self.module.add_function("nixjit_function", self.helpers.func_type, None); let func_ = self.module.add_function("nixjit_function", self.helpers.func_type, None);
@@ -125,8 +125,8 @@ impl<'vm, 'ctx: 'vm> JITContext<'ctx> {
func_.print_to_stderr(); func_.print_to_stderr();
unsafe { unsafe {
let name = func_.get_name().to_str().unwrap(); let name = func_.get_name().to_str().unwrap();
let addr = self.execution_engine.get_function_address(name).unwrap(); let addr = self.execution_engine.get_function(name).unwrap();
Ok(std::mem::transmute(addr)) Ok(addr)
} }
} else { } else {
todo!() todo!()

View File

@@ -11,11 +11,11 @@ use super::Value;
#[repr(C)] #[repr(C)]
#[derive(Debug, Constructor, Clone, PartialEq)] #[derive(Debug, Constructor, Clone, PartialEq)]
pub struct AttrSet<'vm> { pub struct AttrSet<'jit: 'vm, 'vm> {
data: HashMap<usize, Value<'vm>>, data: HashMap<usize, Value<'jit, 'vm>>,
} }
impl<'vm> AttrSet<'vm> { impl<'jit: 'vm, 'vm> AttrSet<'jit, 'vm> {
pub fn empty() -> Self { pub fn empty() -> Self {
AttrSet { AttrSet {
data: HashMap::new(), data: HashMap::new(),
@@ -28,18 +28,18 @@ impl<'vm> AttrSet<'vm> {
} }
} }
pub fn push_attr_force(&mut self, sym: usize, val: Value<'vm>) { pub fn push_attr_force(&mut self, sym: usize, val: Value<'jit, 'vm>) {
self.data.insert(sym, val); self.data.insert(sym, val);
} }
pub fn push_attr(&mut self, sym: usize, val: Value<'vm>) { pub fn push_attr(&mut self, sym: usize, val: Value<'jit, 'vm>) {
if self.data.get(&sym).is_some() { if self.data.get(&sym).is_some() {
todo!() todo!()
} }
self.data.insert(sym, val); self.data.insert(sym, val);
} }
pub fn select(&self, sym: usize) -> Option<Value<'vm>> { pub fn select(&self, sym: usize) -> Option<Value<'jit, 'vm>> {
self.data.get(&sym).cloned() self.data.get(&sym).cloned()
} }
@@ -47,7 +47,7 @@ impl<'vm> AttrSet<'vm> {
self.data.get(&sym).is_some() self.data.get(&sym).is_some()
} }
pub fn capture(&mut self, env: &Env<'vm>) { pub fn capture(&mut self, env: &Env<'jit, 'vm>) {
self.data.iter().for_each(|(_, v)| match v.clone() { self.data.iter().for_each(|(_, v)| match v.clone() {
Value::Thunk(ref thunk) => { Value::Thunk(ref thunk) => {
thunk.capture(env.clone()); thunk.capture(env.clone());
@@ -56,21 +56,21 @@ impl<'vm> AttrSet<'vm> {
}) })
} }
pub fn update(&mut self, other: &AttrSet<'vm>) { pub fn update(&mut self, other: &AttrSet<'jit, 'vm>) {
for (k, v) in other.data.iter() { for (k, v) in other.data.iter() {
self.push_attr_force(k.clone(), v.clone()) self.push_attr_force(k.clone(), v.clone())
} }
} }
pub fn as_inner(&self) -> &HashMap<usize, Value<'vm>> { pub fn as_inner(&self) -> &HashMap<usize, Value<'jit, 'vm>> {
&self.data &self.data
} }
pub fn from_inner(data: HashMap<usize, Value<'vm>>) -> Self { pub fn from_inner(data: HashMap<usize, Value<'jit, 'vm>>) -> Self {
Self { data } Self { data }
} }
pub fn force_deep(&mut self, vm: &'vm VM<'_>) -> Result<()> { pub fn force_deep(&mut self, vm: &'vm VM<'jit>) -> Result<()> {
let mut map: Vec<_> = self let mut map: Vec<_> = self
.data .data
.iter() .iter()
@@ -83,7 +83,7 @@ impl<'vm> AttrSet<'vm> {
Ok(()) Ok(())
} }
pub fn eq_impl(&self, other: &AttrSet<'vm>, vm: &'vm VM<'_>) -> bool { pub fn eq_impl(&self, other: &AttrSet<'jit, 'vm>, vm: &'vm VM<'jit>) -> bool {
self.data.iter().len() == other.data.iter().len() self.data.iter().len() == other.data.iter().len()
&& std::iter::zip( && std::iter::zip(
self.data.iter().sorted_by_key(|(k, _)| **k), self.data.iter().sorted_by_key(|(k, _)| **k),
@@ -92,7 +92,7 @@ impl<'vm> AttrSet<'vm> {
.all(|((_, v1), (_, v2))| v1.eq_impl(v2, vm)) .all(|((_, v1), (_, v2))| v1.eq_impl(v2, vm))
} }
pub fn to_public(&self, vm: &'vm VM, seen: &mut HashSet<Value<'vm>>) -> p::Value { pub fn to_public(&self, vm: &'vm VM, seen: &mut HashSet<Value<'jit, 'vm>>) -> p::Value {
p::Value::AttrSet(p::AttrSet::new( p::Value::AttrSet(p::AttrSet::new(
self.data self.data
.iter() .iter()

View File

@@ -1,5 +1,6 @@
use std::cell::{Cell, OnceCell}; use std::cell::{Cell, OnceCell};
use inkwell::execution_engine::JitFunction;
use itertools::Itertools; use itertools::Itertools;
use derive_more::Constructor; use derive_more::Constructor;
@@ -41,21 +42,21 @@ impl From<ir::Param> for Param {
} }
#[derive(Debug, Clone, Constructor)] #[derive(Debug, Clone, Constructor)]
pub struct Func<'vm> { pub struct Func<'jit: 'vm, 'vm> {
pub func: &'vm BFunc, pub func: &'vm BFunc,
pub env: Env<'vm>, pub env: Env<'jit, 'vm>,
pub compiled: OnceCell<&'vm JITFunc<'vm>>, pub compiled: OnceCell<JitFunction<'jit, JITFunc<'jit, 'vm>>>,
pub count: Cell<usize> pub count: Cell<usize>
} }
impl<'vm, 'jit: 'vm> Func<'vm> { impl<'vm, 'jit: 'vm> Func<'jit, 'vm> {
pub fn call(&self, vm: &'vm VM<'jit>, arg: Value<'vm>) -> Result<Value<'vm>> { pub fn call(&self, vm: &'vm VM<'jit>, arg: Value<'jit, 'vm>) -> Result<Value<'jit, 'vm>> {
use Param::*; use Param::*;
let count = self.count.get(); let count = self.count.get();
if count >= 1 { if count >= 1 {
let compiled = self.compiled.get_or_init(|| vm.compile_func(self.func)); let compiled = self.compiled.get_or_init(|| vm.compile_func(self.func));
let ret = compiled(vm as _, &self.env as _, arg.into()); let ret = unsafe { compiled.call(vm as _, &self.env as _, arg.into()) };
return Ok(ret.into()) return Ok(ret.into())
} }
self.count.replace(count + 1); self.count.replace(count + 1);
@@ -101,7 +102,7 @@ impl<'vm, 'jit: 'vm> Func<'vm> {
} }
} }
impl PartialEq for Func<'_> { impl PartialEq for Func<'_, '_> {
fn eq(&self, _: &Self) -> bool { fn eq(&self, _: &Self) -> bool {
false false
} }

View File

@@ -10,28 +10,28 @@ use crate::vm::VM;
use super::Value; use super::Value;
#[derive(Debug, Constructor, Clone, PartialEq)] #[derive(Debug, Constructor, Clone, PartialEq)]
pub struct List<'vm> { pub struct List<'jit: 'vm, 'vm> {
data: Vector<Value<'vm>>, data: Vector<Value<'jit, 'vm>>,
} }
impl<'vm> List<'vm> { impl<'jit: 'vm, 'vm> List<'jit, 'vm> {
pub fn empty() -> Self { pub fn empty() -> Self {
List { List {
data: Vector::new(), data: Vector::new(),
} }
} }
pub fn push(&mut self, elem: Value<'vm>) { pub fn push(&mut self, elem: Value<'jit, 'vm>) {
self.data.push_back_mut(elem); self.data.push_back_mut(elem);
} }
pub fn concat(&mut self, other: &List<'vm>) { pub fn concat(&mut self, other: &List<'jit, 'vm>) {
for elem in other.data.iter() { for elem in other.data.iter() {
self.data.push_back_mut(elem.clone()); self.data.push_back_mut(elem.clone());
} }
} }
pub fn force_deep(&mut self, vm: &'vm VM<'_>) -> Result<()> { pub fn force_deep(&mut self, vm: &'vm VM<'jit>) -> Result<()> {
let mut vec: Vec<_> = self.data.iter().cloned().collect(); let mut vec: Vec<_> = self.data.iter().cloned().collect();
for v in vec.iter_mut() { for v in vec.iter_mut() {
v.force_deep(vm)?; v.force_deep(vm)?;
@@ -40,7 +40,7 @@ impl<'vm> List<'vm> {
Ok(()) Ok(())
} }
pub fn to_public(&self, vm: &'vm VM, seen: &mut HashSet<Value<'vm>>) -> p::Value { pub fn to_public(&self, vm: &'vm VM, seen: &mut HashSet<Value<'jit, 'vm>>) -> p::Value {
p::Value::List(p::List::new( p::Value::List(p::List::new(
self.data self.data
.iter() .iter()

View File

@@ -25,20 +25,20 @@ pub use list::List;
pub use primop::*; pub use primop::*;
#[derive(Debug, IsVariant, Unwrap, Clone, PartialEq)] #[derive(Debug, IsVariant, Unwrap, Clone, PartialEq)]
pub enum Value<'vm> { pub enum Value<'jit: 'vm, 'vm> {
Const(Const), Const(Const),
Thunk(Rc<Thunk<'vm>>), Thunk(Rc<Thunk<'jit, 'vm>>),
ThunkRef(&'vm Thunk<'vm>), ThunkRef(&'vm Thunk<'jit, 'vm>),
AttrSet(Rc<AttrSet<'vm>>), AttrSet(Rc<AttrSet<'jit, 'vm>>),
List(Rc<List<'vm>>), List(Rc<List<'jit, 'vm>>),
Catchable(Catchable), Catchable(Catchable),
PrimOp(Rc<PrimOp<'vm>>), PrimOp(Rc<PrimOp<'jit, 'vm>>),
PartialPrimOp(Rc<PartialPrimOp<'vm>>), PartialPrimOp(Rc<PartialPrimOp<'jit, 'vm>>),
Func(Rc<Func<'vm>>), Func(Rc<Func<'jit, 'vm>>),
Builtins, Builtins,
} }
impl Hash for Value<'_> { impl Hash for Value<'_, '_> {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) { fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
use Value::*; use Value::*;
std::mem::discriminant(self).hash(state); std::mem::discriminant(self).hash(state);
@@ -57,8 +57,8 @@ impl Hash for Value<'_> {
} }
} }
impl<'vm> Value<'vm> { impl<'jit: 'vm, 'vm> Value<'jit, 'vm> {
fn eq_impl(&self, other: &Self, vm: &'vm VM<'_>) -> bool { fn eq_impl(&self, other: &Self, vm: &'vm VM<'jit>) -> bool {
use Value::*; use Value::*;
match (self, other) { match (self, other) {
(Const(a), Const(b)) => a.eq(b), (Const(a), Const(b)) => a.eq(b),
@@ -71,34 +71,34 @@ impl<'vm> Value<'vm> {
} }
} }
impl Eq for Value<'_> {} impl Eq for Value<'_, '_> {}
#[derive(Debug, IsVariant, Unwrap, Clone, PartialEq)] #[derive(Debug, IsVariant, Unwrap, Clone, PartialEq)]
pub enum ValueAsRef<'v, 'vm: 'v> { pub enum ValueAsRef<'v, 'vm: 'v, 'jit: 'vm> {
Const(&'v Const), Const(&'v Const),
Thunk(&'v Thunk<'vm>), Thunk(&'v Thunk<'jit, 'vm>),
AttrSet(&'v AttrSet<'vm>), AttrSet(&'v AttrSet<'jit, 'vm>),
List(&'v List<'vm>), List(&'v List<'jit, 'vm>),
Catchable(&'v Catchable), Catchable(&'v Catchable),
PrimOp(&'v PrimOp<'vm>), PrimOp(&'v PrimOp<'jit, 'vm>),
PartialPrimOp(&'v PartialPrimOp<'vm>), PartialPrimOp(&'v PartialPrimOp<'jit, 'vm>),
Func(&'v Func<'vm>), Func(&'v Func<'jit, 'vm>),
} }
#[derive(Debug, IsVariant, Unwrap, PartialEq)] #[derive(Debug, IsVariant, Unwrap, PartialEq)]
pub enum ValueAsMut<'v, 'vm: 'v> { pub enum ValueAsMut<'v, 'vm: 'v, 'jit: 'vm> {
Const(&'v mut Const), Const(&'v mut Const),
Thunk(&'v Thunk<'vm>), Thunk(&'v Thunk<'jit, 'vm>),
AttrSet(&'v mut AttrSet<'vm>), AttrSet(&'v mut AttrSet<'jit, 'vm>),
List(&'v mut List<'vm>), List(&'v mut List<'jit, 'vm>),
Catchable(&'v mut Catchable), Catchable(&'v mut Catchable),
PrimOp(&'v mut PrimOp<'vm>), PrimOp(&'v mut PrimOp<'jit, 'vm>),
PartialPrimOp(&'v mut PartialPrimOp<'vm>), PartialPrimOp(&'v mut PartialPrimOp<'jit, 'vm>),
Func(&'v Func<'vm>), Func(&'v Func<'jit, 'vm>),
} }
impl<'v, 'vm: 'v> Value<'vm> { impl<'v, 'vm: 'v, 'jit: 'vm> Value<'jit, 'vm> {
pub fn as_ref(&'v self) -> ValueAsRef<'v, 'vm> { pub fn as_ref(&'v self) -> ValueAsRef<'v, 'vm, 'jit> {
use Value::*; use Value::*;
use ValueAsRef as R; use ValueAsRef as R;
match self { match self {
@@ -115,7 +115,7 @@ impl<'v, 'vm: 'v> Value<'vm> {
} }
} }
pub fn as_mut(&'v mut self) -> ValueAsMut<'v, 'vm> { pub fn as_mut(&'v mut self) -> ValueAsMut<'v, 'vm, 'jit> {
use Value::*; use Value::*;
use ValueAsMut as M; use ValueAsMut as M;
match self { match self {
@@ -134,7 +134,7 @@ impl<'v, 'vm: 'v> Value<'vm> {
} }
use Value::Const as VmConst; use Value::Const as VmConst;
impl<'vm> Value<'vm> { impl<'jit, 'vm> Value<'jit, 'vm> {
pub fn ok(self) -> Result<Self> { pub fn ok(self) -> Result<Self> {
Ok(self) Ok(self)
} }
@@ -163,7 +163,7 @@ impl<'vm> Value<'vm> {
} }
} }
pub fn call(&self, vm: &'vm VM<'_>, args: Vec<Self>) -> Result<Self> { pub fn call(&self, vm: &'vm VM<'jit>, args: Vec<Self>) -> Result<Self> {
use Value::*; use Value::*;
match self { match self {
PrimOp(func) => func.call(vm, args), PrimOp(func) => func.call(vm, args),
@@ -217,7 +217,7 @@ impl<'vm> Value<'vm> {
} }
} }
pub fn eq(self, other: Self, vm: &'vm VM<'_>) -> Self { pub fn eq(self, other: Self, vm: &'vm VM<'jit>) -> Self {
use Const::Bool; use Const::Bool;
match (self, other) { match (self, other) {
(x @ Value::Catchable(_), _) | (_, x @ Value::Catchable(_)) => x, (x @ Value::Catchable(_), _) | (_, x @ Value::Catchable(_)) => x,
@@ -349,7 +349,7 @@ impl<'vm> Value<'vm> {
} }
} }
pub fn select(&mut self, sym: usize, vm: &'vm VM<'_>) -> Result<&mut Self> { pub fn select(&mut self, sym: usize, vm: &'vm VM<'jit>) -> Result<&mut Self> {
let val = match self { let val = match self {
Value::AttrSet(attrs) => attrs Value::AttrSet(attrs) => attrs
.select(sym) .select(sym)
@@ -405,7 +405,7 @@ impl<'vm> Value<'vm> {
self self
} }
pub fn force(&mut self, vm: &'vm VM<'_>) -> Result<&mut Self> { pub fn force(&mut self, vm: &'vm VM<'jit>) -> Result<&mut Self> {
if let Value::Thunk(thunk) = self { if let Value::Thunk(thunk) = self {
let value = thunk.force(vm)?; let value = thunk.force(vm)?;
*self = value *self = value
@@ -416,7 +416,7 @@ impl<'vm> Value<'vm> {
Ok(self) Ok(self)
} }
pub fn force_deep(&mut self, vm: &'vm VM<'_>) -> Result<&mut Self> { pub fn force_deep(&mut self, vm: &'vm VM<'jit>) -> Result<&mut Self> {
match self { match self {
Value::Thunk(thunk) => { Value::Thunk(thunk) => {
let mut value = thunk.force(vm)?; let mut value = thunk.force(vm)?;
@@ -435,7 +435,7 @@ impl<'vm> Value<'vm> {
Ok(self) Ok(self)
} }
pub fn to_public(&self, vm: &'vm VM, seen: &mut HashSet<Value<'vm>>) -> p::Value { pub fn to_public(&self, vm: &'vm VM, seen: &mut HashSet<Value<'jit, 'vm>>) -> p::Value {
use self::Value::*; use self::Value::*;
use p::Value; use p::Value;
if seen.contains(self) { if seen.contains(self) {
@@ -458,31 +458,31 @@ impl<'vm> Value<'vm> {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Thunk<'vm> { pub struct Thunk<'jit, 'vm> {
pub thunk: RefCell<_Thunk<'vm>>, pub thunk: RefCell<_Thunk<'jit, 'vm>>,
} }
#[derive(Debug, IsVariant, Unwrap, Clone)] #[derive(Debug, IsVariant, Unwrap, Clone)]
pub enum _Thunk<'vm> { pub enum _Thunk<'jit, 'vm> {
Code(&'vm OpCodes, OnceCell<Env<'vm>>), Code(&'vm OpCodes, OnceCell<Env<'jit, 'vm>>),
SuspendedFrom(*const Thunk<'vm>), SuspendedFrom(*const Thunk<'jit, 'vm>),
Value(Value<'vm>), Value(Value<'jit, 'vm>),
} }
impl<'vm> Thunk<'vm> { impl<'jit, 'vm> Thunk<'jit, 'vm> {
pub fn new(opcodes: &'vm OpCodes) -> Self { pub fn new(opcodes: &'vm OpCodes) -> Self {
Thunk { Thunk {
thunk: RefCell::new(_Thunk::Code(opcodes, OnceCell::new())), thunk: RefCell::new(_Thunk::Code(opcodes, OnceCell::new())),
} }
} }
pub fn capture(&self, env: Env<'vm>) { pub fn capture(&self, env: Env<'jit, 'vm>) {
if let _Thunk::Code(_, envcell) = &*self.thunk.borrow() { if let _Thunk::Code(_, envcell) = &*self.thunk.borrow() {
envcell.get_or_init(|| env); envcell.get_or_init(|| env);
} }
} }
pub fn force(&self, vm: &'vm VM<'_>) -> Result<Value<'vm>> { pub fn force(&self, vm: &'vm VM<'jit>) -> Result<Value<'jit, 'vm>> {
match &*self.thunk.borrow() { match &*self.thunk.borrow() {
_Thunk::Value(value) => return Ok(value.clone()), _Thunk::Value(value) => return Ok(value.clone()),
_Thunk::SuspendedFrom(from) => { _Thunk::SuspendedFrom(from) => {
@@ -506,7 +506,7 @@ impl<'vm> Thunk<'vm> {
Ok(value) Ok(value)
} }
pub fn value(&'vm self) -> Option<Value<'vm>> { pub fn value(&'vm self) -> Option<Value<'jit, 'vm>> {
match &*self.thunk.borrow() { match &*self.thunk.borrow() {
_Thunk::Value(value) => Some(value.clone()), _Thunk::Value(value) => Some(value.clone()),
_ => None, _ => None,
@@ -514,7 +514,7 @@ impl<'vm> Thunk<'vm> {
} }
} }
impl PartialEq for Thunk<'_> { impl PartialEq for Thunk<'_, '_> {
fn eq(&self, _: &Self) -> bool { fn eq(&self, _: &Self) -> bool {
false false
} }

View File

@@ -8,20 +8,20 @@ use crate::vm::VM;
use super::Value; use super::Value;
#[derive(Debug, Clone, Constructor)] #[derive(Debug, Clone, Constructor)]
pub struct PrimOp<'vm> { pub struct PrimOp<'jit: 'vm, 'vm> {
pub name: &'static str, pub name: &'static str,
arity: usize, arity: usize,
func: fn(&'vm VM<'_>, Vec<Value<'vm>>) -> Result<Value<'vm>>, func: fn(&'vm VM<'jit>, Vec<Value<'jit, 'vm>>) -> Result<Value<'jit, 'vm>>,
} }
impl PartialEq for PrimOp<'_> { impl PartialEq for PrimOp<'_, '_> {
fn eq(&self, _: &Self) -> bool { fn eq(&self, _: &Self) -> bool {
false false
} }
} }
impl<'vm> PrimOp<'vm> { impl<'jit, 'vm> PrimOp<'jit, 'vm> {
pub fn call(&self, vm: &'vm VM<'_>, args: Vec<Value<'vm>>) -> Result<Value<'vm>> { pub fn call(&self, vm: &'vm VM<'jit>, args: Vec<Value<'jit, 'vm>>) -> Result<Value<'jit, 'vm>> {
if (args.len()) < self.arity { if (args.len()) < self.arity {
Value::PartialPrimOp( Value::PartialPrimOp(
PartialPrimOp { PartialPrimOp {
@@ -42,21 +42,21 @@ impl<'vm> PrimOp<'vm> {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct PartialPrimOp<'vm> { pub struct PartialPrimOp<'jit: 'vm, 'vm> {
pub name: &'static str, pub name: &'static str,
arity: usize, arity: usize,
args: Vec<Value<'vm>>, args: Vec<Value<'jit, 'vm>>,
func: fn(&'vm VM<'_>, Vec<Value<'vm>>) -> Result<Value<'vm>>, func: fn(&'vm VM<'jit>, Vec<Value<'jit, 'vm>>) -> Result<Value<'jit, 'vm>>,
} }
impl PartialEq for PartialPrimOp<'_> { impl PartialEq for PartialPrimOp<'_, '_> {
fn eq(&self, _: &Self) -> bool { fn eq(&self, _: &Self) -> bool {
false false
} }
} }
impl<'vm> PartialPrimOp<'vm> { impl<'jit: 'vm, 'vm> PartialPrimOp<'jit, 'vm> {
pub fn call(self: &Rc<Self>, vm: &'vm VM<'_>, args: Vec<Value<'vm>>) -> Result<Value<'vm>> { pub fn call(self: &Rc<Self>, vm: &'vm VM<'jit>, args: Vec<Value<'jit, 'vm>>) -> Result<Value<'jit, 'vm>> {
let len = args.len(); let len = args.len();
let mut self_clone = self.clone(); let mut self_clone = self.clone();
let self_mut = Rc::make_mut(&mut self_clone); let self_mut = Rc::make_mut(&mut self_clone);

View File

@@ -4,28 +4,28 @@ use std::rc::Rc;
use crate::ty::internal::{AttrSet, Value}; use crate::ty::internal::{AttrSet, Value};
#[derive(Debug, Default, Clone)] #[derive(Debug, Default, Clone)]
pub struct Env<'vm> { pub struct Env<'jit, 'vm> {
last: Option<Rc<Env<'vm>>>, last: Option<Rc<Env<'jit, 'vm>>>,
map: Rc<HashMap<usize, Value<'vm>>>, map: Rc<HashMap<usize, Value<'jit, 'vm>>>,
} }
impl<'vm> Env<'vm> { impl<'jit, 'vm> Env<'jit, 'vm> {
pub fn empty() -> Self { pub fn empty() -> Self {
Env::default() Env::default()
} }
pub fn lookup(&self, symbol: usize) -> Option<Value<'vm>> { pub fn lookup(&self, symbol: usize) -> Option<Value<'jit, 'vm>> {
if let Some(val) = self.map.get(&symbol).cloned() { if let Some(val) = self.map.get(&symbol).cloned() {
return Some(val); return Some(val);
} }
self.last.as_ref().map(|env| env.lookup(symbol)).flatten() self.last.as_ref().map(|env| env.lookup(symbol)).flatten()
} }
pub fn insert(&mut self, symbol: usize, value: Value<'vm>) { pub fn insert(&mut self, symbol: usize, value: Value<'jit, 'vm>) {
Rc::make_mut(&mut self.map).insert(symbol, value); Rc::make_mut(&mut self.map).insert(symbol, value);
} }
pub fn enter(self, new: impl Iterator<Item = (usize, Value<'vm>)>) -> Self { pub fn enter(self, new: impl Iterator<Item = (usize, Value<'jit, 'vm>)>) -> Self {
let map = Rc::new(new.collect()); let map = Rc::new(new.collect());
let last = Some( let last = Some(
Env { Env {
@@ -37,7 +37,7 @@ impl<'vm> Env<'vm> {
Env { last, map } Env { last, map }
} }
pub fn enter_with(self, new: Rc<AttrSet<'vm>>) -> Self { pub fn enter_with(self, new: Rc<AttrSet<'jit, 'vm>>) -> Self {
let map = Rc::new( let map = Rc::new(
new.as_inner() new.as_inner()
.iter() .iter()

View File

@@ -1,4 +1,5 @@
use hashbrown::{HashMap, HashSet}; use hashbrown::{HashMap, HashSet};
use inkwell::execution_engine::JitFunction;
use std::cell::{Cell, OnceCell, RefCell}; use std::cell::{Cell, OnceCell, RefCell};
use crate::builtins::env; use crate::builtins::env;
@@ -81,8 +82,8 @@ impl<'vm, 'jit: 'vm> VM<'jit> {
pub fn eval( pub fn eval(
&'vm self, &'vm self,
opcodes: impl Iterator<Item = OpCode>, opcodes: impl Iterator<Item = OpCode>,
mut env: Env<'vm>, mut env: Env<'jit, 'vm>,
) -> Result<Value<'vm>> { ) -> Result<Value<'jit, 'vm>> {
let mut stack = Stack::<_, STACK_SIZE>::new(); let mut stack = Stack::<_, STACK_SIZE>::new();
let mut iter = opcodes.into_iter(); let mut iter = opcodes.into_iter();
while let Some(opcode) = iter.next() { while let Some(opcode) = iter.next() {
@@ -101,8 +102,8 @@ impl<'vm, 'jit: 'vm> VM<'jit> {
fn single_op<'s, const CAP: usize>( fn single_op<'s, const CAP: usize>(
&'vm self, &'vm self,
opcode: OpCode, opcode: OpCode,
stack: &'s mut Stack<Value<'vm>, CAP>, stack: &'s mut Stack<Value<'jit, 'vm>, CAP>,
env: &mut Env<'vm>, env: &mut Env<'jit, 'vm>,
) -> Result<usize> { ) -> Result<usize> {
match opcode { match opcode {
OpCode::Illegal => panic!("illegal opcode"), OpCode::Illegal => panic!("illegal opcode"),
@@ -264,7 +265,7 @@ impl<'vm, 'jit: 'vm> VM<'jit> {
Ok(0) Ok(0)
} }
pub fn compile_func(&'vm self, func: &'vm F) -> &'vm JITFunc<'vm> { pub fn compile_func(&'vm self, func: &'vm F) -> JitFunction<'jit, JITFunc<'jit, 'vm>> {
self.jit.compile_function(func, self).unwrap() self.jit.compile_function(func, self).unwrap()
} }
} }