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