(self, mc: &Mutation<'gc>, s: &[u8])
| 271 | } |
| 272 | |
| 273 | fn intern(self, mc: &Mutation<'gc>, s: &[u8]) -> InternedString<'gc> { |
| 274 | // SAFETY: If a new string is added, we call the write barrier. |
| 275 | let mut dyn_strings = unsafe { self.0.0.unlock_unchecked() }.borrow_mut(); |
| 276 | |
| 277 | // SAFETY: The RawTable outlives the iterator |
| 278 | unsafe { |
| 279 | for bucket in dyn_strings.iter_hash(str_hash(s)) { |
| 280 | let (key, _) = *bucket.as_ref(); |
| 281 | if let Some(st) = key.upgrade(mc).map(InternedString::from_inner) { |
| 282 | if st == s { |
| 283 | return st; |
| 284 | } |
| 285 | } else { |
| 286 | // SAFETY: it is okay to erase items yielded by the iterator. |
| 287 | dyn_strings.erase(bucket); |
| 288 | } |
| 289 | } |
| 290 | } |
| 291 | |
| 292 | // SAFETY: We are going to modify the dyn_strings table, so call the write barrier. |
| 293 | Gc::write(mc, self.0); |
| 294 | |
| 295 | let s = InternedString::from_slice(mc, s); |
| 296 | dyn_strings.insert( |
| 297 | s.stored_hash(), |
| 298 | (Gc::downgrade(s.into_inner()), s.stored_hash()), |
| 299 | |(_, hash)| *hash, |
| 300 | ); |
| 301 | |
| 302 | s |
| 303 | } |
| 304 | } |
| 305 | |
| 306 | #[derive(Copy, Clone, Collect)] |
no test coverage detected