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