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