use crate::{vm::CompletionType, Context, JsResult};
mod await_stm;
mod binary_ops;
mod call;
mod concat;
mod control_flow;
mod copy;
mod define;
mod delete;
mod dup;
mod environment;
mod generator;
mod get;
mod iteration;
mod jump;
mod meta;
mod new;
mod nop;
mod pop;
mod push;
mod require;
mod rest_parameter;
mod set;
mod swap;
mod switch;
mod templates;
mod to;
mod unary_ops;
mod value;
#[doc(inline)]
pub(crate) use await_stm::*;
#[doc(inline)]
pub(crate) use binary_ops::*;
#[doc(inline)]
pub(crate) use call::*;
#[doc(inline)]
pub(crate) use concat::*;
#[doc(inline)]
pub(crate) use control_flow::*;
#[doc(inline)]
pub(crate) use copy::*;
#[doc(inline)]
pub(crate) use define::*;
#[doc(inline)]
pub(crate) use delete::*;
#[doc(inline)]
pub(crate) use dup::*;
#[doc(inline)]
pub(crate) use environment::*;
#[doc(inline)]
pub(crate) use generator::*;
#[doc(inline)]
pub(crate) use get::*;
#[doc(inline)]
pub(crate) use iteration::*;
#[doc(inline)]
pub(crate) use jump::*;
#[doc(inline)]
pub(crate) use meta::*;
#[doc(inline)]
pub(crate) use new::*;
#[doc(inline)]
pub(crate) use nop::*;
#[doc(inline)]
pub(crate) use pop::*;
#[doc(inline)]
pub(crate) use push::*;
#[doc(inline)]
pub(crate) use require::*;
#[doc(inline)]
pub(crate) use rest_parameter::*;
#[doc(inline)]
pub(crate) use set::*;
#[doc(inline)]
pub(crate) use swap::*;
#[doc(inline)]
pub(crate) use switch::*;
#[doc(inline)]
pub(crate) use templates::*;
#[doc(inline)]
pub(crate) use to::*;
#[doc(inline)]
pub(crate) use unary_ops::*;
#[doc(inline)]
pub(crate) use value::*;
macro_rules! generate_impl {
( name $name:ident ) => { $name };
( name $name:ident => $mapping:ident ) => { $mapping };
(
$(#[$outer:meta])*
pub enum $Type:ident {
$(
$(#[$inner:ident $($args:tt)*])*
$Variant:ident $(=> $mapping:ident)? $(= $index:expr)*
),*
$(,)?
}
) => {
$(#[$outer])*
pub enum $Type {
$(
$(#[$inner $($args)*])*
$Variant $(= $index)*
),*
}
impl From<u8> for Opcode {
#[inline]
#[allow(non_upper_case_globals)]
fn from(value: u8) -> Self {
$(
const $Variant: u8 = Opcode::$Variant as u8;
)*
match value {
$($Variant => Self::$Variant),*
}
}
}
impl $Type {
const MAX: usize = 2usize.pow(8);
const NAMES: [&'static str; Self::MAX] = [
$(<generate_impl!(name $Variant $(=> $mapping)?)>::NAME),*
];
#[must_use]
pub const fn as_str(self) -> &'static str {
Self::NAMES[self as usize]
}
const INSTRUCTIONS: [&'static str; Self::MAX] = [
$(<generate_impl!(name $Variant $(=> $mapping)?)>::INSTRUCTION),*
];
#[must_use]
pub const fn as_instruction_str(self) -> &'static str {
Self::INSTRUCTIONS[self as usize]
}
const EXECUTE_FNS: [fn(&mut Context<'_>) -> JsResult<CompletionType>; Self::MAX] = [
$(<generate_impl!(name $Variant $(=> $mapping)?)>::execute),*
];
pub(super) fn execute(self, context: &mut Context<'_>) -> JsResult<CompletionType> {
Self::EXECUTE_FNS[self as usize](context)
}
}
};
}
pub(crate) trait Operation {
const NAME: &'static str;
const INSTRUCTION: &'static str;
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType>;
}
generate_impl! {
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum Opcode {
Pop = 0,
Dup,
Swap,
RotateLeft,
RotateRight,
PushZero,
PushOne,
PushInt8,
PushInt16,
PushInt32,
PushRational,
PushNaN,
PushPositiveInfinity,
PushNegativeInfinity,
PushNull,
PushTrue,
PushFalse,
PushUndefined,
PushLiteral,
PushEmptyObject,
PushClassPrototype,
SetClassPrototype,
SetHomeObject,
SetHomeObjectClass,
SetPrototype,
PushNewArray,
PushValueToArray,
PushElisionToArray,
PushIteratorToArray,
Add,
Sub,
Div,
Mul,
Mod,
Pow,
ShiftRight,
ShiftLeft,
UnsignedShiftRight,
BitOr,
BitAnd,
BitXor,
BitNot,
In,
InPrivate,
Eq,
StrictEq,
NotEq,
StrictNotEq,
GreaterThan,
GreaterThanOrEq,
LessThan,
LessThanOrEq,
InstanceOf,
LogicalAnd,
LogicalOr,
Coalesce,
TypeOf,
Void,
LogicalNot,
Pos,
Neg,
Inc,
IncPost,
Dec,
DecPost,
DefVar,
DefInitVar,
PutLexicalValue,
ThrowMutateImmutable,
GetName,
GetLocator,
GetNameAndLocator,
GetNameOrUndefined,
SetName,
SetNameByLocator,
DeleteName,
GetPropertyByName,
GetMethod,
GetPropertyByValue,
GetPropertyByValuePush,
SetPropertyByName,
SetFunctionName,
DefineOwnPropertyByName,
DefineClassStaticMethodByName,
DefineClassMethodByName,
SetPropertyByValue,
DefineOwnPropertyByValue,
DefineClassStaticMethodByValue,
DefineClassMethodByValue,
SetPropertyGetterByName,
DefineClassStaticGetterByName,
DefineClassGetterByName,
SetPropertyGetterByValue,
DefineClassStaticGetterByValue,
DefineClassGetterByValue,
SetPropertySetterByName,
DefineClassStaticSetterByName,
DefineClassSetterByName,
SetPropertySetterByValue,
DefineClassStaticSetterByValue,
DefineClassSetterByValue,
SetPrivateField,
DefinePrivateField,
SetPrivateMethod,
SetPrivateSetter,
SetPrivateGetter,
GetPrivateField,
PushClassField,
PushClassFieldPrivate,
PushClassPrivateGetter,
PushClassPrivateSetter,
PushClassPrivateMethod,
DeletePropertyByName,
DeletePropertyByValue,
DeleteSuperThrow,
CopyDataProperties,
ToPropertyKey,
Jump,
JumpIfTrue,
JumpIfFalse,
JumpIfNotUndefined,
JumpIfNullOrUndefined,
Throw,
ThrowNewTypeError,
TryStart,
TryEnd,
FinallyStart,
FinallyEnd,
Break,
Continue,
ToBoolean,
This,
Super,
SuperCallPrepare,
SuperCall,
SuperCallSpread,
SuperCallDerived,
ImportCall,
Case,
Default,
GetArrowFunction,
GetAsyncArrowFunction,
GetFunction,
GetFunctionAsync,
GetGenerator,
GetGeneratorAsync,
CallEval,
CallEvalSpread,
Call,
CallSpread,
New,
NewSpread,
Return,
GetReturnValue,
SetReturnValue,
PushDeclarativeEnvironment,
PushObjectEnvironment,
PushFunctionEnvironment,
PopEnvironment,
LoopStart,
LoopContinue,
LoopEnd,
LabelledStart,
LabelledEnd,
CreateForInIterator,
IteratorLoopStart,
GetIterator,
GetAsyncIterator,
IteratorNext,
IteratorDone,
IteratorFinishAsyncNext,
IteratorValue,
IteratorResult,
IteratorToArray,
IteratorPop,
IteratorStackEmpty,
CreateIteratorResult,
IteratorReturn,
ConcatToString,
RequireObjectCoercible,
ValueNotNullOrUndefined,
RestParameterInit,
RestParameterPop,
GeneratorYield,
GeneratorNext,
GeneratorResumeReturn,
AsyncGeneratorYield,
GeneratorJumpOnResumeKind,
GeneratorSetReturn,
GeneratorDelegateNext,
GeneratorDelegateResume,
Await,
NewTarget,
ImportMeta,
IsObject,
TemplateLookup,
TemplateCreate,
PushPrivateEnvironment,
PopPrivateEnvironment,
Nop,
Reserved1 => Reserved,
Reserved2 => Reserved,
Reserved3 => Reserved,
Reserved4 => Reserved,
Reserved5 => Reserved,
Reserved6 => Reserved,
Reserved7 => Reserved,
Reserved8 => Reserved,
Reserved9 => Reserved,
Reserved10 => Reserved,
Reserved11 => Reserved,
Reserved12 => Reserved,
Reserved13 => Reserved,
Reserved14 => Reserved,
Reserved15 => Reserved,
Reserved16 => Reserved,
Reserved17 => Reserved,
Reserved18 => Reserved,
Reserved19 => Reserved,
Reserved20 => Reserved,
Reserved21 => Reserved,
Reserved22 => Reserved,
Reserved23 => Reserved,
Reserved24 => Reserved,
Reserved25 => Reserved,
Reserved26 => Reserved,
Reserved27 => Reserved,
Reserved28 => Reserved,
Reserved29 => Reserved,
Reserved30 => Reserved,
Reserved31 => Reserved,
Reserved32 => Reserved,
Reserved33 => Reserved,
Reserved34 => Reserved,
Reserved35 => Reserved,
Reserved36 => Reserved,
Reserved37 => Reserved,
Reserved38 => Reserved,
Reserved39 => Reserved,
Reserved40 => Reserved,
Reserved41 => Reserved,
Reserved42 => Reserved,
Reserved43 => Reserved,
Reserved44 => Reserved,
Reserved45 => Reserved,
Reserved46 => Reserved,
Reserved47 => Reserved,
Reserved48 => Reserved,
Reserved49 => Reserved,
Reserved50 => Reserved,
Reserved51 => Reserved,
Reserved52 => Reserved,
Reserved53 => Reserved,
Reserved54 => Reserved,
Reserved55 => Reserved,
Reserved56 => Reserved,
}
}
#[derive(Clone, Copy, Debug)]
pub(crate) enum BindingOpcode {
Var,
InitVar,
InitLet,
InitConst,
SetName,
}