Code cleanup

This commit is contained in:
Mia
2026-03-06 15:28:30 +01:00
parent bd0b619127
commit 92c02c6ca2
9 changed files with 63 additions and 68 deletions
+6 -2
View File
@@ -17,7 +17,10 @@ unsafe impl Send for AllocationEntry {}
unsafe impl Sync for AllocationEntry {}
pub trait Allocator {
#[allow(clippy::missing_safety_doc)]
unsafe fn alloc_uninit(&self, layout: Layout, drop: DropFn) -> *mut u8;
#[allow(clippy::missing_safety_doc)]
unsafe fn alloc_unsafe(&self, data: *const u8, layout: Layout, drop: DropFn) -> *mut u8;
}
@@ -26,6 +29,7 @@ pub trait SyncAllocator: Allocator + Send + Sync {}
impl<T: Allocator + Send + Sync> SyncAllocator for T {}
impl<'l> dyn Allocator + 'l {
#[allow(clippy::mut_from_ref)]
pub fn alloc<T>(&'l self, value: T) -> &'l mut T {
unsafe {
let value = MaybeUninit::new(value);
@@ -49,7 +53,7 @@ impl<'l> dyn Allocator + 'l {
}
}
pub fn alloc_slice<T>(&'l self, iter: impl Iterator<Item = T> + ExactSizeIterator) -> &'l [T] {
pub fn alloc_slice<T>(&'l self, iter: impl ExactSizeIterator<Item = T>) -> &'l [T] {
unsafe {
let len = iter.len();
let layout = Layout::array::<T>(len).unwrap();
@@ -82,7 +86,7 @@ impl<'l> dyn SyncAllocator + 'l {
<dyn Allocator>::alloc_str(self, value)
}
pub fn alloc_slice<T>(&'l self, iter: impl Iterator<Item = T> + ExactSizeIterator) -> &'l [T] {
pub fn alloc_slice<T>(&'l self, iter: impl ExactSizeIterator<Item = T>) -> &'l [T] {
<dyn Allocator>::alloc_slice(self, iter)
}
}
+10 -12
View File
@@ -6,7 +6,7 @@ use derive_more::{Debug, Display};
use fxhash::FxBuildHasher;
use leaf_allocators::SyncAllocator;
use scc::HashMap;
use std::{borrow::Cow, fmt::Display, hash::Hash, sync::OnceLock};
use std::{borrow::Cow, hash::Hash, sync::OnceLock};
#[derive(
derive_more::Debug, Display, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash,
@@ -69,7 +69,7 @@ impl<'l> Context<'l> {
}
pub fn get_or_create_assembly(&'l self, ident: AssemblyIdentifier) -> &'l Assembly<'l> {
&*self
&self
.assemblies
.entry_sync(ident.clone())
.or_insert_with(|| Assembly::new(self, ident))
@@ -77,7 +77,7 @@ impl<'l> Context<'l> {
pub fn intern_str(&'l self, str: &str) -> &'l str {
if let Some(value) = self.strings.get_sync(str) {
return (*value).into();
return *value;
}
let str = self.alloc.alloc_str(str);
let _ = self.strings.insert_sync(str, str);
@@ -109,12 +109,11 @@ impl Hash for Assembly<'_> {
impl<'l> Assembly<'l> {
pub fn new(ctx: &'l Context<'l>, ident: AssemblyIdentifier) -> &'l Self {
let assembly = ctx.alloc.alloc(Self {
(ctx.alloc.alloc(Self {
ctx,
ident,
functions: boxcar::vec![],
});
assembly
})) as _
}
pub fn ctx(&self) -> Ctx<'l> {
@@ -144,11 +143,10 @@ impl<'l> Assembly<'l> {
&'l self,
filter: impl Fn(&'l Function<'l>) -> bool,
) -> Option<&'l Function<'l>> {
for (_, func) in self.functions.iter() {
if filter(func) {
return Some(func);
}
}
None
self.functions
.iter()
.map(|(_, func)| func)
.find(|&func| filter(func))
.map(|v| v as _)
}
}
+2 -7
View File
@@ -161,12 +161,7 @@ pub enum InstructionVariant<'l> {
impl InstructionVariant<'_> {
pub fn is_block_termination(&self) -> bool {
match self {
Self::Return(_) => true,
Self::Jump(_) => true,
Self::Branch { .. } => true,
_ => false,
}
matches!(self, Self::Return(_) | Self::Jump(_) | Self::Branch { .. })
}
}
@@ -197,7 +192,7 @@ impl std::fmt::Debug for InstructionVariant<'_> {
write!(
f,
"call {}(",
func.name.get().unwrap_or(&"<anonymous function>".into())
func.name.get().unwrap_or(&"<anonymous function>")
)?;
let mut separator = "";
for arg in args {
+1 -1
View File
@@ -83,7 +83,7 @@ pub struct FunctionBody<'l> {
pub blocks: Vec<&'l Block<'l>>,
}
impl<'l> FmtDebug for FunctionBody<'_> {
impl FmtDebug for FunctionBody<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
struct BlockDbg<'l>(&'l Block<'l>);
+2 -1
View File
@@ -61,6 +61,7 @@ pub enum Type<'l> {
}
impl<'l> Type<'l> {
#[allow(clippy::missing_transmute_annotations)]
pub fn ctx(&self) -> &'l Context<'l> {
match self.non_default_ctx() {
Some(ctx) => ctx,
@@ -69,7 +70,7 @@ impl<'l> Type<'l> {
static ALLOCATOR: OnceLock<SyncArenaAllocator> = OnceLock::new();
let ctx: &'static Context = DEFAULT.get_or_init(|| {
let allocator: &'static SyncArenaAllocator =
ALLOCATOR.get_or_init(|| SyncArenaAllocator::default());
ALLOCATOR.get_or_init(SyncArenaAllocator::default);
Context::new(allocator)
});
std::mem::transmute(ctx)
+4 -4
View File
@@ -50,12 +50,12 @@ impl Hash for Float {
#[display("{}", _0)]
pub struct Const<T>(T);
impl<'l, T: 'l> Into<AnyConst<'l>> for &'l Const<T>
impl<'l, T: 'l> From<&'l Const<T>> for AnyConst<'l>
where
for<'a> &'a T: Into<AnyConst<'a>>,
{
fn into(self) -> AnyConst<'l> {
(&self.0).into()
fn from(val: &'l Const<T>) -> Self {
(&val.0).into()
}
}
@@ -134,7 +134,7 @@ impl<'l> AnyConst<'l> {
pub fn flags(&self) -> super::ValueFlags {
match self {
AnyConst::Function(function) => ValueFlags::Function,
AnyConst::Function(_) => ValueFlags::Function,
AnyConst::Type(_) => ValueFlags::Type,
_ => ValueFlags::Const,
}
+13 -13
View File
@@ -42,16 +42,17 @@ impl<'l> CompilationContext<'l> {
modules: HashMap::default(),
functions: HashMap::default(),
native_int_ty: match target.get_target_data().get_pointer_byte_size(None) {
8 => ctx.i8_type().into(),
16 => ctx.i16_type().into(),
32 => ctx.i32_type().into(),
64 => ctx.i64_type().into(),
128 => ctx.i128_type().into(),
8 => ctx.i8_type(),
16 => ctx.i16_type(),
32 => ctx.i32_type(),
64 => ctx.i64_type(),
128 => ctx.i128_type(),
_ => unreachable!(),
},
}
}
#[allow(clippy::mutable_key_type)]
pub fn compile(&self, assembly: &'l Assembly<'l>) -> LlvmModule<'l> {
let mut exists = true;
let module = self
@@ -79,8 +80,8 @@ impl<'l> CompilationContext<'l> {
.or_insert_with(|| module.add_function(name, ty, None));
}
for (i, func) in assembly.functions() {
let llvm_func = self.functions.get_sync(&(assembly, *func)).unwrap().clone();
for (_, func) in assembly.functions() {
let llvm_func = *self.functions.get_sync(&(assembly, *func)).unwrap();
let Some(body) = func.body() else {
continue;
@@ -128,7 +129,7 @@ impl<'l> CompilationContext<'l> {
break 'val None;
};
let ptr = value.into_pointer_value();
Some(builder.build_load(ty, ptr, "").unwrap().into())
Some(builder.build_load(ty, ptr, "").unwrap())
}
InstructionVariant::Store(target, value) => 'val: {
let Some(t_val) = self.get_value(&values, target) else {
@@ -220,7 +221,7 @@ impl<'l> CompilationContext<'l> {
InstructionVariant::Call(func, args) => {
// TODO This will fail with external assemblies. Fix this.
let func = self.functions.get_sync(&(assembly, *func)).unwrap().clone();
let func = *self.functions.get_sync(&(assembly, *func)).unwrap();
let args: Vec<_> = args
.iter()
.filter_map(|a| self.get_value(&values, a).map(|a| a.into()))
@@ -334,13 +335,14 @@ impl<'l> CompilationContext<'l> {
llvm_ty
}
#[allow(clippy::mutable_key_type)]
fn get_value(
&self,
map: &FxHashMap<Value<'l>, Option<BasicValueEnum<'l>>>,
val: &Value<'l>,
) -> Option<BasicValueEnum<'l>> {
if let Some(value) = map.get(val) {
return value.clone();
return *value;
}
match val {
Value::Constant(val) => match val {
@@ -353,9 +355,7 @@ impl<'l> CompilationContext<'l> {
AnyConst::Int(Int::U32(v)) => {
Some(self.ctx.i32_type().const_int(*v as u64, false).into())
}
AnyConst::Int(Int::U64(v)) => {
Some(self.ctx.i64_type().const_int(*v as u64, false).into())
}
AnyConst::Int(Int::U64(v)) => Some(self.ctx.i64_type().const_int(*v, false).into()),
AnyConst::Int(Int::USize(v)) => {
Some(self.native_int_ty.const_int(*v as u64, false).into())
}
+22 -25
View File
@@ -5,7 +5,7 @@ use leaf_assembly::{
Function,
ir::{Cmp, FunctionBodyBuilder},
},
types::{IntT, Type, derivations::PtrT},
types::{Type, derivations::PtrT},
values::{AnyConst, Int, Value, ValueFlags},
};
use leaf_parser::{
@@ -118,7 +118,7 @@ impl<'l> Scope<'l> {
.map(|f| Value::Constant(AnyConst::Function(f)))
.map_err(|err| CompilationError {
kind: Kind::FunctionCompilationFailed,
message: format!("Could not compile function."),
message: "Could not compile function.".to_string(),
location: Location::Range {
file: self.source.clone(),
range: func.text.range(),
@@ -135,7 +135,7 @@ impl<'l> Scope<'l> {
match n.text.split_at_checked(2) {
Some(("0b", value)) => <$ty>::from_str_radix(value, 2),
Some(("0x", value)) => <$ty>::from_str_radix(value, 16),
_ => <$ty>::from_str_radix(&n.text, 10),
_ => n.text.parse::<$ty>(),
}
.map(|v| Value::Constant(AnyConst::Int(Int::$id(v))))
.map_err(|_| CompilationError {
@@ -163,17 +163,15 @@ impl<'l> Scope<'l> {
Some("u64") => parse_number!(u64, U64),
Some("u128") => parse_number!(u128, U128),
Some("usize") => parse_number!(u128, USize),
Some(ty) => {
return Err(CompilationError {
kind: Kind::InvalidIntegerType,
message: format!("`{ty}` is not a valid integer type."),
location: Location::Range {
file: self.source.clone(),
range: n.text.range(),
},
cause: None,
});
}
Some(ty) => Err(CompilationError {
kind: Kind::InvalidIntegerType,
message: format!("`{ty}` is not a valid integer type."),
location: Location::Range {
file: self.source.clone(),
range: n.text.range(),
},
cause: None,
}),
}
}
@@ -247,14 +245,14 @@ impl<'l> Scope<'l> {
let Value::Constant(AnyConst::Type(dst_ty)) = rhs else {
return Err(CompilationError {
kind: Kind::NotAType,
message: format!("Cannot perform cast."),
message: "Cannot perform cast.".to_string(),
location: Location::Range {
file: self.source.clone(),
range: expr.range(),
},
cause: Some(Box::new(CompilationError {
kind: Kind::NotAType,
message: format!("Cast target is not a type."),
message: "Cast target is not a type.".to_string(),
location: Location::Range {
file: self.source.clone(),
range: rhs_expr.range(),
@@ -266,7 +264,7 @@ impl<'l> Scope<'l> {
match (src_ty, dst_ty) {
(Type::Int(src_ty), Type::Int(dst_ty)) => {
if dst_ty.precision < src_ty.precision {
return Ok(builder.trunc(lhs, dst_ty).unwrap().into());
return Ok(builder.trunc(lhs, dst_ty).unwrap());
}
todo!("{src_ty} as {dst_ty}");
}
@@ -373,8 +371,7 @@ impl<'l> Scope<'l> {
unsafe {
Ok(builder
.reinterpret(Value::Instruction(inst), ptr, flags)
.unwrap()
.into())
.unwrap())
}
}
v => todo!("{v:?}"),
@@ -509,10 +506,10 @@ impl<'l> Scope<'l> {
match func.ty.ret_t {
Type::Void => builder.ret(None).unwrap(),
_ => {
if let Some(expr) = last_expr.as_mut() {
if expr.flags().contains(ValueFlags::LValue) {
*expr = builder.load(*expr).unwrap();
}
if let Some(expr) = last_expr.as_mut()
&& expr.flags().contains(ValueFlags::LValue)
{
*expr = builder.load(*expr).unwrap();
}
builder.ret(last_expr).unwrap()
}
@@ -533,7 +530,7 @@ impl<'l> Scope<'l> {
) -> Result<Value<'l>, CompilationError> {
let mut sub_ctx = ExpressionContext {
decl_names: Some(names),
builder: ctx.builder.as_mut().map(|v| &mut **v),
builder: ctx.builder.as_deref_mut(),
};
let mut value = self.compile_expression(value, &mut sub_ctx)?;
if mutable {
@@ -558,7 +555,7 @@ impl<'l> Scope<'l> {
Value::Constant(AnyConst::Type(ty)) => Ok(ty),
_ => Err(CompilationError {
kind: Kind::NotAType,
message: format!("Value is not a type."),
message: "Value is not a type.".to_string(),
location: Location::None,
cause: None,
}),
+3 -3
View File
@@ -8,17 +8,17 @@ impl Parse for SourceCode {
type PositionRepr = LineCol;
#[inline]
fn start<'input>(&'input self) -> usize {
fn start(&self) -> usize {
self.text.as_str().start()
}
#[inline]
fn is_eof<'input>(&'input self, p: usize) -> bool {
fn is_eof(&self, p: usize) -> bool {
self.text.as_str().is_eof(p)
}
#[inline]
fn position_repr<'input>(&'input self, p: usize) -> Self::PositionRepr {
fn position_repr(&self, p: usize) -> Self::PositionRepr {
self.text.as_str().position_repr(p)
}
}