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