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,
Types,
},
std::fmt::Display,
core::panic,
std::{fmt::Display, usize},
};
type Offset = u32;
@ -411,7 +412,6 @@ struct Loop {
struct Variable {
id: Ident,
uses_left: u32,
value: Value,
}
@ -744,7 +744,7 @@ impl Codegen {
is_ct: false,
id,
name: "booodab",
index: u16::MAX,
is_first: false,
})
.map(|expr| self.expr(&expr))
.collect::<Option<Vec<_>>>()?;
@ -854,13 +854,7 @@ impl Codegen {
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 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,
});
self.ci.vars.push(Variable { id: carg.id, value: Value { ty, loc } });
}
}
@ -1364,7 +1358,6 @@ impl Codegen {
if let Some((var_index, var)) =
self.ci.vars.iter_mut().enumerate().find(|(_, v)| v.id == id) =>
{
var.uses_left -= 1;
let loc = var.value.loc.as_ref();
Some(Value { ty: self.ci.vars[var_index].value.ty, loc })
}
@ -1731,11 +1724,7 @@ impl Codegen {
arg.loc
};
self.ci.vars.push(Variable {
id: carg.id,
value: Value { ty, loc },
uses_left: idfl::count(sym.flags) as u32,
});
self.ci.vars.push(Variable { id: carg.id, value: Value { ty, loc } });
}
let args = self.pack_args(pos, arg_base);
@ -1779,7 +1768,6 @@ impl Codegen {
.map(|v| Variable {
id: v.id,
value: Value { ty: v.value.ty, loc: v.value.loc.as_ref() },
uses_left: v.uses_left,
})
.collect(),
stack_relocs: self.ci.stack_relocs.clone(),
@ -1848,15 +1836,11 @@ impl Codegen {
&& size <= 8 =>
{
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
}
Expr::Ident { id, .. } => {
let var = Variable {
id,
value: Value { ty, loc: Loc::ct_ptr(offset as _) },
uses_left: u32::MAX,
};
let var = Variable { id, value: Value { ty, loc: Loc::ct_ptr(offset as _) } };
self.ci.vars.push(var);
false
}
@ -1872,11 +1856,7 @@ impl Codegen {
if sym & idfl::REFERENCED != 0 {
loc = self.spill(loc, self.tys.size_of(right.ty));
}
self.ci.vars.push(Variable {
id,
value: Value { ty: right.ty, loc },
uses_left: idfl::count(sym) as u32,
});
self.ci.vars.push(Variable { id, value: Value { ty: right.ty, loc } });
}
Expr::Ctor { pos, fields, .. } => {
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()]),
false => self.load_arg(sym, ty, &mut parama),
};
self.ci.vars.push(Variable {
id: arg.id,
value: Value { ty, loc },
uses_left: idfl::count(sym) as u32,
});
self.ci.vars.push(Variable { id: arg.id, value: Value { ty, loc } });
}
if self.tys.size_of(sig.ret) > 16 {
@ -2292,25 +2268,6 @@ impl Codegen {
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)) => {
if size < 8 {
self.ci.emit(cp(dst.get(), 0));
@ -2366,8 +2323,8 @@ impl Codegen {
let trap = Self::read_trap(self.ct.vm.pc.get()).unwrap();
self.ct.vm.pc = self.ct.vm.pc.wrapping_add(trap.size() + 1);
let mut extra_jump = 0;
let mut code_index = Some(self.ct.vm.pc.get() as usize - self.ci.code.as_ptr() as usize);
let mut code_index = self.ct.vm.pc.get() as usize - self.ct.code.as_ptr() as usize;
debug_assert!(code_index < self.ct.code.len());
match *trap {
trap::Trap::MakeStruct(trap::MakeStruct { file, struct_expr }) => {
@ -2390,32 +2347,28 @@ impl Codegen {
self.ci.vars.push(Variable {
id,
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();
self.ci.vars.truncate(prev_len);
self.ct.vm.write_reg(1, stru.repr() as u64);
debug_assert_ne!(stru.expand().inner(), 1);
}
trap::Trap::MomizedCall(trap::MomizedCall { func }) => {
let sym = SymKey { file: u32::MAX, ident: ty::Kind::Func(func).compress().repr() };
if let Some(&ty) = self.tys.syms.get(&sym) {
self.ct.vm.write_reg(1, ty.repr());
extra_jump = jal(0, 0, 0).0 + tx().0;
} else {
code_index = None;
self.run_vm();
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 = lpc + self.ci.code.as_ptr() as usize;
self.ct.vm.pc = hbvm::mem::Address::new(offset as _);
}
self.ct.vm.pc += extra_jump;
let offset = code_index + self.ct.code.as_ptr() as usize;
self.ct.vm.pc = hbvm::mem::Address::new(offset as _);
}
fn find_or_declare(
@ -2588,7 +2541,8 @@ impl Codegen {
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 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)]
{
@ -2600,12 +2554,12 @@ impl Codegen {
}) {
panic!("{e} {}", String::from_utf8(vc).unwrap());
} else {
//log::inf!("{}", String::from_utf8(vc).unwrap());
log::trc!("{}", String::from_utf8(vc).unwrap());
}
}
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();
}
@ -2644,9 +2598,9 @@ impl Codegen {
if let Some(res) = ty.try_upcast(expected) {
res
} else {
let ty = self.ty_display(ty);
let expected = self.ty_display(expected);
self.report(pos, format_args!("expected {hint} of type {expected}, got {ty}"));
let dty = self.ty_display(ty);
let dexpected = self.ty_display(expected);
self.report(pos, format_args!("expected {hint} of type {dexpected}, got {dty}",));
}
}

View file

@ -270,7 +270,8 @@ mod ty {
self.0.get()
}
pub(crate) fn is_struct(&self) -> bool {
#[allow(unused)]
pub fn is_struct(&self) -> bool {
matches!(self.expand(), Kind::Struct(_))
}
}
@ -442,7 +443,7 @@ mod ty {
}
TK::Struct(idx) => {
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() {
if i != 0 {
write!(f, ", ")?;
@ -481,7 +482,7 @@ fn emit(out: &mut Vec<u8>, (len, instr): EncodedInstr) {
out.extend_from_slice(&instr[..len]);
}
#[derive(PartialEq, Eq, Hash)]
#[derive(PartialEq, Eq, Hash, Debug)]
struct SymKey {
file: u32,
ident: u32,

View file

@ -36,10 +36,6 @@ pub mod idfl {
REFERENCED,
COMPTIME,
}
pub fn count(i: IdentFlags) -> IdentIndex {
(i & !ALL) as _
}
}
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) {
let idx = |idx| top_level.not().then_some(idx);
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, .. } => {
for CtorField { value, .. } in fields {
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>) {
if let Some(index) = index_to_check
&& index != 0
{
fn declare(&mut self, pos: Pos, id: Ident, valid_order: bool) {
if !valid_order {
self.report(
pos,
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 name = self.lexer.slice(token.range());
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
.iter_mut()
.enumerate()
.rfind(|(_, elem)| self.lexer.slice(ident::range(elem.ident)) == name)
{
Some((i, elem)) => {
elem.flags += 1;
(i, elem)
}
Some((i, elem)) => (i, elem, false),
None => {
let id = ident::new(token.start, name.len() as _);
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);
}
(id.ident, idfl::count(id.flags))
(id.ident, bl)
}
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),
},
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);
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 {
pos,
@ -359,15 +349,14 @@ impl<'a, 'b> Parser<'a, 'b> {
self.expect_advance(T::LParen);
self.collect_list(T::Comma, T::RParen, |s| {
let name = s.advance_ident();
let (id, index) = s.resolve_ident(name);
s.declare(name.start, id, None);
let (id, _) = s.resolve_ident(name);
s.declare(name.start, id, true);
s.expect_advance(T::Colon);
Arg {
pos: name.start,
name: s.move_str(name),
is_ct: name.kind == T::CtIdent,
id,
index,
ty: s.expr(),
}
})
@ -488,8 +477,8 @@ impl<'a, 'b> Parser<'a, 'b> {
value: if s.advance_if(TokenKind::Colon) {
s.expr()
} else {
let (id, index) = s.resolve_ident(name_tok);
Expr::Ident { pos: name_tok.start, is_ct: false, id, name, index }
let (id, is_first) = s.resolve_ident(name_tok);
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 id: Ident,
pub is_ct: bool,
pub index: IdentIndex,
pub ty: Expr<'a>,
}
@ -710,11 +698,11 @@ generate_expr! {
/// note: ':unicode:' is any utf-8 character except ascii
/// `'[a-zA-Z_:unicode:][a-zA-Z0-9_:unicode:]*'`
Ident {
pos: Pos,
pos: Pos,
is_ct: bool,
id: Ident,
name: &'a str,
index: IdentIndex,
is_first: bool,
id: Ident,
name: &'a str,
},
/// `LIST('{', [';'], '}', Expr)`
Block {