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