Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions core/engine/src/bytecompiler/expression/binary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ use crate::{
};
use boa_ast::{
Expression,
expression::operator::{
Binary, BinaryInPrivate,
binary::{ArithmeticOp, BinaryOp, BitwiseOp, LogicalOp, RelationalOp},
expression::{
literal::LiteralKind,
operator::{
Binary, BinaryInPrivate,
binary::{ArithmeticOp, BinaryOp, BitwiseOp, LogicalOp, RelationalOp},
},
},
};

Expand All @@ -20,7 +23,20 @@ impl ByteCompiler<'_> {
}
BinaryOp::Bitwise(op) => {
self.compile_expr_operand(binary.lhs(), |self_, lhs| {
self_.compile_binary_bitwise(op, binary.rhs(), dst, lhs);
const MAX_UINT32_LITERAL: LiteralKind = LiteralKind::Num(u32::MAX as f64);
if let Expression::Literal(literal) = binary.rhs().flatten()
&& (
// x | 0
(op == BitwiseOp::Or && literal.kind() == &LiteralKind::Int(0))
||
// x & 0xFFFFFFFF
(op == BitwiseOp::And && literal.kind() == &MAX_UINT32_LITERAL)
)
{
self_.bytecode.emit_to_int32(dst.variable(), lhs);
} else {
self_.compile_binary_bitwise(op, binary.rhs(), dst, lhs);
}
});
}
BinaryOp::Relational(op) => {
Expand Down
4 changes: 2 additions & 2 deletions core/engine/src/vm/code_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ impl CodeBlock {
| Instruction::CreateUnmappedArgumentsObject { dst }
| Instruction::RestParameterInit { dst }
| Instruction::StoreNewArray { dst } => format!("dst:{dst}"),
Instruction::ToInt32 { dst, src } => format!("dst:{dst}, src:{src}"),
Instruction::Add { lhs, rhs, dst }
| Instruction::Sub { lhs, rhs, dst }
| Instruction::Div { lhs, rhs, dst }
Expand Down Expand Up @@ -933,8 +934,7 @@ impl CodeBlock {
| Instruction::Reserved56
| Instruction::Reserved57
| Instruction::Reserved58
| Instruction::Reserved59
| Instruction::Reserved60 => unreachable!("Reserved opcodes are unreachable"),
| Instruction::Reserved59 => unreachable!("Reserved opcodes are unreachable"),
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions core/engine/src/vm/flowgraph/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ impl CodeBlock {
| Instruction::Move { .. }
| Instruction::PopIntoRegister { .. }
| Instruction::PushFromRegister { .. }
| Instruction::ToInt32 { .. }
| Instruction::Add { .. }
| Instruction::Sub { .. }
| Instruction::Div { .. }
Expand Down Expand Up @@ -432,8 +433,7 @@ impl CodeBlock {
| Instruction::Reserved56
| Instruction::Reserved57
| Instruction::Reserved58
| Instruction::Reserved59
| Instruction::Reserved60 => unreachable!("Reserved opcodes are unreachable"),
| Instruction::Reserved59 => unreachable!("Reserved opcodes are unreachable"),
}
}

Expand Down
9 changes: 7 additions & 2 deletions core/engine/src/vm/opcode/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,13 @@ generate_opcodes! {
/// - Input: array
PushIteratorToArray { array: RegisterOperand },

/// Convert the value into a int32.
///
/// - Registers
/// - Input: src
/// - Output: dst
ToInt32 { dst: RegisterOperand, src: RegisterOperand },

/// Binary `+` operator.
///
/// - Registers
Expand Down Expand Up @@ -2270,6 +2277,4 @@ generate_opcodes! {
Reserved58 => Reserved,
/// Reserved [`Opcode`].
Reserved59 => Reserved,
/// Reserved [`Opcode`].
Reserved60 => Reserved,
}
29 changes: 29 additions & 0 deletions core/engine/src/vm/opcode/unary_ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,32 @@ impl Operation for BitNot {
const INSTRUCTION: &'static str = "INST - BitNot";
const COST: u8 = 3;
}

/// `ToInt32` implements the Opcode Operation for `Opcode::ToInt32`
///
/// Operation:
/// - Unary bitwise `~` operator.
#[derive(Debug, Clone, Copy)]
pub(crate) struct ToInt32;

impl ToInt32 {
#[inline(always)]
pub(super) fn operation(
(dst, src): (RegisterOperand, RegisterOperand),
context: &mut Context,
) -> JsResult<()> {
let result = context
.vm
.get_register(src.into())
.clone()
.to_i32(context)?;
context.vm.set_register(dst.into(), result.into());
Ok(())
}
}

impl Operation for ToInt32 {
const NAME: &'static str = "ToInt32";
const INSTRUCTION: &'static str = "INST - ToInt32";
const COST: u8 = 1;
}
Loading