use std::num::NonZeroU32;
use crate::{
ecmascript::{ObjectShape, PropertyKey, ProtoIntrinsics, Symbol, Value},
heap::HeapIndexHandle,
};
#[repr(u32)]
#[derive(Debug, Clone, Copy)]
pub(crate) enum IntrinsicObjectIndexes {
ObjectPrototype,
SymbolPrototype,
ErrorPrototype,
BigIntPrototype,
#[cfg(feature = "math")]
MathObject,
#[cfg(feature = "date")]
DatePrototype,
#[cfg(feature = "temporal")]
Temporal,
#[cfg(feature = "temporal")]
TemporalInstantPrototype,
#[cfg(feature = "temporal")]
TemporalDurationPrototype,
#[cfg(feature = "temporal")]
TemporalPlainTimePrototype,
#[cfg(feature = "regexp")]
RegExpPrototype,
ArrayPrototype,
#[cfg(feature = "array-buffer")]
TypedArrayPrototype,
#[cfg(feature = "array-buffer")]
Int8ArrayPrototype,
#[cfg(feature = "array-buffer")]
Uint8ArrayPrototype,
#[cfg(feature = "array-buffer")]
Uint8ClampedArrayPrototype,
#[cfg(feature = "array-buffer")]
Int16ArrayPrototype,
#[cfg(feature = "array-buffer")]
Uint16ArrayPrototype,
#[cfg(feature = "array-buffer")]
Int32ArrayPrototype,
#[cfg(feature = "array-buffer")]
Uint32ArrayPrototype,
#[cfg(feature = "array-buffer")]
BigInt64ArrayPrototype,
#[cfg(feature = "array-buffer")]
BigUint64ArrayPrototype,
#[cfg(feature = "proposal-float16array")]
Float16ArrayPrototype,
#[cfg(feature = "array-buffer")]
Float32ArrayPrototype,
#[cfg(feature = "array-buffer")]
Float64ArrayPrototype,
MapPrototype,
#[cfg(feature = "set")]
SetPrototype,
#[cfg(feature = "weak-refs")]
WeakMapPrototype,
#[cfg(feature = "weak-refs")]
WeakSetPrototype,
#[cfg(feature = "array-buffer")]
ArrayBufferPrototype,
#[cfg(feature = "shared-array-buffer")]
SharedArrayBufferPrototype,
#[cfg(feature = "array-buffer")]
DataViewPrototype,
#[cfg(feature = "atomics")]
AtomicsObject,
#[cfg(feature = "json")]
JSONObject,
#[cfg(feature = "weak-refs")]
WeakRefPrototype,
FinalizationRegistryPrototype,
IteratorPrototype,
ArrayIteratorPrototype,
AsyncIteratorPrototype,
MapIteratorPrototype,
#[cfg(feature = "set")]
SetIteratorPrototype,
PromisePrototype,
StringIteratorPrototype,
GeneratorFunctionPrototype,
AsyncGeneratorFunctionPrototype,
GeneratorPrototype,
AsyncGeneratorPrototype,
AsyncFunctionPrototype,
ReflectObject,
AggregateErrorPrototype,
EvalErrorPrototype,
RangeErrorPrototype,
ReferenceErrorPrototype,
SyntaxErrorPrototype,
TypeErrorPrototype,
URIErrorPrototype,
#[cfg(feature = "regexp")]
RegExpStringIteratorPrototype,
}
#[cfg(feature = "regexp")]
pub(crate) const LAST_INTRINSIC_OBJECT_INDEX: IntrinsicObjectIndexes =
IntrinsicObjectIndexes::RegExpStringIteratorPrototype;
#[cfg(not(feature = "regexp"))]
pub(crate) const LAST_INTRINSIC_OBJECT_INDEX: IntrinsicObjectIndexes =
IntrinsicObjectIndexes::URIErrorPrototype;
#[repr(u32)]
#[derive(Debug, Clone, Copy)]
#[allow(clippy::enum_variant_names)]
pub(crate) enum IntrinsicPrimitiveObjectIndexes {
BooleanPrototype,
NumberPrototype,
StringPrototype,
}
const LAST_INTRINSIC_PRIMITIVE_OBJECT_INDEX: IntrinsicPrimitiveObjectIndexes =
IntrinsicPrimitiveObjectIndexes::StringPrototype;
#[repr(u32)]
#[derive(Debug, Clone, Copy)]
pub(crate) enum IntrinsicConstructorIndexes {
Object,
Function,
FunctionPrototype,
Boolean,
Symbol,
Error,
Number,
BigInt,
#[cfg(feature = "date")]
Date,
#[cfg(feature = "temporal")]
TemporalInstant,
#[cfg(feature = "temporal")]
TemporalDuration,
#[cfg(feature = "temporal")]
TemporalPlainTime,
String,
#[cfg(feature = "regexp")]
RegExp,
Array,
#[cfg(feature = "array-buffer")]
TypedArray,
#[cfg(feature = "array-buffer")]
Int8Array,
#[cfg(feature = "array-buffer")]
Uint8Array,
#[cfg(feature = "array-buffer")]
Uint8ClampedArray,
#[cfg(feature = "array-buffer")]
Int16Array,
#[cfg(feature = "array-buffer")]
Uint16Array,
#[cfg(feature = "array-buffer")]
Int32Array,
#[cfg(feature = "array-buffer")]
Uint32Array,
#[cfg(feature = "array-buffer")]
BigInt64Array,
#[cfg(feature = "array-buffer")]
BigUint64Array,
#[cfg(feature = "proposal-float16array")]
Float16Array,
#[cfg(feature = "array-buffer")]
Float32Array,
#[cfg(feature = "array-buffer")]
Float64Array,
Map,
#[cfg(feature = "set")]
Set,
#[cfg(feature = "weak-refs")]
WeakMap,
#[cfg(feature = "weak-refs")]
WeakSet,
#[cfg(feature = "array-buffer")]
ArrayBuffer,
#[cfg(feature = "shared-array-buffer")]
SharedArrayBuffer,
#[cfg(feature = "array-buffer")]
DataView,
#[cfg(feature = "weak-refs")]
WeakRef,
FinalizationRegistry,
Iterator,
Promise,
GeneratorFunction,
AsyncGeneratorFunction,
AsyncFunction,
Proxy,
AggregateError,
EvalError,
RangeError,
ReferenceError,
SyntaxError,
TypeError,
URIError,
}
pub(crate) const LAST_INTRINSIC_CONSTRUCTOR_INDEX: IntrinsicConstructorIndexes =
IntrinsicConstructorIndexes::URIError;
#[repr(u32)]
#[derive(Debug, Clone, Copy)]
pub(crate) enum IntrinsicFunctionIndexes {
ArrayPrototypeSort,
ArrayPrototypeToString,
ArrayPrototypeValues,
#[cfg(feature = "date")]
DatePrototypeToUTCString,
DecodeURI,
DecodeURIComponent,
EncodeURI,
EncodeURIComponent,
#[cfg(feature = "annex-b-global")]
Escape,
Eval,
GeneratorFunctionPrototypePrototypeNext,
IsFinite,
IsNaN,
MapPrototypeEntries,
ObjectPrototypeToString,
ParseFloat,
ParseInt,
#[cfg(feature = "regexp")]
RegExpPrototypeExec,
#[cfg(feature = "set")]
SetPrototypeValues,
StringPrototypeTrimEnd,
StringPrototypeTrimStart,
ThrowTypeError,
#[cfg(feature = "array-buffer")]
TypedArrayPrototypeValues,
#[cfg(feature = "annex-b-global")]
Unescape,
}
#[cfg(feature = "annex-b-global")]
pub(crate) const LAST_INTRINSIC_FUNCTION_INDEX: IntrinsicFunctionIndexes =
IntrinsicFunctionIndexes::Unescape;
#[cfg(all(not(feature = "annex-b-global"), feature = "array-buffer"))]
pub(crate) const LAST_INTRINSIC_FUNCTION_INDEX: IntrinsicFunctionIndexes =
IntrinsicFunctionIndexes::TypedArrayPrototypeValues;
#[cfg(all(not(feature = "annex-b-global"), not(feature = "array-buffer")))]
pub(crate) const LAST_INTRINSIC_FUNCTION_INDEX: IntrinsicFunctionIndexes =
IntrinsicFunctionIndexes::ThrowTypeError;
impl IntrinsicObjectIndexes {
pub(crate) const OBJECT_INDEX_OFFSET: u32 = 0;
}
impl IntrinsicPrimitiveObjectIndexes {
pub(crate) const OBJECT_INDEX_OFFSET: u32 =
IntrinsicObjectIndexes::OBJECT_INDEX_OFFSET + LAST_INTRINSIC_OBJECT_INDEX as u32 + 1;
pub(crate) const PRIMITIVE_OBJECT_INDEX_OFFSET: u32 = 0;
}
impl IntrinsicConstructorIndexes {
pub(crate) const OBJECT_INDEX_OFFSET: u32 = IntrinsicPrimitiveObjectIndexes::OBJECT_INDEX_OFFSET
+ LAST_INTRINSIC_PRIMITIVE_OBJECT_INDEX as u32
+ 1;
pub(crate) const BUILTIN_FUNCTION_INDEX_OFFSET: u32 = 0;
}
impl IntrinsicFunctionIndexes {
pub(crate) const BUILTIN_FUNCTION_INDEX_OFFSET: u32 =
IntrinsicConstructorIndexes::BUILTIN_FUNCTION_INDEX_OFFSET
+ LAST_INTRINSIC_CONSTRUCTOR_INDEX as u32
+ 1;
}
pub(crate) const fn intrinsic_object_count() -> usize {
LAST_INTRINSIC_OBJECT_INDEX as usize
+ 1
+ LAST_INTRINSIC_PRIMITIVE_OBJECT_INDEX as usize
+ 1
+ LAST_INTRINSIC_CONSTRUCTOR_INDEX as usize
+ 1
}
pub(crate) const fn intrinsic_primitive_object_count() -> usize {
LAST_INTRINSIC_PRIMITIVE_OBJECT_INDEX as usize + 1
}
pub(crate) const fn intrinsic_function_count() -> usize {
LAST_INTRINSIC_CONSTRUCTOR_INDEX as usize + 1 + LAST_INTRINSIC_FUNCTION_INDEX as usize + 1
}
#[derive(Debug, Clone, Copy)]
#[repr(u32)]
pub(crate) enum IntrinsicObjectShapes {
Object,
Array,
Number,
String,
}
impl IntrinsicObjectShapes {
pub(crate) const fn get_object_shape_index(self, base: ObjectShape) -> ObjectShape<'static> {
ObjectShape::from_non_zero(
NonZeroU32::new(self as u32 + base.get_index_u32_const() + 1).unwrap(),
)
}
pub(crate) const fn get_proto_intrinsic(self) -> ProtoIntrinsics {
match self {
Self::Object => ProtoIntrinsics::Object,
Self::Array => ProtoIntrinsics::Array,
Self::Number => ProtoIntrinsics::Number,
Self::String => ProtoIntrinsics::String,
}
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
pub(crate) enum WellKnownSymbols {
AsyncIterator,
HasInstance,
IsConcatSpreadable,
Iterator,
#[cfg(feature = "regexp")]
Match,
#[cfg(feature = "regexp")]
MatchAll,
#[cfg(feature = "regexp")]
Replace,
#[cfg(feature = "regexp")]
Search,
Species,
#[cfg(feature = "regexp")]
Split,
ToPrimitive,
ToStringTag,
Unscopables,
}
impl From<WellKnownSymbols> for Value<'_> {
fn from(value: WellKnownSymbols) -> Self {
Value::Symbol(value.into())
}
}
impl From<WellKnownSymbols> for PropertyKey<'static> {
fn from(value: WellKnownSymbols) -> Self {
PropertyKey::Symbol(value.into())
}
}
impl TryFrom<Symbol<'_>> for WellKnownSymbols {
type Error = ();
fn try_from(value: Symbol<'_>) -> Result<Self, Self::Error> {
const ASYNCITERATOR: u32 = WellKnownSymbols::AsyncIterator as u32;
const HASINSTANCE: u32 = WellKnownSymbols::HasInstance as u32;
const ISCONCATSPREADABLE: u32 = WellKnownSymbols::IsConcatSpreadable as u32;
const ITERATOR: u32 = WellKnownSymbols::Iterator as u32;
const MATCH: u32 = WellKnownSymbols::Match as u32;
const MATCHALL: u32 = WellKnownSymbols::MatchAll as u32;
const REPLACE: u32 = WellKnownSymbols::Replace as u32;
const SEARCH: u32 = WellKnownSymbols::Search as u32;
const SPECIES: u32 = WellKnownSymbols::Species as u32;
const SPLIT: u32 = WellKnownSymbols::Split as u32;
const TOPRIMITIVE: u32 = WellKnownSymbols::ToPrimitive as u32;
const TOSTRINGTAG: u32 = WellKnownSymbols::ToStringTag as u32;
const UNSCOPABLES: u32 = WellKnownSymbols::Unscopables as u32;
match value.get_index_u32() {
ASYNCITERATOR => Ok(Self::AsyncIterator),
HASINSTANCE => Ok(Self::HasInstance),
ISCONCATSPREADABLE => Ok(Self::IsConcatSpreadable),
ITERATOR => Ok(Self::Iterator),
#[cfg(feature = "regexp")]
MATCH => Ok(Self::Match),
#[cfg(feature = "regexp")]
MATCHALL => Ok(Self::MatchAll),
#[cfg(feature = "regexp")]
REPLACE => Ok(Self::Replace),
#[cfg(feature = "regexp")]
SEARCH => Ok(Self::Search),
SPECIES => Ok(Self::Species),
#[cfg(feature = "regexp")]
SPLIT => Ok(Self::Split),
TOPRIMITIVE => Ok(Self::ToPrimitive),
TOSTRINGTAG => Ok(Self::ToStringTag),
UNSCOPABLES => Ok(Self::Unscopables),
_ => Err(()),
}
}
}
#[cfg(test)]
pub(crate) const LAST_WELL_KNOWN_SYMBOL_INDEX: u32 = WellKnownSymbols::Unscopables as u32;