use super::scope::ScopeId;
use crate::engine::code::bytecode::EvalVariableSource;
use crate::engine::code::function::metadata::ClosureVariableKind;
use crate::engine::compiler::lexer::Span;
use crate::engine::compiler::module;
use crate::engine::compiler::names::NameId;
use crate::engine::compiler::{EVAL_RET_LOCAL_NAME, FINALLY_EVAL_RET_LOCAL_NAME};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub(in crate::engine::compiler) struct BindingId(pub(in crate::engine::compiler) usize);
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(in crate::engine::compiler) enum SyntheticLocalKind {
EvalCompletion,
FinallySavedEvalCompletion,
}
impl SyntheticLocalKind {
pub(in crate::engine::compiler) const fn name(self) -> &'static str {
match self {
Self::EvalCompletion => EVAL_RET_LOCAL_NAME,
Self::FinallySavedEvalCompletion => FINALLY_EVAL_RET_LOCAL_NAME,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(in crate::engine::compiler) struct SyntheticLocal {
pub(in crate::engine::compiler) index: u16,
pub(in crate::engine::compiler) kind: SyntheticLocalKind,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(in crate::engine::compiler) enum BindingKind {
Normal,
Lexical {
is_const: bool,
},
FunctionName {
is_const: bool,
},
EvalVariableObject,
ArgEvalVariableObject,
WithObject,
PrivateField {
is_static: bool,
},
PrivateMethod {
is_static: bool,
},
PrivateGetter {
is_static: bool,
},
PrivateSetter {
is_static: bool,
},
PrivateGetterSetter {
is_static: bool,
},
}
pub(in crate::engine::compiler) fn binding_kinds_compatible(
left: BindingKind,
right: BindingKind,
) -> bool {
left == right
|| matches!(
(left, right),
(
BindingKind::PrivateField { .. },
BindingKind::PrivateField { .. }
) | (
BindingKind::PrivateMethod { .. },
BindingKind::PrivateMethod { .. }
) | (
BindingKind::PrivateGetter { .. },
BindingKind::PrivateGetter { .. }
) | (
BindingKind::PrivateSetter { .. },
BindingKind::PrivateSetter { .. }
) | (
BindingKind::PrivateGetterSetter { .. },
BindingKind::PrivateGetterSetter { .. }
)
)
}
pub(in crate::engine::compiler) const fn binding_kind_from_closure_flags(
kind: ClosureVariableKind,
is_lexical: bool,
is_const: bool,
) -> Option<BindingKind> {
match kind {
ClosureVariableKind::Normal if is_lexical => Some(BindingKind::Lexical { is_const }),
ClosureVariableKind::Normal if !is_const => Some(BindingKind::Normal),
ClosureVariableKind::ModuleImportView if is_lexical && is_const => {
Some(BindingKind::Lexical { is_const: true })
}
ClosureVariableKind::FunctionName if !is_lexical => {
Some(BindingKind::FunctionName { is_const })
}
ClosureVariableKind::EvalVariableObject if !is_lexical && !is_const => {
Some(BindingKind::EvalVariableObject)
}
ClosureVariableKind::ArgEvalVariableObject if !is_lexical && !is_const => {
Some(BindingKind::ArgEvalVariableObject)
}
ClosureVariableKind::WithObject if !is_lexical && !is_const => {
Some(BindingKind::WithObject)
}
ClosureVariableKind::PrivateField if is_lexical && is_const => {
Some(BindingKind::PrivateField { is_static: false })
}
ClosureVariableKind::PrivateMethod if is_lexical && is_const => {
Some(BindingKind::PrivateMethod { is_static: false })
}
ClosureVariableKind::PrivateGetter if is_lexical && is_const => {
Some(BindingKind::PrivateGetter { is_static: false })
}
ClosureVariableKind::PrivateSetter if is_lexical && is_const => {
Some(BindingKind::PrivateSetter { is_static: false })
}
ClosureVariableKind::PrivateGetterSetter if is_lexical && is_const => {
Some(BindingKind::PrivateGetterSetter { is_static: false })
}
ClosureVariableKind::Normal
| ClosureVariableKind::ModuleImportView
| ClosureVariableKind::FunctionName
| ClosureVariableKind::GlobalFunction
| ClosureVariableKind::EvalVariableObject
| ClosureVariableKind::ArgEvalVariableObject
| ClosureVariableKind::WithObject
| ClosureVariableKind::PrivateField
| ClosureVariableKind::PrivateMethod
| ClosureVariableKind::PrivateGetter
| ClosureVariableKind::PrivateSetter
| ClosureVariableKind::PrivateGetterSetter => None,
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(in crate::engine::compiler) enum BindingStorage {
Argument(u16),
Local(u16),
External(u16),
Module(module::ModuleBindingId),
Global,
}
#[derive(Debug)]
pub(in crate::engine::compiler) struct IrBinding {
pub(in crate::engine::compiler) name: NameId,
pub(in crate::engine::compiler) storage_scope: ScopeId,
pub(in crate::engine::compiler) declaration_scope: ScopeId,
pub(in crate::engine::compiler) storage: BindingStorage,
pub(in crate::engine::compiler) kind: BindingKind,
pub(in crate::engine::compiler) is_scoped_function: bool,
pub(in crate::engine::compiler) is_scoped_generator: bool,
pub(in crate::engine::compiler) is_catch_parameter: bool,
pub(in crate::engine::compiler) declaration_span: Option<Span>,
}
#[derive(Debug)]
pub(in crate::engine::compiler) struct IrGlobalDeclaration {
pub(in crate::engine::compiler) name: NameId,
pub(in crate::engine::compiler) is_lexical: bool,
pub(in crate::engine::compiler) is_const: bool,
pub(in crate::engine::compiler) function_constant: Option<u32>,
pub(in crate::engine::compiler) closure_index: Option<u16>,
}
#[derive(Clone, Copy, Debug)]
pub(in crate::engine::compiler) struct IrHoistedFunction {
pub(in crate::engine::compiler) binding: BindingId,
pub(in crate::engine::compiler) constant: u32,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(in crate::engine::compiler) enum EvalDeclarationTarget {
External { index: u16, kind: BindingKind },
Dynamic(EvalVariableSource),
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(in crate::engine::compiler) enum EvalDeclarationValue {
Undefined,
Function(u32),
}
#[derive(Clone, Debug)]
pub(in crate::engine::compiler) struct IrEvalDeclaration {
pub(in crate::engine::compiler) name: NameId,
pub(in crate::engine::compiler) target: EvalDeclarationTarget,
pub(in crate::engine::compiler) value: EvalDeclarationValue,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(in crate::engine::compiler) enum EvalDeclarationMode {
Local,
Global,
Dynamic(EvalVariableSource),
}
#[derive(Clone, Copy, Debug)]
pub(in crate::engine::compiler) struct IrScopedFunction {
pub(in crate::engine::compiler) binding: BindingId,
pub(in crate::engine::compiler) constant: u32,
pub(in crate::engine::compiler) authored_closure: usize,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(in crate::engine::compiler) enum IrAnnexBinding {
Static(BindingId),
Dynamic,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(in crate::engine::compiler) struct ResolvedBinding {
pub(in crate::engine::compiler) storage: BindingStorage,
pub(in crate::engine::compiler) kind: BindingKind,
}