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