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