parseClass should popScope after pushScope
[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     failIfFalse(popScope(classScope, TreeBuilder::NeedsFreeVariableInfo), "Parser error");
1556     consumeOrFail(CLOSEBRACE, "Expected a closing '}' after a class body");
1557
1558     return context.createClassExpr(location, *className, constructor, parentClass, instanceMethods, staticMethods);
1559 }
1560 #endif
1561
1562 struct LabelInfo {
1563     LabelInfo(const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end)
1564     : m_ident(ident)
1565     , m_start(start)
1566     , m_end(end)
1567     {
1568     }
1569     
1570     const Identifier* m_ident;
1571     JSTextPosition m_start;
1572     JSTextPosition m_end;
1573 };
1574
1575 template <typename LexerType>
1576 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrLabelStatement(TreeBuilder& context)
1577 {
1578     
1579     /* Expression and Label statements are ambiguous at LL(1), so we have a
1580      * special case that looks for a colon as the next character in the input.
1581      */
1582     Vector<LabelInfo> labels;
1583     JSTokenLocation location;
1584     do {
1585         JSTextPosition start = tokenStartPosition();
1586         location = tokenLocation();
1587         if (!nextTokenIsColon()) {
1588             // If we hit this path we're making a expression statement, which
1589             // by definition can't make use of continue/break so we can just
1590             // ignore any labels we might have accumulated.
1591             TreeExpression expression = parseExpression(context);
1592             failIfFalse(expression, "Cannot parse expression statement");
1593             if (!autoSemiColon())
1594                 failDueToUnexpectedToken();
1595             return context.createExprStatement(location, expression, start, m_lastTokenEndPosition.line);
1596         }
1597         const Identifier* ident = m_token.m_data.ident;
1598         JSTextPosition end = tokenEndPosition();
1599         next();
1600         consumeOrFail(COLON, "Labels must be followed by a ':'");
1601         if (!m_syntaxAlreadyValidated) {
1602             // This is O(N^2) over the current list of consecutive labels, but I
1603             // have never seen more than one label in a row in the real world.
1604             for (size_t i = 0; i < labels.size(); i++)
1605                 failIfTrue(ident->impl() == labels[i].m_ident->impl(), "Attempted to redeclare the label '", ident->impl(), "'");
1606             failIfTrue(getLabel(ident), "Cannot find scope for the label '", ident->impl(), "'");
1607             labels.append(LabelInfo(ident, start, end));
1608         }
1609     } while (match(IDENT));
1610     bool isLoop = false;
1611     switch (m_token.m_type) {
1612     case FOR:
1613     case WHILE:
1614     case DO:
1615         isLoop = true;
1616         break;
1617         
1618     default:
1619         break;
1620     }
1621     const Identifier* unused = 0;
1622     if (!m_syntaxAlreadyValidated) {
1623         for (size_t i = 0; i < labels.size(); i++)
1624             pushLabel(labels[i].m_ident, isLoop);
1625     }
1626     TreeStatement statement = parseStatement(context, unused);
1627     if (!m_syntaxAlreadyValidated) {
1628         for (size_t i = 0; i < labels.size(); i++)
1629             popLabel();
1630     }
1631     failIfFalse(statement, "Cannot parse statement");
1632     for (size_t i = 0; i < labels.size(); i++) {
1633         const LabelInfo& info = labels[labels.size() - i - 1];
1634         statement = context.createLabelStatement(location, info.m_ident, statement, info.m_start, info.m_end);
1635     }
1636     return statement;
1637 }
1638
1639 template <typename LexerType>
1640 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionStatement(TreeBuilder& context)
1641 {
1642     JSTextPosition start = tokenStartPosition();
1643     JSTokenLocation location(tokenLocation());
1644     TreeExpression expression = parseExpression(context);
1645     failIfFalse(expression, "Cannot parse expression statement");
1646     failIfFalse(autoSemiColon(), "Parse error");
1647     return context.createExprStatement(location, expression, start, m_lastTokenEndPosition.line);
1648 }
1649
1650 template <typename LexerType>
1651 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(TreeBuilder& context)
1652 {
1653     ASSERT(match(IF));
1654     JSTokenLocation ifLocation(tokenLocation());
1655     int start = tokenLine();
1656     next();
1657     handleProductionOrFail(OPENPAREN, "(", "start", "'if' condition");
1658
1659     TreeExpression condition = parseExpression(context);
1660     failIfFalse(condition, "Expected a expression as the condition for an if statement");
1661     int end = tokenLine();
1662     handleProductionOrFail(CLOSEPAREN, ")", "end", "'if' condition");
1663
1664     const Identifier* unused = 0;
1665     TreeStatement trueBlock = parseStatement(context, unused);
1666     failIfFalse(trueBlock, "Expected a statement as the body of an if block");
1667
1668     if (!match(ELSE))
1669         return context.createIfStatement(ifLocation, condition, trueBlock, 0, start, end);
1670
1671     Vector<TreeExpression> exprStack;
1672     Vector<std::pair<int, int>> posStack;
1673     Vector<JSTokenLocation> tokenLocationStack;
1674     Vector<TreeStatement> statementStack;
1675     bool trailingElse = false;
1676     do {
1677         JSTokenLocation tempLocation = tokenLocation();
1678         next();
1679         if (!match(IF)) {
1680             const Identifier* unused = 0;
1681             TreeStatement block = parseStatement(context, unused);
1682             failIfFalse(block, "Expected a statement as the body of an else block");
1683             statementStack.append(block);
1684             trailingElse = true;
1685             break;
1686         }
1687         int innerStart = tokenLine();
1688         next();
1689         
1690         handleProductionOrFail(OPENPAREN, "(", "start", "'if' condition");
1691
1692         TreeExpression innerCondition = parseExpression(context);
1693         failIfFalse(innerCondition, "Expected a expression as the condition for an if statement");
1694         int innerEnd = tokenLine();
1695         handleProductionOrFail(CLOSEPAREN, ")", "end", "'if' condition");
1696         const Identifier* unused = 0;
1697         TreeStatement innerTrueBlock = parseStatement(context, unused);
1698         failIfFalse(innerTrueBlock, "Expected a statement as the body of an if block");
1699         tokenLocationStack.append(tempLocation);
1700         exprStack.append(innerCondition);
1701         posStack.append(std::make_pair(innerStart, innerEnd));
1702         statementStack.append(innerTrueBlock);
1703     } while (match(ELSE));
1704
1705     if (!trailingElse) {
1706         TreeExpression condition = exprStack.last();
1707         exprStack.removeLast();
1708         TreeStatement trueBlock = statementStack.last();
1709         statementStack.removeLast();
1710         std::pair<int, int> pos = posStack.last();
1711         posStack.removeLast();
1712         JSTokenLocation elseLocation = tokenLocationStack.last();
1713         tokenLocationStack.removeLast();
1714         TreeStatement ifStatement = context.createIfStatement(elseLocation, condition, trueBlock, 0, pos.first, pos.second);
1715         context.setEndOffset(ifStatement, context.endOffset(trueBlock));
1716         statementStack.append(ifStatement);
1717     }
1718
1719     while (!exprStack.isEmpty()) {
1720         TreeExpression condition = exprStack.last();
1721         exprStack.removeLast();
1722         TreeStatement falseBlock = statementStack.last();
1723         statementStack.removeLast();
1724         TreeStatement trueBlock = statementStack.last();
1725         statementStack.removeLast();
1726         std::pair<int, int> pos = posStack.last();
1727         posStack.removeLast();
1728         JSTokenLocation elseLocation = tokenLocationStack.last();
1729         tokenLocationStack.removeLast();
1730         TreeStatement ifStatement = context.createIfStatement(elseLocation, condition, trueBlock, falseBlock, pos.first, pos.second);
1731         context.setEndOffset(ifStatement, context.endOffset(falseBlock));
1732         statementStack.append(ifStatement);
1733     }
1734
1735     return context.createIfStatement(ifLocation, condition, trueBlock, statementStack.last(), start, end);
1736 }
1737
1738 template <typename LexerType>
1739 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseExpression(TreeBuilder& context)
1740 {
1741     failIfStackOverflow();
1742     JSTokenLocation location(tokenLocation());
1743     TreeExpression node = parseAssignmentExpression(context);
1744     failIfFalse(node, "Cannot parse expression");
1745     context.setEndOffset(node, m_lastTokenEndPosition.offset);
1746     if (!match(COMMA))
1747         return node;
1748     next();
1749     m_nonTrivialExpressionCount++;
1750     m_nonLHSCount++;
1751     TreeExpression right = parseAssignmentExpression(context);
1752     failIfFalse(right, "Cannot parse expression in a comma expression");
1753     context.setEndOffset(right, m_lastTokenEndPosition.offset);
1754     typename TreeBuilder::Comma head = context.createCommaExpr(location, node);
1755     typename TreeBuilder::Comma tail = context.appendToCommaExpr(location, head, head, right);
1756     while (match(COMMA)) {
1757         next(TreeBuilder::DontBuildStrings);
1758         right = parseAssignmentExpression(context);
1759         failIfFalse(right, "Cannot parse expression in a comma expression");
1760         context.setEndOffset(right, m_lastTokenEndPosition.offset);
1761         tail = context.appendToCommaExpr(location, head, tail, right);
1762     }
1763     context.setEndOffset(head, m_lastTokenEndPosition.offset);
1764     return head;
1765 }
1766
1767 template <typename LexerType>
1768 template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmentExpression(TreeBuilder& context)
1769 {
1770     failIfStackOverflow();
1771     JSTextPosition start = tokenStartPosition();
1772     JSTokenLocation location(tokenLocation());
1773     int initialAssignmentCount = m_assignmentCount;
1774     int initialNonLHSCount = m_nonLHSCount;
1775     if (match(OPENBRACE) || match(OPENBRACKET)) {
1776         SavePoint savePoint = createSavePoint();
1777         auto pattern = tryParseDeconstructionPatternExpression(context);
1778         if (pattern && consume(EQUAL)) {
1779             auto rhs = parseAssignmentExpression(context);
1780             if (rhs)
1781                 return context.createDeconstructingAssignment(location, pattern, rhs);
1782         }
1783         restoreSavePoint(savePoint);
1784     }
1785     TreeExpression lhs = parseConditionalExpression(context);
1786     failIfFalse(lhs, "Cannot parse expression");
1787     if (initialNonLHSCount != m_nonLHSCount) {
1788         if (m_token.m_type >= EQUAL && m_token.m_type <= OREQUAL)
1789             semanticFail("Left hand side of operator '", getToken(), "' must be a reference");
1790
1791         return lhs;
1792     }
1793     
1794     int assignmentStack = 0;
1795     Operator op;
1796     bool hadAssignment = false;
1797     while (true) {
1798         switch (m_token.m_type) {
1799         case EQUAL: op = OpEqual; break;
1800         case PLUSEQUAL: op = OpPlusEq; break;
1801         case MINUSEQUAL: op = OpMinusEq; break;
1802         case MULTEQUAL: op = OpMultEq; break;
1803         case DIVEQUAL: op = OpDivEq; break;
1804         case LSHIFTEQUAL: op = OpLShift; break;
1805         case RSHIFTEQUAL: op = OpRShift; break;
1806         case URSHIFTEQUAL: op = OpURShift; break;
1807         case ANDEQUAL: op = OpAndEq; break;
1808         case XOREQUAL: op = OpXOrEq; break;
1809         case OREQUAL: op = OpOrEq; break;
1810         case MODEQUAL: op = OpModEq; break;
1811         default:
1812             goto end;
1813         }
1814         m_nonTrivialExpressionCount++;
1815         hadAssignment = true;
1816         context.assignmentStackAppend(assignmentStack, lhs, start, tokenStartPosition(), m_assignmentCount, op);
1817         start = tokenStartPosition();
1818         m_assignmentCount++;
1819         next(TreeBuilder::DontBuildStrings);
1820         if (strictMode() && m_lastIdentifier && context.isResolve(lhs)) {
1821             failIfTrueIfStrict(m_vm->propertyNames->eval == *m_lastIdentifier, "Cannot modify 'eval' in strict mode");
1822             failIfTrueIfStrict(m_vm->propertyNames->arguments == *m_lastIdentifier, "Cannot modify 'arguments' in strict mode");
1823             declareWrite(m_lastIdentifier);
1824             m_lastIdentifier = 0;
1825         }
1826         lhs = parseAssignmentExpression(context);
1827         failIfFalse(lhs, "Cannot parse the right hand side of an assignment expression");
1828         if (initialNonLHSCount != m_nonLHSCount) {
1829             if (m_token.m_type >= EQUAL && m_token.m_type <= OREQUAL)
1830                 semanticFail("Left hand side of operator '", getToken(), "' must be a reference");
1831             break;
1832         }
1833     }
1834 end:
1835     if (hadAssignment)
1836         m_nonLHSCount++;
1837     
1838     if (!TreeBuilder::CreatesAST)
1839         return lhs;
1840     
1841     while (assignmentStack)
1842         lhs = context.createAssignment(location, assignmentStack, lhs, initialAssignmentCount, m_assignmentCount, lastTokenEndPosition());
1843     
1844     return lhs;
1845 }
1846
1847 template <typename LexerType>
1848 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseConditionalExpression(TreeBuilder& context)
1849 {
1850     JSTokenLocation location(tokenLocation());
1851     TreeExpression cond = parseBinaryExpression(context);
1852     failIfFalse(cond, "Cannot parse expression");
1853     if (!match(QUESTION))
1854         return cond;
1855     m_nonTrivialExpressionCount++;
1856     m_nonLHSCount++;
1857     next(TreeBuilder::DontBuildStrings);
1858     TreeExpression lhs = parseAssignmentExpression(context);
1859     failIfFalse(lhs, "Cannot parse left hand side of ternary operator");
1860     context.setEndOffset(lhs, m_lastTokenEndPosition.offset);
1861     consumeOrFailWithFlags(COLON, TreeBuilder::DontBuildStrings, "Expected ':' in ternary operator");
1862     
1863     TreeExpression rhs = parseAssignmentExpression(context);
1864     failIfFalse(rhs, "Cannot parse right hand side of ternary operator");
1865     context.setEndOffset(rhs, m_lastTokenEndPosition.offset);
1866     return context.createConditionalExpr(location, cond, lhs, rhs);
1867 }
1868
1869 ALWAYS_INLINE static bool isUnaryOp(JSTokenType token)
1870 {
1871     return token & UnaryOpTokenFlag;
1872 }
1873
1874 template <typename LexerType>
1875 int Parser<LexerType>::isBinaryOperator(JSTokenType token)
1876 {
1877     if (m_allowsIn)
1878         return token & (BinaryOpTokenPrecedenceMask << BinaryOpTokenAllowsInPrecedenceAdditionalShift);
1879     return token & BinaryOpTokenPrecedenceMask;
1880 }
1881
1882 template <typename LexerType>
1883 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseBinaryExpression(TreeBuilder& context)
1884 {
1885     int operandStackDepth = 0;
1886     int operatorStackDepth = 0;
1887     typename TreeBuilder::BinaryExprContext binaryExprContext(context);
1888     JSTokenLocation location(tokenLocation());
1889     while (true) {
1890         JSTextPosition exprStart = tokenStartPosition();
1891         int initialAssignments = m_assignmentCount;
1892         TreeExpression current = parseUnaryExpression(context);
1893         failIfFalse(current, "Cannot parse expression");
1894         
1895         context.appendBinaryExpressionInfo(operandStackDepth, current, exprStart, lastTokenEndPosition(), lastTokenEndPosition(), initialAssignments != m_assignmentCount);
1896         int precedence = isBinaryOperator(m_token.m_type);
1897         if (!precedence)
1898             break;
1899         m_nonTrivialExpressionCount++;
1900         m_nonLHSCount++;
1901         int operatorToken = m_token.m_type;
1902         next(TreeBuilder::DontBuildStrings);
1903         
1904         while (operatorStackDepth &&  context.operatorStackHasHigherPrecedence(operatorStackDepth, precedence)) {
1905             ASSERT(operandStackDepth > 1);
1906             
1907             typename TreeBuilder::BinaryOperand rhs = context.getFromOperandStack(-1);
1908             typename TreeBuilder::BinaryOperand lhs = context.getFromOperandStack(-2);
1909             context.shrinkOperandStackBy(operandStackDepth, 2);
1910             context.appendBinaryOperation(location, operandStackDepth, operatorStackDepth, lhs, rhs);
1911             context.operatorStackPop(operatorStackDepth);
1912         }
1913         context.operatorStackAppend(operatorStackDepth, operatorToken, precedence);
1914     }
1915     while (operatorStackDepth) {
1916         ASSERT(operandStackDepth > 1);
1917         
1918         typename TreeBuilder::BinaryOperand rhs = context.getFromOperandStack(-1);
1919         typename TreeBuilder::BinaryOperand lhs = context.getFromOperandStack(-2);
1920         context.shrinkOperandStackBy(operandStackDepth, 2);
1921         context.appendBinaryOperation(location, operandStackDepth, operatorStackDepth, lhs, rhs);
1922         context.operatorStackPop(operatorStackDepth);
1923     }
1924     return context.popOperandStack(operandStackDepth);
1925 }
1926
1927 template <typename LexerType>
1928 template <class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeBuilder& context, bool complete)
1929 {
1930     bool wasIdent = false;
1931     switch (m_token.m_type) {
1932     namedProperty:
1933     case IDENT:
1934         wasIdent = true;
1935         FALLTHROUGH;
1936     case STRING: {
1937         const Identifier* ident = m_token.m_data.ident;
1938         unsigned getterOrSetterStartOffset = tokenStart();
1939         if (complete || (wasIdent && (*ident == m_vm->propertyNames->get || *ident == m_vm->propertyNames->set)))
1940             nextExpectIdentifier(LexerFlagsIgnoreReservedWords);
1941         else
1942             nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
1943
1944         if (match(COLON)) {
1945             next();
1946             TreeExpression node = parseAssignmentExpression(context);
1947             failIfFalse(node, "Cannot parse expression for property declaration");
1948             context.setEndOffset(node, m_lexer->currentOffset());
1949             return context.createProperty(ident, node, PropertyNode::Constant, PropertyNode::Unknown, complete);
1950         }
1951
1952         if (match(OPENPAREN)) {
1953             auto method = parsePropertyMethod(context, ident);
1954             propagateError();
1955             return context.createProperty(ident, method, PropertyNode::Constant, PropertyNode::KnownDirect, complete);
1956         }
1957
1958         failIfFalse(wasIdent, "Expected an identifier as property name");
1959
1960         if (match(COMMA) || match(CLOSEBRACE)) {
1961             JSTextPosition start = tokenStartPosition();
1962             JSTokenLocation location(tokenLocation());
1963             currentScope()->useVariable(ident, m_vm->propertyNames->eval == *ident);
1964             TreeExpression node = context.createResolve(location, ident, start);
1965             return context.createProperty(ident, node, PropertyNode::Constant, PropertyNode::KnownDirect, complete);
1966         }
1967
1968         PropertyNode::Type type;
1969         if (*ident == m_vm->propertyNames->get)
1970             type = PropertyNode::Getter;
1971         else if (*ident == m_vm->propertyNames->set)
1972             type = PropertyNode::Setter;
1973         else
1974             failWithMessage("Expected a ':' following the property name '", ident->impl(), "'");
1975         return parseGetterSetter(context, complete, type, getterOrSetterStartOffset);
1976     }
1977     case DOUBLE:
1978     case INTEGER: {
1979         double propertyName = m_token.m_data.doubleValue;
1980         next();
1981
1982         if (match(OPENPAREN)) {
1983             const Identifier& ident = m_parserArena.identifierArena().makeNumericIdentifier(const_cast<VM*>(m_vm), propertyName);
1984             auto method = parsePropertyMethod(context, &ident);
1985             propagateError();
1986             return context.createProperty(&ident, method, PropertyNode::Constant, PropertyNode::Unknown, complete);
1987         }
1988
1989         consumeOrFail(COLON, "Expected ':' after property name");
1990         TreeExpression node = parseAssignmentExpression(context);
1991         failIfFalse(node, "Cannot parse expression for property declaration");
1992         context.setEndOffset(node, m_lexer->currentOffset());
1993         return context.createProperty(const_cast<VM*>(m_vm), m_parserArena, propertyName, node, PropertyNode::Constant, PropertyNode::Unknown, complete);
1994     }
1995     case OPENBRACKET: {
1996         next();
1997         auto propertyName = parseExpression(context);
1998         failIfFalse(propertyName, "Cannot parse computed property name");
1999         handleProductionOrFail(CLOSEBRACKET, "]", "end", "computed property name");
2000
2001         if (match(OPENPAREN)) {
2002             auto method = parsePropertyMethod(context, &m_vm->propertyNames->nullIdentifier);
2003             propagateError();
2004             return context.createProperty(propertyName, method, PropertyNode::Constant, PropertyNode::KnownDirect, complete);
2005         }
2006
2007         consumeOrFail(COLON, "Expected ':' after property name");
2008         TreeExpression node = parseAssignmentExpression(context);
2009         failIfFalse(node, "Cannot parse expression for property declaration");
2010         context.setEndOffset(node, m_lexer->currentOffset());
2011         return context.createProperty(propertyName, node, PropertyNode::Constant, PropertyNode::Unknown, complete);
2012     }
2013     default:
2014         failIfFalse(m_token.m_type & KeywordTokenFlag, "Expected a property name");
2015         goto namedProperty;
2016     }
2017 }
2018
2019 template <typename LexerType>
2020 template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePropertyMethod(TreeBuilder& context, const Identifier* methodName)
2021 {
2022     JSTokenLocation methodLocation(tokenLocation());
2023     unsigned methodStart = tokenStart();
2024     ParserFunctionInfo<TreeBuilder> methodInfo;
2025     failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, MethodMode, false, ConstructorKind::None, methodInfo)), "Cannot parse this method");
2026     methodInfo.name = methodName;
2027     return context.createFunctionExpr(methodLocation, methodInfo, methodStart);
2028 }
2029
2030 template <typename LexerType>
2031 template <class TreeBuilder> TreeProperty Parser<LexerType>::parseGetterSetter(TreeBuilder& context, bool strict, PropertyNode::Type type, unsigned getterOrSetterStartOffset,
2032     ConstructorKind constructorKind, SuperBinding superBinding)
2033 {
2034     const Identifier* stringPropertyName = 0;
2035     double numericPropertyName = 0;
2036     if (m_token.m_type == IDENT || m_token.m_type == STRING)
2037         stringPropertyName = m_token.m_data.ident;
2038     else if (m_token.m_type == DOUBLE || m_token.m_type == INTEGER)
2039         numericPropertyName = m_token.m_data.doubleValue;
2040     else
2041         failDueToUnexpectedToken();
2042     JSTokenLocation location(tokenLocation());
2043     next();
2044     ParserFunctionInfo<TreeBuilder> info;
2045     if (type == PropertyNode::Getter) {
2046         failIfFalse(match(OPENPAREN), "Expected a parameter list for getter definition");
2047         failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, GetterMode, false, constructorKind, info)), "Cannot parse getter definition");
2048     } else {
2049         failIfFalse(match(OPENPAREN), "Expected a parameter list for setter definition");
2050         failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, SetterMode, false, constructorKind, info)), "Cannot parse setter definition");
2051     }
2052     if (stringPropertyName)
2053         return context.createGetterOrSetterProperty(location, type, strict, stringPropertyName, info, getterOrSetterStartOffset, superBinding);
2054     return context.createGetterOrSetterProperty(const_cast<VM*>(m_vm), m_parserArena, location, type, strict, numericPropertyName, info, getterOrSetterStartOffset, superBinding);
2055 }
2056
2057 template <typename LexerType>
2058 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseObjectLiteral(TreeBuilder& context)
2059 {
2060     auto savePoint = createSavePoint();
2061     consumeOrFailWithFlags(OPENBRACE, TreeBuilder::DontBuildStrings, "Expected opening '{' at the start of an object literal");
2062     JSTokenLocation location(tokenLocation());
2063
2064     int oldNonLHSCount = m_nonLHSCount;
2065     
2066     if (match(CLOSEBRACE)) {
2067         next();
2068         return context.createObjectLiteral(location);
2069     }
2070     
2071     TreeProperty property = parseProperty(context, false);
2072     failIfFalse(property, "Cannot parse object literal property");
2073     if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) {
2074         restoreSavePoint(savePoint);
2075         return parseStrictObjectLiteral(context);
2076     }
2077     TreePropertyList propertyList = context.createPropertyList(location, property);
2078     TreePropertyList tail = propertyList;
2079     while (match(COMMA)) {
2080         next(TreeBuilder::DontBuildStrings);
2081         // allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939
2082         if (match(CLOSEBRACE))
2083             break;
2084         JSTokenLocation propertyLocation(tokenLocation());
2085         property = parseProperty(context, false);
2086         failIfFalse(property, "Cannot parse object literal property");
2087         if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) {
2088             restoreSavePoint(savePoint);
2089             return parseStrictObjectLiteral(context);
2090         }
2091         tail = context.createPropertyList(propertyLocation, property, tail);
2092     }
2093
2094     location = tokenLocation();
2095     handleProductionOrFail(CLOSEBRACE, "}", "end", "object literal");
2096     
2097     m_nonLHSCount = oldNonLHSCount;
2098     
2099     return context.createObjectLiteral(location, propertyList);
2100 }
2101
2102 template <typename LexerType>
2103 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseStrictObjectLiteral(TreeBuilder& context)
2104 {
2105     consumeOrFail(OPENBRACE, "Expected opening '{' at the start of an object literal");
2106     
2107     int oldNonLHSCount = m_nonLHSCount;
2108
2109     JSTokenLocation location(tokenLocation());
2110     if (match(CLOSEBRACE)) {
2111         next();
2112         return context.createObjectLiteral(location);
2113     }
2114     
2115     TreeProperty property = parseProperty(context, true);
2116     failIfFalse(property, "Cannot parse object literal property");
2117     
2118     typedef HashMap<RefPtr<StringImpl>, unsigned, IdentifierRepHash> ObjectValidationMap;
2119     ObjectValidationMap objectValidator;
2120     // Add the first property
2121     if (!m_syntaxAlreadyValidated && context.getName(property))
2122         objectValidator.add(context.getName(property)->impl(), context.getType(property));
2123     
2124     TreePropertyList propertyList = context.createPropertyList(location, property);
2125     TreePropertyList tail = propertyList;
2126     while (match(COMMA)) {
2127         next();
2128         // allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939
2129         if (match(CLOSEBRACE))
2130             break;
2131         JSTokenLocation propertyLocation(tokenLocation());
2132         property = parseProperty(context, true);
2133         failIfFalse(property, "Cannot parse object literal property");
2134         if (!m_syntaxAlreadyValidated && context.getName(property)) {
2135             ObjectValidationMap::AddResult propertyEntry = objectValidator.add(context.getName(property)->impl(), context.getType(property));
2136             if (!propertyEntry.isNewEntry) {
2137                 semanticFailIfTrue(propertyEntry.iterator->value == PropertyNode::Constant, "Attempted to redefine property '", propertyEntry.iterator->key.get(), "'");
2138                 semanticFailIfTrue(context.getType(property) == PropertyNode::Constant, "Attempted to redefine property '", propertyEntry.iterator->key.get(), "'");
2139                 semanticFailIfTrue(context.getType(property) & propertyEntry.iterator->value, "Attempted to redefine property '", propertyEntry.iterator->key.get(), "'");
2140                 propertyEntry.iterator->value |= context.getType(property);
2141             }
2142         }
2143         tail = context.createPropertyList(propertyLocation, property, tail);
2144     }
2145
2146     location = tokenLocation();
2147     handleProductionOrFail(CLOSEBRACE, "}", "end", "object literal");
2148
2149     m_nonLHSCount = oldNonLHSCount;
2150
2151     return context.createObjectLiteral(location, propertyList);
2152 }
2153
2154 template <typename LexerType>
2155 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrayLiteral(TreeBuilder& context)
2156 {
2157     consumeOrFailWithFlags(OPENBRACKET, TreeBuilder::DontBuildStrings, "Expected an opening '[' at the beginning of an array literal");
2158     
2159     int oldNonLHSCount = m_nonLHSCount;
2160     
2161     int elisions = 0;
2162     while (match(COMMA)) {
2163         next(TreeBuilder::DontBuildStrings);
2164         elisions++;
2165     }
2166     if (match(CLOSEBRACKET)) {
2167         JSTokenLocation location(tokenLocation());
2168         next(TreeBuilder::DontBuildStrings);
2169         return context.createArray(location, elisions);
2170     }
2171     
2172     TreeExpression elem;
2173     if (UNLIKELY(match(DOTDOTDOT))) {
2174         auto spreadLocation = m_token.m_location;
2175         auto start = m_token.m_startPosition;
2176         auto divot = m_token.m_endPosition;
2177         next();
2178         auto spreadExpr = parseAssignmentExpression(context);
2179         failIfFalse(spreadExpr, "Cannot parse subject of a spread operation");
2180         elem = context.createSpreadExpression(spreadLocation, spreadExpr, start, divot, m_lastTokenEndPosition);
2181     } else
2182         elem = parseAssignmentExpression(context);
2183     failIfFalse(elem, "Cannot parse array literal element");
2184     typename TreeBuilder::ElementList elementList = context.createElementList(elisions, elem);
2185     typename TreeBuilder::ElementList tail = elementList;
2186     elisions = 0;
2187     while (match(COMMA)) {
2188         next(TreeBuilder::DontBuildStrings);
2189         elisions = 0;
2190         
2191         while (match(COMMA)) {
2192             next();
2193             elisions++;
2194         }
2195         
2196         if (match(CLOSEBRACKET)) {
2197             JSTokenLocation location(tokenLocation());
2198             next(TreeBuilder::DontBuildStrings);
2199             return context.createArray(location, elisions, elementList);
2200         }
2201         if (UNLIKELY(match(DOTDOTDOT))) {
2202             auto spreadLocation = m_token.m_location;
2203             auto start = m_token.m_startPosition;
2204             auto divot = m_token.m_endPosition;
2205             next();
2206             TreeExpression elem = parseAssignmentExpression(context);
2207             failIfFalse(elem, "Cannot parse subject of a spread operation");
2208             auto spread = context.createSpreadExpression(spreadLocation, elem, start, divot, m_lastTokenEndPosition);
2209             tail = context.createElementList(tail, elisions, spread);
2210             continue;
2211         }
2212         TreeExpression elem = parseAssignmentExpression(context);
2213         failIfFalse(elem, "Cannot parse array literal element");
2214         tail = context.createElementList(tail, elisions, elem);
2215     }
2216
2217     JSTokenLocation location(tokenLocation());
2218     if (!consume(CLOSEBRACKET)) {
2219         failIfFalse(match(DOTDOTDOT), "Expected either a closing ']' or a ',' following an array element");
2220         semanticFail("The '...' operator should come before a target expression");
2221     }
2222     
2223     m_nonLHSCount = oldNonLHSCount;
2224     
2225     return context.createArray(location, elementList);
2226 }
2227
2228 template <typename LexerType>
2229 template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpression(TreeBuilder& context)
2230 {
2231     failIfStackOverflow();
2232     switch (m_token.m_type) {
2233     case FUNCTION: {
2234         JSTokenLocation location(tokenLocation());
2235         unsigned functionKeywordStart = tokenStart();
2236         next();
2237         ParserFunctionInfo<TreeBuilder> info;
2238         info.name = &m_vm->propertyNames->nullIdentifier;
2239         failIfFalse((parseFunctionInfo(context, FunctionNoRequirements, FunctionMode, false, ConstructorKind::None, info)), "Cannot parse function expression");
2240         return context.createFunctionExpr(location, info, functionKeywordStart);
2241     }
2242 #if ENABLE(ES6_CLASS_SYNTAX)
2243     case CLASSTOKEN:
2244         return parseClass(context, FunctionNoRequirements);
2245 #endif
2246     case OPENBRACE:
2247         if (strictMode())
2248             return parseStrictObjectLiteral(context);
2249         return parseObjectLiteral(context);
2250     case OPENBRACKET:
2251         return parseArrayLiteral(context);
2252     case OPENPAREN: {
2253         next();
2254         int oldNonLHSCount = m_nonLHSCount;
2255         TreeExpression result = parseExpression(context);
2256         m_nonLHSCount = oldNonLHSCount;
2257         handleProductionOrFail(CLOSEPAREN, ")", "end", "compound expression");
2258         return result;
2259     }
2260     case THISTOKEN: {
2261         JSTokenLocation location(tokenLocation());
2262         next();
2263         return context.thisExpr(location);
2264     }
2265     case IDENT: {
2266         JSTextPosition start = tokenStartPosition();
2267         const Identifier* ident = m_token.m_data.ident;
2268         JSTokenLocation location(tokenLocation());
2269         next();
2270         currentScope()->useVariable(ident, m_vm->propertyNames->eval == *ident);
2271         m_lastIdentifier = ident;
2272         return context.createResolve(location, ident, start);
2273     }
2274     case STRING: {
2275         const Identifier* ident = m_token.m_data.ident;
2276         JSTokenLocation location(tokenLocation());
2277         next();
2278         return context.createString(location, ident);
2279     }
2280     case DOUBLE: {
2281         double d = m_token.m_data.doubleValue;
2282         JSTokenLocation location(tokenLocation());
2283         next();
2284         return context.createDoubleExpr(location, d);
2285     }
2286     case INTEGER: {
2287         double d = m_token.m_data.doubleValue;
2288         JSTokenLocation location(tokenLocation());
2289         next();
2290         return context.createIntegerExpr(location, d);
2291     }
2292     case NULLTOKEN: {
2293         JSTokenLocation location(tokenLocation());
2294         next();
2295         return context.createNull(location);
2296     }
2297     case TRUETOKEN: {
2298         JSTokenLocation location(tokenLocation());
2299         next();
2300         return context.createBoolean(location, true);
2301     }
2302     case FALSETOKEN: {
2303         JSTokenLocation location(tokenLocation());
2304         next();
2305         return context.createBoolean(location, false);
2306     }
2307     case DIVEQUAL:
2308     case DIVIDE: {
2309         /* regexp */
2310         const Identifier* pattern;
2311         const Identifier* flags;
2312         if (match(DIVEQUAL))
2313             failIfFalse(m_lexer->scanRegExp(pattern, flags, '='), "Invalid regular expression");
2314         else
2315             failIfFalse(m_lexer->scanRegExp(pattern, flags), "Invalid regular expression");
2316         
2317         JSTextPosition start = tokenStartPosition();
2318         JSTokenLocation location(tokenLocation());
2319         next();
2320         TreeExpression re = context.createRegExp(location, *pattern, *flags, start);
2321         if (!re) {
2322             const char* yarrErrorMsg = Yarr::checkSyntax(pattern->string());
2323             regexFail(yarrErrorMsg);
2324         }
2325         return re;
2326     }
2327     default:
2328         failDueToUnexpectedToken();
2329     }
2330 }
2331
2332 template <typename LexerType>
2333 template <class TreeBuilder> TreeArguments Parser<LexerType>::parseArguments(TreeBuilder& context, SpreadMode mode)
2334 {
2335     consumeOrFailWithFlags(OPENPAREN, TreeBuilder::DontBuildStrings, "Expected opening '(' at start of argument list");
2336     JSTokenLocation location(tokenLocation());
2337     if (match(CLOSEPAREN)) {
2338         next(TreeBuilder::DontBuildStrings);
2339         return context.createArguments();
2340     }
2341     if (match(DOTDOTDOT) && mode == AllowSpread) {
2342         JSTokenLocation spreadLocation(tokenLocation());
2343         auto start = m_token.m_startPosition;
2344         auto divot = m_token.m_endPosition;
2345         next();
2346         auto spreadExpr = parseAssignmentExpression(context);
2347         auto end = m_lastTokenEndPosition;
2348         if (!spreadExpr)
2349             failWithMessage("Cannot parse spread expression");
2350         if (!consume(CLOSEPAREN)) {
2351             if (match(COMMA))
2352                 semanticFail("Spread operator may only be applied to the last argument passed to a function");
2353             handleProductionOrFail(CLOSEPAREN, ")", "end", "argument list");
2354         }
2355         auto spread = context.createSpreadExpression(spreadLocation, spreadExpr, start, divot, end);
2356         TreeArgumentsList argList = context.createArgumentsList(location, spread);
2357         return context.createArguments(argList);
2358     }
2359     TreeExpression firstArg = parseAssignmentExpression(context);
2360     failIfFalse(firstArg, "Cannot parse function argument");
2361     
2362     TreeArgumentsList argList = context.createArgumentsList(location, firstArg);
2363     TreeArgumentsList tail = argList;
2364     while (match(COMMA)) {
2365         JSTokenLocation argumentLocation(tokenLocation());
2366         next(TreeBuilder::DontBuildStrings);
2367         TreeExpression arg = parseAssignmentExpression(context);
2368         failIfFalse(arg, "Cannot parse function argument");
2369         tail = context.createArgumentsList(argumentLocation, tail, arg);
2370     }
2371     semanticFailIfTrue(match(DOTDOTDOT), "The '...' operator should come before the target expression");
2372     handleProductionOrFail(CLOSEPAREN, ")", "end", "argument list");
2373     return context.createArguments(argList);
2374 }
2375
2376 template <typename LexerType>
2377 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpression(TreeBuilder& context)
2378 {
2379     TreeExpression base = 0;
2380     JSTextPosition expressionStart = tokenStartPosition();
2381     int newCount = 0;
2382     JSTokenLocation startLocation = tokenLocation();
2383     JSTokenLocation location;
2384     while (match(NEW)) {
2385         next();
2386         newCount++;
2387     }
2388
2389 #if ENABLE(ES6_CLASS_SYNTAX)
2390     bool baseIsSuper = match(SUPER);
2391 #else
2392     bool baseIsSuper = false;
2393 #endif
2394
2395     if (baseIsSuper) {
2396         base = context.superExpr(location);
2397         next();
2398         currentScope()->setNeedsSuperBinding();
2399     } else
2400         base = parsePrimaryExpression(context);
2401
2402     failIfFalse(base, "Cannot parse base expression");
2403     while (true) {
2404         location = tokenLocation();
2405         switch (m_token.m_type) {
2406         case OPENBRACKET: {
2407             m_nonTrivialExpressionCount++;
2408             JSTextPosition expressionEnd = lastTokenEndPosition();
2409             next();
2410             int nonLHSCount = m_nonLHSCount;
2411             int initialAssignments = m_assignmentCount;
2412             TreeExpression property = parseExpression(context);
2413             failIfFalse(property, "Cannot parse subscript expression");
2414             base = context.createBracketAccess(location, base, property, initialAssignments != m_assignmentCount, expressionStart, expressionEnd, tokenEndPosition());
2415             handleProductionOrFail(CLOSEBRACKET, "]", "end", "subscript expression");
2416             m_nonLHSCount = nonLHSCount;
2417             break;
2418         }
2419         case OPENPAREN: {
2420             m_nonTrivialExpressionCount++;
2421             int nonLHSCount = m_nonLHSCount;
2422             if (newCount) {
2423                 newCount--;
2424                 JSTextPosition expressionEnd = lastTokenEndPosition();
2425                 TreeArguments arguments = parseArguments(context, AllowSpread);
2426                 failIfFalse(arguments, "Cannot parse call arguments");
2427                 base = context.createNewExpr(location, base, arguments, expressionStart, expressionEnd, lastTokenEndPosition());
2428             } else {
2429                 JSTextPosition expressionEnd = lastTokenEndPosition();
2430                 TreeArguments arguments = parseArguments(context, AllowSpread);
2431                 failIfFalse(arguments, "Cannot parse call arguments");
2432                 if (baseIsSuper)
2433                     currentScope()->setHasDirectSuper();
2434                 base = context.makeFunctionCallNode(startLocation, base, arguments, expressionStart, expressionEnd, lastTokenEndPosition());
2435             }
2436             m_nonLHSCount = nonLHSCount;
2437             break;
2438         }
2439         case DOT: {
2440             m_nonTrivialExpressionCount++;
2441             JSTextPosition expressionEnd = lastTokenEndPosition();
2442             nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
2443             matchOrFail(IDENT, "Expected a property name after '.'");
2444             base = context.createDotAccess(location, base, m_token.m_data.ident, expressionStart, expressionEnd, tokenEndPosition());
2445             next();
2446             break;
2447         }
2448         default:
2449             goto endMemberExpression;
2450         }
2451         baseIsSuper = false;
2452     }
2453 endMemberExpression:
2454     semanticFailIfTrue(baseIsSuper && !newCount, "Cannot reference super");
2455     while (newCount--)
2456         base = context.createNewExpr(location, base, expressionStart, lastTokenEndPosition());
2457     return base;
2458 }
2459
2460 static const char* operatorString(bool prefix, unsigned tok)
2461 {
2462     switch (tok) {
2463     case MINUSMINUS:
2464     case AUTOMINUSMINUS:
2465         return prefix ? "prefix-decrement" : "decrement";
2466
2467     case PLUSPLUS:
2468     case AUTOPLUSPLUS:
2469         return prefix ? "prefix-increment" : "increment";
2470
2471     case EXCLAMATION:
2472         return "logical-not";
2473
2474     case TILDE:
2475         return "bitwise-not";
2476     
2477     case TYPEOF:
2478         return "typeof";
2479     
2480     case VOIDTOKEN:
2481         return "void";
2482     
2483     case DELETETOKEN:
2484         return "delete";
2485     }
2486     RELEASE_ASSERT_NOT_REACHED();
2487     return "error";
2488 }
2489
2490 template <typename LexerType>
2491 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpression(TreeBuilder& context)
2492 {
2493     typename TreeBuilder::UnaryExprContext unaryExprContext(context);
2494     AllowInOverride allowInOverride(this);
2495     int tokenStackDepth = 0;
2496     bool modifiesExpr = false;
2497     bool requiresLExpr = false;
2498     unsigned lastOperator = 0;
2499     while (isUnaryOp(m_token.m_type)) {
2500         if (strictMode()) {
2501             switch (m_token.m_type) {
2502             case PLUSPLUS:
2503             case MINUSMINUS:
2504             case AUTOPLUSPLUS:
2505             case AUTOMINUSMINUS:
2506                 semanticFailIfTrue(requiresLExpr, "The ", operatorString(true, lastOperator), " operator requires a reference expression");
2507                 modifiesExpr = true;
2508                 requiresLExpr = true;
2509                 break;
2510             case DELETETOKEN:
2511                 semanticFailIfTrue(requiresLExpr, "The ", operatorString(true, lastOperator), " operator requires a reference expression");
2512                 requiresLExpr = true;
2513                 break;
2514             default:
2515                 semanticFailIfTrue(requiresLExpr, "The ", operatorString(true, lastOperator), " operator requires a reference expression");
2516                 break;
2517             }
2518         }
2519         lastOperator = m_token.m_type;
2520         m_nonLHSCount++;
2521         context.appendUnaryToken(tokenStackDepth, m_token.m_type, tokenStartPosition());
2522         next();
2523         m_nonTrivialExpressionCount++;
2524     }
2525     JSTextPosition subExprStart = tokenStartPosition();
2526     ASSERT(subExprStart.offset >= subExprStart.lineStartOffset);
2527     JSTokenLocation location(tokenLocation());
2528     TreeExpression expr = parseMemberExpression(context);
2529     if (!expr) {
2530         if (lastOperator)
2531             failWithMessage("Cannot parse subexpression of ", operatorString(true, lastOperator), "operator");
2532         failWithMessage("Cannot parse member expression");
2533     }
2534     bool isEvalOrArguments = false;
2535     if (strictMode() && !m_syntaxAlreadyValidated) {
2536         if (context.isResolve(expr))
2537             isEvalOrArguments = *m_lastIdentifier == m_vm->propertyNames->eval || *m_lastIdentifier == m_vm->propertyNames->arguments;
2538     }
2539     failIfTrueIfStrict(isEvalOrArguments && modifiesExpr, "Cannot modify '", m_lastIdentifier->impl(), "' in strict mode");
2540     switch (m_token.m_type) {
2541     case PLUSPLUS:
2542         m_nonTrivialExpressionCount++;
2543         m_nonLHSCount++;
2544         expr = context.makePostfixNode(location, expr, OpPlusPlus, subExprStart, lastTokenEndPosition(), tokenEndPosition());
2545         m_assignmentCount++;
2546         failIfTrueIfStrict(isEvalOrArguments, "Cannot modify '", m_lastIdentifier->impl(), "' in strict mode");
2547         semanticFailIfTrue(requiresLExpr, "The ", operatorString(false, lastOperator), " operator requires a reference expression");
2548         lastOperator = PLUSPLUS;
2549         next();
2550         break;
2551     case MINUSMINUS:
2552         m_nonTrivialExpressionCount++;
2553         m_nonLHSCount++;
2554         expr = context.makePostfixNode(location, expr, OpMinusMinus, subExprStart, lastTokenEndPosition(), tokenEndPosition());
2555         m_assignmentCount++;
2556         failIfTrueIfStrict(isEvalOrArguments, "'", m_lastIdentifier->impl(), "' cannot be modified in strict mode");
2557         semanticFailIfTrue(requiresLExpr, "The ", operatorString(false, lastOperator), " operator requires a reference expression");
2558         lastOperator = PLUSPLUS;
2559         next();
2560         break;
2561     default:
2562         break;
2563     }
2564     
2565     JSTextPosition end = lastTokenEndPosition();
2566
2567     if (!TreeBuilder::CreatesAST && (m_syntaxAlreadyValidated || !strictMode()))
2568         return expr;
2569
2570     location = tokenLocation();
2571     location.line = m_lexer->lastLineNumber();
2572     while (tokenStackDepth) {
2573         switch (context.unaryTokenStackLastType(tokenStackDepth)) {
2574         case EXCLAMATION:
2575             expr = context.createLogicalNot(location, expr);
2576             break;
2577         case TILDE:
2578             expr = context.makeBitwiseNotNode(location, expr);
2579             break;
2580         case MINUS:
2581             expr = context.makeNegateNode(location, expr);
2582             break;
2583         case PLUS:
2584             expr = context.createUnaryPlus(location, expr);
2585             break;
2586         case PLUSPLUS:
2587         case AUTOPLUSPLUS:
2588             expr = context.makePrefixNode(location, expr, OpPlusPlus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
2589             m_assignmentCount++;
2590             break;
2591         case MINUSMINUS:
2592         case AUTOMINUSMINUS:
2593             expr = context.makePrefixNode(location, expr, OpMinusMinus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
2594             m_assignmentCount++;
2595             break;
2596         case TYPEOF:
2597             expr = context.makeTypeOfNode(location, expr);
2598             break;
2599         case VOIDTOKEN:
2600             expr = context.createVoid(location, expr);
2601             break;
2602         case DELETETOKEN:
2603             failIfTrueIfStrict(context.isResolve(expr), "Cannot delete unqualified property '", m_lastIdentifier->impl(), "' in strict mode");
2604             expr = context.makeDeleteNode(location, expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end);
2605             break;
2606         default:
2607             // If we get here something has gone horribly horribly wrong
2608             CRASH();
2609         }
2610         subExprStart = context.unaryTokenStackLastStart(tokenStackDepth);
2611         context.unaryTokenStackRemoveLast(tokenStackDepth);
2612     }
2613     return expr;
2614 }
2615
2616
2617 template <typename LexerType> void Parser<LexerType>::printUnexpectedTokenText(WTF::PrintStream& out)
2618 {
2619     switch (m_token.m_type) {
2620     case EOFTOK:
2621         out.print("Unexpected end of script");
2622         return;
2623     case UNTERMINATED_IDENTIFIER_ESCAPE_ERRORTOK:
2624     case UNTERMINATED_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK:
2625         out.print("Incomplete unicode escape in identifier: '", getToken(), "'");
2626         return;
2627     case UNTERMINATED_MULTILINE_COMMENT_ERRORTOK:
2628         out.print("Unterminated multiline comment");
2629         return;
2630     case UNTERMINATED_NUMERIC_LITERAL_ERRORTOK:
2631         out.print("Unterminated numeric literal '", getToken(), "'");
2632         return;
2633     case UNTERMINATED_STRING_LITERAL_ERRORTOK:
2634         out.print("Unterminated string literal '", getToken(), "'");
2635         return;
2636     case INVALID_IDENTIFIER_ESCAPE_ERRORTOK:
2637         out.print("Invalid escape in identifier: '", getToken(), "'");
2638         return;
2639     case INVALID_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK:
2640         out.print("Invalid unicode escape in identifier: '", getToken(), "'");
2641         return;
2642     case INVALID_NUMERIC_LITERAL_ERRORTOK:
2643         out.print("Invalid numeric literal: '", getToken(), "'");
2644         return;
2645     case INVALID_OCTAL_NUMBER_ERRORTOK:
2646         out.print("Invalid use of octal: '", getToken(), "'");
2647         return;
2648     case INVALID_STRING_LITERAL_ERRORTOK:
2649         out.print("Invalid string literal: '", getToken(), "'");
2650         return;
2651     case ERRORTOK:
2652         out.print("Unrecognized token '", getToken(), "'");
2653         return;
2654     case STRING:
2655         out.print("Unexpected string literal ", getToken());
2656         return;
2657     case INTEGER:
2658     case DOUBLE:
2659         out.print("Unexpected number '", getToken(), "'");
2660         return;
2661     
2662     case RESERVED_IF_STRICT:
2663         out.print("Unexpected use of reserved word '", getToken(), "' in strict mode");
2664         return;
2665         
2666     case RESERVED:
2667         out.print("Unexpected use of reserved word '", getToken(), "'");
2668         return;
2669
2670     case INVALID_PRIVATE_NAME_ERRORTOK:
2671         out.print("Invalid private name '", getToken(), "'");
2672         return;
2673             
2674     case IDENT:
2675         out.print("Unexpected identifier '", getToken(), "'");
2676         return;
2677
2678     default:
2679         break;
2680     }
2681
2682     if (m_token.m_type & KeywordTokenFlag) {
2683         out.print("Unexpected keyword '", getToken(), "'");
2684         return;
2685     }
2686     
2687     out.print("Unexpected token '", getToken(), "'");
2688 }
2689
2690 // Instantiate the two flavors of Parser we need instead of putting most of this file in Parser.h
2691 template class Parser<Lexer<LChar>>;
2692 template class Parser<Lexer<UChar>>;
2693     
2694 } // namespace JSC