286509330294562129e2e58008bcc4100baab78c
[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 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 "JSGlobalData.h"
30 #include "Lexer.h"
31 #include "NodeInfo.h"
32 #include "SourceProvider.h"
33 #include <utility>
34 #include <wtf/HashFunctions.h>
35 #include <wtf/OwnPtr.h>
36 #include <wtf/WTFThreadData.h>
37
38 using namespace std;
39
40 namespace JSC {
41
42 template <typename LexerType>
43 Parser<LexerType>::Parser(JSGlobalData* globalData, const SourceCode& source, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode parserMode)
44     : m_globalData(globalData)
45     , m_source(&source)
46     , m_stack(wtfThreadData().stack())
47     , m_error(false)
48     , m_errorMessage("Parse error")
49     , m_allowsIn(true)
50     , m_lastLine(0)
51     , m_lastTokenEnd(0)
52     , m_assignmentCount(0)
53     , m_nonLHSCount(0)
54     , m_syntaxAlreadyValidated(source.provider()->isValid())
55     , m_statementDepth(0)
56     , m_nonTrivialExpressionCount(0)
57     , m_lastIdentifier(0)
58     , m_sourceElements(0)
59 {
60     m_lexer = adoptPtr(new LexerType(globalData));
61     m_arena = m_globalData->parserArena.get();
62     m_lexer->setCode(source, m_arena);
63
64     m_functionCache = source.provider()->cache();
65     ScopeRef scope = pushScope();
66     if (parserMode == JSParseFunctionCode)
67         scope->setIsFunction();
68     if (strictness == JSParseStrict)
69         scope->setStrictMode();
70     if (parameters) {
71         for (unsigned i = 0; i < parameters->size(); i++)
72             scope->declareParameter(&parameters->at(i));
73     }
74     next();
75     m_lexer->setLastLineNumber(tokenLine());
76 }
77
78 template <typename LexerType>
79 Parser<LexerType>::~Parser()
80 {
81 }
82
83 template <typename LexerType>
84 UString Parser<LexerType>::parseInner()
85 {
86     UString parseError = UString();
87     
88     unsigned oldFunctionCacheSize = m_functionCache ? m_functionCache->byteSize() : 0;
89     ASTBuilder context(const_cast<JSGlobalData*>(m_globalData), const_cast<SourceCode*>(m_source));
90     if (m_lexer->isReparsing())
91         m_statementDepth--;
92     ScopeRef scope = currentScope();
93     SourceElements* sourceElements = parseSourceElements<CheckForStrictMode>(context);
94     if (!sourceElements || !consume(EOFTOK))
95         parseError = m_errorMessage;
96
97     IdentifierSet capturedVariables;
98     scope->getCapturedVariables(capturedVariables);
99     CodeFeatures features = context.features();
100     if (scope->strictMode())
101         features |= StrictModeFeature;
102     if (scope->shadowsArguments())
103         features |= ShadowsArgumentsFeature;
104     unsigned functionCacheSize = m_functionCache ? m_functionCache->byteSize() : 0;
105     if (functionCacheSize != oldFunctionCacheSize)
106         m_lexer->sourceProvider()->notifyCacheSizeChanged(functionCacheSize - oldFunctionCacheSize);
107
108     didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), features,
109                      m_lastLine, context.numConstants(), capturedVariables);
110
111     return parseError;
112 }
113
114 template <typename LexerType>
115 void Parser<LexerType>::didFinishParsing(SourceElements* sourceElements, ParserArenaData<DeclarationStacks::VarStack>* varStack, 
116                               ParserArenaData<DeclarationStacks::FunctionStack>* funcStack, CodeFeatures features, int lastLine, int numConstants, IdentifierSet& capturedVars)
117 {
118     m_sourceElements = sourceElements;
119     m_varDeclarations = varStack;
120     m_funcDeclarations = funcStack;
121     m_capturedVariables.swap(capturedVars);
122     m_features = features;
123     m_lastLine = lastLine;
124     m_numConstants = numConstants;
125 }
126
127 template <typename LexerType>
128 bool Parser<LexerType>::allowAutomaticSemicolon()
129 {
130     return match(CLOSEBRACE) || match(EOFTOK) || m_lexer->prevTerminator();
131 }
132
133 template <typename LexerType>
134 template <SourceElementsMode mode, class TreeBuilder> TreeSourceElements Parser<LexerType>::parseSourceElements(TreeBuilder& context)
135 {
136     const unsigned lengthOfUseStrictLiteral = 12; // "use strict".length
137     TreeSourceElements sourceElements = context.createSourceElements();
138     bool seenNonDirective = false;
139     const Identifier* directive = 0;
140     unsigned directiveLiteralLength = 0;
141     unsigned startOffset = m_token.m_info.startOffset;
142     unsigned oldLastLineNumber = m_lexer->lastLineNumber();
143     unsigned oldLineNumber = m_lexer->lineNumber();
144     bool hasSetStrict = false;
145     while (TreeStatement statement = parseStatement(context, directive, &directiveLiteralLength)) {
146         if (mode == CheckForStrictMode && !seenNonDirective) {
147             if (directive) {
148                 // "use strict" must be the exact literal without escape sequences or line continuation.
149                 if (!hasSetStrict && directiveLiteralLength == lengthOfUseStrictLiteral && m_globalData->propertyNames->useStrictIdentifier == *directive) {
150                     setStrictMode();
151                     hasSetStrict = true;
152                     failIfFalse(isValidStrictMode());
153                     m_lexer->setOffset(startOffset);
154                     next();
155                     m_lexer->setLastLineNumber(oldLastLineNumber);
156                     m_lexer->setLineNumber(oldLineNumber);
157                     failIfTrue(m_error);
158                     continue;
159                 }
160             } else
161                 seenNonDirective = true;
162         }
163         context.appendStatement(sourceElements, statement);
164     }
165     
166     if (m_error)
167         fail();
168     return sourceElements;
169 }
170
171 template <typename LexerType>
172 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseVarDeclaration(TreeBuilder& context)
173 {
174     ASSERT(match(VAR));
175     int start = tokenLine();
176     int end = 0;
177     int scratch;
178     const Identifier* scratch1 = 0;
179     TreeExpression scratch2 = 0;
180     int scratch3 = 0;
181     TreeExpression varDecls = parseVarDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3);
182     failIfTrue(m_error);
183     failIfFalse(autoSemiColon());
184     
185     return context.createVarStatement(m_lexer->lastLineNumber(), varDecls, start, end);
186 }
187
188 template <typename LexerType>
189 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseConstDeclaration(TreeBuilder& context)
190 {
191     ASSERT(match(CONSTTOKEN));
192     int start = tokenLine();
193     int end = 0;
194     TreeConstDeclList constDecls = parseConstDeclarationList(context);
195     failIfTrue(m_error);
196     failIfFalse(autoSemiColon());
197     
198     return context.createConstStatement(m_lexer->lastLineNumber(), constDecls, start, end);
199 }
200
201 template <typename LexerType>
202 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseDoWhileStatement(TreeBuilder& context)
203 {
204     ASSERT(match(DO));
205     int startLine = tokenLine();
206     next();
207     const Identifier* unused = 0;
208     startLoop();
209     TreeStatement statement = parseStatement(context, unused);
210     endLoop();
211     failIfFalse(statement);
212     int endLine = tokenLine();
213     consumeOrFail(WHILE);
214     consumeOrFail(OPENPAREN);
215     TreeExpression expr = parseExpression(context);
216     failIfFalse(expr);
217     consumeOrFail(CLOSEPAREN);
218     if (match(SEMICOLON))
219         next(); // Always performs automatic semicolon insertion.
220     return context.createDoWhileStatement(m_lexer->lastLineNumber(), statement, expr, startLine, endLine);
221 }
222
223 template <typename LexerType>
224 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWhileStatement(TreeBuilder& context)
225 {
226     ASSERT(match(WHILE));
227     int startLine = tokenLine();
228     next();
229     consumeOrFail(OPENPAREN);
230     TreeExpression expr = parseExpression(context);
231     failIfFalse(expr);
232     int endLine = tokenLine();
233     consumeOrFail(CLOSEPAREN);
234     const Identifier* unused = 0;
235     startLoop();
236     TreeStatement statement = parseStatement(context, unused);
237     endLoop();
238     failIfFalse(statement);
239     return context.createWhileStatement(m_lexer->lastLineNumber(), expr, statement, startLine, endLine);
240 }
241
242 template <typename LexerType>
243 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseVarDeclarationList(TreeBuilder& context, int& declarations, const Identifier*& lastIdent, TreeExpression& lastInitializer, int& identStart, int& initStart, int& initEnd)
244 {
245     TreeExpression varDecls = 0;
246     do {
247         declarations++;
248         next();
249         matchOrFail(IDENT);
250         
251         int varStart = tokenStart();
252         identStart = varStart;
253         const Identifier* name = m_token.m_data.ident;
254         lastIdent = name;
255         next();
256         bool hasInitializer = match(EQUAL);
257         failIfFalseIfStrictWithNameAndMessage(declareVariable(name), "Cannot declare a variable named", name->impl(), "in strict mode.");
258         context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0);
259         if (hasInitializer) {
260             int varDivot = tokenStart() + 1;
261             initStart = tokenStart();
262             next(TreeBuilder::DontBuildStrings); // consume '='
263             int initialAssignments = m_assignmentCount;
264             TreeExpression initializer = parseAssignmentExpression(context);
265             initEnd = lastTokenEnd();
266             lastInitializer = initializer;
267             failIfFalse(initializer);
268             
269             TreeExpression node = context.createAssignResolve(m_lexer->lastLineNumber(), *name, initializer, initialAssignments != m_assignmentCount, varStart, varDivot, lastTokenEnd());
270             if (!varDecls)
271                 varDecls = node;
272             else
273                 varDecls = context.combineCommaNodes(m_lexer->lastLineNumber(), varDecls, node);
274         }
275     } while (match(COMMA));
276     return varDecls;
277 }
278
279 template <typename LexerType>
280 template <class TreeBuilder> TreeConstDeclList Parser<LexerType>::parseConstDeclarationList(TreeBuilder& context)
281 {
282     failIfTrue(strictMode());
283     TreeConstDeclList constDecls = 0;
284     TreeConstDeclList tail = 0;
285     do {
286         next();
287         matchOrFail(IDENT);
288         const Identifier* name = m_token.m_data.ident;
289         next();
290         bool hasInitializer = match(EQUAL);
291         declareVariable(name);
292         context.addVar(name, DeclarationStacks::IsConstant | (hasInitializer ? DeclarationStacks::HasInitializer : 0));
293         TreeExpression initializer = 0;
294         if (hasInitializer) {
295             next(TreeBuilder::DontBuildStrings); // consume '='
296             initializer = parseAssignmentExpression(context);
297         }
298         tail = context.appendConstDecl(m_lexer->lastLineNumber(), tail, name, initializer);
299         if (!constDecls)
300             constDecls = tail;
301     } while (match(COMMA));
302     return constDecls;
303 }
304
305 template <typename LexerType>
306 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseForStatement(TreeBuilder& context)
307 {
308     ASSERT(match(FOR));
309     int startLine = tokenLine();
310     next();
311     consumeOrFail(OPENPAREN);
312     int nonLHSCount = m_nonLHSCount;
313     int declarations = 0;
314     int declsStart = 0;
315     int declsEnd = 0;
316     TreeExpression decls = 0;
317     bool hasDeclaration = false;
318     if (match(VAR)) {
319         /*
320          for (var IDENT in expression) statement
321          for (var IDENT = expression in expression) statement
322          for (var varDeclarationList; expressionOpt; expressionOpt)
323          */
324         hasDeclaration = true;
325         const Identifier* forInTarget = 0;
326         TreeExpression forInInitializer = 0;
327         m_allowsIn = false;
328         int initStart = 0;
329         int initEnd = 0;
330         decls = parseVarDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd);
331         m_allowsIn = true;
332         if (m_error)
333             fail();
334         
335         // Remainder of a standard for loop is handled identically
336         if (match(SEMICOLON))
337             goto standardForLoop;
338         
339         failIfFalse(declarations == 1);
340         
341         // Handle for-in with var declaration
342         int inLocation = tokenStart();
343         consumeOrFail(INTOKEN);
344         
345         TreeExpression expr = parseExpression(context);
346         failIfFalse(expr);
347         int exprEnd = lastTokenEnd();
348         
349         int endLine = tokenLine();
350         consumeOrFail(CLOSEPAREN);
351         
352         const Identifier* unused = 0;
353         startLoop();
354         TreeStatement statement = parseStatement(context, unused);
355         endLoop();
356         failIfFalse(statement);
357         
358         return context.createForInLoop(m_lexer->lastLineNumber(), forInTarget, forInInitializer, expr, statement, declsStart, inLocation, exprEnd, initStart, initEnd, startLine, endLine);
359     }
360     
361     if (!match(SEMICOLON)) {
362         m_allowsIn = false;
363         declsStart = tokenStart();
364         decls = parseExpression(context);
365         declsEnd = lastTokenEnd();
366         m_allowsIn = true;
367         failIfFalse(decls);
368     }
369     
370     if (match(SEMICOLON)) {
371     standardForLoop:
372         // Standard for loop
373         next();
374         TreeExpression condition = 0;
375         
376         if (!match(SEMICOLON)) {
377             condition = parseExpression(context);
378             failIfFalse(condition);
379         }
380         consumeOrFail(SEMICOLON);
381         
382         TreeExpression increment = 0;
383         if (!match(CLOSEPAREN)) {
384             increment = parseExpression(context);
385             failIfFalse(increment);
386         }
387         int endLine = tokenLine();
388         consumeOrFail(CLOSEPAREN);
389         const Identifier* unused = 0;
390         startLoop();
391         TreeStatement statement = parseStatement(context, unused);
392         endLoop();
393         failIfFalse(statement);
394         return context.createForLoop(m_lexer->lastLineNumber(), decls, condition, increment, statement, hasDeclaration, startLine, endLine);
395     }
396     
397     // For-in loop
398     failIfFalse(nonLHSCount == m_nonLHSCount);
399     consumeOrFail(INTOKEN);
400     TreeExpression expr = parseExpression(context);
401     failIfFalse(expr);
402     int exprEnd = lastTokenEnd();
403     int endLine = tokenLine();
404     consumeOrFail(CLOSEPAREN);
405     const Identifier* unused = 0;
406     startLoop();
407     TreeStatement statement = parseStatement(context, unused);
408     endLoop();
409     failIfFalse(statement);
410     
411     return context.createForInLoop(m_lexer->lastLineNumber(), decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine);
412 }
413
414 template <typename LexerType>
415 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBreakStatement(TreeBuilder& context)
416 {
417     ASSERT(match(BREAK));
418     int startCol = tokenStart();
419     int endCol = tokenEnd();
420     int startLine = tokenLine();
421     int endLine = tokenLine();
422     next();
423     
424     if (autoSemiColon()) {
425         failIfFalseWithMessage(breakIsValid(), "'break' is only valid inside a switch or loop statement");
426         return context.createBreakStatement(m_lexer->lastLineNumber(), startCol, endCol, startLine, endLine);
427     }
428     matchOrFail(IDENT);
429     const Identifier* ident = m_token.m_data.ident;
430     failIfFalseWithNameAndMessage(getLabel(ident), "Label", ident->impl(), "is not defined");
431     endCol = tokenEnd();
432     endLine = tokenLine();
433     next();
434     failIfFalse(autoSemiColon());
435     return context.createBreakStatement(m_lexer->lastLineNumber(), ident, startCol, endCol, startLine, endLine);
436 }
437
438 template <typename LexerType>
439 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseContinueStatement(TreeBuilder& context)
440 {
441     ASSERT(match(CONTINUE));
442     int startCol = tokenStart();
443     int endCol = tokenEnd();
444     int startLine = tokenLine();
445     int endLine = tokenLine();
446     next();
447     
448     if (autoSemiColon()) {
449         failIfFalseWithMessage(continueIsValid(), "'continue' is only valid inside a loop statement");
450         return context.createContinueStatement(m_lexer->lastLineNumber(), startCol, endCol, startLine, endLine);
451     }
452     matchOrFail(IDENT);
453     const Identifier* ident = m_token.m_data.ident;
454     ScopeLabelInfo* label = getLabel(ident);
455     failIfFalseWithNameAndMessage(label, "Label", ident->impl(), "is not defined");
456     failIfFalseWithMessage(label->m_isLoop, "'continue' is only valid inside a loop statement");
457     endCol = tokenEnd();
458     endLine = tokenLine();
459     next();
460     failIfFalse(autoSemiColon());
461     return context.createContinueStatement(m_lexer->lastLineNumber(), ident, startCol, endCol, startLine, endLine);
462 }
463
464 template <typename LexerType>
465 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseReturnStatement(TreeBuilder& context)
466 {
467     ASSERT(match(RETURN));
468     failIfFalse(currentScope()->isFunction());
469     int startLine = tokenLine();
470     int endLine = startLine;
471     int start = tokenStart();
472     int end = tokenEnd();
473     next();
474     // We do the auto semicolon check before attempting to parse an expression
475     // as we need to ensure the a line break after the return correctly terminates
476     // the statement
477     if (match(SEMICOLON))
478         endLine  = tokenLine();
479     if (autoSemiColon())
480         return context.createReturnStatement(m_lexer->lastLineNumber(), 0, start, end, startLine, endLine);
481     TreeExpression expr = parseExpression(context);
482     failIfFalse(expr);
483     end = lastTokenEnd();
484     if (match(SEMICOLON))
485         endLine  = tokenLine();
486     failIfFalse(autoSemiColon());
487     return context.createReturnStatement(m_lexer->lastLineNumber(), expr, start, end, startLine, endLine);
488 }
489
490 template <typename LexerType>
491 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseThrowStatement(TreeBuilder& context)
492 {
493     ASSERT(match(THROW));
494     int eStart = tokenStart();
495     int startLine = tokenLine();
496     next();
497     
498     failIfTrue(autoSemiColon());
499     
500     TreeExpression expr = parseExpression(context);
501     failIfFalse(expr);
502     int eEnd = lastTokenEnd();
503     int endLine = tokenLine();
504     failIfFalse(autoSemiColon());
505     
506     return context.createThrowStatement(m_lexer->lastLineNumber(), expr, eStart, eEnd, startLine, endLine);
507 }
508
509 template <typename LexerType>
510 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseWithStatement(TreeBuilder& context)
511 {
512     ASSERT(match(WITH));
513     failIfTrueWithMessage(strictMode(), "'with' statements are not valid in strict mode");
514     currentScope()->setNeedsFullActivation();
515     int startLine = tokenLine();
516     next();
517     consumeOrFail(OPENPAREN);
518     int start = tokenStart();
519     TreeExpression expr = parseExpression(context);
520     failIfFalse(expr);
521     int end = lastTokenEnd();
522     
523     int endLine = tokenLine();
524     consumeOrFail(CLOSEPAREN);
525     const Identifier* unused = 0;
526     TreeStatement statement = parseStatement(context, unused);
527     failIfFalse(statement);
528     
529     return context.createWithStatement(m_lexer->lastLineNumber(), expr, statement, start, end, startLine, endLine);
530 }
531
532 template <typename LexerType>
533 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseSwitchStatement(TreeBuilder& context)
534 {
535     ASSERT(match(SWITCH));
536     int startLine = tokenLine();
537     next();
538     consumeOrFail(OPENPAREN);
539     TreeExpression expr = parseExpression(context);
540     failIfFalse(expr);
541     int endLine = tokenLine();
542     consumeOrFail(CLOSEPAREN);
543     consumeOrFail(OPENBRACE);
544     startSwitch();
545     TreeClauseList firstClauses = parseSwitchClauses(context);
546     failIfTrue(m_error);
547     
548     TreeClause defaultClause = parseSwitchDefaultClause(context);
549     failIfTrue(m_error);
550     
551     TreeClauseList secondClauses = parseSwitchClauses(context);
552     failIfTrue(m_error);
553     endSwitch();
554     consumeOrFail(CLOSEBRACE);
555     
556     return context.createSwitchStatement(m_lexer->lastLineNumber(), expr, firstClauses, defaultClause, secondClauses, startLine, endLine);
557     
558 }
559
560 template <typename LexerType>
561 template <class TreeBuilder> TreeClauseList Parser<LexerType>::parseSwitchClauses(TreeBuilder& context)
562 {
563     if (!match(CASE))
564         return 0;
565     next();
566     TreeExpression condition = parseExpression(context);
567     failIfFalse(condition);
568     consumeOrFail(COLON);
569     TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context);
570     failIfFalse(statements);
571     TreeClause clause = context.createClause(condition, statements);
572     TreeClauseList clauseList = context.createClauseList(clause);
573     TreeClauseList tail = clauseList;
574     
575     while (match(CASE)) {
576         next();
577         TreeExpression condition = parseExpression(context);
578         failIfFalse(condition);
579         consumeOrFail(COLON);
580         TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context);
581         failIfFalse(statements);
582         clause = context.createClause(condition, statements);
583         tail = context.createClauseList(tail, clause);
584     }
585     return clauseList;
586 }
587
588 template <typename LexerType>
589 template <class TreeBuilder> TreeClause Parser<LexerType>::parseSwitchDefaultClause(TreeBuilder& context)
590 {
591     if (!match(DEFAULT))
592         return 0;
593     next();
594     consumeOrFail(COLON);
595     TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context);
596     failIfFalse(statements);
597     return context.createClause(0, statements);
598 }
599
600 template <typename LexerType>
601 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseTryStatement(TreeBuilder& context)
602 {
603     ASSERT(match(TRY));
604     TreeStatement tryBlock = 0;
605     const Identifier* ident = &m_globalData->propertyNames->nullIdentifier;
606     bool catchHasEval = false;
607     TreeStatement catchBlock = 0;
608     TreeStatement finallyBlock = 0;
609     int firstLine = tokenLine();
610     next();
611     matchOrFail(OPENBRACE);
612     
613     tryBlock = parseBlockStatement(context);
614     failIfFalse(tryBlock);
615     int lastLine = m_lastLine;
616     
617     if (match(CATCH)) {
618         currentScope()->setNeedsFullActivation();
619         next();
620         consumeOrFail(OPENPAREN);
621         matchOrFail(IDENT);
622         ident = m_token.m_data.ident;
623         next();
624         AutoPopScopeRef catchScope(this, pushScope());
625         failIfFalseIfStrictWithNameAndMessage(declareVariable(ident), "Cannot declare a variable named", ident->impl(), "in strict mode");
626         catchScope->preventNewDecls();
627         consumeOrFail(CLOSEPAREN);
628         matchOrFail(OPENBRACE);
629         int initialEvalCount = context.evalCount();
630         catchBlock = parseBlockStatement(context);
631         failIfFalseWithMessage(catchBlock, "'try' must have a catch or finally block");
632         catchHasEval = initialEvalCount != context.evalCount();
633         failIfFalse(popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo));
634     }
635     
636     if (match(FINALLY)) {
637         next();
638         matchOrFail(OPENBRACE);
639         finallyBlock = parseBlockStatement(context);
640         failIfFalse(finallyBlock);
641     }
642     failIfFalse(catchBlock || finallyBlock);
643     return context.createTryStatement(m_lexer->lastLineNumber(), tryBlock, ident, catchHasEval, catchBlock, finallyBlock, firstLine, lastLine);
644 }
645
646 template <typename LexerType>
647 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseDebuggerStatement(TreeBuilder& context)
648 {
649     ASSERT(match(DEBUGGER));
650     int startLine = tokenLine();
651     int endLine = startLine;
652     next();
653     if (match(SEMICOLON))
654         startLine = tokenLine();
655     failIfFalse(autoSemiColon());
656     return context.createDebugger(m_lexer->lastLineNumber(), startLine, endLine);
657 }
658
659 template <typename LexerType>
660 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBlockStatement(TreeBuilder& context)
661 {
662     ASSERT(match(OPENBRACE));
663     int start = tokenLine();
664     next();
665     if (match(CLOSEBRACE)) {
666         next();
667         return context.createBlockStatement(m_lexer->lastLineNumber(), 0, start, m_lastLine);
668     }
669     TreeSourceElements subtree = parseSourceElements<DontCheckForStrictMode>(context);
670     failIfFalse(subtree);
671     matchOrFail(CLOSEBRACE);
672     next();
673     return context.createBlockStatement(m_lexer->lastLineNumber(), subtree, start, m_lastLine);
674 }
675
676 template <typename LexerType>
677 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength)
678 {
679     DepthManager statementDepth(&m_statementDepth);
680     m_statementDepth++;
681     directive = 0;
682     int nonTrivialExpressionCount = 0;
683     failIfStackOverflow();
684     switch (m_token.m_type) {
685     case OPENBRACE:
686         return parseBlockStatement(context);
687     case VAR:
688         return parseVarDeclaration(context);
689     case CONSTTOKEN:
690         return parseConstDeclaration(context);
691     case FUNCTION:
692         failIfFalseIfStrictWithMessage(m_statementDepth == 1, "Functions cannot be declared in a nested block in strict mode");
693         return parseFunctionDeclaration(context);
694     case SEMICOLON:
695         next();
696         return context.createEmptyStatement(m_lexer->lastLineNumber());
697     case IF:
698         return parseIfStatement(context);
699     case DO:
700         return parseDoWhileStatement(context);
701     case WHILE:
702         return parseWhileStatement(context);
703     case FOR:
704         return parseForStatement(context);
705     case CONTINUE:
706         return parseContinueStatement(context);
707     case BREAK:
708         return parseBreakStatement(context);
709     case RETURN:
710         return parseReturnStatement(context);
711     case WITH:
712         return parseWithStatement(context);
713     case SWITCH:
714         return parseSwitchStatement(context);
715     case THROW:
716         return parseThrowStatement(context);
717     case TRY:
718         return parseTryStatement(context);
719     case DEBUGGER:
720         return parseDebuggerStatement(context);
721     case EOFTOK:
722     case CASE:
723     case CLOSEBRACE:
724     case DEFAULT:
725         // These tokens imply the end of a set of source elements
726         return 0;
727     case IDENT:
728         return parseExpressionOrLabelStatement(context);
729     case STRING:
730         directive = m_token.m_data.ident;
731         if (directiveLiteralLength)
732             *directiveLiteralLength = m_token.m_info.endOffset - m_token.m_info.startOffset;
733         nonTrivialExpressionCount = m_nonTrivialExpressionCount;
734     default:
735         TreeStatement exprStatement = parseExpressionStatement(context);
736         if (directive && nonTrivialExpressionCount != m_nonTrivialExpressionCount)
737             directive = 0;
738         return exprStatement;
739     }
740 }
741
742 template <typename LexerType>
743 template <class TreeBuilder> TreeFormalParameterList Parser<LexerType>::parseFormalParameters(TreeBuilder& context)
744 {
745     matchOrFail(IDENT);
746     failIfFalseIfStrictWithNameAndMessage(declareParameter(m_token.m_data.ident), "Cannot declare a parameter named", m_token.m_data.ident->impl(), " in strict mode");
747     TreeFormalParameterList list = context.createFormalParameterList(*m_token.m_data.ident);
748     TreeFormalParameterList tail = list;
749     next();
750     while (match(COMMA)) {
751         next();
752         matchOrFail(IDENT);
753         const Identifier* ident = m_token.m_data.ident;
754         failIfFalseIfStrictWithNameAndMessage(declareParameter(ident), "Cannot declare a parameter named", ident->impl(), "in strict mode");
755         next();
756         tail = context.createFormalParameterList(tail, *ident);
757     }
758     return list;
759 }
760
761 template <typename LexerType>
762 template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody(TreeBuilder& context)
763 {
764     if (match(CLOSEBRACE))
765         return context.createFunctionBody(m_lexer->lastLineNumber(), strictMode());
766     DepthManager statementDepth(&m_statementDepth);
767     m_statementDepth = 0;
768     typename TreeBuilder::FunctionBodyBuilder bodyBuilder(const_cast<JSGlobalData*>(m_globalData), m_lexer.get());
769     failIfFalse(parseSourceElements<CheckForStrictMode>(bodyBuilder));
770     return context.createFunctionBody(m_lexer->lastLineNumber(), strictMode());
771 }
772
773 template <typename LexerType>
774 template <FunctionRequirements requirements, bool nameIsInContainingScope, class TreeBuilder> bool Parser<LexerType>::parseFunctionInfo(TreeBuilder& context, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, int& openBracePos, int& closeBracePos, int& bodyStartLine)
775 {
776     AutoPopScopeRef functionScope(this, pushScope());
777     functionScope->setIsFunction();
778     if (match(IDENT)) {
779         name = m_token.m_data.ident;
780         failIfTrueWithMessage(*name == m_globalData->propertyNames->underscoreProto, "Cannot name a function __proto__");
781         next();
782         if (!nameIsInContainingScope)
783             failIfFalseIfStrict(functionScope->declareVariable(name));
784     } else if (requirements == FunctionNeedsName)
785         return false;
786     consumeOrFail(OPENPAREN);
787     if (!match(CLOSEPAREN)) {
788         parameters = parseFormalParameters(context);
789         failIfFalse(parameters);
790     }
791     consumeOrFail(CLOSEPAREN);
792     matchOrFail(OPENBRACE);
793     
794     openBracePos = m_token.m_data.intValue;
795     bodyStartLine = tokenLine();
796     
797     // If we know about this function already, we can use the cached info and skip the parser to the end of the function.
798     if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(openBracePos) : 0) {
799         // If we're in a strict context, the cached function info must say it was strict too.
800         ASSERT(!strictMode() || cachedInfo->strictMode);
801         body = context.createFunctionBody(m_lexer->lastLineNumber(), cachedInfo->strictMode);
802         
803         functionScope->restoreFunctionInfo(cachedInfo);
804         failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo));
805         
806         closeBracePos = cachedInfo->closeBracePos;
807         m_token = cachedInfo->closeBraceToken();
808         m_lexer->setOffset(m_token.m_info.endOffset);
809         m_lexer->setLineNumber(m_token.m_info.line);
810         
811         next();
812         return true;
813     }
814     
815     next();
816     
817     body = parseFunctionBody(context);
818     failIfFalse(body);
819     if (functionScope->strictMode() && name) {
820         failIfTrueWithNameAndMessage(m_globalData->propertyNames->arguments == *name, "Function name", name->impl(), "is not valid in strict mode");
821         failIfTrueWithNameAndMessage(m_globalData->propertyNames->eval == *name, "Function name", name->impl(), "is not valid in strict mode");
822     }
823     closeBracePos = m_token.m_data.intValue;
824     
825     // Cache the tokenizer state and the function scope the first time the function is parsed.
826     // Any future reparsing can then skip the function.
827     static const int minimumFunctionLengthToCache = 64;
828     OwnPtr<SourceProviderCacheItem> newInfo;
829     int functionLength = closeBracePos - openBracePos;
830     if (TreeBuilder::CanUseFunctionCache && m_functionCache && functionLength > minimumFunctionLengthToCache) {
831         newInfo = adoptPtr(new SourceProviderCacheItem(m_token.m_info.line, closeBracePos));
832         functionScope->saveFunctionInfo(newInfo.get());
833     }
834     
835     failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo));
836     matchOrFail(CLOSEBRACE);
837     
838     if (newInfo) {
839         unsigned approximateByteSize = newInfo->approximateByteSize();
840         m_functionCache->add(openBracePos, newInfo.release(), approximateByteSize);
841     }
842     
843     next();
844     return true;
845 }
846
847 template <typename LexerType>
848 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclaration(TreeBuilder& context)
849 {
850     ASSERT(match(FUNCTION));
851     next();
852     const Identifier* name = 0;
853     TreeFormalParameterList parameters = 0;
854     TreeFunctionBody body = 0;
855     int openBracePos = 0;
856     int closeBracePos = 0;
857     int bodyStartLine = 0;
858     failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
859     failIfFalse(name);
860     failIfFalseIfStrict(declareVariable(name));
861     return context.createFuncDeclStatement(m_lexer->lastLineNumber(), name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
862 }
863
864 struct LabelInfo {
865     LabelInfo(const Identifier* ident, int start, int end)
866     : m_ident(ident)
867     , m_start(start)
868     , m_end(end)
869     {
870     }
871     
872     const Identifier* m_ident;
873     int m_start;
874     int m_end;
875 };
876
877 template <typename LexerType>
878 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrLabelStatement(TreeBuilder& context)
879 {
880     
881     /* Expression and Label statements are ambiguous at LL(1), so we have a
882      * special case that looks for a colon as the next character in the input.
883      */
884     Vector<LabelInfo> labels;
885     
886     do {
887         int start = tokenStart();
888         int startLine = tokenLine();
889         if (!nextTokenIsColon()) {
890             // If we hit this path we're making a expression statement, which
891             // by definition can't make use of continue/break so we can just
892             // ignore any labels we might have accumulated.
893             TreeExpression expression = parseExpression(context);
894             failIfFalse(expression);
895             failIfFalse(autoSemiColon());
896             return context.createExprStatement(m_lexer->lastLineNumber(), expression, startLine, m_lastLine);
897         }
898         const Identifier* ident = m_token.m_data.ident;
899         int end = tokenEnd();
900         next();
901         consumeOrFail(COLON);
902         if (!m_syntaxAlreadyValidated) {
903             // This is O(N^2) over the current list of consecutive labels, but I
904             // have never seen more than one label in a row in the real world.
905             for (size_t i = 0; i < labels.size(); i++)
906                 failIfTrue(ident->impl() == labels[i].m_ident->impl());
907             failIfTrue(getLabel(ident));
908             labels.append(LabelInfo(ident, start, end));
909         }
910     } while (match(IDENT));
911     bool isLoop = false;
912     switch (m_token.m_type) {
913     case FOR:
914     case WHILE:
915     case DO:
916         isLoop = true;
917         break;
918         
919     default:
920         break;
921     }
922     const Identifier* unused = 0;
923     if (!m_syntaxAlreadyValidated) {
924         for (size_t i = 0; i < labels.size(); i++)
925             pushLabel(labels[i].m_ident, isLoop);
926     }
927     TreeStatement statement = parseStatement(context, unused);
928     if (!m_syntaxAlreadyValidated) {
929         for (size_t i = 0; i < labels.size(); i++)
930             popLabel();
931     }
932     failIfFalse(statement);
933     for (size_t i = 0; i < labels.size(); i++) {
934         const LabelInfo& info = labels[labels.size() - i - 1];
935         statement = context.createLabelStatement(m_lexer->lastLineNumber(), info.m_ident, statement, info.m_start, info.m_end);
936     }
937     return statement;
938 }
939
940 template <typename LexerType>
941 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionStatement(TreeBuilder& context)
942 {
943     int startLine = tokenLine();
944     TreeExpression expression = parseExpression(context);
945     failIfFalse(expression);
946     failIfFalse(autoSemiColon());
947     return context.createExprStatement(m_lexer->lastLineNumber(), expression, startLine, m_lastLine);
948 }
949
950 template <typename LexerType>
951 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(TreeBuilder& context)
952 {
953     ASSERT(match(IF));
954     
955     int start = tokenLine();
956     next();
957     
958     consumeOrFail(OPENPAREN);
959     
960     TreeExpression condition = parseExpression(context);
961     failIfFalse(condition);
962     int end = tokenLine();
963     consumeOrFail(CLOSEPAREN);
964     
965     const Identifier* unused = 0;
966     TreeStatement trueBlock = parseStatement(context, unused);
967     failIfFalse(trueBlock);
968     
969     if (!match(ELSE))
970         return context.createIfStatement(m_lexer->lastLineNumber(), condition, trueBlock, start, end);
971     
972     Vector<TreeExpression> exprStack;
973     Vector<pair<int, int> > posStack;
974     Vector<TreeStatement> statementStack;
975     bool trailingElse = false;
976     do {
977         next();
978         if (!match(IF)) {
979             const Identifier* unused = 0;
980             TreeStatement block = parseStatement(context, unused);
981             failIfFalse(block);
982             statementStack.append(block);
983             trailingElse = true;
984             break;
985         }
986         int innerStart = tokenLine();
987         next();
988         
989         consumeOrFail(OPENPAREN);
990         
991         TreeExpression innerCondition = parseExpression(context);
992         failIfFalse(innerCondition);
993         int innerEnd = tokenLine();
994         consumeOrFail(CLOSEPAREN);
995         const Identifier* unused = 0;
996         TreeStatement innerTrueBlock = parseStatement(context, unused);
997         failIfFalse(innerTrueBlock);     
998         exprStack.append(innerCondition);
999         posStack.append(make_pair(innerStart, innerEnd));
1000         statementStack.append(innerTrueBlock);
1001     } while (match(ELSE));
1002     
1003     if (!trailingElse) {
1004         TreeExpression condition = exprStack.last();
1005         exprStack.removeLast();
1006         TreeStatement trueBlock = statementStack.last();
1007         statementStack.removeLast();
1008         pair<int, int> pos = posStack.last();
1009         posStack.removeLast();
1010         statementStack.append(context.createIfStatement(m_lexer->lastLineNumber(), condition, trueBlock, pos.first, pos.second));
1011     }
1012     
1013     while (!exprStack.isEmpty()) {
1014         TreeExpression condition = exprStack.last();
1015         exprStack.removeLast();
1016         TreeStatement falseBlock = statementStack.last();
1017         statementStack.removeLast();
1018         TreeStatement trueBlock = statementStack.last();
1019         statementStack.removeLast();
1020         pair<int, int> pos = posStack.last();
1021         posStack.removeLast();
1022         statementStack.append(context.createIfStatement(m_lexer->lastLineNumber(), condition, trueBlock, falseBlock, pos.first, pos.second));
1023     }
1024     
1025     return context.createIfStatement(m_lexer->lastLineNumber(), condition, trueBlock, statementStack.last(), start, end);
1026 }
1027
1028 template <typename LexerType>
1029 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseExpression(TreeBuilder& context)
1030 {
1031     failIfStackOverflow();
1032     TreeExpression node = parseAssignmentExpression(context);
1033     failIfFalse(node);
1034     if (!match(COMMA))
1035         return node;
1036     next();
1037     m_nonTrivialExpressionCount++;
1038     m_nonLHSCount++;
1039     TreeExpression right = parseAssignmentExpression(context);
1040     failIfFalse(right);
1041     typename TreeBuilder::Comma commaNode = context.createCommaExpr(m_lexer->lastLineNumber(), node, right);
1042     while (match(COMMA)) {
1043         next(TreeBuilder::DontBuildStrings);
1044         right = parseAssignmentExpression(context);
1045         failIfFalse(right);
1046         context.appendToComma(commaNode, right);
1047     }
1048     return commaNode;
1049 }
1050
1051 template <typename LexerType>
1052 template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmentExpression(TreeBuilder& context)
1053 {
1054     failIfStackOverflow();
1055     int start = tokenStart();
1056     int initialAssignmentCount = m_assignmentCount;
1057     int initialNonLHSCount = m_nonLHSCount;
1058     TreeExpression lhs = parseConditionalExpression(context);
1059     failIfFalse(lhs);
1060     if (initialNonLHSCount != m_nonLHSCount)
1061         return lhs;
1062     
1063     int assignmentStack = 0;
1064     Operator op;
1065     bool hadAssignment = false;
1066     while (true) {
1067         switch (m_token.m_type) {
1068         case EQUAL: op = OpEqual; break;
1069         case PLUSEQUAL: op = OpPlusEq; break;
1070         case MINUSEQUAL: op = OpMinusEq; break;
1071         case MULTEQUAL: op = OpMultEq; break;
1072         case DIVEQUAL: op = OpDivEq; break;
1073         case LSHIFTEQUAL: op = OpLShift; break;
1074         case RSHIFTEQUAL: op = OpRShift; break;
1075         case URSHIFTEQUAL: op = OpURShift; break;
1076         case ANDEQUAL: op = OpAndEq; break;
1077         case XOREQUAL: op = OpXOrEq; break;
1078         case OREQUAL: op = OpOrEq; break;
1079         case MODEQUAL: op = OpModEq; break;
1080         default:
1081             goto end;
1082         }
1083         m_nonTrivialExpressionCount++;
1084         hadAssignment = true;
1085         context.assignmentStackAppend(assignmentStack, lhs, start, tokenStart(), m_assignmentCount, op);
1086         start = tokenStart();
1087         m_assignmentCount++;
1088         next(TreeBuilder::DontBuildStrings);
1089         if (strictMode() && m_lastIdentifier && context.isResolve(lhs)) {
1090             failIfTrueIfStrictWithMessage(m_globalData->propertyNames->eval == *m_lastIdentifier, "'eval' cannot be modified in strict mode");
1091             failIfTrueIfStrictWithMessage(m_globalData->propertyNames->arguments == *m_lastIdentifier, "'arguments' cannot be modified in strict mode");
1092             declareWrite(m_lastIdentifier);
1093             m_lastIdentifier = 0;
1094         }
1095         lhs = parseConditionalExpression(context);
1096         failIfFalse(lhs);
1097         if (initialNonLHSCount != m_nonLHSCount)
1098             break;
1099     }
1100 end:
1101     if (hadAssignment)
1102         m_nonLHSCount++;
1103     
1104     if (!TreeBuilder::CreatesAST)
1105         return lhs;
1106     
1107     while (assignmentStack)
1108         lhs = context.createAssignment(m_lexer->lastLineNumber(), assignmentStack, lhs, initialAssignmentCount, m_assignmentCount, lastTokenEnd());
1109     
1110     return lhs;
1111 }
1112
1113 template <typename LexerType>
1114 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseConditionalExpression(TreeBuilder& context)
1115 {
1116     TreeExpression cond = parseBinaryExpression(context);
1117     failIfFalse(cond);
1118     if (!match(QUESTION))
1119         return cond;
1120     m_nonTrivialExpressionCount++;
1121     m_nonLHSCount++;
1122     next(TreeBuilder::DontBuildStrings);
1123     TreeExpression lhs = parseAssignmentExpression(context);
1124     consumeOrFailWithFlags(COLON, TreeBuilder::DontBuildStrings);
1125     
1126     TreeExpression rhs = parseAssignmentExpression(context);
1127     failIfFalse(rhs);
1128     return context.createConditionalExpr(m_lexer->lastLineNumber(), cond, lhs, rhs);
1129 }
1130
1131 ALWAYS_INLINE static bool isUnaryOp(JSTokenType token)
1132 {
1133     return token & UnaryOpTokenFlag;
1134 }
1135
1136 template <typename LexerType>
1137 int Parser<LexerType>::isBinaryOperator(JSTokenType token)
1138 {
1139     if (m_allowsIn)
1140         return token & (BinaryOpTokenPrecedenceMask << BinaryOpTokenAllowsInPrecedenceAdditionalShift);
1141     return token & BinaryOpTokenPrecedenceMask;
1142 }
1143
1144 template <typename LexerType>
1145 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseBinaryExpression(TreeBuilder& context)
1146 {
1147     
1148     int operandStackDepth = 0;
1149     int operatorStackDepth = 0;
1150     typename TreeBuilder::BinaryExprContext binaryExprContext(context);
1151     while (true) {
1152         int exprStart = tokenStart();
1153         int initialAssignments = m_assignmentCount;
1154         TreeExpression current = parseUnaryExpression(context);
1155         failIfFalse(current);
1156         
1157         context.appendBinaryExpressionInfo(operandStackDepth, current, exprStart, lastTokenEnd(), lastTokenEnd(), initialAssignments != m_assignmentCount);
1158         int precedence = isBinaryOperator(m_token.m_type);
1159         if (!precedence)
1160             break;
1161         m_nonTrivialExpressionCount++;
1162         m_nonLHSCount++;
1163         int operatorToken = m_token.m_type;
1164         next(TreeBuilder::DontBuildStrings);
1165         
1166         while (operatorStackDepth &&  context.operatorStackHasHigherPrecedence(operatorStackDepth, precedence)) {
1167             ASSERT(operandStackDepth > 1);
1168             
1169             typename TreeBuilder::BinaryOperand rhs = context.getFromOperandStack(-1);
1170             typename TreeBuilder::BinaryOperand lhs = context.getFromOperandStack(-2);
1171             context.shrinkOperandStackBy(operandStackDepth, 2);
1172             context.appendBinaryOperation(m_lexer->lastLineNumber(), operandStackDepth, operatorStackDepth, lhs, rhs);
1173             context.operatorStackPop(operatorStackDepth);
1174         }
1175         context.operatorStackAppend(operatorStackDepth, operatorToken, precedence);
1176     }
1177     while (operatorStackDepth) {
1178         ASSERT(operandStackDepth > 1);
1179         
1180         typename TreeBuilder::BinaryOperand rhs = context.getFromOperandStack(-1);
1181         typename TreeBuilder::BinaryOperand lhs = context.getFromOperandStack(-2);
1182         context.shrinkOperandStackBy(operandStackDepth, 2);
1183         context.appendBinaryOperation(m_lexer->lastLineNumber(), operandStackDepth, operatorStackDepth, lhs, rhs);
1184         context.operatorStackPop(operatorStackDepth);
1185     }
1186     return context.popOperandStack(operandStackDepth);
1187 }
1188
1189 template <typename LexerType>
1190 template <bool complete, class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeBuilder& context)
1191 {
1192     bool wasIdent = false;
1193     switch (m_token.m_type) {
1194     namedProperty:
1195     case IDENT:
1196         wasIdent = true;
1197     case STRING: {
1198         const Identifier* ident = m_token.m_data.ident;
1199         if (complete || (wasIdent && (*ident == m_globalData->propertyNames->get || *ident == m_globalData->propertyNames->set)))
1200             nextExpectIdentifier(LexerFlagsIgnoreReservedWords);
1201         else
1202             nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
1203         
1204         if (match(COLON)) {
1205             next();
1206             TreeExpression node = parseAssignmentExpression(context);
1207             failIfFalse(node);
1208             return context.template createProperty<complete>(ident, node, PropertyNode::Constant);
1209         }
1210         failIfFalse(wasIdent);
1211         matchOrFail(IDENT);
1212         const Identifier* accessorName = 0;
1213         TreeFormalParameterList parameters = 0;
1214         TreeFunctionBody body = 0;
1215         int openBracePos = 0;
1216         int closeBracePos = 0;
1217         int bodyStartLine = 0;
1218         PropertyNode::Type type;
1219         if (*ident == m_globalData->propertyNames->get)
1220             type = PropertyNode::Getter;
1221         else if (*ident == m_globalData->propertyNames->set)
1222             type = PropertyNode::Setter;
1223         else
1224             fail();
1225         failIfFalse((parseFunctionInfo<FunctionNeedsName, false>(context, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
1226         return context.template createGetterOrSetterProperty<complete>(m_lexer->lastLineNumber(), type, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
1227     }
1228     case NUMBER: {
1229         double propertyName = m_token.m_data.doubleValue;
1230         next();
1231         consumeOrFail(COLON);
1232         TreeExpression node = parseAssignmentExpression(context);
1233         failIfFalse(node);
1234         return context.template createProperty<complete>(const_cast<JSGlobalData*>(m_globalData), propertyName, node, PropertyNode::Constant);
1235     }
1236     default:
1237         failIfFalse(m_token.m_type & KeywordTokenFlag);
1238         goto namedProperty;
1239     }
1240 }
1241
1242 template <typename LexerType>
1243 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseObjectLiteral(TreeBuilder& context)
1244 {
1245     int startOffset = m_token.m_data.intValue;
1246     consumeOrFailWithFlags(OPENBRACE, TreeBuilder::DontBuildStrings);
1247     
1248     if (match(CLOSEBRACE)) {
1249         next();
1250         return context.createObjectLiteral(m_lexer->lastLineNumber());
1251     }
1252     
1253     TreeProperty property = parseProperty<false>(context);
1254     failIfFalse(property);
1255     if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) {
1256         m_lexer->setOffset(startOffset);
1257         next();
1258         return parseStrictObjectLiteral(context);
1259     }
1260     TreePropertyList propertyList = context.createPropertyList(m_lexer->lastLineNumber(), property);
1261     TreePropertyList tail = propertyList;
1262     while (match(COMMA)) {
1263         next(TreeBuilder::DontBuildStrings);
1264         // allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939
1265         if (match(CLOSEBRACE))
1266             break;
1267         property = parseProperty<false>(context);
1268         failIfFalse(property);
1269         if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) {
1270             m_lexer->setOffset(startOffset);
1271             next();
1272             return parseStrictObjectLiteral(context);
1273         }
1274         tail = context.createPropertyList(m_lexer->lastLineNumber(), property, tail);
1275     }
1276     
1277     consumeOrFail(CLOSEBRACE);
1278     
1279     return context.createObjectLiteral(m_lexer->lastLineNumber(), propertyList);
1280 }
1281
1282 template <typename LexerType>
1283 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseStrictObjectLiteral(TreeBuilder& context)
1284 {
1285     consumeOrFail(OPENBRACE);
1286     
1287     if (match(CLOSEBRACE)) {
1288         next();
1289         return context.createObjectLiteral(m_lexer->lastLineNumber());
1290     }
1291     
1292     TreeProperty property = parseProperty<true>(context);
1293     failIfFalse(property);
1294     
1295     typedef HashMap<RefPtr<StringImpl>, unsigned, IdentifierRepHash> ObjectValidationMap;
1296     ObjectValidationMap objectValidator;
1297     // Add the first property
1298     if (!m_syntaxAlreadyValidated)
1299         objectValidator.add(context.getName(property).impl(), context.getType(property));
1300     
1301     TreePropertyList propertyList = context.createPropertyList(m_lexer->lastLineNumber(), property);
1302     TreePropertyList tail = propertyList;
1303     while (match(COMMA)) {
1304         next();
1305         // allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939
1306         if (match(CLOSEBRACE))
1307             break;
1308         property = parseProperty<true>(context);
1309         failIfFalse(property);
1310         if (!m_syntaxAlreadyValidated) {
1311             std::pair<ObjectValidationMap::iterator, bool> propertyEntryIter = objectValidator.add(context.getName(property).impl(), context.getType(property));
1312             if (!propertyEntryIter.second) {
1313                 failIfTrue(propertyEntryIter.first->second == PropertyNode::Constant);
1314                 failIfTrue(context.getType(property) == PropertyNode::Constant);
1315                 failIfTrue(context.getType(property) & propertyEntryIter.first->second);
1316                 propertyEntryIter.first->second |= context.getType(property);
1317             }
1318         }
1319         tail = context.createPropertyList(m_lexer->lastLineNumber(), property, tail);
1320     }
1321     
1322     consumeOrFail(CLOSEBRACE);
1323     
1324     return context.createObjectLiteral(m_lexer->lastLineNumber(), propertyList);
1325 }
1326
1327 template <typename LexerType>
1328 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrayLiteral(TreeBuilder& context)
1329 {
1330     consumeOrFailWithFlags(OPENBRACKET, TreeBuilder::DontBuildStrings);
1331     
1332     int elisions = 0;
1333     while (match(COMMA)) {
1334         next(TreeBuilder::DontBuildStrings);
1335         elisions++;
1336     }
1337     if (match(CLOSEBRACKET)) {
1338         next(TreeBuilder::DontBuildStrings);
1339         return context.createArray(m_lexer->lastLineNumber(), elisions);
1340     }
1341     
1342     TreeExpression elem = parseAssignmentExpression(context);
1343     failIfFalse(elem);
1344     typename TreeBuilder::ElementList elementList = context.createElementList(elisions, elem);
1345     typename TreeBuilder::ElementList tail = elementList;
1346     elisions = 0;
1347     while (match(COMMA)) {
1348         next(TreeBuilder::DontBuildStrings);
1349         elisions = 0;
1350         
1351         while (match(COMMA)) {
1352             next();
1353             elisions++;
1354         }
1355         
1356         if (match(CLOSEBRACKET)) {
1357             next(TreeBuilder::DontBuildStrings);
1358             return context.createArray(m_lexer->lastLineNumber(), elisions, elementList);
1359         }
1360         TreeExpression elem = parseAssignmentExpression(context);
1361         failIfFalse(elem);
1362         tail = context.createElementList(tail, elisions, elem);
1363     }
1364     
1365     consumeOrFail(CLOSEBRACKET);
1366     
1367     return context.createArray(m_lexer->lastLineNumber(), elementList);
1368 }
1369
1370 template <typename LexerType>
1371 template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpression(TreeBuilder& context)
1372 {
1373     failIfStackOverflow();
1374     switch (m_token.m_type) {
1375     case OPENBRACE:
1376         if (strictMode())
1377             return parseStrictObjectLiteral(context);
1378         return parseObjectLiteral(context);
1379     case OPENBRACKET:
1380         return parseArrayLiteral(context);
1381     case OPENPAREN: {
1382         next();
1383         int oldNonLHSCount = m_nonLHSCount;
1384         TreeExpression result = parseExpression(context);
1385         m_nonLHSCount = oldNonLHSCount;
1386         consumeOrFail(CLOSEPAREN);
1387         
1388         return result;
1389     }
1390     case THISTOKEN: {
1391         next();
1392         return context.thisExpr(m_lexer->lastLineNumber());
1393     }
1394     case IDENT: {
1395         int start = tokenStart();
1396         const Identifier* ident = m_token.m_data.ident;
1397         next();
1398         currentScope()->useVariable(ident, m_globalData->propertyNames->eval == *ident);
1399         m_lastIdentifier = ident;
1400         return context.createResolve(m_lexer->lastLineNumber(), ident, start);
1401     }
1402     case STRING: {
1403         const Identifier* ident = m_token.m_data.ident;
1404         next();
1405         return context.createString(m_lexer->lastLineNumber(), ident);
1406     }
1407     case NUMBER: {
1408         double d = m_token.m_data.doubleValue;
1409         next();
1410         return context.createNumberExpr(m_lexer->lastLineNumber(), d);
1411     }
1412     case NULLTOKEN: {
1413         next();
1414         return context.createNull(m_lexer->lastLineNumber());
1415     }
1416     case TRUETOKEN: {
1417         next();
1418         return context.createBoolean(m_lexer->lastLineNumber(), true);
1419     }
1420     case FALSETOKEN: {
1421         next();
1422         return context.createBoolean(m_lexer->lastLineNumber(), false);
1423     }
1424     case DIVEQUAL:
1425     case DIVIDE: {
1426         /* regexp */
1427         const Identifier* pattern;
1428         const Identifier* flags;
1429         if (match(DIVEQUAL))
1430             failIfFalse(m_lexer->scanRegExp(pattern, flags, '='));
1431         else
1432             failIfFalse(m_lexer->scanRegExp(pattern, flags));
1433         
1434         int start = tokenStart();
1435         next();
1436         TreeExpression re = context.createRegExp(m_lexer->lastLineNumber(), *pattern, *flags, start);
1437         if (!re) {
1438             const char* yarrErrorMsg = Yarr::checkSyntax(pattern->ustring());
1439             ASSERT(!m_errorMessage.isNull());
1440             failWithMessage(yarrErrorMsg);
1441         }
1442         return re;
1443     }
1444     default:
1445         fail();
1446     }
1447 }
1448
1449 template <typename LexerType>
1450 template <class TreeBuilder> TreeArguments Parser<LexerType>::parseArguments(TreeBuilder& context)
1451 {
1452     consumeOrFailWithFlags(OPENPAREN, TreeBuilder::DontBuildStrings);
1453     if (match(CLOSEPAREN)) {
1454         next(TreeBuilder::DontBuildStrings);
1455         return context.createArguments();
1456     }
1457     TreeExpression firstArg = parseAssignmentExpression(context);
1458     failIfFalse(firstArg);
1459     
1460     TreeArgumentsList argList = context.createArgumentsList(m_lexer->lastLineNumber(), firstArg);
1461     TreeArgumentsList tail = argList;
1462     while (match(COMMA)) {
1463         next(TreeBuilder::DontBuildStrings);
1464         TreeExpression arg = parseAssignmentExpression(context);
1465         failIfFalse(arg);
1466         tail = context.createArgumentsList(m_lexer->lastLineNumber(), tail, arg);
1467     }
1468     consumeOrFail(CLOSEPAREN);
1469     return context.createArguments(argList);
1470 }
1471
1472 template <typename LexerType>
1473 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpression(TreeBuilder& context)
1474 {
1475     TreeExpression base = 0;
1476     int start = tokenStart();
1477     int expressionStart = start;
1478     int newCount = 0;
1479     while (match(NEW)) {
1480         next();
1481         newCount++;
1482     }
1483     
1484     if (match(FUNCTION)) {
1485         const Identifier* name = &m_globalData->propertyNames->nullIdentifier;
1486         TreeFormalParameterList parameters = 0;
1487         TreeFunctionBody body = 0;
1488         int openBracePos = 0;
1489         int closeBracePos = 0;
1490         int bodyStartLine = 0;
1491         next();
1492         failIfFalse((parseFunctionInfo<FunctionNoRequirements, false>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
1493         base = context.createFunctionExpr(m_lexer->lastLineNumber(), name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
1494     } else
1495         base = parsePrimaryExpression(context);
1496     
1497     failIfFalse(base);
1498     while (true) {
1499         switch (m_token.m_type) {
1500         case OPENBRACKET: {
1501             m_nonTrivialExpressionCount++;
1502             int expressionEnd = lastTokenEnd();
1503             next();
1504             int nonLHSCount = m_nonLHSCount;
1505             int initialAssignments = m_assignmentCount;
1506             TreeExpression property = parseExpression(context);
1507             failIfFalse(property);
1508             base = context.createBracketAccess(m_lexer->lastLineNumber(), base, property, initialAssignments != m_assignmentCount, expressionStart, expressionEnd, tokenEnd());
1509             consumeOrFail(CLOSEBRACKET);
1510             m_nonLHSCount = nonLHSCount;
1511             break;
1512         }
1513         case OPENPAREN: {
1514             m_nonTrivialExpressionCount++;
1515             int nonLHSCount = m_nonLHSCount;
1516             if (newCount) {
1517                 newCount--;
1518                 int exprEnd = lastTokenEnd();
1519                 TreeArguments arguments = parseArguments(context);
1520                 failIfFalse(arguments);
1521                 base = context.createNewExpr(m_lexer->lastLineNumber(), base, arguments, start, exprEnd, lastTokenEnd());           
1522             } else {
1523                 int expressionEnd = lastTokenEnd();
1524                 TreeArguments arguments = parseArguments(context);
1525                 failIfFalse(arguments);
1526                 base = context.makeFunctionCallNode(m_lexer->lastLineNumber(), base, arguments, expressionStart, expressionEnd, lastTokenEnd());
1527             }
1528             m_nonLHSCount = nonLHSCount;
1529             break;
1530         }
1531         case DOT: {
1532             m_nonTrivialExpressionCount++;
1533             int expressionEnd = lastTokenEnd();
1534             nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
1535             matchOrFail(IDENT);
1536             base = context.createDotAccess(m_lexer->lastLineNumber(), base, m_token.m_data.ident, expressionStart, expressionEnd, tokenEnd());
1537             next();
1538             break;
1539         }
1540         default:
1541             goto endMemberExpression;
1542         }
1543     }
1544 endMemberExpression:
1545     while (newCount--)
1546         base = context.createNewExpr(m_lexer->lastLineNumber(), base, start, lastTokenEnd());
1547     return base;
1548 }
1549
1550 template <typename LexerType>
1551 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpression(TreeBuilder& context)
1552 {
1553     typename TreeBuilder::UnaryExprContext unaryExprContext(context);
1554     AllowInOverride allowInOverride(this);
1555     int tokenStackDepth = 0;
1556     bool modifiesExpr = false;
1557     bool requiresLExpr = false;
1558     while (isUnaryOp(m_token.m_type)) {
1559         if (strictMode()) {
1560             switch (m_token.m_type) {
1561             case PLUSPLUS:
1562             case MINUSMINUS:
1563             case AUTOPLUSPLUS:
1564             case AUTOMINUSMINUS:
1565                 failIfTrue(requiresLExpr);
1566                 modifiesExpr = true;
1567                 requiresLExpr = true;
1568                 break;
1569             case DELETETOKEN:
1570                 failIfTrue(requiresLExpr);
1571                 requiresLExpr = true;
1572                 break;
1573             default:
1574                 failIfTrue(requiresLExpr);
1575                 break;
1576             }
1577         }
1578         m_nonLHSCount++;
1579         context.appendUnaryToken(tokenStackDepth, m_token.m_type, tokenStart());
1580         next();
1581         m_nonTrivialExpressionCount++;
1582     }
1583     int subExprStart = tokenStart();
1584     TreeExpression expr = parseMemberExpression(context);
1585     failIfFalse(expr);
1586     bool isEvalOrArguments = false;
1587     if (strictMode() && !m_syntaxAlreadyValidated) {
1588         if (context.isResolve(expr))
1589             isEvalOrArguments = *m_lastIdentifier == m_globalData->propertyNames->eval || *m_lastIdentifier == m_globalData->propertyNames->arguments;
1590     }
1591     failIfTrueIfStrictWithNameAndMessage(isEvalOrArguments && modifiesExpr, "'", m_lastIdentifier->impl(), "' cannot be modified in strict mode");
1592     switch (m_token.m_type) {
1593     case PLUSPLUS:
1594         m_nonTrivialExpressionCount++;
1595         m_nonLHSCount++;
1596         expr = context.makePostfixNode(m_lexer->lastLineNumber(), expr, OpPlusPlus, subExprStart, lastTokenEnd(), tokenEnd());
1597         m_assignmentCount++;
1598         failIfTrueIfStrictWithNameAndMessage(isEvalOrArguments, "'", m_lastIdentifier->impl(), "' cannot be modified in strict mode");
1599         failIfTrueIfStrict(requiresLExpr);
1600         next();
1601         break;
1602     case MINUSMINUS:
1603         m_nonTrivialExpressionCount++;
1604         m_nonLHSCount++;
1605         expr = context.makePostfixNode(m_lexer->lastLineNumber(), expr, OpMinusMinus, subExprStart, lastTokenEnd(), tokenEnd());
1606         m_assignmentCount++;
1607         failIfTrueIfStrictWithNameAndMessage(isEvalOrArguments, "'", m_lastIdentifier->impl(), "' cannot be modified in strict mode");
1608         failIfTrueIfStrict(requiresLExpr);
1609         next();
1610         break;
1611     default:
1612         break;
1613     }
1614     
1615     int end = lastTokenEnd();
1616     
1617     if (!TreeBuilder::CreatesAST && (m_syntaxAlreadyValidated || !strictMode()))
1618         return expr;
1619     
1620     while (tokenStackDepth) {
1621         switch (context.unaryTokenStackLastType(tokenStackDepth)) {
1622         case EXCLAMATION:
1623             expr = context.createLogicalNot(m_lexer->lastLineNumber(), expr);
1624             break;
1625         case TILDE:
1626             expr = context.makeBitwiseNotNode(m_lexer->lastLineNumber(), expr);
1627             break;
1628         case MINUS:
1629             expr = context.makeNegateNode(m_lexer->lastLineNumber(), expr);
1630             break;
1631         case PLUS:
1632             expr = context.createUnaryPlus(m_lexer->lastLineNumber(), expr);
1633             break;
1634         case PLUSPLUS:
1635         case AUTOPLUSPLUS:
1636             expr = context.makePrefixNode(m_lexer->lastLineNumber(), expr, OpPlusPlus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
1637             m_assignmentCount++;
1638             break;
1639         case MINUSMINUS:
1640         case AUTOMINUSMINUS:
1641             expr = context.makePrefixNode(m_lexer->lastLineNumber(), expr, OpMinusMinus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
1642             m_assignmentCount++;
1643             break;
1644         case TYPEOF:
1645             expr = context.makeTypeOfNode(m_lexer->lastLineNumber(), expr);
1646             break;
1647         case VOIDTOKEN:
1648             expr = context.createVoid(m_lexer->lastLineNumber(), expr);
1649             break;
1650         case DELETETOKEN:
1651             failIfTrueIfStrictWithNameAndMessage(context.isResolve(expr), "Cannot delete unqualified property", m_lastIdentifier->impl(), "in strict mode");
1652             expr = context.makeDeleteNode(m_lexer->lastLineNumber(), expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end);
1653             break;
1654         default:
1655             // If we get here something has gone horribly horribly wrong
1656             CRASH();
1657         }
1658         subExprStart = context.unaryTokenStackLastStart(tokenStackDepth);
1659         context.unaryTokenStackRemoveLast(tokenStackDepth);
1660     }
1661     return expr;
1662 }
1663
1664 // Instantiate the two flavors of Parser we need instead of putting most of this file in Parser.h
1665 template class Parser< Lexer<LChar> >;
1666 template class Parser< Lexer<UChar> >;
1667
1668 } // namespace JSC