feat: JIT (WIP)

This commit is contained in:
2025-05-17 12:18:02 +08:00
parent 15df7e55c9
commit 85f06a30cd
3 changed files with 60 additions and 9 deletions

View File

@@ -4,7 +4,6 @@ use std::ops::Deref;
use crate::error::*; use crate::error::*;
pub struct Stack<T, const CAP: usize> { pub struct Stack<T, const CAP: usize> {
// items: Box<[MaybeUninit<Value<'vm>>; CAP]>,
items: [MaybeUninit<T>; CAP], items: [MaybeUninit<T>; CAP],
top: usize, top: usize,
} }

View File

@@ -1,26 +1,77 @@
use inkwell::OptimizationLevel; use std::pin::Pin;
use inkwell::types::{BasicType, BasicTypeEnum, FunctionType, StructType};
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue};
use inkwell::{AddressSpace, OptimizationLevel};
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;
use inkwell::module::Module; use inkwell::module::Module;
use crate::stack::Stack;
use super::STACK_SIZE;
#[repr(usize)]
pub enum ValueTag {
Int,
String,
Bool,
AttrSet,
List,
Function,
Thunk,
Path
}
#[repr(C)]
pub struct JITValue {
tag: ValueTag,
data: u64
}
pub struct JITContext<'ctx> { pub struct JITContext<'ctx> {
context: &'ctx Context, context: &'ctx Context,
module: Module<'ctx>, module: Module<'ctx>,
builder: Builder<'ctx>, builder: Builder<'ctx>,
execution_engine: ExecutionEngine<'ctx>, execution_engine: ExecutionEngine<'ctx>,
stack: Stack<BasicValueEnum<'ctx>, STACK_SIZE>,
cur_func: Option<FunctionValue<'ctx>>,
value_type: StructType<'ctx>,
func_type: FunctionType<'ctx>,
} }
impl<'ctx> JITContext<'ctx> { impl<'ctx> JITContext<'ctx> {
pub fn new(context: &Context) -> JITContext { pub fn new(context: &'ctx Context) -> Pin<Box<Self>> {
let module = context.create_module("nixjit"); let module = context.create_module("nixjit");
JITContext { let stack = Stack::new();
let int_type = context.i64_type();
let pointer_type = context.ptr_type(AddressSpace::default());
let value_type = context.struct_type(&[int_type.into(), int_type.into()], false);
let func_type = value_type.fn_type(&[pointer_type.into(), pointer_type.into(), value_type.into()], false);
Pin::new(Box::new(JITContext {
execution_engine: module execution_engine: module
.create_jit_execution_engine(OptimizationLevel::None) .create_jit_execution_engine(OptimizationLevel::Default)
.unwrap(), .unwrap(),
builder: context.create_builder(), builder: context.create_builder(),
context, context,
module, module,
stack,
cur_func: None,
value_type,
func_type,
}))
} }
fn new_int(&self, int: i64) -> IntValue {
self.context.i64_type().const_int(int as u64, false)
}
pub fn start_trace(&mut self) {
} }
} }

View File

@@ -1,5 +1,6 @@
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::pin::Pin;
use std::rc::Rc; use std::rc::Rc;
use crate::builtins::env; use crate::builtins::env;
@@ -21,9 +22,9 @@ mod jit;
#[cfg(test)] #[cfg(test)]
mod test; mod test;
const STACK_SIZE: usize = 8 * 1024 / size_of::<Value>(); pub const STACK_SIZE: usize = 8 * 1024 / size_of::<Value>();
pub fn run(prog: Program, jit: JITContext<'_>) -> Result<p::Value> { pub fn run(prog: Program, jit: Pin<Box<JITContext<'_>>>) -> Result<p::Value> {
let vm = VM::new( let vm = VM::new(
prog.thunks, prog.thunks,
prog.funcs, prog.funcs,
@@ -45,7 +46,7 @@ pub struct VM<'jit> {
symbols: RefCell<Vec<EcoString>>, symbols: RefCell<Vec<EcoString>>,
symmap: RefCell<HashMap<EcoString, usize>>, symmap: RefCell<HashMap<EcoString, usize>>,
consts: Box<[Const]>, consts: Box<[Const]>,
jit: JITContext<'jit>, jit: Pin<Box<JITContext<'jit>>>
} }
impl<'vm, 'jit: 'vm> VM<'jit> { impl<'vm, 'jit: 'vm> VM<'jit> {