Remove unused m_writtenVariables from the parser and related bits
[WebKit-https.git] / Source / JavaScriptCore / parser / Parser.cpp
1 /*
2  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4  *  Copyright (C) 2003, 2006-2010, 2013, 2016 Apple Inc. All rights reserved.
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Library General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Library General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Library General Public License
17  *  along with this library; see the file COPYING.LIB.  If not, write to
18  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #include "config.h"
24 #include "Parser.h"
25
26 #include "ASTBuilder.h"
27 #include "CodeBlock.h"
28 #include "Debugger.h"
29 #include "JSCJSValueInlines.h"
30 #include "Lexer.h"
31 #include "JSCInlines.h"
32 #include "SetForScope.h"
33 #include "SourceProvider.h"
34 #include "VM.h"
35 #include <utility>
36 #include <wtf/HashFunctions.h>
37 #include <wtf/StringPrintStream.h>
38 #include <wtf/WTFThreadData.h>
39
40
41 #define updateErrorMessage(shouldPrintToken, ...) do {\
42     propagateError(); \
43     logError(shouldPrintToken, __VA_ARGS__); \
44 } while (0)
45
46 #define propagateError() do { if (hasError()) return 0; } while (0)
47 #define internalFailWithMessage(shouldPrintToken, ...) do { updateErrorMessage(shouldPrintToken, __VA_ARGS__); return 0; } while (0)
48 #define handleErrorToken() do { if (m_token.m_type == EOFTOK || m_token.m_type & ErrorTokenFlag) { failDueToUnexpectedToken(); } } while (0)
49 #define failWithMessage(...) do { { handleErrorToken(); updateErrorMessage(true, __VA_ARGS__); } return 0; } while (0)
50 #define failWithStackOverflow() do { updateErrorMessage(false, "Stack exhausted"); m_hasStackOverflow = true; return 0; } while (0)
51 #define failIfFalse(cond, ...) do { if (!(cond)) { handleErrorToken(); internalFailWithMessage(true, __VA_ARGS__); } } while (0)
52 #define failIfTrue(cond, ...) do { if (cond) { handleErrorToken(); internalFailWithMessage(true, __VA_ARGS__); } } while (0)
53 #define failIfTrueIfStrict(cond, ...) do { if ((cond) && strictMode()) internalFailWithMessage(false, __VA_ARGS__); } while (0)
54 #define failIfFalseIfStrict(cond, ...) do { if ((!(cond)) && strictMode()) internalFailWithMessage(false, __VA_ARGS__); } while (0)
55 #define consumeOrFail(tokenType, ...) do { if (!consume(tokenType)) { handleErrorToken(); internalFailWithMessage(true, __VA_ARGS__); } } while (0)
56 #define consumeOrFailWithFlags(tokenType, flags, ...) do { if (!consume(tokenType, flags)) { handleErrorToken(); internalFailWithMessage(true, __VA_ARGS__); } } while (0)
57 #define matchOrFail(tokenType, ...) do { if (!match(tokenType)) { handleErrorToken(); internalFailWithMessage(true, __VA_ARGS__); } } while (0)
58 #define failIfStackOverflow() do { if (!canRecurse()) failWithStackOverflow(); } while (0)
59 #define semanticFail(...) do { internalFailWithMessage(false, __VA_ARGS__); } while (0)
60 #define semanticFailIfTrue(cond, ...) do { if (cond) internalFailWithMessage(false, __VA_ARGS__); } while (0)
61 #define semanticFailIfFalse(cond, ...) do { if (!(cond)) internalFailWithMessage(false, __VA_ARGS__); } while (0)
62 #define regexFail(failure) do { setErrorMessage(failure); return 0; } while (0)
63 #define failDueToUnexpectedToken() do {\
64         logError(true);\
65     return 0;\
66 } while (0)
67
68 #define handleProductionOrFail(token, tokenString, operation, production) do {\
69     consumeOrFail(token, "Expected '", tokenString, "' to ", operation, " a ", production);\
70 } while (0)
71
72 #define semanticFailureDueToKeyword(...) do { \
73     if (strictMode() && m_token.m_type == RESERVED_IF_STRICT) \
74         semanticFail("Cannot use the reserved word '", getToken(), "' as a ", __VA_ARGS__, " in strict mode"); \
75     if (m_token.m_type == RESERVED || m_token.m_type == RESERVED_IF_STRICT) \
76         semanticFail("Cannot use the reserved word '", getToken(), "' as a ", __VA_ARGS__); \
77     if (m_token.m_type & KeywordTokenFlag) \
78         semanticFail("Cannot use the keyword '", getToken(), "' as a ", __VA_ARGS__); \
79 } while (0)
80
81 using namespace std;
82
83 namespace JSC {
84
85 template <typename LexerType>
86 void Parser<LexerType>::logError(bool)
87 {
88     if (hasError())
89         return;
90     StringPrintStream stream;
91     printUnexpectedTokenText(stream);
92     setErrorMessage(stream.toString());
93 }
94
95 template <typename LexerType> template <typename A>
96 void Parser<LexerType>::logError(bool shouldPrintToken, const A& value1)
97 {
98     if (hasError())
99         return;
100     StringPrintStream stream;
101     if (shouldPrintToken) {
102         printUnexpectedTokenText(stream);
103         stream.print(". ");
104     }
105     stream.print(value1, ".");
106     setErrorMessage(stream.toString());
107 }
108
109 template <typename LexerType> template <typename A, typename B>
110 void Parser<LexerType>::logError(bool shouldPrintToken, const A& value1, const B& value2)
111 {
112     if (hasError())
113         return;
114     StringPrintStream stream;
115     if (shouldPrintToken) {
116         printUnexpectedTokenText(stream);
117         stream.print(". ");
118     }
119     stream.print(value1, value2, ".");
120     setErrorMessage(stream.toString());
121 }
122
123 template <typename LexerType> template <typename A, typename B, typename C>
124 void Parser<LexerType>::logError(bool shouldPrintToken, const A& value1, const B& value2, const C& value3)
125 {
126     if (hasError())
127         return;
128     StringPrintStream stream;
129     if (shouldPrintToken) {
130         printUnexpectedTokenText(stream);
131         stream.print(". ");
132     }
133     stream.print(value1, value2, value3, ".");
134     setErrorMessage(stream.toString());
135 }
136
137 template <typename LexerType> template <typename A, typename B, typename C, typename D>
138 void Parser<LexerType>::logError(bool shouldPrintToken, const A& value1, const B& value2, const C& value3, const D& value4)
139 {
140     if (hasError())
141         return;
142     StringPrintStream stream;
143     if (shouldPrintToken) {
144         printUnexpectedTokenText(stream);
145         stream.print(". ");
146     }
147     stream.print(value1, value2, value3, value4, ".");
148     setErrorMessage(stream.toString());
149 }
150
151 template <typename LexerType> template <typename A, typename B, typename C, typename D, typename E>
152 void Parser<LexerType>::logError(bool shouldPrintToken, const A& value1, const B& value2, const C& value3, const D& value4, const E& value5)
153 {
154     if (hasError())
155         return;
156     StringPrintStream stream;
157     if (shouldPrintToken) {
158         printUnexpectedTokenText(stream);
159         stream.print(". ");
160     }
161     stream.print(value1, value2, value3, value4, value5, ".");
162     setErrorMessage(stream.toString());
163 }
164
165 template <typename LexerType> template <typename A, typename B, typename C, typename D, typename E, typename F>
166 void Parser<LexerType>::logError(bool shouldPrintToken, const A& value1, const B& value2, const C& value3, const D& value4, const E& value5, const F& value6)
167 {
168     if (hasError())
169         return;
170     StringPrintStream stream;
171     if (shouldPrintToken) {
172         printUnexpectedTokenText(stream);
173         stream.print(". ");
174     }
175     stream.print(value1, value2, value3, value4, value5, value6, ".");
176     setErrorMessage(stream.toString());
177 }
178
179 template <typename LexerType> template <typename A, typename B, typename C, typename D, typename E, typename F, typename G>
180 void Parser<LexerType>::logError(bool shouldPrintToken, const A& value1, const B& value2, const C& value3, const D& value4, const E& value5, const F& value6, const G& value7)
181 {
182     if (hasError())
183         return;
184     StringPrintStream stream;
185     if (shouldPrintToken) {
186         printUnexpectedTokenText(stream);
187         stream.print(". ");
188     }
189     stream.print(value1, value2, value3, value4, value5, value6, value7, ".");
190     setErrorMessage(stream.toString());
191 }
192
193 template <typename LexerType>
194 Parser<LexerType>::Parser(VM* vm, const SourceCode& source, JSParserBuiltinMode builtinMode, JSParserStrictMode strictMode, SourceParseMode parseMode, SuperBinding superBinding, ConstructorKind defaultConstructorKind, ThisTDZMode thisTDZMode, DerivedContextType derivedContextType, bool isEvalContext, EvalContextType evalContextType)
195     : m_vm(vm)
196     , m_source(&source)
197     , m_hasStackOverflow(false)
198     , m_allowsIn(true)
199     , m_syntaxAlreadyValidated(source.provider()->isValid())
200     , m_statementDepth(0)
201     , m_sourceElements(0)
202     , m_parsingBuiltin(builtinMode == JSParserBuiltinMode::Builtin)
203     , m_superBinding(superBinding)
204     , m_defaultConstructorKind(defaultConstructorKind)
205     , m_thisTDZMode(thisTDZMode)
206     , m_immediateParentAllowsFunctionDeclarationInStatement(false)
207 {
208     m_lexer = std::make_unique<LexerType>(vm, builtinMode);
209     m_lexer->setCode(source, &m_parserArena);
210     m_token.m_location.line = source.firstLine();
211     m_token.m_location.startOffset = source.startOffset();
212     m_token.m_location.endOffset = source.startOffset();
213     m_token.m_location.lineStartOffset = source.startOffset();
214     m_functionCache = vm->addSourceProviderCache(source.provider());
215     m_expressionErrorClassifier = nullptr;
216
217     ScopeRef scope = pushScope();
218     scope->setSourceParseMode(parseMode);
219     scope->setIsEvalContext(isEvalContext);
220     if (isEvalContext)
221         scope->setEvalContextType(evalContextType);
222     
223     if (derivedContextType == DerivedContextType::DerivedConstructorContext) {
224         scope->setConstructorKind(ConstructorKind::Derived);
225         scope->setExpectedSuperBinding(SuperBinding::Needed);
226     }
227     
228     if (derivedContextType == DerivedContextType::DerivedMethodContext)
229         scope->setExpectedSuperBinding(SuperBinding::Needed);
230
231     if (strictMode == JSParserStrictMode::Strict)
232         scope->setStrictMode();
233
234     next();
235 }
236
237 template <typename LexerType>
238 Parser<LexerType>::~Parser()
239 {
240 }
241
242 template <typename LexerType>
243 String Parser<LexerType>::parseInner(const Identifier& calleeName, SourceParseMode parseMode)
244 {
245     String parseError = String();
246
247     ASTBuilder context(const_cast<VM*>(m_vm), m_parserArena, const_cast<SourceCode*>(m_source));
248     ScopeRef scope = currentScope();
249     scope->setIsLexicalScope();
250     SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body);
251
252     bool isArrowFunctionBodyExpression = false;
253     if (m_lexer->isReparsingFunction()) {
254         ParserFunctionInfo<ASTBuilder> functionInfo;
255         if (parseMode == SourceParseMode::GeneratorBodyMode)
256             functionInfo.parameters = createGeneratorParameters(context);
257         else
258             parseFunctionParameters(context, parseMode, functionInfo);
259         m_parameters = functionInfo.parameters;
260
261         if (parseMode == SourceParseMode::ArrowFunctionMode && !hasError()) {
262             // The only way we could have an error wile reparsing is if we run out of stack space.
263             RELEASE_ASSERT(match(ARROWFUNCTION));
264             next();
265             isArrowFunctionBodyExpression = !match(OPENBRACE);
266         }
267     }
268
269     if (!calleeName.isNull())
270         scope->declareCallee(&calleeName);
271
272     if (m_lexer->isReparsingFunction())
273         m_statementDepth--;
274
275     SourceElements* sourceElements = nullptr;
276     // The only way we can error this early is if we reparse a function and we run out of stack space.
277     if (!hasError()) {
278         if (isArrowFunctionBodyExpression)
279             sourceElements = parseArrowFunctionSingleExpressionBodySourceElements(context);
280         else if (isModuleParseMode(parseMode))
281             sourceElements = parseModuleSourceElements(context, parseMode);
282         else {
283             if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode)
284                 sourceElements = parseGeneratorFunctionSourceElements(context, CheckForStrictMode);
285             else
286                 sourceElements = parseSourceElements(context, CheckForStrictMode);
287         }
288     }
289
290     bool validEnding = consume(EOFTOK);
291     if (!sourceElements || !validEnding) {
292         if (hasError())
293             parseError = m_errorMessage;
294         else
295             parseError = ASCIILiteral("Parser error");
296     }
297
298     IdentifierSet capturedVariables;
299     UniquedStringImplPtrSet sloppyModeHoistedFunctions;
300     scope->getSloppyModeHoistedFunctions(sloppyModeHoistedFunctions);
301     scope->getCapturedVars(capturedVariables);
302
303     VariableEnvironment& varDeclarations = scope->declaredVariables();
304     for (auto& entry : capturedVariables)
305         varDeclarations.markVariableAsCaptured(entry);
306
307     if (parseMode == SourceParseMode::GeneratorWrapperFunctionMode) {
308         if (scope->usedVariablesContains(m_vm->propertyNames->arguments.impl()))
309             context.propagateArgumentsUse();
310     }
311
312     CodeFeatures features = context.features();
313     if (scope->strictMode())
314         features |= StrictModeFeature;
315     if (scope->shadowsArguments())
316         features |= ShadowsArgumentsFeature;
317
318 #ifndef NDEBUG
319     if (m_parsingBuiltin && isProgramParseMode(parseMode)) {
320         VariableEnvironment& lexicalVariables = scope->lexicalVariables();
321         const IdentifierSet& closedVariableCandidates = scope->closedVariableCandidates();
322         const BuiltinNames& builtinNames = m_vm->propertyNames->builtinNames();
323         for (const RefPtr<UniquedStringImpl>& candidate : closedVariableCandidates) {
324             if (!lexicalVariables.contains(candidate) && !varDeclarations.contains(candidate) && !builtinNames.isPrivateName(*candidate.get())) {
325                 dataLog("Bad global capture in builtin: '", candidate, "'\n");
326                 dataLog(m_source->view());
327                 CRASH();
328             }
329         }
330     }
331 #endif // NDEBUG
332     didFinishParsing(sourceElements, scope->takeFunctionDeclarations(), varDeclarations, WTFMove(sloppyModeHoistedFunctions), features, context.numConstants());
333
334     return parseError;
335 }
336
337 template <typename LexerType>
338 void Parser<LexerType>::didFinishParsing(SourceElements* sourceElements, DeclarationStacks::FunctionStack&& funcStack, 
339     VariableEnvironment& varDeclarations, UniquedStringImplPtrSet&& sloppyModeHoistedFunctions, CodeFeatures features, int numConstants)
340 {
341     m_sourceElements = sourceElements;
342     m_funcDeclarations = WTFMove(funcStack);
343     m_varDeclarations.swap(varDeclarations);
344     m_features = features;
345     m_sloppyModeHoistedFunctions = WTFMove(sloppyModeHoistedFunctions);
346     m_numConstants = numConstants;
347 }
348
349 template <typename LexerType>
350 bool Parser<LexerType>::isArrowFunctionParameters()
351 {
352     bool isOpenParen = match(OPENPAREN);
353     bool isIdent = match(IDENT);
354     
355     if (!isOpenParen && !isIdent)
356         return false;
357
358     bool isArrowFunction = false;
359     SavePoint saveArrowFunctionPoint = createSavePoint();
360         
361     if (isIdent) {
362         next();
363         isArrowFunction = match(ARROWFUNCTION);
364     } else {
365         RELEASE_ASSERT(isOpenParen);
366         next();
367         if (match(CLOSEPAREN)) {
368             next();
369             isArrowFunction = match(ARROWFUNCTION);
370         } else {
371             SyntaxChecker syntaxChecker(const_cast<VM*>(m_vm), m_lexer.get());
372             // We make fake scope, otherwise parseFormalParameters will add variable to current scope that lead to errors
373             AutoPopScopeRef fakeScope(this, pushScope());
374             fakeScope->setSourceParseMode(SourceParseMode::ArrowFunctionMode);
375
376             unsigned parametersCount = 0;
377             isArrowFunction = parseFormalParameters(syntaxChecker, syntaxChecker.createFormalParameterList(), parametersCount) && consume(CLOSEPAREN) && match(ARROWFUNCTION);
378                 
379             popScope(fakeScope, syntaxChecker.NeedsFreeVariableInfo);
380         }
381     }
382         
383     restoreSavePoint(saveArrowFunctionPoint);
384         
385     return isArrowFunction;
386 }
387
388 template <typename LexerType>
389 bool Parser<LexerType>::allowAutomaticSemicolon()
390 {
391     return match(CLOSEBRACE) || match(EOFTOK) || m_lexer->prevTerminator();
392 }
393
394 template <typename LexerType>
395 template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseSourceElements(TreeBuilder& context, SourceElementsMode mode)
396 {
397     const unsigned lengthOfUseStrictLiteral = 12; // "use strict".length
398     TreeSourceElements sourceElements = context.createSourceElements();
399     bool seenNonDirective = false;
400     const Identifier* directive = 0;
401     unsigned directiveLiteralLength = 0;
402     auto savePoint = createSavePoint();
403     bool hasSetStrict = false;
404     
405     while (TreeStatement statement = parseStatementListItem(context, directive, &directiveLiteralLength)) {
406         if (mode == CheckForStrictMode && !seenNonDirective) {
407             if (directive) {
408                 // "use strict" must be the exact literal without escape sequences or line continuation.
409                 if (!hasSetStrict && directiveLiteralLength == lengthOfUseStrictLiteral && m_vm->propertyNames->useStrictIdentifier == *directive) {
410                     setStrictMode();
411                     hasSetStrict = true;
412                     if (!isValidStrictMode()) {
413                         if (m_parserState.lastFunctionName) {
414                             if (m_vm->propertyNames->arguments == *m_parserState.lastFunctionName)
415                                 semanticFail("Cannot name a function 'arguments' in strict mode");
416                             if (m_vm->propertyNames->eval == *m_parserState.lastFunctionName)
417                                 semanticFail("Cannot name a function 'eval' in strict mode");
418                         }
419                         if (hasDeclaredVariable(m_vm->propertyNames->arguments))
420                             semanticFail("Cannot declare a variable named 'arguments' in strict mode");
421                         if (hasDeclaredVariable(m_vm->propertyNames->eval))
422                             semanticFail("Cannot declare a variable named 'eval' in strict mode");
423                         semanticFailIfFalse(isValidStrictMode(), "Invalid parameters or function name in strict mode");
424                     }
425                     restoreSavePoint(savePoint);
426                     propagateError();
427                     continue;
428                 }
429             } else
430                 seenNonDirective = true;
431         }
432         context.appendStatement(sourceElements, statement);
433     }
434
435     propagateError();
436     return sourceElements;
437 }
438
439 template <typename LexerType>
440 template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseModuleSourceElements(TreeBuilder& context, SourceParseMode parseMode)
441 {
442     TreeSourceElements sourceElements = context.createSourceElements();
443     SyntaxChecker syntaxChecker(const_cast<VM*>(m_vm), m_lexer.get());
444
445     while (true) {
446         TreeStatement statement = 0;
447         if (match(IMPORT))
448             statement = parseImportDeclaration(context);
449         else if (match(EXPORT))
450             statement = parseExportDeclaration(context);
451         else {
452             const Identifier* directive = 0;
453             unsigned directiveLiteralLength = 0;
454             if (parseMode == SourceParseMode::ModuleAnalyzeMode) {
455                 if (!parseStatementListItem(syntaxChecker, directive, &directiveLiteralLength))
456                     break;
457                 continue;
458             }
459             statement = parseStatementListItem(context, directive, &directiveLiteralLength);
460         }
461
462         if (!statement)
463             break;
464         context.appendStatement(sourceElements, statement);
465     }
466
467     propagateError();
468
469     for (const auto& uid : currentScope()->moduleScopeData().exportedBindings()) {
470         if (currentScope()->hasDeclaredVariable(uid)) {
471             currentScope()->declaredVariables().markVariableAsExported(uid);
472             continue;
473         }
474
475         if (currentScope()->hasLexicallyDeclaredVariable(uid)) {
476             currentScope()->lexicalVariables().markVariableAsExported(uid);
477             continue;
478         }
479
480         semanticFail("Exported binding '", uid.get(), "' needs to refer to a top-level declared variable");
481     }
482
483     return sourceElements;
484 }
485
486 template <typename LexerType>
487 template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseGeneratorFunctionSourceElements(TreeBuilder& context, SourceElementsMode mode)
488 {
489     auto sourceElements = context.createSourceElements();
490
491     unsigned functionKeywordStart = tokenStart();
492     JSTokenLocation startLocation(tokenLocation());
493     JSTextPosition start = tokenStartPosition();
494     unsigned startColumn = tokenColumn();
495     int functionNameStart = m_token.m_location.startOffset;
496     int parametersStart = m_token.m_location.startOffset;
497
498     ParserFunctionInfo<TreeBuilder> info;
499     info.name = &m_vm->propertyNames->nullIdentifier;
500     info.parameters = createGeneratorParameters(context);
501     info.startOffset = parametersStart;
502     info.startLine = tokenLine();
503     info.parameterCount = 4; // generator, state, value, resume mode
504
505     {
506         AutoPopScopeRef generatorBodyScope(this, pushScope());
507         generatorBodyScope->setSourceParseMode(SourceParseMode::GeneratorBodyMode);
508         SyntaxChecker generatorFunctionContext(const_cast<VM*>(m_vm), m_lexer.get());
509         failIfFalse(parseSourceElements(generatorFunctionContext, mode), "Cannot parse the body of a generator");
510         popScope(generatorBodyScope, TreeBuilder::NeedsFreeVariableInfo);
511     }
512     info.body = context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, tokenColumn(), functionKeywordStart, functionNameStart, parametersStart, strictMode(), ConstructorKind::None, m_superBinding, info.parameterCount, SourceParseMode::GeneratorBodyMode, false);
513
514     info.endLine = tokenLine();
515     info.endOffset = m_token.m_data.offset;
516     info.bodyStartColumn = startColumn;
517
518     auto functionExpr = context.createFunctionExpr(startLocation, info);
519     auto statement = context.createExprStatement(startLocation, functionExpr, start, m_lastTokenEndPosition.line);
520     context.appendStatement(sourceElements, statement);
521
522     return sourceElements;
523 }
524
525 template <typename LexerType>
526 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatementListItem(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength)
527 {
528     // The grammar is documented here:
529     // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-statements
530     DepthManager statementDepth(&m_statementDepth);
531     m_statementDepth++;
532     TreeStatement result = 0;
533     bool shouldSetEndOffset = true;
534     switch (m_token.m_type) {
535     case CONSTTOKEN:
536         result = parseVariableDeclaration(context, DeclarationType::ConstDeclaration);
537         break;
538     case LET: {
539         bool shouldParseVariableDeclaration = true;
540         if (!strictMode()) {
541             SavePoint savePoint = createSavePoint();
542             next();
543             // Intentionally use `match(IDENT) || match(LET) || match(YIELD)` and don't use `matchSpecIdentifier()`.
544             // We would like to fall into parseVariableDeclaration path even if "yield" is not treated as an Identifier.
545             // For example, under a generator context, matchSpecIdentifier() for "yield" returns `false`.
546             // But we would like to enter parseVariableDeclaration and raise an error under the context of parseVariableDeclaration
547             // to raise consistent errors between "var", "const" and "let".
548             if (!(match(IDENT) || match(LET) || match(YIELD)) && !match(OPENBRACE) && !match(OPENBRACKET))
549                 shouldParseVariableDeclaration = false;
550             restoreSavePoint(savePoint);
551         }
552         if (shouldParseVariableDeclaration)
553             result = parseVariableDeclaration(context, DeclarationType::LetDeclaration);
554         else {
555             bool allowFunctionDeclarationAsStatement = true;
556             result = parseExpressionOrLabelStatement(context, allowFunctionDeclarationAsStatement);
557         }
558
559         break;
560     }
561     case CLASSTOKEN:
562         result = parseClassDeclaration(context);
563         break;
564     case FUNCTION:
565         result = parseFunctionDeclaration(context);
566         break;
567     case IDENT:
568     case YIELD: {
569         // This is a convenient place to notice labeled statements
570         // (even though we also parse them as normal statements)
571         // because we allow the following type of code in sloppy mode:
572         // ``` function foo() { label: function bar() { } } ```
573         bool allowFunctionDeclarationAsStatement = true;
574         result = parseExpressionOrLabelStatement(context, allowFunctionDeclarationAsStatement);
575         break;
576     }
577     default:
578         m_statementDepth--; // parseStatement() increments the depth.
579         result = parseStatement(context, directive, directiveLiteralLength);
580         shouldSetEndOffset = false;
581         break;
582     }
583
584     if (result && shouldSetEndOffset)
585         context.setEndOffset(result, m_lastTokenEndPosition.offset);
586
587     return result;
588 }
589
590 template <typename LexerType>
591 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseVariableDeclaration(TreeBuilder& context, DeclarationType declarationType, ExportType exportType)
592 {
593     ASSERT(match(VAR) || match(LET) || match(CONSTTOKEN));
594     JSTokenLocation location(tokenLocation());
595     int start = tokenLine();
596     int end = 0;
597     int scratch;
598     TreeDestructuringPattern scratch1 = 0;
599     TreeExpression scratch2 = 0;
600     JSTextPosition scratch3;
601     bool scratchBool;
602     TreeExpression variableDecls = parseVariableDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3, VarDeclarationContext, declarationType, exportType, scratchBool);
603     propagateError();
604     failIfFalse(autoSemiColon(), "Expected ';' after variable declaration");
605     
606     return context.createDeclarationStatement(location, variableDecls, start, end);
607 }
608
609 template <typename LexerType>
610 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseDoWhileStatement(TreeBuilder& context)
611 {
612     ASSERT(match(DO));
613     int startLine = tokenLine();
614     next();
615     const Identifier* unused = 0;
616     startLoop();
617     TreeStatement statement = parseStatement(context, unused);
618     endLoop();
619     failIfFalse(statement, "Expected a statement following 'do'");
620     int endLine = tokenLine();
621     JSTokenLocation location(tokenLocation());
622     handleProductionOrFail(WHILE, "while", "end", "do-while loop");
623     handleProductionOrFail(OPENPAREN, "(", "start", "do-while loop condition");
624     semanticFailIfTrue(match(CLOSEPAREN), "Must provide an expression as a do-while loop condition");
625     TreeExpression expr = parseExpression(context);
626     failIfFalse(expr, "Unable to parse do-while loop condition");
627     handleProductionOrFail(CLOSEPAREN, ")", "end", "do-while loop condition");
628     if (match(SEMICOLON))
629         next(); // Always performs automatic semicolon insertion.
630     return context.createDoWhileStatement(location, statement, expr, startLine, endLine);
631 }
632
633 template <typename LexerType>
634 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWhileStatement(TreeBuilder& context)
635 {
636     ASSERT(match(WHILE));
637     JSTokenLocation location(tokenLocation());
638     int startLine = tokenLine();
639     next();
640     
641     handleProductionOrFail(OPENPAREN, "(", "start", "while loop condition");
642     semanticFailIfTrue(match(CLOSEPAREN), "Must provide an expression as a while loop condition");
643     TreeExpression expr = parseExpression(context);
644     failIfFalse(expr, "Unable to parse while loop condition");
645     int endLine = tokenLine();
646     handleProductionOrFail(CLOSEPAREN, ")", "end", "while loop condition");
647     
648     const Identifier* unused = 0;
649     startLoop();
650     TreeStatement statement = parseStatement(context, unused);
651     endLoop();
652     failIfFalse(statement, "Expected a statement as the body of a while loop");
653     return context.createWhileStatement(location, expr, statement, startLine, endLine);
654 }
655
656 template <typename LexerType>
657 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVariableDeclarationList(TreeBuilder& context, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext declarationListContext, DeclarationType declarationType, ExportType exportType, bool& forLoopConstDoesNotHaveInitializer)
658 {
659     ASSERT(declarationType == DeclarationType::LetDeclaration || declarationType == DeclarationType::VarDeclaration || declarationType == DeclarationType::ConstDeclaration);
660     TreeExpression head = 0;
661     TreeExpression tail = 0;
662     const Identifier* lastIdent;
663     JSToken lastIdentToken; 
664     AssignmentContext assignmentContext = assignmentContextFromDeclarationType(declarationType);
665     do {
666         lastIdent = 0;
667         lastPattern = TreeDestructuringPattern(0);
668         JSTokenLocation location(tokenLocation());
669         next();
670         TreeExpression node = 0;
671         declarations++;
672         bool hasInitializer = false;
673         if (matchSpecIdentifier()) {
674             failIfTrue(match(LET) && (declarationType == DeclarationType::LetDeclaration || declarationType == DeclarationType::ConstDeclaration), 
675                 "Can't use 'let' as an identifier name for a LexicalDeclaration");
676             JSTextPosition varStart = tokenStartPosition();
677             JSTokenLocation varStartLocation(tokenLocation());
678             identStart = varStart;
679             const Identifier* name = m_token.m_data.ident;
680             lastIdent = name;
681             lastIdentToken = m_token;
682             next();
683             hasInitializer = match(EQUAL);
684             DeclarationResultMask declarationResult = declareVariable(name, declarationType);
685             if (declarationResult != DeclarationResult::Valid) {
686                 failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare a variable named ", name->impl(), " in strict mode");
687                 if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration) {
688                     if (declarationType == DeclarationType::LetDeclaration) 
689                         internalFailWithMessage(false, "Cannot declare a let variable twice: '", name->impl(), "'");
690                     if (declarationType == DeclarationType::ConstDeclaration)
691                         internalFailWithMessage(false, "Cannot declare a const variable twice: '", name->impl(), "'");
692                     ASSERT(declarationType == DeclarationType::VarDeclaration);
693                     internalFailWithMessage(false, "Cannot declare a var variable that shadows a let/const/class variable: '", name->impl(), "'");
694                 }
695             }
696             if (exportType == ExportType::Exported) {
697                 semanticFailIfFalse(exportName(*name), "Cannot export a duplicate name '", name->impl(), "'");
698                 currentScope()->moduleScopeData().exportBinding(*name);
699             }
700
701             if (hasInitializer) {
702                 JSTextPosition varDivot = tokenStartPosition() + 1;
703                 initStart = tokenStartPosition();
704                 next(TreeBuilder::DontBuildStrings); // consume '='
705                 propagateError();
706                 TreeExpression initializer = parseAssignmentExpression(context);
707                 initEnd = lastTokenEndPosition();
708                 lastInitializer = initializer;
709                 failIfFalse(initializer, "Expected expression as the intializer for the variable '", name->impl(), "'");
710                 
711                 node = context.createAssignResolve(location, *name, initializer, varStart, varDivot, lastTokenEndPosition(), assignmentContext);
712             } else {
713                 if (declarationListContext == ForLoopContext && declarationType == DeclarationType::ConstDeclaration)
714                     forLoopConstDoesNotHaveInitializer = true;
715                 failIfTrue(declarationListContext != ForLoopContext && declarationType == DeclarationType::ConstDeclaration, "const declared variable '", name->impl(), "'", " must have an initializer");
716                 if (declarationType == DeclarationType::VarDeclaration)
717                     node = context.createEmptyVarExpression(varStartLocation, *name);
718                 else
719                     node = context.createEmptyLetExpression(varStartLocation, *name);
720             }
721         } else {
722             lastIdent = 0;
723             auto pattern = parseDestructuringPattern(context, destructuringKindFromDeclarationType(declarationType), exportType, nullptr, nullptr, assignmentContext);
724             failIfFalse(pattern, "Cannot parse this destructuring pattern");
725             hasInitializer = match(EQUAL);
726             failIfTrue(declarationListContext == VarDeclarationContext && !hasInitializer, "Expected an initializer in destructuring variable declaration");
727             lastPattern = pattern;
728             if (hasInitializer) {
729                 next(TreeBuilder::DontBuildStrings); // consume '='
730                 TreeExpression rhs = parseAssignmentExpression(context);
731                 node = context.createDestructuringAssignment(location, pattern, rhs);
732                 lastInitializer = rhs;
733             }
734         }
735
736         if (node) {
737             if (!head)
738                 head = node;
739             else if (!tail) {
740                 head = context.createCommaExpr(location, head);
741                 tail = context.appendToCommaExpr(location, head, head, node);
742             } else
743                 tail = context.appendToCommaExpr(location, head, tail, node);
744         }
745     } while (match(COMMA));
746     if (lastIdent)
747         lastPattern = context.createBindingLocation(lastIdentToken.m_location, *lastIdent, lastIdentToken.m_startPosition, lastIdentToken.m_endPosition, assignmentContext);
748
749     return head;
750 }
751
752 template <typename LexerType>
753 bool Parser<LexerType>::declareRestOrNormalParameter(const Identifier& name, const Identifier** duplicateIdentifier)
754 {
755     DeclarationResultMask declarationResult = declareParameter(&name);
756     if ((declarationResult & DeclarationResult::InvalidStrictMode) && strictMode()) {
757         semanticFailIfTrue(isEvalOrArguments(&name), "Cannot destructure to a parameter name '", name.impl(), "' in strict mode");
758         if (m_parserState.lastFunctionName && name == *m_parserState.lastFunctionName)
759             semanticFail("Cannot declare a parameter named '", name.impl(), "' as it shadows the name of a strict mode function");
760         semanticFailureDueToKeyword("parameter name");
761         if (hasDeclaredParameter(name))
762             semanticFail("Cannot declare a parameter named '", name.impl(), "' in strict mode as it has already been declared");
763         semanticFail("Cannot declare a parameter named '", name.impl(), "' in strict mode");
764     }
765     if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration) {
766         // It's not always an error to define a duplicate parameter.
767         // It's only an error when there are default parameter values or destructuring parameters.
768         // We note this value now so we can check it later.
769         if (duplicateIdentifier)
770             *duplicateIdentifier = &name;
771     }
772
773     return true;
774 }
775
776 template <typename LexerType>
777 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::createBindingPattern(TreeBuilder& context, DestructuringKind kind, ExportType exportType, const Identifier& name, JSToken token, AssignmentContext bindingContext, const Identifier** duplicateIdentifier)
778 {
779     ASSERT(!name.isNull());
780     
781     ASSERT(name.impl()->isAtomic() || name.impl()->isSymbol());
782
783     switch (kind) {
784     case DestructuringKind::DestructureToVariables: {
785         DeclarationResultMask declarationResult = declareVariable(&name);
786         failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare a variable named '", name.impl(), "' in strict mode");
787         if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
788             internalFailWithMessage(false, "Cannot declare a var variable that shadows a let/const/class variable: '", name.impl(), "'");
789         break;
790     }
791
792     case DestructuringKind::DestructureToLet:
793     case DestructuringKind::DestructureToConst:
794     case DestructuringKind::DestructureToCatchParameters: {
795         DeclarationResultMask declarationResult = declareVariable(&name, kind == DestructuringKind::DestructureToConst ? DeclarationType::ConstDeclaration : DeclarationType::LetDeclaration);
796         if (declarationResult != DeclarationResult::Valid) {
797             failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot destructure to a variable named '", name.impl(), "' in strict mode");
798             failIfTrue(declarationResult & DeclarationResult::InvalidDuplicateDeclaration, "Cannot declare a lexical variable twice: '", name.impl(), "'");
799         }
800         break;
801     }
802
803     case DestructuringKind::DestructureToParameters: {
804         declareRestOrNormalParameter(name, duplicateIdentifier);
805         propagateError();
806         break;
807     }
808
809     case DestructuringKind::DestructureToExpressions: {
810         break;
811     }
812     }
813
814     if (exportType == ExportType::Exported) {
815         semanticFailIfFalse(exportName(name), "Cannot export a duplicate name '", name.impl(), "'");
816         currentScope()->moduleScopeData().exportBinding(name);
817     }
818     return context.createBindingLocation(token.m_location, name, token.m_startPosition, token.m_endPosition, bindingContext);
819 }
820
821 template <typename LexerType>
822 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern Parser<LexerType>::createAssignmentElement(TreeBuilder& context, TreeExpression& assignmentTarget, const JSTextPosition& startPosition, const JSTextPosition& endPosition)
823 {
824     return context.createAssignmentElement(assignmentTarget, startPosition, endPosition);
825 }
826
827 template <typename LexerType>
828 template <class TreeBuilder> TreeSourceElements Parser<LexerType>::parseArrowFunctionSingleExpressionBodySourceElements(TreeBuilder& context)
829 {
830     ASSERT(!match(OPENBRACE));
831
832     JSTokenLocation location(tokenLocation());
833     JSTextPosition start = tokenStartPosition();
834
835     failIfStackOverflow();
836     TreeExpression expr = parseAssignmentExpression(context);
837     failIfFalse(expr, "Cannot parse the arrow function expression");
838     
839     context.setEndOffset(expr, m_lastTokenEndPosition.offset);
840
841     JSTextPosition end = tokenEndPosition();
842     
843     TreeSourceElements sourceElements = context.createSourceElements();
844     TreeStatement body = context.createReturnStatement(location, expr, start, end);
845     context.setEndOffset(body, m_lastTokenEndPosition.offset);
846     context.appendStatement(sourceElements, body);
847
848     return sourceElements;
849 }
850
851 template <typename LexerType>
852 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::tryParseDestructuringPatternExpression(TreeBuilder& context, AssignmentContext bindingContext)
853 {
854     return parseDestructuringPattern(context, DestructuringKind::DestructureToExpressions, ExportType::NotExported, nullptr, nullptr, bindingContext);
855 }
856
857 template <typename LexerType>
858 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseBindingOrAssignmentElement(TreeBuilder& context, DestructuringKind kind, ExportType exportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth)
859 {
860     if (kind == DestructuringKind::DestructureToExpressions)
861         return parseAssignmentElement(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth);
862     return parseDestructuringPattern(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth);
863 }
864
865 template <typename LexerType>
866 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseAssignmentElement(TreeBuilder& context, DestructuringKind kind, ExportType exportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth)
867 {
868     TreeDestructuringPattern assignmentTarget = 0;
869
870     if (match(OPENBRACE) || match(OPENBRACKET)) {
871         SavePoint savePoint = createSavePoint();
872         assignmentTarget = parseDestructuringPattern(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth);
873         if (assignmentTarget && !match(DOT) && !match(OPENBRACKET) && !match(OPENPAREN) && !match(TEMPLATE))
874             return assignmentTarget;
875         restoreSavePoint(savePoint);
876     }
877
878     JSTextPosition startPosition = tokenStartPosition();
879     auto element = parseMemberExpression(context);
880
881     semanticFailIfFalse(element && context.isAssignmentLocation(element), "Invalid destructuring assignment target");
882
883     if (strictMode() && m_parserState.lastIdentifier && context.isResolve(element)) {
884         bool isEvalOrArguments = m_vm->propertyNames->eval == *m_parserState.lastIdentifier || m_vm->propertyNames->arguments == *m_parserState.lastIdentifier;
885         failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", m_parserState.lastIdentifier->impl(), "' in strict mode");
886     }
887
888     return createAssignmentElement(context, element, startPosition, lastTokenEndPosition());
889 }
890
891 static const char* destructuringKindToVariableKindName(DestructuringKind kind)
892 {
893     switch (kind) {
894     case DestructuringKind::DestructureToLet:
895     case DestructuringKind::DestructureToConst:
896         return "lexical variable name";
897     case DestructuringKind::DestructureToVariables:
898         return "variable name";
899     case DestructuringKind::DestructureToParameters:
900         return "parameter name";
901     case DestructuringKind::DestructureToCatchParameters:
902         return "catch parameter name";
903     case DestructuringKind::DestructureToExpressions:
904         return "expression name";
905     }
906     RELEASE_ASSERT_NOT_REACHED();
907     return "invalid";
908 }
909
910 template <typename LexerType>
911 template <class TreeBuilder> TreeDestructuringPattern Parser<LexerType>::parseDestructuringPattern(TreeBuilder& context, DestructuringKind kind, ExportType exportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth)
912 {
913     failIfStackOverflow();
914     int nonLHSCount = m_parserState.nonLHSCount;
915     TreeDestructuringPattern pattern;
916     switch (m_token.m_type) {
917     case OPENBRACKET: {
918         JSTextPosition divotStart = tokenStartPosition();
919         auto arrayPattern = context.createArrayPattern(m_token.m_location);
920         next();
921
922         if (hasDestructuringPattern)
923             *hasDestructuringPattern = true;
924
925         bool restElementWasFound = false;
926
927         do {
928             while (match(COMMA)) {
929                 context.appendArrayPatternSkipEntry(arrayPattern, m_token.m_location);
930                 next();
931             }
932             propagateError();
933
934             if (match(CLOSEBRACKET))
935                 break;
936
937             if (UNLIKELY(match(DOTDOTDOT))) {
938                 JSTokenLocation location = m_token.m_location;
939                 next();
940                 auto innerPattern = parseBindingOrAssignmentElement(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1);
941                 if (kind == DestructuringKind::DestructureToExpressions && !innerPattern)
942                     return 0;
943                 failIfFalse(innerPattern, "Cannot parse this destructuring pattern");
944
945                 failIfTrue(kind != DestructuringKind::DestructureToExpressions && !context.isBindingNode(innerPattern),  "Expected identifier for a rest element destructuring pattern");
946
947                 context.appendArrayPatternRestEntry(arrayPattern, location, innerPattern);
948                 restElementWasFound = true;
949                 break;
950             }
951
952             JSTokenLocation location = m_token.m_location;
953             auto innerPattern = parseBindingOrAssignmentElement(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1);
954             if (kind == DestructuringKind::DestructureToExpressions && !innerPattern)
955                 return 0;
956             failIfFalse(innerPattern, "Cannot parse this destructuring pattern");
957             TreeExpression defaultValue = parseDefaultValueForDestructuringPattern(context);
958             context.appendArrayPatternEntry(arrayPattern, location, innerPattern, defaultValue);
959         } while (consume(COMMA));
960
961         consumeOrFail(CLOSEBRACKET, restElementWasFound ? "Expected a closing ']' following a rest element destructuring pattern" : "Expected either a closing ']' or a ',' following an element destructuring pattern");
962         context.finishArrayPattern(arrayPattern, divotStart, divotStart, lastTokenEndPosition());
963         pattern = arrayPattern;
964         break;
965     }
966     case OPENBRACE: {
967         auto objectPattern = context.createObjectPattern(m_token.m_location);
968         next();
969
970         if (hasDestructuringPattern)
971             *hasDestructuringPattern = true;
972
973         do {
974             bool wasString = false;
975
976             if (match(CLOSEBRACE))
977                 break;
978
979             const Identifier* propertyName = nullptr;
980             TreeExpression propertyExpression = 0;
981             TreeDestructuringPattern innerPattern = 0;
982             JSTokenLocation location = m_token.m_location;
983             if (matchSpecIdentifier()) {
984                 failIfTrue(match(LET) && (kind == DestructuringKind::DestructureToLet || kind == DestructuringKind::DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration");
985                 propertyName = m_token.m_data.ident;
986                 JSToken identifierToken = m_token;
987                 next();
988                 if (consume(COLON))
989                     innerPattern = parseBindingOrAssignmentElement(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1);
990                 else {
991                     if (kind == DestructuringKind::DestructureToExpressions) {
992                         bool isEvalOrArguments = m_vm->propertyNames->eval == *propertyName || m_vm->propertyNames->arguments == *propertyName;
993                         if (isEvalOrArguments && strictMode())
994                             reclassifyExpressionError(ErrorIndicatesPattern, ErrorIndicatesNothing);
995                         failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", propertyName->impl(), "' in strict mode");
996                     }
997                     innerPattern = createBindingPattern(context, kind, exportType, *propertyName, identifierToken, bindingContext, duplicateIdentifier);
998                 }
999             } else {
1000                 JSTokenType tokenType = m_token.m_type;
1001                 switch (m_token.m_type) {
1002                 case DOUBLE:
1003                 case INTEGER:
1004                     propertyName = &m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), m_token.m_data.doubleValue);
1005                     break;
1006                 case STRING:
1007                     propertyName = m_token.m_data.ident;
1008                     wasString = true;
1009                     break;
1010                 case OPENBRACKET:
1011                     next();
1012                     propertyExpression = parseAssignmentExpression(context);
1013                     failIfFalse(propertyExpression, "Cannot parse computed property name");
1014                     matchOrFail(CLOSEBRACKET, "Expected ']' to end end a computed property name");
1015                     break;
1016                 default:
1017                     if (m_token.m_type != RESERVED && m_token.m_type != RESERVED_IF_STRICT && !(m_token.m_type & KeywordTokenFlag)) {
1018                         if (kind == DestructuringKind::DestructureToExpressions)
1019                             return 0;
1020                         failWithMessage("Expected a property name");
1021                     }
1022                     propertyName = m_token.m_data.ident;
1023                     break;
1024                 }
1025                 next();
1026                 if (!consume(COLON)) {
1027                     if (kind == DestructuringKind::DestructureToExpressions)
1028                         return 0;
1029                     semanticFailIfTrue(tokenType == RESERVED, "Cannot use abbreviated destructuring syntax for reserved name '", propertyName->impl(), "'");
1030                     semanticFailIfTrue(tokenType == RESERVED_IF_STRICT, "Cannot use abbreviated destructuring syntax for reserved name '", propertyName->impl(), "' in strict mode");
1031                     semanticFailIfTrue(tokenType & KeywordTokenFlag, "Cannot use abbreviated destructuring syntax for keyword '", propertyName->impl(), "'");
1032                     
1033                     failWithMessage("Expected a ':' prior to a named destructuring property");
1034                 }
1035                 innerPattern = parseBindingOrAssignmentElement(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1);
1036             }
1037             if (kind == DestructuringKind::DestructureToExpressions && !innerPattern)
1038                 return 0;
1039             failIfFalse(innerPattern, "Cannot parse this destructuring pattern");
1040             TreeExpression defaultValue = parseDefaultValueForDestructuringPattern(context);
1041             if (propertyExpression)
1042                 context.appendObjectPatternEntry(objectPattern, location, propertyExpression, innerPattern, defaultValue);
1043             else {
1044                 ASSERT(propertyName);
1045                 context.appendObjectPatternEntry(objectPattern, location, wasString, *propertyName, innerPattern, defaultValue);
1046             }
1047         } while (consume(COMMA));
1048
1049         if (kind == DestructuringKind::DestructureToExpressions && !match(CLOSEBRACE))
1050             return 0;
1051         consumeOrFail(CLOSEBRACE, "Expected either a closing '}' or an ',' after a property destructuring pattern");
1052         pattern = objectPattern;
1053         break;
1054     }
1055
1056     default: {
1057         if (!matchSpecIdentifier()) {
1058             if (kind == DestructuringKind::DestructureToExpressions)
1059                 return 0;
1060             semanticFailureDueToKeyword(destructuringKindToVariableKindName(kind));
1061             failWithMessage("Expected a parameter pattern or a ')' in parameter list");
1062         }
1063         failIfTrue(match(LET) && (kind == DestructuringKind::DestructureToLet || kind == DestructuringKind::DestructureToConst), "Can't use 'let' as an identifier name for a LexicalDeclaration");
1064         pattern = createBindingPattern(context, kind, exportType, *m_token.m_data.ident, m_token, bindingContext, duplicateIdentifier);
1065         next();
1066         break;
1067     }
1068     }
1069     m_parserState.nonLHSCount = nonLHSCount;
1070     return pattern;
1071 }
1072
1073 template <typename LexerType>
1074 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseDefaultValueForDestructuringPattern(TreeBuilder& context)
1075 {
1076     if (!match(EQUAL))
1077         return 0;
1078
1079     next(TreeBuilder::DontBuildStrings); // consume '='
1080     return parseAssignmentExpression(context);
1081 }
1082
1083 template <typename LexerType>
1084 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(TreeBuilder& context)
1085 {
1086     ASSERT(match(FOR));
1087     JSTokenLocation location(tokenLocation());
1088     int startLine = tokenLine();
1089     next();
1090     handleProductionOrFail(OPENPAREN, "(", "start", "for-loop header");
1091     int nonLHSCount = m_parserState.nonLHSCount;
1092     int declarations = 0;
1093     JSTextPosition declsStart;
1094     JSTextPosition declsEnd;
1095     TreeExpression decls = 0;
1096     TreeDestructuringPattern pattern = 0;
1097     bool isVarDeclaraton = match(VAR);
1098     bool isLetDeclaration = match(LET);
1099     bool isConstDeclaration = match(CONSTTOKEN);
1100     bool forLoopConstDoesNotHaveInitializer = false;
1101
1102     VariableEnvironment dummySet;
1103     VariableEnvironment* lexicalVariables = nullptr;
1104     AutoCleanupLexicalScope lexicalScope;
1105
1106     auto gatherLexicalVariablesIfNecessary = [&] {
1107         if (isLetDeclaration || isConstDeclaration) {
1108             ScopeRef scope = lexicalScope.scope();
1109             lexicalVariables = &scope->finalizeLexicalEnvironment();
1110         } else
1111             lexicalVariables = &dummySet;
1112     };
1113
1114     auto popLexicalScopeIfNecessary = [&] {
1115         if (isLetDeclaration || isConstDeclaration)
1116             popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
1117     };
1118
1119     if (isVarDeclaraton || isLetDeclaration || isConstDeclaration) {
1120         /*
1121          for (var/let/const IDENT in/of expression) statement
1122          for (var/let/const varDeclarationList; expressionOpt; expressionOpt)
1123          */
1124         if (isLetDeclaration || isConstDeclaration) {
1125             ScopeRef newScope = pushScope();
1126             newScope->setIsLexicalScope();
1127             newScope->preventVarDeclarations();
1128             lexicalScope.setIsValid(newScope, this);
1129         }
1130
1131         TreeDestructuringPattern forInTarget = 0;
1132         TreeExpression forInInitializer = 0;
1133         m_allowsIn = false;
1134         JSTextPosition initStart;
1135         JSTextPosition initEnd;
1136         DeclarationType declarationType;
1137         if (isVarDeclaraton)
1138             declarationType = DeclarationType::VarDeclaration;
1139         else if (isLetDeclaration)
1140             declarationType = DeclarationType::LetDeclaration;
1141         else if (isConstDeclaration)
1142             declarationType = DeclarationType::ConstDeclaration;
1143         else
1144             RELEASE_ASSERT_NOT_REACHED();
1145         decls = parseVariableDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd, ForLoopContext, declarationType, ExportType::NotExported, forLoopConstDoesNotHaveInitializer);
1146         m_allowsIn = true;
1147         propagateError();
1148
1149         // Remainder of a standard for loop is handled identically
1150         if (match(SEMICOLON))
1151             goto standardForLoop;
1152
1153         failIfFalse(declarations == 1, "can only declare a single variable in an enumeration");
1154
1155         // Handle for-in with var declaration
1156         JSTextPosition inLocation = tokenStartPosition();
1157         bool isOfEnumeration = false;
1158         if (!consume(INTOKEN)) {
1159             failIfFalse(match(IDENT) && *m_token.m_data.ident == m_vm->propertyNames->of, "Expected either 'in' or 'of' in enumeration syntax");
1160             isOfEnumeration = true;
1161             next();
1162         }
1163         bool hasAnyAssignments = !!forInInitializer;
1164         if (hasAnyAssignments) {
1165             if (isOfEnumeration)
1166                 internalFailWithMessage(false, "Cannot assign to the loop variable inside a for-of loop header");
1167             internalFailWithMessage(false, "Cannot assign to the loop variable inside a for-in loop header");
1168         }
1169         TreeExpression expr = parseExpression(context);
1170         failIfFalse(expr, "Expected expression to enumerate");
1171         JSTextPosition exprEnd = lastTokenEndPosition();
1172         
1173         int endLine = tokenLine();
1174         
1175         handleProductionOrFail(CLOSEPAREN, ")", "end", (isOfEnumeration ? "for-of header" : "for-in header"));
1176         
1177         const Identifier* unused = 0;
1178         startLoop();
1179         TreeStatement statement = parseStatement(context, unused);
1180         endLoop();
1181         failIfFalse(statement, "Expected statement as body of for-", isOfEnumeration ? "of" : "in", " statement");
1182         gatherLexicalVariablesIfNecessary();
1183         TreeStatement result;
1184         if (isOfEnumeration)
1185             result = context.createForOfLoop(location, forInTarget, expr, statement, declsStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables);
1186         else
1187             result = context.createForInLoop(location, forInTarget, expr, statement, declsStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables);
1188         popLexicalScopeIfNecessary();
1189         return result;
1190     }
1191     
1192     if (!match(SEMICOLON)) {
1193         if (match(OPENBRACE) || match(OPENBRACKET)) {
1194             SavePoint savePoint = createSavePoint();
1195             declsStart = tokenStartPosition();
1196             pattern = tryParseDestructuringPatternExpression(context, AssignmentContext::DeclarationStatement);
1197             declsEnd = lastTokenEndPosition();
1198             if (pattern && (match(INTOKEN) || (match(IDENT) && *m_token.m_data.ident == m_vm->propertyNames->of)))
1199                 goto enumerationLoop;
1200             pattern = TreeDestructuringPattern(0);
1201             restoreSavePoint(savePoint);
1202         }
1203         m_allowsIn = false;
1204         declsStart = tokenStartPosition();
1205         decls = parseExpression(context);
1206         declsEnd = lastTokenEndPosition();
1207         m_allowsIn = true;
1208         failIfFalse(decls, "Cannot parse for loop declarations");
1209     }
1210     
1211     if (match(SEMICOLON)) {
1212     standardForLoop:
1213         // Standard for loop
1214         next();
1215         TreeExpression condition = 0;
1216         failIfTrue(forLoopConstDoesNotHaveInitializer && isConstDeclaration, "const variables in for loops must have initializers");
1217         
1218         if (!match(SEMICOLON)) {
1219             condition = parseExpression(context);
1220             failIfFalse(condition, "Cannot parse for loop condition expression");
1221         }
1222         consumeOrFail(SEMICOLON, "Expected a ';' after the for loop condition expression");
1223         
1224         TreeExpression increment = 0;
1225         if (!match(CLOSEPAREN)) {
1226             increment = parseExpression(context);
1227             failIfFalse(increment, "Cannot parse for loop iteration expression");
1228         }
1229         int endLine = tokenLine();
1230         handleProductionOrFail(CLOSEPAREN, ")", "end", "for-loop header");
1231         const Identifier* unused = 0;
1232         startLoop();
1233         TreeStatement statement = parseStatement(context, unused);
1234         endLoop();
1235         failIfFalse(statement, "Expected a statement as the body of a for loop");
1236         gatherLexicalVariablesIfNecessary();
1237         TreeStatement result = context.createForLoop(location, decls, condition, increment, statement, startLine, endLine, *lexicalVariables);
1238         popLexicalScopeIfNecessary();
1239         return result;
1240     }
1241     
1242     // For-in and For-of loop
1243 enumerationLoop:
1244     failIfFalse(nonLHSCount == m_parserState.nonLHSCount, "Expected a reference on the left hand side of an enumeration statement");
1245     bool isOfEnumeration = false;
1246     if (!consume(INTOKEN)) {
1247         failIfFalse(match(IDENT) && *m_token.m_data.ident == m_vm->propertyNames->of, "Expected either 'in' or 'of' in enumeration syntax");
1248         isOfEnumeration = true;
1249         next();
1250     }
1251     TreeExpression expr = parseExpression(context);
1252     failIfFalse(expr, "Cannot parse subject for-", isOfEnumeration ? "of" : "in", " statement");
1253     JSTextPosition exprEnd = lastTokenEndPosition();
1254     int endLine = tokenLine();
1255     
1256     handleProductionOrFail(CLOSEPAREN, ")", "end", (isOfEnumeration ? "for-of header" : "for-in header"));
1257     const Identifier* unused = 0;
1258     startLoop();
1259     TreeStatement statement = parseStatement(context, unused);
1260     endLoop();
1261     failIfFalse(statement, "Expected a statement as the body of a for-", isOfEnumeration ? "of" : "in", "loop");
1262     gatherLexicalVariablesIfNecessary();
1263     TreeStatement result;
1264     if (pattern) {
1265         ASSERT(!decls);
1266         if (isOfEnumeration)
1267             result = context.createForOfLoop(location, pattern, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);
1268         else 
1269             result = context.createForInLoop(location, pattern, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);
1270
1271         popLexicalScopeIfNecessary();
1272         return result;
1273     }
1274     if (isOfEnumeration)
1275         result = context.createForOfLoop(location, decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);
1276     else
1277         result = context.createForInLoop(location, decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);
1278     popLexicalScopeIfNecessary();
1279     return result;
1280 }
1281
1282 template <typename LexerType>
1283 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBreakStatement(TreeBuilder& context)
1284 {
1285     ASSERT(match(BREAK));
1286     JSTokenLocation location(tokenLocation());
1287     JSTextPosition start = tokenStartPosition();
1288     JSTextPosition end = tokenEndPosition();
1289     next();
1290     
1291     if (autoSemiColon()) {
1292         semanticFailIfFalse(breakIsValid(), "'break' is only valid inside a switch or loop statement");
1293         return context.createBreakStatement(location, &m_vm->propertyNames->nullIdentifier, start, end);
1294     }
1295     failIfFalse(matchSpecIdentifier(), "Expected an identifier as the target for a break statement");
1296     const Identifier* ident = m_token.m_data.ident;
1297     semanticFailIfFalse(getLabel(ident), "Cannot use the undeclared label '", ident->impl(), "'");
1298     end = tokenEndPosition();
1299     next();
1300     failIfFalse(autoSemiColon(), "Expected a ';' following a targeted break statement");
1301     return context.createBreakStatement(location, ident, start, end);
1302 }
1303
1304 template <typename LexerType>
1305 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseContinueStatement(TreeBuilder& context)
1306 {
1307     ASSERT(match(CONTINUE));
1308     JSTokenLocation location(tokenLocation());
1309     JSTextPosition start = tokenStartPosition();
1310     JSTextPosition end = tokenEndPosition();
1311     next();
1312     
1313     if (autoSemiColon()) {
1314         semanticFailIfFalse(continueIsValid(), "'continue' is only valid inside a loop statement");
1315         return context.createContinueStatement(location, &m_vm->propertyNames->nullIdentifier, start, end);
1316     }
1317     failIfFalse(matchSpecIdentifier(), "Expected an identifier as the target for a continue statement");
1318     const Identifier* ident = m_token.m_data.ident;
1319     ScopeLabelInfo* label = getLabel(ident);
1320     semanticFailIfFalse(label, "Cannot use the undeclared label '", ident->impl(), "'");
1321     semanticFailIfFalse(label->isLoop, "Cannot continue to the label '", ident->impl(), "' as it is not targeting a loop");
1322     end = tokenEndPosition();
1323     next();
1324     failIfFalse(autoSemiColon(), "Expected a ';' following a targeted continue statement");
1325     return context.createContinueStatement(location, ident, start, end);
1326 }
1327
1328 template <typename LexerType>
1329 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseReturnStatement(TreeBuilder& context)
1330 {
1331     ASSERT(match(RETURN));
1332     JSTokenLocation location(tokenLocation());
1333     semanticFailIfFalse(currentScope()->isFunction(), "Return statements are only valid inside functions");
1334     JSTextPosition start = tokenStartPosition();
1335     JSTextPosition end = tokenEndPosition();
1336     next();
1337     // We do the auto semicolon check before attempting to parse expression
1338     // as we need to ensure the a line break after the return correctly terminates
1339     // the statement
1340     if (match(SEMICOLON))
1341         end = tokenEndPosition();
1342
1343     if (autoSemiColon())
1344         return context.createReturnStatement(location, 0, start, end);
1345     TreeExpression expr = parseExpression(context);
1346     failIfFalse(expr, "Cannot parse the return expression");
1347     end = lastTokenEndPosition();
1348     if (match(SEMICOLON))
1349         end  = tokenEndPosition();
1350     if (!autoSemiColon())
1351         failWithMessage("Expected a ';' following a return statement");
1352     return context.createReturnStatement(location, expr, start, end);
1353 }
1354
1355 template <typename LexerType>
1356 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseThrowStatement(TreeBuilder& context)
1357 {
1358     ASSERT(match(THROW));
1359     JSTokenLocation location(tokenLocation());
1360     JSTextPosition start = tokenStartPosition();
1361     next();
1362     failIfTrue(match(SEMICOLON), "Expected expression after 'throw'");
1363     semanticFailIfTrue(autoSemiColon(), "Cannot have a newline after 'throw'");
1364     
1365     TreeExpression expr = parseExpression(context);
1366     failIfFalse(expr, "Cannot parse expression for throw statement");
1367     JSTextPosition end = lastTokenEndPosition();
1368     failIfFalse(autoSemiColon(), "Expected a ';' after a throw statement");
1369     
1370     return context.createThrowStatement(location, expr, start, end);
1371 }
1372
1373 template <typename LexerType>
1374 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWithStatement(TreeBuilder& context)
1375 {
1376     ASSERT(match(WITH));
1377     JSTokenLocation location(tokenLocation());
1378     semanticFailIfTrue(strictMode(), "'with' statements are not valid in strict mode");
1379     currentScope()->setNeedsFullActivation();
1380     int startLine = tokenLine();
1381     next();
1382
1383     handleProductionOrFail(OPENPAREN, "(", "start", "subject of a 'with' statement");
1384     int start = tokenStart();
1385     TreeExpression expr = parseExpression(context);
1386     failIfFalse(expr, "Cannot parse 'with' subject expression");
1387     JSTextPosition end = lastTokenEndPosition();
1388     int endLine = tokenLine();
1389     handleProductionOrFail(CLOSEPAREN, ")", "start", "subject of a 'with' statement");
1390     const Identifier* unused = 0;
1391     TreeStatement statement = parseStatement(context, unused);
1392     failIfFalse(statement, "A 'with' statement must have a body");
1393     
1394     return context.createWithStatement(location, expr, statement, start, end, startLine, endLine);
1395 }
1396
1397 template <typename LexerType>
1398 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseSwitchStatement(TreeBuilder& context)
1399 {
1400     ASSERT(match(SWITCH));
1401     JSTokenLocation location(tokenLocation());
1402     int startLine = tokenLine();
1403     next();
1404     handleProductionOrFail(OPENPAREN, "(", "start", "subject of a 'switch'");
1405     TreeExpression expr = parseExpression(context);
1406     failIfFalse(expr, "Cannot parse switch subject expression");
1407     int endLine = tokenLine();
1408     
1409     handleProductionOrFail(CLOSEPAREN, ")", "end", "subject of a 'switch'");
1410     handleProductionOrFail(OPENBRACE, "{", "start", "body of a 'switch'");
1411     AutoPopScopeRef lexicalScope(this, pushScope());
1412     lexicalScope->setIsLexicalScope();
1413     lexicalScope->preventVarDeclarations();
1414     startSwitch();
1415     TreeClauseList firstClauses = parseSwitchClauses(context);
1416     propagateError();
1417     
1418     TreeClause defaultClause = parseSwitchDefaultClause(context);
1419     propagateError();
1420     
1421     TreeClauseList secondClauses = parseSwitchClauses(context);
1422     propagateError();
1423     endSwitch();
1424     handleProductionOrFail(CLOSEBRACE, "}", "end", "body of a 'switch'");
1425     
1426     TreeStatement result = context.createSwitchStatement(location, expr, firstClauses, defaultClause, secondClauses, startLine, endLine, lexicalScope->finalizeLexicalEnvironment(), lexicalScope->takeFunctionDeclarations());
1427     popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
1428     return result;
1429 }
1430
1431 template <typename LexerType>
1432 template <class TreeBuilder> TreeClauseList Parser<LexerType>::parseSwitchClauses(TreeBuilder& context)
1433 {
1434     if (!match(CASE))
1435         return 0;
1436     unsigned startOffset = tokenStart();
1437     next();
1438     TreeExpression condition = parseExpression(context);
1439     failIfFalse(condition, "Cannot parse switch clause");
1440     consumeOrFail(COLON, "Expected a ':' after switch clause expression");
1441     TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode);
1442     failIfFalse(statements, "Cannot parse the body of a switch clause");
1443     TreeClause clause = context.createClause(condition, statements);
1444     context.setStartOffset(clause, startOffset);
1445     TreeClauseList clauseList = context.createClauseList(clause);
1446     TreeClauseList tail = clauseList;
1447     
1448     while (match(CASE)) {
1449         startOffset = tokenStart();
1450         next();
1451         TreeExpression condition = parseExpression(context);
1452         failIfFalse(condition, "Cannot parse switch case expression");
1453         consumeOrFail(COLON, "Expected a ':' after switch clause expression");
1454         TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode);
1455         failIfFalse(statements, "Cannot parse the body of a switch clause");
1456         clause = context.createClause(condition, statements);
1457         context.setStartOffset(clause, startOffset);
1458         tail = context.createClauseList(tail, clause);
1459     }
1460     return clauseList;
1461 }
1462
1463 template <typename LexerType>
1464 template <class TreeBuilder> TreeClause Parser<LexerType>::parseSwitchDefaultClause(TreeBuilder& context)
1465 {
1466     if (!match(DEFAULT))
1467         return 0;
1468     unsigned startOffset = tokenStart();
1469     next();
1470     consumeOrFail(COLON, "Expected a ':' after switch default clause");
1471     TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode);
1472     failIfFalse(statements, "Cannot parse the body of a switch default clause");
1473     TreeClause result = context.createClause(0, statements);
1474     context.setStartOffset(result, startOffset);
1475     return result;
1476 }
1477
1478 template <typename LexerType>
1479 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseTryStatement(TreeBuilder& context)
1480 {
1481     ASSERT(match(TRY));
1482     JSTokenLocation location(tokenLocation());
1483     TreeStatement tryBlock = 0;
1484     TreeDestructuringPattern catchPattern = 0;
1485     TreeStatement catchBlock = 0;
1486     TreeStatement finallyBlock = 0;
1487     int firstLine = tokenLine();
1488     next();
1489     matchOrFail(OPENBRACE, "Expected a block statement as body of a try statement");
1490     
1491     tryBlock = parseBlockStatement(context);
1492     failIfFalse(tryBlock, "Cannot parse the body of try block");
1493     int lastLine = m_lastTokenEndPosition.line;
1494     VariableEnvironment catchEnvironment; 
1495     if (match(CATCH)) {
1496         next();
1497         
1498         handleProductionOrFail(OPENPAREN, "(", "start", "'catch' target");
1499         AutoPopScopeRef catchScope(this, pushScope());
1500         catchScope->setIsLexicalScope();
1501         catchScope->preventVarDeclarations();
1502         const Identifier* ident = nullptr;
1503         if (matchSpecIdentifier()) {
1504             ident = m_token.m_data.ident;
1505             catchPattern = context.createBindingLocation(m_token.m_location, *ident, m_token.m_startPosition, m_token.m_endPosition, AssignmentContext::DeclarationStatement);
1506             next();
1507             failIfTrueIfStrict(catchScope->declareLexicalVariable(ident, false) & DeclarationResult::InvalidStrictMode, "Cannot declare a catch variable named '", ident->impl(), "' in strict mode");
1508         } else {
1509             catchPattern = parseDestructuringPattern(context, DestructuringKind::DestructureToCatchParameters, ExportType::NotExported);
1510             failIfFalse(catchPattern, "Cannot parse this destructuring pattern");
1511         }
1512         handleProductionOrFail(CLOSEPAREN, ")", "end", "'catch' target");
1513         matchOrFail(OPENBRACE, "Expected exception handler to be a block statement");
1514         catchBlock = parseBlockStatement(context);
1515         failIfFalse(catchBlock, "Unable to parse 'catch' block");
1516         catchEnvironment = catchScope->finalizeLexicalEnvironment();
1517         RELEASE_ASSERT(!ident || (catchEnvironment.size() == 1 && catchEnvironment.contains(ident->impl())));
1518         popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo);
1519     }
1520     
1521     if (match(FINALLY)) {
1522         next();
1523         matchOrFail(OPENBRACE, "Expected block statement for finally body");
1524         finallyBlock = parseBlockStatement(context);
1525         failIfFalse(finallyBlock, "Cannot parse finally body");
1526     }
1527     failIfFalse(catchBlock || finallyBlock, "Try statements must have at least a catch or finally block");
1528     return context.createTryStatement(location, tryBlock, catchPattern, catchBlock, finallyBlock, firstLine, lastLine, catchEnvironment);
1529 }
1530
1531 template <typename LexerType>
1532 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseDebuggerStatement(TreeBuilder& context)
1533 {
1534     ASSERT(match(DEBUGGER));
1535     JSTokenLocation location(tokenLocation());
1536     int startLine = tokenLine();
1537     int endLine = startLine;
1538     next();
1539     if (match(SEMICOLON))
1540         startLine = tokenLine();
1541     failIfFalse(autoSemiColon(), "Debugger keyword must be followed by a ';'");
1542     return context.createDebugger(location, startLine, endLine);
1543 }
1544
1545 template <typename LexerType>
1546 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBlockStatement(TreeBuilder& context)
1547 {
1548     ASSERT(match(OPENBRACE));
1549
1550     // We should treat the first block statement of the function (the body of the function) as the lexical 
1551     // scope of the function itself, and not the lexical scope of a 'block' statement within the function.
1552     AutoCleanupLexicalScope lexicalScope;
1553     bool shouldPushLexicalScope = m_statementDepth > 0;
1554     if (shouldPushLexicalScope) {
1555         ScopeRef newScope = pushScope();
1556         newScope->setIsLexicalScope();
1557         newScope->preventVarDeclarations();
1558         lexicalScope.setIsValid(newScope, this);
1559     }
1560     JSTokenLocation location(tokenLocation());
1561     int startOffset = m_token.m_data.offset;
1562     int start = tokenLine();
1563     VariableEnvironment emptyEnvironment;
1564     DeclarationStacks::FunctionStack emptyFunctionStack;
1565     next();
1566     if (match(CLOSEBRACE)) {
1567         int endOffset = m_token.m_data.offset;
1568         next();
1569         TreeStatement result = context.createBlockStatement(location, 0, start, m_lastTokenEndPosition.line, shouldPushLexicalScope ? currentScope()->finalizeLexicalEnvironment() : emptyEnvironment, shouldPushLexicalScope ? currentScope()->takeFunctionDeclarations() : WTFMove(emptyFunctionStack));
1570         context.setStartOffset(result, startOffset);
1571         context.setEndOffset(result, endOffset);
1572         if (shouldPushLexicalScope)
1573             popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
1574         return result;
1575     }
1576     TreeSourceElements subtree = parseSourceElements(context, DontCheckForStrictMode);
1577     failIfFalse(subtree, "Cannot parse the body of the block statement");
1578     matchOrFail(CLOSEBRACE, "Expected a closing '}' at the end of a block statement");
1579     int endOffset = m_token.m_data.offset;
1580     next();
1581     TreeStatement result = context.createBlockStatement(location, subtree, start, m_lastTokenEndPosition.line, shouldPushLexicalScope ? currentScope()->finalizeLexicalEnvironment() : emptyEnvironment, shouldPushLexicalScope ? currentScope()->takeFunctionDeclarations() : WTFMove(emptyFunctionStack));
1582     context.setStartOffset(result, startOffset);
1583     context.setEndOffset(result, endOffset);
1584     if (shouldPushLexicalScope)
1585         popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
1586
1587     return result;
1588 }
1589
1590 template <typename LexerType>
1591 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength)
1592 {
1593     DepthManager statementDepth(&m_statementDepth);
1594     m_statementDepth++;
1595     directive = 0;
1596     int nonTrivialExpressionCount = 0;
1597     failIfStackOverflow();
1598     TreeStatement result = 0;
1599     bool shouldSetEndOffset = true;
1600     bool parentAllowsFunctionDeclarationAsStatement = m_immediateParentAllowsFunctionDeclarationInStatement;
1601     m_immediateParentAllowsFunctionDeclarationInStatement = false;
1602
1603     switch (m_token.m_type) {
1604     case OPENBRACE:
1605         result = parseBlockStatement(context);
1606         shouldSetEndOffset = false;
1607         break;
1608     case VAR:
1609         result = parseVariableDeclaration(context, DeclarationType::VarDeclaration);
1610         break;
1611     case FUNCTION: {
1612         if (!strictMode()) {
1613             failIfFalse(parentAllowsFunctionDeclarationAsStatement, "Function declarations are only allowed inside block statements or at the top level of a program");
1614             if (currentScope()->isFunction()) {
1615                 // Any function declaration that isn't in a block is a syntax error unless it's
1616                 // in an if/else statement. If it's in an if/else statement, we will magically
1617                 // treat it as if the if/else statement is inside a block statement.
1618                 // to the very top like a "var". For example:
1619                 // function a() {
1620                 //     if (cond) function foo() { }
1621                 // }
1622                 // will be rewritten as:
1623                 // function a() {
1624                 //     if (cond) { function foo() { } }
1625                 // }
1626                 AutoPopScopeRef blockScope(this, pushScope());
1627                 blockScope->setIsLexicalScope();
1628                 blockScope->preventVarDeclarations();
1629                 JSTokenLocation location(tokenLocation());
1630                 int start = tokenLine();
1631
1632                 TreeStatement function = parseFunctionDeclaration(context);
1633                 propagateError();
1634                 failIfFalse(function, "Expected valid function statement after 'function' keyword");
1635                 TreeSourceElements sourceElements = context.createSourceElements();
1636                 context.appendStatement(sourceElements, function);
1637                 result = context.createBlockStatement(location, sourceElements, start, m_lastTokenEndPosition.line, currentScope()->finalizeLexicalEnvironment(), currentScope()->takeFunctionDeclarations());
1638                 popScope(blockScope, TreeBuilder::NeedsFreeVariableInfo);
1639             } else {
1640                 // We only implement annex B.3.3 if we're in function mode. Otherwise, we fall back
1641                 // to hoisting behavior.
1642                 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=155813
1643                 DepthManager statementDepth(&m_statementDepth);
1644                 m_statementDepth = 1;
1645                 result = parseFunctionDeclaration(context);
1646             }
1647         } else
1648             failWithMessage("Function declarations are only allowed inside blocks or switch statements in strict mode");
1649         break;
1650     }
1651     case SEMICOLON: {
1652         JSTokenLocation location(tokenLocation());
1653         next();
1654         result = context.createEmptyStatement(location);
1655         break;
1656     }
1657     case IF:
1658         result = parseIfStatement(context);
1659         break;
1660     case DO:
1661         result = parseDoWhileStatement(context);
1662         break;
1663     case WHILE:
1664         result = parseWhileStatement(context);
1665         break;
1666     case FOR:
1667         result = parseForStatement(context);
1668         break;
1669     case CONTINUE:
1670         result = parseContinueStatement(context);
1671         break;
1672     case BREAK:
1673         result = parseBreakStatement(context);
1674         break;
1675     case RETURN:
1676         result = parseReturnStatement(context);
1677         break;
1678     case WITH:
1679         result = parseWithStatement(context);
1680         break;
1681     case SWITCH:
1682         result = parseSwitchStatement(context);
1683         break;
1684     case THROW:
1685         result = parseThrowStatement(context);
1686         break;
1687     case TRY:
1688         result = parseTryStatement(context);
1689         break;
1690     case DEBUGGER:
1691         result = parseDebuggerStatement(context);
1692         break;
1693     case EOFTOK:
1694     case CASE:
1695     case CLOSEBRACE:
1696     case DEFAULT:
1697         // These tokens imply the end of a set of source elements
1698         return 0;
1699     case IDENT:
1700     case YIELD: {
1701         bool allowFunctionDeclarationAsStatement = false;
1702         result = parseExpressionOrLabelStatement(context, allowFunctionDeclarationAsStatement);
1703         break;
1704     }
1705     case STRING:
1706         directive = m_token.m_data.ident;
1707         if (directiveLiteralLength)
1708             *directiveLiteralLength = m_token.m_location.endOffset - m_token.m_location.startOffset;
1709         nonTrivialExpressionCount = m_parserState.nonTrivialExpressionCount;
1710         FALLTHROUGH;
1711     default:
1712         TreeStatement exprStatement = parseExpressionStatement(context);
1713         if (directive && nonTrivialExpressionCount != m_parserState.nonTrivialExpressionCount)
1714             directive = 0;
1715         result = exprStatement;
1716         break;
1717     }
1718
1719     if (result && shouldSetEndOffset)
1720         context.setEndOffset(result, m_lastTokenEndPosition.offset);
1721     return result;
1722 }
1723
1724 template <typename LexerType>
1725 template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeBuilder& context, TreeFormalParameterList list, unsigned& parameterCount)
1726 {
1727 #define failIfDuplicateIfViolation() \
1728     if (duplicateParameter) {\
1729         semanticFailIfTrue(defaultValue, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in function with default parameter values");\
1730         semanticFailIfTrue(hasDestructuringPattern, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in function with destructuring parameters");\
1731         semanticFailIfTrue(isRestParameter, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in function with a rest parameter");\
1732     }
1733
1734     bool hasDestructuringPattern = false;
1735     bool isRestParameter = false;
1736     const Identifier* duplicateParameter = nullptr;
1737     do {
1738         TreeDestructuringPattern parameter = 0;
1739         TreeExpression defaultValue = 0;
1740
1741         if (match(DOTDOTDOT)) {
1742             next();
1743             failIfFalse(matchSpecIdentifier(), "Rest parameter '...' should be followed by a variable identifier");
1744             declareRestOrNormalParameter(*m_token.m_data.ident, &duplicateParameter);
1745             propagateError();
1746             JSTextPosition identifierStart = tokenStartPosition();
1747             JSTextPosition identifierEnd = tokenEndPosition();
1748             parameter = context.createRestParameter(*m_token.m_data.ident, parameterCount, identifierStart, identifierEnd);
1749             next();
1750             failIfTrue(match(COMMA), "Rest parameter should be the last parameter in a function declaration"); // Let's have a good error message for this common case.
1751             isRestParameter = true;
1752         } else
1753             parameter = parseDestructuringPattern(context, DestructuringKind::DestructureToParameters, ExportType::NotExported, &duplicateParameter, &hasDestructuringPattern);
1754         failIfFalse(parameter, "Cannot parse parameter pattern");
1755         if (!isRestParameter)
1756             defaultValue = parseDefaultValueForDestructuringPattern(context);
1757         propagateError();
1758         failIfDuplicateIfViolation();
1759         context.appendParameter(list, parameter, defaultValue);
1760         if (!isRestParameter)
1761             parameterCount++;
1762     } while (!isRestParameter && consume(COMMA));
1763
1764     return true;
1765 #undef failIfDuplicateIfViolation
1766 }
1767
1768 template <typename LexerType>
1769 template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody(
1770     TreeBuilder& context, const JSTokenLocation& startLocation, int startColumn, int functionKeywordStart, int functionNameStart, int parametersStart, 
1771     ConstructorKind constructorKind, SuperBinding superBinding, FunctionBodyType bodyType, unsigned parameterCount, SourceParseMode parseMode)
1772 {
1773     bool isArrowFunctionBodyExpression = bodyType == ArrowFunctionBodyExpression;
1774     if (!isArrowFunctionBodyExpression) {
1775         next();
1776         if (match(CLOSEBRACE)) {
1777             unsigned endColumn = tokenColumn();
1778             return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, superBinding, parameterCount, parseMode, isArrowFunctionBodyExpression);
1779         }
1780     }
1781
1782     DepthManager statementDepth(&m_statementDepth);
1783     m_statementDepth = 0;
1784     SyntaxChecker syntaxChecker(const_cast<VM*>(m_vm), m_lexer.get());
1785     if (bodyType == ArrowFunctionBodyExpression)
1786         failIfFalse(parseArrowFunctionSingleExpressionBodySourceElements(syntaxChecker), "Cannot parse body of this arrow function");
1787     else
1788         failIfFalse(parseSourceElements(syntaxChecker, CheckForStrictMode), bodyType == StandardFunctionBodyBlock ? "Cannot parse body of this function" : "Cannot parse body of this arrow function");
1789     unsigned endColumn = tokenColumn();
1790     return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, superBinding, parameterCount, parseMode, isArrowFunctionBodyExpression);
1791 }
1792
1793 static const char* stringForFunctionMode(SourceParseMode mode)
1794 {
1795     switch (mode) {
1796     case SourceParseMode::GetterMode:
1797         return "getter";
1798     case SourceParseMode::SetterMode:
1799         return "setter";
1800     case SourceParseMode::NormalFunctionMode:
1801         return "function";
1802     case SourceParseMode::MethodMode:
1803         return "method";
1804     case SourceParseMode::GeneratorBodyMode:
1805         return "generator";
1806     case SourceParseMode::GeneratorWrapperFunctionMode:
1807         return "generator function";
1808     case SourceParseMode::ArrowFunctionMode:
1809         return "arrow function";
1810     case SourceParseMode::ProgramMode:
1811     case SourceParseMode::ModuleAnalyzeMode:
1812     case SourceParseMode::ModuleEvaluateMode:
1813         RELEASE_ASSERT_NOT_REACHED();
1814         return "";
1815     }
1816     RELEASE_ASSERT_NOT_REACHED();
1817     return nullptr;
1818 }
1819
1820 template <typename LexerType> template <class TreeBuilder> int Parser<LexerType>::parseFunctionParameters(TreeBuilder& context, SourceParseMode mode, ParserFunctionInfo<TreeBuilder>& functionInfo)
1821 {
1822     RELEASE_ASSERT(mode != SourceParseMode::ProgramMode && mode != SourceParseMode::ModuleAnalyzeMode && mode != SourceParseMode::ModuleEvaluateMode);
1823     int parametersStart = m_token.m_location.startOffset;
1824     TreeFormalParameterList parameterList = context.createFormalParameterList();
1825     functionInfo.parameters = parameterList;
1826     functionInfo.startOffset = parametersStart;
1827     SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Parameters);
1828     
1829     if (mode == SourceParseMode::ArrowFunctionMode) {
1830         if (!match(IDENT) && !match(OPENPAREN)) {
1831             semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
1832             failWithMessage("Expected an arrow function input parameter");
1833         } else {
1834             if (match(OPENPAREN)) {
1835                 next();
1836                 
1837                 if (match(CLOSEPAREN))
1838                     functionInfo.parameterCount = 0;
1839                 else
1840                     failIfFalse(parseFormalParameters(context, parameterList, functionInfo.parameterCount), "Cannot parse parameters for this ", stringForFunctionMode(mode));
1841                 
1842                 consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
1843             } else {
1844                 functionInfo.parameterCount = 1;
1845                 auto parameter = parseDestructuringPattern(context, DestructuringKind::DestructureToParameters, ExportType::NotExported);
1846                 failIfFalse(parameter, "Cannot parse parameter pattern");
1847                 context.appendParameter(parameterList, parameter, 0);
1848             }
1849         }
1850
1851         return parametersStart;
1852     }
1853
1854     if (!consume(OPENPAREN)) {
1855         semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
1856         failWithMessage("Expected an opening '(' before a ", stringForFunctionMode(mode), "'s parameter list");
1857     }
1858
1859     if (mode == SourceParseMode::GetterMode) {
1860         consumeOrFail(CLOSEPAREN, "getter functions must have no parameters");
1861         functionInfo.parameterCount = 0;
1862     } else if (mode == SourceParseMode::SetterMode) {
1863         failIfTrue(match(CLOSEPAREN), "setter functions must have one parameter");
1864         const Identifier* duplicateParameter = nullptr;
1865         auto parameter = parseDestructuringPattern(context, DestructuringKind::DestructureToParameters, ExportType::NotExported, &duplicateParameter);
1866         failIfFalse(parameter, "setter functions must have one parameter");
1867         auto defaultValue = parseDefaultValueForDestructuringPattern(context);
1868         propagateError();
1869         semanticFailIfTrue(duplicateParameter && defaultValue, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in function with default parameter values");
1870         context.appendParameter(parameterList, parameter, defaultValue);
1871         functionInfo.parameterCount = 1;
1872         failIfTrue(match(COMMA), "setter functions must have one parameter");
1873         consumeOrFail(CLOSEPAREN, "Expected a ')' after a parameter declaration");
1874     } else {
1875         if (match(CLOSEPAREN))
1876             functionInfo.parameterCount = 0;
1877         else
1878             failIfFalse(parseFormalParameters(context, parameterList, functionInfo.parameterCount), "Cannot parse parameters for this ", stringForFunctionMode(mode));
1879         consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
1880     }
1881
1882     return parametersStart;
1883 }
1884
1885 template <typename LexerType>
1886 template <class TreeBuilder> typename TreeBuilder::FormalParameterList Parser<LexerType>::createGeneratorParameters(TreeBuilder& context)
1887 {
1888     auto parameters = context.createFormalParameterList();
1889
1890     JSTokenLocation location(tokenLocation());
1891     JSTextPosition position = tokenStartPosition();
1892
1893     // @generator
1894     declareParameter(&m_vm->propertyNames->generatorPrivateName);
1895     auto generator = context.createBindingLocation(location, m_vm->propertyNames->generatorPrivateName, position, position, AssignmentContext::DeclarationStatement);
1896     context.appendParameter(parameters, generator, 0);
1897
1898     // @generatorState
1899     declareParameter(&m_vm->propertyNames->generatorStatePrivateName);
1900     auto generatorState = context.createBindingLocation(location, m_vm->propertyNames->generatorStatePrivateName, position, position, AssignmentContext::DeclarationStatement);
1901     context.appendParameter(parameters, generatorState, 0);
1902
1903     // @generatorValue
1904     declareParameter(&m_vm->propertyNames->generatorValuePrivateName);
1905     auto generatorValue = context.createBindingLocation(location, m_vm->propertyNames->generatorValuePrivateName, position, position, AssignmentContext::DeclarationStatement);
1906     context.appendParameter(parameters, generatorValue, 0);
1907
1908     // @generatorResumeMode
1909     declareParameter(&m_vm->propertyNames->generatorResumeModePrivateName);
1910     auto generatorResumeMode = context.createBindingLocation(location, m_vm->propertyNames->generatorResumeModePrivateName, position, position, AssignmentContext::DeclarationStatement);
1911     context.appendParameter(parameters, generatorResumeMode, 0);
1912
1913     return parameters;
1914 }
1915
1916 template <typename LexerType>
1917 template <class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, FunctionRequirements requirements, SourceParseMode mode, bool nameIsInContainingScope, ConstructorKind constructorKind, SuperBinding expectedSuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>& functionInfo, FunctionDefinitionType functionDefinitionType)
1918 {
1919     RELEASE_ASSERT(isFunctionParseMode(mode));
1920
1921     bool upperScopeIsGenerator = currentScope()->isGenerator();
1922     AutoPopScopeRef functionScope(this, pushScope());
1923     functionScope->setSourceParseMode(mode);
1924     SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body);
1925     int functionNameStart = m_token.m_location.startOffset;
1926     const Identifier* lastFunctionName = m_parserState.lastFunctionName;
1927     m_parserState.lastFunctionName = nullptr;
1928     int parametersStart;
1929     JSTokenLocation startLocation;
1930     int startColumn;
1931     FunctionBodyType functionBodyType;
1932
1933     if (mode == SourceParseMode::ArrowFunctionMode) {
1934         startLocation = tokenLocation();
1935         functionInfo.startLine = tokenLine();
1936         startColumn = tokenColumn();
1937
1938         parametersStart = parseFunctionParameters(context, mode, functionInfo);
1939         propagateError();
1940
1941         matchOrFail(ARROWFUNCTION, "Expected a '=>' after arrow function parameter declaration");
1942
1943         if (m_lexer->prevTerminator())
1944             failDueToUnexpectedToken();
1945
1946         ASSERT(constructorKind == ConstructorKind::None);
1947
1948         // Check if arrow body start with {. If it true it mean that arrow function is Fat arrow function
1949         // and we need use common approach to parse function body
1950         next();
1951         functionBodyType = match(OPENBRACE) ? ArrowFunctionBodyBlock : ArrowFunctionBodyExpression;
1952     } else {
1953         // http://ecma-international.org/ecma-262/6.0/#sec-function-definitions
1954         // FunctionExpression :
1955         //     function BindingIdentifieropt ( FormalParameters ) { FunctionBody }
1956         //
1957         // FunctionDeclaration[Yield, Default] :
1958         //     function BindingIdentifier[?Yield] ( FormalParameters ) { FunctionBody }
1959         //     [+Default] function ( FormalParameters ) { FunctionBody }
1960         //
1961         // GeneratorDeclaration[Yield, Default] :
1962         //     function * BindingIdentifier[?Yield] ( FormalParameters[Yield] ) { GeneratorBody }
1963         //     [+Default] function * ( FormalParameters[Yield] ) { GeneratorBody }
1964         //
1965         // GeneratorExpression :
1966         //     function * BindingIdentifier[Yield]opt ( FormalParameters[Yield] ) { GeneratorBody }
1967         //
1968         // The name of FunctionExpression can accept "yield" even in the context of generator.
1969         if (functionDefinitionType == FunctionDefinitionType::Expression && mode == SourceParseMode::NormalFunctionMode)
1970             upperScopeIsGenerator = false;
1971
1972         if (matchSpecIdentifier(upperScopeIsGenerator)) {
1973             functionInfo.name = m_token.m_data.ident;
1974             m_parserState.lastFunctionName = functionInfo.name;
1975             next();
1976             if (!nameIsInContainingScope)
1977                 failIfTrueIfStrict(functionScope->declareCallee(functionInfo.name) & DeclarationResult::InvalidStrictMode, "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode");
1978         } else if (requirements == FunctionNeedsName) {
1979             if (match(OPENPAREN) && mode == SourceParseMode::NormalFunctionMode)
1980                 semanticFail("Function statements must have a name");
1981             semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
1982             failDueToUnexpectedToken();
1983             return false;
1984         }
1985
1986         startLocation = tokenLocation();
1987         functionInfo.startLine = tokenLine();
1988         startColumn = tokenColumn();
1989
1990         parametersStart = parseFunctionParameters(context, mode, functionInfo);
1991         propagateError();
1992         
1993         matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body");
1994         
1995         // BytecodeGenerator emits code to throw TypeError when a class constructor is "call"ed.
1996         // Set ConstructorKind to None for non-constructor methods of classes.
1997     
1998         if (m_defaultConstructorKind != ConstructorKind::None) {
1999             constructorKind = m_defaultConstructorKind;
2000             expectedSuperBinding = m_defaultConstructorKind == ConstructorKind::Derived ? SuperBinding::Needed : SuperBinding::NotNeeded;
2001         }
2002
2003         functionBodyType = StandardFunctionBodyBlock;
2004     }
2005
2006     functionScope->setConstructorKind(constructorKind);
2007     functionScope->setExpectedSuperBinding(expectedSuperBinding);
2008
2009     functionInfo.bodyStartColumn = startColumn;
2010     
2011     // If we know about this function already, we can use the cached info and skip the parser to the end of the function.
2012     if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(functionInfo.startOffset) : 0) {
2013         // If we're in a strict context, the cached function info must say it was strict too.
2014         ASSERT(!strictMode() || cachedInfo->strictMode);
2015         JSTokenLocation endLocation;
2016
2017         endLocation.line = cachedInfo->lastTockenLine;
2018         endLocation.startOffset = cachedInfo->lastTockenStartOffset;
2019         endLocation.lineStartOffset = cachedInfo->lastTockenLineStartOffset;
2020
2021         bool endColumnIsOnStartLine = (endLocation.line == functionInfo.startLine);
2022         ASSERT(endLocation.startOffset >= endLocation.lineStartOffset);
2023         unsigned bodyEndColumn = endColumnIsOnStartLine ?
2024             endLocation.startOffset - m_token.m_data.lineStartOffset :
2025             endLocation.startOffset - endLocation.lineStartOffset;
2026         unsigned currentLineStartOffset = m_token.m_location.lineStartOffset;
2027         
2028         functionInfo.body = context.createFunctionMetadata(
2029             startLocation, endLocation, functionInfo.bodyStartColumn, bodyEndColumn, 
2030             functionKeywordStart, functionNameStart, parametersStart, 
2031             cachedInfo->strictMode, constructorKind, expectedSuperBinding, cachedInfo->parameterCount, mode, functionBodyType == ArrowFunctionBodyExpression);
2032         
2033         functionScope->restoreFromSourceProviderCache(cachedInfo);
2034         popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo);
2035         
2036         m_token = cachedInfo->endFunctionToken();
2037         
2038         if (endColumnIsOnStartLine)
2039             m_token.m_location.lineStartOffset = currentLineStartOffset;
2040
2041         m_lexer->setOffset(m_token.m_location.endOffset, m_token.m_location.lineStartOffset);
2042         m_lexer->setLineNumber(m_token.m_location.line);
2043         functionInfo.endOffset = cachedInfo->endFunctionOffset;
2044
2045         if (mode == SourceParseMode::ArrowFunctionMode)
2046             functionBodyType = cachedInfo->isBodyArrowExpression ?  ArrowFunctionBodyExpression : ArrowFunctionBodyBlock;
2047         else
2048             functionBodyType = StandardFunctionBodyBlock;
2049         
2050         switch (functionBodyType) {
2051         case ArrowFunctionBodyExpression:
2052             next();
2053             context.setEndOffset(functionInfo.body, m_lexer->currentOffset());
2054             break;
2055         case ArrowFunctionBodyBlock:
2056         case StandardFunctionBodyBlock:
2057             context.setEndOffset(functionInfo.body, m_lexer->currentOffset());
2058             next();
2059             break;
2060         }
2061         functionInfo.endLine = m_lastTokenEndPosition.line;
2062         return true;
2063     }
2064     
2065     m_parserState.lastFunctionName = lastFunctionName;
2066     ParserState oldState = internalSaveParserState();
2067
2068     auto performParsingFunctionBody = [&] {
2069         return parseFunctionBody(context, startLocation, startColumn, functionKeywordStart, functionNameStart, parametersStart, constructorKind, expectedSuperBinding, functionBodyType, functionInfo.parameterCount, mode);
2070     };
2071
2072     if (mode == SourceParseMode::GeneratorWrapperFunctionMode) {
2073         AutoPopScopeRef generatorBodyScope(this, pushScope());
2074         generatorBodyScope->setSourceParseMode(SourceParseMode::GeneratorBodyMode);
2075         functionInfo.body = performParsingFunctionBody();
2076
2077         // When a generator has a "use strict" directive, a generator function wrapping it should be strict mode.
2078         if  (generatorBodyScope->strictMode())
2079             functionScope->setStrictMode();
2080
2081         semanticFailIfTrue(generatorBodyScope->hasDirectSuper(), "Cannot call super() outside of a class constructor");
2082         if (generatorBodyScope->needsSuperBinding())
2083             semanticFailIfTrue(expectedSuperBinding == SuperBinding::NotNeeded, "super can only be used in a method of a derived class");
2084
2085         popScope(generatorBodyScope, TreeBuilder::NeedsFreeVariableInfo);
2086     } else
2087         functionInfo.body = performParsingFunctionBody();
2088     
2089     restoreParserState(oldState);
2090     failIfFalse(functionInfo.body, "Cannot parse the body of this ", stringForFunctionMode(mode));
2091     context.setEndOffset(functionInfo.body, m_lexer->currentOffset());
2092     if (functionScope->strictMode() && functionInfo.name) {
2093         RELEASE_ASSERT(mode == SourceParseMode::NormalFunctionMode || mode == SourceParseMode::MethodMode || mode == SourceParseMode::ArrowFunctionMode || mode == SourceParseMode::GeneratorBodyMode || mode == SourceParseMode::GeneratorWrapperFunctionMode);
2094         semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
2095         semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
2096     }
2097     // It unncecessary to check of using super during reparsing one more time. Also it can lead to syntax error
2098     // in case of arrow function becuase during reparsing we don't know that parse arrow function
2099     // inside of the constructor or method
2100     if (!m_lexer->isReparsingFunction()) {
2101         if (functionScope->hasDirectSuper()) {
2102             ScopeRef scopeRef = closestParentOrdinaryFunctionNonLexicalScope();
2103             ConstructorKind functionConstructorKind = functionBodyType == StandardFunctionBodyBlock && !scopeRef->isEvalContext()
2104                 ? constructorKind
2105                 : scopeRef->constructorKind();
2106             semanticFailIfTrue(functionConstructorKind == ConstructorKind::None, "Cannot call super() outside of a class constructor");
2107             semanticFailIfTrue(functionConstructorKind != ConstructorKind::Derived, "Cannot call super() in a base class constructor");
2108         }
2109         if (functionScope->needsSuperBinding()) {
2110             ScopeRef scopeRef = closestParentOrdinaryFunctionNonLexicalScope();
2111             SuperBinding functionSuperBinding = functionBodyType == StandardFunctionBodyBlock && !scopeRef->isEvalContext()
2112                 ? expectedSuperBinding
2113                 : scopeRef->expectedSuperBinding();
2114             semanticFailIfTrue(functionSuperBinding == SuperBinding::NotNeeded, "super can only be used in a method of a derived class");
2115         }
2116     }
2117
2118     JSTokenLocation location = JSTokenLocation(m_token.m_location);
2119     functionInfo.endOffset = m_token.m_data.offset;
2120     
2121     if (functionBodyType == ArrowFunctionBodyExpression) {
2122         location = locationBeforeLastToken();
2123         functionInfo.endOffset = location.endOffset;
2124     }
2125     
2126     // Cache the tokenizer state and the function scope the first time the function is parsed.
2127     // Any future reparsing can then skip the function.
2128     // For arrow function is 8 = x=>x + 4 symbols;
2129     // For ordinary function is 16  = function(){} + 4 symbols
2130     const int minimumFunctionLengthToCache = functionBodyType == StandardFunctionBodyBlock ? 16 : 8;
2131     std::unique_ptr<SourceProviderCacheItem> newInfo;
2132     int functionLength = functionInfo.endOffset - functionInfo.startOffset;
2133     if (TreeBuilder::CanUseFunctionCache && m_functionCache && functionLength > minimumFunctionLengthToCache) {
2134         SourceProviderCacheItemCreationParameters parameters;
2135         parameters.endFunctionOffset = functionInfo.endOffset;
2136         parameters.functionNameStart = functionNameStart;
2137         parameters.lastTockenLine = location.line;
2138         parameters.lastTockenStartOffset = location.startOffset;
2139         parameters.lastTockenEndOffset = location.endOffset;
2140         parameters.lastTockenLineStartOffset = location.lineStartOffset;
2141         parameters.parameterCount = functionInfo.parameterCount;
2142         if (functionBodyType == ArrowFunctionBodyExpression) {
2143             parameters.isBodyArrowExpression = true;
2144             parameters.tokenType = m_token.m_type;
2145         }
2146         functionScope->fillParametersForSourceProviderCache(parameters);
2147         newInfo = SourceProviderCacheItem::create(parameters);
2148     }
2149     
2150     popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo);
2151     
2152     if (functionBodyType != ArrowFunctionBodyExpression) {
2153         matchOrFail(CLOSEBRACE, "Expected a closing '}' after a ", stringForFunctionMode(mode), " body");
2154         next();
2155     }
2156     
2157     if (newInfo)
2158         m_functionCache->add(functionInfo.startOffset, WTFMove(newInfo));
2159     
2160     functionInfo.endLine = m_lastTokenEndPosition.line;
2161     return true;
2162 }
2163
2164 static NO_RETURN_DUE_TO_CRASH FunctionMetadataNode* getMetadata(ParserFunctionInfo<SyntaxChecker>&) { RELEASE_ASSERT_NOT_REACHED(); }
2165 static FunctionMetadataNode* getMetadata(ParserFunctionInfo<ASTBuilder>& info) { return info.body; }
2166
2167 template <typename LexerType>
2168 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclaration(TreeBuilder& context, ExportType exportType)
2169 {
2170     ASSERT(match(FUNCTION));
2171     JSTokenLocation location(tokenLocation());
2172     unsigned functionKeywordStart = tokenStart();
2173     next();
2174     ParserFunctionInfo<TreeBuilder> functionInfo;
2175     SourceParseMode parseMode = SourceParseMode::NormalFunctionMode;
2176 #if ENABLE(ES6_GENERATORS)
2177     if (consume(TIMES))
2178         parseMode = SourceParseMode::GeneratorWrapperFunctionMode;
2179 #endif
2180     failIfFalse((parseFunctionInfo(context, FunctionNeedsName, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Declaration)), "Cannot parse this function");
2181     failIfFalse(functionInfo.name, "Function statements must have a name");
2182
2183     std::pair<DeclarationResultMask, ScopeRef> functionDeclaration = declareFunction(functionInfo.name);
2184     DeclarationResultMask declarationResult = functionDeclaration.first;
2185     failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare a function named '", functionInfo.name->impl(), "' in strict mode");
2186     if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
2187         internalFailWithMessage(false, "Cannot declare a function that shadows a let/const/class/function variable '", functionInfo.name->impl(), "' in strict mode");
2188     if (exportType == ExportType::Exported) {
2189         semanticFailIfFalse(exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'");
2190         currentScope()->moduleScopeData().exportBinding(*functionInfo.name);
2191     }
2192
2193     TreeStatement result = context.createFuncDeclStatement(location, functionInfo);
2194     if (TreeBuilder::CreatesAST)
2195         functionDeclaration.second->appendFunction(getMetadata(functionInfo));
2196     return result;
2197 }
2198
2199 template <typename LexerType>
2200 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclaration(TreeBuilder& context, ExportType exportType)
2201 {
2202     ASSERT(match(CLASSTOKEN));
2203     JSTokenLocation location(tokenLocation());
2204     JSTextPosition classStart = tokenStartPosition();
2205     unsigned classStartLine = tokenLine();
2206
2207     ParserClassInfo<TreeBuilder> info;
2208     TreeClassExpression classExpr = parseClass(context, FunctionNeedsName, info);
2209     failIfFalse(classExpr, "Failed to parse class");
2210
2211     DeclarationResultMask declarationResult = declareVariable(info.className, DeclarationType::LetDeclaration);
2212     if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
2213         internalFailWithMessage(false, "Cannot declare a class twice: '", info.className->impl(), "'");
2214     if (exportType == ExportType::Exported) {
2215         semanticFailIfFalse(exportName(*info.className), "Cannot export a duplicate class name: '", info.className->impl(), "'");
2216         currentScope()->moduleScopeData().exportBinding(*info.className);
2217     }
2218
2219     JSTextPosition classEnd = lastTokenEndPosition();
2220     unsigned classEndLine = tokenLine();
2221
2222     return context.createClassDeclStatement(location, classExpr, classStart, classEnd, classStartLine, classEndLine);
2223 }
2224
2225 template <typename LexerType>
2226 template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(TreeBuilder& context, FunctionRequirements requirements, ParserClassInfo<TreeBuilder>& info)
2227 {
2228     ASSERT(match(CLASSTOKEN));
2229     JSTokenLocation location(tokenLocation());
2230     info.startLine = location.line;
2231     info.startColumn = tokenColumn();
2232     info.startOffset = location.startOffset;
2233     next();
2234
2235     AutoPopScopeRef classScope(this, pushScope());
2236     classScope->setIsLexicalScope();
2237     classScope->preventVarDeclarations();
2238     classScope->setStrictMode();
2239
2240     const Identifier* className = nullptr;
2241     if (match(IDENT)) {
2242         className = m_token.m_data.ident;
2243         next();
2244         failIfTrue(classScope->declareLexicalVariable(className, true) & DeclarationResult::InvalidStrictMode, "'", className->impl(), "' is not a valid class name");
2245     } else if (requirements == FunctionNeedsName) {
2246         if (match(OPENBRACE))
2247             semanticFail("Class statements must have a name");
2248         semanticFailureDueToKeyword("class name");
2249         failDueToUnexpectedToken();
2250     } else
2251         className = &m_vm->propertyNames->nullIdentifier;
2252     ASSERT(className);
2253     info.className = className;
2254
2255     TreeExpression parentClass = 0;
2256     if (consume(EXTENDS)) {
2257         parentClass = parseMemberExpression(context);
2258         failIfFalse(parentClass, "Cannot parse the parent class name");
2259     }
2260     const ConstructorKind constructorKind = parentClass ? ConstructorKind::Derived : ConstructorKind::Base;
2261
2262     consumeOrFail(OPENBRACE, "Expected opening '{' at the start of a class body");
2263
2264     TreeExpression constructor = 0;
2265     TreePropertyList staticMethods = 0;
2266     TreePropertyList instanceMethods = 0;
2267     TreePropertyList instanceMethodsTail = 0;
2268     TreePropertyList staticMethodsTail = 0;
2269     while (!match(CLOSEBRACE)) {
2270         if (match(SEMICOLON)) {
2271             next();
2272             continue;
2273         }
2274
2275         JSTokenLocation methodLocation(tokenLocation());
2276         unsigned methodStart = tokenStart();
2277
2278         // For backwards compatibility, "static" is a non-reserved keyword in non-strict mode.
2279         bool isStaticMethod = false;
2280         if (match(RESERVED_IF_STRICT) && *m_token.m_data.ident == m_vm->propertyNames->staticKeyword) {
2281             SavePoint savePoint = createSavePoint();
2282             next();
2283             if (match(OPENPAREN)) {
2284                 // Reparse "static()" as a method named "static".
2285                 restoreSavePoint(savePoint);
2286             } else
2287                 isStaticMethod = true;
2288         }
2289
2290         // FIXME: Figure out a way to share more code with parseProperty.
2291         const CommonIdentifiers& propertyNames = *m_vm->propertyNames;
2292         const Identifier* ident = &propertyNames.nullIdentifier;
2293         TreeExpression computedPropertyName = 0;
2294         bool isGetter = false;
2295         bool isSetter = false;
2296         bool isGenerator = false;
2297 #if ENABLE(ES6_GENERATORS)
2298         if (consume(TIMES))
2299             isGenerator = true;
2300 #endif
2301         switch (m_token.m_type) {
2302         namedKeyword:
2303         case STRING:
2304             ident = m_token.m_data.ident;
2305             ASSERT(ident);
2306             next();
2307             break;
2308         case IDENT:
2309             ident = m_token.m_data.ident;
2310             ASSERT(ident);
2311             next();
2312             if (!isGenerator && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) {
2313                 isGetter = *ident == propertyNames.get;
2314                 isSetter = *ident == propertyNames.set;
2315             }
2316             break;
2317         case DOUBLE:
2318         case INTEGER:
2319             ident = &m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), m_token.m_data.doubleValue);
2320             ASSERT(ident);
2321             next();
2322             break;
2323         case OPENBRACKET:
2324             next();
2325             computedPropertyName = parseAssignmentExpression(context);
2326             failIfFalse(computedPropertyName, "Cannot parse computed property name");
2327             handleProductionOrFail(CLOSEBRACKET, "]", "end", "computed property name");
2328             break;
2329         default:
2330             if (m_token.m_type & KeywordTokenFlag)
2331                 goto namedKeyword;
2332             failDueToUnexpectedToken();
2333         }
2334
2335         TreeProperty property;
2336         const bool alwaysStrictInsideClass = true;
2337         if (isGetter || isSetter) {
2338             property = parseGetterSetter(context, alwaysStrictInsideClass, isGetter ? PropertyNode::Getter : PropertyNode::Setter, methodStart,
2339                 ConstructorKind::None, SuperBinding::Needed);
2340             failIfFalse(property, "Cannot parse this method");
2341         } else {
2342             ParserFunctionInfo<TreeBuilder> methodInfo;
2343             bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor;
2344             SourceParseMode parseMode = SourceParseMode::MethodMode;
2345             if (isGenerator) {
2346                 isConstructor = false;
2347                 parseMode = SourceParseMode::GeneratorWrapperFunctionMode;
2348                 semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare a generator named 'prototype'");
2349                 semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare a generator named 'constructor'");
2350             }
2351             failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, parseMode, false, isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method");
2352             methodInfo.name = isConstructor ? className : ident;
2353
2354             TreeExpression method = context.createMethodDefinition(methodLocation, methodInfo);
2355             if (isConstructor) {
2356                 semanticFailIfTrue(constructor, "Cannot declare multiple constructors in a single class");
2357                 constructor = method;
2358                 continue;
2359             }
2360
2361             // FIXME: Syntax error when super() is called
2362             semanticFailIfTrue(isStaticMethod && methodInfo.name && *methodInfo.name == propertyNames.prototype,
2363                 "Cannot declare a static method named 'prototype'");
2364             if (computedPropertyName) {
2365                 property = context.createProperty(computedPropertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed),
2366                     PropertyNode::Unknown, alwaysStrictInsideClass, SuperBinding::Needed);
2367             } else
2368                 property = context.createProperty(methodInfo.name, method, PropertyNode::Constant, PropertyNode::Unknown, alwaysStrictInsideClass, SuperBinding::Needed);
2369         }
2370
2371         TreePropertyList& tail = isStaticMethod ? staticMethodsTail : instanceMethodsTail;
2372         if (tail)
2373             tail = context.createPropertyList(methodLocation, property, tail);
2374         else {
2375             tail = context.createPropertyList(methodLocation, property);
2376             if (isStaticMethod)
2377                 staticMethods = tail;
2378             else
2379                 instanceMethods = tail;
2380         }
2381     }
2382
2383     info.endOffset = tokenLocation().endOffset - 1;
2384     consumeOrFail(CLOSEBRACE, "Expected a closing '}' after a class body");
2385
2386     auto classExpression = context.createClassExpr(location, info, classScope->finalizeLexicalEnvironment(), constructor, parentClass, instanceMethods, staticMethods);
2387     popScope(classScope, TreeBuilder::NeedsFreeVariableInfo);
2388     return classExpression;
2389 }
2390
2391 struct LabelInfo {
2392     LabelInfo(const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end)
2393     : m_ident(ident)
2394     , m_start(start)
2395     , m_end(end)
2396     {
2397     }
2398     
2399     const Identifier* m_ident;
2400     JSTextPosition m_start;
2401     JSTextPosition m_end;
2402 };
2403
2404 template <typename LexerType>
2405 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrLabelStatement(TreeBuilder& context, bool allowFunctionDeclarationAsStatement)
2406 {
2407     
2408     /* Expression and Label statements are ambiguous at LL(1), so we have a
2409      * special case that looks for a colon as the next character in the input.
2410      */
2411     Vector<LabelInfo> labels;
2412     JSTokenLocation location;
2413     do {
2414         JSTextPosition start = tokenStartPosition();
2415         location = tokenLocation();
2416         if (!nextTokenIsColon()) {
2417             // If we hit this path we're making a expression statement, which
2418             // by definition can't make use of continue/break so we can just
2419             // ignore any labels we might have accumulated.
2420             TreeExpression expression = parseExpression(context);
2421             failIfFalse(expression, "Cannot parse expression statement");
2422             if (!autoSemiColon())
2423                 failDueToUnexpectedToken();
2424             return context.createExprStatement(location, expression, start, m_lastTokenEndPosition.line);
2425         }
2426         const Identifier* ident = m_token.m_data.ident;
2427         JSTextPosition end = tokenEndPosition();
2428         next();
2429         consumeOrFail(COLON, "Labels must be followed by a ':'");
2430         if (!m_syntaxAlreadyValidated) {
2431             // This is O(N^2) over the current list of consecutive labels, but I
2432             // have never seen more than one label in a row in the real world.
2433             for (size_t i = 0; i < labels.size(); i++)
2434                 failIfTrue(ident->impl() == labels[i].m_ident->impl(), "Attempted to redeclare the label '", ident->impl(), "'");
2435             failIfTrue(getLabel(ident), "Cannot find scope for the label '", ident->impl(), "'");
2436             labels.append(LabelInfo(ident, start, end));
2437         }
2438     } while (matchSpecIdentifier());
2439     bool isLoop = false;
2440     switch (m_token.m_type) {
2441     case FOR:
2442     case WHILE:
2443     case DO:
2444         isLoop = true;
2445         break;
2446         
2447     default:
2448         break;
2449     }
2450     const Identifier* unused = 0;
2451     ScopeRef labelScope = currentScope();
2452     if (!m_syntaxAlreadyValidated) {
2453         for (size_t i = 0; i < labels.size(); i++)
2454             pushLabel(labels[i].m_ident, isLoop);
2455     }
2456     m_immediateParentAllowsFunctionDeclarationInStatement = allowFunctionDeclarationAsStatement;
2457     TreeStatement statement = parseStatement(context, unused);
2458     if (!m_syntaxAlreadyValidated) {
2459         for (size_t i = 0; i < labels.size(); i++)
2460             popLabel(labelScope);
2461     }
2462     failIfFalse(statement, "Cannot parse statement");
2463     for (size_t i = 0; i < labels.size(); i++) {
2464         const LabelInfo& info = labels[labels.size() - i - 1];
2465         statement = context.createLabelStatement(location, info.m_ident, statement, info.m_start, info.m_end);
2466     }
2467     return statement;
2468 }
2469
2470 template <typename LexerType>
2471 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionStatement(TreeBuilder& context)
2472 {
2473     switch (m_token.m_type) {
2474     // Consult: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-expression-statement
2475     // The ES6 spec mandates that we should fail from FUNCTION token here. We handle this case 
2476     // in parseStatement() which is the only caller of parseExpressionStatement().
2477     // We actually allow FUNCTION in situations where it should not be allowed unless we're in strict mode.
2478     case CLASSTOKEN:
2479         failWithMessage("'class' declaration is not directly within a block statement");
2480         break;
2481     default:
2482         // FIXME: when implementing 'let' we should fail when we see the token sequence "let [".
2483         // https://bugs.webkit.org/show_bug.cgi?id=142944
2484         break;
2485     }
2486     JSTextPosition start = tokenStartPosition();
2487     JSTokenLocation location(tokenLocation());
2488     TreeExpression expression = parseExpression(context);
2489     failIfFalse(expression, "Cannot parse expression statement");
2490     failIfFalse(autoSemiColon(), "Parse error");
2491     return context.createExprStatement(location, expression, start, m_lastTokenEndPosition.line);
2492 }
2493
2494 template <typename LexerType>
2495 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(TreeBuilder& context)
2496 {
2497     ASSERT(match(IF));
2498     JSTokenLocation ifLocation(tokenLocation());
2499     int start = tokenLine();
2500     next();
2501     handleProductionOrFail(OPENPAREN, "(", "start", "'if' condition");
2502
2503     TreeExpression condition = parseExpression(context);
2504     failIfFalse(condition, "Expected a expression as the condition for an if statement");
2505     int end = tokenLine();
2506     handleProductionOrFail(CLOSEPAREN, ")", "end", "'if' condition");
2507
2508     const Identifier* unused = 0;
2509     m_immediateParentAllowsFunctionDeclarationInStatement = true;
2510     TreeStatement trueBlock = parseStatement(context, unused);
2511     failIfFalse(trueBlock, "Expected a statement as the body of an if block");
2512
2513     if (!match(ELSE))
2514         return context.createIfStatement(ifLocation, condition, trueBlock, 0, start, end);
2515
2516     Vector<TreeExpression> exprStack;
2517     Vector<std::pair<int, int>> posStack;
2518     Vector<JSTokenLocation> tokenLocationStack;
2519     Vector<TreeStatement> statementStack;
2520     bool trailingElse = false;
2521     do {
2522         JSTokenLocation tempLocation = tokenLocation();
2523         next();
2524         if (!match(IF)) {
2525             const Identifier* unused = 0;
2526             m_immediateParentAllowsFunctionDeclarationInStatement = true;
2527             TreeStatement block = parseStatement(context, unused);
2528             failIfFalse(block, "Expected a statement as the body of an else block");
2529             statementStack.append(block);
2530             trailingElse = true;
2531             break;
2532         }
2533         int innerStart = tokenLine();
2534         next();
2535         
2536         handleProductionOrFail(OPENPAREN, "(", "start", "'if' condition");
2537
2538         TreeExpression innerCondition = parseExpression(context);
2539         failIfFalse(innerCondition, "Expected a expression as the condition for an if statement");
2540         int innerEnd = tokenLine();
2541         handleProductionOrFail(CLOSEPAREN, ")", "end", "'if' condition");
2542         const Identifier* unused = 0;
2543         m_immediateParentAllowsFunctionDeclarationInStatement = true;
2544         TreeStatement innerTrueBlock = parseStatement(context, unused);
2545         failIfFalse(innerTrueBlock, "Expected a statement as the body of an if block");
2546         tokenLocationStack.append(tempLocation);
2547         exprStack.append(innerCondition);
2548         posStack.append(std::make_pair(innerStart, innerEnd));
2549         statementStack.append(innerTrueBlock);
2550     } while (match(ELSE));
2551
2552     if (!trailingElse) {
2553         TreeExpression condition = exprStack.last();
2554         exprStack.removeLast();
2555         TreeStatement trueBlock = statementStack.last();
2556         statementStack.removeLast();
2557         std::pair<int, int> pos = posStack.last();
2558         posStack.removeLast();
2559         JSTokenLocation elseLocation = tokenLocationStack.last();
2560         tokenLocationStack.removeLast();
2561         TreeStatement ifStatement = context.createIfStatement(elseLocation, condition, trueBlock, 0, pos.first, pos.second);
2562         context.setEndOffset(ifStatement, context.endOffset(trueBlock));
2563         statementStack.append(ifStatement);
2564     }
2565
2566     while (!exprStack.isEmpty()) {
2567         TreeExpression condition = exprStack.last();
2568         exprStack.removeLast();
2569         TreeStatement falseBlock = statementStack.last();
2570         statementStack.removeLast();
2571         TreeStatement trueBlock = statementStack.last();
2572         statementStack.removeLast();
2573         std::pair<int, int> pos = posStack.last();
2574         posStack.removeLast();
2575         JSTokenLocation elseLocation = tokenLocationStack.last();
2576         tokenLocationStack.removeLast();
2577         TreeStatement ifStatement = context.createIfStatement(elseLocation, condition, trueBlock, falseBlock, pos.first, pos.second);
2578         context.setEndOffset(ifStatement, context.endOffset(falseBlock));
2579         statementStack.append(ifStatement);
2580     }
2581
2582     return context.createIfStatement(ifLocation, condition, trueBlock, statementStack.last(), start, end);
2583 }
2584
2585 template <typename LexerType>
2586 template <class TreeBuilder> typename TreeBuilder::ModuleName Parser<LexerType>::parseModuleName(TreeBuilder& context)
2587 {
2588     // ModuleName (ModuleSpecifier in the spec) represents the module name imported by the script.
2589     // http://www.ecma-international.org/ecma-262/6.0/#sec-imports
2590     // http://www.ecma-international.org/ecma-262/6.0/#sec-exports
2591     JSTokenLocation specifierLocation(tokenLocation());
2592     failIfFalse(match(STRING), "Imported modules names must be string literals");
2593     const Identifier* moduleName = m_token.m_data.ident;
2594     next();
2595     return context.createModuleName(specifierLocation, *moduleName);
2596 }
2597
2598 template <typename LexerType>
2599 template <class TreeBuilder> typename TreeBuilder::ImportSpecifier Parser<LexerType>::parseImportClauseItem(TreeBuilder& context, ImportSpecifierType specifierType)
2600 {
2601     // Produced node is the item of the ImportClause.
2602     // That is the ImportSpecifier, ImportedDefaultBinding or NameSpaceImport.
2603     // http://www.ecma-international.org/ecma-262/6.0/#sec-imports
2604     JSTokenLocation specifierLocation(tokenLocation());
2605     JSToken localNameToken;
2606     const Identifier* importedName = nullptr;
2607     const Identifier* localName = nullptr;
2608
2609     switch (specifierType) {
2610     case ImportSpecifierType::NamespaceImport: {
2611         // NameSpaceImport :
2612         // * as ImportedBinding
2613         // e.g.
2614         //     * as namespace
2615         ASSERT(match(TIMES));
2616         importedName = &m_vm->propertyNames->timesIdentifier;
2617         next();
2618
2619         failIfFalse(matchContextualKeyword(m_vm->propertyNames->as), "Expected 'as' before imported binding name");
2620         next();
2621
2622         matchOrFail(IDENT, "Expected a variable name for the import declaration");
2623         localNameToken = m_token;
2624         localName = m_token.m_data.ident;
2625         next();
2626         break;
2627     }
2628
2629     case ImportSpecifierType::NamedImport: {
2630         // ImportSpecifier :
2631         // ImportedBinding
2632         // IdentifierName as ImportedBinding
2633         // e.g.
2634         //     A
2635         //     A as B
2636         ASSERT(matchIdentifierOrKeyword());
2637         localNameToken = m_token;
2638         localName = m_token.m_data.ident;
2639         importedName = localName;
2640         next();
2641
2642         if (matchContextualKeyword(m_vm->propertyNames->as)) {
2643             next();
2644             matchOrFail(IDENT, "Expected a variable name for the import declaration");
2645             localNameToken = m_token;
2646             localName = m_token.m_data.ident;
2647             next();
2648         }
2649         break;
2650     }
2651
2652     case ImportSpecifierType::DefaultImport: {
2653         // ImportedDefaultBinding :
2654         // ImportedBinding
2655         ASSERT(match(IDENT));
2656         localNameToken = m_token;
2657         localName = m_token.m_data.ident;
2658         importedName = &m_vm->propertyNames->defaultKeyword;
2659         next();
2660         break;
2661     }
2662     }
2663
2664     semanticFailIfTrue(localNameToken.m_type & KeywordTokenFlag, "Cannot use keyword as imported binding name");
2665     DeclarationResultMask declarationResult = declareVariable(localName, DeclarationType::ConstDeclaration, (specifierType == ImportSpecifierType::NamespaceImport) ? DeclarationImportType::ImportedNamespace : DeclarationImportType::Imported);
2666     if (declarationResult != DeclarationResult::Valid) {
2667         failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare an imported binding named ", localName->impl(), " in strict mode");
2668         if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
2669             internalFailWithMessage(false, "Cannot declare an imported binding name twice: '", localName->impl(), "'");
2670     }
2671
2672     return context.createImportSpecifier(specifierLocation, *importedName, *localName);
2673 }
2674
2675 template <typename LexerType>
2676 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseImportDeclaration(TreeBuilder& context)
2677 {
2678     // http://www.ecma-international.org/ecma-262/6.0/#sec-imports
2679     ASSERT(match(IMPORT));
2680     JSTokenLocation importLocation(tokenLocation());
2681     next();
2682
2683     auto specifierList = context.createImportSpecifierList();
2684
2685     if (match(STRING)) {
2686         // import ModuleSpecifier ;
2687         auto moduleName = parseModuleName(context);
2688         failIfFalse(moduleName, "Cannot parse the module name");
2689         failIfFalse(autoSemiColon(), "Expected a ';' following a targeted import declaration");
2690         return context.createImportDeclaration(importLocation, specifierList, moduleName);
2691     }
2692
2693     bool isFinishedParsingImport = false;
2694     if (match(IDENT)) {
2695         // ImportedDefaultBinding :
2696         // ImportedBinding
2697         auto specifier = parseImportClauseItem(context, ImportSpecifierType::DefaultImport);
2698         failIfFalse(specifier, "Cannot parse the default import");
2699         context.appendImportSpecifier(specifierList, specifier);
2700         if (match(COMMA))
2701             next();
2702         else
2703             isFinishedParsingImport = true;
2704     }
2705
2706     if (!isFinishedParsingImport) {
2707         if (match(TIMES)) {
2708             // import NameSpaceImport FromClause ;
2709             auto specifier = parseImportClauseItem(context, ImportSpecifierType::NamespaceImport);
2710             failIfFalse(specifier, "Cannot parse the namespace import");
2711             context.appendImportSpecifier(specifierList, specifier);
2712         } else if (match(OPENBRACE)) {
2713             // NamedImports :
2714             // { }
2715             // { ImportsList }
2716             // { ImportsList , }
2717             next();
2718
2719             while (!match(CLOSEBRACE)) {
2720                 failIfFalse(matchIdentifierOrKeyword(), "Expected an imported name for the import declaration");
2721                 auto specifier = parseImportClauseItem(context, ImportSpecifierType::NamedImport);
2722                 failIfFalse(specifier, "Cannot parse the named import");
2723                 context.appendImportSpecifier(specifierList, specifier);
2724                 if (!consume(COMMA))
2725                     break;
2726             }
2727             handleProductionOrFail(CLOSEBRACE, "}", "end", "import list");
2728         } else
2729             failWithMessage("Expected namespace import or import list");
2730     }
2731
2732     // FromClause :
2733     // from ModuleSpecifier
2734
2735     failIfFalse(matchContextualKeyword(m_vm->propertyNames->from), "Expected 'from' before imported module name");
2736     next();
2737
2738     auto moduleName = parseModuleName(context);
2739     failIfFalse(moduleName, "Cannot parse the module name");
2740     failIfFalse(autoSemiColon(), "Expected a ';' following a targeted import declaration");
2741
2742     return context.createImportDeclaration(importLocation, specifierList, moduleName);
2743 }
2744
2745 template <typename LexerType>
2746 template <class TreeBuilder> typename TreeBuilder::ExportSpecifier Parser<LexerType>::parseExportSpecifier(TreeBuilder& context, Vector<const Identifier*>& maybeLocalNames, bool& hasKeywordForLocalBindings)
2747 {
2748     // ExportSpecifier :
2749     // IdentifierName
2750     // IdentifierName as IdentifierName
2751     // http://www.ecma-international.org/ecma-262/6.0/#sec-exports
2752     ASSERT(matchIdentifierOrKeyword());
2753     JSTokenLocation specifierLocation(tokenLocation());
2754     if (m_token.m_type & KeywordTokenFlag)
2755         hasKeywordForLocalBindings = true;
2756     const Identifier* localName = m_token.m_data.ident;
2757     const Identifier* exportedName = localName;
2758     next();
2759
2760     if (matchContextualKeyword(m_vm->propertyNames->as)) {
2761         next();
2762         failIfFalse(matchIdentifierOrKeyword(), "Expected an exported name for the export declaration");
2763         exportedName = m_token.m_data.ident;
2764         next();
2765     }
2766
2767     semanticFailIfFalse(exportName(*exportedName), "Cannot export a duplicate name '", exportedName->impl(), "'");
2768     maybeLocalNames.append(localName);
2769     return context.createExportSpecifier(specifierLocation, *localName, *exportedName);
2770 }
2771
2772 template <typename LexerType>
2773 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclaration(TreeBuilder& context)
2774 {
2775     // http://www.ecma-international.org/ecma-262/6.0/#sec-exports
2776     ASSERT(match(EXPORT));
2777     JSTokenLocation exportLocation(tokenLocation());
2778     next();
2779
2780     switch (m_token.m_type) {
2781     case TIMES: {
2782         // export * FromClause ;
2783         next();
2784
2785         failIfFalse(matchContextualKeyword(m_vm->propertyNames->from), "Expected 'from' before exported module name");
2786         next();
2787         auto moduleName = parseModuleName(context);
2788         failIfFalse(moduleName, "Cannot parse the 'from' clause");
2789         failIfFalse(autoSemiColon(), "Expected a ';' following a targeted export declaration");
2790
2791         return context.createExportAllDeclaration(exportLocation, moduleName);
2792     }
2793
2794     case DEFAULT: {
2795         // export default HoistableDeclaration[Default]
2796         // export default ClassDeclaration[Default]
2797         // export default [lookahead not-in {function, class}] AssignmentExpression[In] ;
2798
2799         next();
2800
2801         TreeStatement result = 0;
2802         bool isFunctionOrClassDeclaration = false;
2803         const Identifier* localName = nullptr;
2804         SavePoint savePoint = createSavePoint();
2805
2806         bool startsWithFunction = match(FUNCTION);
2807         if (startsWithFunction || match(CLASSTOKEN)) {
2808             isFunctionOrClassDeclaration = true;
2809             next();
2810
2811 #if ENABLE(ES6_GENERATORS)
2812             // ES6 Generators
2813             if (startsWithFunction && match(TIMES))
2814                 next();
2815 #endif
2816             if (match(IDENT))
2817                 localName = m_token.m_data.ident;
2818             restoreSavePoint(savePoint);
2819         }
2820
2821         if (localName) {
2822             if (match(FUNCTION)) {
2823                 DepthManager statementDepth(&m_statementDepth);
2824                 m_statementDepth = 1;
2825                 result = parseFunctionDeclaration(context);
2826             } else {
2827                 ASSERT(match(CLASSTOKEN));
2828                 result = parseClassDeclaration(context);
2829             }
2830         } else {
2831             // export default expr;
2832             //
2833             // It should be treated as the same to the following.
2834             //
2835             // const *default* = expr;
2836             // export { *default* as default }
2837             //
2838             // In the above example, *default* is the invisible variable to the users.
2839             // We use the private symbol to represent the name of this variable.
2840             JSTokenLocation location(tokenLocation());
2841             JSTextPosition start = tokenStartPosition();
2842             TreeExpression expression = parseAssignmentExpression(context);
2843             failIfFalse(expression, "Cannot parse expression");
2844
2845             DeclarationResultMask declarationResult = declareVariable(&m_vm->propertyNames->starDefaultPrivateName, DeclarationType::ConstDeclaration);
2846             if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
2847                 internalFailWithMessage(false, "Only one 'default' export is allowed");
2848
2849             TreeExpression assignment = context.createAssignResolve(location, m_vm->propertyNames->starDefaultPrivateName, expression, start, start, tokenEndPosition(), AssignmentContext::ConstDeclarationStatement);
2850             result = context.createExprStatement(location, assignment, start, tokenEndPosition());
2851             if (!isFunctionOrClassDeclaration)
2852                 failIfFalse(autoSemiColon(), "Expected a ';' following a targeted export declaration");
2853             localName = &m_vm->propertyNames->starDefaultPrivateName;
2854         }
2855         failIfFalse(result, "Cannot parse the declaration");
2856
2857         semanticFailIfFalse(exportName(m_vm->propertyNames->defaultKeyword), "Only one 'default' export is allowed");
2858         currentScope()->moduleScopeData().exportBinding(*localName);
2859         return context.createExportDefaultDeclaration(exportLocation, result, *localName);
2860     }
2861
2862     case OPENBRACE: {
2863         // export ExportClause FromClause ;
2864         // export ExportClause ;
2865         //
2866         // ExportClause :
2867         // { }
2868         // { ExportsList }
2869         // { ExportsList , }
2870         //
2871         // ExportsList :
2872         // ExportSpecifier
2873         // ExportsList , ExportSpecifier
2874
2875         next();
2876
2877         auto specifierList = context.createExportSpecifierList();
2878         Vector<const Identifier*> maybeLocalNames;
2879
2880         bool hasKeywordForLocalBindings = false;
2881         while (!match(CLOSEBRACE)) {
2882             failIfFalse(matchIdentifierOrKeyword(), "Expected a variable name for the export declaration");
2883             auto specifier = parseExportSpecifier(context, maybeLocalNames, hasKeywordForLocalBindings);
2884             failIfFalse(specifier, "Cannot parse the named export");
2885             context.appendExportSpecifier(specifierList, specifier);
2886             if (!consume(COMMA))
2887                 break;
2888         }
2889         handleProductionOrFail(CLOSEBRACE, "}", "end", "export list");
2890
2891         typename TreeBuilder::ModuleName moduleName = 0;
2892         if (matchContextualKeyword(m_vm->propertyNames->from)) {
2893             next();
2894             moduleName = parseModuleName(context);
2895             failIfFalse(moduleName, "Cannot parse the 'from' clause");
2896         }
2897         failIfFalse(autoSemiColon(), "Expected a ';' following a targeted export declaration");
2898
2899         if (!moduleName) {
2900             semanticFailIfTrue(hasKeywordForLocalBindings, "Cannot use keyword as exported variable name");
2901             // Since this export declaration does not have module specifier part, it exports the local bindings.
2902             // While the export declaration with module specifier does not have any effect on the current module's scope,
2903             // the export named declaration without module specifier references the the local binding names.
2904             // For example,
2905             //   export { A, B, C as D } from "mod"
2906             // does not have effect on the current module's scope. But,
2907             //   export { A, B, C as D }
2908             // will reference the current module's bindings.
2909             for (const Identifier* localName : maybeLocalNames)
2910                 currentScope()->moduleScopeData().exportBinding(*localName);
2911         }
2912
2913         return context.createExportNamedDeclaration(exportLocation, specifierList, moduleName);
2914     }
2915
2916     default: {
2917         // export VariableStatement
2918         // export Declaration
2919         TreeStatement result = 0;
2920         switch (m_token.m_type) {
2921         case VAR:
2922             result = parseVariableDeclaration(context, DeclarationType::VarDeclaration, ExportType::Exported);
2923             break;
2924
2925         case CONSTTOKEN:
2926             result = parseVariableDeclaration(context, DeclarationType::ConstDeclaration, ExportType::Exported);
2927             break;
2928
2929         case LET:
2930             result = parseVariableDeclaration(context, DeclarationType::LetDeclaration, ExportType::Exported);
2931             break;
2932
2933         case FUNCTION: {
2934             DepthManager statementDepth(&m_statementDepth);
2935             m_statementDepth = 1;
2936             result = parseFunctionDeclaration(context, ExportType::Exported);
2937             break;
2938         }
2939
2940         case CLASSTOKEN:
2941             result = parseClassDeclaration(context, ExportType::Exported);
2942             break;
2943
2944         default:
2945             failWithMessage("Expected either a declaration or a variable statement");
2946             break;
2947         }
2948         failIfFalse(result, "Cannot parse the declaration");
2949         return context.createExportLocalDeclaration(exportLocation, result);
2950     }
2951     }
2952
2953     RELEASE_ASSERT_NOT_REACHED();
2954     return 0;
2955 }
2956
2957 template <typename LexerType>
2958 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseExpression(TreeBuilder& context)
2959 {
2960     failIfStackOverflow();
2961     JSTokenLocation location(tokenLocation());
2962     TreeExpression node = parseAssignmentExpression(context);
2963     failIfFalse(node, "Cannot parse expression");
2964     context.setEndOffset(node, m_lastTokenEndPosition.offset);
2965     if (!match(COMMA))
2966         return node;
2967     next();
2968     m_parserState.nonTrivialExpressionCount++;
2969     m_parserState.nonLHSCount++;
2970     TreeExpression right = parseAssignmentExpression(context);
2971     failIfFalse(right, "Cannot parse expression in a comma expression");
2972     context.setEndOffset(right, m_lastTokenEndPosition.offset);
2973     typename TreeBuilder::Comma head = context.createCommaExpr(location, node);
2974     typename TreeBuilder::Comma tail = context.appendToCommaExpr(location, head, head, right);
2975     while (match(COMMA)) {
2976         next(TreeBuilder::DontBuildStrings);
2977         right = parseAssignmentExpression(context);
2978         failIfFalse(right, "Cannot parse expression in a comma expression");
2979         context.setEndOffset(right, m_lastTokenEndPosition.offset);
2980         tail = context.appendToCommaExpr(location, head, tail, right);
2981     }
2982     context.setEndOffset(head, m_lastTokenEndPosition.offset);
2983     return head;
2984 }
2985
2986 template <typename LexerType>
2987 template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmentExpressionOrPropagateErrorClass(TreeBuilder& context)
2988 {
2989     ExpressionErrorClassifier classifier(this);
2990     auto assignment = parseAssignmentExpression(context, classifier);
2991     if (!assignment)
2992         classifier.propagateExpressionErrorClass();
2993     return assignment;
2994 }
2995
2996 template <typename LexerType>
2997 template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmentExpression(TreeBuilder& context)
2998 {
2999     ExpressionErrorClassifier classifier(this);
3000     return parseAssignmentExpression(context, classifier);
3001 }
3002     
3003 template <typename LexerType>
3004 template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmentExpression(TreeBuilder& context, ExpressionErrorClassifier& classifier)
3005 {
3006     ASSERT(!hasError());
3007     
3008     failIfStackOverflow();
3009     JSTextPosition start = tokenStartPosition();
3010     JSTokenLocation location(tokenLocation());
3011     int initialAssignmentCount = m_parserState.assignmentCount;
3012     int initialNonLHSCount = m_parserState.nonLHSCount;
3013     bool maybeAssignmentPattern = match(OPENBRACE) || match(OPENBRACKET);
3014 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
3015     bool wasOpenParen = match(OPENPAREN);
3016     bool isValidArrowFunctionStart = match(OPENPAREN) || match(IDENT);
3017     SavePoint savePoint = createSavePoint();
3018     size_t usedVariablesSize;
3019     if (wasOpenParen) {
3020         usedVariablesSize = currentScope()->currentUsedVariablesSize();
3021         currentScope()->pushUsedVariableSet();
3022     }
3023 #endif
3024
3025 #if ENABLE(ES6_GENERATORS)
3026     if (match(YIELD) && !isYIELDMaskedAsIDENT(currentScope()->isGenerator()))
3027         return parseYieldExpression(context);
3028 #endif
3029
3030     TreeExpression lhs = parseConditionalExpression(context);
3031
3032 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
3033     if (isValidArrowFunctionStart && !match(EOFTOK)) {
3034         bool isArrowFunctionToken = match(ARROWFUNCTION);
3035         if (!lhs || isArrowFunctionToken) {
3036             SavePoint errorRestorationSavePoint = createSavePointForError();
3037             String oldErrorMessage = m_errorMessage;
3038             String oldLexerErrorMessage = m_lexer->getErrorMessage();
3039             bool hasLexerError = m_lexer->sawError();
3040             restoreSavePoint(savePoint);
3041             if (isArrowFunctionParameters()) {
3042                 if (wasOpenParen)
3043                     currentScope()->revertToPreviousUsedVariables(usedVariablesSize);
3044                 return parseArrowFunctionExpression(context);
3045             }
3046             restoreSavePointWithError(errorRestorationSavePoint, oldErrorMessage);
3047             m_lexer->setErrorMessage(oldLexerErrorMessage);
3048             m_lexer->setSawError(hasLexerError);
3049             if (isArrowFunctionToken)
3050                 failDueToUnexpectedToken();
3051         }
3052     }
3053
3054 #endif
3055
3056     if (!lhs && (!maybeAssignmentPattern || !classifier.indicatesPossiblePattern()))
3057         propagateError();
3058
3059     if (maybeAssignmentPattern && (!lhs || (context.isObjectOrArrayLiteral(lhs) && match(EQUAL)))) {
3060         String expressionError = m_errorMessage;
3061         String oldLexerErrorMessage = m_lexer->getErrorMessage();
3062         bool hasLexerError = m_lexer->sawError();
3063         SavePoint expressionErrorLocation = createSavePointForError();
3064         restoreSavePoint(savePoint);
3065         auto pattern = tryParseDestructuringPatternExpression(context, AssignmentContext::AssignmentExpression);
3066         if (classifier.indicatesPossiblePattern() && (!pattern || !match(EQUAL))) {
3067             restoreSavePointWithError(expressionErrorLocation, expressionError);
3068             m_lexer->setErrorMessage(oldLexerErrorMessage);
3069             m_lexer->setSawError(hasLexerError);
3070             return 0;
3071         }
3072         failIfFalse(pattern, "Cannot parse assignment pattern");
3073         consumeOrFail(EQUAL, "Expected '=' following assignment pattern");
3074         auto rhs = parseAssignmentExpression(context);
3075         if (!rhs)
3076             propagateError();
3077         return context.createDestructuringAssignment(location, pattern, rhs);
3078     }
3079
3080     failIfFalse(lhs, "Cannot parse expression");
3081     if (initialNonLHSCount != m_parserState.nonLHSCount) {
3082         if (m_token.m_type >= EQUAL && m_token.m_type <= OREQUAL)
3083             semanticFail("Left hand side of operator '", getToken(), "' must be a reference");
3084
3085         return lhs;
3086     }
3087     
3088     int assignmentStack = 0;
3089     Operator op;
3090     bool hadAssignment = false;
3091     while (true) {
3092         switch (m_token.m_type) {
3093         case EQUAL: op = OpEqual; break;
3094         case PLUSEQUAL: op = OpPlusEq; break;
3095         case MINUSEQUAL: op = OpMinusEq; break;
3096         case MULTEQUAL: op = OpMultEq; break;
3097         case DIVEQUAL: op = OpDivEq; break;
3098         case LSHIFTEQUAL: op = OpLShift; break;
3099         case RSHIFTEQUAL: op = OpRShift; break;
3100         case URSHIFTEQUAL: op = OpURShift; break;
3101         case ANDEQUAL: op = OpAndEq; break;
3102         case XOREQUAL: op = OpXOrEq; break;
3103         case OREQUAL: op = OpOrEq; break;
3104         case MODEQUAL: op = OpModEq; break;
3105         default:
3106             goto end;
3107         }
3108         m_parserState.nonTrivialExpressionCount++;
3109         hadAssignment = true;
3110         if (UNLIKELY(context.isNewTarget(lhs)))
3111             internalFailWithMessage(false, "new.target can't be the left hand side of an assignment expression");
3112         context.assignmentStackAppend(assignmentStack, lhs, start, tokenStartPosition(), m_parserState.assignmentCount, op);
3113         start = tokenStartPosition();
3114         m_parserState.assignmentCount++;
3115         next(TreeBuilder::DontBuildStrings);
3116         if (strictMode() && m_parserState.lastIdentifier && context.isResolve(lhs)) {
3117             failIfTrueIfStrict(m_vm->propertyNames->eval == *m_parserState.lastIdentifier, "Cannot modify 'eval' in strict mode");
3118             failIfTrueIfStrict(m_vm->propertyNames->arguments == *m_parserState.lastIdentifier, "Cannot modify 'arguments' in strict mode");
3119             m_parserState.lastIdentifier = 0;
3120         }
3121         lhs = parseAssignmentExpression(context);
3122         failIfFalse(lhs, "Cannot parse the right hand side of an assignment expression");
3123         if (initialNonLHSCount != m_parserState.nonLHSCount) {
3124             if (m_token.m_type >= EQUAL && m_token.m_type <= OREQUAL)
3125                 semanticFail("Left hand side of operator '", getToken(), "' must be a reference");
3126             break;
3127         }
3128     }
3129 end:
3130     if (hadAssignment)
3131         m_parserState.nonLHSCount++;
3132     
3133     if (!TreeBuilder::CreatesAST)
3134         return lhs;
3135     
3136     while (assignmentStack)
3137         lhs = context.createAssignment(location, assignmentStack, lhs, initialAssignmentCount, m_parserState.assignmentCount, lastTokenEndPosition());
3138     
3139     return lhs;
3140 }
3141
3142 template <typename LexerType>
3143 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseYieldExpression(TreeBuilder& context)
3144 {
3145     // YieldExpression[In] :
3146     //     yield
3147     //     yield [no LineTerminator here] AssignmentExpression[?In, Yield]
3148     //     yield [no LineTerminator here] * AssignmentExpression[?In, Yield]
3149
3150     // http://ecma-international.org/ecma-262/6.0/#sec-generator-function-definitions
3151     failIfFalse(currentScope()->isGenerator(), "Cannot use yield expression out of generator");
3152
3153     // http://ecma-international.org/ecma-262/6.0/#sec-generator-function-definitions-static-semantics-early-errors
3154     failIfTrue(m_parserState.functionParsePhase == FunctionParsePhase::Parameters, "Cannot use yield expression within parameters");
3155
3156     JSTokenLocation location(tokenLocation());
3157     JSTextPosition divotStart = tokenStartPosition();
3158     ASSERT(match(YIELD));
3159     SavePoint savePoint = createSavePoint();
3160     next();
3161     if (m_lexer->prevTerminator())
3162         return context.createYield(location);
3163
3164     bool delegate = consume(TIMES);
3165     JSTextPosition argumentStart = tokenStartPosition();
3166     TreeExpression argument = parseAssignmentExpression(context);
3167     if (!argument) {
3168         restoreSavePoint(savePoint);
3169         next();
3170         return context.createYield(location);
3171     }
3172     return context.createYield(location, argument, delegate, divotStart, argumentStart, lastTokenEndPosition());
3173 }
3174
3175 template <typename LexerType>
3176 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseConditionalExpression(TreeBuilder& context)
3177 {
3178     JSTokenLocation location(tokenLocation());
3179     TreeExpression cond = parseBinaryExpression(context);
3180     failIfFalse(cond, "Cannot parse expression");
3181     if (!match(QUESTION))
3182         return cond;
3183     m_parserState.nonTrivialExpressionCount++;
3184     m_parserState.nonLHSCount++;
3185     next(TreeBuilder::DontBuildStrings);
3186     TreeExpression lhs = parseAssignmentExpression(context);
3187     failIfFalse(lhs, "Cannot parse left hand side of ternary operator");
3188     context.setEndOffset(lhs, m_lastTokenEndPosition.offset);
3189     consumeOrFailWithFlags(COLON, TreeBuilder::DontBuildStrings, "Expected ':' in ternary operator");
3190     
3191     TreeExpression rhs = parseAssignmentExpression(context);
3192     failIfFalse(rhs, "Cannot parse right hand side of ternary operator");
3193     context.setEndOffset(rhs, m_lastTokenEndPosition.offset);
3194     return context.createConditionalExpr(location, cond, lhs, rhs);
3195 }
3196
3197 ALWAYS_INLINE static bool isUnaryOp(JSTokenType token)
3198 {
3199     return token & UnaryOpTokenFlag;
3200 }
3201
3202 template <typename LexerType>
3203 int Parser<LexerType>::isBinaryOperator(JSTokenType token)
3204 {
3205     if (m_allowsIn)
3206         return token & (BinaryOpTokenPrecedenceMask << BinaryOpTokenAllowsInPrecedenceAdditionalShift);
3207     return token & BinaryOpTokenPrecedenceMask;
3208 }
3209
3210 template <typename LexerType>
3211 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseBinaryExpression(TreeBuilder& context)
3212 {
3213     int operandStackDepth = 0;
3214     int operatorStackDepth = 0;
3215     typename TreeBuilder::BinaryExprContext binaryExprContext(context);
3216     JSTokenLocation location(tokenLocation());
3217     while (true) {
3218         JSTextPosition exprStart = tokenStartPosition();
3219         int initialAssignments = m_parserState.assignmentCount;
3220         TreeExpression current = parseUnaryExpression(context);
3221         failIfFalse(current, "Cannot parse expression");
3222         
3223         context.appendBinaryExpressionInfo(operandStackDepth, current, exprStart, lastTokenEndPosition(), lastTokenEndPosition(), initialAssignments != m_parserState.assignmentCount);