summaryrefslogtreecommitdiff
path: root/js/src
diff options
context:
space:
mode:
Diffstat (limited to 'js/src')
-rw-r--r--js/src/frontend/Parser.cpp74
-rw-r--r--js/src/frontend/Parser.h4
2 files changed, 28 insertions, 50 deletions
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index c979e38c37..3a5b5d6d7c 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -7470,45 +7470,6 @@ Parser<ParseHandler>::condExpr1(InHandling inHandling, YieldHandling yieldHandli
return handler.newConditional(condition, thenExpr, elseExpr);
}
-template <typename ParseHandler>
-bool
-Parser<ParseHandler>::checkAndMarkAsAssignmentLhs(Node target, AssignmentFlavor flavor,
- PossibleError* possibleError)
-{
- MOZ_ASSERT(flavor != KeyedDestructuringAssignment,
- "destructuring must use special checking/marking code, not "
- "this method");
-
- if (handler.isUnparenthesizedDestructuringPattern(target)) {
- if (flavor == CompoundAssignment) {
- error(JSMSG_BAD_DESTRUCT_ASS);
- return false;
- }
-
- return checkDestructuringPattern(target, Nothing(), possibleError);
- }
-
- // All other permitted targets are simple.
- if (!reportIfNotValidSimpleAssignmentTarget(target, flavor))
- return false;
-
- if (handler.isPropertyAccess(target))
- return true;
-
- if (handler.isNameAnyParentheses(target)) {
- // The arguments/eval identifiers are simple in non-strict mode code,
- // but warn to discourage use nonetheless.
- if (!reportIfArgumentsEvalTarget(target))
- return false;
-
- handler.adjustGetToSet(target);
- return true;
- }
-
- MOZ_ASSERT(handler.isFunctionCall(target));
- return checkAssignmentToCall(target, JSMSG_BAD_LEFTSIDE_OF_ASS);
-}
-
class AutoClearInDestructuringDecl
{
ParseContext* pc_;
@@ -7553,6 +7514,8 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl
if (!tokenStream.getToken(&tt, TokenStream::Operand))
return null();
+ uint32_t exprOffset = pos().begin;
+
bool endsExpr;
if (tt == TOK_NAME) {
@@ -7752,9 +7715,33 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl
return lhs;
}
- AssignmentFlavor flavor = kind == PNK_ASSIGN ? PlainAssignment : CompoundAssignment;
- if (!checkAndMarkAsAssignmentLhs(lhs, flavor, &possibleErrorInner))
+ // Verify the left-hand side expression doesn't have a forbidden form.
+ if (handler.isUnparenthesizedDestructuringPattern(lhs)) {
+ if (kind != PNK_ASSIGN) {
+ error(JSMSG_BAD_DESTRUCT_ASS);
+ return null();
+ }
+
+ if (!checkDestructuringPattern(lhs, Nothing(), &possibleErrorInner))
+ return null();
+ } else if (handler.isNameAnyParentheses(lhs)) {
+ if (const char* chars = handler.nameIsArgumentsEvalAnyParentheses(lhs, context)) {
+ // |chars| is "arguments" or "eval" here.
+ if (!strictModeErrorAt(exprOffset, JSMSG_BAD_STRICT_ASSIGN, chars))
+ return null();
+ }
+
+ handler.adjustGetToSet(lhs);
+ } else if (handler.isPropertyAccess(lhs)) {
+ // Permitted: no additional testing/fixup needed.
+ } else if (handler.isFunctionCall(lhs)) {
+ if (!strictModeErrorAt(exprOffset, JSMSG_BAD_LEFTSIDE_OF_ASS))
+ return null();
+ } else {
+ errorAt(exprOffset, JSMSG_BAD_LEFTSIDE_OF_ASS);
return null();
+ }
+
if (!possibleErrorInner.checkForExpressionError())
return null();
@@ -7852,11 +7839,6 @@ Parser<ParseHandler>::reportIfNotValidSimpleAssignmentTarget(Node target, Assign
case KeyedDestructuringAssignment:
errnum = JSMSG_BAD_DESTRUCT_TARGET;
break;
-
- case PlainAssignment:
- case CompoundAssignment:
- errnum = JSMSG_BAD_LEFTSIDE_OF_ASS;
- break;
}
reportWithNode(ParseError, pc->sc()->strict(), target, errnum, extra);
diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h
index e3827d9535..70d382501a 100644
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -1332,15 +1332,11 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter
}
enum AssignmentFlavor {
- PlainAssignment,
- CompoundAssignment,
KeyedDestructuringAssignment,
IncrementAssignment,
DecrementAssignment,
};
- bool checkAndMarkAsAssignmentLhs(Node pn, AssignmentFlavor flavor,
- PossibleError* possibleError=nullptr);
bool matchInOrOf(bool* isForInp, bool* isForOfp);
bool hasUsedFunctionSpecialName(HandlePropertyName name);