diff options
Diffstat (limited to 'js/src/frontend/Parser.cpp')
-rw-r--r-- | js/src/frontend/Parser.cpp | 62 |
1 files changed, 26 insertions, 36 deletions
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index fe30328de..94573fce7 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -5417,37 +5417,6 @@ Parser<ParseHandler>::matchInOrOf(bool* isForInp, bool* isForOfp) template <class ParseHandler> bool -Parser<ParseHandler>::validateForInOrOfLHSExpression(Node target, PossibleError* possibleError) -{ - if (handler.isUnparenthesizedDestructuringPattern(target)) - return checkDestructuringPattern(target, Nothing(), possibleError); - - // All other permitted targets are simple. - if (!reportIfNotValidSimpleAssignmentTarget(target, ForInOrOfTarget)) - 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; - } - - if (handler.isFunctionCall(target)) - return checkAssignmentToCall(target, JSMSG_BAD_FOR_LEFTSIDE); - - reportWithNode(ParseError, false, target, JSMSG_BAD_FOR_LEFTSIDE); - return false; -} - -template <class ParseHandler> -bool Parser<ParseHandler>::forHeadStart(YieldHandling yieldHandling, ParseNodeKind* forHeadKind, Node* forInitialPart, @@ -5526,6 +5495,10 @@ Parser<ParseHandler>::forHeadStart(YieldHandling yieldHandling, return *forInitialPart != null(); } + uint32_t exprOffset; + if (!tokenStream.peekOffset(&exprOffset, TokenStream::Operand)) + return false; + // Finally, handle for-loops that start with expressions. Pass // |InProhibited| so that |in| isn't parsed in a RelationalExpression as a // binary operator. |in| makes it a for-in loop, *not* an |in| expression. @@ -5569,8 +5542,29 @@ Parser<ParseHandler>::forHeadStart(YieldHandling yieldHandling, *forHeadKind = isForIn ? PNK_FORIN : PNK_FOROF; - if (!validateForInOrOfLHSExpression(*forInitialPart, &possibleError)) + // Verify the left-hand side expression doesn't have a forbidden form. + if (handler.isUnparenthesizedDestructuringPattern(*forInitialPart)) { + if (!checkDestructuringPattern(*forInitialPart, Nothing(), &possibleError)) + return false; + } else if (handler.isNameAnyParentheses(*forInitialPart)) { + const char* chars = handler.nameIsArgumentsEvalAnyParentheses(*forInitialPart, context); + if (chars) { + // |chars| is "arguments" or "eval" here. + if (!strictModeErrorAt(exprOffset, JSMSG_BAD_STRICT_ASSIGN, chars)) + return false; + } + + handler.adjustGetToSet(*forInitialPart); + } else if (handler.isPropertyAccess(*forInitialPart)) { + // Permitted: no additional testing/fixup needed. + } else if (handler.isFunctionCall(*forInitialPart)) { + if (!strictModeErrorAt(exprOffset, JSMSG_BAD_FOR_LEFTSIDE)) + return false; + } else { + errorAt(exprOffset, JSMSG_BAD_FOR_LEFTSIDE); return false; + } + if (!possibleError.checkForExpressionError()) return false; @@ -7869,10 +7863,6 @@ Parser<ParseHandler>::reportIfNotValidSimpleAssignmentTarget(Node target, Assign case CompoundAssignment: errnum = JSMSG_BAD_LEFTSIDE_OF_ASS; break; - - case ForInOrOfTarget: - errnum = JSMSG_BAD_FOR_LEFTSIDE; - break; } reportWithNode(ParseError, pc->sc()->strict(), target, errnum, extra); |