mirror of https://github.com/boa-dev/boa.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
77 lines
2.5 KiB
77 lines
2.5 KiB
2 years ago
|
//! String interner for Boa.
|
||
|
//!
|
||
|
//! The idea behind using a string interner is that in most of the code, strings such as
|
||
|
//! identifiers and literals are often repeated. This causes extra burden when comparing them and
|
||
|
//! storing them. A string interner stores a unique `usize` symbol for each string, making sure
|
||
|
//! that there are no duplicates. This makes it much easier to compare, since it's just comparing
|
||
|
//! to `usize`, and also it's easier to store, since instead of a heap-allocated string, you only
|
||
|
//! need to store a `usize`. This reduces memory consumption and improves performance in the
|
||
|
//! compiler.
|
||
|
|
||
|
#![doc(
|
||
|
html_logo_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg",
|
||
|
html_favicon_url = "https://raw.githubusercontent.com/boa-dev/boa/main/assets/logo.svg"
|
||
|
)]
|
||
|
#![deny(
|
||
|
clippy::all,
|
||
|
unused_qualifications,
|
||
|
unused_import_braces,
|
||
|
unused_lifetimes,
|
||
|
unreachable_pub,
|
||
|
trivial_numeric_casts,
|
||
|
// rustdoc,
|
||
|
missing_debug_implementations,
|
||
|
missing_copy_implementations,
|
||
|
deprecated_in_future,
|
||
|
meta_variable_misuse,
|
||
|
non_ascii_idents,
|
||
|
rust_2018_compatibility,
|
||
|
rust_2018_idioms,
|
||
|
future_incompatible,
|
||
|
nonstandard_style,
|
||
|
)]
|
||
|
#![warn(clippy::perf, clippy::single_match_else, clippy::dbg_macro)]
|
||
|
#![allow(
|
||
|
clippy::missing_inline_in_public_items,
|
||
|
clippy::cognitive_complexity,
|
||
|
clippy::must_use_candidate,
|
||
|
clippy::missing_errors_doc,
|
||
|
clippy::as_conversions,
|
||
|
clippy::let_unit_value,
|
||
|
rustdoc::missing_doc_code_examples
|
||
|
)]
|
||
|
|
||
|
use std::num::NonZeroUsize;
|
||
|
|
||
|
#[cfg(feature = "serde")]
|
||
|
use serde::{Deserialize, Serialize};
|
||
|
use string_interner::{backend::BucketBackend, StringInterner, Symbol};
|
||
|
|
||
|
/// The string interner for Boa.
|
||
|
///
|
||
|
/// This is a type alias that makes it easier to reference it in the code.
|
||
|
pub type Interner = StringInterner<BucketBackend<Sym>>;
|
||
|
|
||
|
/// The string symbol type for Boa.
|
||
|
///
|
||
|
/// This symbol type is internally a `NonZeroUsize`, which makes it pointer-width in size and it's
|
||
|
/// optimized so that it can ocupy 1 pointer width even in an `Option` type.
|
||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||
|
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
|
||
|
#[cfg_attr(feature = "serde", serde(transparent))]
|
||
|
pub struct Sym {
|
||
|
value: NonZeroUsize,
|
||
|
}
|
||
|
|
||
|
impl Symbol for Sym {
|
||
|
#[inline]
|
||
|
fn try_from_usize(index: usize) -> Option<Self> {
|
||
|
NonZeroUsize::new(index.wrapping_add(1)).map(|value| Self { value })
|
||
|
}
|
||
|
|
||
|
#[inline]
|
||
|
fn to_usize(self) -> usize {
|
||
|
self.value.get() - 1
|
||
|
}
|
||
|
}
|