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