Unreviewed, rolling out r215476.
[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         bool restElementWasFound = false;
1017
1018         do {
1019             bool wasString = false;
1020
1021             if (match(CLOSEBRACE))
1022                 break;
1023
1024             if (UNLIKELY(match(DOTDOTDOT))) {
1025                 JSTokenLocation location = m_token.m_location;
1026                 next();
1027                 auto innerPattern = parseBindingOrAssignmentElement(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1);
1028                 if (kind == DestructuringKind::DestructureToExpressions && !innerPattern)
1029                     return 0;
1030                 propagateError();
1031                 context.appendObjectPatternRestEntry(objectPattern, location, innerPattern);
1032                 restElementWasFound = true;
1033                 context.setContainsObjectRestElement(objectPattern, restElementWasFound);
1034                 break;
1035             }
1036
1037             const Identifier* propertyName = nullptr;
1038             TreeExpression propertyExpression = 0;
1039             TreeDestructuringPattern innerPattern = 0;
1040             JSTokenLocation location = m_token.m_location;
1041             if (matchSpecIdentifier()) {
1042                 failIfTrue(match(LET) && (kind == DestructuringKind::DestructureToLet || kind == DestructuringKind::DestructureToConst), "Cannot use 'let' as an identifier name for a LexicalDeclaration");
1043                 propertyName = m_token.m_data.ident;
1044                 JSToken identifierToken = m_token;
1045                 next();
1046                 if (consume(COLON))
1047                     innerPattern = parseBindingOrAssignmentElement(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1);
1048                 else {
1049                     if (kind == DestructuringKind::DestructureToExpressions) {
1050                         bool isEvalOrArguments = m_vm->propertyNames->eval == *propertyName || m_vm->propertyNames->arguments == *propertyName;
1051                         if (isEvalOrArguments && strictMode())
1052                             reclassifyExpressionError(ErrorIndicatesPattern, ErrorIndicatesNothing);
1053                         failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", propertyName->impl(), "' in strict mode");
1054                     }
1055                     semanticFailIfTrue(isDisallowedIdentifierAwait(identifierToken), "Cannot use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason());
1056                     innerPattern = createBindingPattern(context, kind, exportType, *propertyName, identifierToken, bindingContext, duplicateIdentifier);
1057                 }
1058             } else {
1059                 JSTokenType tokenType = m_token.m_type;
1060                 switch (m_token.m_type) {
1061                 case DOUBLE:
1062                 case INTEGER:
1063                     propertyName = &m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), m_token.m_data.doubleValue);
1064                     break;
1065                 case STRING:
1066                     propertyName = m_token.m_data.ident;
1067                     wasString = true;
1068                     break;
1069                 case OPENBRACKET:
1070                     next();
1071                     propertyExpression = parseAssignmentExpression(context);
1072                     failIfFalse(propertyExpression, "Cannot parse computed property name");
1073                     matchOrFail(CLOSEBRACKET, "Expected ']' to end end a computed property name");
1074                     break;
1075                 default:
1076                     if (m_token.m_type != RESERVED && m_token.m_type != RESERVED_IF_STRICT && !(m_token.m_type & KeywordTokenFlag)) {
1077                         if (kind == DestructuringKind::DestructureToExpressions)
1078                             return 0;
1079                         failWithMessage("Expected a property name");
1080                     }
1081                     propertyName = m_token.m_data.ident;
1082                     break;
1083                 }
1084                 next();
1085                 if (!consume(COLON)) {
1086                     if (kind == DestructuringKind::DestructureToExpressions)
1087                         return 0;
1088                     semanticFailIfTrue(tokenType == RESERVED, "Cannot use abbreviated destructuring syntax for reserved name '", propertyName->impl(), "'");
1089                     semanticFailIfTrue(tokenType == RESERVED_IF_STRICT, "Cannot use abbreviated destructuring syntax for reserved name '", propertyName->impl(), "' in strict mode");
1090                     semanticFailIfTrue(tokenType & KeywordTokenFlag, "Cannot use abbreviated destructuring syntax for keyword '", propertyName->impl(), "'");
1091                     
1092                     failWithMessage("Expected a ':' prior to a named destructuring property");
1093                 }
1094                 innerPattern = parseBindingOrAssignmentElement(context, kind, exportType, duplicateIdentifier, hasDestructuringPattern, bindingContext, depth + 1);
1095             }
1096             if (kind == DestructuringKind::DestructureToExpressions && !innerPattern)
1097                 return 0;
1098             failIfFalse(innerPattern, "Cannot parse this destructuring pattern");
1099             TreeExpression defaultValue = parseDefaultValueForDestructuringPattern(context);
1100             propagateError();
1101             if (propertyExpression)
1102                 context.appendObjectPatternEntry(objectPattern, location, propertyExpression, innerPattern, defaultValue);
1103             else {
1104                 ASSERT(propertyName);
1105                 context.appendObjectPatternEntry(objectPattern, location, wasString, *propertyName, innerPattern, defaultValue);
1106             }
1107         } while (consume(COMMA));
1108
1109         if (kind == DestructuringKind::DestructureToExpressions && !match(CLOSEBRACE))
1110             return 0;
1111         consumeOrFail(CLOSEBRACE, restElementWasFound ? "Expected a closing '}' following a rest element destructuring pattern" : "Expected either a closing '}' or an ',' after a property destructuring pattern");
1112         pattern = objectPattern;
1113         break;
1114     }
1115
1116     default: {
1117         if (!matchSpecIdentifier()) {
1118             if (kind == DestructuringKind::DestructureToExpressions)
1119                 return 0;
1120             semanticFailureDueToKeyword(destructuringKindToVariableKindName(kind));
1121             failWithMessage("Expected a parameter pattern or a ')' in parameter list");
1122         }
1123         failIfTrue(match(LET) && (kind == DestructuringKind::DestructureToLet || kind == DestructuringKind::DestructureToConst), "Cannot use 'let' as an identifier name for a LexicalDeclaration");
1124         semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Cannot use 'await' as a ", destructuringKindToVariableKindName(kind), " ", disallowedIdentifierAwaitReason());
1125         pattern = createBindingPattern(context, kind, exportType, *m_token.m_data.ident, m_token, bindingContext, duplicateIdentifier);
1126         next();
1127         break;
1128     }
1129     }
1130     m_parserState.nonLHSCount = nonLHSCount;
1131     return pattern;
1132 }
1133
1134 template <typename LexerType>
1135 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseDefaultValueForDestructuringPattern(TreeBuilder& context)
1136 {
1137     if (!match(EQUAL))
1138         return 0;
1139
1140     next(TreeBuilder::DontBuildStrings); // consume '='
1141     return parseAssignmentExpression(context);
1142 }
1143
1144 template <typename LexerType>
1145 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(TreeBuilder& context)
1146 {
1147     ASSERT(match(FOR));
1148     JSTokenLocation location(tokenLocation());
1149     int startLine = tokenLine();
1150     next();
1151     handleProductionOrFail(OPENPAREN, "(", "start", "for-loop header");
1152     int nonLHSCount = m_parserState.nonLHSCount;
1153     int declarations = 0;
1154     JSTokenLocation declLocation(tokenLocation());
1155     JSTextPosition declsStart;
1156     JSTextPosition declsEnd;
1157     TreeExpression decls = 0;
1158     TreeDestructuringPattern pattern = 0;
1159     bool isVarDeclaraton = match(VAR);
1160     bool isLetDeclaration = match(LET);
1161     bool isConstDeclaration = match(CONSTTOKEN);
1162     bool forLoopConstDoesNotHaveInitializer = false;
1163
1164     VariableEnvironment dummySet;
1165     VariableEnvironment* lexicalVariables = nullptr;
1166     AutoCleanupLexicalScope lexicalScope;
1167
1168     auto gatherLexicalVariablesIfNecessary = [&] {
1169         if (isLetDeclaration || isConstDeclaration) {
1170             ScopeRef scope = lexicalScope.scope();
1171             lexicalVariables = &scope->finalizeLexicalEnvironment();
1172         } else
1173             lexicalVariables = &dummySet;
1174     };
1175
1176     auto popLexicalScopeIfNecessary = [&] {
1177         if (isLetDeclaration || isConstDeclaration)
1178             popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
1179     };
1180
1181     if (isVarDeclaraton || isLetDeclaration || isConstDeclaration) {
1182         /*
1183          for (var/let/const IDENT in/of expression) statement
1184          for (var/let/const varDeclarationList; expressionOpt; expressionOpt)
1185          */
1186         if (isLetDeclaration || isConstDeclaration) {
1187             ScopeRef newScope = pushScope();
1188             newScope->setIsLexicalScope();
1189             newScope->preventVarDeclarations();
1190             lexicalScope.setIsValid(newScope, this);
1191         }
1192
1193         TreeDestructuringPattern forInTarget = 0;
1194         TreeExpression forInInitializer = 0;
1195         m_allowsIn = false;
1196         JSTextPosition initStart;
1197         JSTextPosition initEnd;
1198         DeclarationType declarationType;
1199         if (isVarDeclaraton)
1200             declarationType = DeclarationType::VarDeclaration;
1201         else if (isLetDeclaration)
1202             declarationType = DeclarationType::LetDeclaration;
1203         else if (isConstDeclaration)
1204             declarationType = DeclarationType::ConstDeclaration;
1205         else
1206             RELEASE_ASSERT_NOT_REACHED();
1207         decls = parseVariableDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd, ForLoopContext, declarationType, ExportType::NotExported, forLoopConstDoesNotHaveInitializer);
1208         m_allowsIn = true;
1209         propagateError();
1210
1211         // Remainder of a standard for loop is handled identically
1212         if (match(SEMICOLON))
1213             goto standardForLoop;
1214
1215         failIfFalse(declarations == 1, "can only declare a single variable in an enumeration");
1216
1217         // Handle for-in with var declaration
1218         JSTextPosition inLocation = tokenStartPosition();
1219         bool isOfEnumeration = false;
1220         if (!consume(INTOKEN)) {
1221             failIfFalse(match(IDENT) && *m_token.m_data.ident == m_vm->propertyNames->of, "Expected either 'in' or 'of' in enumeration syntax");
1222             isOfEnumeration = true;
1223             next();
1224         }
1225         bool hasAnyAssignments = !!forInInitializer;
1226         if (hasAnyAssignments) {
1227             if (isOfEnumeration)
1228                 internalFailWithMessage(false, "Cannot assign to the loop variable inside a for-of loop header");
1229             if (strictMode() || (isLetDeclaration || isConstDeclaration) || !context.isBindingNode(forInTarget))
1230                 internalFailWithMessage(false, "Cannot assign to the loop variable inside a for-in loop header");
1231         }
1232         TreeExpression expr = parseExpression(context);
1233         failIfFalse(expr, "Expected expression to enumerate");
1234         recordPauseLocation(context.breakpointLocation(expr));
1235         JSTextPosition exprEnd = lastTokenEndPosition();
1236         
1237         int endLine = tokenLine();
1238         
1239         handleProductionOrFail(CLOSEPAREN, ")", "end", (isOfEnumeration ? "for-of header" : "for-in header"));
1240         
1241         const Identifier* unused = 0;
1242         startLoop();
1243         TreeStatement statement = parseStatement(context, unused);
1244         endLoop();
1245         failIfFalse(statement, "Expected statement as body of for-", isOfEnumeration ? "of" : "in", " statement");
1246         gatherLexicalVariablesIfNecessary();
1247         TreeStatement result;
1248         if (isOfEnumeration)
1249             result = context.createForOfLoop(location, forInTarget, expr, statement, declLocation, declsStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables);
1250         else {
1251             if (isVarDeclaraton && forInInitializer)
1252                 result = context.createForInLoop(location, decls, expr, statement, declLocation, declsStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables);
1253             else
1254                 result = context.createForInLoop(location, forInTarget, expr, statement, declLocation, declsStart, inLocation, exprEnd, startLine, endLine, *lexicalVariables);
1255         }
1256         popLexicalScopeIfNecessary();
1257         return result;
1258     }
1259     
1260     if (!match(SEMICOLON)) {
1261         if (match(OPENBRACE) || match(OPENBRACKET)) {
1262             SavePoint savePoint = createSavePoint();
1263             declsStart = tokenStartPosition();
1264             pattern = tryParseDestructuringPatternExpression(context, AssignmentContext::DeclarationStatement);
1265             declsEnd = lastTokenEndPosition();
1266             if (pattern && (match(INTOKEN) || (match(IDENT) && *m_token.m_data.ident == m_vm->propertyNames->of)))
1267                 goto enumerationLoop;
1268             pattern = TreeDestructuringPattern(0);
1269             restoreSavePoint(savePoint);
1270         }
1271         m_allowsIn = false;
1272         declsStart = tokenStartPosition();
1273         decls = parseExpression(context);
1274         declsEnd = lastTokenEndPosition();
1275         m_allowsIn = true;
1276         failIfFalse(decls, "Cannot parse for loop declarations");
1277         recordPauseLocation(context.breakpointLocation(decls));
1278     }
1279     
1280     if (match(SEMICOLON)) {
1281     standardForLoop:
1282         // Standard for loop
1283         if (decls)
1284             recordPauseLocation(context.breakpointLocation(decls));
1285         next();
1286         TreeExpression condition = 0;
1287         failIfTrue(forLoopConstDoesNotHaveInitializer && isConstDeclaration, "const variables in for loops must have initializers");
1288         
1289         if (!match(SEMICOLON)) {
1290             condition = parseExpression(context);
1291             failIfFalse(condition, "Cannot parse for loop condition expression");
1292             recordPauseLocation(context.breakpointLocation(condition));
1293         }
1294         consumeOrFail(SEMICOLON, "Expected a ';' after the for loop condition expression");
1295         
1296         TreeExpression increment = 0;
1297         if (!match(CLOSEPAREN)) {
1298             increment = parseExpression(context);
1299             failIfFalse(increment, "Cannot parse for loop iteration expression");
1300             recordPauseLocation(context.breakpointLocation(increment));
1301         }
1302         int endLine = tokenLine();
1303         handleProductionOrFail(CLOSEPAREN, ")", "end", "for-loop header");
1304         const Identifier* unused = 0;
1305         startLoop();
1306         TreeStatement statement = parseStatement(context, unused);
1307         endLoop();
1308         failIfFalse(statement, "Expected a statement as the body of a for loop");
1309         gatherLexicalVariablesIfNecessary();
1310         TreeStatement result = context.createForLoop(location, decls, condition, increment, statement, startLine, endLine, *lexicalVariables);
1311         popLexicalScopeIfNecessary();
1312         return result;
1313     }
1314     
1315     // For-in and For-of loop
1316 enumerationLoop:
1317     failIfFalse(nonLHSCount == m_parserState.nonLHSCount, "Expected a reference on the left hand side of an enumeration statement");
1318     bool isOfEnumeration = false;
1319     if (!consume(INTOKEN)) {
1320         failIfFalse(match(IDENT) && *m_token.m_data.ident == m_vm->propertyNames->of, "Expected either 'in' or 'of' in enumeration syntax");
1321         isOfEnumeration = true;
1322         next();
1323     }
1324     TreeExpression expr = parseExpression(context);
1325     failIfFalse(expr, "Cannot parse subject for-", isOfEnumeration ? "of" : "in", " statement");
1326     recordPauseLocation(context.breakpointLocation(expr));
1327     JSTextPosition exprEnd = lastTokenEndPosition();
1328     int endLine = tokenLine();
1329     
1330     handleProductionOrFail(CLOSEPAREN, ")", "end", (isOfEnumeration ? "for-of header" : "for-in header"));
1331     const Identifier* unused = 0;
1332     startLoop();
1333     TreeStatement statement = parseStatement(context, unused);
1334     endLoop();
1335     failIfFalse(statement, "Expected a statement as the body of a for-", isOfEnumeration ? "of" : "in", "loop");
1336     gatherLexicalVariablesIfNecessary();
1337     TreeStatement result;
1338     if (pattern) {
1339         ASSERT(!decls);
1340         if (isOfEnumeration)
1341             result = context.createForOfLoop(location, pattern, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);
1342         else 
1343             result = context.createForInLoop(location, pattern, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);
1344
1345         popLexicalScopeIfNecessary();
1346         return result;
1347     }
1348     if (isOfEnumeration)
1349         result = context.createForOfLoop(location, decls, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);
1350     else
1351         result = context.createForInLoop(location, decls, expr, statement, declLocation, declsStart, declsEnd, exprEnd, startLine, endLine, *lexicalVariables);
1352     popLexicalScopeIfNecessary();
1353     return result;
1354 }
1355
1356 template <typename LexerType>
1357 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBreakStatement(TreeBuilder& context)
1358 {
1359     ASSERT(match(BREAK));
1360     JSTokenLocation location(tokenLocation());
1361     JSTextPosition start = tokenStartPosition();
1362     JSTextPosition end = tokenEndPosition();
1363     next();
1364     
1365     if (autoSemiColon()) {
1366         semanticFailIfFalse(breakIsValid(), "'break' is only valid inside a switch or loop statement");
1367         return context.createBreakStatement(location, &m_vm->propertyNames->nullIdentifier, start, end);
1368     }
1369     failIfFalse(matchSpecIdentifier(), "Expected an identifier as the target for a break statement");
1370     const Identifier* ident = m_token.m_data.ident;
1371     semanticFailIfFalse(getLabel(ident), "Cannot use the undeclared label '", ident->impl(), "'");
1372     end = tokenEndPosition();
1373     next();
1374     failIfFalse(autoSemiColon(), "Expected a ';' following a targeted break statement");
1375     return context.createBreakStatement(location, ident, start, end);
1376 }
1377
1378 template <typename LexerType>
1379 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseContinueStatement(TreeBuilder& context)
1380 {
1381     ASSERT(match(CONTINUE));
1382     JSTokenLocation location(tokenLocation());
1383     JSTextPosition start = tokenStartPosition();
1384     JSTextPosition end = tokenEndPosition();
1385     next();
1386     
1387     if (autoSemiColon()) {
1388         semanticFailIfFalse(continueIsValid(), "'continue' is only valid inside a loop statement");
1389         return context.createContinueStatement(location, &m_vm->propertyNames->nullIdentifier, start, end);
1390     }
1391     failIfFalse(matchSpecIdentifier(), "Expected an identifier as the target for a continue statement");
1392     const Identifier* ident = m_token.m_data.ident;
1393     ScopeLabelInfo* label = getLabel(ident);
1394     semanticFailIfFalse(label, "Cannot use the undeclared label '", ident->impl(), "'");
1395     semanticFailIfFalse(label->isLoop, "Cannot continue to the label '", ident->impl(), "' as it is not targeting a loop");
1396     end = tokenEndPosition();
1397     next();
1398     failIfFalse(autoSemiColon(), "Expected a ';' following a targeted continue statement");
1399     return context.createContinueStatement(location, ident, start, end);
1400 }
1401
1402 template <typename LexerType>
1403 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseReturnStatement(TreeBuilder& context)
1404 {
1405     ASSERT(match(RETURN));
1406     JSTokenLocation location(tokenLocation());
1407     semanticFailIfFalse(currentScope()->isFunction(), "Return statements are only valid inside functions");
1408     JSTextPosition start = tokenStartPosition();
1409     JSTextPosition end = tokenEndPosition();
1410     next();
1411     // We do the auto semicolon check before attempting to parse expression
1412     // as we need to ensure the a line break after the return correctly terminates
1413     // the statement
1414     if (match(SEMICOLON))
1415         end = tokenEndPosition();
1416
1417     if (autoSemiColon())
1418         return context.createReturnStatement(location, 0, start, end);
1419     TreeExpression expr = parseExpression(context);
1420     failIfFalse(expr, "Cannot parse the return expression");
1421     end = lastTokenEndPosition();
1422     if (match(SEMICOLON))
1423         end  = tokenEndPosition();
1424     if (!autoSemiColon())
1425         failWithMessage("Expected a ';' following a return statement");
1426     return context.createReturnStatement(location, expr, start, end);
1427 }
1428
1429 template <typename LexerType>
1430 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseThrowStatement(TreeBuilder& context)
1431 {
1432     ASSERT(match(THROW));
1433     JSTokenLocation location(tokenLocation());
1434     JSTextPosition start = tokenStartPosition();
1435     next();
1436     failIfTrue(match(SEMICOLON), "Expected expression after 'throw'");
1437     semanticFailIfTrue(autoSemiColon(), "Cannot have a newline after 'throw'");
1438     
1439     TreeExpression expr = parseExpression(context);
1440     failIfFalse(expr, "Cannot parse expression for throw statement");
1441     JSTextPosition end = lastTokenEndPosition();
1442     failIfFalse(autoSemiColon(), "Expected a ';' after a throw statement");
1443     
1444     return context.createThrowStatement(location, expr, start, end);
1445 }
1446
1447 template <typename LexerType>
1448 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWithStatement(TreeBuilder& context)
1449 {
1450     ASSERT(match(WITH));
1451     JSTokenLocation location(tokenLocation());
1452     semanticFailIfTrue(strictMode(), "'with' statements are not valid in strict mode");
1453     currentScope()->setNeedsFullActivation();
1454     int startLine = tokenLine();
1455     next();
1456
1457     handleProductionOrFail(OPENPAREN, "(", "start", "subject of a 'with' statement");
1458     int start = tokenStart();
1459     TreeExpression expr = parseExpression(context);
1460     failIfFalse(expr, "Cannot parse 'with' subject expression");
1461     recordPauseLocation(context.breakpointLocation(expr));
1462     JSTextPosition end = lastTokenEndPosition();
1463     int endLine = tokenLine();
1464     handleProductionOrFail(CLOSEPAREN, ")", "start", "subject of a 'with' statement");
1465     const Identifier* unused = 0;
1466     TreeStatement statement = parseStatement(context, unused);
1467     failIfFalse(statement, "A 'with' statement must have a body");
1468     
1469     return context.createWithStatement(location, expr, statement, start, end, startLine, endLine);
1470 }
1471
1472 template <typename LexerType>
1473 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseSwitchStatement(TreeBuilder& context)
1474 {
1475     ASSERT(match(SWITCH));
1476     JSTokenLocation location(tokenLocation());
1477     int startLine = tokenLine();
1478     next();
1479     handleProductionOrFail(OPENPAREN, "(", "start", "subject of a 'switch'");
1480     TreeExpression expr = parseExpression(context);
1481     failIfFalse(expr, "Cannot parse switch subject expression");
1482     recordPauseLocation(context.breakpointLocation(expr));
1483     int endLine = tokenLine();
1484     
1485     handleProductionOrFail(CLOSEPAREN, ")", "end", "subject of a 'switch'");
1486     handleProductionOrFail(OPENBRACE, "{", "start", "body of a 'switch'");
1487     AutoPopScopeRef lexicalScope(this, pushScope());
1488     lexicalScope->setIsLexicalScope();
1489     lexicalScope->preventVarDeclarations();
1490     startSwitch();
1491     TreeClauseList firstClauses = parseSwitchClauses(context);
1492     propagateError();
1493     
1494     TreeClause defaultClause = parseSwitchDefaultClause(context);
1495     propagateError();
1496     
1497     TreeClauseList secondClauses = parseSwitchClauses(context);
1498     propagateError();
1499     endSwitch();
1500     handleProductionOrFail(CLOSEBRACE, "}", "end", "body of a 'switch'");
1501     
1502     TreeStatement result = context.createSwitchStatement(location, expr, firstClauses, defaultClause, secondClauses, startLine, endLine, lexicalScope->finalizeLexicalEnvironment(), lexicalScope->takeFunctionDeclarations());
1503     popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
1504     return result;
1505 }
1506
1507 template <typename LexerType>
1508 template <class TreeBuilder> TreeClauseList Parser<LexerType>::parseSwitchClauses(TreeBuilder& context)
1509 {
1510     if (!match(CASE))
1511         return 0;
1512     unsigned startOffset = tokenStart();
1513     next();
1514     TreeExpression condition = parseExpression(context);
1515     failIfFalse(condition, "Cannot parse switch clause");
1516     consumeOrFail(COLON, "Expected a ':' after switch clause expression");
1517     TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode);
1518     failIfFalse(statements, "Cannot parse the body of a switch clause");
1519     TreeClause clause = context.createClause(condition, statements);
1520     context.setStartOffset(clause, startOffset);
1521     TreeClauseList clauseList = context.createClauseList(clause);
1522     TreeClauseList tail = clauseList;
1523     
1524     while (match(CASE)) {
1525         startOffset = tokenStart();
1526         next();
1527         TreeExpression condition = parseExpression(context);
1528         failIfFalse(condition, "Cannot parse switch case expression");
1529         consumeOrFail(COLON, "Expected a ':' after switch clause expression");
1530         TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode);
1531         failIfFalse(statements, "Cannot parse the body of a switch clause");
1532         clause = context.createClause(condition, statements);
1533         context.setStartOffset(clause, startOffset);
1534         tail = context.createClauseList(tail, clause);
1535     }
1536     return clauseList;
1537 }
1538
1539 template <typename LexerType>
1540 template <class TreeBuilder> TreeClause Parser<LexerType>::parseSwitchDefaultClause(TreeBuilder& context)
1541 {
1542     if (!match(DEFAULT))
1543         return 0;
1544     unsigned startOffset = tokenStart();
1545     next();
1546     consumeOrFail(COLON, "Expected a ':' after switch default clause");
1547     TreeSourceElements statements = parseSourceElements(context, DontCheckForStrictMode);
1548     failIfFalse(statements, "Cannot parse the body of a switch default clause");
1549     TreeClause result = context.createClause(0, statements);
1550     context.setStartOffset(result, startOffset);
1551     return result;
1552 }
1553
1554 template <typename LexerType>
1555 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseTryStatement(TreeBuilder& context)
1556 {
1557     ASSERT(match(TRY));
1558     JSTokenLocation location(tokenLocation());
1559     TreeStatement tryBlock = 0;
1560     TreeDestructuringPattern catchPattern = 0;
1561     TreeStatement catchBlock = 0;
1562     TreeStatement finallyBlock = 0;
1563     int firstLine = tokenLine();
1564     next();
1565     matchOrFail(OPENBRACE, "Expected a block statement as body of a try statement");
1566     
1567     tryBlock = parseBlockStatement(context);
1568     failIfFalse(tryBlock, "Cannot parse the body of try block");
1569     int lastLine = m_lastTokenEndPosition.line;
1570     VariableEnvironment catchEnvironment; 
1571     if (match(CATCH)) {
1572         next();
1573         
1574         handleProductionOrFail(OPENPAREN, "(", "start", "'catch' target");
1575         AutoPopScopeRef catchScope(this, pushScope());
1576         catchScope->setIsLexicalScope();
1577         catchScope->preventVarDeclarations();
1578         const Identifier* ident = nullptr;
1579         if (matchSpecIdentifier()) {
1580             ident = m_token.m_data.ident;
1581             catchPattern = context.createBindingLocation(m_token.m_location, *ident, m_token.m_startPosition, m_token.m_endPosition, AssignmentContext::DeclarationStatement);
1582             next();
1583             failIfTrueIfStrict(catchScope->declareLexicalVariable(ident, false) & DeclarationResult::InvalidStrictMode, "Cannot declare a catch variable named '", ident->impl(), "' in strict mode");
1584         } else {
1585             catchPattern = parseDestructuringPattern(context, DestructuringKind::DestructureToCatchParameters, ExportType::NotExported);
1586             failIfFalse(catchPattern, "Cannot parse this destructuring pattern");
1587         }
1588         handleProductionOrFail(CLOSEPAREN, ")", "end", "'catch' target");
1589         matchOrFail(OPENBRACE, "Expected exception handler to be a block statement");
1590         catchBlock = parseBlockStatement(context);
1591         failIfFalse(catchBlock, "Unable to parse 'catch' block");
1592         catchEnvironment = catchScope->finalizeLexicalEnvironment();
1593         RELEASE_ASSERT(!ident || (catchEnvironment.size() == 1 && catchEnvironment.contains(ident->impl())));
1594         popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo);
1595     }
1596     
1597     if (match(FINALLY)) {
1598         next();
1599         matchOrFail(OPENBRACE, "Expected block statement for finally body");
1600         finallyBlock = parseBlockStatement(context);
1601         failIfFalse(finallyBlock, "Cannot parse finally body");
1602     }
1603     failIfFalse(catchBlock || finallyBlock, "Try statements must have at least a catch or finally block");
1604     return context.createTryStatement(location, tryBlock, catchPattern, catchBlock, finallyBlock, firstLine, lastLine, catchEnvironment);
1605 }
1606
1607 template <typename LexerType>
1608 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseDebuggerStatement(TreeBuilder& context)
1609 {
1610     ASSERT(match(DEBUGGER));
1611     JSTokenLocation location(tokenLocation());
1612     int startLine = tokenLine();
1613     int endLine = startLine;
1614     next();
1615     if (match(SEMICOLON))
1616         startLine = tokenLine();
1617     failIfFalse(autoSemiColon(), "Debugger keyword must be followed by a ';'");
1618     return context.createDebugger(location, startLine, endLine);
1619 }
1620
1621 template <typename LexerType>
1622 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBlockStatement(TreeBuilder& context)
1623 {
1624     ASSERT(match(OPENBRACE));
1625
1626     // We should treat the first block statement of the function (the body of the function) as the lexical 
1627     // scope of the function itself, and not the lexical scope of a 'block' statement within the function.
1628     AutoCleanupLexicalScope lexicalScope;
1629     bool shouldPushLexicalScope = m_statementDepth > 0;
1630     if (shouldPushLexicalScope) {
1631         ScopeRef newScope = pushScope();
1632         newScope->setIsLexicalScope();
1633         newScope->preventVarDeclarations();
1634         lexicalScope.setIsValid(newScope, this);
1635     }
1636     JSTokenLocation location(tokenLocation());
1637     int startOffset = m_token.m_data.offset;
1638     int start = tokenLine();
1639     VariableEnvironment emptyEnvironment;
1640     DeclarationStacks::FunctionStack emptyFunctionStack;
1641     next();
1642     if (match(CLOSEBRACE)) {
1643         int endOffset = m_token.m_data.offset;
1644         next();
1645         TreeStatement result = context.createBlockStatement(location, 0, start, m_lastTokenEndPosition.line, shouldPushLexicalScope ? currentScope()->finalizeLexicalEnvironment() : emptyEnvironment, shouldPushLexicalScope ? currentScope()->takeFunctionDeclarations() : WTFMove(emptyFunctionStack));
1646         context.setStartOffset(result, startOffset);
1647         context.setEndOffset(result, endOffset);
1648         if (shouldPushLexicalScope)
1649             popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
1650         return result;
1651     }
1652     TreeSourceElements subtree = parseSourceElements(context, DontCheckForStrictMode);
1653     failIfFalse(subtree, "Cannot parse the body of the block statement");
1654     matchOrFail(CLOSEBRACE, "Expected a closing '}' at the end of a block statement");
1655     int endOffset = m_token.m_data.offset;
1656     next();
1657     TreeStatement result = context.createBlockStatement(location, subtree, start, m_lastTokenEndPosition.line, shouldPushLexicalScope ? currentScope()->finalizeLexicalEnvironment() : emptyEnvironment, shouldPushLexicalScope ? currentScope()->takeFunctionDeclarations() : WTFMove(emptyFunctionStack));
1658     context.setStartOffset(result, startOffset);
1659     context.setEndOffset(result, endOffset);
1660     if (shouldPushLexicalScope)
1661         popScope(lexicalScope, TreeBuilder::NeedsFreeVariableInfo);
1662
1663     return result;
1664 }
1665
1666 template <typename LexerType>
1667 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength)
1668 {
1669     DepthManager statementDepth(&m_statementDepth);
1670     m_statementDepth++;
1671     int nonTrivialExpressionCount = 0;
1672     failIfStackOverflow();
1673     TreeStatement result = 0;
1674     bool shouldSetEndOffset = true;
1675     bool shouldSetPauseLocation = false;
1676     bool parentAllowsFunctionDeclarationAsStatement = m_immediateParentAllowsFunctionDeclarationInStatement;
1677     m_immediateParentAllowsFunctionDeclarationInStatement = false;
1678
1679     switch (m_token.m_type) {
1680     case OPENBRACE:
1681         result = parseBlockStatement(context);
1682         shouldSetEndOffset = false;
1683         break;
1684     case VAR:
1685         result = parseVariableDeclaration(context, DeclarationType::VarDeclaration);
1686         shouldSetPauseLocation = true;
1687         break;
1688     case FUNCTION: {
1689         const bool isAsync = false;
1690         result = parseFunctionDeclarationStatement(context, isAsync, parentAllowsFunctionDeclarationAsStatement);
1691         break;
1692     }
1693     case SEMICOLON: {
1694         JSTokenLocation location(tokenLocation());
1695         next();
1696         result = context.createEmptyStatement(location);
1697         shouldSetPauseLocation = true;
1698         break;
1699     }
1700     case IF:
1701         result = parseIfStatement(context);
1702         break;
1703     case DO:
1704         result = parseDoWhileStatement(context);
1705         break;
1706     case WHILE:
1707         result = parseWhileStatement(context);
1708         break;
1709     case FOR:
1710         result = parseForStatement(context);
1711         break;
1712     case CONTINUE:
1713         result = parseContinueStatement(context);
1714         shouldSetPauseLocation = true;
1715         break;
1716     case BREAK:
1717         result = parseBreakStatement(context);
1718         shouldSetPauseLocation = true;
1719         break;
1720     case RETURN:
1721         result = parseReturnStatement(context);
1722         shouldSetPauseLocation = true;
1723         break;
1724     case WITH:
1725         result = parseWithStatement(context);
1726         break;
1727     case SWITCH:
1728         result = parseSwitchStatement(context);
1729         break;
1730     case THROW:
1731         result = parseThrowStatement(context);
1732         shouldSetPauseLocation = true;
1733         break;
1734     case TRY:
1735         result = parseTryStatement(context);
1736         break;
1737     case DEBUGGER:
1738         result = parseDebuggerStatement(context);
1739         shouldSetPauseLocation = true;
1740         break;
1741     case EOFTOK:
1742     case CASE:
1743     case CLOSEBRACE:
1744     case DEFAULT:
1745         // These tokens imply the end of a set of source elements
1746         return 0;
1747     case LET: {
1748         if (!strictMode())
1749             goto identcase;
1750         goto defaultCase;
1751     }
1752     case ASYNC:
1753         if (maybeParseAsyncFunctionDeclarationStatement(context, result, parentAllowsFunctionDeclarationAsStatement))
1754             break;
1755         FALLTHROUGH;
1756     case IDENT:
1757     case AWAIT:
1758     case YIELD: {
1759         identcase:
1760         bool allowFunctionDeclarationAsStatement = false;
1761         result = parseExpressionOrLabelStatement(context, allowFunctionDeclarationAsStatement);
1762         shouldSetPauseLocation = !context.shouldSkipPauseLocation(result);
1763         break;
1764     }
1765     case STRING:
1766         directive = m_token.m_data.ident;
1767         if (directiveLiteralLength)
1768             *directiveLiteralLength = m_token.m_location.endOffset - m_token.m_location.startOffset;
1769         nonTrivialExpressionCount = m_parserState.nonTrivialExpressionCount;
1770         FALLTHROUGH;
1771     default:
1772         defaultCase:
1773         TreeStatement exprStatement = parseExpressionStatement(context);
1774         if (directive && nonTrivialExpressionCount != m_parserState.nonTrivialExpressionCount)
1775             directive = nullptr;
1776         result = exprStatement;
1777         shouldSetPauseLocation = true;
1778         break;
1779     }
1780
1781     if (result) {
1782         if (shouldSetEndOffset)
1783             context.setEndOffset(result, m_lastTokenEndPosition.offset);
1784         if (shouldSetPauseLocation)
1785             recordPauseLocation(context.breakpointLocation(result));
1786     }
1787
1788     return result;
1789 }
1790
1791 template <typename LexerType>
1792 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclarationStatement(TreeBuilder& context, bool isAsync, bool parentAllowsFunctionDeclarationAsStatement)
1793 {
1794     semanticFailIfTrue(strictMode(), "Function declarations are only allowed inside blocks or switch statements in strict mode");
1795     failIfFalse(parentAllowsFunctionDeclarationAsStatement, "Function declarations are only allowed inside block statements or at the top level of a program");
1796     if (!currentScope()->isFunction()) {
1797         // We only implement annex B.3.3 if we're in function mode. Otherwise, we fall back
1798         // to hoisting behavior.
1799         // FIXME: https://bugs.webkit.org/show_bug.cgi?id=155813
1800         DepthManager statementDepth(&m_statementDepth);
1801         m_statementDepth = 1;
1802         if (isAsync)
1803             return parseAsyncFunctionDeclaration(context);
1804         return parseFunctionDeclaration(context);
1805     }
1806
1807     // Any function declaration that isn't in a block is a syntax error unless it's
1808     // in an if/else statement. If it's in an if/else statement, we will magically
1809     // treat it as if the if/else statement is inside a block statement.
1810     // to the very top like a "var". For example:
1811     // function a() {
1812     //     if (cond) function foo() { }
1813     // }
1814     // will be rewritten as:
1815     // function a() {
1816     //     if (cond) { function foo() { } }
1817     // }
1818     AutoPopScopeRef blockScope(this, pushScope());
1819     blockScope->setIsLexicalScope();
1820     blockScope->preventVarDeclarations();
1821     JSTokenLocation location(tokenLocation());
1822     int start = tokenLine();
1823
1824     TreeStatement function = 0;
1825     if (!isAsync)
1826         function = parseFunctionDeclaration(context);
1827     else
1828         function = parseAsyncFunctionDeclaration(context);
1829     propagateError();
1830     failIfFalse(function, "Expected valid function statement after 'function' keyword");
1831     TreeSourceElements sourceElements = context.createSourceElements();
1832     context.appendStatement(sourceElements, function);
1833     TreeStatement result = context.createBlockStatement(location, sourceElements, start, m_lastTokenEndPosition.line, currentScope()->finalizeLexicalEnvironment(), currentScope()->takeFunctionDeclarations());
1834     popScope(blockScope, TreeBuilder::NeedsFreeVariableInfo);
1835     return result;
1836 }
1837
1838 template <typename LexerType>
1839 template <class TreeBuilder> bool Parser<LexerType>::maybeParseAsyncFunctionDeclarationStatement(TreeBuilder& context, TreeStatement& result, bool parentAllowsFunctionDeclarationAsStatement)
1840 {
1841     ASSERT(match(ASYNC));
1842     SavePoint savePoint = createSavePoint();
1843     next();
1844     if (match(FUNCTION) && !m_lexer->prevTerminator()) {
1845         const bool isAsync = true;
1846         result = parseFunctionDeclarationStatement(context, isAsync, parentAllowsFunctionDeclarationAsStatement);
1847         return true;
1848     }
1849     restoreSavePoint(savePoint);
1850     return false;
1851 }
1852
1853 template <typename LexerType>
1854 template <class TreeBuilder> bool Parser<LexerType>::parseFormalParameters(TreeBuilder& context, TreeFormalParameterList list, bool isArrowFunction, bool isMethod, unsigned& parameterCount)
1855 {
1856 #define failIfDuplicateIfViolation() \
1857     if (duplicateParameter) {\
1858         semanticFailIfTrue(hasDefaultParameterValues, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in function with default parameter values");\
1859         semanticFailIfTrue(hasDestructuringPattern, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in function with destructuring parameters");\
1860         semanticFailIfTrue(isRestParameter, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in function with a rest parameter");\
1861         semanticFailIfTrue(isArrowFunction, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in an arrow function");\
1862         semanticFailIfTrue(isMethod, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in a method");\
1863     }
1864
1865     bool hasDefaultParameterValues = false;
1866     bool hasDestructuringPattern = false;
1867     bool isRestParameter = false;
1868     const Identifier* duplicateParameter = nullptr;
1869     unsigned restParameterStart = 0;
1870     do {
1871         TreeDestructuringPattern parameter = 0;
1872         TreeExpression defaultValue = 0;
1873
1874         if (UNLIKELY(match(CLOSEPAREN)))
1875             break;
1876         
1877         if (match(DOTDOTDOT)) {
1878             next();
1879             semanticFailIfTrue(!m_parserState.allowAwait && match(AWAIT), "Cannot use 'await' as a parameter name in an async function");
1880             TreeDestructuringPattern destructuringPattern = parseDestructuringPattern(context, DestructuringKind::DestructureToParameters, ExportType::NotExported, &duplicateParameter, &hasDestructuringPattern);
1881             propagateError();
1882             parameter = context.createRestParameter(destructuringPattern, restParameterStart);
1883             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.
1884             isRestParameter = true;
1885         } else
1886             parameter = parseDestructuringPattern(context, DestructuringKind::DestructureToParameters, ExportType::NotExported, &duplicateParameter, &hasDestructuringPattern);
1887         failIfFalse(parameter, "Cannot parse parameter pattern");
1888         if (!isRestParameter) {
1889             defaultValue = parseDefaultValueForDestructuringPattern(context);
1890             if (defaultValue)
1891                 hasDefaultParameterValues = true;
1892         }
1893         propagateError();
1894         failIfDuplicateIfViolation();
1895         if (isRestParameter || defaultValue || hasDestructuringPattern)
1896             currentScope()->setHasNonSimpleParameterList();
1897         context.appendParameter(list, parameter, defaultValue);
1898         if (!isRestParameter) {
1899             restParameterStart++;
1900             if (!hasDefaultParameterValues)
1901                 parameterCount++;
1902         }
1903     } while (!isRestParameter && consume(COMMA));
1904
1905     return true;
1906 #undef failIfDuplicateIfViolation
1907 }
1908
1909 template <typename LexerType>
1910 template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody(
1911     TreeBuilder& context, SyntaxChecker& syntaxChecker, const JSTokenLocation& startLocation, int startColumn, int functionKeywordStart, int functionNameStart, int parametersStart,
1912     ConstructorKind constructorKind, SuperBinding superBinding, FunctionBodyType bodyType, unsigned parameterCount, SourceParseMode parseMode)
1913 {
1914     bool isArrowFunctionBodyExpression = bodyType == ArrowFunctionBodyExpression;
1915     if (!isArrowFunctionBodyExpression) {
1916         next();
1917         if (match(CLOSEBRACE)) {
1918             unsigned endColumn = tokenColumn();
1919             SuperBinding functionSuperBinding = adjustSuperBindingForBaseConstructor(constructorKind, superBinding, currentScope());
1920             return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, functionSuperBinding, parameterCount, parseMode, isArrowFunctionBodyExpression);
1921         }
1922     }
1923
1924     DepthManager statementDepth(&m_statementDepth);
1925     m_statementDepth = 0;
1926     if (bodyType == ArrowFunctionBodyExpression) {
1927         if (m_debuggerParseData)
1928             failIfFalse(parseArrowFunctionSingleExpressionBodySourceElements(context), "Cannot parse body of this arrow function");
1929         else
1930             failIfFalse(parseArrowFunctionSingleExpressionBodySourceElements(syntaxChecker), "Cannot parse body of this arrow function");
1931     } else {
1932         if (m_debuggerParseData)
1933             failIfFalse(parseSourceElements(context, CheckForStrictMode), bodyType == StandardFunctionBodyBlock ? "Cannot parse body of this function" : "Cannot parse body of this arrow function");
1934         else
1935             failIfFalse(parseSourceElements(syntaxChecker, CheckForStrictMode), bodyType == StandardFunctionBodyBlock ? "Cannot parse body of this function" : "Cannot parse body of this arrow function");
1936     }
1937     unsigned endColumn = tokenColumn();
1938     SuperBinding functionSuperBinding = adjustSuperBindingForBaseConstructor(constructorKind, superBinding, currentScope());
1939     return context.createFunctionMetadata(startLocation, tokenLocation(), startColumn, endColumn, functionKeywordStart, functionNameStart, parametersStart, strictMode(), constructorKind, functionSuperBinding, parameterCount, parseMode, isArrowFunctionBodyExpression);
1940 }
1941
1942 static const char* stringForFunctionMode(SourceParseMode mode)
1943 {
1944     switch (mode) {
1945     case SourceParseMode::GetterMode:
1946         return "getter";
1947     case SourceParseMode::SetterMode:
1948         return "setter";
1949     case SourceParseMode::NormalFunctionMode:
1950         return "function";
1951     case SourceParseMode::MethodMode:
1952         return "method";
1953     case SourceParseMode::GeneratorBodyMode:
1954         return "generator";
1955     case SourceParseMode::GeneratorWrapperFunctionMode:
1956     case SourceParseMode::GeneratorWrapperMethodMode:
1957         return "generator function";
1958     case SourceParseMode::ArrowFunctionMode:
1959         return "arrow function";
1960     case SourceParseMode::AsyncFunctionMode:
1961     case SourceParseMode::AsyncFunctionBodyMode:
1962         return "async function";
1963     case SourceParseMode::AsyncMethodMode:
1964         return "async method";
1965     case SourceParseMode::AsyncArrowFunctionBodyMode:
1966     case SourceParseMode::AsyncArrowFunctionMode:
1967         return "async arrow function";
1968     case SourceParseMode::ProgramMode:
1969     case SourceParseMode::ModuleAnalyzeMode:
1970     case SourceParseMode::ModuleEvaluateMode:
1971         RELEASE_ASSERT_NOT_REACHED();
1972         return "";
1973     }
1974     RELEASE_ASSERT_NOT_REACHED();
1975     return nullptr;
1976 }
1977
1978 template <typename LexerType> template <class TreeBuilder, class FunctionInfoType> typename TreeBuilder::FormalParameterList Parser<LexerType>::parseFunctionParameters(TreeBuilder& context, SourceParseMode mode, FunctionInfoType& functionInfo)
1979 {
1980     RELEASE_ASSERT(!(SourceParseModeSet(SourceParseMode::ProgramMode, SourceParseMode::ModuleAnalyzeMode, SourceParseMode::ModuleEvaluateMode).contains(mode)));
1981     TreeFormalParameterList parameterList = context.createFormalParameterList();
1982     SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Parameters);
1983     
1984     if (UNLIKELY((SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(mode)))) {
1985         if (!matchSpecIdentifier() && !match(OPENPAREN)) {
1986             semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
1987             failWithMessage("Expected an arrow function input parameter");
1988         } else {
1989             if (match(OPENPAREN)) {
1990                 next();
1991                 
1992                 if (match(CLOSEPAREN)) {
1993                     functionInfo.parameterCount = 0;
1994                 } else {
1995                     bool isArrowFunction = true;
1996                     bool isMethod = false;
1997                     failIfFalse(parseFormalParameters(context, parameterList, isArrowFunction, isMethod, functionInfo.parameterCount), "Cannot parse parameters for this ", stringForFunctionMode(mode));
1998                 }
1999                 
2000                 consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
2001             } else {
2002                 functionInfo.parameterCount = 1;
2003                 auto parameter = parseDestructuringPattern(context, DestructuringKind::DestructureToParameters, ExportType::NotExported);
2004                 failIfFalse(parameter, "Cannot parse parameter pattern");
2005                 context.appendParameter(parameterList, parameter, 0);
2006             }
2007         }
2008
2009         return parameterList;
2010     }
2011
2012     if (!consume(OPENPAREN)) {
2013         semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
2014         failWithMessage("Expected an opening '(' before a ", stringForFunctionMode(mode), "'s parameter list");
2015     }
2016
2017     if (mode == SourceParseMode::GetterMode) {
2018         consumeOrFail(CLOSEPAREN, "getter functions must have no parameters");
2019         functionInfo.parameterCount = 0;
2020     } else if (mode == SourceParseMode::SetterMode) {
2021         failIfTrue(match(CLOSEPAREN), "setter functions must have one parameter");
2022         const Identifier* duplicateParameter = nullptr;
2023         bool hasDestructuringPattern = false;
2024         auto parameter = parseDestructuringPattern(context, DestructuringKind::DestructureToParameters, ExportType::NotExported, &duplicateParameter, &hasDestructuringPattern);
2025         failIfFalse(parameter, "setter functions must have one parameter");
2026         auto defaultValue = parseDefaultValueForDestructuringPattern(context);
2027         propagateError();
2028         if (defaultValue || hasDestructuringPattern) {
2029             semanticFailIfTrue(duplicateParameter, "Duplicate parameter '", duplicateParameter->impl(), "' not allowed in function with non-simple parameter list");
2030             currentScope()->setHasNonSimpleParameterList();
2031         }
2032         context.appendParameter(parameterList, parameter, defaultValue);
2033         functionInfo.parameterCount = defaultValue ? 0 : 1;
2034         failIfTrue(match(COMMA), "setter functions must have one parameter");
2035         consumeOrFail(CLOSEPAREN, "Expected a ')' after a parameter declaration");
2036     } else {
2037         if (match(CLOSEPAREN)) {
2038             functionInfo.parameterCount = 0;
2039         } else {
2040             bool isArrowFunction = false;
2041             bool isMethod = isMethodParseMode(mode);
2042             failIfFalse(parseFormalParameters(context, parameterList, isArrowFunction, isMethod, functionInfo.parameterCount), "Cannot parse parameters for this ", stringForFunctionMode(mode));
2043         }
2044         consumeOrFail(CLOSEPAREN, "Expected a ')' or a ',' after a parameter declaration");
2045     }
2046
2047     return parameterList;
2048 }
2049
2050 template <typename LexerType>
2051 template <class TreeBuilder> typename TreeBuilder::FormalParameterList Parser<LexerType>::createGeneratorParameters(TreeBuilder& context, unsigned& parameterCount)
2052 {
2053     auto parameters = context.createFormalParameterList();
2054
2055     JSTokenLocation location(tokenLocation());
2056     JSTextPosition position = tokenStartPosition();
2057
2058     auto addParameter = [&](const Identifier& name) {
2059         declareParameter(&name);
2060         auto binding = context.createBindingLocation(location, name, position, position, AssignmentContext::DeclarationStatement);
2061         context.appendParameter(parameters, binding, 0);
2062         ++parameterCount;
2063     };
2064
2065     // @generator
2066     addParameter(m_vm->propertyNames->builtinNames().generatorPrivateName());
2067     // @generatorState
2068     addParameter(m_vm->propertyNames->builtinNames().generatorStatePrivateName());
2069     // @generatorValue
2070     addParameter(m_vm->propertyNames->builtinNames().generatorValuePrivateName());
2071     // @generatorResumeMode
2072     addParameter(m_vm->propertyNames->builtinNames().generatorResumeModePrivateName());
2073     // @generatorFrame
2074     addParameter(m_vm->propertyNames->builtinNames().generatorFramePrivateName());
2075
2076     return parameters;
2077 }
2078
2079 template <typename LexerType>
2080 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)
2081 {
2082     RELEASE_ASSERT(isFunctionParseMode(mode));
2083
2084     ScopeRef parentScope = currentScope();
2085
2086     bool isDisallowedAwaitFunctionName = isDisallowedIdentifierAwait(m_token);
2087     const char* isDisallowedAwaitFunctionNameReason = isDisallowedAwaitFunctionName ? disallowedIdentifierAwaitReason() : nullptr;
2088
2089     AutoPopScopeRef functionScope(this, pushScope());
2090     functionScope->setSourceParseMode(mode);
2091     functionScope->setExpectedSuperBinding(expectedSuperBinding);
2092     functionScope->setConstructorKind(constructorKind);
2093     SetForScope<FunctionParsePhase> functionParsePhasePoisoner(m_parserState.functionParsePhase, FunctionParsePhase::Body);
2094     int functionNameStart = m_token.m_location.startOffset;
2095     const Identifier* lastFunctionName = m_parserState.lastFunctionName;
2096     m_parserState.lastFunctionName = nullptr;
2097     int parametersStart = -1;
2098     JSTokenLocation startLocation;
2099     int startColumn = -1;
2100     FunctionBodyType functionBodyType;
2101
2102     auto loadCachedFunction = [&] () -> bool {
2103         if (UNLIKELY(!Options::useSourceProviderCache()))
2104             return false;
2105
2106         if (UNLIKELY(m_debuggerParseData))
2107             return false;
2108
2109         ASSERT(parametersStart != -1);
2110         ASSERT(startColumn != -1);
2111
2112         // If we know about this function already, we can use the cached info and skip the parser to the end of the function.
2113         if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(parametersStart) : 0) {
2114             // If we're in a strict context, the cached function info must say it was strict too.
2115             ASSERT(!strictMode() || cachedInfo->strictMode);
2116             JSTokenLocation endLocation;
2117
2118             ConstructorKind constructorKind = static_cast<ConstructorKind>(cachedInfo->constructorKind);
2119             SuperBinding expectedSuperBinding = static_cast<SuperBinding>(cachedInfo->expectedSuperBinding);
2120
2121             endLocation.line = cachedInfo->lastTokenLine;
2122             endLocation.startOffset = cachedInfo->lastTokenStartOffset;
2123             endLocation.lineStartOffset = cachedInfo->lastTokenLineStartOffset;
2124             ASSERT(endLocation.startOffset >= endLocation.lineStartOffset);
2125
2126             bool endColumnIsOnStartLine = endLocation.line == functionInfo.startLine;
2127             unsigned currentLineStartOffset = m_lexer->currentLineStartOffset();
2128             unsigned bodyEndColumn = endColumnIsOnStartLine ? endLocation.startOffset - currentLineStartOffset : endLocation.startOffset - endLocation.lineStartOffset;
2129
2130             ASSERT(endLocation.startOffset >= endLocation.lineStartOffset);
2131             
2132             FunctionBodyType functionBodyType;
2133             if (UNLIKELY(SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(mode)))
2134                 functionBodyType = cachedInfo->isBodyArrowExpression ?  ArrowFunctionBodyExpression : ArrowFunctionBodyBlock;
2135             else
2136                 functionBodyType = StandardFunctionBodyBlock;
2137
2138             SuperBinding functionSuperBinding = adjustSuperBindingForBaseConstructor(constructorKind, expectedSuperBinding, cachedInfo->needsSuperBinding, cachedInfo->usesEval, cachedInfo->innerArrowFunctionFeatures);
2139
2140             functionInfo.body = context.createFunctionMetadata(
2141                 startLocation, endLocation, startColumn, bodyEndColumn, 
2142                 functionKeywordStart, functionNameStart, parametersStart, 
2143                 cachedInfo->strictMode, constructorKind, functionSuperBinding,
2144                 cachedInfo->parameterCount,
2145                 mode, functionBodyType == ArrowFunctionBodyExpression);
2146             functionInfo.endOffset = cachedInfo->endFunctionOffset;
2147             functionInfo.parameterCount = cachedInfo->parameterCount;
2148
2149             functionScope->restoreFromSourceProviderCache(cachedInfo);
2150             popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo);
2151             
2152             m_token = cachedInfo->endFunctionToken();
2153
2154             if (endColumnIsOnStartLine)
2155                 m_token.m_location.lineStartOffset = currentLineStartOffset;
2156
2157             m_lexer->setOffset(m_token.m_location.endOffset, m_token.m_location.lineStartOffset);
2158             m_lexer->setLineNumber(m_token.m_location.line);
2159
2160             switch (functionBodyType) {
2161             case ArrowFunctionBodyExpression:
2162                 next();
2163                 context.setEndOffset(functionInfo.body, m_lexer->currentOffset());
2164                 break;
2165             case ArrowFunctionBodyBlock:
2166             case StandardFunctionBodyBlock:
2167                 context.setEndOffset(functionInfo.body, m_lexer->currentOffset());
2168                 next();
2169                 break;
2170             }
2171             functionInfo.endLine = m_lastTokenEndPosition.line;
2172             return true;
2173         }
2174
2175         return false;
2176     };
2177
2178     SyntaxChecker syntaxChecker(const_cast<VM*>(m_vm), m_lexer.get());
2179
2180     if (UNLIKELY((SourceParseModeSet(SourceParseMode::ArrowFunctionMode, SourceParseMode::AsyncArrowFunctionMode).contains(mode)))) {
2181         startLocation = tokenLocation();
2182         functionInfo.startLine = tokenLine();
2183         startColumn = tokenColumn();
2184
2185         parametersStart = m_token.m_location.startOffset;
2186         functionInfo.startOffset = parametersStart;
2187         functionInfo.parametersStartColumn = startColumn;
2188
2189         if (loadCachedFunction())
2190             return true;
2191
2192         {
2193             // Parse formal parameters with [+Yield] parameterization, in order to ban YieldExpressions
2194             // in ArrowFormalParameters, per ES6 #sec-arrow-function-definitions-static-semantics-early-errors.
2195             Scope::MaybeParseAsGeneratorForScope parseAsGenerator(functionScope, parentScope->isGenerator());
2196             SetForScope<bool> overrideAllowAwait(m_parserState.allowAwait, !isAsyncFunctionParseMode(mode));
2197             parseFunctionParameters(syntaxChecker, mode, functionInfo);
2198             propagateError();
2199         }
2200
2201         matchOrFail(ARROWFUNCTION, "Expected a '=>' after arrow function parameter declaration");
2202
2203         if (m_lexer->prevTerminator())
2204             failDueToUnexpectedToken();
2205
2206         ASSERT(constructorKind == ConstructorKind::None);
2207
2208         // Check if arrow body start with {. If it true it mean that arrow function is Fat arrow function
2209         // and we need use common approach to parse function body
2210         next();
2211         functionBodyType = match(OPENBRACE) ? ArrowFunctionBodyBlock : ArrowFunctionBodyExpression;
2212     } else {
2213         // http://ecma-international.org/ecma-262/6.0/#sec-function-definitions
2214         // FunctionExpression :
2215         //     function BindingIdentifieropt ( FormalParameters ) { FunctionBody }
2216         //
2217         // FunctionDeclaration[Yield, Default] :
2218         //     function BindingIdentifier[?Yield] ( FormalParameters ) { FunctionBody }
2219         //     [+Default] function ( FormalParameters ) { FunctionBody }
2220         //
2221         // GeneratorDeclaration[Yield, Default] :
2222         //     function * BindingIdentifier[?Yield] ( FormalParameters[Yield] ) { GeneratorBody }
2223         //     [+Default] function * ( FormalParameters[Yield] ) { GeneratorBody }
2224         //
2225         // GeneratorExpression :
2226         //     function * BindingIdentifier[Yield]opt ( FormalParameters[Yield] ) { GeneratorBody }
2227         //
2228         // The name of FunctionExpression and AsyncFunctionExpression can accept "yield" even in the context of generator.
2229         bool upperScopeIsGenerator = false;
2230         if (!(functionDefinitionType == FunctionDefinitionType::Expression && SourceParseModeSet(SourceParseMode::NormalFunctionMode, SourceParseMode::AsyncFunctionMode).contains(mode)))
2231             upperScopeIsGenerator = upperScope(1)->isGenerator();
2232
2233         if (requirements != FunctionNameRequirements::Unnamed) {
2234             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.");
2235             if (matchSpecIdentifier(upperScopeIsGenerator)) {
2236                 functionInfo.name = m_token.m_data.ident;
2237                 m_parserState.lastFunctionName = functionInfo.name;
2238                 if (UNLIKELY(isDisallowedAwaitFunctionName))
2239                     semanticFailIfTrue(functionDefinitionType == FunctionDefinitionType::Declaration || isAsyncFunctionWrapperParseMode(mode), "Cannot declare function named 'await' ", isDisallowedAwaitFunctionNameReason);
2240                 else if (isAsyncFunctionWrapperParseMode(mode) && match(AWAIT) && functionDefinitionType == FunctionDefinitionType::Expression)
2241                     semanticFail("Cannot declare async function named 'await'");
2242                 else if (isGeneratorWrapperParseMode(mode) && match(YIELD) && functionDefinitionType == FunctionDefinitionType::Expression)
2243                     semanticFail("Cannot declare generator function named 'yield'");
2244                 next();
2245                 if (!nameIsInContainingScope)
2246                     failIfTrueIfStrict(functionScope->declareCallee(functionInfo.name) & DeclarationResult::InvalidStrictMode, "'", functionInfo.name->impl(), "' is not a valid ", stringForFunctionMode(mode), " name in strict mode");
2247             } else if (requirements == FunctionNameRequirements::Named) {
2248                 if (match(OPENPAREN)) {
2249                     semanticFailIfTrue(mode == SourceParseMode::NormalFunctionMode, "Function statements must have a name");
2250                     semanticFailIfTrue(mode == SourceParseMode::AsyncFunctionMode, "Async function statements must have a name");
2251                 }
2252                 semanticFailureDueToKeyword(stringForFunctionMode(mode), " name");
2253                 failDueToUnexpectedToken();
2254                 return false;
2255             }
2256             ASSERT(functionInfo.name);
2257         }
2258
2259         startLocation = tokenLocation();
2260         functionInfo.startLine = tokenLine();
2261         startColumn = tokenColumn();
2262         functionInfo.parametersStartColumn = startColumn;
2263
2264         parametersStart = m_token.m_location.startOffset;
2265         functionInfo.startOffset = parametersStart;
2266
2267         if (loadCachedFunction())
2268             return true;
2269         {
2270             SetForScope<bool> overrideAllowAwait(m_parserState.allowAwait, !isAsyncFunctionParseMode(mode));
2271             parseFunctionParameters(syntaxChecker, mode, functionInfo);
2272             propagateError();
2273         }
2274         
2275         matchOrFail(OPENBRACE, "Expected an opening '{' at the start of a ", stringForFunctionMode(mode), " body");
2276         
2277         // BytecodeGenerator emits code to throw TypeError when a class constructor is "call"ed.
2278         // Set ConstructorKind to None for non-constructor methods of classes.
2279     
2280         if (m_defaultConstructorKind != ConstructorKind::None) {
2281             constructorKind = m_defaultConstructorKind;
2282             expectedSuperBinding = m_defaultConstructorKind == ConstructorKind::Extends ? SuperBinding::Needed : SuperBinding::NotNeeded;
2283         }
2284
2285         functionBodyType = StandardFunctionBodyBlock;
2286     }
2287
2288     functionScope->setConstructorKind(constructorKind);
2289     functionScope->setExpectedSuperBinding(expectedSuperBinding);
2290
2291     m_parserState.lastFunctionName = lastFunctionName;
2292     ParserState oldState = internalSaveParserState();
2293
2294     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=156962
2295     // This loop collects the set of capture candidates that aren't
2296     // part of the set of this function's declared parameters. We will
2297     // figure out which parameters are captured for this function when
2298     // we actually generate code for it. For now, we just propagate to
2299     // our parent scopes which variables we might have closed over that
2300     // belong to them. This is necessary for correctness when using
2301     // the source provider cache because we can't close over a variable
2302     // that we don't claim to close over. The source provider cache must
2303     // know this information to properly cache this function.
2304     // This might work itself out nicer if we declared a different
2305     // Scope struct for the parameters (because they are indeed implemented
2306     // as their own scope).
2307     UniquedStringImplPtrSet nonLocalCapturesFromParameterExpressions;
2308     functionScope->forEachUsedVariable([&] (UniquedStringImpl* impl) {
2309         if (!functionScope->hasDeclaredParameter(impl)) {
2310             nonLocalCapturesFromParameterExpressions.add(impl);
2311             if (TreeBuilder::NeedsFreeVariableInfo)
2312                 parentScope->addClosedVariableCandidateUnconditionally(impl);
2313         }
2314     });
2315
2316     auto performParsingFunctionBody = [&] {
2317         return parseFunctionBody(context, syntaxChecker, startLocation, startColumn, functionKeywordStart, functionNameStart, parametersStart, constructorKind, expectedSuperBinding, functionBodyType, functionInfo.parameterCount, mode);
2318     };
2319
2320     if (isGeneratorOrAsyncFunctionWrapperParseMode(mode)) {
2321         AutoPopScopeRef generatorBodyScope(this, pushScope());
2322         SourceParseMode innerParseMode = SourceParseMode::GeneratorBodyMode;
2323         if (isAsyncFunctionWrapperParseMode(mode)) {
2324             innerParseMode = mode == SourceParseMode::AsyncArrowFunctionMode
2325                 ? SourceParseMode::AsyncArrowFunctionBodyMode
2326                 : SourceParseMode::AsyncFunctionBodyMode;
2327         }
2328         generatorBodyScope->setSourceParseMode(innerParseMode);
2329         generatorBodyScope->setConstructorKind(ConstructorKind::None);
2330         generatorBodyScope->setExpectedSuperBinding(expectedSuperBinding);
2331
2332         // Disallow 'use strict' directives in the implicit inner function if
2333         // needed.
2334         if (functionScope->hasNonSimpleParameterList())
2335             generatorBodyScope->setHasNonSimpleParameterList();
2336
2337         functionInfo.body = performParsingFunctionBody();
2338
2339         // When a generator has a "use strict" directive, a generator function wrapping it should be strict mode.
2340         if  (generatorBodyScope->strictMode())
2341             functionScope->setStrictMode();
2342
2343         popScope(generatorBodyScope, TreeBuilder::NeedsFreeVariableInfo);
2344     } else
2345         functionInfo.body = performParsingFunctionBody();
2346     
2347     restoreParserState(oldState);
2348     failIfFalse(functionInfo.body, "Cannot parse the body of this ", stringForFunctionMode(mode));
2349     context.setEndOffset(functionInfo.body, m_lexer->currentOffset());
2350     if (functionScope->strictMode() && requirements != FunctionNameRequirements::Unnamed) {
2351         ASSERT(functionInfo.name);
2352         RELEASE_ASSERT(SourceParseModeSet(SourceParseMode::NormalFunctionMode, SourceParseMode::MethodMode, SourceParseMode::ArrowFunctionMode, SourceParseMode::GeneratorBodyMode, SourceParseMode::GeneratorWrapperFunctionMode).contains(mode) || isAsyncFunctionWrapperParseMode(mode));
2353         semanticFailIfTrue(m_vm->propertyNames->arguments == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
2354         semanticFailIfTrue(m_vm->propertyNames->eval == *functionInfo.name, "'", functionInfo.name->impl(), "' is not a valid function name in strict mode");
2355     }
2356
2357     JSTokenLocation location = JSTokenLocation(m_token.m_location);
2358     functionInfo.endOffset = m_token.m_data.offset;
2359     
2360     if (functionBodyType == ArrowFunctionBodyExpression) {
2361         location = locationBeforeLastToken();
2362         functionInfo.endOffset = location.endOffset;
2363     } else {
2364         recordFunctionEntryLocation(JSTextPosition(startLocation.line, startLocation.startOffset, startLocation.lineStartOffset));
2365         recordFunctionLeaveLocation(JSTextPosition(location.line, location.startOffset, location.lineStartOffset));
2366     }
2367
2368     // Cache the tokenizer state and the function scope the first time the function is parsed.
2369     // Any future reparsing can then skip the function.
2370     // For arrow function is 8 = x=>x + 4 symbols;
2371     // For ordinary function is 16  = function(){} + 4 symbols
2372     const int minimumSourceLengthToCache = functionBodyType == StandardFunctionBodyBlock ? 16 : 8;
2373     std::unique_ptr<SourceProviderCacheItem> newInfo;
2374     int sourceLength = functionInfo.endOffset - functionInfo.startOffset;
2375     if (TreeBuilder::CanUseFunctionCache && m_functionCache && sourceLength > minimumSourceLengthToCache) {
2376         SourceProviderCacheItemCreationParameters parameters;
2377         parameters.endFunctionOffset = functionInfo.endOffset;
2378         parameters.functionNameStart = functionNameStart;
2379         parameters.lastTokenLine = location.line;
2380         parameters.lastTokenStartOffset = location.startOffset;
2381         parameters.lastTokenEndOffset = location.endOffset;
2382         parameters.lastTokenLineStartOffset = location.lineStartOffset;
2383         parameters.parameterCount = functionInfo.parameterCount;
2384         parameters.constructorKind = constructorKind;
2385         parameters.expectedSuperBinding = expectedSuperBinding;
2386         if (functionBodyType == ArrowFunctionBodyExpression) {
2387             parameters.isBodyArrowExpression = true;
2388             parameters.tokenType = m_token.m_type;
2389         }
2390         functionScope->fillParametersForSourceProviderCache(parameters, nonLocalCapturesFromParameterExpressions);
2391         newInfo = SourceProviderCacheItem::create(parameters);
2392     }
2393     
2394     popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo);
2395     
2396     if (functionBodyType != ArrowFunctionBodyExpression) {
2397         matchOrFail(CLOSEBRACE, "Expected a closing '}' after a ", stringForFunctionMode(mode), " body");
2398         next();
2399     }
2400
2401     if (newInfo)
2402         m_functionCache->add(functionInfo.startOffset, WTFMove(newInfo));
2403     
2404     functionInfo.endLine = m_lastTokenEndPosition.line;
2405     return true;
2406 }
2407
2408 static NO_RETURN_DUE_TO_CRASH FunctionMetadataNode* getMetadata(ParserFunctionInfo<SyntaxChecker>&) { RELEASE_ASSERT_NOT_REACHED(); }
2409 static FunctionMetadataNode* getMetadata(ParserFunctionInfo<ASTBuilder>& info) { return info.body; }
2410
2411 template <typename LexerType>
2412 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclaration(TreeBuilder& context, ExportType exportType, DeclarationDefaultContext declarationDefaultContext)
2413 {
2414     ASSERT(match(FUNCTION));
2415     JSTokenLocation location(tokenLocation());
2416     unsigned functionKeywordStart = tokenStart();
2417     next();
2418     SourceParseMode parseMode = SourceParseMode::NormalFunctionMode;
2419     if (consume(TIMES))
2420         parseMode = SourceParseMode::GeneratorWrapperFunctionMode;
2421
2422     ParserFunctionInfo<TreeBuilder> functionInfo;
2423     FunctionNameRequirements requirements = FunctionNameRequirements::Named;
2424     if (declarationDefaultContext == DeclarationDefaultContext::ExportDefault) {
2425         // Under the "export default" context, function declaration does not require the function name.
2426         //
2427         //     ExportDeclaration:
2428         //         ...
2429         //         export default HoistableDeclaration[~Yield, +Default]
2430         //         ...
2431         //
2432         //     HoistableDeclaration[Yield, Default]:
2433         //         FunctionDeclaration[?Yield, ?Default]
2434         //         GeneratorDeclaration[?Yield, ?Default]
2435         //
2436         //     FunctionDeclaration[Yield, Default]:
2437         //         ...
2438         //         [+Default] function ( FormalParameters[~Yield] ) { FunctionBody[~Yield] }
2439         //
2440         //     GeneratorDeclaration[Yield, Default]:
2441         //         ...
2442         //         [+Default] function * ( FormalParameters[+Yield] ) { GeneratorBody }
2443         //
2444         // In this case, we use "*default*" as this function declaration's name.
2445         requirements = FunctionNameRequirements::None;
2446         functionInfo.name = &m_vm->propertyNames->builtinNames().starDefaultPrivateName();
2447     }
2448
2449     failIfFalse((parseFunctionInfo(context, requirements, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Declaration)), "Cannot parse this function");
2450     ASSERT(functionInfo.name);
2451
2452     std::pair<DeclarationResultMask, ScopeRef> functionDeclaration = declareFunction(functionInfo.name);
2453     DeclarationResultMask declarationResult = functionDeclaration.first;
2454     failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare a function named '", functionInfo.name->impl(), "' in strict mode");
2455     if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
2456         internalFailWithMessage(false, "Cannot declare a function that shadows a let/const/class/function variable '", functionInfo.name->impl(), "' in strict mode");
2457     if (exportType == ExportType::Exported) {
2458         ASSERT_WITH_MESSAGE(declarationDefaultContext != DeclarationDefaultContext::ExportDefault, "Export default case will export the name and binding in the caller.");
2459         semanticFailIfFalse(exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'");
2460         m_moduleScopeData->exportBinding(*functionInfo.name);
2461     }
2462
2463     TreeStatement result = context.createFuncDeclStatement(location, functionInfo);
2464     if (TreeBuilder::CreatesAST)
2465         functionDeclaration.second->appendFunction(getMetadata(functionInfo));
2466     return result;
2467 }
2468
2469 template <typename LexerType>
2470 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseAsyncFunctionDeclaration(TreeBuilder& context, ExportType exportType, DeclarationDefaultContext declarationDefaultContext)
2471 {
2472     ASSERT(match(FUNCTION));
2473     JSTokenLocation location(tokenLocation());
2474     unsigned functionKeywordStart = tokenStart();
2475     next();
2476     ParserFunctionInfo<TreeBuilder> functionInfo;
2477     SourceParseMode parseMode = SourceParseMode::AsyncFunctionMode;
2478     FunctionNameRequirements requirements = FunctionNameRequirements::Named;
2479     if (declarationDefaultContext == DeclarationDefaultContext::ExportDefault) {
2480         // Under the "export default" context, function declaration does not require the function name.
2481         //
2482         //     ExportDeclaration:
2483         //         ...
2484         //         export default HoistableDeclaration[~Yield, +Default]
2485         //         ...
2486         //
2487         //     HoistableDeclaration[Yield, Default]:
2488         //         FunctionDeclaration[?Yield, ?Default]
2489         //         GeneratorDeclaration[?Yield, ?Default]
2490         //
2491         //     FunctionDeclaration[Yield, Default]:
2492         //         ...
2493         //         [+Default] function ( FormalParameters[~Yield] ) { FunctionBody[~Yield] }
2494         //
2495         //     GeneratorDeclaration[Yield, Default]:
2496         //         ...
2497         //         [+Default] function * ( FormalParameters[+Yield] ) { GeneratorBody }
2498         //
2499         // In this case, we use "*default*" as this function declaration's name.
2500         requirements = FunctionNameRequirements::None;
2501         functionInfo.name = &m_vm->propertyNames->builtinNames().starDefaultPrivateName();
2502     }
2503
2504     failIfFalse((parseFunctionInfo(context, requirements, parseMode, true, ConstructorKind::None, SuperBinding::NotNeeded, functionKeywordStart, functionInfo, FunctionDefinitionType::Declaration)), "Cannot parse this async function");
2505     failIfFalse(functionInfo.name, "Async function statements must have a name");
2506
2507     std::pair<DeclarationResultMask, ScopeRef> functionDeclaration = declareFunction(functionInfo.name);
2508     DeclarationResultMask declarationResult = functionDeclaration.first;
2509     failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare an async function named '", functionInfo.name->impl(), "' in strict mode");
2510     if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
2511         internalFailWithMessage(false, "Cannot declare an async function that shadows a let/const/class/function variable '", functionInfo.name->impl(), "' in strict mode");
2512     if (exportType == ExportType::Exported) {
2513         semanticFailIfFalse(exportName(*functionInfo.name), "Cannot export a duplicate function name: '", functionInfo.name->impl(), "'");
2514         m_moduleScopeData->exportBinding(*functionInfo.name);
2515     }
2516
2517     TreeStatement result = context.createFuncDeclStatement(location, functionInfo);
2518     if (TreeBuilder::CreatesAST)
2519         functionDeclaration.second->appendFunction(getMetadata(functionInfo));
2520     return result;
2521 }
2522
2523 template <typename LexerType>
2524 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseClassDeclaration(TreeBuilder& context, ExportType exportType, DeclarationDefaultContext declarationDefaultContext)
2525 {
2526     ASSERT(match(CLASSTOKEN));
2527     JSTokenLocation location(tokenLocation());
2528     JSTextPosition classStart = tokenStartPosition();
2529     unsigned classStartLine = tokenLine();
2530
2531     ParserClassInfo<TreeBuilder> info;
2532     FunctionNameRequirements requirements = FunctionNameRequirements::Named;
2533     if (declarationDefaultContext == DeclarationDefaultContext::ExportDefault) {
2534         // Under the "export default" context, class declaration does not require the class name.
2535         //
2536         //     ExportDeclaration:
2537         //         ...
2538         //         export default ClassDeclaration[~Yield, +Default]
2539         //         ...
2540         //
2541         //     ClassDeclaration[Yield, Default]:
2542         //         ...
2543         //         [+Default] class ClassTail[?Yield]
2544         //
2545         // In this case, we use "*default*" as this class declaration's name.
2546         requirements = FunctionNameRequirements::None;
2547         info.className = &m_vm->propertyNames->builtinNames().starDefaultPrivateName();
2548     }
2549
2550     TreeClassExpression classExpr = parseClass(context, requirements, info);
2551     failIfFalse(classExpr, "Failed to parse class");
2552     ASSERT(info.className);
2553
2554     DeclarationResultMask declarationResult = declareVariable(info.className, DeclarationType::LetDeclaration);
2555     if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
2556         internalFailWithMessage(false, "Cannot declare a class twice: '", info.className->impl(), "'");
2557     if (exportType == ExportType::Exported) {
2558         ASSERT_WITH_MESSAGE(declarationDefaultContext != DeclarationDefaultContext::ExportDefault, "Export default case will export the name and binding in the caller.");
2559         semanticFailIfFalse(exportName(*info.className), "Cannot export a duplicate class name: '", info.className->impl(), "'");
2560         m_moduleScopeData->exportBinding(*info.className);
2561     }
2562
2563     JSTextPosition classEnd = lastTokenEndPosition();
2564     unsigned classEndLine = tokenLine();
2565
2566     return context.createClassDeclStatement(location, classExpr, classStart, classEnd, classStartLine, classEndLine);
2567 }
2568
2569 template <typename LexerType>
2570 template <class TreeBuilder> TreeClassExpression Parser<LexerType>::parseClass(TreeBuilder& context, FunctionNameRequirements requirements, ParserClassInfo<TreeBuilder>& info)
2571 {
2572     ASSERT(match(CLASSTOKEN));
2573     JSTokenLocation location(tokenLocation());
2574     info.startLine = location.line;
2575     info.startColumn = tokenColumn();
2576     info.startOffset = location.startOffset;
2577     next();
2578
2579     AutoPopScopeRef classScope(this, pushScope());
2580     classScope->setIsLexicalScope();
2581     classScope->preventVarDeclarations();
2582     classScope->setStrictMode();
2583
2584     ASSERT_WITH_MESSAGE(requirements != FunctionNameRequirements::Unnamed, "Currently, there is no caller that uses FunctionNameRequirements::Unnamed for class syntax.");
2585     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.");
2586     if (match(IDENT)) {
2587         info.className = m_token.m_data.ident;
2588         next();
2589         failIfTrue(classScope->declareLexicalVariable(info.className, true) & DeclarationResult::InvalidStrictMode, "'", info.className->impl(), "' is not a valid class name");
2590     } else if (requirements == FunctionNameRequirements::Named) {
2591         if (match(OPENBRACE))
2592             semanticFail("Class statements must have a name");
2593         semanticFailureDueToKeyword("class name");
2594         failDueToUnexpectedToken();
2595     }
2596     ASSERT(info.className);
2597
2598     TreeExpression parentClass = 0;
2599     if (consume(EXTENDS)) {
2600         parentClass = parseMemberExpression(context);
2601         failIfFalse(parentClass, "Cannot parse the parent class name");
2602     }
2603     const ConstructorKind constructorKind = parentClass ? ConstructorKind::Extends : ConstructorKind::Base;
2604
2605     consumeOrFail(OPENBRACE, "Expected opening '{' at the start of a class body");
2606
2607     TreeExpression constructor = 0;
2608     TreePropertyList staticMethods = 0;
2609     TreePropertyList instanceMethods = 0;
2610     TreePropertyList instanceMethodsTail = 0;
2611     TreePropertyList staticMethodsTail = 0;
2612     while (!match(CLOSEBRACE)) {
2613         if (match(SEMICOLON)) {
2614             next();
2615             continue;
2616         }
2617
2618         JSTokenLocation methodLocation(tokenLocation());
2619         unsigned methodStart = tokenStart();
2620
2621         // For backwards compatibility, "static" is a non-reserved keyword in non-strict mode.
2622         bool isStaticMethod = false;
2623         if (match(RESERVED_IF_STRICT) && *m_token.m_data.ident == m_vm->propertyNames->staticKeyword) {
2624             SavePoint savePoint = createSavePoint();
2625             next();
2626             if (match(OPENPAREN)) {
2627                 // Reparse "static()" as a method named "static".
2628                 restoreSavePoint(savePoint);
2629             } else
2630                 isStaticMethod = true;
2631         }
2632
2633         // FIXME: Figure out a way to share more code with parseProperty.
2634         const CommonIdentifiers& propertyNames = *m_vm->propertyNames;
2635         const Identifier* ident = &propertyNames.nullIdentifier;
2636         TreeExpression computedPropertyName = 0;
2637         bool isGetter = false;
2638         bool isSetter = false;
2639         bool isGenerator = false;
2640         bool isAsync = false;
2641         bool isAsyncMethod = false;
2642         if (consume(TIMES))
2643             isGenerator = true;
2644
2645 parseMethod:
2646         switch (m_token.m_type) {
2647         namedKeyword:
2648         case STRING:
2649             ident = m_token.m_data.ident;
2650             ASSERT(ident);
2651             next();
2652             break;
2653         case ASYNC:
2654             isAsync = !isGenerator && !isAsyncMethod;
2655             FALLTHROUGH;
2656         case IDENT:
2657         case AWAIT:
2658             ident = m_token.m_data.ident;
2659             ASSERT(ident);
2660             next();
2661             if (!isGenerator && !isAsyncMethod && (matchIdentifierOrKeyword() || match(STRING) || match(DOUBLE) || match(INTEGER) || match(OPENBRACKET))) {
2662                 isGetter = *ident == propertyNames.get;
2663                 isSetter = *ident == propertyNames.set;
2664
2665                 if (UNLIKELY(isAsync && !m_lexer->prevTerminator())) {
2666                     isAsyncMethod = true;
2667                     goto parseMethod;
2668                 }
2669             }
2670             break;
2671         case DOUBLE:
2672         case INTEGER:
2673             ident = &m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), m_token.m_data.doubleValue);
2674             ASSERT(ident);
2675             next();
2676             break;
2677         case OPENBRACKET:
2678             next();
2679             computedPropertyName = parseAssignmentExpression(context);
2680             failIfFalse(computedPropertyName, "Cannot parse computed property name");
2681             handleProductionOrFail(CLOSEBRACKET, "]", "end", "computed property name");
2682             break;
2683         default:
2684             if (m_token.m_type & KeywordTokenFlag)
2685                 goto namedKeyword;
2686             failDueToUnexpectedToken();
2687         }
2688
2689         TreeProperty property;
2690         const bool alwaysStrictInsideClass = true;
2691         if (isGetter || isSetter) {
2692             bool isClassProperty = true;
2693             property = parseGetterSetter(context, alwaysStrictInsideClass, isGetter ? PropertyNode::Getter : PropertyNode::Setter,
2694                 methodStart, ConstructorKind::None, isClassProperty, isStaticMethod);
2695             failIfFalse(property, "Cannot parse this method");
2696         } else {
2697             ParserFunctionInfo<TreeBuilder> methodInfo;
2698             bool isConstructor = !isStaticMethod && *ident == propertyNames.constructor;
2699             SourceParseMode parseMode = SourceParseMode::MethodMode;
2700             if (isAsyncMethod) {
2701                 isConstructor = false;
2702                 parseMode = SourceParseMode::AsyncMethodMode;
2703                 semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare an async method named 'prototype'");
2704                 semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare an async method named 'constructor'");
2705             } else if (isGenerator) {
2706                 isConstructor = false;
2707                 parseMode = SourceParseMode::GeneratorWrapperMethodMode;
2708                 semanticFailIfTrue(*ident == m_vm->propertyNames->prototype, "Cannot declare a generator named 'prototype'");
2709                 semanticFailIfTrue(*ident == m_vm->propertyNames->constructor, "Cannot declare a generator named 'constructor'");
2710             }
2711             methodInfo.name = isConstructor ? info.className : ident;
2712             failIfFalse((parseFunctionInfo(context, FunctionNameRequirements::Unnamed, parseMode, false, isConstructor ? constructorKind : ConstructorKind::None, SuperBinding::Needed, methodStart, methodInfo, FunctionDefinitionType::Method)), "Cannot parse this method");
2713
2714             TreeExpression method = context.createMethodDefinition(methodLocation, methodInfo);
2715             if (isConstructor) {
2716                 semanticFailIfTrue(constructor, "Cannot declare multiple constructors in a single class");
2717                 constructor = method;
2718                 continue;
2719             }
2720
2721             // FIXME: Syntax error when super() is called
2722             semanticFailIfTrue(isStaticMethod && methodInfo.name && *methodInfo.name == propertyNames.prototype,
2723                 "Cannot declare a static method named 'prototype'");
2724
2725             bool isClassProperty = true;
2726             if (computedPropertyName) {
2727                 property = context.createProperty(computedPropertyName, method, static_cast<PropertyNode::Type>(PropertyNode::Constant | PropertyNode::Computed),
2728                     PropertyNode::Unknown, alwaysStrictInsideClass, SuperBinding::Needed, isClassProperty);
2729             } else {
2730                 property = context.createProperty(methodInfo.name, method, PropertyNode::Constant,
2731                     PropertyNode::Unknown, alwaysStrictInsideClass, SuperBinding::Needed, InferName::Allowed, isClassProperty);
2732             }
2733         }
2734
2735         TreePropertyList& tail = isStaticMethod ? staticMethodsTail : instanceMethodsTail;
2736         if (tail)
2737             tail = context.createPropertyList(methodLocation, property, tail);
2738         else {
2739             tail = context.createPropertyList(methodLocation, property);
2740             if (isStaticMethod)
2741                 staticMethods = tail;
2742             else
2743                 instanceMethods = tail;
2744         }
2745     }
2746
2747     info.endOffset = tokenLocation().endOffset - 1;
2748     consumeOrFail(CLOSEBRACE, "Expected a closing '}' after a class body");
2749
2750     auto classExpression = context.createClassExpr(location, info, classScope->finalizeLexicalEnvironment(), constructor, parentClass, instanceMethods, staticMethods);
2751     popScope(classScope, TreeBuilder::NeedsFreeVariableInfo);
2752     return classExpression;
2753 }
2754
2755 struct LabelInfo {
2756     LabelInfo(const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end)
2757     : m_ident(ident)
2758     , m_start(start)
2759     , m_end(end)
2760     {
2761     }
2762     
2763     const Identifier* m_ident;
2764     JSTextPosition m_start;
2765     JSTextPosition m_end;
2766 };
2767
2768 template <typename LexerType>
2769 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrLabelStatement(TreeBuilder& context, bool allowFunctionDeclarationAsStatement)
2770 {
2771     
2772     /* Expression and Label statements are ambiguous at LL(1), so we have a
2773      * special case that looks for a colon as the next character in the input.
2774      */
2775     Vector<LabelInfo> labels;
2776     JSTokenLocation location;
2777     do {
2778         JSTextPosition start = tokenStartPosition();
2779         location = tokenLocation();
2780         if (!nextTokenIsColon()) {
2781             // If we hit this path we're making a expression statement, which
2782             // by definition can't make use of continue/break so we can just
2783             // ignore any labels we might have accumulated.
2784             TreeExpression expression = parseExpression(context);
2785             failIfFalse(expression, "Cannot parse expression statement");
2786             if (!autoSemiColon())
2787                 failDueToUnexpectedToken();
2788             return context.createExprStatement(location, expression, start, m_lastTokenEndPosition.line);
2789         }
2790
2791         semanticFailIfTrue(isDisallowedIdentifierAwait(m_token), "Cannot use 'await' as a label ", disallowedIdentifierAwaitReason());
2792         semanticFailIfTrue(isDisallowedIdentifierYield(m_token), "Cannot use 'yield' as a label ", disallowedIdentifierYieldReason());
2793
2794         const Identifier* ident = m_token.m_data.ident;
2795         JSTextPosition end = tokenEndPosition();
2796         next();
2797         consumeOrFail(COLON, "Labels must be followed by a ':'");
2798         if (!m_syntaxAlreadyValidated) {
2799             // This is O(N^2) over the current list of consecutive labels, but I
2800             // have never seen more than one label in a row in the real world.
2801             for (size_t i = 0; i < labels.size(); i++)
2802                 failIfTrue(ident->impl() == labels[i].m_ident->impl(), "Attempted to redeclare the label '", ident->impl(), "'");
2803             failIfTrue(getLabel(ident), "Cannot find scope for the label '", ident->impl(), "'");
2804             labels.append(LabelInfo(ident, start, end));
2805         }
2806     } while (matchSpecIdentifier());
2807     bool isLoop = false;
2808     switch (m_token.m_type) {
2809     case FOR:
2810     case WHILE:
2811     case DO:
2812         isLoop = true;
2813         break;
2814         
2815     default:
2816         break;
2817     }
2818     const Identifier* unused = 0;
2819     ScopeRef labelScope = currentScope();
2820     if (!m_syntaxAlreadyValidated) {
2821         for (size_t i = 0; i < labels.size(); i++)
2822             pushLabel(labels[i].m_ident, isLoop);
2823     }
2824     m_immediateParentAllowsFunctionDeclarationInStatement = allowFunctionDeclarationAsStatement;
2825     TreeStatement statement = parseStatement(context, unused);
2826     if (!m_syntaxAlreadyValidated) {
2827         for (size_t i = 0; i < labels.size(); i++)
2828             popLabel(labelScope);
2829     }
2830     failIfFalse(statement, "Cannot parse statement");
2831     for (size_t i = 0; i < labels.size(); i++) {
2832         const LabelInfo& info = labels[labels.size() - i - 1];
2833         statement = context.createLabelStatement(location, info.m_ident, statement, info.m_start, info.m_end);
2834     }
2835     return statement;
2836 }
2837
2838 template <typename LexerType>
2839 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionStatement(TreeBuilder& context)
2840 {
2841     switch (m_token.m_type) {
2842     // Consult: http://www.ecma-international.org/ecma-262/6.0/index.html#sec-expression-statement
2843     // The ES6 spec mandates that we should fail from FUNCTION token here. We handle this case 
2844     // in parseStatement() which is the only caller of parseExpressionStatement().
2845     // We actually allow FUNCTION in situations where it should not be allowed unless we're in strict mode.
2846     case CLASSTOKEN:
2847         failWithMessage("'class' declaration is not directly within a block statement");
2848         break;
2849     default:
2850         // FIXME: when implementing 'let' we should fail when we see the token sequence "let [".
2851         // https://bugs.webkit.org/show_bug.cgi?id=142944
2852         break;
2853     }
2854     JSTextPosition start = tokenStartPosition();
2855     JSTokenLocation location(tokenLocation());
2856     TreeExpression expression = parseExpression(context);
2857     failIfFalse(expression, "Cannot parse expression statement");
2858     failIfFalse(autoSemiColon(), "Parse error");
2859     return context.createExprStatement(location, expression, start, m_lastTokenEndPosition.line);
2860 }
2861
2862 template <typename LexerType>
2863 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(TreeBuilder& context)
2864 {
2865     ASSERT(match(IF));
2866     JSTokenLocation ifLocation(tokenLocation());
2867     int start = tokenLine();
2868     next();
2869     handleProductionOrFail2(OPENPAREN, "(", "start", "'if' condition");
2870
2871     TreeExpression condition = parseExpression(context);
2872     failIfFalse(condition, "Expected a expression as the condition for an if statement");
2873     recordPauseLocation(context.breakpointLocation(condition));
2874     int end = tokenLine();
2875     handleProductionOrFail2(CLOSEPAREN, ")", "end", "'if' condition");
2876
2877     const Identifier* unused = 0;
2878     m_immediateParentAllowsFunctionDeclarationInStatement = true;
2879     TreeStatement trueBlock = parseStatement(context, unused);
2880     failIfFalse(trueBlock, "Expected a statement as the body of an if block");
2881
2882     if (!match(ELSE))
2883         return context.createIfStatement(ifLocation, condition, trueBlock, 0, start, end);
2884
2885     Vector<TreeExpression> exprStack;
2886     Vector<std::pair<int, int>> posStack;
2887     Vector<JSTokenLocation> tokenLocationStack;
2888     Vector<TreeStatement> statementStack;
2889     bool trailingElse = false;
2890     do {
2891         JSTokenLocation tempLocation = tokenLocation();
2892         next();
2893         if (!match(IF)) {
2894             const Identifier* unused = 0;
2895             m_immediateParentAllowsFunctionDeclarationInStatement = true;
2896             TreeStatement block = parseStatement(context, unused);
2897             failIfFalse(block, "Expected a statement as the body of an else block");
2898             statementStack.append(block);
2899             trailingElse = true;
2900             break;
2901         }
2902         int innerStart = tokenLine();
2903         next();
2904         
2905         handleProductionOrFail2(OPENPAREN, "(", "start", "'if' condition");
2906
2907         TreeExpression innerCondition = parseExpression(context);
2908         failIfFalse(innerCondition, "Expected a expression as the condition for an if statement");
2909         recordPauseLocation(context.breakpointLocation(innerCondition));
2910         int innerEnd = tokenLine();
2911         handleProductionOrFail2(CLOSEPAREN, ")", "end", "'if' condition");
2912         const Identifier* unused = 0;
2913         m_immediateParentAllowsFunctionDeclarationInStatement = true;
2914         TreeStatement innerTrueBlock = parseStatement(context, unused);
2915         failIfFalse(innerTrueBlock, "Expected a statement as the body of an if block");
2916         tokenLocationStack.append(tempLocation);
2917         exprStack.append(innerCondition);
2918         posStack.append(std::make_pair(innerStart, innerEnd));
2919         statementStack.append(innerTrueBlock);
2920     } while (match(ELSE));
2921
2922     if (!trailingElse) {
2923         TreeExpression condition = exprStack.last();
2924         exprStack.removeLast();
2925         TreeStatement trueBlock = statementStack.last();
2926         statementStack.removeLast();
2927         std::pair<int, int> pos = posStack.last();
2928         posStack.removeLast();
2929         JSTokenLocation elseLocation = tokenLocationStack.last();
2930         tokenLocationStack.removeLast();
2931         TreeStatement ifStatement = context.createIfStatement(elseLocation, condition, trueBlock, 0, pos.first, pos.second);
2932         context.setEndOffset(ifStatement, context.endOffset(trueBlock));
2933         statementStack.append(ifStatement);
2934     }
2935
2936     while (!exprStack.isEmpty()) {
2937         TreeExpression condition = exprStack.last();
2938         exprStack.removeLast();
2939         TreeStatement falseBlock = statementStack.last();
2940         statementStack.removeLast();
2941         TreeStatement trueBlock = statementStack.last();
2942         statementStack.removeLast();
2943         std::pair<int, int> pos = posStack.last();
2944         posStack.removeLast();
2945         JSTokenLocation elseLocation = tokenLocationStack.last();
2946         tokenLocationStack.removeLast();
2947         TreeStatement ifStatement = context.createIfStatement(elseLocation, condition, trueBlock, falseBlock, pos.first, pos.second);
2948         context.setEndOffset(ifStatement, context.endOffset(falseBlock));
2949         statementStack.append(ifStatement);
2950     }
2951
2952     return context.createIfStatement(ifLocation, condition, trueBlock, statementStack.last(), start, end);
2953 }
2954
2955 template <typename LexerType>
2956 template <class TreeBuilder> typename TreeBuilder::ModuleName Parser<LexerType>::parseModuleName(TreeBuilder& context)
2957 {
2958     // ModuleName (ModuleSpecifier in the spec) represents the module name imported by the script.
2959     // http://www.ecma-international.org/ecma-262/6.0/#sec-imports
2960     // http://www.ecma-international.org/ecma-262/6.0/#sec-exports
2961     JSTokenLocation specifierLocation(tokenLocation());
2962     failIfFalse(match(STRING), "Imported modules names must be string literals");
2963     const Identifier* moduleName = m_token.m_data.ident;
2964     next();
2965     return context.createModuleName(specifierLocation, *moduleName);
2966 }
2967
2968 template <typename LexerType>
2969 template <class TreeBuilder> typename TreeBuilder::ImportSpecifier Parser<LexerType>::parseImportClauseItem(TreeBuilder& context, ImportSpecifierType specifierType)
2970 {
2971     // Produced node is the item of the ImportClause.
2972     // That is the ImportSpecifier, ImportedDefaultBinding or NameSpaceImport.
2973     // http://www.ecma-international.org/ecma-262/6.0/#sec-imports
2974     JSTokenLocation specifierLocation(tokenLocation());
2975     JSToken localNameToken;
2976     const Identifier* importedName = nullptr;
2977     const Identifier* localName = nullptr;
2978
2979     switch (specifierType) {
2980     case ImportSpecifierType::NamespaceImport: {
2981         // NameSpaceImport :
2982         // * as ImportedBinding
2983         // e.g.
2984         //     * as namespace
2985         ASSERT(match(TIMES));
2986         importedName = &m_vm->propertyNames->timesIdentifier;
2987         next();
2988
2989         failIfFalse(matchContextualKeyword(m_vm->propertyNames->as), "Expected 'as' before imported binding name");
2990         next();
2991
2992         failIfFalse(matchSpecIdentifier(), "Expected a variable name for the import declaration");
2993         localNameToken = m_token;
2994         localName = m_token.m_data.ident;
2995         next();
2996         break;
2997     }
2998
2999     case ImportSpecifierType::NamedImport: {
3000         // ImportSpecifier :
3001         // ImportedBinding
3002         // IdentifierName as ImportedBinding
3003         // e.g.
3004         //     A
3005         //     A as B
3006         ASSERT(matchIdentifierOrKeyword());
3007         localNameToken = m_token;
3008         localName = m_token.m_data.ident;
3009         importedName = localName;
3010         next();
3011
3012         if (matchContextualKeyword(m_vm->propertyNames->as)) {
3013             next();
3014             failIfFalse(matchSpecIdentifier(), "Expected a variable name for the import declaration");
3015             localNameToken = m_token;
3016             localName = m_token.m_data.ident;
3017             next();
3018         }
3019         break;
3020     }
3021
3022     case ImportSpecifierType::DefaultImport: {
3023         // ImportedDefaultBinding :
3024         // ImportedBinding
3025         ASSERT(matchSpecIdentifier());
3026         localNameToken = m_token;
3027         localName = m_token.m_data.ident;
3028         importedName = &m_vm->propertyNames->defaultKeyword;
3029         next();
3030         break;
3031     }
3032     }
3033
3034     semanticFailIfTrue(localNameToken.m_type == AWAIT, "Cannot use 'await' as an imported binding name");
3035     semanticFailIfTrue(localNameToken.m_type & KeywordTokenFlag, "Cannot use keyword as imported binding name");
3036     DeclarationResultMask declarationResult = declareVariable(localName, DeclarationType::ConstDeclaration, (specifierType == ImportSpecifierType::NamespaceImport) ? DeclarationImportType::ImportedNamespace : DeclarationImportType::Imported);
3037     if (declarationResult != DeclarationResult::Valid) {
3038         failIfTrueIfStrict(declarationResult & DeclarationResult::InvalidStrictMode, "Cannot declare an imported binding named ", localName->impl(), " in strict mode");
3039         if (declarationResult & DeclarationResult::InvalidDuplicateDeclaration)
3040             internalFailWithMessage(false, "Cannot declare an imported binding name twice: '", localName->impl(), "'");
3041     }
3042
3043     return context.createImportSpecifier(specifierLocation, *importedName, *localName);
3044 }
3045
3046 template <typename LexerType>
3047 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseImportDeclaration(TreeBuilder& context)
3048 {
3049     // http://www.ecma-international.org/ecma-262/6.0/#sec-imports
3050     ASSERT(match(IMPORT));
3051     JSTokenLocation importLocation(tokenLocation());
3052     next();
3053
3054     auto specifierList = context.createImportSpecifierList();
3055
3056     if (match(STRING)) {
3057         // import ModuleSpecifier ;
3058         auto moduleName = parseModuleName(context);
3059         failIfFalse(moduleName, "Cannot parse the module name");
3060         failIfFalse(autoSemiColon(), "Expected a ';' following a targeted import declaration");
3061         return context.createImportDeclaration(importLocation, specifierList, moduleName);
3062     }
3063
3064     bool isFinishedParsingImport = false;
3065     if (matchSpecIdentifier()) {
3066         // ImportedDefaultBinding :
3067         // ImportedBinding
3068         auto specifier = parseImportClauseItem(context, ImportSpecifierType::DefaultImport);
3069         failIfFalse(specifier, "Cannot parse the default import");
3070         context.appendImportSpecifier(specifierList, specifier);
3071         if (match(COMMA))
3072             next();
3073         else
3074             isFinishedParsingImport = true;
3075     }
3076
3077     if (!isFinishedParsingImport) {
3078         if (match(TIMES)) {
3079             // import NameSpaceImport FromClause ;
3080             auto specifier = parseImportClauseItem(context, ImportSpecifierType::NamespaceImport);
3081             failIfFalse(specifier, "Cannot parse the namespace import");
3082             context.appendImportSpecifier(specifierList, specifier);
3083         } else if (match(OPENBRACE)) {
3084             // NamedImports :
3085             // { }
3086             // { ImportsList }
3087             // { ImportsList , }
3088             next();
3089
3090             while (!match(CLOSEBRACE)) {
3091                 failIfFalse(matchIdentifierOrKeyword(), "Expected an imported name for the import declaration");
3092                 auto specifier = parseImportClauseItem(context, ImportSpecifierType::NamedImport);
3093                 failIfFalse(specifier, "Cannot parse the named import");
3094                 context.appendImportSpecifier(specifierList, specifier);
3095                 if (!consume(COMMA))
3096                     break;
3097             }
3098             handleProductionOrFail2(CLOSEBRACE, "}", "end", "import list");
3099         } else
3100             failWithMessage("Expected namespace import or import list");
3101     }
3102
3103     // FromClause :
3104     // from ModuleSpecifier
3105
3106     failIfFalse(matchContextualKeyword(m_vm->propertyNames->from), "Expected 'from' before imported module name");
3107     next();
3108
3109     auto moduleName = parseModuleName(context);
3110     failIfFalse(moduleName, "Cannot parse the module name");
3111     failIfFalse(autoSemiColon(), "Expected a ';' following a targeted import declaration");
3112
3113     return context.createImportDeclaration(importLocation, specifierList, moduleName);
3114 }
3115
3116 template <typename LexerType>
3117 template <class TreeBuilder> typename TreeBuilder::ExportSpecifier Parser<LexerType>::parseExportSpecifier(TreeBuilder& context, Vector<std::pair<const Identifier*, const Identifier*>>& maybeExportedLocalNames, bool& hasKeywordForLocalBindings)
3118 {
3119     // ExportSpecifier :
3120     // IdentifierName
3121     // IdentifierName as IdentifierName
3122     // http://www.ecma-international.org/ecma-262/6.0/#sec-exports
3123     ASSERT(matchIdentifierOrKeyword());
3124     JSTokenLocation specifierLocation(tokenLocation());
3125     if (m_token.m_type & KeywordTokenFlag)
3126         hasKeywordForLocalBindings = true;
3127     const Identifier* localName = m_token.m_data.ident;
3128     const Identifier* exportedName = localName;
3129     next();
3130
3131     if (matchContextualKeyword(m_vm->propertyNames->as)) {
3132         next();
3133         failIfFalse(matchIdentifierOrKeyword(), "Expected an exported name for the export declaration");
3134         exportedName = m_token.m_data.ident;
3135         next();
3136     }
3137
3138     semanticFailIfFalse(exportName(*exportedName), "Cannot export a duplicate name '", exportedName->impl(), "'");
3139     maybeExportedLocalNames.append(std::make_pair(localName, exportedName));
3140     return context.createExportSpecifier(specifierLocation, *localName, *exportedName);
3141 }
3142
3143 template <typename LexerType>
3144 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExportDeclaration(TreeBuilder& context)
3145 {
3146     // http://www.ecma-international.org/ecma-262/6.0/#sec-exports
3147     ASSERT(match(EXPORT));
3148     JSTokenLocation exportLocation(tokenLocation());
3149     next();
3150
3151     switch (m_token.m_type) {
3152     case TIMES: {
3153         // export * FromClause ;
3154         next();
3155
3156         failIfFalse(matchContextualKeyword(m_vm->propertyNames->from), "Expected 'from' before exported module name");
3157         next();
3158         auto moduleName = parseModuleName(context);
3159         failIfFalse(moduleName, "Cannot parse the 'from' clause");
3160         failIfFalse(autoSemiColon(), "Expected a ';' following a targeted export declaration");
3161
3162         return context.createExportAllDeclaration(exportLocation, moduleName);
3163     }
3164
3165     case DEFAULT: {
3166         // export default HoistableDeclaration[Default]
3167         // export default ClassDeclaration[Default]
3168         // export default [lookahead not-in {function, class}] AssignmentExpression[In] ;
3169
3170         next();
3171
3172         TreeStatement result = 0;
3173         bool isFunctionOrClassDeclaration = false;
3174         const Identifier* localName = nullptr;
3175
3176         bool startsWithFunction = match(FUNCTION);
3177         if (startsWithFunction || match(CLASSTOKEN)) {
3178             SavePoint savePoint = createSavePoint();
3179             isFunctionOrClassDeclaration = true;
3180             next();
3181
3182             // ES6 Generators
3183             if (startsWithFunction && match(TIMES))
3184                 next();
3185             if (match(IDENT))
3186                 localName = m_token.m_data.ident;
3187             restoreSavePoint(savePoint);