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