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

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