[JSC] Upstream iOS Stack bound checking
[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 "ParserError.h"
34 #include "ParserTokens.h"
35 #include "SourceProvider.h"
36 #include "SourceProviderCache.h"
37 #include "SourceProviderCacheItem.h"
38 #include <wtf/Forward.h>
39 #include <wtf/Noncopyable.h>
40 #include <wtf/OwnPtr.h>
41 #include <wtf/RefPtr.h>
42 #include <wtf/WTFThreadData.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 JSGlobalData;
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 JSGlobalData* globalData, bool isFunction, bool strictMode)
115         : m_globalData(globalData)
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_globalData(rhs.m_globalData)
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_globalData->propertyNames->eval != *ident && m_globalData->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_globalData->propertyNames->arguments == *ident;
218         bool isValidStrictMode = m_declaredVariables.add(ident->string().impl()).isNewEntry && m_globalData->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 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(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_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         RELEASE_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             RELEASE_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 #if USE(WEB_THREAD)
886         return wtfThreadData().stack().isSafeToRecurse();
887 #else
888         return m_stack.isSafeToRecurse();
889 #endif
890     }
891     
892     int lastTokenEnd() const
893     {
894         return m_lastTokenEnd;
895     }
896
897     JSGlobalData* m_globalData;
898     const SourceCode* m_source;
899     ParserArena* m_arena;
900     OwnPtr<LexerType> m_lexer;
901
902 #if !USE(WEB_THREAD)
903     StackBounds m_stack;
904 #endif
905     bool m_hasStackOverflow;
906     bool m_error;
907     String m_errorMessage;
908     JSToken m_token;
909     bool m_allowsIn;
910     int m_lastLine;
911     int m_lastTokenEnd;
912     int m_assignmentCount;
913     int m_nonLHSCount;
914     bool m_syntaxAlreadyValidated;
915     int m_statementDepth;
916     int m_nonTrivialExpressionCount;
917     const Identifier* m_lastIdentifier;
918     RefPtr<SourceProviderCache> m_functionCache;
919     SourceElements* m_sourceElements;
920     ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
921     ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
922     IdentifierSet m_capturedVariables;
923     CodeFeatures m_features;
924     int m_numConstants;
925     
926     struct DepthManager {
927         DepthManager(int* depth)
928         : m_originalDepth(*depth)
929         , m_depth(depth)
930         {
931         }
932         
933         ~DepthManager()
934         {
935             *m_depth = m_originalDepth;
936         }
937         
938     private:
939         int m_originalDepth;
940         int* m_depth;
941     };
942 };
943
944
945 template <typename LexerType>
946 template <class ParsedNode>
947 PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
948 {
949     int errLine;
950     String errMsg;
951
952     if (ParsedNode::scopeIsFunction)
953         m_lexer->setIsReparsing();
954
955     m_sourceElements = 0;
956
957     errLine = -1;
958     errMsg = String();
959
960     String parseError = parseInner();
961
962     int lineNumber = m_lexer->lineNumber();
963     bool lexError = m_lexer->sawError();
964     String lexErrorMessage = lexError ? m_lexer->getErrorMessage() : String();
965     ASSERT(lexErrorMessage.isNull() != lexError);
966     m_lexer->clear();
967
968     if (!parseError.isNull() || lexError) {
969         errLine = lineNumber;
970         errMsg = !lexErrorMessage.isNull() ? lexErrorMessage : parseError;
971         m_sourceElements = 0;
972     }
973
974     RefPtr<ParsedNode> result;
975     if (m_sourceElements) {
976         JSTokenLocation location;
977         location.line = m_lexer->lastLineNumber();
978         location.column = m_lexer->currentColumnNumber();
979         result = ParsedNode::create(m_globalData,
980                                     location,
981                                     m_sourceElements,
982                                     m_varDeclarations ? &m_varDeclarations->data : 0,
983                                     m_funcDeclarations ? &m_funcDeclarations->data : 0,
984                                     m_capturedVariables,
985                                     *m_source,
986                                     m_features,
987                                     m_numConstants);
988         result->setLoc(m_source->firstLine(), m_lastLine, m_lexer->currentColumnNumber());
989     } else {
990         // We can never see a syntax error when reparsing a function, since we should have
991         // reported the error when parsing the containing program or eval code. So if we're
992         // parsing a function body node, we assume that what actually happened here is that
993         // we ran out of stack while parsing. If we see an error while parsing eval or program
994         // code we assume that it was a syntax error since running out of stack is much less
995         // likely, and we are currently unable to distinguish between the two cases.
996         if (isFunctionBodyNode(static_cast<ParsedNode*>(0)) || m_hasStackOverflow)
997             error = ParserError::StackOverflow;
998         else if (isEvalNode<ParsedNode>())
999             error = ParserError(ParserError::EvalError, errMsg, errLine);
1000         else
1001             error = ParserError(ParserError::SyntaxError, errMsg, errLine);
1002     }
1003
1004     m_arena->reset();
1005
1006     return result.release();
1007 }
1008
1009 template <class ParsedNode>
1010 PassRefPtr<ParsedNode> parse(JSGlobalData* globalData, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, ParserError& error)
1011 {
1012     SamplingRegion samplingRegion("Parsing");
1013
1014     ASSERT(!source.provider()->source().isNull());
1015     if (source.provider()->source().is8Bit()) {
1016         Parser< Lexer<LChar> > parser(globalData, source, parameters, name, strictness, parserMode);
1017         return parser.parse<ParsedNode>(error);
1018     }
1019     Parser< Lexer<UChar> > parser(globalData, source, parameters, name, strictness, parserMode);
1020     return parser.parse<ParsedNode>(error);
1021 }
1022
1023 } // namespace
1024 #endif