calling function on catch block scope containing an eval result in wrong this value...
[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     TreeStatement catchBlock = 0;
607     TreeStatement finallyBlock = 0;
608     int firstLine = tokenLine();
609     next();
610     matchOrFail(OPENBRACE);
611     
612     tryBlock = parseBlockStatement(context);
613     failIfFalse(tryBlock);
614     int lastLine = m_lastLine;
615     
616     if (match(CATCH)) {
617         currentScope()->setNeedsFullActivation();
618         next();
619         consumeOrFail(OPENPAREN);
620         matchOrFail(IDENT);
621         ident = m_token.m_data.ident;
622         next();
623         AutoPopScopeRef catchScope(this, pushScope());
624         failIfFalseIfStrictWithNameAndMessage(declareVariable(ident), "Cannot declare a variable named", ident->impl(), "in strict mode");
625         catchScope->preventNewDecls();
626         consumeOrFail(CLOSEPAREN);
627         matchOrFail(OPENBRACE);
628         catchBlock = parseBlockStatement(context);
629         failIfFalseWithMessage(catchBlock, "'try' must have a catch or finally block");
630         failIfFalse(popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo));
631     }
632     
633     if (match(FINALLY)) {
634         next();
635         matchOrFail(OPENBRACE);
636         finallyBlock = parseBlockStatement(context);
637         failIfFalse(finallyBlock);
638     }
639     failIfFalse(catchBlock || finallyBlock);
640     return context.createTryStatement(m_lexer->lastLineNumber(), tryBlock, ident, catchBlock, finallyBlock, firstLine, lastLine);
641 }
642
643 template <typename LexerType>
644 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseDebuggerStatement(TreeBuilder& context)
645 {
646     ASSERT(match(DEBUGGER));
647     int startLine = tokenLine();
648     int endLine = startLine;
649     next();
650     if (match(SEMICOLON))
651         startLine = tokenLine();
652     failIfFalse(autoSemiColon());
653     return context.createDebugger(m_lexer->lastLineNumber(), startLine, endLine);
654 }
655
656 template <typename LexerType>
657 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseBlockStatement(TreeBuilder& context)
658 {
659     ASSERT(match(OPENBRACE));
660     int start = tokenLine();
661     next();
662     if (match(CLOSEBRACE)) {
663         next();
664         return context.createBlockStatement(m_lexer->lastLineNumber(), 0, start, m_lastLine);
665     }
666     TreeSourceElements subtree = parseSourceElements<DontCheckForStrictMode>(context);
667     failIfFalse(subtree);
668     matchOrFail(CLOSEBRACE);
669     next();
670     return context.createBlockStatement(m_lexer->lastLineNumber(), subtree, start, m_lastLine);
671 }
672
673 template <typename LexerType>
674 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseStatement(TreeBuilder& context, const Identifier*& directive, unsigned* directiveLiteralLength)
675 {
676     DepthManager statementDepth(&m_statementDepth);
677     m_statementDepth++;
678     directive = 0;
679     int nonTrivialExpressionCount = 0;
680     failIfStackOverflow();
681     switch (m_token.m_type) {
682     case OPENBRACE:
683         return parseBlockStatement(context);
684     case VAR:
685         return parseVarDeclaration(context);
686     case CONSTTOKEN:
687         return parseConstDeclaration(context);
688     case FUNCTION:
689         failIfFalseIfStrictWithMessage(m_statementDepth == 1, "Functions cannot be declared in a nested block in strict mode");
690         return parseFunctionDeclaration(context);
691     case SEMICOLON:
692         next();
693         return context.createEmptyStatement(m_lexer->lastLineNumber());
694     case IF:
695         return parseIfStatement(context);
696     case DO:
697         return parseDoWhileStatement(context);
698     case WHILE:
699         return parseWhileStatement(context);
700     case FOR:
701         return parseForStatement(context);
702     case CONTINUE:
703         return parseContinueStatement(context);
704     case BREAK:
705         return parseBreakStatement(context);
706     case RETURN:
707         return parseReturnStatement(context);
708     case WITH:
709         return parseWithStatement(context);
710     case SWITCH:
711         return parseSwitchStatement(context);
712     case THROW:
713         return parseThrowStatement(context);
714     case TRY:
715         return parseTryStatement(context);
716     case DEBUGGER:
717         return parseDebuggerStatement(context);
718     case EOFTOK:
719     case CASE:
720     case CLOSEBRACE:
721     case DEFAULT:
722         // These tokens imply the end of a set of source elements
723         return 0;
724     case IDENT:
725         return parseExpressionOrLabelStatement(context);
726     case STRING:
727         directive = m_token.m_data.ident;
728         if (directiveLiteralLength)
729             *directiveLiteralLength = m_token.m_info.endOffset - m_token.m_info.startOffset;
730         nonTrivialExpressionCount = m_nonTrivialExpressionCount;
731     default:
732         TreeStatement exprStatement = parseExpressionStatement(context);
733         if (directive && nonTrivialExpressionCount != m_nonTrivialExpressionCount)
734             directive = 0;
735         return exprStatement;
736     }
737 }
738
739 template <typename LexerType>
740 template <class TreeBuilder> TreeFormalParameterList Parser<LexerType>::parseFormalParameters(TreeBuilder& context)
741 {
742     matchOrFail(IDENT);
743     failIfFalseIfStrictWithNameAndMessage(declareParameter(m_token.m_data.ident), "Cannot declare a parameter named", m_token.m_data.ident->impl(), " in strict mode");
744     TreeFormalParameterList list = context.createFormalParameterList(*m_token.m_data.ident);
745     TreeFormalParameterList tail = list;
746     next();
747     while (match(COMMA)) {
748         next();
749         matchOrFail(IDENT);
750         const Identifier* ident = m_token.m_data.ident;
751         failIfFalseIfStrictWithNameAndMessage(declareParameter(ident), "Cannot declare a parameter named", ident->impl(), "in strict mode");
752         next();
753         tail = context.createFormalParameterList(tail, *ident);
754     }
755     return list;
756 }
757
758 template <typename LexerType>
759 template <class TreeBuilder> TreeFunctionBody Parser<LexerType>::parseFunctionBody(TreeBuilder& context)
760 {
761     if (match(CLOSEBRACE))
762         return context.createFunctionBody(m_lexer->lastLineNumber(), strictMode());
763     DepthManager statementDepth(&m_statementDepth);
764     m_statementDepth = 0;
765     typename TreeBuilder::FunctionBodyBuilder bodyBuilder(const_cast<JSGlobalData*>(m_globalData), m_lexer.get());
766     failIfFalse(parseSourceElements<CheckForStrictMode>(bodyBuilder));
767     return context.createFunctionBody(m_lexer->lastLineNumber(), strictMode());
768 }
769
770 template <typename LexerType>
771 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)
772 {
773     AutoPopScopeRef functionScope(this, pushScope());
774     functionScope->setIsFunction();
775     if (match(IDENT)) {
776         name = m_token.m_data.ident;
777         failIfTrueWithMessage(*name == m_globalData->propertyNames->underscoreProto, "Cannot name a function __proto__");
778         next();
779         if (!nameIsInContainingScope)
780             failIfFalseIfStrict(functionScope->declareVariable(name));
781     } else if (requirements == FunctionNeedsName)
782         return false;
783     consumeOrFail(OPENPAREN);
784     if (!match(CLOSEPAREN)) {
785         parameters = parseFormalParameters(context);
786         failIfFalse(parameters);
787     }
788     consumeOrFail(CLOSEPAREN);
789     matchOrFail(OPENBRACE);
790     
791     openBracePos = m_token.m_data.intValue;
792     bodyStartLine = tokenLine();
793     
794     // If we know about this function already, we can use the cached info and skip the parser to the end of the function.
795     if (const SourceProviderCacheItem* cachedInfo = TreeBuilder::CanUseFunctionCache ? findCachedFunctionInfo(openBracePos) : 0) {
796         // If we're in a strict context, the cached function info must say it was strict too.
797         ASSERT(!strictMode() || cachedInfo->strictMode);
798         body = context.createFunctionBody(m_lexer->lastLineNumber(), cachedInfo->strictMode);
799         
800         functionScope->restoreFunctionInfo(cachedInfo);
801         failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo));
802         
803         closeBracePos = cachedInfo->closeBracePos;
804         m_token = cachedInfo->closeBraceToken();
805         m_lexer->setOffset(m_token.m_info.endOffset);
806         m_lexer->setLineNumber(m_token.m_info.line);
807         
808         next();
809         return true;
810     }
811     
812     next();
813     
814     body = parseFunctionBody(context);
815     failIfFalse(body);
816     if (functionScope->strictMode() && name) {
817         failIfTrueWithNameAndMessage(m_globalData->propertyNames->arguments == *name, "Function name", name->impl(), "is not valid in strict mode");
818         failIfTrueWithNameAndMessage(m_globalData->propertyNames->eval == *name, "Function name", name->impl(), "is not valid in strict mode");
819     }
820     closeBracePos = m_token.m_data.intValue;
821     
822     // Cache the tokenizer state and the function scope the first time the function is parsed.
823     // Any future reparsing can then skip the function.
824     static const int minimumFunctionLengthToCache = 64;
825     OwnPtr<SourceProviderCacheItem> newInfo;
826     int functionLength = closeBracePos - openBracePos;
827     if (TreeBuilder::CanUseFunctionCache && m_functionCache && functionLength > minimumFunctionLengthToCache) {
828         newInfo = adoptPtr(new SourceProviderCacheItem(m_token.m_info.line, closeBracePos));
829         functionScope->saveFunctionInfo(newInfo.get());
830     }
831     
832     failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo));
833     matchOrFail(CLOSEBRACE);
834     
835     if (newInfo) {
836         unsigned approximateByteSize = newInfo->approximateByteSize();
837         m_functionCache->add(openBracePos, newInfo.release(), approximateByteSize);
838     }
839     
840     next();
841     return true;
842 }
843
844 template <typename LexerType>
845 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseFunctionDeclaration(TreeBuilder& context)
846 {
847     ASSERT(match(FUNCTION));
848     next();
849     const Identifier* name = 0;
850     TreeFormalParameterList parameters = 0;
851     TreeFunctionBody body = 0;
852     int openBracePos = 0;
853     int closeBracePos = 0;
854     int bodyStartLine = 0;
855     failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
856     failIfFalse(name);
857     failIfFalseIfStrict(declareVariable(name));
858     return context.createFuncDeclStatement(m_lexer->lastLineNumber(), name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
859 }
860
861 struct LabelInfo {
862     LabelInfo(const Identifier* ident, int start, int end)
863     : m_ident(ident)
864     , m_start(start)
865     , m_end(end)
866     {
867     }
868     
869     const Identifier* m_ident;
870     int m_start;
871     int m_end;
872 };
873
874 template <typename LexerType>
875 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionOrLabelStatement(TreeBuilder& context)
876 {
877     
878     /* Expression and Label statements are ambiguous at LL(1), so we have a
879      * special case that looks for a colon as the next character in the input.
880      */
881     Vector<LabelInfo> labels;
882     
883     do {
884         int start = tokenStart();
885         int startLine = tokenLine();
886         if (!nextTokenIsColon()) {
887             // If we hit this path we're making a expression statement, which
888             // by definition can't make use of continue/break so we can just
889             // ignore any labels we might have accumulated.
890             TreeExpression expression = parseExpression(context);
891             failIfFalse(expression);
892             failIfFalse(autoSemiColon());
893             return context.createExprStatement(m_lexer->lastLineNumber(), expression, startLine, m_lastLine);
894         }
895         const Identifier* ident = m_token.m_data.ident;
896         int end = tokenEnd();
897         next();
898         consumeOrFail(COLON);
899         if (!m_syntaxAlreadyValidated) {
900             // This is O(N^2) over the current list of consecutive labels, but I
901             // have never seen more than one label in a row in the real world.
902             for (size_t i = 0; i < labels.size(); i++)
903                 failIfTrue(ident->impl() == labels[i].m_ident->impl());
904             failIfTrue(getLabel(ident));
905             labels.append(LabelInfo(ident, start, end));
906         }
907     } while (match(IDENT));
908     bool isLoop = false;
909     switch (m_token.m_type) {
910     case FOR:
911     case WHILE:
912     case DO:
913         isLoop = true;
914         break;
915         
916     default:
917         break;
918     }
919     const Identifier* unused = 0;
920     if (!m_syntaxAlreadyValidated) {
921         for (size_t i = 0; i < labels.size(); i++)
922             pushLabel(labels[i].m_ident, isLoop);
923     }
924     TreeStatement statement = parseStatement(context, unused);
925     if (!m_syntaxAlreadyValidated) {
926         for (size_t i = 0; i < labels.size(); i++)
927             popLabel();
928     }
929     failIfFalse(statement);
930     for (size_t i = 0; i < labels.size(); i++) {
931         const LabelInfo& info = labels[labels.size() - i - 1];
932         statement = context.createLabelStatement(m_lexer->lastLineNumber(), info.m_ident, statement, info.m_start, info.m_end);
933     }
934     return statement;
935 }
936
937 template <typename LexerType>
938 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseExpressionStatement(TreeBuilder& context)
939 {
940     int startLine = tokenLine();
941     TreeExpression expression = parseExpression(context);
942     failIfFalse(expression);
943     failIfFalse(autoSemiColon());
944     return context.createExprStatement(m_lexer->lastLineNumber(), expression, startLine, m_lastLine);
945 }
946
947 template <typename LexerType>
948 template <class TreeBuilder> TreeStatement Parser<LexerType>::parseIfStatement(TreeBuilder& context)
949 {
950     ASSERT(match(IF));
951     
952     int start = tokenLine();
953     next();
954     
955     consumeOrFail(OPENPAREN);
956     
957     TreeExpression condition = parseExpression(context);
958     failIfFalse(condition);
959     int end = tokenLine();
960     consumeOrFail(CLOSEPAREN);
961     
962     const Identifier* unused = 0;
963     TreeStatement trueBlock = parseStatement(context, unused);
964     failIfFalse(trueBlock);
965     
966     if (!match(ELSE))
967         return context.createIfStatement(m_lexer->lastLineNumber(), condition, trueBlock, start, end);
968     
969     Vector<TreeExpression> exprStack;
970     Vector<pair<int, int> > posStack;
971     Vector<TreeStatement> statementStack;
972     bool trailingElse = false;
973     do {
974         next();
975         if (!match(IF)) {
976             const Identifier* unused = 0;
977             TreeStatement block = parseStatement(context, unused);
978             failIfFalse(block);
979             statementStack.append(block);
980             trailingElse = true;
981             break;
982         }
983         int innerStart = tokenLine();
984         next();
985         
986         consumeOrFail(OPENPAREN);
987         
988         TreeExpression innerCondition = parseExpression(context);
989         failIfFalse(innerCondition);
990         int innerEnd = tokenLine();
991         consumeOrFail(CLOSEPAREN);
992         const Identifier* unused = 0;
993         TreeStatement innerTrueBlock = parseStatement(context, unused);
994         failIfFalse(innerTrueBlock);     
995         exprStack.append(innerCondition);
996         posStack.append(make_pair(innerStart, innerEnd));
997         statementStack.append(innerTrueBlock);
998     } while (match(ELSE));
999     
1000     if (!trailingElse) {
1001         TreeExpression condition = exprStack.last();
1002         exprStack.removeLast();
1003         TreeStatement trueBlock = statementStack.last();
1004         statementStack.removeLast();
1005         pair<int, int> pos = posStack.last();
1006         posStack.removeLast();
1007         statementStack.append(context.createIfStatement(m_lexer->lastLineNumber(), condition, trueBlock, pos.first, pos.second));
1008     }
1009     
1010     while (!exprStack.isEmpty()) {
1011         TreeExpression condition = exprStack.last();
1012         exprStack.removeLast();
1013         TreeStatement falseBlock = statementStack.last();
1014         statementStack.removeLast();
1015         TreeStatement trueBlock = statementStack.last();
1016         statementStack.removeLast();
1017         pair<int, int> pos = posStack.last();
1018         posStack.removeLast();
1019         statementStack.append(context.createIfStatement(m_lexer->lastLineNumber(), condition, trueBlock, falseBlock, pos.first, pos.second));
1020     }
1021     
1022     return context.createIfStatement(m_lexer->lastLineNumber(), condition, trueBlock, statementStack.last(), start, end);
1023 }
1024
1025 template <typename LexerType>
1026 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseExpression(TreeBuilder& context)
1027 {
1028     failIfStackOverflow();
1029     TreeExpression node = parseAssignmentExpression(context);
1030     failIfFalse(node);
1031     if (!match(COMMA))
1032         return node;
1033     next();
1034     m_nonTrivialExpressionCount++;
1035     m_nonLHSCount++;
1036     TreeExpression right = parseAssignmentExpression(context);
1037     failIfFalse(right);
1038     typename TreeBuilder::Comma commaNode = context.createCommaExpr(m_lexer->lastLineNumber(), node, right);
1039     while (match(COMMA)) {
1040         next(TreeBuilder::DontBuildStrings);
1041         right = parseAssignmentExpression(context);
1042         failIfFalse(right);
1043         context.appendToComma(commaNode, right);
1044     }
1045     return commaNode;
1046 }
1047
1048 template <typename LexerType>
1049 template <typename TreeBuilder> TreeExpression Parser<LexerType>::parseAssignmentExpression(TreeBuilder& context)
1050 {
1051     failIfStackOverflow();
1052     int start = tokenStart();
1053     int initialAssignmentCount = m_assignmentCount;
1054     int initialNonLHSCount = m_nonLHSCount;
1055     TreeExpression lhs = parseConditionalExpression(context);
1056     failIfFalse(lhs);
1057     if (initialNonLHSCount != m_nonLHSCount)
1058         return lhs;
1059     
1060     int assignmentStack = 0;
1061     Operator op;
1062     bool hadAssignment = false;
1063     while (true) {
1064         switch (m_token.m_type) {
1065         case EQUAL: op = OpEqual; break;
1066         case PLUSEQUAL: op = OpPlusEq; break;
1067         case MINUSEQUAL: op = OpMinusEq; break;
1068         case MULTEQUAL: op = OpMultEq; break;
1069         case DIVEQUAL: op = OpDivEq; break;
1070         case LSHIFTEQUAL: op = OpLShift; break;
1071         case RSHIFTEQUAL: op = OpRShift; break;
1072         case URSHIFTEQUAL: op = OpURShift; break;
1073         case ANDEQUAL: op = OpAndEq; break;
1074         case XOREQUAL: op = OpXOrEq; break;
1075         case OREQUAL: op = OpOrEq; break;
1076         case MODEQUAL: op = OpModEq; break;
1077         default:
1078             goto end;
1079         }
1080         m_nonTrivialExpressionCount++;
1081         hadAssignment = true;
1082         context.assignmentStackAppend(assignmentStack, lhs, start, tokenStart(), m_assignmentCount, op);
1083         start = tokenStart();
1084         m_assignmentCount++;
1085         next(TreeBuilder::DontBuildStrings);
1086         if (strictMode() && m_lastIdentifier && context.isResolve(lhs)) {
1087             failIfTrueIfStrictWithMessage(m_globalData->propertyNames->eval == *m_lastIdentifier, "'eval' cannot be modified in strict mode");
1088             failIfTrueIfStrictWithMessage(m_globalData->propertyNames->arguments == *m_lastIdentifier, "'arguments' cannot be modified in strict mode");
1089             declareWrite(m_lastIdentifier);
1090             m_lastIdentifier = 0;
1091         }
1092         lhs = parseConditionalExpression(context);
1093         failIfFalse(lhs);
1094         if (initialNonLHSCount != m_nonLHSCount)
1095             break;
1096     }
1097 end:
1098     if (hadAssignment)
1099         m_nonLHSCount++;
1100     
1101     if (!TreeBuilder::CreatesAST)
1102         return lhs;
1103     
1104     while (assignmentStack)
1105         lhs = context.createAssignment(m_lexer->lastLineNumber(), assignmentStack, lhs, initialAssignmentCount, m_assignmentCount, lastTokenEnd());
1106     
1107     return lhs;
1108 }
1109
1110 template <typename LexerType>
1111 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseConditionalExpression(TreeBuilder& context)
1112 {
1113     TreeExpression cond = parseBinaryExpression(context);
1114     failIfFalse(cond);
1115     if (!match(QUESTION))
1116         return cond;
1117     m_nonTrivialExpressionCount++;
1118     m_nonLHSCount++;
1119     next(TreeBuilder::DontBuildStrings);
1120     TreeExpression lhs = parseAssignmentExpression(context);
1121     consumeOrFailWithFlags(COLON, TreeBuilder::DontBuildStrings);
1122     
1123     TreeExpression rhs = parseAssignmentExpression(context);
1124     failIfFalse(rhs);
1125     return context.createConditionalExpr(m_lexer->lastLineNumber(), cond, lhs, rhs);
1126 }
1127
1128 ALWAYS_INLINE static bool isUnaryOp(JSTokenType token)
1129 {
1130     return token & UnaryOpTokenFlag;
1131 }
1132
1133 template <typename LexerType>
1134 int Parser<LexerType>::isBinaryOperator(JSTokenType token)
1135 {
1136     if (m_allowsIn)
1137         return token & (BinaryOpTokenPrecedenceMask << BinaryOpTokenAllowsInPrecedenceAdditionalShift);
1138     return token & BinaryOpTokenPrecedenceMask;
1139 }
1140
1141 template <typename LexerType>
1142 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseBinaryExpression(TreeBuilder& context)
1143 {
1144     
1145     int operandStackDepth = 0;
1146     int operatorStackDepth = 0;
1147     typename TreeBuilder::BinaryExprContext binaryExprContext(context);
1148     while (true) {
1149         int exprStart = tokenStart();
1150         int initialAssignments = m_assignmentCount;
1151         TreeExpression current = parseUnaryExpression(context);
1152         failIfFalse(current);
1153         
1154         context.appendBinaryExpressionInfo(operandStackDepth, current, exprStart, lastTokenEnd(), lastTokenEnd(), initialAssignments != m_assignmentCount);
1155         int precedence = isBinaryOperator(m_token.m_type);
1156         if (!precedence)
1157             break;
1158         m_nonTrivialExpressionCount++;
1159         m_nonLHSCount++;
1160         int operatorToken = m_token.m_type;
1161         next(TreeBuilder::DontBuildStrings);
1162         
1163         while (operatorStackDepth &&  context.operatorStackHasHigherPrecedence(operatorStackDepth, precedence)) {
1164             ASSERT(operandStackDepth > 1);
1165             
1166             typename TreeBuilder::BinaryOperand rhs = context.getFromOperandStack(-1);
1167             typename TreeBuilder::BinaryOperand lhs = context.getFromOperandStack(-2);
1168             context.shrinkOperandStackBy(operandStackDepth, 2);
1169             context.appendBinaryOperation(m_lexer->lastLineNumber(), operandStackDepth, operatorStackDepth, lhs, rhs);
1170             context.operatorStackPop(operatorStackDepth);
1171         }
1172         context.operatorStackAppend(operatorStackDepth, operatorToken, precedence);
1173     }
1174     while (operatorStackDepth) {
1175         ASSERT(operandStackDepth > 1);
1176         
1177         typename TreeBuilder::BinaryOperand rhs = context.getFromOperandStack(-1);
1178         typename TreeBuilder::BinaryOperand lhs = context.getFromOperandStack(-2);
1179         context.shrinkOperandStackBy(operandStackDepth, 2);
1180         context.appendBinaryOperation(m_lexer->lastLineNumber(), operandStackDepth, operatorStackDepth, lhs, rhs);
1181         context.operatorStackPop(operatorStackDepth);
1182     }
1183     return context.popOperandStack(operandStackDepth);
1184 }
1185
1186 template <typename LexerType>
1187 template <bool complete, class TreeBuilder> TreeProperty Parser<LexerType>::parseProperty(TreeBuilder& context)
1188 {
1189     bool wasIdent = false;
1190     switch (m_token.m_type) {
1191     namedProperty:
1192     case IDENT:
1193         wasIdent = true;
1194     case STRING: {
1195         const Identifier* ident = m_token.m_data.ident;
1196         if (complete || (wasIdent && (*ident == m_globalData->propertyNames->get || *ident == m_globalData->propertyNames->set)))
1197             nextExpectIdentifier(LexerFlagsIgnoreReservedWords);
1198         else
1199             nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
1200         
1201         if (match(COLON)) {
1202             next();
1203             TreeExpression node = parseAssignmentExpression(context);
1204             failIfFalse(node);
1205             return context.template createProperty<complete>(ident, node, PropertyNode::Constant);
1206         }
1207         failIfFalse(wasIdent);
1208         matchOrFail(IDENT);
1209         const Identifier* accessorName = 0;
1210         TreeFormalParameterList parameters = 0;
1211         TreeFunctionBody body = 0;
1212         int openBracePos = 0;
1213         int closeBracePos = 0;
1214         int bodyStartLine = 0;
1215         PropertyNode::Type type;
1216         if (*ident == m_globalData->propertyNames->get)
1217             type = PropertyNode::Getter;
1218         else if (*ident == m_globalData->propertyNames->set)
1219             type = PropertyNode::Setter;
1220         else
1221             fail();
1222         failIfFalse((parseFunctionInfo<FunctionNeedsName, false>(context, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
1223         return context.template createGetterOrSetterProperty<complete>(m_lexer->lastLineNumber(), type, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
1224     }
1225     case NUMBER: {
1226         double propertyName = m_token.m_data.doubleValue;
1227         next();
1228         consumeOrFail(COLON);
1229         TreeExpression node = parseAssignmentExpression(context);
1230         failIfFalse(node);
1231         return context.template createProperty<complete>(const_cast<JSGlobalData*>(m_globalData), propertyName, node, PropertyNode::Constant);
1232     }
1233     default:
1234         failIfFalse(m_token.m_type & KeywordTokenFlag);
1235         goto namedProperty;
1236     }
1237 }
1238
1239 template <typename LexerType>
1240 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseObjectLiteral(TreeBuilder& context)
1241 {
1242     int startOffset = m_token.m_data.intValue;
1243     consumeOrFailWithFlags(OPENBRACE, TreeBuilder::DontBuildStrings);
1244     
1245     if (match(CLOSEBRACE)) {
1246         next();
1247         return context.createObjectLiteral(m_lexer->lastLineNumber());
1248     }
1249     
1250     TreeProperty property = parseProperty<false>(context);
1251     failIfFalse(property);
1252     if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) {
1253         m_lexer->setOffset(startOffset);
1254         next();
1255         return parseStrictObjectLiteral(context);
1256     }
1257     TreePropertyList propertyList = context.createPropertyList(m_lexer->lastLineNumber(), property);
1258     TreePropertyList tail = propertyList;
1259     while (match(COMMA)) {
1260         next(TreeBuilder::DontBuildStrings);
1261         // allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939
1262         if (match(CLOSEBRACE))
1263             break;
1264         property = parseProperty<false>(context);
1265         failIfFalse(property);
1266         if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) {
1267             m_lexer->setOffset(startOffset);
1268             next();
1269             return parseStrictObjectLiteral(context);
1270         }
1271         tail = context.createPropertyList(m_lexer->lastLineNumber(), property, tail);
1272     }
1273     
1274     consumeOrFail(CLOSEBRACE);
1275     
1276     return context.createObjectLiteral(m_lexer->lastLineNumber(), propertyList);
1277 }
1278
1279 template <typename LexerType>
1280 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseStrictObjectLiteral(TreeBuilder& context)
1281 {
1282     consumeOrFail(OPENBRACE);
1283     
1284     if (match(CLOSEBRACE)) {
1285         next();
1286         return context.createObjectLiteral(m_lexer->lastLineNumber());
1287     }
1288     
1289     TreeProperty property = parseProperty<true>(context);
1290     failIfFalse(property);
1291     
1292     typedef HashMap<RefPtr<StringImpl>, unsigned, IdentifierRepHash> ObjectValidationMap;
1293     ObjectValidationMap objectValidator;
1294     // Add the first property
1295     if (!m_syntaxAlreadyValidated)
1296         objectValidator.add(context.getName(property).impl(), context.getType(property));
1297     
1298     TreePropertyList propertyList = context.createPropertyList(m_lexer->lastLineNumber(), property);
1299     TreePropertyList tail = propertyList;
1300     while (match(COMMA)) {
1301         next();
1302         // allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939
1303         if (match(CLOSEBRACE))
1304             break;
1305         property = parseProperty<true>(context);
1306         failIfFalse(property);
1307         if (!m_syntaxAlreadyValidated) {
1308             std::pair<ObjectValidationMap::iterator, bool> propertyEntryIter = objectValidator.add(context.getName(property).impl(), context.getType(property));
1309             if (!propertyEntryIter.second) {
1310                 failIfTrue(propertyEntryIter.first->second == PropertyNode::Constant);
1311                 failIfTrue(context.getType(property) == PropertyNode::Constant);
1312                 failIfTrue(context.getType(property) & propertyEntryIter.first->second);
1313                 propertyEntryIter.first->second |= context.getType(property);
1314             }
1315         }
1316         tail = context.createPropertyList(m_lexer->lastLineNumber(), property, tail);
1317     }
1318     
1319     consumeOrFail(CLOSEBRACE);
1320     
1321     return context.createObjectLiteral(m_lexer->lastLineNumber(), propertyList);
1322 }
1323
1324 template <typename LexerType>
1325 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseArrayLiteral(TreeBuilder& context)
1326 {
1327     consumeOrFailWithFlags(OPENBRACKET, TreeBuilder::DontBuildStrings);
1328     
1329     int elisions = 0;
1330     while (match(COMMA)) {
1331         next(TreeBuilder::DontBuildStrings);
1332         elisions++;
1333     }
1334     if (match(CLOSEBRACKET)) {
1335         next(TreeBuilder::DontBuildStrings);
1336         return context.createArray(m_lexer->lastLineNumber(), elisions);
1337     }
1338     
1339     TreeExpression elem = parseAssignmentExpression(context);
1340     failIfFalse(elem);
1341     typename TreeBuilder::ElementList elementList = context.createElementList(elisions, elem);
1342     typename TreeBuilder::ElementList tail = elementList;
1343     elisions = 0;
1344     while (match(COMMA)) {
1345         next(TreeBuilder::DontBuildStrings);
1346         elisions = 0;
1347         
1348         while (match(COMMA)) {
1349             next();
1350             elisions++;
1351         }
1352         
1353         if (match(CLOSEBRACKET)) {
1354             next(TreeBuilder::DontBuildStrings);
1355             return context.createArray(m_lexer->lastLineNumber(), elisions, elementList);
1356         }
1357         TreeExpression elem = parseAssignmentExpression(context);
1358         failIfFalse(elem);
1359         tail = context.createElementList(tail, elisions, elem);
1360     }
1361     
1362     consumeOrFail(CLOSEBRACKET);
1363     
1364     return context.createArray(m_lexer->lastLineNumber(), elementList);
1365 }
1366
1367 template <typename LexerType>
1368 template <class TreeBuilder> TreeExpression Parser<LexerType>::parsePrimaryExpression(TreeBuilder& context)
1369 {
1370     failIfStackOverflow();
1371     switch (m_token.m_type) {
1372     case OPENBRACE:
1373         if (strictMode())
1374             return parseStrictObjectLiteral(context);
1375         return parseObjectLiteral(context);
1376     case OPENBRACKET:
1377         return parseArrayLiteral(context);
1378     case OPENPAREN: {
1379         next();
1380         int oldNonLHSCount = m_nonLHSCount;
1381         TreeExpression result = parseExpression(context);
1382         m_nonLHSCount = oldNonLHSCount;
1383         consumeOrFail(CLOSEPAREN);
1384         
1385         return result;
1386     }
1387     case THISTOKEN: {
1388         next();
1389         return context.thisExpr(m_lexer->lastLineNumber());
1390     }
1391     case IDENT: {
1392         int start = tokenStart();
1393         const Identifier* ident = m_token.m_data.ident;
1394         next();
1395         currentScope()->useVariable(ident, m_globalData->propertyNames->eval == *ident);
1396         m_lastIdentifier = ident;
1397         return context.createResolve(m_lexer->lastLineNumber(), ident, start);
1398     }
1399     case STRING: {
1400         const Identifier* ident = m_token.m_data.ident;
1401         next();
1402         return context.createString(m_lexer->lastLineNumber(), ident);
1403     }
1404     case NUMBER: {
1405         double d = m_token.m_data.doubleValue;
1406         next();
1407         return context.createNumberExpr(m_lexer->lastLineNumber(), d);
1408     }
1409     case NULLTOKEN: {
1410         next();
1411         return context.createNull(m_lexer->lastLineNumber());
1412     }
1413     case TRUETOKEN: {
1414         next();
1415         return context.createBoolean(m_lexer->lastLineNumber(), true);
1416     }
1417     case FALSETOKEN: {
1418         next();
1419         return context.createBoolean(m_lexer->lastLineNumber(), false);
1420     }
1421     case DIVEQUAL:
1422     case DIVIDE: {
1423         /* regexp */
1424         const Identifier* pattern;
1425         const Identifier* flags;
1426         if (match(DIVEQUAL))
1427             failIfFalse(m_lexer->scanRegExp(pattern, flags, '='));
1428         else
1429             failIfFalse(m_lexer->scanRegExp(pattern, flags));
1430         
1431         int start = tokenStart();
1432         next();
1433         TreeExpression re = context.createRegExp(m_lexer->lastLineNumber(), *pattern, *flags, start);
1434         if (!re) {
1435             const char* yarrErrorMsg = Yarr::checkSyntax(pattern->ustring());
1436             ASSERT(!m_errorMessage.isNull());
1437             failWithMessage(yarrErrorMsg);
1438         }
1439         return re;
1440     }
1441     default:
1442         fail();
1443     }
1444 }
1445
1446 template <typename LexerType>
1447 template <class TreeBuilder> TreeArguments Parser<LexerType>::parseArguments(TreeBuilder& context)
1448 {
1449     consumeOrFailWithFlags(OPENPAREN, TreeBuilder::DontBuildStrings);
1450     if (match(CLOSEPAREN)) {
1451         next(TreeBuilder::DontBuildStrings);
1452         return context.createArguments();
1453     }
1454     TreeExpression firstArg = parseAssignmentExpression(context);
1455     failIfFalse(firstArg);
1456     
1457     TreeArgumentsList argList = context.createArgumentsList(m_lexer->lastLineNumber(), firstArg);
1458     TreeArgumentsList tail = argList;
1459     while (match(COMMA)) {
1460         next(TreeBuilder::DontBuildStrings);
1461         TreeExpression arg = parseAssignmentExpression(context);
1462         failIfFalse(arg);
1463         tail = context.createArgumentsList(m_lexer->lastLineNumber(), tail, arg);
1464     }
1465     consumeOrFail(CLOSEPAREN);
1466     return context.createArguments(argList);
1467 }
1468
1469 template <typename LexerType>
1470 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseMemberExpression(TreeBuilder& context)
1471 {
1472     TreeExpression base = 0;
1473     int start = tokenStart();
1474     int expressionStart = start;
1475     int newCount = 0;
1476     while (match(NEW)) {
1477         next();
1478         newCount++;
1479     }
1480     
1481     if (match(FUNCTION)) {
1482         const Identifier* name = &m_globalData->propertyNames->nullIdentifier;
1483         TreeFormalParameterList parameters = 0;
1484         TreeFunctionBody body = 0;
1485         int openBracePos = 0;
1486         int closeBracePos = 0;
1487         int bodyStartLine = 0;
1488         next();
1489         failIfFalse((parseFunctionInfo<FunctionNoRequirements, false>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
1490         base = context.createFunctionExpr(m_lexer->lastLineNumber(), name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
1491     } else
1492         base = parsePrimaryExpression(context);
1493     
1494     failIfFalse(base);
1495     while (true) {
1496         switch (m_token.m_type) {
1497         case OPENBRACKET: {
1498             m_nonTrivialExpressionCount++;
1499             int expressionEnd = lastTokenEnd();
1500             next();
1501             int nonLHSCount = m_nonLHSCount;
1502             int initialAssignments = m_assignmentCount;
1503             TreeExpression property = parseExpression(context);
1504             failIfFalse(property);
1505             base = context.createBracketAccess(m_lexer->lastLineNumber(), base, property, initialAssignments != m_assignmentCount, expressionStart, expressionEnd, tokenEnd());
1506             consumeOrFail(CLOSEBRACKET);
1507             m_nonLHSCount = nonLHSCount;
1508             break;
1509         }
1510         case OPENPAREN: {
1511             m_nonTrivialExpressionCount++;
1512             int nonLHSCount = m_nonLHSCount;
1513             if (newCount) {
1514                 newCount--;
1515                 int exprEnd = lastTokenEnd();
1516                 TreeArguments arguments = parseArguments(context);
1517                 failIfFalse(arguments);
1518                 base = context.createNewExpr(m_lexer->lastLineNumber(), base, arguments, start, exprEnd, lastTokenEnd());           
1519             } else {
1520                 int expressionEnd = lastTokenEnd();
1521                 TreeArguments arguments = parseArguments(context);
1522                 failIfFalse(arguments);
1523                 base = context.makeFunctionCallNode(m_lexer->lastLineNumber(), base, arguments, expressionStart, expressionEnd, lastTokenEnd());
1524             }
1525             m_nonLHSCount = nonLHSCount;
1526             break;
1527         }
1528         case DOT: {
1529             m_nonTrivialExpressionCount++;
1530             int expressionEnd = lastTokenEnd();
1531             nextExpectIdentifier(LexerFlagsIgnoreReservedWords | TreeBuilder::DontBuildKeywords);
1532             matchOrFail(IDENT);
1533             base = context.createDotAccess(m_lexer->lastLineNumber(), base, m_token.m_data.ident, expressionStart, expressionEnd, tokenEnd());
1534             next();
1535             break;
1536         }
1537         default:
1538             goto endMemberExpression;
1539         }
1540     }
1541 endMemberExpression:
1542     while (newCount--)
1543         base = context.createNewExpr(m_lexer->lastLineNumber(), base, start, lastTokenEnd());
1544     return base;
1545 }
1546
1547 template <typename LexerType>
1548 template <class TreeBuilder> TreeExpression Parser<LexerType>::parseUnaryExpression(TreeBuilder& context)
1549 {
1550     typename TreeBuilder::UnaryExprContext unaryExprContext(context);
1551     AllowInOverride allowInOverride(this);
1552     int tokenStackDepth = 0;
1553     bool modifiesExpr = false;
1554     bool requiresLExpr = false;
1555     while (isUnaryOp(m_token.m_type)) {
1556         if (strictMode()) {
1557             switch (m_token.m_type) {
1558             case PLUSPLUS:
1559             case MINUSMINUS:
1560             case AUTOPLUSPLUS:
1561             case AUTOMINUSMINUS:
1562                 failIfTrue(requiresLExpr);
1563                 modifiesExpr = true;
1564                 requiresLExpr = true;
1565                 break;
1566             case DELETETOKEN:
1567                 failIfTrue(requiresLExpr);
1568                 requiresLExpr = true;
1569                 break;
1570             default:
1571                 failIfTrue(requiresLExpr);
1572                 break;
1573             }
1574         }
1575         m_nonLHSCount++;
1576         context.appendUnaryToken(tokenStackDepth, m_token.m_type, tokenStart());
1577         next();
1578         m_nonTrivialExpressionCount++;
1579     }
1580     int subExprStart = tokenStart();
1581     TreeExpression expr = parseMemberExpression(context);
1582     failIfFalse(expr);
1583     bool isEvalOrArguments = false;
1584     if (strictMode() && !m_syntaxAlreadyValidated) {
1585         if (context.isResolve(expr))
1586             isEvalOrArguments = *m_lastIdentifier == m_globalData->propertyNames->eval || *m_lastIdentifier == m_globalData->propertyNames->arguments;
1587     }
1588     failIfTrueIfStrictWithNameAndMessage(isEvalOrArguments && modifiesExpr, "'", m_lastIdentifier->impl(), "' cannot be modified in strict mode");
1589     switch (m_token.m_type) {
1590     case PLUSPLUS:
1591         m_nonTrivialExpressionCount++;
1592         m_nonLHSCount++;
1593         expr = context.makePostfixNode(m_lexer->lastLineNumber(), expr, OpPlusPlus, subExprStart, lastTokenEnd(), tokenEnd());
1594         m_assignmentCount++;
1595         failIfTrueIfStrictWithNameAndMessage(isEvalOrArguments, "'", m_lastIdentifier->impl(), "' cannot be modified in strict mode");
1596         failIfTrueIfStrict(requiresLExpr);
1597         next();
1598         break;
1599     case MINUSMINUS:
1600         m_nonTrivialExpressionCount++;
1601         m_nonLHSCount++;
1602         expr = context.makePostfixNode(m_lexer->lastLineNumber(), expr, OpMinusMinus, subExprStart, lastTokenEnd(), tokenEnd());
1603         m_assignmentCount++;
1604         failIfTrueIfStrictWithNameAndMessage(isEvalOrArguments, "'", m_lastIdentifier->impl(), "' cannot be modified in strict mode");
1605         failIfTrueIfStrict(requiresLExpr);
1606         next();
1607         break;
1608     default:
1609         break;
1610     }
1611     
1612     int end = lastTokenEnd();
1613     
1614     if (!TreeBuilder::CreatesAST && (m_syntaxAlreadyValidated || !strictMode()))
1615         return expr;
1616     
1617     while (tokenStackDepth) {
1618         switch (context.unaryTokenStackLastType(tokenStackDepth)) {
1619         case EXCLAMATION:
1620             expr = context.createLogicalNot(m_lexer->lastLineNumber(), expr);
1621             break;
1622         case TILDE:
1623             expr = context.makeBitwiseNotNode(m_lexer->lastLineNumber(), expr);
1624             break;
1625         case MINUS:
1626             expr = context.makeNegateNode(m_lexer->lastLineNumber(), expr);
1627             break;
1628         case PLUS:
1629             expr = context.createUnaryPlus(m_lexer->lastLineNumber(), expr);
1630             break;
1631         case PLUSPLUS:
1632         case AUTOPLUSPLUS:
1633             expr = context.makePrefixNode(m_lexer->lastLineNumber(), expr, OpPlusPlus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
1634             m_assignmentCount++;
1635             break;
1636         case MINUSMINUS:
1637         case AUTOMINUSMINUS:
1638             expr = context.makePrefixNode(m_lexer->lastLineNumber(), expr, OpMinusMinus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
1639             m_assignmentCount++;
1640             break;
1641         case TYPEOF:
1642             expr = context.makeTypeOfNode(m_lexer->lastLineNumber(), expr);
1643             break;
1644         case VOIDTOKEN:
1645             expr = context.createVoid(m_lexer->lastLineNumber(), expr);
1646             break;
1647         case DELETETOKEN:
1648             failIfTrueIfStrictWithNameAndMessage(context.isResolve(expr), "Cannot delete unqualified property", m_lastIdentifier->impl(), "in strict mode");
1649             expr = context.makeDeleteNode(m_lexer->lastLineNumber(), expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end);
1650             break;
1651         default:
1652             // If we get here something has gone horribly horribly wrong
1653             CRASH();
1654         }
1655         subExprStart = context.unaryTokenStackLastStart(tokenStackDepth);
1656         context.unaryTokenStackRemoveLast(tokenStackDepth);
1657     }
1658     return expr;
1659 }
1660
1661 // Instantiate the two flavors of Parser we need instead of putting most of this file in Parser.h
1662 template class Parser< Lexer<LChar> >;
1663 template class Parser< Lexer<UChar> >;
1664
1665 } // namespace JSC