Browse Source

Fix postfix increment and decrement return values (#1913)

This fixes a bug with the postfix increment and decrement. Before those operators would return the left-hand-side value, but the spec specifies they should return ToNumeric(left-had-side value).
pull/1919/head
raskad 3 years ago
parent
commit
a44be7073b
  1. 6
      boa_engine/src/bytecompiler.rs
  2. 2
      boa_engine/src/vm/code_block.rs
  3. 22
      boa_engine/src/vm/mod.rs
  4. 16
      boa_engine/src/vm/opcode.rs

6
boa_engine/src/bytecompiler.rs

@ -595,8 +595,7 @@ impl<'b> ByteCompiler<'b> {
}
UnaryOp::IncrementPost => {
self.compile_expr(unary.target(), true)?;
self.emit(Opcode::Dup, &[]);
self.emit(Opcode::Inc, &[]);
self.emit(Opcode::IncPost, &[]);
let access = Self::compile_access(unary.target()).ok_or_else(|| {
self.context
@ -608,8 +607,7 @@ impl<'b> ByteCompiler<'b> {
}
UnaryOp::DecrementPost => {
self.compile_expr(unary.target(), true)?;
self.emit(Opcode::Dup, &[]);
self.emit(Opcode::Dec, &[]);
self.emit(Opcode::DecPost, &[]);
let access = Self::compile_access(unary.target()).ok_or_else(|| {
self.context

2
boa_engine/src/vm/code_block.rs

@ -287,7 +287,9 @@ impl CodeBlock {
| Opcode::Pos
| Opcode::Neg
| Opcode::Inc
| Opcode::IncPost
| Opcode::Dec
| Opcode::DecPost
| Opcode::GetPropertyByValue
| Opcode::SetPropertyByValue
| Opcode::DefineOwnPropertyByValue

22
boa_engine/src/vm/mod.rs

@ -314,6 +314,17 @@ impl Context {
}
}
}
Opcode::IncPost => {
let value = self.vm.pop();
let value = value.to_numeric(self)?;
self.vm.push(value.clone());
match value {
Numeric::Number(number) => self.vm.push(number + 1f64),
Numeric::BigInt(bigint) => {
self.vm.push(JsBigInt::add(&bigint, &JsBigInt::one()));
}
}
}
Opcode::Dec => {
let value = self.vm.pop();
match value.to_numeric(self)? {
@ -323,6 +334,17 @@ impl Context {
}
}
}
Opcode::DecPost => {
let value = self.vm.pop();
let value = value.to_numeric(self)?;
self.vm.push(value.clone());
match value {
Numeric::Number(number) => self.vm.push(number - 1f64),
Numeric::BigInt(bigint) => {
self.vm.push(JsBigInt::sub(&bigint, &JsBigInt::one()));
}
}
}
Opcode::LogicalNot => {
let value = self.vm.pop();
self.vm.push(!value.to_boolean());

16
boa_engine/src/vm/opcode.rs

@ -390,6 +390,13 @@ pub enum Opcode {
/// Stack: value **=>** (value + 1)
Inc,
/// Unary postfix `++` operator.
///
/// Operands:
///
/// Stack: value **=>** (ToNumeric(value)), (value + 1)
IncPost,
/// Unary `--` operator.
///
/// Operands:
@ -397,6 +404,13 @@ pub enum Opcode {
/// Stack: value **=>** (value - 1)
Dec,
/// Unary postfix `--` operator.
///
/// Operands:
///
/// Stack: value **=>** (ToNumeric(value)), (value - 1)
DecPost,
/// Declare and initialize a function argument.
///
/// Operands: name_index: `u32`
@ -978,7 +992,9 @@ impl Opcode {
Opcode::Pos => "Pos",
Opcode::Neg => "Neg",
Opcode::Inc => "Inc",
Opcode::IncPost => "IncPost",
Opcode::Dec => "Dec",
Opcode::DecPost => "DecPost",
Opcode::DefInitArg => "DefInitArg",
Opcode::DefVar => "DefVar",
Opcode::DefInitVar => "DefInitVar",

Loading…
Cancel
Save