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