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