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