Skip to content

Commit

Permalink
Implement custom string interner
Browse files Browse the repository at this point in the history
  • Loading branch information
jedel1043 committed Jun 28, 2022
1 parent ce8c6e2 commit a33e8aa
Show file tree
Hide file tree
Showing 6 changed files with 321 additions and 262 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions boa_interner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ license = "Unlicense/MIT"
string-interner = "0.14.0"
serde = { version = "1.0.137", features = ["derive"], optional = true }
gc = { version = "0.4.1", features = ["derive"] }
phf = { version = "0.10.1", features = ["macros"] }
rustc-hash = "1.1.0"
70 changes: 70 additions & 0 deletions boa_interner/src/interned_str.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use std::{borrow::Borrow, ptr::NonNull};

/// Wrapper for an interned str pointer, required to
/// quickly check using a hash if a string is inside an [`Interner`].
///
/// # Safety
///
/// This struct could cause Undefined Behaviour on:
/// - Use without ensuring the referenced memory is still allocated.
/// - Construction of an [`InternedStr`] from an invalid [`NonNull<str>`].
///
/// In general, this should not be used outside of an [`Interner`].
#[derive(Debug, Clone)]
pub(super) struct InternedStr {
ptr: NonNull<str>,
}

impl InternedStr {
/// Create a new interned string from the given `str`.
///
/// # Safety
///
/// Not maintaining the invariants specified on the struct definition
/// could cause Undefined Behaviour.
#[inline]
pub(super) unsafe fn new(ptr: NonNull<str>) -> Self {
Self { ptr }
}

/// Returns a shared reference to the underlying string.
///
/// # Safety
///
/// Not maintaining the invariants specified on the struct definition
/// could cause Undefined Behaviour.
#[inline]
pub(super) unsafe fn as_str(&self) -> &str {
// SAFETY: The user must verify the invariants
// specified on the struct definition.
unsafe { self.ptr.as_ref() }
}
}

impl std::hash::Hash for InternedStr {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
// SAFETY: The user must verify the invariants
// specified in the struct definition.
unsafe {
self.as_str().hash(state);
}
}
}

impl Eq for InternedStr {}

impl PartialEq for InternedStr {
fn eq(&self, other: &Self) -> bool {
// SAFETY: The user must verify the invariants
// specified in the struct definition.
unsafe { self.as_str() == other.as_str() }
}
}

impl Borrow<str> for InternedStr {
fn borrow(&self) -> &str {
// SAFETY: The user must verify the invariants
// specified in the struct definition.
unsafe { self.as_str() }
}
}
Loading

0 comments on commit a33e8aa

Please sign in to comment.