Fix 30% JSBench regression (caused by adding column numbers to stack traces).
[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, 2013 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 "ParserError.h"
34 #include "ParserTokens.h"
35 #include "SourceProvider.h"
36 #include "SourceProviderCache.h"
37 #include "SourceProviderCacheItem.h"
38 #include "VMStackBounds.h"
39 #include <wtf/Forward.h>
40 #include <wtf/Noncopyable.h>
41 #include <wtf/OwnPtr.h>
42 #include <wtf/RefPtr.h>
43 namespace JSC {
44 struct Scope;
45 }
46
47 namespace WTF {
48 template <> struct VectorTraits<JSC::Scope> : SimpleClassVectorTraits {
49     static const bool canInitializeWithMemset = false; // Not all Scope data members initialize to 0.
50 };
51 }
52
53 namespace JSC {
54
55 class ExecState;
56 class FunctionBodyNode;
57 class FunctionParameters;
58 class Identifier;
59 class VM;
60 class ProgramNode;
61 class SourceCode;
62
63 // Macros to make the more common TreeBuilder types a little less verbose
64 #define TreeStatement typename TreeBuilder::Statement
65 #define TreeExpression typename TreeBuilder::Expression
66 #define TreeFormalParameterList typename TreeBuilder::FormalParameterList
67 #define TreeSourceElements typename TreeBuilder::SourceElements
68 #define TreeClause typename TreeBuilder::Clause
69 #define TreeClauseList typename TreeBuilder::ClauseList
70 #define TreeConstDeclList typename TreeBuilder::ConstDeclList
71 #define TreeArguments typename TreeBuilder::Arguments
72 #define TreeArgumentsList typename TreeBuilder::ArgumentsList
73 #define TreeFunctionBody typename TreeBuilder::FunctionBody
74 #define TreeProperty typename TreeBuilder::Property
75 #define TreePropertyList typename TreeBuilder::PropertyList
76
77 COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
78
79 enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
80 enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName };
81
82 template <typename T> inline bool isEvalNode() { return false; }
83 template <> inline bool isEvalNode<EvalNode>() { return true; }
84
85 struct DepthManager {
86     DepthManager(int* depth)
87         : m_originalDepth(*depth)
88         , m_depth(depth)
89     {
90     }
91
92     ~DepthManager()
93     {
94         *m_depth = m_originalDepth;
95     }
96
97 private:
98     int m_originalDepth;
99     int* m_depth;
100 };
101
102 struct ScopeLabelInfo {
103     ScopeLabelInfo(StringImpl* ident, bool isLoop)
104         : m_ident(ident)
105         , m_isLoop(isLoop)
106     {
107     }
108
109     StringImpl* m_ident;
110     bool m_isLoop;
111 };
112
113 struct Scope {
114     Scope(const VM* vm, bool isFunction, bool strictMode)
115         : m_vm(vm)
116         , m_shadowsArguments(false)
117         , m_usesEval(false)
118         , m_needsFullActivation(false)
119         , m_allowsNewDecls(true)
120         , m_strictMode(strictMode)
121         , m_isFunction(isFunction)
122         , m_isFunctionBoundary(false)
123         , m_isValidStrictMode(true)
124         , m_loopDepth(0)
125         , m_switchDepth(0)
126     {
127     }
128
129     Scope(const Scope& rhs)
130         : m_vm(rhs.m_vm)
131         , m_shadowsArguments(rhs.m_shadowsArguments)
132         , m_usesEval(rhs.m_usesEval)
133         , m_needsFullActivation(rhs.m_needsFullActivation)
134         , m_allowsNewDecls(rhs.m_allowsNewDecls)
135         , m_strictMode(rhs.m_strictMode)
136         , m_isFunction(rhs.m_isFunction)
137         , m_isFunctionBoundary(rhs.m_isFunctionBoundary)
138         , m_isValidStrictMode(rhs.m_isValidStrictMode)
139         , m_loopDepth(rhs.m_loopDepth)
140         , m_switchDepth(rhs.m_switchDepth)
141     {
142         if (rhs.m_labels) {
143             m_labels = adoptPtr(new LabelStack);
144
145             typedef LabelStack::const_iterator iterator;
146             iterator end = rhs.m_labels->end();
147             for (iterator it = rhs.m_labels->begin(); it != end; ++it)
148                 m_labels->append(ScopeLabelInfo(it->m_ident, it->m_isLoop));
149         }
150     }
151
152     void startSwitch() { m_switchDepth++; }
153     void endSwitch() { m_switchDepth--; }
154     void startLoop() { m_loopDepth++; }
155     void endLoop() { ASSERT(m_loopDepth); m_loopDepth--; }
156     bool inLoop() { return !!m_loopDepth; }
157     bool breakIsValid() { return m_loopDepth || m_switchDepth; }
158     bool continueIsValid() { return m_loopDepth; }
159
160     void pushLabel(const Identifier* label, bool isLoop)
161     {
162         if (!m_labels)
163             m_labels = adoptPtr(new LabelStack);
164         m_labels->append(ScopeLabelInfo(label->impl(), isLoop));
165     }
166
167     void popLabel()
168     {
169         ASSERT(m_labels);
170         ASSERT(m_labels->size());
171         m_labels->removeLast();
172     }
173
174     ScopeLabelInfo* getLabel(const Identifier* label)
175     {
176         if (!m_labels)
177             return 0;
178         for (int i = m_labels->size(); i > 0; i--) {
179             if (m_labels->at(i - 1).m_ident == label->impl())
180                 return &m_labels->at(i - 1);
181         }
182         return 0;
183     }
184
185     void setIsFunction()
186     {
187         m_isFunction = true;
188         m_isFunctionBoundary = true;
189     }
190     bool isFunction() { return m_isFunction; }
191     bool isFunctionBoundary() { return m_isFunctionBoundary; }
192
193     void declareCallee(const Identifier* ident)
194     {
195         m_declaredVariables.add(ident->string().impl());
196     }
197
198     bool declareVariable(const Identifier* ident)
199     {
200         bool isValidStrictMode = m_vm->propertyNames->eval != *ident && m_vm->propertyNames->arguments != *ident;
201         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
202         m_declaredVariables.add(ident->string().impl());
203         return isValidStrictMode;
204     }
205
206     void declareWrite(const Identifier* ident)
207     {
208         ASSERT(m_strictMode);
209         m_writtenVariables.add(ident->impl());
210     }
211
212     void preventNewDecls() { m_allowsNewDecls = false; }
213     bool allowsNewDecls() const { return m_allowsNewDecls; }
214
215     bool declareParameter(const Identifier* ident)
216     {
217         bool isArguments = m_vm->propertyNames->arguments == *ident;
218         bool isValidStrictMode = m_declaredVariables.add(ident->string().impl()).isNewEntry && m_vm->propertyNames->eval != *ident && !isArguments;
219         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
220         if (isArguments)
221             m_shadowsArguments = true;
222         return isValidStrictMode;
223     }
224
225     void useVariable(const Identifier* ident, bool isEval)
226     {
227         m_usesEval |= isEval;
228         m_usedVariables.add(ident->string().impl());
229     }
230
231     void setNeedsFullActivation() { m_needsFullActivation = true; }
232
233     bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
234     {
235         if (nestedScope->m_usesEval)
236             m_usesEval = true;
237         IdentifierSet::iterator end = nestedScope->m_usedVariables.end();
238         for (IdentifierSet::iterator ptr = nestedScope->m_usedVariables.begin(); ptr != end; ++ptr) {
239             if (nestedScope->m_declaredVariables.contains(*ptr))
240                 continue;
241             m_usedVariables.add(*ptr);
242             if (shouldTrackClosedVariables)
243                 m_closedVariables.add(*ptr);
244         }
245         if (nestedScope->m_writtenVariables.size()) {
246             IdentifierSet::iterator end = nestedScope->m_writtenVariables.end();
247             for (IdentifierSet::iterator ptr = nestedScope->m_writtenVariables.begin(); ptr != end; ++ptr) {
248                 if (nestedScope->m_declaredVariables.contains(*ptr))
249                     continue;
250                 m_writtenVariables.add(*ptr);
251             }
252         }
253
254         return true;
255     }
256
257     void getUncapturedWrittenVariables(IdentifierSet& writtenVariables)
258     {
259         IdentifierSet::iterator end = m_writtenVariables.end();
260         for (IdentifierSet::iterator ptr = m_writtenVariables.begin(); ptr != end; ++ptr) {
261             if (!m_declaredVariables.contains(*ptr))
262                 writtenVariables.add(*ptr);
263         }
264     }
265
266     void getCapturedVariables(IdentifierSet& capturedVariables)
267     {
268         if (m_needsFullActivation || m_usesEval) {
269             capturedVariables.swap(m_declaredVariables);
270             return;
271         }
272         for (IdentifierSet::iterator ptr = m_closedVariables.begin(); ptr != m_closedVariables.end(); ++ptr) {
273             if (!m_declaredVariables.contains(*ptr))
274                 continue;
275             capturedVariables.add(*ptr);
276         }
277     }
278     void setStrictMode() { m_strictMode = true; }
279     bool strictMode() const { return m_strictMode; }
280     bool isValidStrictMode() const { return m_isValidStrictMode; }
281     bool shadowsArguments() const { return m_shadowsArguments; }
282
283     void copyCapturedVariablesToVector(const IdentifierSet& capturedVariables, Vector<RefPtr<StringImpl> >& vector)
284     {
285         IdentifierSet::iterator end = capturedVariables.end();
286         for (IdentifierSet::iterator it = capturedVariables.begin(); it != end; ++it) {
287             if (m_declaredVariables.contains(*it))
288                 continue;
289             vector.append(*it);
290         }
291     }
292
293     void fillParametersForSourceProviderCache(SourceProviderCacheItemCreationParameters& parameters)
294     {
295         ASSERT(m_isFunction);
296         parameters.usesEval = m_usesEval;
297         parameters.strictMode = m_strictMode;
298         parameters.needsFullActivation = m_needsFullActivation;
299         copyCapturedVariablesToVector(m_writtenVariables, parameters.writtenVariables);
300         copyCapturedVariablesToVector(m_usedVariables, parameters.usedVariables);
301     }
302
303     void restoreFromSourceProviderCache(const SourceProviderCacheItem* info)
304     {
305         ASSERT(m_isFunction);
306         m_usesEval = info->usesEval;
307         m_strictMode = info->strictMode;
308         m_needsFullActivation = info->needsFullActivation;
309         for (unsigned i = 0; i < info->usedVariablesCount; ++i)
310             m_usedVariables.add(info->usedVariables()[i]);
311         for (unsigned i = 0; i < info->writtenVariablesCount; ++i)
312             m_writtenVariables.add(info->writtenVariables()[i]);
313     }
314
315 private:
316     const VM* m_vm;
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(VM*, const SourceCode&, FunctionParameters*, const Identifier&, JSParserStrictness, JSParserMode);
370     ~Parser();
371
372     template <class ParsedNode>
373     PassRefPtr<ParsedNode> parse(ParserError&);
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_vm, 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     ALWAYS_INLINE void next(unsigned lexerFlags = 0)
486     {
487         m_lastLine = m_token.m_location.line;
488         m_lastTokenEnd = m_token.m_location.endOffset;
489         m_lastTokenLineStart = m_token.m_location.lineStartOffset;
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_lastTokenLineStart = m_token.m_location.lineStartOffset;
499         m_lexer->setLastLineNumber(m_lastLine);
500         m_token.m_type = m_lexer->lexExpectIdentifier(&m_token.m_data, &m_token.m_location, lexerFlags, strictMode());
501     }
502
503     ALWAYS_INLINE bool nextTokenIsColon()
504     {
505         return m_lexer->nextTokenIsColon();
506     }
507
508     ALWAYS_INLINE bool consume(JSTokenType expected, unsigned flags = 0)
509     {
510         bool result = m_token.m_type == expected;
511         if (result)
512             next(flags);
513         return result;
514     }
515     
516     ALWAYS_INLINE String getToken() {
517         SourceProvider* sourceProvider = m_source->provider();
518         return sourceProvider->getRange(tokenStart(), tokenEnd());
519     }
520     
521     ALWAYS_INLINE bool match(JSTokenType expected)
522     {
523         return m_token.m_type == expected;
524     }
525     
526     ALWAYS_INLINE unsigned tokenStart()
527     {
528         return m_token.m_location.startOffset;
529     }
530     
531     ALWAYS_INLINE int tokenLine()
532     {
533         return m_token.m_location.line;
534     }
535     
536     ALWAYS_INLINE int tokenColumn()
537     {
538         return tokenStart() - tokenLineStart();
539     }
540
541     ALWAYS_INLINE unsigned tokenEnd()
542     {
543         return m_token.m_location.endOffset;
544     }
545     
546     ALWAYS_INLINE unsigned tokenLineStart()
547     {
548         return m_token.m_location.lineStartOffset;
549     }
550     
551     ALWAYS_INLINE const JSTokenLocation& tokenLocation()
552     {
553         return m_token.m_location;
554     }
555
556     const char* getTokenName(JSTokenType tok)
557     {
558         switch (tok) {
559         case NULLTOKEN: 
560             return "null";
561         case TRUETOKEN:
562             return "true";
563         case FALSETOKEN: 
564             return "false";
565         case BREAK: 
566             return "break";
567         case CASE: 
568             return "case";
569         case DEFAULT: 
570             return "default";
571         case FOR: 
572             return "for";
573         case NEW: 
574             return "new";
575         case VAR: 
576             return "var";
577         case CONSTTOKEN: 
578             return "const";
579         case CONTINUE: 
580             return "continue";
581         case FUNCTION: 
582             return "function";
583         case IF: 
584             return "if";
585         case THISTOKEN: 
586             return "this";
587         case DO: 
588             return "do";
589         case WHILE: 
590             return "while";
591         case SWITCH: 
592             return "switch";
593         case WITH: 
594             return "with";
595         case THROW: 
596             return "throw";
597         case TRY: 
598             return "try";
599         case CATCH: 
600             return "catch";
601         case FINALLY: 
602             return "finally";
603         case DEBUGGER: 
604             return "debugger";
605         case ELSE: 
606             return "else";
607         case OPENBRACE: 
608             return "{";
609         case CLOSEBRACE: 
610             return "}";
611         case OPENPAREN: 
612             return "(";
613         case CLOSEPAREN: 
614             return ")";
615         case OPENBRACKET: 
616             return "[";
617         case CLOSEBRACKET: 
618             return "]";
619         case COMMA: 
620             return ",";
621         case QUESTION: 
622             return "?";
623         case SEMICOLON: 
624             return ";";
625         case COLON: 
626             return ":";
627         case DOT: 
628             return ".";
629         case EQUAL: 
630             return "=";
631         case PLUSEQUAL: 
632             return "+=";
633         case MINUSEQUAL: 
634             return "-=";
635         case MULTEQUAL: 
636             return "*=";
637         case DIVEQUAL: 
638             return "/=";
639         case LSHIFTEQUAL: 
640             return "<<=";
641         case RSHIFTEQUAL: 
642             return ">>=";
643         case URSHIFTEQUAL: 
644             return ">>>=";
645         case ANDEQUAL: 
646             return "&=";
647         case MODEQUAL: 
648             return "%=";
649         case XOREQUAL: 
650             return "^=";
651         case OREQUAL: 
652             return "|=";
653         case AUTOPLUSPLUS: 
654         case PLUSPLUS: 
655             return "++";
656         case AUTOMINUSMINUS: 
657         case MINUSMINUS: 
658             return "--";
659         case EXCLAMATION: 
660             return "!";
661         case TILDE: 
662             return "~";
663         case TYPEOF: 
664             return "typeof";
665         case VOIDTOKEN: 
666             return "void";
667         case DELETETOKEN: 
668             return "delete";
669         case OR: 
670             return "||";
671         case AND: 
672             return "&&";
673         case BITOR: 
674             return "|";
675         case BITXOR: 
676             return "^";
677         case BITAND: 
678             return "&";
679         case EQEQ: 
680             return "==";
681         case NE: 
682             return "!=";
683         case STREQ: 
684             return "===";
685         case STRNEQ: 
686             return "!==";
687         case LT: 
688             return "<";
689         case GT: 
690             return ">";
691         case LE: 
692             return "<=";
693         case GE: 
694             return ">=";
695         case INSTANCEOF: 
696             return "instanceof";
697         case INTOKEN: 
698             return "in";
699         case LSHIFT: 
700             return "<<";
701         case RSHIFT: 
702             return ">>";
703         case URSHIFT: 
704             return ">>>";
705         case PLUS: 
706             return "+";
707         case MINUS: 
708             return "-";
709         case TIMES: 
710             return "*";
711         case DIVIDE: 
712             return "/";
713         case MOD: 
714             return "%";
715         case RETURN: 
716         case RESERVED_IF_STRICT:
717         case RESERVED: 
718         case NUMBER:
719         case IDENT: 
720         case STRING:
721         case UNTERMINATED_IDENTIFIER_ESCAPE_ERRORTOK:
722         case UNTERMINATED_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK:
723         case UNTERMINATED_MULTILINE_COMMENT_ERRORTOK:
724         case UNTERMINATED_NUMERIC_LITERAL_ERRORTOK:
725         case UNTERMINATED_STRING_LITERAL_ERRORTOK:
726         case INVALID_IDENTIFIER_ESCAPE_ERRORTOK:
727         case INVALID_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK:
728         case INVALID_NUMERIC_LITERAL_ERRORTOK:
729         case INVALID_OCTAL_NUMBER_ERRORTOK:
730         case INVALID_STRING_LITERAL_ERRORTOK:
731         case ERRORTOK:
732         case EOFTOK:
733             return 0;
734         case LastUntaggedToken: 
735             break;
736         }
737         RELEASE_ASSERT_NOT_REACHED();
738         return "internal error";
739     }
740     
741     ALWAYS_INLINE void updateErrorMessageSpecialCase(JSTokenType expectedToken) 
742     {
743         switch (expectedToken) {
744         case RESERVED_IF_STRICT:
745             m_errorMessage = "Use of reserved word '" + getToken() + "' in strict mode";
746             return;
747         case RESERVED:
748             m_errorMessage = "Use of reserved word '" + getToken() + '\'';
749             return;
750         case NUMBER: 
751             m_errorMessage = "Unexpected number '" + getToken() + '\'';
752             return;
753         case IDENT: 
754             m_errorMessage = "Expected an identifier but found '" + getToken() + "' instead";
755             return;
756         case STRING: 
757             m_errorMessage = "Unexpected string " + getToken();
758             return;
759             
760         case UNTERMINATED_IDENTIFIER_ESCAPE_ERRORTOK:
761         case UNTERMINATED_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK:
762             m_errorMessage = "Incomplete unicode escape in identifier: '" + getToken() + '\'';
763             return;
764         case UNTERMINATED_MULTILINE_COMMENT_ERRORTOK:
765             m_errorMessage = "Unterminated multiline comment";
766             return;
767         case UNTERMINATED_NUMERIC_LITERAL_ERRORTOK:
768             m_errorMessage = "Unterminated numeric literal '" + getToken() + '\'';
769             return;
770         case UNTERMINATED_STRING_LITERAL_ERRORTOK:
771             m_errorMessage = "Unterminated string literal '" + getToken() + '\'';
772             return;
773         case INVALID_IDENTIFIER_ESCAPE_ERRORTOK:
774             m_errorMessage = "Invalid escape in identifier: '" + getToken() + '\'';
775             return;
776         case INVALID_IDENTIFIER_UNICODE_ESCAPE_ERRORTOK:
777             m_errorMessage = "Invalid unicode escape in identifier: '" + getToken() + '\'';
778             return;
779         case INVALID_NUMERIC_LITERAL_ERRORTOK:
780             m_errorMessage = "Invalid numeric literal: '" + getToken() + '\'';
781             return;
782         case INVALID_OCTAL_NUMBER_ERRORTOK:
783             m_errorMessage = "Invalid use of octal: '" + getToken() + '\'';
784                 return;
785         case INVALID_STRING_LITERAL_ERRORTOK:
786             m_errorMessage = "Invalid string literal: '" + getToken() + '\'';
787             return;
788         case ERRORTOK:
789             m_errorMessage = "Unrecognized token '" + getToken() + '\'';
790             return;
791         case EOFTOK:  
792             m_errorMessage = ASCIILiteral("Unexpected EOF");
793             return;
794         case RETURN:
795             m_errorMessage = ASCIILiteral("Return statements are only valid inside functions");
796             return;
797         default:
798             RELEASE_ASSERT_NOT_REACHED();
799             m_errorMessage = ASCIILiteral("internal error");
800             return;
801         }
802     }
803     
804     NEVER_INLINE void updateErrorMessage() 
805     {
806         const char* name = getTokenName(m_token.m_type);
807         if (!name) 
808             updateErrorMessageSpecialCase(m_token.m_type);
809         else 
810             m_errorMessage = String::format("Unexpected token '%s'", name);
811         ASSERT(!m_errorMessage.isNull());
812     }
813     
814     NEVER_INLINE void updateErrorMessage(JSTokenType expectedToken) 
815     {
816         const char* name = getTokenName(expectedToken);
817         if (name)
818             m_errorMessage = String::format("Expected token '%s'", name);
819         else {
820             if (!getTokenName(m_token.m_type))
821                 updateErrorMessageSpecialCase(m_token.m_type);
822             else
823                 updateErrorMessageSpecialCase(expectedToken);
824         }
825         ASSERT(!m_errorMessage.isNull());
826     }
827     
828     NEVER_INLINE void updateErrorWithNameAndMessage(const char* beforeMsg, String name, const char* afterMsg)
829     {
830         m_errorMessage = makeString(beforeMsg, " '", name, "' ", afterMsg);
831     }
832     
833     NEVER_INLINE void updateErrorMessage(const char* msg)
834     {
835         ASSERT(msg);
836         m_errorMessage = String(msg);
837         ASSERT(!m_errorMessage.isNull());
838     }
839     
840     void startLoop() { currentScope()->startLoop(); }
841     void endLoop() { currentScope()->endLoop(); }
842     void startSwitch() { currentScope()->startSwitch(); }
843     void endSwitch() { currentScope()->endSwitch(); }
844     void setStrictMode() { currentScope()->setStrictMode(); }
845     bool strictMode() { return currentScope()->strictMode(); }
846     bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
847     bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
848     bool breakIsValid()
849     {
850         ScopeRef current = currentScope();
851         while (!current->breakIsValid()) {
852             if (!current.hasContainingScope())
853                 return false;
854             current = current.containingScope();
855         }
856         return true;
857     }
858     bool continueIsValid()
859     {
860         ScopeRef current = currentScope();
861         while (!current->continueIsValid()) {
862             if (!current.hasContainingScope())
863                 return false;
864             current = current.containingScope();
865         }
866         return true;
867     }
868     void pushLabel(const Identifier* label, bool isLoop) { currentScope()->pushLabel(label, isLoop); }
869     void popLabel() { currentScope()->popLabel(); }
870     ScopeLabelInfo* getLabel(const Identifier* label)
871     {
872         ScopeRef current = currentScope();
873         ScopeLabelInfo* result = 0;
874         while (!(result = current->getLabel(label))) {
875             if (!current.hasContainingScope())
876                 return 0;
877             current = current.containingScope();
878         }
879         return result;
880     }
881     
882     template <SourceElementsMode mode, class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&);
883     template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
884     template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&);
885     template <class TreeBuilder> TreeStatement parseVarDeclaration(TreeBuilder&);
886     template <class TreeBuilder> TreeStatement parseConstDeclaration(TreeBuilder&);
887     template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&);
888     template <class TreeBuilder> TreeStatement parseWhileStatement(TreeBuilder&);
889     template <class TreeBuilder> TreeStatement parseForStatement(TreeBuilder&);
890     template <class TreeBuilder> TreeStatement parseBreakStatement(TreeBuilder&);
891     template <class TreeBuilder> TreeStatement parseContinueStatement(TreeBuilder&);
892     template <class TreeBuilder> TreeStatement parseReturnStatement(TreeBuilder&);
893     template <class TreeBuilder> TreeStatement parseThrowStatement(TreeBuilder&);
894     template <class TreeBuilder> TreeStatement parseWithStatement(TreeBuilder&);
895     template <class TreeBuilder> TreeStatement parseSwitchStatement(TreeBuilder&);
896     template <class TreeBuilder> TreeClauseList parseSwitchClauses(TreeBuilder&);
897     template <class TreeBuilder> TreeClause parseSwitchDefaultClause(TreeBuilder&);
898     template <class TreeBuilder> TreeStatement parseTryStatement(TreeBuilder&);
899     template <class TreeBuilder> TreeStatement parseDebuggerStatement(TreeBuilder&);
900     template <class TreeBuilder> TreeStatement parseExpressionStatement(TreeBuilder&);
901     template <class TreeBuilder> TreeStatement parseExpressionOrLabelStatement(TreeBuilder&);
902     template <class TreeBuilder> TreeStatement parseIfStatement(TreeBuilder&);
903     template <class TreeBuilder> ALWAYS_INLINE TreeStatement parseBlockStatement(TreeBuilder&);
904     template <class TreeBuilder> TreeExpression parseExpression(TreeBuilder&);
905     template <class TreeBuilder> TreeExpression parseAssignmentExpression(TreeBuilder&);
906     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseConditionalExpression(TreeBuilder&);
907     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseBinaryExpression(TreeBuilder&);
908     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseUnaryExpression(TreeBuilder&);
909     template <class TreeBuilder> TreeExpression parseMemberExpression(TreeBuilder&);
910     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parsePrimaryExpression(TreeBuilder&);
911     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArrayLiteral(TreeBuilder&);
912     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseObjectLiteral(TreeBuilder&);
913     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&);
914     template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&);
915     template <bool strict, class TreeBuilder> ALWAYS_INLINE TreeProperty parseProperty(TreeBuilder&);
916     template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&);
917     template <class TreeBuilder> ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&);
918     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, const Identifier*& lastIdent, TreeExpression& lastInitializer, int& identStart, int& initStart, int& initEnd);
919     template <class TreeBuilder> ALWAYS_INLINE TreeConstDeclList parseConstDeclarationList(TreeBuilder& context);
920     template <FunctionRequirements, bool nameIsInContainingScope, class TreeBuilder> bool parseFunctionInfo(TreeBuilder&, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, unsigned& openBraceOffset, unsigned& closeBraceOffset, int& bodyStartLine, unsigned& bodyStartColumn);
921     ALWAYS_INLINE int isBinaryOperator(JSTokenType);
922     bool allowAutomaticSemicolon();
923     
924     bool autoSemiColon()
925     {
926         if (m_token.m_type == SEMICOLON) {
927             next();
928             return true;
929         }
930         return allowAutomaticSemicolon();
931     }
932     
933     bool canRecurse()
934     {
935         return m_stack.isSafeToRecurse();
936     }
937     
938     int lastTokenEnd() const
939     {
940         return m_lastTokenEnd;
941     }
942
943     unsigned lastTokenLine() const
944     {
945         return m_lastLine;
946     }
947
948     unsigned lastTokenLineStart() const
949     {
950         return m_lastTokenLineStart;
951     }
952
953     bool hasError() const
954     {
955         return !m_errorMessage.isNull();
956     }
957
958     VM* m_vm;
959     const SourceCode* m_source;
960     ParserArena* m_arena;
961     OwnPtr<LexerType> m_lexer;
962     
963     VMStackBounds m_stack;
964     bool m_hasStackOverflow;
965     String m_errorMessage;
966     JSToken m_token;
967     bool m_allowsIn;
968     unsigned m_lastLine;
969     int m_lastTokenEnd;
970     unsigned m_lastTokenLine;
971     unsigned m_lastTokenLineStart;
972     int m_assignmentCount;
973     int m_nonLHSCount;
974     bool m_syntaxAlreadyValidated;
975     int m_statementDepth;
976     int m_nonTrivialExpressionCount;
977     const Identifier* m_lastIdentifier;
978     RefPtr<SourceProviderCache> m_functionCache;
979     SourceElements* m_sourceElements;
980     ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
981     ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
982     IdentifierSet m_capturedVariables;
983     CodeFeatures m_features;
984     int m_numConstants;
985     
986     struct DepthManager {
987         DepthManager(int* depth)
988         : m_originalDepth(*depth)
989         , m_depth(depth)
990         {
991         }
992         
993         ~DepthManager()
994         {
995             *m_depth = m_originalDepth;
996         }
997         
998     private:
999         int m_originalDepth;
1000         int* m_depth;
1001     };
1002 };
1003
1004
1005 template <typename LexerType>
1006 template <class ParsedNode>
1007 PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
1008 {
1009     int errLine;
1010     String errMsg;
1011
1012     if (ParsedNode::scopeIsFunction)
1013         m_lexer->setIsReparsing();
1014
1015     m_sourceElements = 0;
1016
1017     errLine = -1;
1018     errMsg = String();
1019
1020     JSTokenLocation startLocation(tokenLocation());
1021     unsigned startColumn = m_source->startColumn();
1022
1023     String parseError = parseInner();
1024
1025     int lineNumber = m_lexer->lineNumber();
1026     bool lexError = m_lexer->sawError();
1027     String lexErrorMessage = lexError ? m_lexer->getErrorMessage() : String();
1028     ASSERT(lexErrorMessage.isNull() != lexError);
1029     m_lexer->clear();
1030
1031     if (!parseError.isNull() || lexError) {
1032         errLine = lineNumber;
1033         errMsg = !lexErrorMessage.isNull() ? lexErrorMessage : parseError;
1034         m_sourceElements = 0;
1035     }
1036
1037     RefPtr<ParsedNode> result;
1038     if (m_sourceElements) {
1039         JSTokenLocation endLocation(m_source->startOffset());
1040         endLocation.line = m_lexer->lastLineNumber();
1041         endLocation.lineStartOffset = m_lexer->currentLineStartOffset();
1042         endLocation.startOffset = m_lexer->currentOffset();
1043         result = ParsedNode::create(m_vm,
1044                                     startLocation,
1045                                     endLocation,
1046                                     startColumn,
1047                                     m_sourceElements,
1048                                     m_varDeclarations ? &m_varDeclarations->data : 0,
1049                                     m_funcDeclarations ? &m_funcDeclarations->data : 0,
1050                                     m_capturedVariables,
1051                                     *m_source,
1052                                     m_features,
1053                                     m_numConstants);
1054         result->setLoc(m_source->firstLine(), m_lastLine, m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
1055     } else {
1056         // We can never see a syntax error when reparsing a function, since we should have
1057         // reported the error when parsing the containing program or eval code. So if we're
1058         // parsing a function body node, we assume that what actually happened here is that
1059         // we ran out of stack while parsing. If we see an error while parsing eval or program
1060         // code we assume that it was a syntax error since running out of stack is much less
1061         // likely, and we are currently unable to distinguish between the two cases.
1062         if (isFunctionBodyNode(static_cast<ParsedNode*>(0)) || m_hasStackOverflow)
1063             error = ParserError(ParserError::StackOverflow, ParserError::SyntaxErrorNone, m_token);
1064         else {
1065             ParserError::SyntaxErrorType errorType = ParserError::SyntaxErrorIrrecoverable;
1066             if (m_token.m_type == EOFTOK)
1067                 errorType = ParserError::SyntaxErrorRecoverable;
1068             else if (m_token.m_type & UnterminatedErrorTokenFlag)
1069                 errorType = ParserError::SyntaxErrorUnterminatedLiteral;
1070             
1071             if (isEvalNode<ParsedNode>())
1072                 error = ParserError(ParserError::EvalError, errorType, m_token, errMsg, errLine);
1073             else
1074                 error = ParserError(ParserError::SyntaxError, errorType, m_token, errMsg, errLine);
1075         }
1076     }
1077
1078     m_arena->reset();
1079
1080     return result.release();
1081 }
1082
1083 template <class ParsedNode>
1084 PassRefPtr<ParsedNode> parse(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, ParserError& error)
1085 {
1086     SamplingRegion samplingRegion("Parsing");
1087
1088     ASSERT(!source.provider()->source().isNull());
1089     if (source.provider()->source().is8Bit()) {
1090         Parser< Lexer<LChar> > parser(vm, source, parameters, name, strictness, parserMode);
1091         return parser.parse<ParsedNode>(error);
1092     }
1093     Parser< Lexer<UChar> > parser(vm, source, parameters, name, strictness, parserMode);
1094     return parser.parse<ParsedNode>(error);
1095 }
1096
1097 } // namespace
1098 #endif