153 lines
4.7 KiB
Rust
153 lines
4.7 KiB
Rust
use std::num::NonZeroUsize;
|
|
|
|
#[cfg(feature = "serde")]
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
/// 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 occupy 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))]
|
|
#[allow(clippy::unsafe_derive_deserialize)]
|
|
pub struct Sym {
|
|
value: NonZeroUsize,
|
|
}
|
|
|
|
impl Sym {
|
|
/// Symbol for the empty string (`""`).
|
|
pub const EMPTY_STRING: Self = unsafe { Self::new_unchecked(1) };
|
|
|
|
/// Symbol for the `"arguments"` string.
|
|
pub const ARGUMENTS: Self = unsafe { Self::new_unchecked(2) };
|
|
|
|
/// Symbol for the `"await"` string.
|
|
pub const AWAIT: Self = unsafe { Self::new_unchecked(3) };
|
|
|
|
/// Symbol for the `"yield"` string.
|
|
pub const YIELD: Self = unsafe { Self::new_unchecked(4) };
|
|
|
|
/// Symbol for the `"eval"` string.
|
|
pub const EVAL: Self = unsafe { Self::new_unchecked(5) };
|
|
|
|
/// Symbol for the `"default"` string.
|
|
pub const DEFAULT: Self = unsafe { Self::new_unchecked(6) };
|
|
|
|
/// Symbol for the `"null"` string.
|
|
pub const NULL: Self = unsafe { Self::new_unchecked(7) };
|
|
|
|
/// Symbol for the `"RegExp"` string.
|
|
pub const REGEXP: Self = unsafe { Self::new_unchecked(8) };
|
|
|
|
/// Symbol for the `"get"` string.
|
|
pub const GET: Self = unsafe { Self::new_unchecked(9) };
|
|
|
|
/// Symbol for the `"set"` string.
|
|
pub const SET: Self = unsafe { Self::new_unchecked(10) };
|
|
|
|
/// Symbol for the `"<main>"` string.
|
|
pub const MAIN: Self = unsafe { Self::new_unchecked(11) };
|
|
|
|
/// Symbol for the `"raw"` string.
|
|
pub const RAW: Self = unsafe { Self::new_unchecked(12) };
|
|
|
|
/// Symbol for the `"static"` string.
|
|
pub const STATIC: Self = unsafe { Self::new_unchecked(13) };
|
|
|
|
/// Symbol for the `"prototype"` string.
|
|
pub const PROTOTYPE: Self = unsafe { Self::new_unchecked(14) };
|
|
|
|
/// Symbol for the `"constructor"` string.
|
|
pub const CONSTRUCTOR: Self = unsafe { Self::new_unchecked(15) };
|
|
|
|
/// Symbol for the `"implements"` string.
|
|
pub const IMPLEMENTS: Self = unsafe { Self::new_unchecked(16) };
|
|
|
|
/// Symbol for the `"interface"` string.
|
|
pub const INTERFACE: Self = unsafe { Self::new_unchecked(17) };
|
|
|
|
/// Symbol for the `"let"` string.
|
|
pub const LET: Self = unsafe { Self::new_unchecked(18) };
|
|
|
|
/// Symbol for the `"package"` string.
|
|
pub const PACKAGE: Self = unsafe { Self::new_unchecked(19) };
|
|
|
|
/// Symbol for the `"private"` string.
|
|
pub const PRIVATE: Self = unsafe { Self::new_unchecked(20) };
|
|
|
|
/// Symbol for the `"protected"` string.
|
|
pub const PROTECTED: Self = unsafe { Self::new_unchecked(21) };
|
|
|
|
/// Symbol for the `"public"` string.
|
|
pub const PUBLIC: Self = unsafe { Self::new_unchecked(22) };
|
|
|
|
/// Symbol for the `"anonymous"` string.
|
|
pub const ANONYMOUS: Self = unsafe { Self::new_unchecked(23) };
|
|
|
|
/// Creates a new [`Sym`] from the provided `value`, or returns `None` if `index` is zero.
|
|
#[inline]
|
|
pub(super) fn new(value: usize) -> Option<Self> {
|
|
NonZeroUsize::new(value).map(|value| Self { value })
|
|
}
|
|
|
|
/// Creates a new [`Sym`] from the provided `value`, without checking if `value` is not zero
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// `value` must not be zero.
|
|
#[inline]
|
|
pub(super) const unsafe fn new_unchecked(value: usize) -> Self {
|
|
Self {
|
|
value:
|
|
// SAFETY: The caller must ensure the invariants of the function.
|
|
unsafe {
|
|
NonZeroUsize::new_unchecked(value)
|
|
},
|
|
}
|
|
}
|
|
|
|
/// Returns the internal value of the [`Sym`]
|
|
#[inline]
|
|
pub(super) const fn get(self) -> usize {
|
|
self.value.get()
|
|
}
|
|
}
|
|
|
|
/// Ordered set of commonly used static strings.
|
|
///
|
|
/// # Note
|
|
///
|
|
/// `COMMON_STRINGS` and the constants defined in [`Sym`] must always
|
|
/// be in sync.
|
|
pub(super) static COMMON_STRINGS: phf::OrderedSet<&'static str> = {
|
|
const COMMON_STRINGS: phf::OrderedSet<&'static str> = phf::phf_ordered_set! {
|
|
"",
|
|
"arguments",
|
|
"await",
|
|
"yield",
|
|
"eval",
|
|
"default",
|
|
"null",
|
|
"RegExp",
|
|
"get",
|
|
"set",
|
|
"<main>",
|
|
"raw",
|
|
"static",
|
|
"prototype",
|
|
"constructor",
|
|
"implements",
|
|
"interface",
|
|
"let",
|
|
"package",
|
|
"private",
|
|
"protected",
|
|
"public",
|
|
"anonymous",
|
|
};
|
|
// A `COMMON_STRINGS` of size `usize::MAX` would cause an overflow on our `Interner`
|
|
sa::const_assert!(COMMON_STRINGS.len() < usize::MAX);
|
|
COMMON_STRINGS
|
|
};
|