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