summaryrefslogtreecommitdiff
path: root/Libraries/LibJS/AST.cpp
diff options
context:
space:
mode:
authorLinus Groh <mail@linusgroh.de>2020-10-05 12:30:08 +0100
committerAndreas Kling <kling@serenityos.org>2020-10-05 14:34:37 +0200
commit2d4cd5b49b9b9d800aa24e8dccc042ed9257d1a7 (patch)
tree2c24edb9bcc86ccd213fbfcf246f555dd5497992 /Libraries/LibJS/AST.cpp
parent7fd4646acb65bc0611d8a57f1e650a158d01dc53 (diff)
downloadserenity-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.cpp67
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 {};