use crate::{
error::JsNativeError,
vm::{opcode::Operation, CompletionType},
Context, JsResult,
};
pub(crate) mod logical;
pub(crate) mod macro_defined;
pub(crate) use logical::*;
pub(crate) use macro_defined::*;
#[derive(Debug, Clone, Copy)]
pub(crate) struct NotEq;
impl Operation for NotEq {
const NAME: &'static str = "NotEq";
const INSTRUCTION: &'static str = "INST - NotEq";
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let rhs = context.vm.pop();
let lhs = context.vm.pop();
let value = !lhs.equals(&rhs, context)?;
context.vm.push(value);
Ok(CompletionType::Normal)
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct StrictEq;
impl Operation for StrictEq {
const NAME: &'static str = "StrictEq";
const INSTRUCTION: &'static str = "INST - StrictEq";
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let rhs = context.vm.pop();
let lhs = context.vm.pop();
context.vm.push(lhs.strict_equals(&rhs));
Ok(CompletionType::Normal)
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct StrictNotEq;
impl Operation for StrictNotEq {
const NAME: &'static str = "StrictNotEq";
const INSTRUCTION: &'static str = "INST - StrictNotEq";
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let rhs = context.vm.pop();
let lhs = context.vm.pop();
context.vm.push(!lhs.strict_equals(&rhs));
Ok(CompletionType::Normal)
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct In;
impl Operation for In {
const NAME: &'static str = "In";
const INSTRUCTION: &'static str = "INST - In";
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let rhs = context.vm.pop();
let lhs = context.vm.pop();
let Some(rhs) = rhs.as_object() else {
return Err(JsNativeError::typ()
.with_message(format!(
"right-hand side of 'in' should be an object, got `{}`",
rhs.type_of()
))
.into());
};
let key = lhs.to_property_key(context)?;
let value = rhs.has_property(key, context)?;
context.vm.push(value);
Ok(CompletionType::Normal)
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct InPrivate;
impl Operation for InPrivate {
const NAME: &'static str = "InPrivate";
const INSTRUCTION: &'static str = "INST - InPrivate";
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let index = context.vm.read::<u32>();
let name = context.vm.frame().code_block.names[index as usize].clone();
let rhs = context.vm.pop();
let Some(rhs) = rhs.as_object() else {
return Err(JsNativeError::typ()
.with_message(format!(
"right-hand side of 'in' should be an object, got `{}`",
rhs.type_of()
))
.into());
};
let name = context
.vm
.environments
.resolve_private_identifier(name)
.expect("private name must be in environment");
if rhs.private_element_find(&name, true, true).is_some() {
context.vm.push(true);
} else {
context.vm.push(false);
}
Ok(CompletionType::Normal)
}
}
#[derive(Debug, Clone, Copy)]
pub(crate) struct InstanceOf;
impl Operation for InstanceOf {
const NAME: &'static str = "InstanceOf";
const INSTRUCTION: &'static str = "INST - InstanceOf";
fn execute(context: &mut Context<'_>) -> JsResult<CompletionType> {
let target = context.vm.pop();
let v = context.vm.pop();
let value = v.instance_of(&target, context)?;
context.vm.push(value);
Ok(CompletionType::Normal)
}
}