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