diff --git a/cranelift-backend/src/lib.rs b/cranelift-backend/src/lib.rs index 0d9418c..3c3002a 100644 --- a/cranelift-backend/src/lib.rs +++ b/cranelift-backend/src/lib.rs @@ -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, ) { - 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(); } } diff --git a/lang/src/backend/hbvm.rs b/lang/src/backend/hbvm.rs index 52ffe59..805d0af 100644 --- a/lang/src/backend/hbvm.rs +++ b/lang/src/backend/hbvm.rs @@ -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() { diff --git a/lang/src/son.rs b/lang/src/son.rs index ec8fab4..bdff748 100644 --- a/lang/src/son.rs +++ b/lang/src/son.rs @@ -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) { diff --git a/lang/src/ty.rs b/lang/src/ty.rs index 1b99de7..22f1979 100644 --- a/lang/src/ty.rs +++ b/lang/src/ty.rs @@ -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), } diff --git a/lang/src/utils.rs b/lang/src/utils.rs index 0a9bdb4..6c45399 100644 --- a/lang/src/utils.rs +++ b/lang/src/utils.rs @@ -646,7 +646,7 @@ impl EntVec { } } - pub fn iter(&self) -> core::slice::Iter { + pub fn values(&self) -> core::slice::Iter { self.data.iter() } }