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