feat(jit): fix segfault
This commit is contained in:
@@ -5,7 +5,7 @@ use crate::ty::internal::{AttrSet, PrimOp, Value};
|
||||
use crate::ty::common::Const;
|
||||
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();
|
||||
env.insert(vm.new_sym("true"), Value::Const(Const::Bool(true)));
|
||||
env.insert(vm.new_sym("false"), Value::Const(Const::Bool(false)));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use inkwell::AddressSpace;
|
||||
use inkwell::context::Context;
|
||||
use inkwell::execution_engine::ExecutionEngine;
|
||||
use inkwell::module::{Linkage, Module};
|
||||
use inkwell::module::Module;
|
||||
use inkwell::types::{FloatType, FunctionType, IntType, PointerType, StructType};
|
||||
use inkwell::values::{BasicValueEnum, FunctionValue};
|
||||
|
||||
@@ -194,7 +194,9 @@ extern "C" fn helper_add(lhs: JITValue, rhs: JITValue) -> JITValue {
|
||||
}
|
||||
|
||||
#[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) };
|
||||
unsafe {
|
||||
func(vm, env, arg)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::rc::Rc;
|
||||
|
||||
use inkwell::builder::Builder;
|
||||
use inkwell::context::Context;
|
||||
use inkwell::execution_engine::ExecutionEngine;
|
||||
use inkwell::execution_engine::{ExecutionEngine, JitFunction};
|
||||
use inkwell::module::Module;
|
||||
use inkwell::values::{BasicValueEnum, PointerValue};
|
||||
use inkwell::OptimizationLevel;
|
||||
@@ -52,8 +52,8 @@ pub union JITValueData {
|
||||
ptr: *const ()
|
||||
}
|
||||
|
||||
impl<'vm> Into<Value<'vm>> for JITValue {
|
||||
fn into(self) -> Value<'vm> {
|
||||
impl<'jit: 'vm, 'vm> Into<Value<'jit, 'vm>> for JITValue {
|
||||
fn into(self) -> Value<'jit, 'vm> {
|
||||
use ValueTag::*;
|
||||
match self.tag {
|
||||
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 {
|
||||
fn from(value: Value<'_>) -> Self {
|
||||
impl From<Value<'_, '_>> for JITValue {
|
||||
fn from(value: Value<'_, '_>) -> Self {
|
||||
match value {
|
||||
Value::Const(Const::Int(int)) => JITValue { tag: ValueTag::Int, data: JITValueData { int } },
|
||||
_ => 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> {
|
||||
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()
|
||||
}
|
||||
|
||||
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 iter = func.opcodes.iter().copied();
|
||||
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();
|
||||
unsafe {
|
||||
let name = func_.get_name().to_str().unwrap();
|
||||
let addr = self.execution_engine.get_function_address(name).unwrap();
|
||||
Ok(std::mem::transmute(addr))
|
||||
let addr = self.execution_engine.get_function(name).unwrap();
|
||||
Ok(addr)
|
||||
}
|
||||
} else {
|
||||
todo!()
|
||||
|
||||
@@ -11,11 +11,11 @@ use super::Value;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Constructor, Clone, PartialEq)]
|
||||
pub struct AttrSet<'vm> {
|
||||
data: HashMap<usize, Value<'vm>>,
|
||||
pub struct AttrSet<'jit: 'vm, 'vm> {
|
||||
data: HashMap<usize, Value<'jit, 'vm>>,
|
||||
}
|
||||
|
||||
impl<'vm> AttrSet<'vm> {
|
||||
impl<'jit: 'vm, 'vm> AttrSet<'jit, 'vm> {
|
||||
pub fn empty() -> Self {
|
||||
AttrSet {
|
||||
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);
|
||||
}
|
||||
|
||||
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() {
|
||||
todo!()
|
||||
}
|
||||
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()
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ impl<'vm> AttrSet<'vm> {
|
||||
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() {
|
||||
Value::Thunk(ref thunk) => {
|
||||
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() {
|
||||
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
|
||||
}
|
||||
|
||||
pub fn from_inner(data: HashMap<usize, Value<'vm>>) -> Self {
|
||||
pub fn from_inner(data: HashMap<usize, Value<'jit, 'vm>>) -> Self {
|
||||
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
|
||||
.data
|
||||
.iter()
|
||||
@@ -83,7 +83,7 @@ impl<'vm> AttrSet<'vm> {
|
||||
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()
|
||||
&& std::iter::zip(
|
||||
self.data.iter().sorted_by_key(|(k, _)| **k),
|
||||
@@ -92,7 +92,7 @@ impl<'vm> AttrSet<'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(
|
||||
self.data
|
||||
.iter()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use std::cell::{Cell, OnceCell};
|
||||
|
||||
use inkwell::execution_engine::JitFunction;
|
||||
use itertools::Itertools;
|
||||
use derive_more::Constructor;
|
||||
|
||||
@@ -41,21 +42,21 @@ impl From<ir::Param> for Param {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Constructor)]
|
||||
pub struct Func<'vm> {
|
||||
pub struct Func<'jit: 'vm, 'vm> {
|
||||
pub func: &'vm BFunc,
|
||||
pub env: Env<'vm>,
|
||||
pub compiled: OnceCell<&'vm JITFunc<'vm>>,
|
||||
pub env: Env<'jit, 'vm>,
|
||||
pub compiled: OnceCell<JitFunction<'jit, JITFunc<'jit, 'vm>>>,
|
||||
pub count: Cell<usize>
|
||||
}
|
||||
|
||||
impl<'vm, 'jit: 'vm> Func<'vm> {
|
||||
pub fn call(&self, vm: &'vm VM<'jit>, arg: Value<'vm>) -> Result<Value<'vm>> {
|
||||
impl<'vm, 'jit: 'vm> Func<'jit, 'vm> {
|
||||
pub fn call(&self, vm: &'vm VM<'jit>, arg: Value<'jit, 'vm>) -> Result<Value<'jit, 'vm>> {
|
||||
use Param::*;
|
||||
|
||||
let count = self.count.get();
|
||||
if count >= 1 {
|
||||
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())
|
||||
}
|
||||
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 {
|
||||
false
|
||||
}
|
||||
|
||||
@@ -10,28 +10,28 @@ use crate::vm::VM;
|
||||
use super::Value;
|
||||
|
||||
#[derive(Debug, Constructor, Clone, PartialEq)]
|
||||
pub struct List<'vm> {
|
||||
data: Vector<Value<'vm>>,
|
||||
pub struct List<'jit: 'vm, 'vm> {
|
||||
data: Vector<Value<'jit, 'vm>>,
|
||||
}
|
||||
|
||||
impl<'vm> List<'vm> {
|
||||
impl<'jit: 'vm, 'vm> List<'jit, 'vm> {
|
||||
pub fn empty() -> Self {
|
||||
List {
|
||||
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);
|
||||
}
|
||||
|
||||
pub fn concat(&mut self, other: &List<'vm>) {
|
||||
pub fn concat(&mut self, other: &List<'jit, 'vm>) {
|
||||
for elem in other.data.iter() {
|
||||
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();
|
||||
for v in vec.iter_mut() {
|
||||
v.force_deep(vm)?;
|
||||
@@ -40,7 +40,7 @@ impl<'vm> List<'vm> {
|
||||
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(
|
||||
self.data
|
||||
.iter()
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -8,20 +8,20 @@ use crate::vm::VM;
|
||||
use super::Value;
|
||||
|
||||
#[derive(Debug, Clone, Constructor)]
|
||||
pub struct PrimOp<'vm> {
|
||||
pub struct PrimOp<'jit: 'vm, 'vm> {
|
||||
pub name: &'static str,
|
||||
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 {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'vm> PrimOp<'vm> {
|
||||
pub fn call(&self, vm: &'vm VM<'_>, args: Vec<Value<'vm>>) -> Result<Value<'vm>> {
|
||||
impl<'jit, 'vm> PrimOp<'jit, 'vm> {
|
||||
pub fn call(&self, vm: &'vm VM<'jit>, args: Vec<Value<'jit, 'vm>>) -> Result<Value<'jit, 'vm>> {
|
||||
if (args.len()) < self.arity {
|
||||
Value::PartialPrimOp(
|
||||
PartialPrimOp {
|
||||
@@ -42,21 +42,21 @@ impl<'vm> PrimOp<'vm> {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PartialPrimOp<'vm> {
|
||||
pub struct PartialPrimOp<'jit: 'vm, 'vm> {
|
||||
pub name: &'static str,
|
||||
arity: usize,
|
||||
args: Vec<Value<'vm>>,
|
||||
func: fn(&'vm VM<'_>, Vec<Value<'vm>>) -> Result<Value<'vm>>,
|
||||
args: Vec<Value<'jit, '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 {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
impl<'vm> PartialPrimOp<'vm> {
|
||||
pub fn call(self: &Rc<Self>, vm: &'vm VM<'_>, args: Vec<Value<'vm>>) -> Result<Value<'vm>> {
|
||||
impl<'jit: 'vm, 'vm> PartialPrimOp<'jit, '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 mut self_clone = self.clone();
|
||||
let self_mut = Rc::make_mut(&mut self_clone);
|
||||
|
||||
@@ -4,28 +4,28 @@ use std::rc::Rc;
|
||||
use crate::ty::internal::{AttrSet, Value};
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct Env<'vm> {
|
||||
last: Option<Rc<Env<'vm>>>,
|
||||
map: Rc<HashMap<usize, Value<'vm>>>,
|
||||
pub struct Env<'jit, 'vm> {
|
||||
last: Option<Rc<Env<'jit, 'vm>>>,
|
||||
map: Rc<HashMap<usize, Value<'jit, 'vm>>>,
|
||||
}
|
||||
|
||||
impl<'vm> Env<'vm> {
|
||||
impl<'jit, 'vm> Env<'jit, 'vm> {
|
||||
pub fn empty() -> Self {
|
||||
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() {
|
||||
return Some(val);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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 last = Some(
|
||||
Env {
|
||||
@@ -37,7 +37,7 @@ impl<'vm> Env<'vm> {
|
||||
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(
|
||||
new.as_inner()
|
||||
.iter()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use inkwell::execution_engine::JitFunction;
|
||||
use std::cell::{Cell, OnceCell, RefCell};
|
||||
|
||||
use crate::builtins::env;
|
||||
@@ -81,8 +82,8 @@ impl<'vm, 'jit: 'vm> VM<'jit> {
|
||||
pub fn eval(
|
||||
&'vm self,
|
||||
opcodes: impl Iterator<Item = OpCode>,
|
||||
mut env: Env<'vm>,
|
||||
) -> Result<Value<'vm>> {
|
||||
mut env: Env<'jit, 'vm>,
|
||||
) -> Result<Value<'jit, 'vm>> {
|
||||
let mut stack = Stack::<_, STACK_SIZE>::new();
|
||||
let mut iter = opcodes.into_iter();
|
||||
while let Some(opcode) = iter.next() {
|
||||
@@ -101,8 +102,8 @@ impl<'vm, 'jit: 'vm> VM<'jit> {
|
||||
fn single_op<'s, const CAP: usize>(
|
||||
&'vm self,
|
||||
opcode: OpCode,
|
||||
stack: &'s mut Stack<Value<'vm>, CAP>,
|
||||
env: &mut Env<'vm>,
|
||||
stack: &'s mut Stack<Value<'jit, 'vm>, CAP>,
|
||||
env: &mut Env<'jit, 'vm>,
|
||||
) -> Result<usize> {
|
||||
match opcode {
|
||||
OpCode::Illegal => panic!("illegal opcode"),
|
||||
@@ -264,7 +265,7 @@ impl<'vm, 'jit: 'vm> VM<'jit> {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user