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