Properly deduplicating imported functions

Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
Jakub Doka 2025-01-01 21:24:03 +01:00
parent da5bd3d36a
commit 8aee4f2890
No known key found for this signature in database
GPG key ID: C6E9A89936B8C143
5 changed files with 49 additions and 19 deletions

View file

@ -17,6 +17,7 @@ use {
utils::{self as hbutils, Ent, EntVec},
},
std::{
collections::HashSet,
fmt::{Display, Write},
ops::Range,
},
@ -90,6 +91,9 @@ impl hblang::backend::Backend for Backend {
self.globals.shadow(types.ins.globals.len());
#[cfg(debug_assertions)]
let mut seen_names = HashSet::new();
self.asm.frontier.push(from.into());
while let Some(itm) = self.asm.frontier.pop() {
match itm.expand() {
@ -156,6 +160,7 @@ impl hblang::backend::Backend for Backend {
&mut self.ctx.func.signature,
&mut vec![],
);
debug_assert!(seen_names.insert(self.asm.name.clone()), "{}", self.asm.name);
fuc.module_id = Some(
module
.declare_function(&self.asm.name, linkage, &self.ctx.func.signature)
@ -211,7 +216,9 @@ impl hblang::backend::Backend for Backend {
nm.index =
self.globals[hbty::Global::new(nm.index as _)].module_id.unwrap().as_u32();
}
let prev_len = self.ctx.func.params.user_named_funcs().len();
self.ctx.func.params.ensure_user_func_name(nm.clone());
debug_assert_ne!(self.ctx.func.params.user_named_funcs().len(), prev_len, "{}", nm);
});
module
.define_function_bytes(
@ -254,7 +261,6 @@ impl hblang::backend::Backend for Backend {
tys: &hbty::Types,
files: &hbutils::EntSlice<hbty::Module, hblang::parser::Ast>,
) {
self.ctx.clear();
let isa = self.module.as_ref().unwrap().isa();
let mut lens = vec![];
@ -286,6 +292,7 @@ impl hblang::backend::Backend for Backend {
self.ctx.compile(isa, &mut self.ctrl_plane).unwrap();
let code = self.ctx.compiled_code().unwrap();
self.funcs.push(id, &self.ctx.func, &code.buffer);
self.ctx.clear();
}
}

View file

@ -229,8 +229,8 @@ impl Backend for HbvmBackend {
let functions = types
.ins
.funcs
.iter()
.zip(self.funcs.iter())
.values()
.zip(self.funcs.values())
.filter(|(_, f)| f.offset != u32::MAX)
.map(|(f, fd)| {
let name = if f.file != Module::default() {
@ -245,8 +245,8 @@ impl Backend for HbvmBackend {
types
.ins
.globals
.iter()
.zip(self.globals.iter())
.values()
.zip(self.globals.values())
.filter(|(_, g)| g.offset != u32::MAX)
.map(|(g, gd)| {
let name = if g.file == Module::default() {

View file

@ -4258,24 +4258,43 @@ impl<'a> Codegen<'a> {
"the simbol name is limmited to 63 characters, please don't import java",
);
};
name
} else {
name
};
let func = FuncData {
file: sc.file,
parent: sc.parent,
name,
pos,
sig,
expr: ExprRef::new(expr),
is_inline: sc.is_ct,
is_generic: false,
is_import: true,
comp_state: [CompState::Compiled.into(); 2],
};
self.tys.ins.funcs.push(func).into()
if let Some(f) = self
.tys
.ins
.funcs
.values()
.find(|f| f.name == name && f.is_import && f.pos != pos)
{
self.error_low(sc.file, pos, "second import of this symbol");
self.error_low(sc.file, f.pos, "...previous occured here");
}
*self.tys.syms.get_or_insert(
SymKey::Import(sc.parent, name),
&mut self.tys.ins,
|ins| {
ins.funcs
.push(FuncData {
file: sc.file,
parent: sc.parent,
name,
pos,
sig,
expr: ExprRef::new(expr),
is_inline: sc.is_ct,
is_generic: false,
is_import: true,
comp_state: [CompState::Compiled.into(); 2],
})
.into()
},
)
}
Expr::Closure { pos, args, ret, .. } if let Some(name) = sc.name => {
match self.try_parse_concrete_signature(pos, sc, args, ret) {

View file

@ -143,6 +143,8 @@ impl crate::ctx_map::CtxEntry for Id {
let fc = &ctx.funcs[f];
if fc.is_generic {
SymKey::Type(fc.parent, fc.pos, fc.sig.args)
} else if fc.is_import {
SymKey::Import(fc.parent, fc.name)
} else {
SymKey::Decl(fc.parent, fc.name)
}
@ -643,6 +645,8 @@ pub enum SymKey<'a> {
Optional(&'a OptData),
Type(Id, Pos, List),
Decl(Id, Ident),
// separate to avoid colision with decl
Import(Id, Ident),
Array(&'a ArrayData),
Constant(&'a ConstData),
}

View file

@ -646,7 +646,7 @@ impl<K: Ent, T> EntVec<K, T> {
}
}
pub fn iter(&self) -> core::slice::Iter<T> {
pub fn values(&self) -> core::slice::Iter<T> {
self.data.iter()
}
}