Code cleanup
This commit is contained in:
@@ -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
@@ -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 _)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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())
|
||||
}
|
||||
|
||||
+14
-17
@@ -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,8 +163,7 @@ 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 {
|
||||
Some(ty) => Err(CompilationError {
|
||||
kind: Kind::InvalidIntegerType,
|
||||
message: format!("`{ty}` is not a valid integer type."),
|
||||
location: Location::Range {
|
||||
@@ -172,8 +171,7 @@ impl<'l> Scope<'l> {
|
||||
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,11 +506,11 @@ 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) {
|
||||
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,
|
||||
}),
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user