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::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)));
|
||||||
|
|||||||
@@ -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) };
|
||||||
|
unsafe {
|
||||||
func(vm, env, arg)
|
func(vm, env, arg)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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!()
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user