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