forked from AbleOS/holey-bytes
making compiler a bit smarter about evaluating types (more shortcuts)
This commit is contained in:
parent
d293e02f62
commit
b2254e9820
|
@ -736,9 +736,17 @@ impl Codegen {
|
|||
fn build_struct(
|
||||
&mut self,
|
||||
file: FileId,
|
||||
pos: Option<Pos>,
|
||||
explicit_alignment: Option<u8>,
|
||||
fields: &[CommentOr<StructField>],
|
||||
) -> ty::Struct {
|
||||
let sym = pos.map(|pos| SymKey::Struct(file, pos));
|
||||
if let Some(ref sym) = sym
|
||||
&& let Some(&ty) = self.tys.syms.get(sym)
|
||||
{
|
||||
return ty.expand().inner();
|
||||
}
|
||||
|
||||
let prev_tmp = self.tys.fields_tmp.len();
|
||||
for sf in fields.iter().filter_map(CommentOr::or) {
|
||||
let f = Field { name: self.tys.field_names.intern(sf.name), ty: self.ty(&sf.ty) };
|
||||
|
@ -752,6 +760,12 @@ impl Codegen {
|
|||
});
|
||||
self.tys.fields.extend(self.tys.fields_tmp.drain(prev_tmp..));
|
||||
|
||||
if let Some(sym) = sym {
|
||||
self.tys
|
||||
.syms
|
||||
.insert(sym, ty::Kind::Struct(self.tys.structs.len() as u32 - 1).compress());
|
||||
}
|
||||
|
||||
self.tys.structs.len() as u32 - 1
|
||||
}
|
||||
|
||||
|
@ -759,11 +773,12 @@ impl Codegen {
|
|||
use {Expr as E, TokenKind as T};
|
||||
let value = match *expr {
|
||||
E::Mod { id, .. } => Some(Value::ty(ty::Kind::Module(id).compress())),
|
||||
E::Struct { captured, packed, fields, .. } => {
|
||||
E::Struct { captured, packed, fields, pos, .. } => {
|
||||
if captured.is_empty() {
|
||||
Some(Value::ty(
|
||||
ty::Kind::Struct(self.build_struct(
|
||||
self.ci.file,
|
||||
Some(pos),
|
||||
packed.then_some(1),
|
||||
fields,
|
||||
))
|
||||
|
@ -902,7 +917,7 @@ impl Codegen {
|
|||
self.ci.file = prev_file;
|
||||
self.ci.ret = prev_ret;
|
||||
|
||||
let mut vars = std::mem::take(&mut self.ci.vars);
|
||||
let mut vars = core::mem::take(&mut self.ci.vars);
|
||||
for var in vars.drain(scope..) {
|
||||
self.ci.free_loc(var.value.loc);
|
||||
}
|
||||
|
@ -1204,7 +1219,7 @@ impl Codegen {
|
|||
ty::Kind::Builtin(ty::TYPE) => {
|
||||
self.ci.free_loc(tal.loc);
|
||||
self.ci.revert(checkpoint);
|
||||
match ty::Kind::from_ty(self.ty(target)) {
|
||||
match self.ty(target).expand() {
|
||||
ty::Kind::Module(idx) => {
|
||||
match self.find_or_declare(target.pos(), idx, Err(field), "") {
|
||||
ty::Kind::Global(idx) => self.handle_global(idx),
|
||||
|
@ -1393,17 +1408,12 @@ impl Codegen {
|
|||
let loc = var.value.loc.as_ref();
|
||||
Some(Value { ty: self.ci.vars[var_index].value.ty, loc })
|
||||
}
|
||||
E::Ident { id, name, .. } => match self
|
||||
.tys
|
||||
.syms
|
||||
.get(&SymKey { ident: id, file: self.ci.file })
|
||||
.copied()
|
||||
.map(ty::Kind::from_ty)
|
||||
.unwrap_or_else(|| self.find_or_declare(ident::pos(id), self.ci.file, Ok(id), name))
|
||||
{
|
||||
ty::Kind::Global(id) => self.handle_global(id),
|
||||
tk => Some(Value::ty(tk.compress())),
|
||||
},
|
||||
E::Ident { id, name, .. } => {
|
||||
match self.find_or_declare(ident::pos(id), self.ci.file, Ok(id), name) {
|
||||
ty::Kind::Global(id) => self.handle_global(id),
|
||||
tk => Some(Value::ty(tk.compress())),
|
||||
}
|
||||
}
|
||||
E::Return { pos, val, .. } => {
|
||||
let size = self.ci.ret.map_or(17, |ty| self.tys.size_of(ty));
|
||||
let loc = match size {
|
||||
|
@ -1767,7 +1777,7 @@ impl Codegen {
|
|||
let args = self.pack_args(pos, arg_base);
|
||||
let ret = self.ty(ret);
|
||||
|
||||
let sym = SymKey { file: !args.repr(), ident: ty::Kind::Func(*func).compress().repr() };
|
||||
let sym = SymKey::FuncInst(*func, args);
|
||||
let ct = || {
|
||||
let func_id = self.tys.funcs.len();
|
||||
let fuc = &self.tys.funcs[*func as usize];
|
||||
|
@ -2125,7 +2135,7 @@ impl Codegen {
|
|||
self.report(body.pos(), "expected all paths in the fucntion to return");
|
||||
}
|
||||
|
||||
let mut vars = std::mem::take(&mut self.ci.vars);
|
||||
let mut vars = core::mem::take(&mut self.ci.vars);
|
||||
for var in vars.drain(..) {
|
||||
self.ci.free_loc(var.value.loc);
|
||||
}
|
||||
|
@ -2350,9 +2360,18 @@ impl Codegen {
|
|||
}
|
||||
|
||||
fn ty(&mut self, expr: &Expr) -> ty::Id {
|
||||
self.tys
|
||||
.ty(self.ci.file, expr, &self.files)
|
||||
.unwrap_or_else(|| ty::Id::from(self.eval_const(expr, ty::TYPE)))
|
||||
let ty = self.tys.ty(self.ci.file, expr, &self.files);
|
||||
let evaled_ty = ty::Id::from(self.eval_const(expr, ty::TYPE));
|
||||
if let Some(ty) = ty {
|
||||
debug_assert_eq!(
|
||||
ty,
|
||||
evaled_ty,
|
||||
"{} {}",
|
||||
self.ty_display(ty),
|
||||
self.ty_display(evaled_ty)
|
||||
);
|
||||
}
|
||||
evaled_ty
|
||||
}
|
||||
|
||||
fn read_trap(addr: u64) -> Option<&'static trap::Trap> {
|
||||
|
@ -2395,15 +2414,19 @@ impl Codegen {
|
|||
});
|
||||
}
|
||||
|
||||
let stru =
|
||||
ty::Kind::Struct(self.build_struct(self.ci.file, packed.then_some(1), fields))
|
||||
.compress();
|
||||
let stru = ty::Kind::Struct(self.build_struct(
|
||||
self.ci.file,
|
||||
packed.then_some(1),
|
||||
None,
|
||||
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() };
|
||||
let sym = SymKey::MomizedCall(func);
|
||||
if let Some(&ty) = self.tys.syms.get(&sym) {
|
||||
self.ct.vm.write_reg(1, ty.repr());
|
||||
} else {
|
||||
|
@ -2426,6 +2449,10 @@ impl Codegen {
|
|||
lit_name: &str,
|
||||
) -> ty::Kind {
|
||||
log::trace!("find_or_declare: {lit_name} {file}");
|
||||
if let Some(ty) = self.tys.find_type(file, name, &self.files) {
|
||||
return ty.expand();
|
||||
}
|
||||
|
||||
let f = self.files[file as usize].clone();
|
||||
let Some((expr, ident)) = f.find_decl(name) else {
|
||||
match name {
|
||||
|
@ -2435,7 +2462,8 @@ impl Codegen {
|
|||
}
|
||||
};
|
||||
|
||||
if let Some(existing) = self.tys.syms.get(&SymKey { file, ident }) {
|
||||
let key = SymKey::Decl(file, ident);
|
||||
if let Some(existing) = self.tys.syms.get(&key) {
|
||||
if let ty::Kind::Func(id) = existing.expand()
|
||||
&& let func = &mut self.tys.funcs[id as usize]
|
||||
&& let Err(idx) = task::unpack(func.offset)
|
||||
|
@ -2517,7 +2545,7 @@ impl Codegen {
|
|||
e => unimplemented!("{e:#?}"),
|
||||
};
|
||||
self.ci.file = prev_file;
|
||||
self.tys.syms.insert(SymKey { ident, file }, sym.compress());
|
||||
self.tys.syms.insert(key, sym.compress());
|
||||
sym
|
||||
}
|
||||
|
||||
|
@ -2552,7 +2580,7 @@ impl Codegen {
|
|||
|
||||
self.ci.free_loc(ret.loc);
|
||||
|
||||
Global { ty: ret.ty, file, name, data, ..Default::default() }
|
||||
Global { ty: ret.ty, file, name, data, ast: ExprRef::new(expr), ..Default::default() }
|
||||
}
|
||||
|
||||
fn ct_eval<T, E>(
|
||||
|
@ -2579,8 +2607,8 @@ impl Codegen {
|
|||
let last_fn = self.tys.funcs.len();
|
||||
self.tys.funcs.push(Default::default());
|
||||
|
||||
self.tys.funcs[last_fn].code = std::mem::take(&mut self.ci.code);
|
||||
self.tys.funcs[last_fn].relocs = std::mem::take(&mut self.ci.relocs);
|
||||
self.tys.funcs[last_fn].code = core::mem::take(&mut self.ci.code);
|
||||
self.tys.funcs[last_fn].relocs = core::mem::take(&mut self.ci.relocs);
|
||||
|
||||
if is_on_stack {
|
||||
let size =
|
||||
|
|
|
@ -31,12 +31,12 @@ use {
|
|||
self::{
|
||||
ident::Ident,
|
||||
lexer::TokenKind,
|
||||
parser::{CommentOr, Expr, ExprRef, FileId},
|
||||
parser::{CommentOr, Expr, ExprRef, FileId, Pos},
|
||||
son::reg,
|
||||
ty::ArrayLen,
|
||||
},
|
||||
alloc::{collections::BTreeMap, string::String, vec::Vec},
|
||||
core::{cell::Cell, fmt::Display, hash::BuildHasher, ops::Range},
|
||||
core::{cell::Cell, fmt::Display, hash::BuildHasher, ops::Range, usize},
|
||||
hashbrown::hash_map,
|
||||
hbbytecode as instrs,
|
||||
};
|
||||
|
@ -124,7 +124,7 @@ mod ty {
|
|||
lexer::TokenKind,
|
||||
parser::{self},
|
||||
},
|
||||
core::{num::NonZeroU32, ops::Range},
|
||||
core::{num::NonZeroU32, ops::Range, usize},
|
||||
};
|
||||
|
||||
pub type ArrayLen = u32;
|
||||
|
@ -137,7 +137,7 @@ mod ty {
|
|||
pub type Module = u32;
|
||||
pub type Slice = u32;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
|
||||
pub struct Tuple(pub u32);
|
||||
|
||||
impl Tuple {
|
||||
|
@ -384,7 +384,7 @@ mod ty {
|
|||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
use Kind as TK;
|
||||
match TK::from_ty(self.ty) {
|
||||
TK::Module(idx) => write!(f, "module{}", idx),
|
||||
TK::Module(idx) => write!(f, "@use({:?})[{}]", self.files[idx as usize].path, idx),
|
||||
TK::Builtin(ty) => write!(f, "{}", to_str(ty)),
|
||||
TK::Ptr(ty) => {
|
||||
write!(f, "^{}", self.rety(self.tys.ptrs[ty as usize].base))
|
||||
|
@ -443,15 +443,14 @@ fn emit(out: &mut Vec<u8>, (len, instr): EncodedInstr) {
|
|||
}
|
||||
|
||||
#[derive(PartialEq, Eq, Hash, Debug)]
|
||||
struct SymKey {
|
||||
file: u32,
|
||||
ident: u32,
|
||||
}
|
||||
|
||||
impl SymKey {
|
||||
pub fn pointer_to(ty: ty::Id) -> Self {
|
||||
Self { file: u32::MAX, ident: ty.repr() }
|
||||
}
|
||||
enum SymKey {
|
||||
Pointer(ty::Id),
|
||||
Struct(FileId, Pos),
|
||||
FuncInst(ty::Func, ty::Tuple),
|
||||
MomizedCall(ty::Func),
|
||||
Decl(FileId, Ident),
|
||||
Slice(ty::Id),
|
||||
Array(ty::Id, ArrayLen),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
|
@ -492,6 +491,7 @@ struct Global {
|
|||
file: FileId,
|
||||
name: Ident,
|
||||
ty: ty::Id,
|
||||
ast: ExprRef,
|
||||
offset: Offset,
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
@ -502,6 +502,7 @@ impl Default for Global {
|
|||
ty: Default::default(),
|
||||
offset: u32::MAX,
|
||||
data: Default::default(),
|
||||
ast: ExprRef::default(),
|
||||
file: u32::MAX,
|
||||
name: u32::MAX,
|
||||
}
|
||||
|
@ -690,35 +691,68 @@ impl Types {
|
|||
&self.fields[self.struct_field_range(strct)]
|
||||
}
|
||||
|
||||
fn find_type(
|
||||
&mut self,
|
||||
file: FileId,
|
||||
id: Result<Ident, &str>,
|
||||
files: &[parser::Ast],
|
||||
) -> Option<ty::Id> {
|
||||
if let Ok(id) = id
|
||||
&& let Some(&ty) = self.syms.get(&SymKey::Decl(file, id))
|
||||
{
|
||||
if let ty::Kind::Global(g) = ty.expand() {
|
||||
let g = &self.globals[g as usize];
|
||||
if g.ty == ty::Id::TYPE {
|
||||
return Some(ty::Id::from(
|
||||
u32::from_ne_bytes(*g.data.first_chunk().unwrap()) as u64
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
return Some(ty);
|
||||
}
|
||||
|
||||
let f = &files[file as usize];
|
||||
let (Expr::BinOp { left, right, .. }, name) = f.find_decl(id)? else { unreachable!() };
|
||||
|
||||
let ty = left
|
||||
.find_pattern_path(name, right, |right| self.ty(file, right, files))
|
||||
.unwrap_or_else(|_| unreachable!())?;
|
||||
if let ty::Kind::Struct(s) = ty.expand() {
|
||||
self.structs[s as usize].name = name;
|
||||
}
|
||||
|
||||
self.syms.insert(SymKey::Decl(file, name), ty);
|
||||
Some(ty)
|
||||
}
|
||||
|
||||
/// returns none if comptime eval is required
|
||||
fn ty(&mut self, file: FileId, expr: &Expr, files: &[parser::Ast]) -> Option<ty::Id> {
|
||||
Some(match *expr {
|
||||
Expr::Mod { id, .. } => ty::Kind::Module(id).compress(),
|
||||
Expr::UnOp { op: TokenKind::Xor, val, .. } => {
|
||||
let base = self.ty(file, val, files)?;
|
||||
self.make_ptr(base)
|
||||
}
|
||||
Expr::Ident { id, .. } if ident::is_null(id) => id.into(),
|
||||
Expr::Ident { id, .. } => {
|
||||
let f = &files[file as usize];
|
||||
let (Expr::BinOp { right, .. }, name) = f.find_decl(Ok(id))? else {
|
||||
unreachable!()
|
||||
Expr::Ident { id, .. } => self.find_type(file, Ok(id), files)?,
|
||||
Expr::Field { target, name, .. } => {
|
||||
let ty::Kind::Module(file) = self.ty(file, target, files)?.expand() else {
|
||||
return None;
|
||||
};
|
||||
let ty = self.ty(file, right, files)?;
|
||||
if let ty::Kind::Struct(s) = ty.expand() {
|
||||
self.structs[s as usize].name = name;
|
||||
}
|
||||
ty
|
||||
|
||||
self.find_type(file, Err(name), files)?
|
||||
}
|
||||
Expr::Slice { size: None, item, .. } => {
|
||||
let ty = self.ty(file, item, files)?;
|
||||
self.make_array(ty, ArrayLen::MAX)
|
||||
}
|
||||
//Expr::Slice { size: Some(&Expr::Number { value, .. }), item, .. } => {
|
||||
// let ty = self.ty(file, item, files)?;
|
||||
// self.make_array(ty, value as _)
|
||||
//}
|
||||
Expr::Slice { size: Some(&Expr::Number { value, .. }), item, .. } => {
|
||||
let ty = self.ty(file, item, files)?;
|
||||
self.make_array(ty, value as _)
|
||||
}
|
||||
Expr::Struct { pos, fields, packed, .. } => {
|
||||
let sym = SymKey { file, ident: pos };
|
||||
let sym = SymKey::Struct(file, pos);
|
||||
if let Some(&ty) = self.syms.get(&sym) {
|
||||
return Some(ty);
|
||||
}
|
||||
|
@ -875,10 +909,8 @@ impl Types {
|
|||
}
|
||||
|
||||
fn make_ptr_low(&mut self, base: ty::Id) -> ty::Ptr {
|
||||
let id = SymKey::pointer_to(base);
|
||||
|
||||
self.syms
|
||||
.entry(id)
|
||||
.entry(SymKey::Pointer(base))
|
||||
.or_insert_with(|| {
|
||||
self.ptrs.push(Ptr { base });
|
||||
ty::Kind::Ptr(self.ptrs.len() as u32 - 1).compress()
|
||||
|
@ -892,16 +924,8 @@ impl Types {
|
|||
}
|
||||
|
||||
fn make_array_low(&mut self, ty: ty::Id, len: ArrayLen) -> ty::Slice {
|
||||
let id = SymKey {
|
||||
file: match len {
|
||||
ArrayLen::MAX => ArrayLen::MAX - 1,
|
||||
len => ArrayLen::MAX - len - 2,
|
||||
},
|
||||
ident: ty.repr(),
|
||||
};
|
||||
|
||||
self.syms
|
||||
.entry(id)
|
||||
.entry(SymKey::Array(ty, len))
|
||||
.or_insert_with(|| {
|
||||
self.arrays.push(Array { ty, len });
|
||||
ty::Kind::Slice(self.arrays.len() as u32 - 1).compress()
|
||||
|
|
|
@ -7,12 +7,12 @@ use {
|
|||
core::{
|
||||
cell::UnsafeCell,
|
||||
fmt::{self},
|
||||
intrinsics::unlikely,
|
||||
marker::PhantomData,
|
||||
ops::Deref,
|
||||
ptr::NonNull,
|
||||
sync::atomic::AtomicUsize,
|
||||
},
|
||||
std::intrinsics::unlikely,
|
||||
};
|
||||
|
||||
pub type Pos = u32;
|
||||
|
@ -54,6 +54,7 @@ pub struct Symbol {
|
|||
struct ScopeIdent {
|
||||
ident: Ident,
|
||||
declared: bool,
|
||||
ordered: bool,
|
||||
flags: IdentFlags,
|
||||
}
|
||||
|
||||
|
@ -195,7 +196,9 @@ impl<'a, 'b> Parser<'a, 'b> {
|
|||
|
||||
fn declare_rec(&mut self, expr: &Expr, top_level: bool) {
|
||||
match *expr {
|
||||
Expr::Ident { pos, id, is_first, .. } => self.declare(pos, id, is_first || top_level),
|
||||
Expr::Ident { pos, id, is_first, .. } => {
|
||||
self.declare(pos, id, !top_level, is_first || top_level)
|
||||
}
|
||||
Expr::Ctor { fields, .. } => {
|
||||
for CtorField { value, .. } in fields {
|
||||
self.declare_rec(value, top_level)
|
||||
|
@ -205,7 +208,7 @@ impl<'a, 'b> Parser<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
fn declare(&mut self, pos: Pos, id: Ident, valid_order: bool) {
|
||||
fn declare(&mut self, pos: Pos, id: Ident, ordered: bool, valid_order: bool) {
|
||||
if !valid_order {
|
||||
self.report(
|
||||
pos,
|
||||
|
@ -223,6 +226,8 @@ impl<'a, 'b> Parser<'a, 'b> {
|
|||
format_args!("redeclaration of identifier: {}", self.lexer.slice(ident::range(id))),
|
||||
)
|
||||
}
|
||||
|
||||
self.idents[index].ordered = ordered;
|
||||
}
|
||||
|
||||
fn resolve_ident(&mut self, token: Token) -> (Ident, bool) {
|
||||
|
@ -242,13 +247,18 @@ impl<'a, 'b> Parser<'a, 'b> {
|
|||
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.push(ScopeIdent {
|
||||
ident: id,
|
||||
declared: false,
|
||||
ordered: false,
|
||||
flags: 0,
|
||||
});
|
||||
(self.idents.len() - 1, self.idents.last_mut().unwrap(), true)
|
||||
}
|
||||
};
|
||||
|
||||
id.flags |= idfl::COMPTIME * is_ct as u32;
|
||||
if id.declared && self.ns_bound > i {
|
||||
if id.declared && id.ordered && self.ns_bound > i {
|
||||
id.flags |= idfl::COMPTIME;
|
||||
self.captured.push(id.ident);
|
||||
}
|
||||
|
@ -374,7 +384,7 @@ impl<'a, 'b> Parser<'a, 'b> {
|
|||
self.collect_list(T::Comma, T::RParen, |s| {
|
||||
let name = s.advance_ident();
|
||||
let (id, _) = s.resolve_ident(name);
|
||||
s.declare(name.start, id, true);
|
||||
s.declare(name.start, id, true, true);
|
||||
s.expect_advance(T::Colon);
|
||||
Arg {
|
||||
pos: name.start,
|
||||
|
@ -839,17 +849,14 @@ impl<'a> Expr<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn find_pattern_path<F: FnOnce(&Expr)>(
|
||||
pub fn find_pattern_path<T, F: FnOnce(&Expr) -> T>(
|
||||
&self,
|
||||
ident: Ident,
|
||||
target: &Expr,
|
||||
mut with_final: F,
|
||||
) -> Result<(), F> {
|
||||
) -> Result<T, F> {
|
||||
match *self {
|
||||
Self::Ident { id, .. } if id == ident => {
|
||||
with_final(target);
|
||||
Ok(())
|
||||
}
|
||||
Self::Ident { id, .. } if id == ident => Ok(with_final(target)),
|
||||
Self::Ctor { fields, .. } => {
|
||||
for &CtorField { name, value, pos } in fields {
|
||||
match value.find_pattern_path(
|
||||
|
@ -857,7 +864,7 @@ impl<'a> Expr<'a> {
|
|||
&Expr::Field { pos, target, name },
|
||||
with_final,
|
||||
) {
|
||||
Ok(()) => return Ok(()),
|
||||
Ok(value) => return Ok(value),
|
||||
Err(e) => with_final = e,
|
||||
}
|
||||
}
|
||||
|
@ -1457,7 +1464,7 @@ impl StackAlloc {
|
|||
|
||||
unsafe fn push<T: Copy>(&mut self, _view: &mut StackAllocView<T>, value: T) {
|
||||
if unlikely(self.len + core::mem::size_of::<T>() > self.cap) {
|
||||
let next_cap = self.cap.max(16 * 32).max(std::mem::size_of::<T>()) * 2;
|
||||
let next_cap = self.cap.max(16 * 32).max(core::mem::size_of::<T>()) * 2;
|
||||
if self.cap == 0 {
|
||||
let layout =
|
||||
core::alloc::Layout::from_size_align_unchecked(next_cap, Self::MAX_ALIGN);
|
||||
|
@ -1471,15 +1478,7 @@ impl StackAlloc {
|
|||
}
|
||||
|
||||
let dst = self.data.add(self.len) as *mut T;
|
||||
debug_assert!(
|
||||
dst.is_aligned(),
|
||||
"{:?} {:?} {} {} {}",
|
||||
dst,
|
||||
std::mem::size_of::<T>(),
|
||||
std::mem::align_of::<T>(),
|
||||
self.len,
|
||||
self.cap
|
||||
);
|
||||
debug_assert!(dst.is_aligned(),);
|
||||
self.len += core::mem::size_of::<T>();
|
||||
core::ptr::write(dst, value);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ use {
|
|||
},
|
||||
hashbrown::hash_map,
|
||||
regalloc2::VReg,
|
||||
std::process::id,
|
||||
};
|
||||
|
||||
const VOID: Nid = 0;
|
||||
|
@ -2016,6 +2017,9 @@ impl Codegen {
|
|||
lit_name: &str,
|
||||
) -> ty::Kind {
|
||||
log::trace!("find_or_declare: {lit_name} {file}");
|
||||
if let Some(ty) = self.tys.find_type(file, name.ok_or(lit_name), &self.files) {
|
||||
return ty.expand();
|
||||
}
|
||||
|
||||
let f = self.files[file as usize].clone();
|
||||
let Some((expr, ident)) = f.find_decl(name.ok_or(lit_name)) else {
|
||||
|
@ -2037,7 +2041,8 @@ impl Codegen {
|
|||
return ty::Kind::Builtin(ty::NEVER);
|
||||
};
|
||||
|
||||
if let Some(existing) = self.tys.syms.get(&SymKey { file, ident }) {
|
||||
let key = SymKey::Decl(file, ident);
|
||||
if let Some(existing) = self.tys.syms.get(&key) {
|
||||
if let ty::Kind::Func(id) = existing.expand()
|
||||
&& let func = &mut self.tys.funcs[id as usize]
|
||||
&& let Err(idx) = task::unpack(func.offset)
|
||||
|
@ -2099,7 +2104,7 @@ impl Codegen {
|
|||
e => unimplemented!("{e:#?}"),
|
||||
};
|
||||
self.ci.file = prev_file;
|
||||
self.tys.syms.insert(SymKey { ident, file }, sym.compress());
|
||||
self.tys.syms.insert(key, sym.compress());
|
||||
sym
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue