From 6d26716412c5e70a3d23eb712df2782ed2d51529 Mon Sep 17 00:00:00 2001 From: imxyy_soope_ Date: Mon, 19 May 2025 11:33:18 +0800 Subject: [PATCH] chore: cargo fmt --- src/bin/repl.rs | 2 +- src/builtins/mod.rs | 4 +- src/bytecode.rs | 2 +- src/ir.rs | 2 +- src/jit/helpers.rs | 62 ++++++++------- src/jit/mod.rs | 153 +++++++++++++++++++++++++++++++------- src/jit/test.rs | 21 ++++-- src/ty/common.rs | 2 +- src/ty/internal/func.rs | 6 +- src/ty/internal/mod.rs | 4 +- src/ty/internal/primop.rs | 6 +- src/ty/public.rs | 3 +- src/vm/mod.rs | 19 +++-- src/vm/test.rs | 2 +- 14 files changed, 209 insertions(+), 79 deletions(-) diff --git a/src/bin/repl.rs b/src/bin/repl.rs index 4f5edee..4f0d704 100644 --- a/src/bin/repl.rs +++ b/src/bin/repl.rs @@ -6,8 +6,8 @@ use rustyline::{DefaultEditor, Result}; use nixjit::compile::compile; use nixjit::error::Error; use nixjit::ir::downgrade; -use nixjit::vm::run; use nixjit::jit::JITContext; +use nixjit::vm::run; macro_rules! unwrap { ($e:expr) => { diff --git a/src/builtins/mod.rs b/src/builtins/mod.rs index ae91268..4bcf81e 100644 --- a/src/builtins/mod.rs +++ b/src/builtins/mod.rs @@ -1,8 +1,8 @@ use hashbrown::HashMap; use std::rc::Rc; -use crate::ty::internal::{AttrSet, PrimOp, Value}; use crate::ty::common::Const; +use crate::ty::internal::{AttrSet, PrimOp, Value}; use crate::vm::{Env, VM}; pub fn env<'jit, 'vm>(vm: &'vm VM<'jit>) -> Env<'jit, 'vm> { @@ -52,7 +52,7 @@ pub fn env<'jit, 'vm>(vm: &'vm VM<'jit>) -> Env<'jit, 'vm> { ); map.insert(vm.new_sym(primop.name), Value::PrimOp(primop)); } - let attrs: Rc<_> = Rc::new_cyclic(|weak| { + let attrs = Rc::new_cyclic(|weak| { map.insert(vm.new_sym("builtins"), Value::Builtins(weak.clone())); AttrSet::from_inner(map) }); diff --git a/src/bytecode.rs b/src/bytecode.rs index c259492..f156e22 100644 --- a/src/bytecode.rs +++ b/src/bytecode.rs @@ -2,8 +2,8 @@ use hashbrown::HashMap; use ecow::EcoString; -use crate::ty::internal::Param; use crate::ty::common::Const; +use crate::ty::internal::Param; type Slice = Box<[T]>; diff --git a/src/ir.rs b/src/ir.rs index d50b18a..1ce8a46 100644 --- a/src/ir.rs +++ b/src/ir.rs @@ -1,5 +1,5 @@ -use hashbrown::HashMap; use derive_more::IsVariant; +use hashbrown::HashMap; use ecow::EcoString; use rnix::ast::{self, Expr}; diff --git a/src/jit/helpers.rs b/src/jit/helpers.rs index 3e7c196..4ece819 100644 --- a/src/jit/helpers.rs +++ b/src/jit/helpers.rs @@ -9,9 +9,9 @@ use inkwell::values::{BasicValueEnum, FunctionValue}; use crate::jit::JITValueData; use crate::ty::internal::Thunk; -use crate::vm::{VM, Env}; +use crate::vm::{Env, VM}; -use super::{JITValue, ValueTag, JITFunc}; +use super::{JITFunc, JITValue, ValueTag}; pub struct Helpers<'ctx> { pub int_type: IntType<'ctx>, @@ -43,52 +43,54 @@ impl<'ctx> Helpers<'ctx> { let ptr_int_type = context.ptr_sized_int_type(execution_engine.get_target_data(), None); let ptr_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( - &[ptr_type.into(), ptr_type.into()], - false, - ); + let func_type = value_type.fn_type(&[ptr_type.into(), ptr_type.into()], false); let debug = module.add_function( "debug", - context - .void_type() - .fn_type(&[value_type.into()], false), - None + context.void_type().fn_type(&[value_type.into()], false), + None, ); let capture_env = module.add_function( "capture_env", context .void_type() .fn_type(&[value_type.into(), ptr_type.into()], false), - None + None, ); let neg = module.add_function( "neg", value_type.fn_type(&[value_type.into(), ptr_type.into()], false), - None + None, ); let add = module.add_function( "add", value_type.fn_type(&[value_type.into(), value_type.into()], false), - None + None, ); let sub = module.add_function( "sub", value_type.fn_type(&[value_type.into(), value_type.into()], false), - None + None, ); // Assuming a single argument for now based on the test case let call = module.add_function( "call", - value_type.fn_type(&[ptr_type.into(), ptr_type.into(), ptr_type.into(), value_type.into()], false), - None + value_type.fn_type( + &[ + ptr_type.into(), + ptr_type.into(), + ptr_type.into(), + value_type.into(), + ], + false, + ), + None, ); let lookup = module.add_function( "lookup", value_type.fn_type(&[ptr_int_type.into(), ptr_type.into()], false), - None + None, ); - execution_engine.add_global_mapping(&debug, helper_debug as _); execution_engine.add_global_mapping(&capture_env, helper_capture_env as _); execution_engine.add_global_mapping(&neg, helper_neg as _); @@ -97,7 +99,6 @@ impl<'ctx> Helpers<'ctx> { execution_engine.add_global_mapping(&call, helper_call as _); execution_engine.add_global_mapping(&lookup, helper_lookup as _); - Helpers { int_type, float_type, @@ -207,7 +208,11 @@ extern "C" fn helper_add(lhs: JITValue, rhs: JITValue) -> JITValue { int: unsafe { lhs.data.int + rhs.data.int }, }, }, - _ => todo!("Addition not implemented for {:?} and {:?}", lhs.tag, rhs.tag), + _ => todo!( + "Addition not implemented for {:?} and {:?}", + lhs.tag, + rhs.tag + ), } } @@ -221,17 +226,24 @@ extern "C" fn helper_sub(lhs: JITValue, rhs: JITValue) -> JITValue { int: unsafe { lhs.data.int - rhs.data.int }, }, }, - _ => todo!("Substruction not implemented for {:?} and {:?}", lhs.tag, rhs.tag), + _ => todo!( + "Substruction not implemented for {:?} and {:?}", + lhs.tag, + rhs.tag + ), } } #[unsafe(no_mangle)] -extern "C" fn helper_call<'jit, 'vm>(vm: *const VM<'jit>, env: *const Env<'jit, 'vm>, 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) }; todo!(); - unsafe { - func(vm, env) - } + unsafe { func(vm, env) } } #[unsafe(no_mangle)] diff --git a/src/jit/mod.rs b/src/jit/mod.rs index 03f81c4..8fdf63d 100644 --- a/src/jit/mod.rs +++ b/src/jit/mod.rs @@ -1,11 +1,11 @@ use std::rc::Rc; +use inkwell::OptimizationLevel; use inkwell::builder::Builder; use inkwell::context::Context; use inkwell::execution_engine::{ExecutionEngine, JitFunction}; use inkwell::module::Module; use inkwell::values::{BasicValueEnum, PointerValue}; -use inkwell::OptimizationLevel; use crate::bytecode::{Func, OpCode, UnOp}; use crate::error::*; @@ -49,7 +49,7 @@ pub union JITValueData { int: i64, float: f64, boolean: bool, - ptr: *const () + ptr: *const (), } impl<'jit: 'vm, 'vm> Into> for JITValue { @@ -58,7 +58,7 @@ impl<'jit: 'vm, 'vm> Into> for JITValue { match self.tag { Int => Value::Const(Const::Int(unsafe { self.data.int })), Null => Value::Const(Const::Null), - _ => todo!("not implemented for {:?}", self.tag) + _ => todo!("not implemented for {:?}", self.tag), } } } @@ -66,13 +66,17 @@ impl<'jit: 'vm, 'vm> Into> for JITValue { impl From> for JITValue { fn from(value: Value<'_, '_>) -> Self { match value { - Value::Const(Const::Int(int)) => JITValue { tag: ValueTag::Int, data: JITValueData { int } }, - _ => todo!() + Value::Const(Const::Int(int)) => JITValue { + tag: ValueTag::Int, + data: JITValueData { int }, + }, + _ => todo!(), } } } -pub type JITFunc<'jit, 'vm> = unsafe extern "C" fn(*const VM<'jit>, *const Env<'jit, 'vm>) -> JITValue; +pub type JITFunc<'jit, 'vm> = + unsafe extern "C" fn(*const VM<'jit>, *const Env<'jit, 'vm>) -> JITValue; pub struct JITContext<'ctx> { context: &'ctx Context, @@ -80,7 +84,7 @@ pub struct JITContext<'ctx> { builder: Builder<'ctx>, execution_engine: ExecutionEngine<'ctx>, - helpers: Helpers<'ctx> + helpers: Helpers<'ctx>, } impl<'vm, 'ctx: 'vm> JITContext<'ctx> { @@ -97,18 +101,30 @@ impl<'vm, 'ctx: 'vm> JITContext<'ctx> { context, module, - helpers + helpers, } } pub fn new_ptr(&self, ptr: *const T) -> PointerValue<'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>> { + pub fn compile_function( + &self, + func: &Func, + vm: &'vm VM<'_>, + ) -> Result>> { 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); + let func_ = self + .module + .add_function("nixjit_function", self.helpers.func_type, None); let entry = self.context.append_basic_block(func_, "entry"); self.builder.position_at_end(entry); let env = func_.get_nth_param(1).unwrap().into_pointer_value(); @@ -148,26 +164,48 @@ impl<'vm, 'ctx: 'vm> JITContext<'ctx> { Null => stack.push(self.helpers.new_null())?, } } - OpCode::LoadThunk { idx } => stack.push(self.helpers.new_thunk(Rc::into_raw(Rc::new(Thunk::new(vm.get_thunk(idx))))))?, + OpCode::LoadThunk { idx } => stack.push( + self.helpers + .new_thunk(Rc::into_raw(Rc::new(Thunk::new(vm.get_thunk(idx))))), + )?, OpCode::CaptureEnv => { let thunk = *stack.tos()?; - self.builder.build_direct_call(self.helpers.capture_env, &[thunk.into(), env.into()], "call_capture_env")?; + self.builder.build_direct_call( + self.helpers.capture_env, + &[thunk.into(), env.into()], + "call_capture_env", + )?; } OpCode::UnOp { op } => { use UnOp::*; let rhs = stack.pop(); stack.push(match op { - Neg => self.builder.build_direct_call(self.helpers.neg, &[rhs.into(), env.into()], "call_neg")?.try_as_basic_value().left().unwrap(), - _ => todo!() + Neg => self + .builder + .build_direct_call(self.helpers.neg, &[rhs.into(), env.into()], "call_neg")? + .try_as_basic_value() + .left() + .unwrap(), + _ => todo!(), })? } OpCode::Func { idx } => { let func = vm.get_func(idx); let jit_func_ptr = self.compile_function(func, vm)?; - let jit_value = self.helpers.value_type.const_named_struct(&[ - self.helpers.int_type.const_int(ValueTag::Function as _, false).into(), - self.helpers.ptr_int_type.const_int(unsafe { jit_func_ptr.as_raw() } as _, false).into(), - ]).into(); + let jit_value = self + .helpers + .value_type + .const_named_struct(&[ + self.helpers + .int_type + .const_int(ValueTag::Function as _, false) + .into(), + self.helpers + .ptr_int_type + .const_int(unsafe { jit_func_ptr.as_raw() } as _, false) + .into(), + ]) + .into(); stack.push(jit_value)?; } OpCode::Call { arity } => { @@ -175,8 +213,25 @@ impl<'vm, 'ctx: 'vm> JITContext<'ctx> { assert_eq!(arity, 1); let arg = stack.pop(); let func_value = stack.pop(); - let func_ptr = self.builder.build_extract_value(func_value.into_struct_value(), 1, "func_ptr")?.into_pointer_value(); - let result = self.builder.build_direct_call(self.helpers.call, &[self.new_ptr(vm).into(), env.into(), func_ptr.into(), arg.into()], "call_func")?.try_as_basic_value().left().unwrap(); + let func_ptr = self + .builder + .build_extract_value(func_value.into_struct_value(), 1, "func_ptr")? + .into_pointer_value(); + let result = self + .builder + .build_direct_call( + self.helpers.call, + &[ + self.new_ptr(vm).into(), + env.into(), + func_ptr.into(), + arg.into(), + ], + "call_func", + )? + .try_as_basic_value() + .left() + .unwrap(); stack.push(result)?; } OpCode::BinOp { op } => { @@ -185,24 +240,66 @@ impl<'vm, 'ctx: 'vm> JITContext<'ctx> { let lhs = stack.pop(); match op { BinOp::Add => { - let result = self.builder.build_direct_call(self.helpers.add, &[lhs.into(), rhs.into()], "call_add")?.try_as_basic_value().left().unwrap(); + let result = self + .builder + .build_direct_call( + self.helpers.add, + &[lhs.into(), rhs.into()], + "call_add", + )? + .try_as_basic_value() + .left() + .unwrap(); stack.push(result)?; } BinOp::Sub => { - let result = self.builder.build_direct_call(self.helpers.sub, &[lhs.into(), rhs.into()], "call_add")?.try_as_basic_value().left().unwrap(); + let result = self + .builder + .build_direct_call( + self.helpers.sub, + &[lhs.into(), rhs.into()], + "call_add", + )? + .try_as_basic_value() + .left() + .unwrap(); stack.push(result)?; } BinOp::Eq => { - let result = self.builder.build_direct_call(self.helpers.add, &[lhs.into(), rhs.into()], "call_add")?.try_as_basic_value().left().unwrap(); + let result = self + .builder + .build_direct_call( + self.helpers.add, + &[lhs.into(), rhs.into()], + "call_add", + )? + .try_as_basic_value() + .left() + .unwrap(); stack.push(result)?; } _ => todo!("BinOp::{:?} not implemented in JIT", op), } } - OpCode::LookUp { sym } => { - stack.push(self.builder.build_direct_call(self.helpers.lookup, &[self.helpers.ptr_int_type.const_int(sym as u64, false).into(), env.into()], "call_lookup").unwrap().try_as_basic_value().left().unwrap())? - } - _ => todo!("{opcode:?} not implemented") + OpCode::LookUp { sym } => stack.push( + self.builder + .build_direct_call( + self.helpers.lookup, + &[ + self.helpers + .ptr_int_type + .const_int(sym as u64, false) + .into(), + env.into(), + ], + "call_lookup", + ) + .unwrap() + .try_as_basic_value() + .left() + .unwrap(), + )?, + _ => todo!("{opcode:?} not implemented"), } Ok(()) } diff --git a/src/jit/test.rs b/src/jit/test.rs index 1773c1a..34f6f2e 100644 --- a/src/jit/test.rs +++ b/src/jit/test.rs @@ -7,14 +7,13 @@ use inkwell::context::Context; use ecow::EcoString; use rpds::vector_sync; +use crate::builtins::env; use crate::compile::compile; use crate::ir::downgrade; -use crate::ty::public::*; -use crate::ty::common::Const; use crate::jit::JITContext; +use crate::ty::common::Const; +use crate::ty::public::*; use crate::vm::VM; -use crate::builtins::env; - #[inline] fn test_expr(expr: &str, expected: Value) { @@ -23,9 +22,19 @@ fn test_expr(expr: &str, expected: Value) { dbg!(&prog); let ctx = Context::create(); let jit = JITContext::new(&ctx); - let vm = VM::new(prog.thunks, prog.funcs, prog.symbols.into(), prog.symmap.into(), prog.consts, jit); + let vm = VM::new( + prog.thunks, + prog.funcs, + prog.symbols.into(), + prog.symmap.into(), + prog.consts, + jit, + ); let env = env(&vm); - let value = vm.eval(prog.top_level.into_iter(), env).unwrap().to_public(&vm, &mut HashSet::new()); + let value = vm + .eval(prog.top_level.into_iter(), env) + .unwrap() + .to_public(&vm, &mut HashSet::new()); assert_eq!(value, expected); } diff --git a/src/ty/common.rs b/src/ty/common.rs index ced4f3d..6bfbbdf 100644 --- a/src/ty/common.rs +++ b/src/ty/common.rs @@ -1,5 +1,5 @@ -use std::hash::Hash; use std::fmt::{Display, Formatter, Result as FmtResult}; +use std::hash::Hash; use derive_more::{Constructor, IsVariant, Unwrap}; use ecow::EcoString; diff --git a/src/ty/internal/func.rs b/src/ty/internal/func.rs index a3835eb..ac1ec70 100644 --- a/src/ty/internal/func.rs +++ b/src/ty/internal/func.rs @@ -1,8 +1,8 @@ use std::cell::{Cell, OnceCell}; +use derive_more::Constructor; use inkwell::execution_engine::JitFunction; use itertools::Itertools; -use derive_more::Constructor; use crate::bytecode::Func as BFunc; use crate::error::Result; @@ -46,7 +46,7 @@ pub struct Func<'jit: 'vm, 'vm> { pub func: &'vm BFunc, pub env: Env<'jit, 'vm>, pub compiled: OnceCell>>, - pub count: Cell + pub count: Cell, } impl<'vm, 'jit: 'vm> Func<'jit, 'vm> { @@ -94,7 +94,7 @@ impl<'vm, 'jit: 'vm> Func<'jit, 'vm> { if count >= 1 { let compiled = self.compiled.get_or_init(|| vm.compile_func(self.func)); let ret = unsafe { compiled.call(vm as *const VM, &env as *const Env) }; - return Ok(ret.into()) + return Ok(ret.into()); } vm.eval(self.func.opcodes.iter().copied(), env) } diff --git a/src/ty/internal/mod.rs b/src/ty/internal/mod.rs index 94634e9..10b3826 100644 --- a/src/ty/internal/mod.rs +++ b/src/ty/internal/mod.rs @@ -76,7 +76,9 @@ impl<'jit: 'vm, 'vm> PartialEq for Value<'jit, 'vm> { use Value::*; match (self, other) { (Const(a), Const(b)) => a.eq(b), - (AttrSet(a), AttrSet(b)) => (a.as_ref() as *const self::AttrSet).eq(&(b.as_ref() as *const _)), + (AttrSet(a), AttrSet(b)) => { + (a.as_ref() as *const self::AttrSet).eq(&(b.as_ref() as *const _)) + } (List(a), List(b)) => (a.as_ref() as *const self::List).eq(&(b.as_ref() as *const _)), (Builtins(a), Builtins(b)) => a.ptr_eq(b), _ => false, diff --git a/src/ty/internal/primop.rs b/src/ty/internal/primop.rs index 5145590..984b57c 100644 --- a/src/ty/internal/primop.rs +++ b/src/ty/internal/primop.rs @@ -56,7 +56,11 @@ impl PartialEq for PartialPrimOp<'_, '_> { } impl<'jit: 'vm, 'vm> PartialPrimOp<'jit, 'vm> { - pub fn call(self: &Rc, vm: &'vm VM<'jit>, args: Vec>) -> Result> { + pub fn call( + self: &Rc, + vm: &'vm VM<'jit>, + args: Vec>, + ) -> Result> { let len = args.len(); let mut self_clone = self.clone(); let self_mut = Rc::make_mut(&mut self_clone); diff --git a/src/ty/public.rs b/src/ty/public.rs index 323e5f5..5f97ac2 100644 --- a/src/ty/public.rs +++ b/src/ty/public.rs @@ -83,7 +83,7 @@ impl Display for AttrSet { match v { AttrSet(_) => write!(f, "{{ ... }}"), List(_) => write!(f, "[ ... ]"), - v => write!(f, "{v}") + v => write!(f, "{v}"), }?; write!(f, "; ")?; } @@ -135,4 +135,3 @@ impl Display for Value { } } } - diff --git a/src/vm/mod.rs b/src/vm/mod.rs index 6724004..c1f73f9 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -5,11 +5,11 @@ use std::cell::{Cell, OnceCell, RefCell}; use crate::builtins::env; use crate::bytecode::{BinOp, Func as F, OpCode, OpCodes, Program, UnOp}; use crate::error::*; -use crate::ty::internal::*; -use crate::ty::common::Const; -use crate::ty::public::{self as p, Symbol}; -use crate::stack::Stack; use crate::jit::{JITContext, JITFunc}; +use crate::stack::Stack; +use crate::ty::common::Const; +use crate::ty::internal::*; +use crate::ty::public::{self as p, Symbol}; use derive_more::Constructor; use ecow::EcoString; @@ -111,7 +111,12 @@ impl<'vm, 'jit: 'vm> VM<'jit> { OpCode::LoadThunk { idx } => { stack.push(Value::Thunk(Thunk::new(self.get_thunk(idx)).into()))? } - OpCode::CaptureEnv => stack.tos().unwrap().as_ref().unwrap_thunk().capture(env.clone()), + OpCode::CaptureEnv => stack + .tos() + .unwrap() + .as_ref() + .unwrap_thunk() + .capture(env.clone()), OpCode::ForceValue => { stack.tos_mut()?.force(self)?; } @@ -137,7 +142,9 @@ impl<'vm, 'jit: 'vm> VM<'jit> { } OpCode::Func { idx } => { let func = self.get_func(idx); - stack.push(Value::Func(Func::new(func, env.clone(), OnceCell::new(), Cell::new(0)).into()))?; + stack.push(Value::Func( + Func::new(func, env.clone(), OnceCell::new(), Cell::new(0)).into(), + ))?; } OpCode::UnOp { op } => { use UnOp::*; diff --git a/src/vm/test.rs b/src/vm/test.rs index 17631af..a40d770 100644 --- a/src/vm/test.rs +++ b/src/vm/test.rs @@ -10,8 +10,8 @@ use rpds::vector_sync; use crate::compile::compile; use crate::ir::downgrade; -use crate::ty::public::*; use crate::ty::common::Const; +use crate::ty::public::*; use crate::vm::JITContext; use super::run;