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