From 632729af52d0ae8e07b66baae0d868457a566ad2 Mon Sep 17 00:00:00 2001 From: Janis Date: Sun, 22 Dec 2024 23:52:39 +0100 Subject: [PATCH] InternPool bytes make intern::Index a bit safer/clearer to use added bytes to internpool more helper functions for interning numbers/bytes/strings --- src/ast2/intern.rs | 82 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/src/ast2/intern.rs b/src/ast2/intern.rs index 9386d29..59fc884 100644 --- a/src/ast2/intern.rs +++ b/src/ast2/intern.rs @@ -73,6 +73,9 @@ pub enum Key<'a> { String { str: &'a str, }, + Bytes { + bytes: &'a [u8], + }, SIntSmall { bits: i32, }, @@ -136,6 +139,7 @@ impl Hash for Key<'_> { core::mem::discriminant(self).hash(state); match self { Key::String { str } => str.hash(state), + Key::Bytes { bytes } => bytes.hash(state), Key::SIntSmall { bits } => bits.hash(state), Key::UIntSmall { bits } => bits.hash(state), Key::SInt64 { bits } => bits.hash(state), @@ -270,18 +274,24 @@ impl Item { #[repr(transparent)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct Index(pub u32); +pub struct Index(u32); impl Display for Index { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "#{}", self.0) + write!(f, "#{}", self.index()) } } impl Index { + pub fn new(inner: u32) -> Self { + Self(inner) + } pub fn into_u32(self) -> u32 { unsafe { core::mem::transmute(self) } } + pub fn from_u32(inner: u32) -> Self { + unsafe { core::mem::transmute(inner) } + } pub fn as_u32(&self) -> &u32 { unsafe { core::mem::transmute(self) } } @@ -370,6 +380,8 @@ static_keys!( U128 => Key::UIntType { bit_width: 128 }, TRUE => Key::TrueValue, FALSE => Key::FalseValue, + EMPTY_STRING => Key::String { str: "" }, + EMPTY_BYTES => Key::Bytes { bytes: &[] }, ); impl InternPool { @@ -826,6 +838,13 @@ impl InternPool { let words_idx = self.extend_words([start, len]); self.create_item(Tag::String, words_idx) } + Key::Bytes { bytes } => { + let len = bytes.len() as u32; + let start = self.extend_strings(bytes); + + let words_idx = self.extend_words([start, len]); + self.create_item(Tag::String, words_idx) + } Key::SIntSmall { bits } => { self.create_item(Tag::SIntSmall, bits as u32) } @@ -872,7 +891,7 @@ impl InternPool { } Key::PointerType { pointee, flags } => { let flags = flags.pack(); - let i = self.extend_words([pointee.0, flags as u32]); + let i = self.extend_words([pointee.index(), flags as u32]); self.create_item(Tag::PointerType, i) } Key::ArrayType { @@ -881,7 +900,8 @@ impl InternPool { length, } => { let flags = flags.pack(); - let i = self.extend_words([pointee.0, flags as u32, length]); + let i = + self.extend_words([pointee.index(), flags as u32, length]); self.create_item(Tag::ArrayType, i) } Key::StructType { @@ -922,7 +942,8 @@ impl InternPool { let start = self.push_word(info.pack()); self.extend_words([return_type.into_u32()]); - _ = self.extend_words(parameters.into_iter().map(|i| i.0)); + _ = self + .extend_words(parameters.into_iter().map(|i| i.index())); self.create_item(Tag::FunctionType, start) } @@ -951,7 +972,7 @@ impl InternPool { let len = self.len(); self.tags.push(tag); self.indices.push(index); - Index(len) + Index::new(len) } pub fn get_key(&self, index: Index) -> Key { @@ -1028,14 +1049,14 @@ impl InternPool { } } Tag::PointerType => { - let pointee = Index(self.words[item.idx()]); + let pointee = Index::new(self.words[item.idx()]); let flags = PointerFlags::unpack(self.words[item.idx() + 1] as u8); Key::PointerType { pointee, flags } } Tag::ArrayType => { - let pointee = Index(self.words[item.idx()]); + let pointee = Index::new(self.words[item.idx()]); let flags = PointerFlags::unpack(self.words[item.idx() + 1] as u8); let length = self.words[item.idx() + 2]; @@ -1047,7 +1068,7 @@ impl InternPool { } } Tag::StructType => { - let name = Index(self.words[item.idx()]); + let name = Index::new(self.words[item.idx()]); let decl = super::Index::new(self.words[item.idx() + 1]); let flags = StructFlags::unpack(self.words[item.idx() + 2]); let fields = if flags.num_fields != 0 { @@ -1059,7 +1080,7 @@ impl InternPool { .iter() .cloned() .array_chunks::<2>() - .map(|[n, t]| (Index(n), Index(t))) + .map(|[n, t]| (Index::new(n), Index::new(t))) .collect::>() } else { vec![] @@ -1081,7 +1102,7 @@ impl InternPool { let end = start + len as usize; let params = self.words[start..end] .iter() - .map(|&i| Index(i)) + .map(|&i| Index::new(i)) .collect::>(); ( self.get_assume_present(&Key::SimpleType { @@ -1090,12 +1111,12 @@ impl InternPool { params, ) } else { - let return_type = Index(self.words[item.idx() + 1]); + let return_type = Index::new(self.words[item.idx() + 1]); let start = item.idx() + 2; let end = start + len as usize; let params = self.words[start..end] .iter() - .map(|&i| Index(i)) + .map(|&i| Index::new(i)) .collect::>(); (return_type, params) }; @@ -1131,6 +1152,31 @@ impl InternPool { self.get_or_insert(key) } + pub fn get_unsigned_integer(&mut self, value: u64) -> Index { + let key = match value { + _ if value <= u32::MAX as u64 => { + Key::UIntSmall { bits: value as u32 } + } + _ => Key::UInt64 { bits: value as u64 }, + }; + + self.get_or_insert(key) + } + + pub fn get_bytes_index(&mut self, bytes: &[u8]) -> Index { + self.get_or_insert(Key::Bytes { bytes }) + } + pub fn try_get_bytes_index(&self, bytes: &[u8]) -> Option { + self.try_get_index(&Key::Bytes { bytes }) + } + + pub fn insert_string(&mut self, str: &str) -> Index { + self.get_string_index(str) + } + pub fn insert_bytes(&mut self, bytes: &[u8]) -> Index { + self.get_bytes_index(bytes) + } + pub fn get_string_index(&mut self, str: &str) -> Index { self.get_or_insert(Key::String { str }) } @@ -1287,8 +1333,16 @@ impl InternPool { str } + pub fn get_bytes(&self, index: Index) -> &[u8] { + let key = self.get_key(index); + assert!(matches!(key, Key::Bytes { .. })); + variant!(key => Key::Bytes { bytes }); + + bytes + } + fn check_bounds(&self, index: Index) -> Option { - (index.0 < self.len()).then_some(index) + ((index.index() as u32) < self.len()).then_some(index) } fn get_item(&self, index: Index) -> Option {