From a44be7073b678afd2ce0472108b6315ea4b81574 Mon Sep 17 00:00:00 2001 From: raskad <32105367+raskad@users.noreply.github.com> Date: Wed, 9 Mar 2022 19:26:46 +0000 Subject: [PATCH] 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). --- boa_engine/src/bytecompiler.rs | 6 ++---- boa_engine/src/vm/code_block.rs | 2 ++ boa_engine/src/vm/mod.rs | 22 ++++++++++++++++++++++ boa_engine/src/vm/opcode.rs | 16 ++++++++++++++++ 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/boa_engine/src/bytecompiler.rs b/boa_engine/src/bytecompiler.rs index 3dd8cac706..4153a8bd20 100644 --- a/boa_engine/src/bytecompiler.rs +++ b/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 diff --git a/boa_engine/src/vm/code_block.rs b/boa_engine/src/vm/code_block.rs index 8673e2de97..a2e8161577 100644 --- a/boa_engine/src/vm/code_block.rs +++ b/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 diff --git a/boa_engine/src/vm/mod.rs b/boa_engine/src/vm/mod.rs index 90639f1ccf..be039b75d2 100644 --- a/boa_engine/src/vm/mod.rs +++ b/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()); diff --git a/boa_engine/src/vm/opcode.rs b/boa_engine/src/vm/opcode.rs index 83afbd5df0..0020b640ac 100644 --- a/boa_engine/src/vm/opcode.rs +++ b/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",