diff options
author | Linus Groh <mail@linusgroh.de> | 2020-10-05 12:30:08 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-10-05 14:34:37 +0200 |
commit | 2d4cd5b49b9b9d800aa24e8dccc042ed9257d1a7 (patch) | |
tree | 2c24edb9bcc86ccd213fbfcf246f555dd5497992 /Libraries/LibJS/AST.cpp | |
parent | 7fd4646acb65bc0611d8a57f1e650a158d01dc53 (diff) | |
download | serenity-2d4cd5b49b9b9d800aa24e8dccc042ed9257d1a7.zip |
LibJS: Evaluate AssignmentExpression LHS before RHS according to the spec
Fixes #3689.
Diffstat (limited to 'Libraries/LibJS/AST.cpp')
-rw-r--r-- | Libraries/LibJS/AST.cpp | 67 |
1 files changed, 28 insertions, 39 deletions
diff --git a/Libraries/LibJS/AST.cpp b/Libraries/LibJS/AST.cpp index e12f51e89e..44253bbf17 100644 --- a/Libraries/LibJS/AST.cpp +++ b/Libraries/LibJS/AST.cpp @@ -1198,84 +1198,67 @@ void ThisExpression::dump(int indent) const Value AssignmentExpression::execute(Interpreter& interpreter, GlobalObject& global_object) const { - auto rhs_result = m_rhs->execute(interpreter, global_object); - if (interpreter.exception()) - return {}; +#define EXECUTE_LHS_AND_RHS() \ + do { \ + lhs_result = m_lhs->execute(interpreter, global_object); \ + if (interpreter.exception()) \ + return {}; \ + rhs_result = m_rhs->execute(interpreter, global_object); \ + if (interpreter.exception()) \ + return {}; \ + } while (0) Value lhs_result; + Value rhs_result; switch (m_op) { case AssignmentOp::Assignment: break; case AssignmentOp::AdditionAssignment: - lhs_result = m_lhs->execute(interpreter, global_object); - if (interpreter.exception()) - return {}; + EXECUTE_LHS_AND_RHS(); rhs_result = add(global_object, lhs_result, rhs_result); break; case AssignmentOp::SubtractionAssignment: - lhs_result = m_lhs->execute(interpreter, global_object); - if (interpreter.exception()) - return {}; + EXECUTE_LHS_AND_RHS(); rhs_result = sub(global_object, lhs_result, rhs_result); break; case AssignmentOp::MultiplicationAssignment: - lhs_result = m_lhs->execute(interpreter, global_object); - if (interpreter.exception()) - return {}; + EXECUTE_LHS_AND_RHS(); rhs_result = mul(global_object, lhs_result, rhs_result); break; case AssignmentOp::DivisionAssignment: - lhs_result = m_lhs->execute(interpreter, global_object); - if (interpreter.exception()) - return {}; + EXECUTE_LHS_AND_RHS(); rhs_result = div(global_object, lhs_result, rhs_result); break; case AssignmentOp::ModuloAssignment: - lhs_result = m_lhs->execute(interpreter, global_object); - if (interpreter.exception()) - return {}; + EXECUTE_LHS_AND_RHS(); rhs_result = mod(global_object, lhs_result, rhs_result); break; case AssignmentOp::ExponentiationAssignment: - lhs_result = m_lhs->execute(interpreter, global_object); - if (interpreter.exception()) - return {}; + EXECUTE_LHS_AND_RHS(); rhs_result = exp(global_object, lhs_result, rhs_result); break; case AssignmentOp::BitwiseAndAssignment: - lhs_result = m_lhs->execute(interpreter, global_object); - if (interpreter.exception()) - return {}; + EXECUTE_LHS_AND_RHS(); rhs_result = bitwise_and(global_object, lhs_result, rhs_result); break; case AssignmentOp::BitwiseOrAssignment: - lhs_result = m_lhs->execute(interpreter, global_object); - if (interpreter.exception()) - return {}; + EXECUTE_LHS_AND_RHS(); rhs_result = bitwise_or(global_object, lhs_result, rhs_result); break; case AssignmentOp::BitwiseXorAssignment: - lhs_result = m_lhs->execute(interpreter, global_object); - if (interpreter.exception()) - return {}; + EXECUTE_LHS_AND_RHS(); rhs_result = bitwise_xor(global_object, lhs_result, rhs_result); break; case AssignmentOp::LeftShiftAssignment: - lhs_result = m_lhs->execute(interpreter, global_object); - if (interpreter.exception()) - return {}; + EXECUTE_LHS_AND_RHS(); rhs_result = left_shift(global_object, lhs_result, rhs_result); break; case AssignmentOp::RightShiftAssignment: - lhs_result = m_lhs->execute(interpreter, global_object); - if (interpreter.exception()) - return {}; + EXECUTE_LHS_AND_RHS(); rhs_result = right_shift(global_object, lhs_result, rhs_result); break; case AssignmentOp::UnsignedRightShiftAssignment: - lhs_result = m_lhs->execute(interpreter, global_object); - if (interpreter.exception()) - return {}; + EXECUTE_LHS_AND_RHS(); rhs_result = unsigned_right_shift(global_object, lhs_result, rhs_result); break; } @@ -1286,6 +1269,12 @@ Value AssignmentExpression::execute(Interpreter& interpreter, GlobalObject& glob if (interpreter.exception()) return {}; + if (m_op == AssignmentOp::Assignment) { + rhs_result = m_rhs->execute(interpreter, global_object); + if (interpreter.exception()) + return {}; + } + if (reference.is_unresolvable()) { interpreter.vm().throw_exception<ReferenceError>(global_object, ErrorType::InvalidLeftHandAssignment); return {}; |