Added WTF::StackStats mechanism.
[WebKit-https.git] / Source / JavaScriptCore / parser / Parser.h
1 /*
2  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4  *  Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2011 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 #ifndef Parser_h
24 #define Parser_h
25
26 #include "Debugger.h"
27 #include "ExceptionHelpers.h"
28 #include "Executable.h"
29 #include "JSGlobalObject.h"
30 #include "Lexer.h"
31 #include "Nodes.h"
32 #include "ParserArena.h"
33 #include "ParserTokens.h"
34 #include "SourceProvider.h"
35 #include "SourceProviderCacheItem.h"
36 #include <wtf/Forward.h>
37 #include <wtf/Noncopyable.h>
38 #include <wtf/OwnPtr.h>
39 #include <wtf/RefPtr.h>
40 namespace JSC {
41 struct Scope;
42 }
43
44 namespace WTF {
45 template <> struct VectorTraits<JSC::Scope> : SimpleClassVectorTraits {
46     static const bool canInitializeWithMemset = false; // Not all Scope data members initialize to 0.
47 };
48 }
49
50 namespace JSC {
51
52 class ExecState;
53 class FunctionBodyNode;
54 class FunctionParameters;
55 class Identifier;
56 class JSGlobalData;
57 class ProgramNode;
58 class SourceCode;
59
60 // Macros to make the more common TreeBuilder types a little less verbose
61 #define TreeStatement typename TreeBuilder::Statement
62 #define TreeExpression typename TreeBuilder::Expression
63 #define TreeFormalParameterList typename TreeBuilder::FormalParameterList
64 #define TreeSourceElements typename TreeBuilder::SourceElements
65 #define TreeClause typename TreeBuilder::Clause
66 #define TreeClauseList typename TreeBuilder::ClauseList
67 #define TreeConstDeclList typename TreeBuilder::ConstDeclList
68 #define TreeArguments typename TreeBuilder::Arguments
69 #define TreeArgumentsList typename TreeBuilder::ArgumentsList
70 #define TreeFunctionBody typename TreeBuilder::FunctionBody
71 #define TreeProperty typename TreeBuilder::Property
72 #define TreePropertyList typename TreeBuilder::PropertyList
73
74 COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
75
76 enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
77 enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName };
78
79 template <typename T> inline bool isEvalNode() { return false; }
80 template <> inline bool isEvalNode<EvalNode>() { return true; }
81
82 struct DepthManager {
83     DepthManager(int* depth)
84         : m_originalDepth(*depth)
85         , m_depth(depth)
86     {
87     }
88
89     ~DepthManager()
90     {
91         *m_depth = m_originalDepth;
92     }
93
94 private:
95     int m_originalDepth;
96     int* m_depth;
97 };
98
99 struct ScopeLabelInfo {
100     ScopeLabelInfo(StringImpl* ident, bool isLoop)
101         : m_ident(ident)
102         , m_isLoop(isLoop)
103     {
104     }
105
106     StringImpl* m_ident;
107     bool m_isLoop;
108 };
109
110 struct Scope {
111     Scope(const JSGlobalData* globalData, bool isFunction, bool strictMode)
112         : m_globalData(globalData)
113         , m_shadowsArguments(false)
114         , m_usesEval(false)
115         , m_needsFullActivation(false)
116         , m_allowsNewDecls(true)
117         , m_strictMode(strictMode)
118         , m_isFunction(isFunction)
119         , m_isFunctionBoundary(false)
120         , m_isValidStrictMode(true)
121         , m_loopDepth(0)
122         , m_switchDepth(0)
123     {
124     }
125
126     Scope(const Scope& rhs)
127         : m_globalData(rhs.m_globalData)
128         , m_shadowsArguments(rhs.m_shadowsArguments)
129         , m_usesEval(rhs.m_usesEval)
130         , m_needsFullActivation(rhs.m_needsFullActivation)
131         , m_allowsNewDecls(rhs.m_allowsNewDecls)
132         , m_strictMode(rhs.m_strictMode)
133         , m_isFunction(rhs.m_isFunction)
134         , m_isFunctionBoundary(rhs.m_isFunctionBoundary)
135         , m_isValidStrictMode(rhs.m_isValidStrictMode)
136         , m_loopDepth(rhs.m_loopDepth)
137         , m_switchDepth(rhs.m_switchDepth)
138     {
139         if (rhs.m_labels) {
140             m_labels = adoptPtr(new LabelStack);
141
142             typedef LabelStack::const_iterator iterator;
143             iterator end = rhs.m_labels->end();
144             for (iterator it = rhs.m_labels->begin(); it != end; ++it)
145                 m_labels->append(ScopeLabelInfo(it->m_ident, it->m_isLoop));
146         }
147     }
148
149     void startSwitch() { m_switchDepth++; }
150     void endSwitch() { m_switchDepth--; }
151     void startLoop() { m_loopDepth++; }
152     void endLoop() { ASSERT(m_loopDepth); m_loopDepth--; }
153     bool inLoop() { return !!m_loopDepth; }
154     bool breakIsValid() { return m_loopDepth || m_switchDepth; }
155     bool continueIsValid() { return m_loopDepth; }
156
157     void pushLabel(const Identifier* label, bool isLoop)
158     {
159         if (!m_labels)
160             m_labels = adoptPtr(new LabelStack);
161         m_labels->append(ScopeLabelInfo(label->impl(), isLoop));
162     }
163
164     void popLabel()
165     {
166         ASSERT(m_labels);
167         ASSERT(m_labels->size());
168         m_labels->removeLast();
169     }
170
171     ScopeLabelInfo* getLabel(const Identifier* label)
172     {
173         if (!m_labels)
174             return 0;
175         for (int i = m_labels->size(); i > 0; i--) {
176             if (m_labels->at(i - 1).m_ident == label->impl())
177                 return &m_labels->at(i - 1);
178         }
179         return 0;
180     }
181
182     void setIsFunction()
183     {
184         m_isFunction = true;
185         m_isFunctionBoundary = true;
186     }
187     bool isFunction() { return m_isFunction; }
188     bool isFunctionBoundary() { return m_isFunctionBoundary; }
189
190     void declareCallee(const Identifier* ident)
191     {
192         m_declaredVariables.add(ident->string().impl());
193     }
194
195     bool declareVariable(const Identifier* ident)
196     {
197         bool isValidStrictMode = m_globalData->propertyNames->eval != *ident && m_globalData->propertyNames->arguments != *ident;
198         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
199         m_declaredVariables.add(ident->string().impl());
200         return isValidStrictMode;
201     }
202
203     void declareWrite(const Identifier* ident)
204     {
205         ASSERT(m_strictMode);
206         m_writtenVariables.add(ident->impl());
207     }
208
209     void preventNewDecls() { m_allowsNewDecls = false; }
210     bool allowsNewDecls() const { return m_allowsNewDecls; }
211
212     bool declareParameter(const Identifier* ident)
213     {
214         bool isArguments = m_globalData->propertyNames->arguments == *ident;
215         bool isValidStrictMode = m_declaredVariables.add(ident->string().impl()).isNewEntry && m_globalData->propertyNames->eval != *ident && !isArguments;
216         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
217         if (isArguments)
218             m_shadowsArguments = true;
219         return isValidStrictMode;
220     }
221
222     void useVariable(const Identifier* ident, bool isEval)
223     {
224         m_usesEval |= isEval;
225         m_usedVariables.add(ident->string().impl());
226     }
227
228     void setNeedsFullActivation() { m_needsFullActivation = true; }
229
230     bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
231     {
232         if (nestedScope->m_usesEval)
233             m_usesEval = true;
234         IdentifierSet::iterator end = nestedScope->m_usedVariables.end();
235         for (IdentifierSet::iterator ptr = nestedScope->m_usedVariables.begin(); ptr != end; ++ptr) {
236             if (nestedScope->m_declaredVariables.contains(*ptr))
237                 continue;
238             m_usedVariables.add(*ptr);
239             if (shouldTrackClosedVariables)
240                 m_closedVariables.add(*ptr);
241         }
242         if (nestedScope->m_writtenVariables.size()) {
243             IdentifierSet::iterator end = nestedScope->m_writtenVariables.end();
244             for (IdentifierSet::iterator ptr = nestedScope->m_writtenVariables.begin(); ptr != end; ++ptr) {
245                 if (nestedScope->m_declaredVariables.contains(*ptr))
246                     continue;
247                 m_writtenVariables.add(*ptr);
248             }
249         }
250
251         return true;
252     }
253
254     void getUncapturedWrittenVariables(IdentifierSet& writtenVariables)
255     {
256         IdentifierSet::iterator end = m_writtenVariables.end();
257         for (IdentifierSet::iterator ptr = m_writtenVariables.begin(); ptr != end; ++ptr) {
258             if (!m_declaredVariables.contains(*ptr))
259                 writtenVariables.add(*ptr);
260         }
261     }
262
263     void getCapturedVariables(IdentifierSet& capturedVariables)
264     {
265         if (m_needsFullActivation || m_usesEval) {
266             capturedVariables.swap(m_declaredVariables);
267             return;
268         }
269         for (IdentifierSet::iterator ptr = m_closedVariables.begin(); ptr != m_closedVariables.end(); ++ptr) {
270             if (!m_declaredVariables.contains(*ptr))
271                 continue;
272             capturedVariables.add(*ptr);
273         }
274     }
275     void setStrictMode() { m_strictMode = true; }
276     bool strictMode() const { return m_strictMode; }
277     bool isValidStrictMode() const { return m_isValidStrictMode; }
278     bool shadowsArguments() const { return m_shadowsArguments; }
279
280     void copyCapturedVariablesToVector(const IdentifierSet& capturedVariables, Vector<RefPtr<StringImpl> >& vector)
281     {
282         IdentifierSet::iterator end = capturedVariables.end();
283         for (IdentifierSet::iterator it = capturedVariables.begin(); it != end; ++it) {
284             if (m_declaredVariables.contains(*it))
285                 continue;
286             vector.append(*it);
287         }
288         vector.shrinkToFit();
289     }
290
291     void saveFunctionInfo(SourceProviderCacheItem* info)
292     {
293         ASSERT(m_isFunction);
294         info->usesEval = m_usesEval;
295         info->strictMode = m_strictMode;
296         info->needsFullActivation = m_needsFullActivation;
297         copyCapturedVariablesToVector(m_writtenVariables, info->writtenVariables);
298         copyCapturedVariablesToVector(m_usedVariables, info->usedVariables);
299     }
300
301     void restoreFunctionInfo(const SourceProviderCacheItem* info)
302     {
303         ASSERT(m_isFunction);
304         m_usesEval = info->usesEval;
305         m_strictMode = info->strictMode;
306         m_needsFullActivation = info->needsFullActivation;
307         unsigned size = info->usedVariables.size();
308         for (unsigned i = 0; i < size; ++i)
309             m_usedVariables.add(info->usedVariables[i]);
310         size = info->writtenVariables.size();
311         for (unsigned i = 0; i < size; ++i)
312             m_writtenVariables.add(info->writtenVariables[i]);
313     }
314
315 private:
316     const JSGlobalData* m_globalData;
317     bool m_shadowsArguments : 1;
318     bool m_usesEval : 1;
319     bool m_needsFullActivation : 1;
320     bool m_allowsNewDecls : 1;
321     bool m_strictMode : 1;
322     bool m_isFunction : 1;
323     bool m_isFunctionBoundary : 1;
324     bool m_isValidStrictMode : 1;
325     int m_loopDepth;
326     int m_switchDepth;
327
328     typedef Vector<ScopeLabelInfo, 2> LabelStack;
329     OwnPtr<LabelStack> m_labels;
330     IdentifierSet m_declaredVariables;
331     IdentifierSet m_usedVariables;
332     IdentifierSet m_closedVariables;
333     IdentifierSet m_writtenVariables;
334 };
335
336 typedef Vector<Scope, 10> ScopeStack;
337
338 struct ScopeRef {
339     ScopeRef(ScopeStack* scopeStack, unsigned index)
340         : m_scopeStack(scopeStack)
341         , m_index(index)
342     {
343     }
344     Scope* operator->() { return &m_scopeStack->at(m_index); }
345     unsigned index() const { return m_index; }
346
347     bool hasContainingScope()
348     {
349         return m_index && !m_scopeStack->at(m_index).isFunctionBoundary();
350     }
351
352     ScopeRef containingScope()
353     {
354         ASSERT(hasContainingScope());
355         return ScopeRef(m_scopeStack, m_index - 1);
356     }
357
358 private:
359     ScopeStack* m_scopeStack;
360     unsigned m_index;
361 };
362
363 template <typename LexerType>
364 class Parser {
365     WTF_MAKE_NONCOPYABLE(Parser);
366     WTF_MAKE_FAST_ALLOCATED;
367
368 public:
369     Parser(JSGlobalData*, const SourceCode&, FunctionParameters*, const Identifier&, JSParserStrictness, JSParserMode);
370     ~Parser();
371
372     template <class ParsedNode>
373     PassRefPtr<ParsedNode> parse(JSGlobalObject* lexicalGlobalObject, Debugger*, ExecState*, JSObject**);
374
375 private:
376     struct AllowInOverride {
377         AllowInOverride(Parser* parser)
378             : m_parser(parser)
379             , m_oldAllowsIn(parser->m_allowsIn)
380         {
381             parser->m_allowsIn = true;
382         }
383         ~AllowInOverride()
384         {
385             m_parser->m_allowsIn = m_oldAllowsIn;
386         }
387         Parser* m_parser;
388         bool m_oldAllowsIn;
389     };
390
391     struct AutoPopScopeRef : public ScopeRef {
392         AutoPopScopeRef(Parser* parser, ScopeRef scope)
393         : ScopeRef(scope)
394         , m_parser(parser)
395         {
396         }
397         
398         ~AutoPopScopeRef()
399         {
400             if (m_parser)
401                 m_parser->popScope(*this, false);
402         }
403         
404         void setPopped()
405         {
406             m_parser = 0;
407         }
408         
409     private:
410         Parser* m_parser;
411     };
412
413     ScopeRef currentScope()
414     {
415         return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
416     }
417     
418     ScopeRef pushScope()
419     {
420         bool isFunction = false;
421         bool isStrict = false;
422         if (!m_scopeStack.isEmpty()) {
423             isStrict = m_scopeStack.last().strictMode();
424             isFunction = m_scopeStack.last().isFunction();
425         }
426         m_scopeStack.append(Scope(m_globalData, isFunction, isStrict));
427         return currentScope();
428     }
429     
430     bool popScopeInternal(ScopeRef& scope, bool shouldTrackClosedVariables)
431     {
432         ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1);
433         ASSERT(m_scopeStack.size() > 1);
434         bool result = m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
435         m_scopeStack.removeLast();
436         return result;
437     }
438     
439     bool popScope(ScopeRef& scope, bool shouldTrackClosedVariables)
440     {
441         return popScopeInternal(scope, shouldTrackClosedVariables);
442     }
443     
444     bool popScope(AutoPopScopeRef& scope, bool shouldTrackClosedVariables)
445     {
446         scope.setPopped();
447         return popScopeInternal(scope, shouldTrackClosedVariables);
448     }
449     
450     bool declareVariable(const Identifier* ident)
451     {
452         unsigned i = m_scopeStack.size() - 1;
453         ASSERT(i < m_scopeStack.size());
454         while (!m_scopeStack[i].allowsNewDecls()) {
455             i--;
456             ASSERT(i < m_scopeStack.size());
457         }
458         return m_scopeStack[i].declareVariable(ident);
459     }
460     
461     void declareWrite(const Identifier* ident)
462     {
463         if (!m_syntaxAlreadyValidated)
464             m_scopeStack.last().declareWrite(ident);
465     }
466     
467     ScopeStack m_scopeStack;
468     
469     const SourceProviderCacheItem* findCachedFunctionInfo(int openBracePos) 
470     {
471         return m_functionCache ? m_functionCache->get(openBracePos) : 0;
472     }
473
474     Parser();
475     String parseInner();
476
477     void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, 
478                           ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures,
479                           int, int, IdentifierSet&);
480
481     // Used to determine type of error to report.
482     bool isFunctionBodyNode(ScopeNode*) { return false; }
483     bool isFunctionBodyNode(FunctionBodyNode*) { return true; }
484
485
486     ALWAYS_INLINE void next(unsigned lexerFlags = 0)
487     {
488         m_lastLine = m_token.m_location.line;
489         m_lastTokenEnd = m_token.m_location.endOffset;
490         m_lexer->setLastLineNumber(m_lastLine);
491         m_token.m_type = m_lexer->lex(&m_token.m_data, &m_token.m_location, lexerFlags, strictMode());
492     }
493
494     ALWAYS_INLINE void nextExpectIdentifier(unsigned lexerFlags = 0)
495     {
496         m_lastLine = m_token.m_location.line;
497         m_lastTokenEnd = m_token.m_location.endOffset;
498         m_lexer->setLastLineNumber(m_lastLine);
499         m_token.m_type = m_lexer->lexExpectIdentifier(&m_token.m_data, &m_token.m_location, lexerFlags, strictMode());
500     }
501
502     ALWAYS_INLINE bool nextTokenIsColon()
503     {
504         return m_lexer->nextTokenIsColon();
505     }
506
507     ALWAYS_INLINE bool consume(JSTokenType expected, unsigned flags = 0)
508     {
509         bool result = m_token.m_type == expected;
510         if (result)
511             next(flags);
512         return result;
513     }
514     
515     ALWAYS_INLINE String getToken() {
516         SourceProvider* sourceProvider = m_source->provider();
517         return sourceProvider->getRange(tokenStart(), tokenEnd());
518     }
519     
520     ALWAYS_INLINE bool match(JSTokenType expected)
521     {
522         return m_token.m_type == expected;
523     }
524     
525     ALWAYS_INLINE int tokenStart()
526     {
527         return m_token.m_location.startOffset;
528     }
529     
530     ALWAYS_INLINE int tokenLine()
531     {
532         return m_token.m_location.line;
533     }
534     
535     ALWAYS_INLINE int tokenEnd()
536     {
537         return m_token.m_location.endOffset;
538     }
539     
540     ALWAYS_INLINE const JSTokenLocation& tokenLocation()
541     {
542         return m_token.m_location;
543     }
544
545     const char* getTokenName(JSTokenType tok)
546     {
547         switch (tok) {
548         case NULLTOKEN: 
549             return "null";
550         case TRUETOKEN:
551             return "true";
552         case FALSETOKEN: 
553             return "false";
554         case BREAK: 
555             return "break";
556         case CASE: 
557             return "case";
558         case DEFAULT: 
559             return "default";
560         case FOR: 
561             return "for";
562         case NEW: 
563             return "new";
564         case VAR: 
565             return "var";
566         case CONSTTOKEN: 
567             return "const";
568         case CONTINUE: 
569             return "continue";
570         case FUNCTION: 
571             return "function";
572         case IF: 
573             return "if";
574         case THISTOKEN: 
575             return "this";
576         case DO: 
577             return "do";
578         case WHILE: 
579             return "while";
580         case SWITCH: 
581             return "switch";
582         case WITH: 
583             return "with";
584         case THROW: 
585             return "throw";
586         case TRY: 
587             return "try";
588         case CATCH: 
589             return "catch";
590         case FINALLY: 
591             return "finally";
592         case DEBUGGER: 
593             return "debugger";
594         case ELSE: 
595             return "else";
596         case OPENBRACE: 
597             return "{";
598         case CLOSEBRACE: 
599             return "}";
600         case OPENPAREN: 
601             return "(";
602         case CLOSEPAREN: 
603             return ")";
604         case OPENBRACKET: 
605             return "[";
606         case CLOSEBRACKET: 
607             return "]";
608         case COMMA: 
609             return ",";
610         case QUESTION: 
611             return "?";
612         case SEMICOLON: 
613             return ";";
614         case COLON: 
615             return ":";
616         case DOT: 
617             return ".";
618         case EQUAL: 
619             return "=";
620         case PLUSEQUAL: 
621             return "+=";
622         case MINUSEQUAL: 
623             return "-=";
624         case MULTEQUAL: 
625             return "*=";
626         case DIVEQUAL: 
627             return "/=";
628         case LSHIFTEQUAL: 
629             return "<<=";
630         case RSHIFTEQUAL: 
631             return ">>=";
632         case URSHIFTEQUAL: 
633             return ">>>=";
634         case ANDEQUAL: 
635             return "&=";
636         case MODEQUAL: 
637             return "%=";
638         case XOREQUAL: 
639             return "^=";
640         case OREQUAL: 
641             return "|=";
642         case AUTOPLUSPLUS: 
643         case PLUSPLUS: 
644             return "++";
645         case AUTOMINUSMINUS: 
646         case MINUSMINUS: 
647             return "--";
648         case EXCLAMATION: 
649             return "!";
650         case TILDE: 
651             return "~";
652         case TYPEOF: 
653             return "typeof";
654         case VOIDTOKEN: 
655             return "void";
656         case DELETETOKEN: 
657             return "delete";
658         case OR: 
659             return "||";
660         case AND: 
661             return "&&";
662         case BITOR: 
663             return "|";
664         case BITXOR: 
665             return "^";
666         case BITAND: 
667             return "&";
668         case EQEQ: 
669             return "==";
670         case NE: 
671             return "!=";
672         case STREQ: 
673             return "===";
674         case STRNEQ: 
675             return "!==";
676         case LT: 
677             return "<";
678         case GT: 
679             return ">";
680         case LE: 
681             return "<=";
682         case GE: 
683             return ">=";
684         case INSTANCEOF: 
685             return "instanceof";
686         case INTOKEN: 
687             return "in";
688         case LSHIFT: 
689             return "<<";
690         case RSHIFT: 
691             return ">>";
692         case URSHIFT: 
693             return ">>>";
694         case PLUS: 
695             return "+";
696         case MINUS: 
697             return "-";
698         case TIMES: 
699             return "*";
700         case DIVIDE: 
701             return "/";
702         case MOD: 
703             return "%";
704         case RETURN: 
705         case RESERVED_IF_STRICT:
706         case RESERVED: 
707         case NUMBER:
708         case IDENT: 
709         case STRING: 
710         case ERRORTOK:
711         case EOFTOK: 
712             return 0;
713         case LastUntaggedToken: 
714             break;
715         }
716         ASSERT_NOT_REACHED();
717         return "internal error";
718     }
719     
720     ALWAYS_INLINE void updateErrorMessageSpecialCase(JSTokenType expectedToken) 
721     {
722         switch (expectedToken) {
723         case RESERVED_IF_STRICT:
724             m_errorMessage = "Use of reserved word '" + getToken() + "' in strict mode";
725             return;
726         case RESERVED:
727             m_errorMessage = "Use of reserved word '" + getToken() + '\'';
728             return;
729         case NUMBER: 
730             m_errorMessage = "Unexpected number '" + getToken() + '\'';
731             return;
732         case IDENT: 
733             m_errorMessage = "Expected an identifier but found '" + getToken() + "' instead";
734             return;
735         case STRING: 
736             m_errorMessage = "Unexpected string " + getToken();
737             return;
738         case ERRORTOK: 
739             m_errorMessage = "Unrecognized token '" + getToken() + '\'';
740             return;
741         case EOFTOK:  
742             m_errorMessage = ASCIILiteral("Unexpected EOF");
743             return;
744         case RETURN:
745             m_errorMessage = ASCIILiteral("Return statements are only valid inside functions");
746             return;
747         default:
748             ASSERT_NOT_REACHED();
749             m_errorMessage = ASCIILiteral("internal error");
750             return;
751         }
752     }
753     
754     NEVER_INLINE void updateErrorMessage() 
755     {
756         m_error = true;
757         const char* name = getTokenName(m_token.m_type);
758         if (!name) 
759             updateErrorMessageSpecialCase(m_token.m_type);
760         else 
761             m_errorMessage = String::format("Unexpected token '%s'", name);
762     }
763     
764     NEVER_INLINE void updateErrorMessage(JSTokenType expectedToken) 
765     {
766         m_error = true;
767         const char* name = getTokenName(expectedToken);
768         if (name)
769             m_errorMessage = String::format("Expected token '%s'", name);
770         else {
771             if (!getTokenName(m_token.m_type))
772                 updateErrorMessageSpecialCase(m_token.m_type);
773             else
774                 updateErrorMessageSpecialCase(expectedToken);
775         }
776     }
777     
778     NEVER_INLINE void updateErrorWithNameAndMessage(const char* beforeMsg, String name, const char* afterMsg)
779     {
780         m_error = true;
781         m_errorMessage = makeString(beforeMsg, " '", name, "' ", afterMsg);
782     }
783     
784     NEVER_INLINE void updateErrorMessage(const char* msg)
785     {   
786         m_error = true;
787         m_errorMessage = String(msg);
788     }
789     
790     void startLoop() { currentScope()->startLoop(); }
791     void endLoop() { currentScope()->endLoop(); }
792     void startSwitch() { currentScope()->startSwitch(); }
793     void endSwitch() { currentScope()->endSwitch(); }
794     void setStrictMode() { currentScope()->setStrictMode(); }
795     bool strictMode() { return currentScope()->strictMode(); }
796     bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
797     bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
798     bool breakIsValid()
799     {
800         ScopeRef current = currentScope();
801         while (!current->breakIsValid()) {
802             if (!current.hasContainingScope())
803                 return false;
804             current = current.containingScope();
805         }
806         return true;
807     }
808     bool continueIsValid()
809     {
810         ScopeRef current = currentScope();
811         while (!current->continueIsValid()) {
812             if (!current.hasContainingScope())
813                 return false;
814             current = current.containingScope();
815         }
816         return true;
817     }
818     void pushLabel(const Identifier* label, bool isLoop) { currentScope()->pushLabel(label, isLoop); }
819     void popLabel() { currentScope()->popLabel(); }
820     ScopeLabelInfo* getLabel(const Identifier* label)
821     {
822         ScopeRef current = currentScope();
823         ScopeLabelInfo* result = 0;
824         while (!(result = current->getLabel(label))) {
825             if (!current.hasContainingScope())
826                 return 0;
827             current = current.containingScope();
828         }
829         return result;
830     }
831     
832     template <SourceElementsMode mode, class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&);
833     template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
834     template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&);
835     template <class TreeBuilder> TreeStatement parseVarDeclaration(TreeBuilder&);
836     template <class TreeBuilder> TreeStatement parseConstDeclaration(TreeBuilder&);
837     template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&);
838     template <class TreeBuilder> TreeStatement parseWhileStatement(TreeBuilder&);
839     template <class TreeBuilder> TreeStatement parseForStatement(TreeBuilder&);
840     template <class TreeBuilder> TreeStatement parseBreakStatement(TreeBuilder&);
841     template <class TreeBuilder> TreeStatement parseContinueStatement(TreeBuilder&);
842     template <class TreeBuilder> TreeStatement parseReturnStatement(TreeBuilder&);
843     template <class TreeBuilder> TreeStatement parseThrowStatement(TreeBuilder&);
844     template <class TreeBuilder> TreeStatement parseWithStatement(TreeBuilder&);
845     template <class TreeBuilder> TreeStatement parseSwitchStatement(TreeBuilder&);
846     template <class TreeBuilder> TreeClauseList parseSwitchClauses(TreeBuilder&);
847     template <class TreeBuilder> TreeClause parseSwitchDefaultClause(TreeBuilder&);
848     template <class TreeBuilder> TreeStatement parseTryStatement(TreeBuilder&);
849     template <class TreeBuilder> TreeStatement parseDebuggerStatement(TreeBuilder&);
850     template <class TreeBuilder> TreeStatement parseExpressionStatement(TreeBuilder&);
851     template <class TreeBuilder> TreeStatement parseExpressionOrLabelStatement(TreeBuilder&);
852     template <class TreeBuilder> TreeStatement parseIfStatement(TreeBuilder&);
853     template <class TreeBuilder> ALWAYS_INLINE TreeStatement parseBlockStatement(TreeBuilder&);
854     template <class TreeBuilder> TreeExpression parseExpression(TreeBuilder&);
855     template <class TreeBuilder> TreeExpression parseAssignmentExpression(TreeBuilder&);
856     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseConditionalExpression(TreeBuilder&);
857     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseBinaryExpression(TreeBuilder&);
858     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseUnaryExpression(TreeBuilder&);
859     template <class TreeBuilder> TreeExpression parseMemberExpression(TreeBuilder&);
860     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parsePrimaryExpression(TreeBuilder&);
861     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArrayLiteral(TreeBuilder&);
862     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseObjectLiteral(TreeBuilder&);
863     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&);
864     template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&);
865     template <bool strict, class TreeBuilder> ALWAYS_INLINE TreeProperty parseProperty(TreeBuilder&);
866     template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&);
867     template <class TreeBuilder> ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&);
868     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, const Identifier*& lastIdent, TreeExpression& lastInitializer, int& identStart, int& initStart, int& initEnd);
869     template <class TreeBuilder> ALWAYS_INLINE TreeConstDeclList parseConstDeclarationList(TreeBuilder& context);
870     template <FunctionRequirements, bool nameIsInContainingScope, class TreeBuilder> bool parseFunctionInfo(TreeBuilder&, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, int& openBrace, int& closeBrace, int& bodyStartLine);
871     ALWAYS_INLINE int isBinaryOperator(JSTokenType);
872     bool allowAutomaticSemicolon();
873     
874     bool autoSemiColon()
875     {
876         if (m_token.m_type == SEMICOLON) {
877             next();
878             return true;
879         }
880         return allowAutomaticSemicolon();
881     }
882     
883     bool canRecurse()
884     {
885         return m_stack.isSafeToRecurse();
886     }
887     
888     int lastTokenEnd() const
889     {
890         return m_lastTokenEnd;
891     }
892
893     mutable const JSGlobalData* m_globalData;
894     const SourceCode* m_source;
895     ParserArena* m_arena;
896     OwnPtr<LexerType> m_lexer;
897     
898     StackBounds m_stack;
899     bool m_error;
900     String m_errorMessage;
901     JSToken m_token;
902     bool m_allowsIn;
903     int m_lastLine;
904     int m_lastTokenEnd;
905     int m_assignmentCount;
906     int m_nonLHSCount;
907     bool m_syntaxAlreadyValidated;
908     int m_statementDepth;
909     int m_nonTrivialExpressionCount;
910     const Identifier* m_lastIdentifier;
911     SourceProviderCache* m_functionCache;
912     SourceElements* m_sourceElements;
913     ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
914     ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
915     IdentifierSet m_capturedVariables;
916     CodeFeatures m_features;
917     int m_numConstants;
918     
919     struct DepthManager {
920         DepthManager(int* depth)
921         : m_originalDepth(*depth)
922         , m_depth(depth)
923         {
924         }
925         
926         ~DepthManager()
927         {
928             *m_depth = m_originalDepth;
929         }
930         
931     private:
932         int m_originalDepth;
933         int* m_depth;
934     };
935 };
936
937 template <typename LexerType>
938 template <class ParsedNode>
939 PassRefPtr<ParsedNode> Parser<LexerType>::parse(JSGlobalObject* lexicalGlobalObject, Debugger* debugger, ExecState* debuggerExecState, JSObject** exception)
940 {
941     ASSERT(lexicalGlobalObject);
942     ASSERT(exception && !*exception);
943     int errLine;
944     String errMsg;
945
946     if (ParsedNode::scopeIsFunction)
947         m_lexer->setIsReparsing();
948
949     m_sourceElements = 0;
950
951     errLine = -1;
952     errMsg = String();
953
954     String parseError = parseInner();
955
956     int lineNumber = m_lexer->lineNumber();
957     bool lexError = m_lexer->sawError();
958     String lexErrorMessage = lexError ? m_lexer->getErrorMessage() : String();
959     ASSERT(lexErrorMessage.isNull() != lexError);
960     m_lexer->clear();
961
962     if (!parseError.isNull() || lexError) {
963         errLine = lineNumber;
964         errMsg = !lexErrorMessage.isNull() ? lexErrorMessage : parseError;
965         m_sourceElements = 0;
966     }
967
968     RefPtr<ParsedNode> result;
969     if (m_sourceElements) {
970         JSTokenLocation location;
971         location.line = m_lexer->lastLineNumber();
972         location.column = m_lexer->currentColumnNumber();
973         result = ParsedNode::create(&lexicalGlobalObject->globalData(),
974                                     location,
975                                     m_sourceElements,
976                                     m_varDeclarations ? &m_varDeclarations->data : 0,
977                                     m_funcDeclarations ? &m_funcDeclarations->data : 0,
978                                     m_capturedVariables,
979                                     *m_source,
980                                     m_features,
981                                     m_numConstants);
982         result->setLoc(m_source->firstLine(), m_lastLine, m_lexer->currentColumnNumber());
983     } else if (lexicalGlobalObject) {
984         // We can never see a syntax error when reparsing a function, since we should have
985         // reported the error when parsing the containing program or eval code. So if we're
986         // parsing a function body node, we assume that what actually happened here is that
987         // we ran out of stack while parsing. If we see an error while parsing eval or program
988         // code we assume that it was a syntax error since running out of stack is much less
989         // likely, and we are currently unable to distinguish between the two cases.
990         if (isFunctionBodyNode(static_cast<ParsedNode*>(0)))
991             *exception = createStackOverflowError(lexicalGlobalObject);
992         else if (isEvalNode<ParsedNode>())
993             *exception = createSyntaxError(lexicalGlobalObject, errMsg);
994         else
995             *exception = addErrorInfo(lexicalGlobalObject->globalExec(), createSyntaxError(lexicalGlobalObject, errMsg), errLine, *m_source);
996     }
997
998     if (debugger && !ParsedNode::scopeIsFunction)
999         debugger->sourceParsed(debuggerExecState, m_source->provider(), errLine, errMsg);
1000
1001     m_arena->reset();
1002
1003     return result.release();
1004 }
1005
1006 template <class ParsedNode>
1007 PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, JSGlobalObject* lexicalGlobalObject, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, Debugger* debugger, ExecState* execState, JSObject** exception)
1008 {
1009     SamplingRegion samplingRegion("Parsing");
1010
1011     ASSERT(!source.provider()->source().isNull());
1012
1013     if (source.provider()->source().is8Bit()) {
1014         Parser< Lexer<LChar> > parser(globalData, source, parameters, name, strictness, parserMode);
1015         return parser.parse<ParsedNode>(lexicalGlobalObject, debugger, execState, exception);
1016     }
1017     Parser< Lexer<UChar> > parser(globalData, source, parameters, name, strictness, parserMode);
1018     return parser.parse<ParsedNode>(lexicalGlobalObject, debugger, execState, exception);
1019 }
1020
1021 } // namespace 
1022 #endif