fixing all supidus bugs

This commit is contained in:
mlokr 2024-09-20 16:37:51 +02:00
parent 8e62bd747b
commit 2a3d077476
No known key found for this signature in database
GPG key ID: DEA147DDEE644993
3 changed files with 45 additions and 102 deletions

View file

@ -11,7 +11,8 @@ use {
ty, Field, Func, Global, LoggedMem, ParamAlloc, Reloc, Sig, Struct, SymKey, TypedReloc, ty, Field, Func, Global, LoggedMem, ParamAlloc, Reloc, Sig, Struct, SymKey, TypedReloc,
Types, Types,
}, },
std::fmt::Display, core::panic,
std::{fmt::Display, usize},
}; };
type Offset = u32; type Offset = u32;
@ -411,7 +412,6 @@ struct Loop {
struct Variable { struct Variable {
id: Ident, id: Ident,
uses_left: u32,
value: Value, value: Value,
} }
@ -744,7 +744,7 @@ impl Codegen {
is_ct: false, is_ct: false,
id, id,
name: "booodab", name: "booodab",
index: u16::MAX, is_first: false,
}) })
.map(|expr| self.expr(&expr)) .map(|expr| self.expr(&expr))
.collect::<Option<Vec<_>>>()?; .collect::<Option<Vec<_>>>()?;
@ -854,13 +854,7 @@ impl Codegen {
args.iter().zip(sig.args.view(&self.tys.args).to_owned()).zip(cargs) args.iter().zip(sig.args.view(&self.tys.args).to_owned()).zip(cargs)
{ {
let loc = self.expr_ctx(arg, Ctx::default().with_ty(ty))?.loc; let loc = self.expr_ctx(arg, Ctx::default().with_ty(ty))?.loc;
self.ci.vars.push(Variable { id: carg.id, value: Value { ty, loc } });
let sym = parser::find_symbol(&fast.symbols, carg.id).flags;
self.ci.vars.push(Variable {
id: carg.id,
value: Value { ty, loc },
uses_left: idfl::count(sym) as u32,
});
} }
} }
@ -1364,7 +1358,6 @@ impl Codegen {
if let Some((var_index, var)) = if let Some((var_index, var)) =
self.ci.vars.iter_mut().enumerate().find(|(_, v)| v.id == id) => self.ci.vars.iter_mut().enumerate().find(|(_, v)| v.id == id) =>
{ {
var.uses_left -= 1;
let loc = var.value.loc.as_ref(); let loc = var.value.loc.as_ref();
Some(Value { ty: self.ci.vars[var_index].value.ty, loc }) Some(Value { ty: self.ci.vars[var_index].value.ty, loc })
} }
@ -1731,11 +1724,7 @@ impl Codegen {
arg.loc arg.loc
}; };
self.ci.vars.push(Variable { self.ci.vars.push(Variable { id: carg.id, value: Value { ty, loc } });
id: carg.id,
value: Value { ty, loc },
uses_left: idfl::count(sym.flags) as u32,
});
} }
let args = self.pack_args(pos, arg_base); let args = self.pack_args(pos, arg_base);
@ -1779,7 +1768,6 @@ impl Codegen {
.map(|v| Variable { .map(|v| Variable {
id: v.id, id: v.id,
value: Value { ty: v.value.ty, loc: v.value.loc.as_ref() }, value: Value { ty: v.value.ty, loc: v.value.loc.as_ref() },
uses_left: v.uses_left,
}) })
.collect(), .collect(),
stack_relocs: self.ci.stack_relocs.clone(), stack_relocs: self.ci.stack_relocs.clone(),
@ -1848,15 +1836,11 @@ impl Codegen {
&& size <= 8 => && size <= 8 =>
{ {
let loc = Loc::ct(load_value(offset, size)); let loc = Loc::ct(load_value(offset, size));
self.ci.vars.push(Variable { id, value: Value { ty, loc }, uses_left: u32::MAX }); self.ci.vars.push(Variable { id, value: Value { ty, loc } });
true true
} }
Expr::Ident { id, .. } => { Expr::Ident { id, .. } => {
let var = Variable { let var = Variable { id, value: Value { ty, loc: Loc::ct_ptr(offset as _) } };
id,
value: Value { ty, loc: Loc::ct_ptr(offset as _) },
uses_left: u32::MAX,
};
self.ci.vars.push(var); self.ci.vars.push(var);
false false
} }
@ -1872,11 +1856,7 @@ impl Codegen {
if sym & idfl::REFERENCED != 0 { if sym & idfl::REFERENCED != 0 {
loc = self.spill(loc, self.tys.size_of(right.ty)); loc = self.spill(loc, self.tys.size_of(right.ty));
} }
self.ci.vars.push(Variable { self.ci.vars.push(Variable { id, value: Value { ty: right.ty, loc } });
id,
value: Value { ty: right.ty, loc },
uses_left: idfl::count(sym) as u32,
});
} }
Expr::Ctor { pos, fields, .. } => { Expr::Ctor { pos, fields, .. } => {
let ty::Kind::Struct(idx) = right.ty.expand() else { let ty::Kind::Struct(idx) = right.ty.expand() else {
@ -2089,11 +2069,7 @@ impl Codegen {
true => Loc::ty(self.tys.args[sig_args.next().unwrap()]), true => Loc::ty(self.tys.args[sig_args.next().unwrap()]),
false => self.load_arg(sym, ty, &mut parama), false => self.load_arg(sym, ty, &mut parama),
}; };
self.ci.vars.push(Variable { self.ci.vars.push(Variable { id: arg.id, value: Value { ty, loc } });
id: arg.id,
value: Value { ty, loc },
uses_left: idfl::count(sym) as u32,
});
} }
if self.tys.size_of(sig.ret) > 16 { if self.tys.size_of(sig.ret) > 16 {
@ -2292,25 +2268,6 @@ impl Codegen {
self.ci.emit(cp(dst.get(), src.get())); self.ci.emit(cp(dst.get(), src.get()));
} }
} }
//(lpat!(false, src, 0, None), lpat!(false, dst, off, None)) => {
// assert!(size <= 8);
// let off_rem = 8 * (off % 8);
// let freg = dst.get() + (off / 8) as u8;
// if size < 8 {
// let mask = !(((1u64 << (8 * size)) - 1) << off_rem);
// self.ci.emit(andi(freg, freg, mask));
// if off_rem == 0 {
// self.ci.emit(or(freg, freg, src.get()));
// } else {
// let tmp = self.ci.regs.allocate();
// self.ci.emit(slui64(tmp.get(), src.get(), off_rem as _));
// self.ci.emit(or(freg, freg, src.get()));
// self.ci.regs.free(tmp);
// }
// } else {
// self.ci.emit(cp(freg, src.get()));
// }
//}
(lpat!(true, src, soff, ref ssta), lpat!(false, dst, 0, None)) => { (lpat!(true, src, soff, ref ssta), lpat!(false, dst, 0, None)) => {
if size < 8 { if size < 8 {
self.ci.emit(cp(dst.get(), 0)); self.ci.emit(cp(dst.get(), 0));
@ -2366,8 +2323,8 @@ impl Codegen {
let trap = Self::read_trap(self.ct.vm.pc.get()).unwrap(); let trap = Self::read_trap(self.ct.vm.pc.get()).unwrap();
self.ct.vm.pc = self.ct.vm.pc.wrapping_add(trap.size() + 1); self.ct.vm.pc = self.ct.vm.pc.wrapping_add(trap.size() + 1);
let mut extra_jump = 0; let mut code_index = self.ct.vm.pc.get() as usize - self.ct.code.as_ptr() as usize;
let mut code_index = Some(self.ct.vm.pc.get() as usize - self.ci.code.as_ptr() as usize); debug_assert!(code_index < self.ct.code.len());
match *trap { match *trap {
trap::Trap::MakeStruct(trap::MakeStruct { file, struct_expr }) => { trap::Trap::MakeStruct(trap::MakeStruct { file, struct_expr }) => {
@ -2390,32 +2347,28 @@ impl Codegen {
self.ci.vars.push(Variable { self.ci.vars.push(Variable {
id, id,
value: Value::new(ty, Loc::ct(u64::from_ne_bytes(imm))), value: Value::new(ty, Loc::ct(u64::from_ne_bytes(imm))),
uses_left: u32::MAX,
}); });
} }
let stru = ty::Kind::Struct(self.build_struct(fields)).compress(); let stru = ty::Kind::Struct(self.build_struct(fields)).compress();
self.ci.vars.truncate(prev_len); self.ci.vars.truncate(prev_len);
self.ct.vm.write_reg(1, stru.repr() as u64); self.ct.vm.write_reg(1, stru.repr() as u64);
debug_assert_ne!(stru.expand().inner(), 1);
} }
trap::Trap::MomizedCall(trap::MomizedCall { func }) => { trap::Trap::MomizedCall(trap::MomizedCall { func }) => {
let sym = SymKey { file: u32::MAX, ident: ty::Kind::Func(func).compress().repr() }; let sym = SymKey { file: u32::MAX, ident: ty::Kind::Func(func).compress().repr() };
if let Some(&ty) = self.tys.syms.get(&sym) { if let Some(&ty) = self.tys.syms.get(&sym) {
self.ct.vm.write_reg(1, ty.repr()); self.ct.vm.write_reg(1, ty.repr());
extra_jump = jal(0, 0, 0).0 + tx().0;
} else { } else {
code_index = None;
self.run_vm(); self.run_vm();
self.tys.syms.insert(sym, self.ct.vm.read_reg(1).0.into()); self.tys.syms.insert(sym, self.ct.vm.read_reg(1).0.into());
} }
code_index += jal(0, 0, 0).0 + tx().0;
} }
} }
if let Some(lpc) = code_index { let offset = code_index + self.ct.code.as_ptr() as usize;
let offset = lpc + self.ci.code.as_ptr() as usize; self.ct.vm.pc = hbvm::mem::Address::new(offset as _);
self.ct.vm.pc = hbvm::mem::Address::new(offset as _);
}
self.ct.vm.pc += extra_jump;
} }
fn find_or_declare( fn find_or_declare(
@ -2588,7 +2541,8 @@ impl Codegen {
self.tys.dump_reachable(last_fn as _, &mut self.ct.code); self.tys.dump_reachable(last_fn as _, &mut self.ct.code);
let entry = &mut self.ct.code[self.tys.funcs[last_fn].offset as usize] as *mut _ as _; let entry = &mut self.ct.code[self.tys.funcs[last_fn].offset as usize] as *mut _ as _;
let prev_pc = std::mem::replace(&mut self.ct.vm.pc, hbvm::mem::Address::new(entry)); let prev_pc = std::mem::replace(&mut self.ct.vm.pc, hbvm::mem::Address::new(entry))
- self.ct.code.as_ptr() as usize;
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
{ {
@ -2600,12 +2554,12 @@ impl Codegen {
}) { }) {
panic!("{e} {}", String::from_utf8(vc).unwrap()); panic!("{e} {}", String::from_utf8(vc).unwrap());
} else { } else {
//log::inf!("{}", String::from_utf8(vc).unwrap()); log::trc!("{}", String::from_utf8(vc).unwrap());
} }
} }
self.run_vm(); self.run_vm();
self.ct.vm.pc = prev_pc; self.ct.vm.pc = prev_pc + self.ct.code.as_ptr() as usize;
self.tys.funcs.pop().unwrap(); self.tys.funcs.pop().unwrap();
} }
@ -2644,9 +2598,9 @@ impl Codegen {
if let Some(res) = ty.try_upcast(expected) { if let Some(res) = ty.try_upcast(expected) {
res res
} else { } else {
let ty = self.ty_display(ty); let dty = self.ty_display(ty);
let expected = self.ty_display(expected); let dexpected = self.ty_display(expected);
self.report(pos, format_args!("expected {hint} of type {expected}, got {ty}")); self.report(pos, format_args!("expected {hint} of type {dexpected}, got {dty}",));
} }
} }

View file

@ -270,7 +270,8 @@ mod ty {
self.0.get() self.0.get()
} }
pub(crate) fn is_struct(&self) -> bool { #[allow(unused)]
pub fn is_struct(&self) -> bool {
matches!(self.expand(), Kind::Struct(_)) matches!(self.expand(), Kind::Struct(_))
} }
} }
@ -442,7 +443,7 @@ mod ty {
} }
TK::Struct(idx) => { TK::Struct(idx) => {
let record = &self.tys.structs[idx as usize]; let record = &self.tys.structs[idx as usize];
write!(f, "{{")?; write!(f, "[{idx}]{{")?;
for (i, &super::Field { ref name, ty }) in record.fields.iter().enumerate() { for (i, &super::Field { ref name, ty }) in record.fields.iter().enumerate() {
if i != 0 { if i != 0 {
write!(f, ", ")?; write!(f, ", ")?;
@ -481,7 +482,7 @@ fn emit(out: &mut Vec<u8>, (len, instr): EncodedInstr) {
out.extend_from_slice(&instr[..len]); out.extend_from_slice(&instr[..len]);
} }
#[derive(PartialEq, Eq, Hash)] #[derive(PartialEq, Eq, Hash, Debug)]
struct SymKey { struct SymKey {
file: u32, file: u32,
ident: u32, ident: u32,

View file

@ -36,10 +36,6 @@ pub mod idfl {
REFERENCED, REFERENCED,
COMPTIME, COMPTIME,
} }
pub fn count(i: IdentFlags) -> IdentIndex {
(i & !ALL) as _
}
} }
pub fn no_loader(_: &str, _: &str) -> io::Result<FileId> { pub fn no_loader(_: &str, _: &str) -> io::Result<FileId> {
@ -187,9 +183,8 @@ impl<'a, 'b> Parser<'a, 'b> {
} }
fn declare_rec(&mut self, expr: &Expr, top_level: bool) { fn declare_rec(&mut self, expr: &Expr, top_level: bool) {
let idx = |idx| top_level.not().then_some(idx);
match *expr { match *expr {
Expr::Ident { pos, id, index, .. } => self.declare(pos, id, idx(index)), Expr::Ident { pos, id, is_first, .. } => self.declare(pos, id, is_first || top_level),
Expr::Ctor { fields, .. } => { Expr::Ctor { fields, .. } => {
for CtorField { value, .. } in fields { for CtorField { value, .. } in fields {
self.declare_rec(value, top_level) self.declare_rec(value, top_level)
@ -199,10 +194,8 @@ impl<'a, 'b> Parser<'a, 'b> {
} }
} }
fn declare(&mut self, pos: Pos, id: Ident, index_to_check: Option<IdentIndex>) { fn declare(&mut self, pos: Pos, id: Ident, valid_order: bool) {
if let Some(index) = index_to_check if !valid_order {
&& index != 0
{
self.report( self.report(
pos, pos,
format_args!( format_args!(
@ -221,28 +214,25 @@ impl<'a, 'b> Parser<'a, 'b> {
} }
} }
fn resolve_ident(&mut self, token: Token) -> (Ident, IdentIndex) { fn resolve_ident(&mut self, token: Token) -> (Ident, bool) {
let is_ct = token.kind == TokenKind::CtIdent; let is_ct = token.kind == TokenKind::CtIdent;
let name = self.lexer.slice(token.range()); let name = self.lexer.slice(token.range());
if let Some(builtin) = crate::ty::from_str(name) { if let Some(builtin) = crate::ty::from_str(name) {
return (builtin, 0); return (builtin, false);
} }
let (i, id) = match self let (i, id, bl) = match self
.idents .idents
.iter_mut() .iter_mut()
.enumerate() .enumerate()
.rfind(|(_, elem)| self.lexer.slice(ident::range(elem.ident)) == name) .rfind(|(_, elem)| self.lexer.slice(ident::range(elem.ident)) == name)
{ {
Some((i, elem)) => { Some((i, elem)) => (i, elem, false),
elem.flags += 1;
(i, elem)
}
None => { None => {
let id = ident::new(token.start, name.len() as _); let id = ident::new(token.start, name.len() as _);
self.idents.push(ScopeIdent { ident: id, declared: false, flags: 0 }); self.idents.push(ScopeIdent { ident: id, declared: false, flags: 0 });
(self.idents.len() - 1, self.idents.last_mut().unwrap()) (self.idents.len() - 1, self.idents.last_mut().unwrap(), true)
} }
}; };
@ -252,7 +242,7 @@ impl<'a, 'b> Parser<'a, 'b> {
self.captured.push(id.ident); self.captured.push(id.ident);
} }
(id.ident, idfl::count(id.flags)) (id.ident, bl)
} }
fn move_str(&mut self, range: Token) -> &'a str { fn move_str(&mut self, range: Token) -> &'a str {
@ -332,9 +322,9 @@ impl<'a, 'b> Parser<'a, 'b> {
trailing_comma: std::mem::take(&mut self.trailing_sep), trailing_comma: std::mem::take(&mut self.trailing_sep),
}, },
T::Ident | T::CtIdent => { T::Ident | T::CtIdent => {
let (id, index) = self.resolve_ident(token); let (id, is_first) = self.resolve_ident(token);
let name = self.move_str(token); let name = self.move_str(token);
E::Ident { pos, is_ct: token.kind == T::CtIdent, name, id, index } E::Ident { pos, is_ct: token.kind == T::CtIdent, name, id, is_first }
} }
T::If => E::If { T::If => E::If {
pos, pos,
@ -359,15 +349,14 @@ impl<'a, 'b> Parser<'a, 'b> {
self.expect_advance(T::LParen); self.expect_advance(T::LParen);
self.collect_list(T::Comma, T::RParen, |s| { self.collect_list(T::Comma, T::RParen, |s| {
let name = s.advance_ident(); let name = s.advance_ident();
let (id, index) = s.resolve_ident(name); let (id, _) = s.resolve_ident(name);
s.declare(name.start, id, None); s.declare(name.start, id, true);
s.expect_advance(T::Colon); s.expect_advance(T::Colon);
Arg { Arg {
pos: name.start, pos: name.start,
name: s.move_str(name), name: s.move_str(name),
is_ct: name.kind == T::CtIdent, is_ct: name.kind == T::CtIdent,
id, id,
index,
ty: s.expr(), ty: s.expr(),
} }
}) })
@ -488,8 +477,8 @@ impl<'a, 'b> Parser<'a, 'b> {
value: if s.advance_if(TokenKind::Colon) { value: if s.advance_if(TokenKind::Colon) {
s.expr() s.expr()
} else { } else {
let (id, index) = s.resolve_ident(name_tok); let (id, is_first) = s.resolve_ident(name_tok);
Expr::Ident { pos: name_tok.start, is_ct: false, id, name, index } Expr::Ident { pos: name_tok.start, is_ct: false, id, name, is_first }
}, },
} }
}), }),
@ -598,7 +587,6 @@ pub struct Arg<'a> {
pub name: &'a str, pub name: &'a str,
pub id: Ident, pub id: Ident,
pub is_ct: bool, pub is_ct: bool,
pub index: IdentIndex,
pub ty: Expr<'a>, pub ty: Expr<'a>,
} }
@ -710,11 +698,11 @@ generate_expr! {
/// note: ':unicode:' is any utf-8 character except ascii /// note: ':unicode:' is any utf-8 character except ascii
/// `'[a-zA-Z_:unicode:][a-zA-Z0-9_:unicode:]*'` /// `'[a-zA-Z_:unicode:][a-zA-Z0-9_:unicode:]*'`
Ident { Ident {
pos: Pos, pos: Pos,
is_ct: bool, is_ct: bool,
id: Ident, is_first: bool,
name: &'a str, id: Ident,
index: IdentIndex, name: &'a str,
}, },
/// `LIST('{', [';'], '}', Expr)` /// `LIST('{', [';'], '}', Expr)`
Block { Block {