Properly deduplicating imported functions
Signed-off-by: Jakub Doka <jakub.doka2@gmail.com>
This commit is contained in:
parent
da5bd3d36a
commit
8aee4f2890
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue