1ff5090826b1f8037847f08664f41e07dd50ad36
[WebKit.git] / Source / JavaScriptCore / parser / JSParser.cpp
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27
28 #include "JSParser.h"
29
30 using namespace JSC;
31
32 #include "CodeBlock.h"
33 #include "JSGlobalData.h"
34 #include "NodeInfo.h"
35 #include "ASTBuilder.h"
36 #include <wtf/HashFunctions.h>
37 #include <wtf/WTFThreadData.h>
38 #include <utility>
39
40 using namespace std;
41
42 namespace JSC {
43 #define fail() do { m_error = true; return 0; } while (0)
44 #define failIfFalse(cond) do { if (!(cond)) fail(); } while (0)
45 #define failIfTrue(cond) do { if ((cond)) fail(); } while (0)
46 #define failIfTrueIfStrict(cond) do { if ((cond) && strictMode()) fail(); } while (0)
47 #define failIfFalseIfStrict(cond) do { if ((!(cond)) && strictMode()) fail(); } while (0)
48 #define consumeOrFail(tokenType) do { if (!consume(tokenType)) fail(); } while (0)
49 #define matchOrFail(tokenType) do { if (!match(tokenType)) fail(); } while (0)
50 #define failIfStackOverflow() do { failIfFalse(canRecurse()); } while (0)
51
52 // Macros to make the more common TreeBuilder types a little less verbose
53 #define TreeStatement typename TreeBuilder::Statement
54 #define TreeExpression typename TreeBuilder::Expression
55 #define TreeFormalParameterList typename TreeBuilder::FormalParameterList
56 #define TreeSourceElements typename TreeBuilder::SourceElements
57 #define TreeClause typename TreeBuilder::Clause
58 #define TreeClauseList typename TreeBuilder::ClauseList
59 #define TreeConstDeclList typename TreeBuilder::ConstDeclList
60 #define TreeArguments typename TreeBuilder::Arguments
61 #define TreeArgumentsList typename TreeBuilder::ArgumentsList
62 #define TreeFunctionBody typename TreeBuilder::FunctionBody
63 #define TreeProperty typename TreeBuilder::Property
64 #define TreePropertyList typename TreeBuilder::PropertyList
65
66 COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
67
68 class JSParser {
69 public:
70     JSParser(Lexer*, JSGlobalData*, FunctionParameters*, bool isStrictContext, bool isFunction, SourceProvider*);
71     const char* parseProgram();
72 private:
73     struct AllowInOverride {
74         AllowInOverride(JSParser* parser)
75             : m_parser(parser)
76             , m_oldAllowsIn(parser->m_allowsIn)
77         {
78             parser->m_allowsIn = true;
79         }
80         ~AllowInOverride()
81         {
82             m_parser->m_allowsIn = m_oldAllowsIn;
83         }
84         JSParser* m_parser;
85         bool m_oldAllowsIn;
86     };
87     
88     struct ScopeLabelInfo {
89         ScopeLabelInfo(StringImpl* ident, bool isLoop)
90         : m_ident(ident)
91         , m_isLoop(isLoop)
92         {
93         }
94         StringImpl* m_ident;
95         bool m_isLoop;
96     };
97
98     void next(Lexer::LexType lexType = Lexer::IdentifyReservedWords)
99     {
100         m_lastLine = m_token.m_info.line;
101         m_lastTokenEnd = m_token.m_info.endOffset;
102         m_lexer->setLastLineNumber(m_lastLine);
103         m_token.m_type = m_lexer->lex(&m_token.m_data, &m_token.m_info, lexType, strictMode());
104     }
105     
106     bool nextTokenIsColon()
107     {
108         return m_lexer->nextTokenIsColon();
109     }
110
111     bool consume(JSTokenType expected)
112     {
113         bool result = m_token.m_type == expected;
114         failIfFalse(result);
115         next();
116         return result;
117     }
118
119     bool match(JSTokenType expected)
120     {
121         return m_token.m_type == expected;
122     }
123
124     int tokenStart()
125     {
126         return m_token.m_info.startOffset;
127     }
128
129     int tokenLine()
130     {
131         return m_token.m_info.line;
132     }
133
134     int tokenEnd()
135     {
136         return m_token.m_info.endOffset;
137     }
138     
139     void startLoop() { currentScope()->startLoop(); }
140     void endLoop() { currentScope()->endLoop(); }
141     void startSwitch() { currentScope()->startSwitch(); }
142     void endSwitch() { currentScope()->endSwitch(); }
143     void setStrictMode() { currentScope()->setStrictMode(); }
144     bool strictMode() { return currentScope()->strictMode(); }
145     bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
146     bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
147     bool breakIsValid()
148     {
149         ScopeRef current = currentScope();
150         while (!current->breakIsValid()) {
151             if (!current.hasContainingScope())
152                 return false;
153             current = current.containingScope();
154         }
155         return true;
156     }
157     bool continueIsValid()
158     {
159         ScopeRef current = currentScope();
160         while (!current->continueIsValid()) {
161             if (!current.hasContainingScope())
162                 return false;
163             current = current.containingScope();
164         }
165         return true;
166     }
167     void pushLabel(const Identifier* label, bool isLoop) { currentScope()->pushLabel(label, isLoop); }
168     void popLabel() { currentScope()->popLabel(); }
169     ScopeLabelInfo* getLabel(const Identifier* label)
170     {
171         ScopeRef current = currentScope();
172         ScopeLabelInfo* result = 0;
173         while (!(result = current->getLabel(label))) {
174             if (!current.hasContainingScope())
175                 return 0;
176             current = current.containingScope();
177         }
178         return result;
179     }
180
181     enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
182     template <SourceElementsMode mode, class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&);
183     template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive);
184     template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&);
185     template <class TreeBuilder> TreeStatement parseVarDeclaration(TreeBuilder&);
186     template <class TreeBuilder> TreeStatement parseConstDeclaration(TreeBuilder&);
187     template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&);
188     template <class TreeBuilder> TreeStatement parseWhileStatement(TreeBuilder&);
189     template <class TreeBuilder> TreeStatement parseForStatement(TreeBuilder&);
190     template <class TreeBuilder> TreeStatement parseBreakStatement(TreeBuilder&);
191     template <class TreeBuilder> TreeStatement parseContinueStatement(TreeBuilder&);
192     template <class TreeBuilder> TreeStatement parseReturnStatement(TreeBuilder&);
193     template <class TreeBuilder> TreeStatement parseThrowStatement(TreeBuilder&);
194     template <class TreeBuilder> TreeStatement parseWithStatement(TreeBuilder&);
195     template <class TreeBuilder> TreeStatement parseSwitchStatement(TreeBuilder&);
196     template <class TreeBuilder> TreeClauseList parseSwitchClauses(TreeBuilder&);
197     template <class TreeBuilder> TreeClause parseSwitchDefaultClause(TreeBuilder&);
198     template <class TreeBuilder> TreeStatement parseTryStatement(TreeBuilder&);
199     template <class TreeBuilder> TreeStatement parseDebuggerStatement(TreeBuilder&);
200     template <class TreeBuilder> TreeStatement parseExpressionStatement(TreeBuilder&);
201     template <class TreeBuilder> TreeStatement parseExpressionOrLabelStatement(TreeBuilder&);
202     template <class TreeBuilder> TreeStatement parseIfStatement(TreeBuilder&);
203     template <class TreeBuilder> ALWAYS_INLINE TreeStatement parseBlockStatement(TreeBuilder&);
204     template <class TreeBuilder> TreeExpression parseExpression(TreeBuilder&);
205     template <class TreeBuilder> TreeExpression parseAssignmentExpression(TreeBuilder&);
206     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseConditionalExpression(TreeBuilder&);
207     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseBinaryExpression(TreeBuilder&);
208     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseUnaryExpression(TreeBuilder&);
209     template <class TreeBuilder> TreeExpression parseMemberExpression(TreeBuilder&);
210     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parsePrimaryExpression(TreeBuilder&);
211     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArrayLiteral(TreeBuilder&);
212     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseObjectLiteral(TreeBuilder&);
213     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&);
214     template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&);
215     template <bool strict, class TreeBuilder> ALWAYS_INLINE TreeProperty parseProperty(TreeBuilder&);
216     template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&);
217     template <class TreeBuilder> ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&);
218     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, const Identifier*& lastIdent, TreeExpression& lastInitializer, int& identStart, int& initStart, int& initEnd);
219     template <class TreeBuilder> ALWAYS_INLINE TreeConstDeclList parseConstDeclarationList(TreeBuilder& context);
220     enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName };
221     template <FunctionRequirements, bool nameIsInContainingScope, class TreeBuilder> bool parseFunctionInfo(TreeBuilder&, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, int& openBrace, int& closeBrace, int& bodyStartLine);
222     ALWAYS_INLINE int isBinaryOperator(JSTokenType token);
223     bool allowAutomaticSemicolon();
224
225     bool autoSemiColon()
226     {
227         if (m_token.m_type == SEMICOLON) {
228             next();
229             return true;
230         }
231         return allowAutomaticSemicolon();
232     }
233
234     bool canRecurse()
235     {
236         return m_stack.recursionCheck();
237     }
238     
239     int lastTokenEnd() const
240     {
241         return m_lastTokenEnd;
242     }
243
244     ParserArena m_arena;
245     Lexer* m_lexer;
246     StackBounds m_stack;
247     bool m_error;
248     const char* m_errorMessage;
249     JSGlobalData* m_globalData;
250     JSToken m_token;
251     bool m_allowsIn;
252     int m_lastLine;
253     int m_lastTokenEnd;
254     int m_assignmentCount;
255     int m_nonLHSCount;
256     bool m_syntaxAlreadyValidated;
257     int m_statementDepth;
258     int m_nonTrivialExpressionCount;
259     const Identifier* m_lastIdentifier;
260
261     struct DepthManager {
262         DepthManager(int* depth)
263             : m_originalDepth(*depth)
264             , m_depth(depth)
265         {
266         }
267         
268         ~DepthManager()
269         {
270             *m_depth = m_originalDepth;
271         }
272         
273     private:
274         int m_originalDepth;
275         int* m_depth;
276     };
277     
278     struct Scope {
279         Scope(JSGlobalData* globalData, bool isFunction, bool strictMode)
280             : m_globalData(globalData)
281             , m_shadowsArguments(false)
282             , m_usesEval(false)
283             , m_needsFullActivation(false)
284             , m_allowsNewDecls(true)
285             , m_strictMode(strictMode)
286             , m_isFunction(isFunction)
287             , m_isFunctionBoundary(false)
288             , m_isValidStrictMode(true)
289             , m_loopDepth(0)
290             , m_switchDepth(0)
291             , m_labels(0)
292         {
293         }
294         
295         void startSwitch() { m_switchDepth++; }
296         void endSwitch() { m_switchDepth--; }
297         void startLoop() { m_loopDepth++; }
298         void endLoop() { ASSERT(m_loopDepth); m_loopDepth--; }
299         bool inLoop() { return !!m_loopDepth; }
300         bool breakIsValid() { return m_loopDepth || m_switchDepth; }
301         bool continueIsValid() { return m_loopDepth; }
302
303         void pushLabel(const Identifier* label, bool isLoop)
304         {
305             if (!m_labels)
306                 m_labels = new LabelStack;
307             m_labels->append(ScopeLabelInfo(label->impl(), isLoop));
308         }
309
310         void popLabel()
311         {
312             ASSERT(m_labels);
313             ASSERT(m_labels->size());
314             m_labels->removeLast();
315         }
316
317         ScopeLabelInfo* getLabel(const Identifier* label)
318         {
319             if (!m_labels)
320                 return 0;
321             for (int i = m_labels->size(); i > 0; i--) {
322                 if (m_labels->at(i - 1).m_ident == label->impl())
323                     return &m_labels->at(i - 1);
324             }
325             return 0;
326         }
327
328         void setIsFunction()
329         {
330             m_isFunction = true;
331             m_isFunctionBoundary = true;
332         }
333         bool isFunction() { return m_isFunction; }
334         bool isFunctionBoundary() { return m_isFunctionBoundary; }
335         
336         bool declareVariable(const Identifier* ident)
337         {
338             bool isValidStrictMode = m_globalData->propertyNames->eval != *ident && m_globalData->propertyNames->arguments != *ident;
339             m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
340             m_declaredVariables.add(ident->ustring().impl());
341             return isValidStrictMode;
342         }
343         
344         void declareWrite(const Identifier* ident)
345         {
346             ASSERT(m_strictMode);
347             m_writtenVariables.add(ident->impl());
348         }
349
350         void preventNewDecls() { m_allowsNewDecls = false; }
351         bool allowsNewDecls() const { return m_allowsNewDecls; }
352
353         bool declareParameter(const Identifier* ident)
354         {
355             bool isArguments = m_globalData->propertyNames->arguments == *ident;
356             bool isValidStrictMode = m_declaredVariables.add(ident->ustring().impl()).second && m_globalData->propertyNames->eval != *ident && !isArguments;
357             m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
358             if (isArguments)
359                 m_shadowsArguments = true;
360             return isValidStrictMode;
361         }
362         
363         void useVariable(const Identifier* ident, bool isEval)
364         {
365             m_usesEval |= isEval;
366             m_usedVariables.add(ident->ustring().impl());
367         }
368         
369         void setNeedsFullActivation() { m_needsFullActivation = true; }
370         
371         bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
372         {
373             if (nestedScope->m_usesEval)
374                 m_usesEval = true;
375             IdentifierSet::iterator end = nestedScope->m_usedVariables.end();
376             for (IdentifierSet::iterator ptr = nestedScope->m_usedVariables.begin(); ptr != end; ++ptr) {
377                 if (nestedScope->m_declaredVariables.contains(*ptr))
378                     continue;
379                 m_usedVariables.add(*ptr);
380                 if (shouldTrackClosedVariables)
381                     m_closedVariables.add(*ptr);
382             }
383             if (nestedScope->m_writtenVariables.size()) {
384                 IdentifierSet::iterator end = nestedScope->m_writtenVariables.end();
385                 for (IdentifierSet::iterator ptr = nestedScope->m_writtenVariables.begin(); ptr != end; ++ptr) {
386                     if (nestedScope->m_declaredVariables.contains(*ptr))
387                         continue;
388                     m_writtenVariables.add(*ptr);
389                 }
390             }
391
392             return true;
393         }
394
395         void getUncapturedWrittenVariables(IdentifierSet& writtenVariables)
396         {
397             IdentifierSet::iterator end = m_writtenVariables.end();
398             for (IdentifierSet::iterator ptr = m_writtenVariables.begin(); ptr != end; ++ptr) {
399                 if (!m_declaredVariables.contains(*ptr))
400                     writtenVariables.add(*ptr);
401             }
402         }
403
404         void getCapturedVariables(IdentifierSet& capturedVariables)
405         {
406             if (m_needsFullActivation || m_usesEval) {
407                 capturedVariables.swap(m_declaredVariables);
408                 return;
409             }
410             for (IdentifierSet::iterator ptr = m_closedVariables.begin(); ptr != m_closedVariables.end(); ++ptr) {
411                 if (!m_declaredVariables.contains(*ptr))
412                     continue;
413                 capturedVariables.add(*ptr);
414             }
415         }
416         void setStrictMode() { m_strictMode = true; }
417         bool strictMode() const { return m_strictMode; }
418         bool isValidStrictMode() const { return m_isValidStrictMode; }
419         bool shadowsArguments() const { return m_shadowsArguments; }
420
421     private:
422         JSGlobalData* m_globalData;
423         bool m_shadowsArguments : 1;
424         bool m_usesEval : 1;
425         bool m_needsFullActivation : 1;
426         bool m_allowsNewDecls : 1;
427         bool m_strictMode : 1;
428         bool m_isFunction : 1;
429         bool m_isFunctionBoundary : 1;
430         bool m_isValidStrictMode : 1;
431         int m_loopDepth;
432         int m_switchDepth;
433
434         typedef Vector<ScopeLabelInfo, 2> LabelStack;
435         LabelStack* m_labels;
436         IdentifierSet m_declaredVariables;
437         IdentifierSet m_usedVariables;
438         IdentifierSet m_closedVariables;
439         IdentifierSet m_writtenVariables;
440     };
441     
442     typedef Vector<Scope, 10> ScopeStack;
443
444     struct ScopeRef {
445         ScopeRef(ScopeStack* scopeStack, unsigned index)
446             : m_scopeStack(scopeStack)
447             , m_index(index)
448         {
449         }
450         Scope* operator->() { return &m_scopeStack->at(m_index); }
451         unsigned index() const { return m_index; }
452
453         bool hasContainingScope()
454         {
455             return m_index && !m_scopeStack->at(m_index).isFunctionBoundary();
456         }
457
458         ScopeRef containingScope()
459         {
460             ASSERT(hasContainingScope());
461             return ScopeRef(m_scopeStack, m_index - 1);
462         }
463
464     private:
465         ScopeStack* m_scopeStack;
466         unsigned m_index;
467     };
468
469     struct AutoPopScopeRef : public ScopeRef {
470         AutoPopScopeRef(JSParser* parser, ScopeRef scope)
471             : ScopeRef(scope)
472             , m_parser(parser)
473         {
474         }
475
476         ~AutoPopScopeRef()
477         {
478             if (m_parser)
479                 m_parser->popScope(*this, false);
480         }
481
482         void setPopped()
483         {
484             m_parser = 0;
485         }
486
487     private:
488         JSParser* m_parser;
489     };
490
491     ScopeRef currentScope()
492     {
493         return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
494     }
495     
496     ScopeRef pushScope()
497     {
498         bool isFunction = false;
499         bool isStrict = false;
500         if (!m_scopeStack.isEmpty()) {
501             isStrict = m_scopeStack.last().strictMode();
502             isFunction = m_scopeStack.last().isFunction();
503         }
504         m_scopeStack.append(Scope(m_globalData, isFunction, isStrict));
505         return currentScope();
506     }
507
508     bool popScopeInternal(ScopeRef& scope, bool shouldTrackClosedVariables)
509     {
510         ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1);
511         ASSERT(m_scopeStack.size() > 1);
512         bool result = m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
513         m_scopeStack.removeLast();
514         return result;
515     }
516
517     bool popScope(ScopeRef& scope, bool shouldTrackClosedVariables)
518     {
519         return popScopeInternal(scope, shouldTrackClosedVariables);
520     }
521
522     bool popScope(AutoPopScopeRef& scope, bool shouldTrackClosedVariables)
523     {
524         scope.setPopped();
525         return popScopeInternal(scope, shouldTrackClosedVariables);
526     }
527
528     bool declareVariable(const Identifier* ident)
529     {
530         unsigned i = m_scopeStack.size() - 1;
531         ASSERT(i < m_scopeStack.size());
532         while (!m_scopeStack[i].allowsNewDecls()) {
533             i--;
534             ASSERT(i < m_scopeStack.size());
535         }
536         return m_scopeStack[i].declareVariable(ident);
537     }
538     
539     void declareWrite(const Identifier* ident)
540     {
541         if (!m_syntaxAlreadyValidated)
542             m_scopeStack.last().declareWrite(ident);
543     }
544
545     ScopeStack m_scopeStack;
546 };
547
548 const char* jsParse(JSGlobalData* globalData, FunctionParameters* parameters, JSParserStrictness strictness, JSParserMode parserMode, const SourceCode* source)
549 {
550     JSParser parser(globalData->lexer, globalData, parameters, strictness == JSParseStrict, parserMode == JSParseFunctionCode, source->provider());
551     return parser.parseProgram();
552 }
553
554 JSParser::JSParser(Lexer* lexer, JSGlobalData* globalData, FunctionParameters* parameters, bool inStrictContext, bool isFunction, SourceProvider* provider)
555     : m_lexer(lexer)
556     , m_stack(globalData->stack())
557     , m_error(false)
558     , m_errorMessage("Parse error")
559     , m_globalData(globalData)
560     , m_allowsIn(true)
561     , m_lastLine(0)
562     , m_lastTokenEnd(0)
563     , m_assignmentCount(0)
564     , m_nonLHSCount(0)
565     , m_syntaxAlreadyValidated(provider->isValid())
566     , m_statementDepth(0)
567     , m_nonTrivialExpressionCount(0)
568     , m_lastIdentifier(0)
569 {
570     ScopeRef scope = pushScope();
571     if (isFunction)
572         scope->setIsFunction();
573     if (inStrictContext)
574         scope->setStrictMode();
575     if (parameters) {
576         for (unsigned i = 0; i < parameters->size(); i++)
577             scope->declareParameter(&parameters->at(i));
578     }
579     next();
580     m_lexer->setLastLineNumber(tokenLine());
581 }
582
583 const char* JSParser::parseProgram()
584 {
585     ASTBuilder context(m_globalData, m_lexer);
586     if (m_lexer->isReparsing())
587         m_statementDepth--;
588     ScopeRef scope = currentScope();
589     SourceElements* sourceElements = parseSourceElements<CheckForStrictMode>(context);
590     if (!sourceElements || !consume(EOFTOK))
591         return m_errorMessage;
592     IdentifierSet capturedVariables;
593     scope->getCapturedVariables(capturedVariables);
594     CodeFeatures features = context.features();
595     if (scope->strictMode())
596         features |= StrictModeFeature;
597     if (scope->shadowsArguments())
598         features |= ShadowsArgumentsFeature;
599
600     m_globalData->parser->didFinishParsing(sourceElements, context.varDeclarations(), context.funcDeclarations(), features,
601                                            m_lastLine, context.numConstants(), capturedVariables);
602     return 0;
603 }
604
605 bool JSParser::allowAutomaticSemicolon()
606 {
607     return match(CLOSEBRACE) || match(EOFTOK) || m_lexer->prevTerminator();
608 }
609
610 template <JSParser::SourceElementsMode mode, class TreeBuilder> TreeSourceElements JSParser::parseSourceElements(TreeBuilder& context)
611 {
612     TreeSourceElements sourceElements = context.createSourceElements();
613     bool seenNonDirective = false;
614     const Identifier* directive = 0;
615     unsigned startOffset = m_token.m_info.startOffset;
616     bool hasSetStrict = false;
617     while (TreeStatement statement = parseStatement(context, directive)) {
618         if (mode == CheckForStrictMode && !seenNonDirective) {
619             if (directive) {
620                 if (!hasSetStrict && m_globalData->propertyNames->useStrictIdentifier == *directive) {
621                     setStrictMode();
622                     hasSetStrict = true;
623                     failIfFalse(isValidStrictMode());
624                     m_lexer->setOffset(startOffset);
625                     next();
626                     failIfTrue(m_error);
627                     continue;
628                 }
629             } else
630                 seenNonDirective = true;
631         }
632         context.appendStatement(sourceElements, statement);
633     }
634
635     if (m_error)
636         fail();
637     return sourceElements;
638 }
639
640 template <class TreeBuilder> TreeStatement JSParser::parseVarDeclaration(TreeBuilder& context)
641 {
642     ASSERT(match(VAR));
643     int start = tokenLine();
644     int end = 0;
645     int scratch;
646     const Identifier* scratch1 = 0;
647     TreeExpression scratch2 = 0;
648     int scratch3 = 0;
649     TreeExpression varDecls = parseVarDeclarationList(context, scratch, scratch1, scratch2, scratch3, scratch3, scratch3);
650     failIfTrue(m_error);
651     failIfFalse(autoSemiColon());
652
653     return context.createVarStatement(varDecls, start, end);
654 }
655
656 template <class TreeBuilder> TreeStatement JSParser::parseConstDeclaration(TreeBuilder& context)
657 {
658     ASSERT(match(CONSTTOKEN));
659     int start = tokenLine();
660     int end = 0;
661     TreeConstDeclList constDecls = parseConstDeclarationList(context);
662     failIfTrue(m_error);
663     failIfFalse(autoSemiColon());
664     
665     return context.createConstStatement(constDecls, start, end);
666 }
667
668 template <class TreeBuilder> TreeStatement JSParser::parseDoWhileStatement(TreeBuilder& context)
669 {
670     ASSERT(match(DO));
671     int startLine = tokenLine();
672     next();
673     const Identifier* unused = 0;
674     startLoop();
675     TreeStatement statement = parseStatement(context, unused);
676     endLoop();
677     failIfFalse(statement);
678     int endLine = tokenLine();
679     consumeOrFail(WHILE);
680     consumeOrFail(OPENPAREN);
681     TreeExpression expr = parseExpression(context);
682     failIfFalse(expr);
683     consumeOrFail(CLOSEPAREN);
684     if (match(SEMICOLON))
685         next(); // Always performs automatic semicolon insertion.
686     return context.createDoWhileStatement(statement, expr, startLine, endLine);
687 }
688
689 template <class TreeBuilder> TreeStatement JSParser::parseWhileStatement(TreeBuilder& context)
690 {
691     ASSERT(match(WHILE));
692     int startLine = tokenLine();
693     next();
694     consumeOrFail(OPENPAREN);
695     TreeExpression expr = parseExpression(context);
696     failIfFalse(expr);
697     int endLine = tokenLine();
698     consumeOrFail(CLOSEPAREN);
699     const Identifier* unused = 0;
700     startLoop();
701     TreeStatement statement = parseStatement(context, unused);
702     endLoop();
703     failIfFalse(statement);
704     return context.createWhileStatement(expr, statement, startLine, endLine);
705 }
706
707 template <class TreeBuilder> TreeExpression JSParser::parseVarDeclarationList(TreeBuilder& context, int& declarations, const Identifier*& lastIdent, TreeExpression& lastInitializer, int& identStart, int& initStart, int& initEnd)
708 {
709     TreeExpression varDecls = 0;
710     do {
711         declarations++;
712         next();
713         matchOrFail(IDENT);
714
715         int varStart = tokenStart();
716         identStart = varStart;
717         const Identifier* name = m_token.m_data.ident;
718         lastIdent = name;
719         next();
720         bool hasInitializer = match(EQUAL);
721         failIfFalseIfStrict(declareVariable(name));
722         context.addVar(name, (hasInitializer || (!m_allowsIn && match(INTOKEN))) ? DeclarationStacks::HasInitializer : 0);
723         if (hasInitializer) {
724             int varDivot = tokenStart() + 1;
725             initStart = tokenStart();
726             next(); // consume '='
727             int initialAssignments = m_assignmentCount;
728             TreeExpression initializer = parseAssignmentExpression(context);
729             initEnd = lastTokenEnd();
730             lastInitializer = initializer;
731             failIfFalse(initializer);
732
733             TreeExpression node = context.createAssignResolve(*name, initializer, initialAssignments != m_assignmentCount, varStart, varDivot, lastTokenEnd());
734             if (!varDecls)
735                 varDecls = node;
736             else
737                 varDecls = context.combineCommaNodes(varDecls, node);
738         }
739     } while (match(COMMA));
740     return varDecls;
741 }
742
743 template <class TreeBuilder> TreeConstDeclList JSParser::parseConstDeclarationList(TreeBuilder& context)
744 {
745     failIfTrue(strictMode());
746     TreeConstDeclList constDecls = 0;
747     TreeConstDeclList tail = 0;
748     do {
749         next();
750         matchOrFail(IDENT);
751         const Identifier* name = m_token.m_data.ident;
752         next();
753         bool hasInitializer = match(EQUAL);
754         declareVariable(name);
755         context.addVar(name, DeclarationStacks::IsConstant | (hasInitializer ? DeclarationStacks::HasInitializer : 0));
756         TreeExpression initializer = 0;
757         if (hasInitializer) {
758             next(); // consume '='
759             initializer = parseAssignmentExpression(context);
760         }
761         tail = context.appendConstDecl(tail, name, initializer);
762         if (!constDecls)
763             constDecls = tail;
764     } while (match(COMMA));
765     return constDecls;
766 }
767
768 template <class TreeBuilder> TreeStatement JSParser::parseForStatement(TreeBuilder& context)
769 {
770     ASSERT(match(FOR));
771     int startLine = tokenLine();
772     next();
773     consumeOrFail(OPENPAREN);
774     int nonLHSCount = m_nonLHSCount;
775     int declarations = 0;
776     int declsStart = 0;
777     int declsEnd = 0;
778     TreeExpression decls = 0;
779     bool hasDeclaration = false;
780     if (match(VAR)) {
781         /*
782          for (var IDENT in expression) statement
783          for (var IDENT = expression in expression) statement
784          for (var varDeclarationList; expressionOpt; expressionOpt)
785          */
786         hasDeclaration = true;
787         const Identifier* forInTarget = 0;
788         TreeExpression forInInitializer = 0;
789         m_allowsIn = false;
790         int initStart = 0;
791         int initEnd = 0;
792         decls = parseVarDeclarationList(context, declarations, forInTarget, forInInitializer, declsStart, initStart, initEnd);
793         m_allowsIn = true;
794         if (m_error)
795             fail();
796
797         // Remainder of a standard for loop is handled identically
798         if (match(SEMICOLON))
799             goto standardForLoop;
800
801         failIfFalse(declarations == 1);
802
803         // Handle for-in with var declaration
804         int inLocation = tokenStart();
805         if (!consume(INTOKEN))
806             fail();
807
808         TreeExpression expr = parseExpression(context);
809         failIfFalse(expr);
810         int exprEnd = lastTokenEnd();
811
812         int endLine = tokenLine();
813         consumeOrFail(CLOSEPAREN);
814
815         const Identifier* unused = 0;
816         startLoop();
817         TreeStatement statement = parseStatement(context, unused);
818         endLoop();
819         failIfFalse(statement);
820
821         return context.createForInLoop(forInTarget, forInInitializer, expr, statement, declsStart, inLocation, exprEnd, initStart, initEnd, startLine, endLine);
822     }
823
824     if (!match(SEMICOLON)) {
825         m_allowsIn = false;
826         declsStart = tokenStart();
827         decls = parseExpression(context);
828         declsEnd = lastTokenEnd();
829         m_allowsIn = true;
830         failIfFalse(decls);
831     }
832
833     if (match(SEMICOLON)) {
834     standardForLoop:
835         // Standard for loop
836         next();
837         TreeExpression condition = 0;
838
839         if (!match(SEMICOLON)) {
840             condition = parseExpression(context);
841             failIfFalse(condition);
842         }
843         consumeOrFail(SEMICOLON);
844
845         TreeExpression increment = 0;
846         if (!match(CLOSEPAREN)) {
847             increment = parseExpression(context);
848             failIfFalse(increment);
849         }
850         int endLine = tokenLine();
851         consumeOrFail(CLOSEPAREN);
852         const Identifier* unused = 0;
853         startLoop();
854         TreeStatement statement = parseStatement(context, unused);
855         endLoop();
856         failIfFalse(statement);
857         return context.createForLoop(decls, condition, increment, statement, hasDeclaration, startLine, endLine);
858     }
859
860     // For-in loop
861     failIfFalse(nonLHSCount == m_nonLHSCount);
862     consumeOrFail(INTOKEN);
863     TreeExpression expr = parseExpression(context);
864     failIfFalse(expr);
865     int exprEnd = lastTokenEnd();
866     int endLine = tokenLine();
867     consumeOrFail(CLOSEPAREN);
868     const Identifier* unused = 0;
869     startLoop();
870     TreeStatement statement = parseStatement(context, unused);
871     endLoop();
872     failIfFalse(statement);
873     
874     return context.createForInLoop(decls, expr, statement, declsStart, declsEnd, exprEnd, startLine, endLine);
875 }
876
877 template <class TreeBuilder> TreeStatement JSParser::parseBreakStatement(TreeBuilder& context)
878 {
879     ASSERT(match(BREAK));
880     int startCol = tokenStart();
881     int endCol = tokenEnd();
882     int startLine = tokenLine();
883     int endLine = tokenLine();
884     next();
885
886     if (autoSemiColon()) {
887         failIfFalse(breakIsValid());
888         return context.createBreakStatement(startCol, endCol, startLine, endLine);
889     }
890     matchOrFail(IDENT);
891     const Identifier* ident = m_token.m_data.ident;
892     failIfFalse(getLabel(ident));
893     endCol = tokenEnd();
894     endLine = tokenLine();
895     next();
896     failIfFalse(autoSemiColon());
897     return context.createBreakStatement(ident, startCol, endCol, startLine, endLine);
898 }
899
900 template <class TreeBuilder> TreeStatement JSParser::parseContinueStatement(TreeBuilder& context)
901 {
902     ASSERT(match(CONTINUE));
903     int startCol = tokenStart();
904     int endCol = tokenEnd();
905     int startLine = tokenLine();
906     int endLine = tokenLine();
907     next();
908
909     if (autoSemiColon()) {
910         failIfFalse(continueIsValid());
911         return context.createContinueStatement(startCol, endCol, startLine, endLine);
912     }
913     matchOrFail(IDENT);
914     const Identifier* ident = m_token.m_data.ident;
915     ScopeLabelInfo* label = getLabel(ident);
916     failIfFalse(label);
917     failIfFalse(label->m_isLoop);
918     endCol = tokenEnd();
919     endLine = tokenLine();
920     next();
921     failIfFalse(autoSemiColon());
922     return context.createContinueStatement(ident, startCol, endCol, startLine, endLine);
923 }
924
925 template <class TreeBuilder> TreeStatement JSParser::parseReturnStatement(TreeBuilder& context)
926 {
927     ASSERT(match(RETURN));
928     failIfFalse(currentScope()->isFunction());
929     int startLine = tokenLine();
930     int endLine = startLine;
931     int start = tokenStart();
932     int end = tokenEnd();
933     next();
934     // We do the auto semicolon check before attempting to parse an expression
935     // as we need to ensure the a line break after the return correctly terminates
936     // the statement
937     if (match(SEMICOLON))
938         endLine  = tokenLine();
939     if (autoSemiColon())
940         return context.createReturnStatement(0, start, end, startLine, endLine);
941     TreeExpression expr = parseExpression(context);
942     failIfFalse(expr);
943     end = lastTokenEnd();
944     if (match(SEMICOLON))
945         endLine  = tokenLine();
946     failIfFalse(autoSemiColon());
947     return context.createReturnStatement(expr, start, end, startLine, endLine);
948 }
949
950 template <class TreeBuilder> TreeStatement JSParser::parseThrowStatement(TreeBuilder& context)
951 {
952     ASSERT(match(THROW));
953     int eStart = tokenStart();
954     int startLine = tokenLine();
955     next();
956     
957     failIfTrue(autoSemiColon());
958
959     TreeExpression expr = parseExpression(context);
960     failIfFalse(expr);
961     int eEnd = lastTokenEnd();
962     int endLine = tokenLine();
963     failIfFalse(autoSemiColon());
964
965     return context.createThrowStatement(expr, eStart, eEnd, startLine, endLine);
966 }
967
968 template <class TreeBuilder> TreeStatement JSParser::parseWithStatement(TreeBuilder& context)
969 {
970     ASSERT(match(WITH));
971     failIfTrue(strictMode());
972     currentScope()->setNeedsFullActivation();
973     int startLine = tokenLine();
974     next();
975     consumeOrFail(OPENPAREN);
976     int start = tokenStart();
977     TreeExpression expr = parseExpression(context);
978     failIfFalse(expr);
979     int end = lastTokenEnd();
980
981     int endLine = tokenLine();
982     consumeOrFail(CLOSEPAREN);
983     const Identifier* unused = 0;
984     TreeStatement statement = parseStatement(context, unused);
985     failIfFalse(statement);
986
987     return context.createWithStatement(expr, statement, start, end, startLine, endLine);
988 }
989
990 template <class TreeBuilder> TreeStatement JSParser::parseSwitchStatement(TreeBuilder& context)
991 {
992     ASSERT(match(SWITCH));
993     int startLine = tokenLine();
994     next();
995     consumeOrFail(OPENPAREN);
996     TreeExpression expr = parseExpression(context);
997     failIfFalse(expr);
998     int endLine = tokenLine();
999     consumeOrFail(CLOSEPAREN);
1000     consumeOrFail(OPENBRACE);
1001     startSwitch();
1002     TreeClauseList firstClauses = parseSwitchClauses(context);
1003     failIfTrue(m_error);
1004
1005     TreeClause defaultClause = parseSwitchDefaultClause(context);
1006     failIfTrue(m_error);
1007
1008     TreeClauseList secondClauses = parseSwitchClauses(context);
1009     failIfTrue(m_error);
1010     endSwitch();
1011     consumeOrFail(CLOSEBRACE);
1012
1013     return context.createSwitchStatement(expr, firstClauses, defaultClause, secondClauses, startLine, endLine);
1014
1015 }
1016
1017 template <class TreeBuilder> TreeClauseList JSParser::parseSwitchClauses(TreeBuilder& context)
1018 {
1019     if (!match(CASE))
1020         return 0;
1021     next();
1022     TreeExpression condition = parseExpression(context);
1023     failIfFalse(condition);
1024     consumeOrFail(COLON);
1025     TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context);
1026     failIfFalse(statements);
1027     TreeClause clause = context.createClause(condition, statements);
1028     TreeClauseList clauseList = context.createClauseList(clause);
1029     TreeClauseList tail = clauseList;
1030
1031     while (match(CASE)) {
1032         next();
1033         TreeExpression condition = parseExpression(context);
1034         failIfFalse(condition);
1035         consumeOrFail(COLON);
1036         TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context);
1037         failIfFalse(statements);
1038         clause = context.createClause(condition, statements);
1039         tail = context.createClauseList(tail, clause);
1040     }
1041     return clauseList;
1042 }
1043
1044 template <class TreeBuilder> TreeClause JSParser::parseSwitchDefaultClause(TreeBuilder& context)
1045 {
1046     if (!match(DEFAULT))
1047         return 0;
1048     next();
1049     consumeOrFail(COLON);
1050     TreeSourceElements statements = parseSourceElements<DontCheckForStrictMode>(context);
1051     failIfFalse(statements);
1052     return context.createClause(0, statements);
1053 }
1054
1055 template <class TreeBuilder> TreeStatement JSParser::parseTryStatement(TreeBuilder& context)
1056 {
1057     ASSERT(match(TRY));
1058     TreeStatement tryBlock = 0;
1059     const Identifier* ident = &m_globalData->propertyNames->nullIdentifier;
1060     bool catchHasEval = false;
1061     TreeStatement catchBlock = 0;
1062     TreeStatement finallyBlock = 0;
1063     int firstLine = tokenLine();
1064     next();
1065     matchOrFail(OPENBRACE);
1066
1067     tryBlock = parseBlockStatement(context);
1068     failIfFalse(tryBlock);
1069     int lastLine = m_lastLine;
1070
1071     if (match(CATCH)) {
1072         currentScope()->setNeedsFullActivation();
1073         next();
1074         consumeOrFail(OPENPAREN);
1075         matchOrFail(IDENT);
1076         ident = m_token.m_data.ident;
1077         next();
1078         AutoPopScopeRef catchScope(this, pushScope());
1079         failIfFalseIfStrict(catchScope->declareVariable(ident));
1080         catchScope->preventNewDecls();
1081         consumeOrFail(CLOSEPAREN);
1082         matchOrFail(OPENBRACE);
1083         int initialEvalCount = context.evalCount();
1084         catchBlock = parseBlockStatement(context);
1085         failIfFalse(catchBlock);
1086         catchHasEval = initialEvalCount != context.evalCount();
1087         failIfFalse(popScope(catchScope, TreeBuilder::NeedsFreeVariableInfo));
1088     }
1089
1090     if (match(FINALLY)) {
1091         next();
1092         matchOrFail(OPENBRACE);
1093         finallyBlock = parseBlockStatement(context);
1094         failIfFalse(finallyBlock);
1095     }
1096     failIfFalse(catchBlock || finallyBlock);
1097     return context.createTryStatement(tryBlock, ident, catchHasEval, catchBlock, finallyBlock, firstLine, lastLine);
1098 }
1099
1100 template <class TreeBuilder> TreeStatement JSParser::parseDebuggerStatement(TreeBuilder& context)
1101 {
1102     ASSERT(match(DEBUGGER));
1103     int startLine = tokenLine();
1104     int endLine = startLine;
1105     next();
1106     if (match(SEMICOLON))
1107         startLine = tokenLine();
1108     failIfFalse(autoSemiColon());
1109     return context.createDebugger(startLine, endLine);
1110 }
1111
1112 template <class TreeBuilder> TreeStatement JSParser::parseBlockStatement(TreeBuilder& context)
1113 {
1114     ASSERT(match(OPENBRACE));
1115     int start = tokenLine();
1116     next();
1117     if (match(CLOSEBRACE)) {
1118         next();
1119         return context.createBlockStatement(0, start, m_lastLine);
1120     }
1121     TreeSourceElements subtree = parseSourceElements<DontCheckForStrictMode>(context);
1122     failIfFalse(subtree);
1123     matchOrFail(CLOSEBRACE);
1124     next();
1125     return context.createBlockStatement(subtree, start, m_lastLine);
1126 }
1127
1128 template <class TreeBuilder> TreeStatement JSParser::parseStatement(TreeBuilder& context, const Identifier*& directive)
1129 {
1130     DepthManager statementDepth(&m_statementDepth);
1131     m_statementDepth++;
1132     directive = 0;
1133     int nonTrivialExpressionCount = 0;
1134     failIfStackOverflow();
1135     switch (m_token.m_type) {
1136     case OPENBRACE:
1137         return parseBlockStatement(context);
1138     case VAR:
1139         return parseVarDeclaration(context);
1140     case CONSTTOKEN:
1141         return parseConstDeclaration(context);
1142     case FUNCTION:
1143         failIfFalseIfStrict(m_statementDepth == 1);
1144         return parseFunctionDeclaration(context);
1145     case SEMICOLON:
1146         next();
1147         return context.createEmptyStatement();
1148     case IF:
1149         return parseIfStatement(context);
1150     case DO:
1151         return parseDoWhileStatement(context);
1152     case WHILE:
1153         return parseWhileStatement(context);
1154     case FOR:
1155         return parseForStatement(context);
1156     case CONTINUE:
1157         return parseContinueStatement(context);
1158     case BREAK:
1159         return parseBreakStatement(context);
1160     case RETURN:
1161         return parseReturnStatement(context);
1162     case WITH:
1163         return parseWithStatement(context);
1164     case SWITCH:
1165         return parseSwitchStatement(context);
1166     case THROW:
1167         return parseThrowStatement(context);
1168     case TRY:
1169         return parseTryStatement(context);
1170     case DEBUGGER:
1171         return parseDebuggerStatement(context);
1172     case EOFTOK:
1173     case CASE:
1174     case CLOSEBRACE:
1175     case DEFAULT:
1176         // These tokens imply the end of a set of source elements
1177         return 0;
1178     case IDENT:
1179         return parseExpressionOrLabelStatement(context);
1180     case STRING:
1181         directive = m_token.m_data.ident;
1182         nonTrivialExpressionCount = m_nonTrivialExpressionCount;
1183     default:
1184         TreeStatement exprStatement = parseExpressionStatement(context);
1185         if (directive && nonTrivialExpressionCount != m_nonTrivialExpressionCount)
1186             directive = 0;
1187         return exprStatement;
1188     }
1189 }
1190
1191 template <class TreeBuilder> TreeFormalParameterList JSParser::parseFormalParameters(TreeBuilder& context)
1192 {
1193     matchOrFail(IDENT);
1194     failIfFalseIfStrict(declareParameter(m_token.m_data.ident));
1195     TreeFormalParameterList list = context.createFormalParameterList(*m_token.m_data.ident);
1196     TreeFormalParameterList tail = list;
1197     next();
1198     while (match(COMMA)) {
1199         next();
1200         matchOrFail(IDENT);
1201         const Identifier* ident = m_token.m_data.ident;
1202         failIfFalseIfStrict(declareParameter(ident));
1203         next();
1204         tail = context.createFormalParameterList(tail, *ident);
1205     }
1206     return list;
1207 }
1208
1209 template <class TreeBuilder> TreeFunctionBody JSParser::parseFunctionBody(TreeBuilder& context)
1210 {
1211     if (match(CLOSEBRACE))
1212         return context.createFunctionBody(strictMode());
1213     DepthManager statementDepth(&m_statementDepth);
1214     m_statementDepth = 0;
1215     typename TreeBuilder::FunctionBodyBuilder bodyBuilder(m_globalData, m_lexer);
1216     failIfFalse(parseSourceElements<CheckForStrictMode>(bodyBuilder));
1217     return context.createFunctionBody(strictMode());
1218 }
1219
1220 template <JSParser::FunctionRequirements requirements, bool nameIsInContainingScope, class TreeBuilder> bool JSParser::parseFunctionInfo(TreeBuilder& context, const Identifier*& name, TreeFormalParameterList& parameters, TreeFunctionBody& body, int& openBracePos, int& closeBracePos, int& bodyStartLine)
1221 {
1222     AutoPopScopeRef functionScope(this, pushScope());
1223     functionScope->setIsFunction();
1224     if (match(IDENT)) {
1225         name = m_token.m_data.ident;
1226         failIfTrue(*name == m_globalData->propertyNames->underscoreProto);
1227         next();
1228         if (!nameIsInContainingScope)
1229             failIfFalseIfStrict(functionScope->declareVariable(name));
1230     } else if (requirements == FunctionNeedsName)
1231         return false;
1232     consumeOrFail(OPENPAREN);
1233     if (!match(CLOSEPAREN)) {
1234         parameters = parseFormalParameters(context);
1235         failIfFalse(parameters);
1236     }
1237     consumeOrFail(CLOSEPAREN);
1238     matchOrFail(OPENBRACE);
1239
1240     openBracePos = m_token.m_data.intValue;
1241     bodyStartLine = tokenLine();
1242     next();
1243
1244     body = parseFunctionBody(context);
1245     failIfFalse(body);
1246     if (functionScope->strictMode() && name) {
1247         failIfTrue(m_globalData->propertyNames->arguments == *name);
1248         failIfTrue(m_globalData->propertyNames->eval == *name);
1249     }
1250     failIfFalse(popScope(functionScope, TreeBuilder::NeedsFreeVariableInfo));
1251     matchOrFail(CLOSEBRACE);
1252     closeBracePos = m_token.m_data.intValue;
1253     next();
1254     return true;
1255 }
1256
1257 template <class TreeBuilder> TreeStatement JSParser::parseFunctionDeclaration(TreeBuilder& context)
1258 {
1259     ASSERT(match(FUNCTION));
1260     next();
1261     const Identifier* name = 0;
1262     TreeFormalParameterList parameters = 0;
1263     TreeFunctionBody body = 0;
1264     int openBracePos = 0;
1265     int closeBracePos = 0;
1266     int bodyStartLine = 0;
1267     failIfFalse((parseFunctionInfo<FunctionNeedsName, true>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
1268     failIfFalse(name);
1269     failIfFalseIfStrict(declareVariable(name));
1270     return context.createFuncDeclStatement(name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
1271 }
1272
1273 struct LabelInfo {
1274     LabelInfo(const Identifier* ident, int start, int end)
1275         : m_ident(ident)
1276         , m_start(start)
1277         , m_end(end)
1278     {
1279     }
1280
1281     const Identifier* m_ident;
1282     int m_start;
1283     int m_end;
1284 };
1285
1286 template <class TreeBuilder> TreeStatement JSParser::parseExpressionOrLabelStatement(TreeBuilder& context)
1287 {
1288
1289     /* Expression and Label statements are ambiguous at LL(1), so we have a
1290      * special case that looks for a colon as the next character in the input.
1291      */
1292     Vector<LabelInfo> labels;
1293
1294     do {
1295         int start = tokenStart();
1296         int startLine = tokenLine();
1297         if (!nextTokenIsColon()) {
1298             // If we hit this path we're making a expression statement, which
1299             // by definition can't make use of continue/break so we can just
1300             // ignore any labels we might have accumulated.
1301             TreeExpression expression = parseExpression(context);
1302             failIfFalse(expression);
1303             failIfFalse(autoSemiColon());
1304             return context.createExprStatement(expression, startLine, m_lastLine);
1305         }
1306         const Identifier* ident = m_token.m_data.ident;
1307         int end = tokenEnd();
1308         next();
1309         consumeOrFail(COLON);
1310         if (!m_syntaxAlreadyValidated) {
1311             // This is O(N^2) over the current list of consecutive labels, but I
1312             // have never seen more than one label in a row in the real world.
1313             for (size_t i = 0; i < labels.size(); i++)
1314                 failIfTrue(ident->impl() == labels[i].m_ident->impl());
1315             failIfTrue(getLabel(ident));
1316             labels.append(LabelInfo(ident, start, end));
1317         }
1318     } while (match(IDENT));
1319     bool isLoop = false;
1320     switch (m_token.m_type) {
1321     case FOR:
1322     case WHILE:
1323     case DO:
1324         isLoop = true;
1325         break;
1326
1327     default:
1328         break;
1329     }
1330     const Identifier* unused = 0;
1331     if (!m_syntaxAlreadyValidated) {
1332         for (size_t i = 0; i < labels.size(); i++)
1333             pushLabel(labels[i].m_ident, isLoop);
1334     }
1335     TreeStatement statement = parseStatement(context, unused);
1336     if (!m_syntaxAlreadyValidated) {
1337         for (size_t i = 0; i < labels.size(); i++)
1338             popLabel();
1339     }
1340     failIfFalse(statement);
1341     for (size_t i = 0; i < labels.size(); i++) {
1342         const LabelInfo& info = labels[labels.size() - i - 1];
1343         statement = context.createLabelStatement(info.m_ident, statement, info.m_start, info.m_end);
1344     }
1345     return statement;
1346 }
1347
1348 template <class TreeBuilder> TreeStatement JSParser::parseExpressionStatement(TreeBuilder& context)
1349 {
1350     int startLine = tokenLine();
1351     TreeExpression expression = parseExpression(context);
1352     failIfFalse(expression);
1353     failIfFalse(autoSemiColon());
1354     return context.createExprStatement(expression, startLine, m_lastLine);
1355 }
1356
1357 template <class TreeBuilder> TreeStatement JSParser::parseIfStatement(TreeBuilder& context)
1358 {
1359     ASSERT(match(IF));
1360
1361     int start = tokenLine();
1362     next();
1363
1364     consumeOrFail(OPENPAREN);
1365
1366     TreeExpression condition = parseExpression(context);
1367     failIfFalse(condition);
1368     int end = tokenLine();
1369     consumeOrFail(CLOSEPAREN);
1370
1371     const Identifier* unused = 0;
1372     TreeStatement trueBlock = parseStatement(context, unused);
1373     failIfFalse(trueBlock);
1374
1375     if (!match(ELSE))
1376         return context.createIfStatement(condition, trueBlock, start, end);
1377     
1378     Vector<TreeExpression> exprStack;
1379     Vector<pair<int, int> > posStack;
1380     Vector<TreeStatement> statementStack;
1381     bool trailingElse = false;
1382     do {
1383         next();
1384         if (!match(IF)) {
1385             const Identifier* unused = 0;
1386             TreeStatement block = parseStatement(context, unused);
1387             failIfFalse(block);
1388             statementStack.append(block);
1389             trailingElse = true;
1390             break;
1391         }
1392         int innerStart = tokenLine();
1393         next();
1394         
1395         consumeOrFail(OPENPAREN);
1396         
1397         TreeExpression innerCondition = parseExpression(context);
1398         failIfFalse(innerCondition);
1399         int innerEnd = tokenLine();
1400         consumeOrFail(CLOSEPAREN);
1401         const Identifier* unused = 0;
1402         TreeStatement innerTrueBlock = parseStatement(context, unused);
1403         failIfFalse(innerTrueBlock);     
1404         exprStack.append(innerCondition);
1405         posStack.append(make_pair(innerStart, innerEnd));
1406         statementStack.append(innerTrueBlock);
1407     } while (match(ELSE));
1408
1409     if (!trailingElse) {
1410         TreeExpression condition = exprStack.last();
1411         exprStack.removeLast();
1412         TreeStatement trueBlock = statementStack.last();
1413         statementStack.removeLast();
1414         pair<int, int> pos = posStack.last();
1415         posStack.removeLast();
1416         statementStack.append(context.createIfStatement(condition, trueBlock, pos.first, pos.second));
1417     }
1418
1419     while (!exprStack.isEmpty()) {
1420         TreeExpression condition = exprStack.last();
1421         exprStack.removeLast();
1422         TreeStatement falseBlock = statementStack.last();
1423         statementStack.removeLast();
1424         TreeStatement trueBlock = statementStack.last();
1425         statementStack.removeLast();
1426         pair<int, int> pos = posStack.last();
1427         posStack.removeLast();
1428         statementStack.append(context.createIfStatement(condition, trueBlock, falseBlock, pos.first, pos.second));
1429     }
1430     
1431     return context.createIfStatement(condition, trueBlock, statementStack.last(), start, end);
1432 }
1433
1434 template <class TreeBuilder> TreeExpression JSParser::parseExpression(TreeBuilder& context)
1435 {
1436     failIfStackOverflow();
1437     TreeExpression node = parseAssignmentExpression(context);
1438     failIfFalse(node);
1439     if (!match(COMMA))
1440         return node;
1441     next();
1442     m_nonTrivialExpressionCount++;
1443     m_nonLHSCount++;
1444     TreeExpression right = parseAssignmentExpression(context);
1445     failIfFalse(right);
1446     typename TreeBuilder::Comma commaNode = context.createCommaExpr(node, right);
1447     while (match(COMMA)) {
1448         next();
1449         right = parseAssignmentExpression(context);
1450         failIfFalse(right);
1451         context.appendToComma(commaNode, right);
1452     }
1453     return commaNode;
1454 }
1455
1456
1457 template <typename TreeBuilder> TreeExpression JSParser::parseAssignmentExpression(TreeBuilder& context)
1458 {
1459     failIfStackOverflow();
1460     int start = tokenStart();
1461     int initialAssignmentCount = m_assignmentCount;
1462     int initialNonLHSCount = m_nonLHSCount;
1463     TreeExpression lhs = parseConditionalExpression(context);
1464     failIfFalse(lhs);
1465     if (initialNonLHSCount != m_nonLHSCount)
1466         return lhs;
1467
1468     int assignmentStack = 0;
1469     Operator op;
1470     bool hadAssignment = false;
1471     while (true) {
1472         switch (m_token.m_type) {
1473         case EQUAL: op = OpEqual; break;
1474         case PLUSEQUAL: op = OpPlusEq; break;
1475         case MINUSEQUAL: op = OpMinusEq; break;
1476         case MULTEQUAL: op = OpMultEq; break;
1477         case DIVEQUAL: op = OpDivEq; break;
1478         case LSHIFTEQUAL: op = OpLShift; break;
1479         case RSHIFTEQUAL: op = OpRShift; break;
1480         case URSHIFTEQUAL: op = OpURShift; break;
1481         case ANDEQUAL: op = OpAndEq; break;
1482         case XOREQUAL: op = OpXOrEq; break;
1483         case OREQUAL: op = OpOrEq; break;
1484         case MODEQUAL: op = OpModEq; break;
1485         default:
1486             goto end;
1487         }
1488         m_nonTrivialExpressionCount++;
1489         hadAssignment = true;
1490         context.assignmentStackAppend(assignmentStack, lhs, start, tokenStart(), m_assignmentCount, op);
1491         start = tokenStart();
1492         m_assignmentCount++;
1493         next();
1494         if (strictMode() && m_lastIdentifier && context.isResolve(lhs)) {
1495             failIfTrueIfStrict(m_globalData->propertyNames->eval == *m_lastIdentifier);
1496             failIfTrueIfStrict(m_globalData->propertyNames->arguments == *m_lastIdentifier);
1497             declareWrite(m_lastIdentifier);
1498             m_lastIdentifier = 0;
1499         }
1500         lhs = parseConditionalExpression(context);
1501         failIfFalse(lhs);
1502         if (initialNonLHSCount != m_nonLHSCount)
1503             break;
1504     }
1505 end:
1506     if (hadAssignment)
1507         m_nonLHSCount++;
1508
1509     if (!TreeBuilder::CreatesAST)
1510         return lhs;
1511
1512     while (assignmentStack)
1513         lhs = context.createAssignment(assignmentStack, lhs, initialAssignmentCount, m_assignmentCount, lastTokenEnd());
1514
1515     return lhs;
1516 }
1517
1518 template <class TreeBuilder> TreeExpression JSParser::parseConditionalExpression(TreeBuilder& context)
1519 {
1520     TreeExpression cond = parseBinaryExpression(context);
1521     failIfFalse(cond);
1522     if (!match(QUESTION))
1523         return cond;
1524     m_nonTrivialExpressionCount++;
1525     m_nonLHSCount++;
1526     next();
1527     TreeExpression lhs = parseAssignmentExpression(context);
1528     consumeOrFail(COLON);
1529
1530     TreeExpression rhs = parseAssignmentExpression(context);
1531     failIfFalse(rhs);
1532     return context.createConditionalExpr(cond, lhs, rhs);
1533 }
1534
1535 ALWAYS_INLINE static bool isUnaryOp(JSTokenType token)
1536 {
1537     return token & UnaryOpTokenFlag;
1538 }
1539
1540 int JSParser::isBinaryOperator(JSTokenType token)
1541 {
1542     if (m_allowsIn)
1543         return token & (BinaryOpTokenPrecedenceMask << BinaryOpTokenAllowsInPrecedenceAdditionalShift);
1544     return token & BinaryOpTokenPrecedenceMask;
1545 }
1546
1547 template <class TreeBuilder> TreeExpression JSParser::parseBinaryExpression(TreeBuilder& context)
1548 {
1549
1550     int operandStackDepth = 0;
1551     int operatorStackDepth = 0;
1552     typename TreeBuilder::BinaryExprContext binaryExprContext(context);
1553     while (true) {
1554         int exprStart = tokenStart();
1555         int initialAssignments = m_assignmentCount;
1556         TreeExpression current = parseUnaryExpression(context);
1557         failIfFalse(current);
1558
1559         context.appendBinaryExpressionInfo(operandStackDepth, current, exprStart, lastTokenEnd(), lastTokenEnd(), initialAssignments != m_assignmentCount);
1560         int precedence = isBinaryOperator(m_token.m_type);
1561         if (!precedence)
1562             break;
1563         m_nonTrivialExpressionCount++;
1564         m_nonLHSCount++;
1565         int operatorToken = m_token.m_type;
1566         next();
1567
1568         while (operatorStackDepth &&  context.operatorStackHasHigherPrecedence(operatorStackDepth, precedence)) {
1569             ASSERT(operandStackDepth > 1);
1570
1571             typename TreeBuilder::BinaryOperand rhs = context.getFromOperandStack(-1);
1572             typename TreeBuilder::BinaryOperand lhs = context.getFromOperandStack(-2);
1573             context.shrinkOperandStackBy(operandStackDepth, 2);
1574             context.appendBinaryOperation(operandStackDepth, operatorStackDepth, lhs, rhs);
1575             context.operatorStackPop(operatorStackDepth);
1576         }
1577         context.operatorStackAppend(operatorStackDepth, operatorToken, precedence);
1578     }
1579     while (operatorStackDepth) {
1580         ASSERT(operandStackDepth > 1);
1581
1582         typename TreeBuilder::BinaryOperand rhs = context.getFromOperandStack(-1);
1583         typename TreeBuilder::BinaryOperand lhs = context.getFromOperandStack(-2);
1584         context.shrinkOperandStackBy(operandStackDepth, 2);
1585         context.appendBinaryOperation(operandStackDepth, operatorStackDepth, lhs, rhs);
1586         context.operatorStackPop(operatorStackDepth);
1587     }
1588     return context.popOperandStack(operandStackDepth);
1589 }
1590
1591
1592 template <bool complete, class TreeBuilder> TreeProperty JSParser::parseProperty(TreeBuilder& context)
1593 {
1594     bool wasIdent = false;
1595     switch (m_token.m_type) {
1596     namedProperty:
1597     case IDENT:
1598         wasIdent = true;
1599     case STRING: {
1600         const Identifier* ident = m_token.m_data.ident;
1601         next(Lexer::IgnoreReservedWords);
1602         if (match(COLON)) {
1603             next();
1604             TreeExpression node = parseAssignmentExpression(context);
1605             failIfFalse(node);
1606             return context.template createProperty<complete>(ident, node, PropertyNode::Constant);
1607         }
1608         failIfFalse(wasIdent);
1609         matchOrFail(IDENT);
1610         const Identifier* accessorName = 0;
1611         TreeFormalParameterList parameters = 0;
1612         TreeFunctionBody body = 0;
1613         int openBracePos = 0;
1614         int closeBracePos = 0;
1615         int bodyStartLine = 0;
1616         PropertyNode::Type type;
1617         if (*ident == m_globalData->propertyNames->get)
1618             type = PropertyNode::Getter;
1619         else if (*ident == m_globalData->propertyNames->set)
1620             type = PropertyNode::Setter;
1621         else
1622             fail();
1623         failIfFalse((parseFunctionInfo<FunctionNeedsName, false>(context, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
1624         return context.template createGetterOrSetterProperty<complete>(type, accessorName, parameters, body, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
1625     }
1626     case NUMBER: {
1627         double propertyName = m_token.m_data.doubleValue;
1628         next();
1629         consumeOrFail(COLON);
1630         TreeExpression node = parseAssignmentExpression(context);
1631         failIfFalse(node);
1632         return context.template createProperty<complete>(m_globalData, propertyName, node, PropertyNode::Constant);
1633     }
1634     default:
1635         failIfFalse(m_token.m_type & KeywordTokenFlag);
1636         goto namedProperty;
1637     }
1638 }
1639
1640 template <class TreeBuilder> TreeExpression JSParser::parseObjectLiteral(TreeBuilder& context)
1641 {
1642     int startOffset = m_token.m_data.intValue;
1643     consumeOrFail(OPENBRACE);
1644
1645     if (match(CLOSEBRACE)) {
1646         next();
1647         return context.createObjectLiteral();
1648     }
1649
1650     TreeProperty property = parseProperty<false>(context);
1651     failIfFalse(property);
1652     if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) {
1653         m_lexer->setOffset(startOffset);
1654         next();
1655         return parseStrictObjectLiteral(context);
1656     }
1657     TreePropertyList propertyList = context.createPropertyList(property);
1658     TreePropertyList tail = propertyList;
1659     while (match(COMMA)) {
1660         next();
1661         // allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939
1662         if (match(CLOSEBRACE))
1663             break;
1664         property = parseProperty<false>(context);
1665         failIfFalse(property);
1666         if (!m_syntaxAlreadyValidated && context.getType(property) != PropertyNode::Constant) {
1667             m_lexer->setOffset(startOffset);
1668             next();
1669             return parseStrictObjectLiteral(context);
1670         }
1671         tail = context.createPropertyList(property, tail);
1672     }
1673
1674     consumeOrFail(CLOSEBRACE);
1675
1676     return context.createObjectLiteral(propertyList);
1677 }
1678
1679 template <class TreeBuilder> TreeExpression JSParser::parseStrictObjectLiteral(TreeBuilder& context)
1680 {
1681     consumeOrFail(OPENBRACE);
1682     
1683     if (match(CLOSEBRACE)) {
1684         next();
1685         return context.createObjectLiteral();
1686     }
1687     
1688     TreeProperty property = parseProperty<true>(context);
1689     failIfFalse(property);
1690     
1691     typedef HashMap<RefPtr<StringImpl>, unsigned, IdentifierRepHash> ObjectValidationMap;
1692     ObjectValidationMap objectValidator;
1693     // Add the first property
1694     if (!m_syntaxAlreadyValidated)
1695         objectValidator.add(context.getName(property).impl(), context.getType(property));
1696     
1697     TreePropertyList propertyList = context.createPropertyList(property);
1698     TreePropertyList tail = propertyList;
1699     while (match(COMMA)) {
1700         next();
1701         // allow extra comma, see http://bugs.webkit.org/show_bug.cgi?id=5939
1702         if (match(CLOSEBRACE))
1703             break;
1704         property = parseProperty<true>(context);
1705         failIfFalse(property);
1706         if (!m_syntaxAlreadyValidated) {
1707             std::pair<ObjectValidationMap::iterator, bool> propertyEntryIter = objectValidator.add(context.getName(property).impl(), context.getType(property));
1708             if (!propertyEntryIter.second) {
1709                 failIfTrue(strictMode());
1710                 if ((context.getType(property) & propertyEntryIter.first->second) != PropertyNode::Constant) {
1711                     // Can't have multiple getters or setters with the same name, nor can we define 
1712                     // a property as both an accessor and a constant value
1713                     failIfTrue(context.getType(property) & propertyEntryIter.first->second);
1714                     failIfTrue((context.getType(property) | propertyEntryIter.first->second) & PropertyNode::Constant);
1715                 }
1716             }
1717         }
1718         tail = context.createPropertyList(property, tail);
1719     }
1720     
1721     consumeOrFail(CLOSEBRACE);
1722     
1723     return context.createObjectLiteral(propertyList);
1724 }
1725
1726 template <class TreeBuilder> TreeExpression JSParser::parseArrayLiteral(TreeBuilder& context)
1727 {
1728     consumeOrFail(OPENBRACKET);
1729
1730     int elisions = 0;
1731     while (match(COMMA)) {
1732         next();
1733         elisions++;
1734     }
1735     if (match(CLOSEBRACKET)) {
1736         next();
1737         return context.createArray(elisions);
1738     }
1739
1740     TreeExpression elem = parseAssignmentExpression(context);
1741     failIfFalse(elem);
1742     typename TreeBuilder::ElementList elementList = context.createElementList(elisions, elem);
1743     typename TreeBuilder::ElementList tail = elementList;
1744     elisions = 0;
1745     while (match(COMMA)) {
1746         next();
1747         elisions = 0;
1748
1749         while (match(COMMA)) {
1750             next();
1751             elisions++;
1752         }
1753
1754         if (match(CLOSEBRACKET)) {
1755             next();
1756             return context.createArray(elisions, elementList);
1757         }
1758         TreeExpression elem = parseAssignmentExpression(context);
1759         failIfFalse(elem);
1760         tail = context.createElementList(tail, elisions, elem);
1761     }
1762
1763     consumeOrFail(CLOSEBRACKET);
1764
1765     return context.createArray(elementList);
1766 }
1767
1768 template <class TreeBuilder> TreeExpression JSParser::parsePrimaryExpression(TreeBuilder& context)
1769 {
1770     switch (m_token.m_type) {
1771     case OPENBRACE:
1772         if (strictMode())
1773             return parseStrictObjectLiteral(context);
1774         return parseObjectLiteral(context);
1775     case OPENBRACKET:
1776         return parseArrayLiteral(context);
1777     case OPENPAREN: {
1778         next();
1779         int oldNonLHSCount = m_nonLHSCount;
1780         TreeExpression result = parseExpression(context);
1781         m_nonLHSCount = oldNonLHSCount;
1782         consumeOrFail(CLOSEPAREN);
1783
1784         return result;
1785     }
1786     case THISTOKEN: {
1787         next();
1788         return context.thisExpr();
1789     }
1790     case IDENT: {
1791         int start = tokenStart();
1792         const Identifier* ident = m_token.m_data.ident;
1793         next();
1794         currentScope()->useVariable(ident, m_globalData->propertyNames->eval == *ident);
1795         m_lastIdentifier = ident;
1796         return context.createResolve(ident, start);
1797     }
1798     case STRING: {
1799         const Identifier* ident = m_token.m_data.ident;
1800         next();
1801         return context.createString(ident);
1802     }
1803     case NUMBER: {
1804         double d = m_token.m_data.doubleValue;
1805         next();
1806         return context.createNumberExpr(d);
1807     }
1808     case NULLTOKEN: {
1809         next();
1810         return context.createNull();
1811     }
1812     case TRUETOKEN: {
1813         next();
1814         return context.createBoolean(true);
1815     }
1816     case FALSETOKEN: {
1817         next();
1818         return context.createBoolean(false);
1819     }
1820     case DIVEQUAL:
1821     case DIVIDE: {
1822         /* regexp */
1823         const Identifier* pattern;
1824         const Identifier* flags;
1825         if (match(DIVEQUAL))
1826             failIfFalse(m_lexer->scanRegExp(pattern, flags, '='));
1827         else
1828             failIfFalse(m_lexer->scanRegExp(pattern, flags));
1829
1830         int start = tokenStart();
1831         next();
1832         TreeExpression re = context.createRegExp(*pattern, *flags, start);
1833         if (!re) {
1834             m_errorMessage = Yarr::checkSyntax(pattern->ustring());
1835             ASSERT(m_errorMessage);
1836             fail();
1837         }
1838         return re;
1839     }
1840     default:
1841         fail();
1842     }
1843 }
1844
1845 template <class TreeBuilder> TreeArguments JSParser::parseArguments(TreeBuilder& context)
1846 {
1847     consumeOrFail(OPENPAREN);
1848     if (match(CLOSEPAREN)) {
1849         next();
1850         return context.createArguments();
1851     }
1852     TreeExpression firstArg = parseAssignmentExpression(context);
1853     failIfFalse(firstArg);
1854
1855     TreeArgumentsList argList = context.createArgumentsList(firstArg);
1856     TreeArgumentsList tail = argList;
1857     while (match(COMMA)) {
1858         next();
1859         TreeExpression arg = parseAssignmentExpression(context);
1860         failIfFalse(arg);
1861         tail = context.createArgumentsList(tail, arg);
1862     }
1863     consumeOrFail(CLOSEPAREN);
1864     return context.createArguments(argList);
1865 }
1866
1867 template <class TreeBuilder> TreeExpression JSParser::parseMemberExpression(TreeBuilder& context)
1868 {
1869     TreeExpression base = 0;
1870     int start = tokenStart();
1871     int expressionStart = start;
1872     int newCount = 0;
1873     while (match(NEW)) {
1874         next();
1875         newCount++;
1876     }
1877
1878     if (match(FUNCTION)) {
1879         const Identifier* name = &m_globalData->propertyNames->nullIdentifier;
1880         TreeFormalParameterList parameters = 0;
1881         TreeFunctionBody body = 0;
1882         int openBracePos = 0;
1883         int closeBracePos = 0;
1884         int bodyStartLine = 0;
1885         next();
1886         failIfFalse((parseFunctionInfo<FunctionNoRequirements, false>(context, name, parameters, body, openBracePos, closeBracePos, bodyStartLine)));
1887         base = context.createFunctionExpr(name, body, parameters, openBracePos, closeBracePos, bodyStartLine, m_lastLine);
1888     } else
1889         base = parsePrimaryExpression(context);
1890
1891     failIfFalse(base);
1892     while (true) {
1893         switch (m_token.m_type) {
1894         case OPENBRACKET: {
1895             m_nonTrivialExpressionCount++;
1896             int expressionEnd = lastTokenEnd();
1897             next();
1898             int nonLHSCount = m_nonLHSCount;
1899             int initialAssignments = m_assignmentCount;
1900             TreeExpression property = parseExpression(context);
1901             failIfFalse(property);
1902             base = context.createBracketAccess(base, property, initialAssignments != m_assignmentCount, expressionStart, expressionEnd, tokenEnd());
1903             if (!consume(CLOSEBRACKET))
1904                 fail();
1905             m_nonLHSCount = nonLHSCount;
1906             break;
1907         }
1908         case OPENPAREN: {
1909             m_nonTrivialExpressionCount++;
1910             if (newCount) {
1911                 newCount--;
1912                 if (match(OPENPAREN)) {
1913                     int exprEnd = lastTokenEnd();
1914                     TreeArguments arguments = parseArguments(context);
1915                     failIfFalse(arguments);
1916                     base = context.createNewExpr(base, arguments, start, exprEnd, lastTokenEnd());
1917                 } else
1918                     base = context.createNewExpr(base, start, lastTokenEnd());               
1919             } else {
1920                 int nonLHSCount = m_nonLHSCount;
1921                 int expressionEnd = lastTokenEnd();
1922                 TreeArguments arguments = parseArguments(context);
1923                 failIfFalse(arguments);
1924                 base = context.makeFunctionCallNode(base, arguments, expressionStart, expressionEnd, lastTokenEnd());
1925                 m_nonLHSCount = nonLHSCount;
1926             }
1927             break;
1928         }
1929         case DOT: {
1930             m_nonTrivialExpressionCount++;
1931             int expressionEnd = lastTokenEnd();
1932             next(Lexer::IgnoreReservedWords);
1933             matchOrFail(IDENT);
1934             base = context.createDotAccess(base, *m_token.m_data.ident, expressionStart, expressionEnd, tokenEnd());
1935             next();
1936             break;
1937         }
1938         default:
1939             goto endMemberExpression;
1940         }
1941     }
1942 endMemberExpression:
1943     while (newCount--)
1944         base = context.createNewExpr(base, start, lastTokenEnd());
1945     return base;
1946 }
1947
1948 template <class TreeBuilder> TreeExpression JSParser::parseUnaryExpression(TreeBuilder& context)
1949 {
1950     typename TreeBuilder::UnaryExprContext unaryExprContext(context);
1951     AllowInOverride allowInOverride(this);
1952     int tokenStackDepth = 0;
1953     bool modifiesExpr = false;
1954     bool requiresLExpr = false;
1955     while (isUnaryOp(m_token.m_type)) {
1956         if (strictMode()) {
1957             switch (m_token.m_type) {
1958             case PLUSPLUS:
1959             case MINUSMINUS:
1960             case AUTOPLUSPLUS:
1961             case AUTOMINUSMINUS:
1962                 failIfTrue(requiresLExpr);
1963                 modifiesExpr = true;
1964                 requiresLExpr = true;
1965                 break;
1966             case DELETETOKEN:
1967                 failIfTrue(requiresLExpr);
1968                 requiresLExpr = true;
1969                 break;
1970             default:
1971                 failIfTrue(requiresLExpr);
1972                 break;
1973             }
1974         }
1975         m_nonLHSCount++;
1976         context.appendUnaryToken(tokenStackDepth, m_token.m_type, tokenStart());
1977         next();
1978         m_nonTrivialExpressionCount++;
1979     }
1980     int subExprStart = tokenStart();
1981     TreeExpression expr = parseMemberExpression(context);
1982     failIfFalse(expr);
1983     bool isEvalOrArguments = false;
1984     if (strictMode() && !m_syntaxAlreadyValidated) {
1985         if (context.isResolve(expr)) {
1986             isEvalOrArguments = *m_lastIdentifier == m_globalData->propertyNames->eval || *m_lastIdentifier == m_globalData->propertyNames->arguments;
1987         }
1988     }
1989     failIfTrueIfStrict(isEvalOrArguments && modifiesExpr);
1990     switch (m_token.m_type) {
1991     case PLUSPLUS:
1992         m_nonTrivialExpressionCount++;
1993         m_nonLHSCount++;
1994         expr = context.makePostfixNode(expr, OpPlusPlus, subExprStart, lastTokenEnd(), tokenEnd());
1995         m_assignmentCount++;
1996         failIfTrueIfStrict(isEvalOrArguments);
1997         failIfTrueIfStrict(requiresLExpr);
1998         next();
1999         break;
2000     case MINUSMINUS:
2001         m_nonTrivialExpressionCount++;
2002         m_nonLHSCount++;
2003         expr = context.makePostfixNode(expr, OpMinusMinus, subExprStart, lastTokenEnd(), tokenEnd());
2004         m_assignmentCount++;
2005         failIfTrueIfStrict(isEvalOrArguments);
2006         failIfTrueIfStrict(requiresLExpr);
2007         next();
2008         break;
2009     default:
2010         break;
2011     }
2012
2013     int end = lastTokenEnd();
2014
2015     if (!TreeBuilder::CreatesAST && (m_syntaxAlreadyValidated || !strictMode()))
2016         return expr;
2017
2018     while (tokenStackDepth) {
2019         switch (context.unaryTokenStackLastType(tokenStackDepth)) {
2020         case EXCLAMATION:
2021             expr = context.createLogicalNot(expr);
2022             break;
2023         case TILDE:
2024             expr = context.makeBitwiseNotNode(expr);
2025             break;
2026         case MINUS:
2027             expr = context.makeNegateNode(expr);
2028             break;
2029         case PLUS:
2030             expr = context.createUnaryPlus(expr);
2031             break;
2032         case PLUSPLUS:
2033         case AUTOPLUSPLUS:
2034             expr = context.makePrefixNode(expr, OpPlusPlus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
2035             m_assignmentCount++;
2036             break;
2037         case MINUSMINUS:
2038         case AUTOMINUSMINUS:
2039             expr = context.makePrefixNode(expr, OpMinusMinus, context.unaryTokenStackLastStart(tokenStackDepth), subExprStart + 1, end);
2040             m_assignmentCount++;
2041             break;
2042         case TYPEOF:
2043             expr = context.makeTypeOfNode(expr);
2044             break;
2045         case VOIDTOKEN:
2046             expr = context.createVoid(expr);
2047             break;
2048         case DELETETOKEN:
2049             failIfTrueIfStrict(context.isResolve(expr));
2050             expr = context.makeDeleteNode(expr, context.unaryTokenStackLastStart(tokenStackDepth), end, end);
2051             break;
2052         default:
2053             // If we get here something has gone horribly horribly wrong
2054             CRASH();
2055         }
2056         subExprStart = context.unaryTokenStackLastStart(tokenStackDepth);
2057         context.unaryTokenStackRemoveLast(tokenStackDepth);
2058     }
2059     return expr;
2060 }
2061
2062 }