fixing typechecking issues, pointers now properly typecheck and generic types are properly cached

This commit is contained in:
mlokr 2024-07-19 12:13:56 +02:00
parent aeb3a37f7d
commit 60b203daee
No known key found for this signature in database
GPG key ID: DEA147DDEE644993

View file

@ -594,32 +594,6 @@ impl Value {
} }
} }
enum LocCow<'a> {
Ref(&'a Loc),
Owned(Loc),
}
impl<'a> LocCow<'a> {
fn as_ref(&self) -> &Loc {
match self {
Self::Ref(value) => value,
Self::Owned(value) => value,
}
}
}
impl<'a> From<&'a Loc> for LocCow<'a> {
fn from(value: &'a Loc) -> Self {
Self::Ref(value)
}
}
impl<'a> From<Loc> for LocCow<'a> {
fn from(value: Loc) -> Self {
Self::Owned(value)
}
}
#[repr(packed)] #[repr(packed)]
#[derive(Debug, PartialEq, Eq, Clone, Copy)] #[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct CtValue(u64); struct CtValue(u64);
@ -816,8 +790,8 @@ impl ItemCtx {
output.emit(addi64(STACK_PTR, STACK_PTR, (pushed + stack) as _)); output.emit(addi64(STACK_PTR, STACK_PTR, (pushed + stack) as _));
} }
fn free_loc(&mut self, src: impl Into<LocCow>) { fn free_loc(&mut self, src: Loc) {
if let LocCow::Owned(Loc::Rt { reg, stack, .. }) = src.into() { if let Loc::Rt { reg, stack, .. } = src {
self.regs.free(reg); self.regs.free(reg);
if let Some(stack) = stack { if let Some(stack) = stack {
self.stack.free(stack); self.stack.free(stack);
@ -1391,10 +1365,10 @@ impl Codegen {
let stack = self.ci.stack.allocate(values_size); let stack = self.ci.stack.allocate(values_size);
let mut ptr = Loc::stack(stack.as_ref()); let mut ptr = Loc::stack(stack.as_ref());
for value in values { for value in values {
self.store_sized(Loc::ty(value.ty), &ptr, 4); self.store_sized(Loc::ty(value.ty), ptr.as_ref(), 4);
ptr = ptr.offset(4); ptr = ptr.offset(4);
let size = self.tys.size_of(value.ty); let size = self.tys.size_of(value.ty);
self.store_sized(value.loc, &ptr, size); self.store_sized(value.loc, ptr.as_ref(), size);
ptr = ptr.offset(size); ptr = ptr.offset(size);
} }
@ -1493,7 +1467,7 @@ impl Codegen {
self.output.emit(eca()); self.output.emit(eca());
self.load_ret(ty, &loc); self.load_ret(ty, loc.as_ref());
return Some(Value { ty, loc }); return Some(Value { ty, loc });
} }
@ -1898,7 +1872,7 @@ impl Codegen {
self.output.emit(tx()); self.output.emit(tx());
} }
self.load_ret(sig.ret, &loc); self.load_ret(sig.ret, loc.as_ref());
return Some(Value { ty: sig.ret, loc }); return Some(Value { ty: sig.ret, loc });
} }
E::Ident { id, .. } if ident::is_null(id) => Some(Value::ty(id.into())), E::Ident { id, .. } if ident::is_null(id) => Some(Value::ty(id.into())),
@ -1958,7 +1932,7 @@ impl Codegen {
E::If { cond, then, else_, .. } => { E::If { cond, then, else_, .. } => {
log::dbg!("if-cond"); log::dbg!("if-cond");
let cond = self.expr_ctx(cond, Ctx::default().with_ty(ty::BOOL))?; let cond = self.expr_ctx(cond, Ctx::default().with_ty(ty::BOOL))?;
let reg = self.loc_to_reg(&cond.loc, 1); let reg = self.loc_to_reg(cond.loc.as_ref(), 1);
let jump_offset = self.local_offset(); let jump_offset = self.local_offset();
self.output.emit(jeq(reg.get(), 0, 0)); self.output.emit(jeq(reg.get(), 0, 0));
self.ci.free_loc(cond.loc); self.ci.free_loc(cond.loc);
@ -2467,7 +2441,7 @@ impl Codegen {
fn spill(&mut self, loc: Loc, size: Size) -> Loc { fn spill(&mut self, loc: Loc, size: Size) -> Loc {
let stack = Loc::stack(self.ci.stack.allocate(size)); let stack = Loc::stack(self.ci.stack.allocate(size));
self.store_sized(loc, &stack, size); self.store_sized(loc, stack.as_ref(), size);
stack stack
} }
@ -2478,7 +2452,7 @@ impl Codegen {
1..=8 => Loc::reg(self.loc_to_reg(loc, size)), 1..=8 => Loc::reg(self.loc_to_reg(loc, size)),
_ if loc.is_ref() => { _ if loc.is_ref() => {
let new_loc = Loc::stack(self.ci.stack.allocate(size)); let new_loc = Loc::stack(self.ci.stack.allocate(size));
self.store_sized(loc, &new_loc, size); self.store_sized(loc, new_loc.as_ref(), size);
new_loc new_loc
} }
_ => loc, _ => loc,
@ -2611,7 +2585,7 @@ impl Codegen {
_ => (Loc::reg(parama.next()).into_derefed(), Loc::stack(self.ci.stack.allocate(size))), _ => (Loc::reg(parama.next()).into_derefed(), Loc::stack(self.ci.stack.allocate(size))),
}; };
self.store_sized(src, &dst, size); self.store_sized(src, dst.as_ref(), size);
dst dst
} }
@ -2637,9 +2611,9 @@ impl Codegen {
} }
} }
fn loc_to_reg(&mut self, loc: impl Into<LocCow>, size: Size) -> reg::Id { fn loc_to_reg(&mut self, loc: Loc, size: Size) -> reg::Id {
match loc.into() { match loc {
LocCow::Owned(Loc::Rt { derefed: false, mut reg, offset, stack }) => { Loc::Rt { derefed: false, mut reg, offset, stack } => {
debug_assert!(stack.is_none(), "TODO"); debug_assert!(stack.is_none(), "TODO");
assert_eq!(offset, 0, "TODO"); assert_eq!(offset, 0, "TODO");
if reg.is_ref() { if reg.is_ref() {
@ -2649,11 +2623,6 @@ impl Codegen {
} }
reg reg
} }
LocCow::Ref(&Loc::Rt { derefed: false, ref reg, offset, ref stack }) => {
debug_assert!(stack.is_none(), "TODO");
assert_eq!(offset, 0, "TODO");
reg.as_ref()
}
loc => { loc => {
let reg = self.ci.regs.allocate(); let reg = self.ci.regs.allocate();
self.store_sized(loc, Loc::reg(reg.as_ref()), size); self.store_sized(loc, Loc::reg(reg.as_ref()), size);
@ -2662,7 +2631,7 @@ impl Codegen {
} }
} }
fn load_ret(&mut self, ty: ty::Id, loc: &Loc) { fn load_ret(&mut self, ty: ty::Id, loc: Loc) {
let size = self.tys.size_of(ty); let size = self.tys.size_of(ty);
if let 1..=16 = size { if let 1..=16 = size {
self.store_sized(Loc::reg(1), loc, size); self.store_sized(Loc::reg(1), loc, size);
@ -2670,13 +2639,13 @@ impl Codegen {
} }
fn pass_arg(&mut self, value: &Value, parama: &mut ParamAlloc) { fn pass_arg(&mut self, value: &Value, parama: &mut ParamAlloc) {
self.pass_arg_low(&value.loc, self.tys.size_of(value.ty), parama) self.pass_arg_low(value.loc.as_ref(), self.tys.size_of(value.ty), parama)
} }
fn pass_arg_low(&mut self, loc: &Loc, size: Size, parama: &mut ParamAlloc) { fn pass_arg_low(&mut self, loc: Loc, size: Size, parama: &mut ParamAlloc) {
if size > 16 { if size > 16 {
let Loc::Rt { reg, stack, offset, .. } = loc else { unreachable!() }; let Loc::Rt { reg, stack, offset, .. } = loc else { unreachable!() };
self.stack_offset(parama.next(), reg.get(), stack.as_ref(), *offset as _); self.stack_offset(parama.next(), reg.get(), stack.as_ref(), offset as _);
return; return;
} }
@ -2689,15 +2658,11 @@ impl Codegen {
self.store_sized(loc, dst, size); self.store_sized(loc, dst, size);
} }
fn store_typed(&mut self, src: impl Into<LocCow>, dst: impl Into<LocCow>, ty: ty::Id) { fn store_typed(&mut self, src: Loc, dst: Loc, ty: ty::Id) {
self.store_sized(src, dst, self.tys.size_of(ty) as _) self.store_sized(src, dst, self.tys.size_of(ty) as _)
} }
fn store_sized(&mut self, src: impl Into<LocCow>, dst: impl Into<LocCow>, size: Size) { fn store_sized(&mut self, src: Loc, dst: Loc, size: Size) {
self.store_sized_low(src.into(), dst.into(), size);
}
fn store_sized_low(&mut self, src: LocCow, dst: LocCow, size: Size) {
macro_rules! lpat { macro_rules! lpat {
($der:literal, $reg:ident, $off:pat, $sta:pat) => { ($der:literal, $reg:ident, $off:pat, $sta:pat) => {
&Loc::Rt { derefed: $der, reg: ref $reg, offset: $off, stack: $sta } &Loc::Rt { derefed: $der, reg: ref $reg, offset: $off, stack: $sta }
@ -2708,10 +2673,10 @@ impl Codegen {
return; return;
} }
src.as_ref().assert_valid(); src.assert_valid();
dst.as_ref().assert_valid(); dst.assert_valid();
match (src.as_ref(), dst.as_ref()) { match (&src, &dst) {
(&Loc::Ct { value, derefed }, lpat!(true, reg, off, ref sta)) => { (&Loc::Ct { value, derefed }, lpat!(true, reg, off, ref sta)) => {
let ct = self.ci.regs.allocate(); let ct = self.ci.regs.allocate();
self.output.emit(li64(ct.get(), ensure_loaded(value, derefed, size))); self.output.emit(li64(ct.get(), ensure_loaded(value, derefed, size)));