REGRESSION (r158014): Many webpages throw stack overflow exceptions on iOS (because...
[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 #define TreeDeconstructionPattern typename TreeBuilder::DeconstructionPattern
77
78 COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
79
80 enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
81 enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName };
82 enum FunctionParseMode { FunctionMode, GetterMode, SetterMode };
83 enum DeconstructionKind {
84     DeconstructToVariables,
85     DeconstructToParameters,
86     DeconstructToExpressions
87 };
88
89 template <typename T> inline bool isEvalNode() { return false; }
90 template <> inline bool isEvalNode<EvalNode>() { return true; }
91
92 struct DepthManager {
93     DepthManager(int* depth)
94         : m_originalDepth(*depth)
95         , m_depth(depth)
96     {
97     }
98
99     ~DepthManager()
100     {
101         *m_depth = m_originalDepth;
102     }
103
104 private:
105     int m_originalDepth;
106     int* m_depth;
107 };
108
109 struct ScopeLabelInfo {
110     ScopeLabelInfo(StringImpl* ident, bool isLoop)
111         : m_ident(ident)
112         , m_isLoop(isLoop)
113     {
114     }
115
116     StringImpl* m_ident;
117     bool m_isLoop;
118 };
119
120 struct Scope {
121     Scope(const VM* vm, bool isFunction, bool strictMode)
122         : m_vm(vm)
123         , m_shadowsArguments(false)
124         , m_usesEval(false)
125         , m_needsFullActivation(false)
126         , m_allowsNewDecls(true)
127         , m_strictMode(strictMode)
128         , m_isFunction(isFunction)
129         , m_isFunctionBoundary(false)
130         , m_isValidStrictMode(true)
131         , m_loopDepth(0)
132         , m_switchDepth(0)
133     {
134     }
135
136     Scope(const Scope& rhs)
137         : m_vm(rhs.m_vm)
138         , m_shadowsArguments(rhs.m_shadowsArguments)
139         , m_usesEval(rhs.m_usesEval)
140         , m_needsFullActivation(rhs.m_needsFullActivation)
141         , m_allowsNewDecls(rhs.m_allowsNewDecls)
142         , m_strictMode(rhs.m_strictMode)
143         , m_isFunction(rhs.m_isFunction)
144         , m_isFunctionBoundary(rhs.m_isFunctionBoundary)
145         , m_isValidStrictMode(rhs.m_isValidStrictMode)
146         , m_loopDepth(rhs.m_loopDepth)
147         , m_switchDepth(rhs.m_switchDepth)
148     {
149         if (rhs.m_labels) {
150             m_labels = adoptPtr(new LabelStack);
151
152             typedef LabelStack::const_iterator iterator;
153             iterator end = rhs.m_labels->end();
154             for (iterator it = rhs.m_labels->begin(); it != end; ++it)
155                 m_labels->append(ScopeLabelInfo(it->m_ident, it->m_isLoop));
156         }
157     }
158
159     void startSwitch() { m_switchDepth++; }
160     void endSwitch() { m_switchDepth--; }
161     void startLoop() { m_loopDepth++; }
162     void endLoop() { ASSERT(m_loopDepth); m_loopDepth--; }
163     bool inLoop() { return !!m_loopDepth; }
164     bool breakIsValid() { return m_loopDepth || m_switchDepth; }
165     bool continueIsValid() { return m_loopDepth; }
166
167     void pushLabel(const Identifier* label, bool isLoop)
168     {
169         if (!m_labels)
170             m_labels = adoptPtr(new LabelStack);
171         m_labels->append(ScopeLabelInfo(label->impl(), isLoop));
172     }
173
174     void popLabel()
175     {
176         ASSERT(m_labels);
177         ASSERT(m_labels->size());
178         m_labels->removeLast();
179     }
180
181     ScopeLabelInfo* getLabel(const Identifier* label)
182     {
183         if (!m_labels)
184             return 0;
185         for (int i = m_labels->size(); i > 0; i--) {
186             if (m_labels->at(i - 1).m_ident == label->impl())
187                 return &m_labels->at(i - 1);
188         }
189         return 0;
190     }
191
192     void setIsFunction()
193     {
194         m_isFunction = true;
195         m_isFunctionBoundary = true;
196     }
197     bool isFunction() { return m_isFunction; }
198     bool isFunctionBoundary() { return m_isFunctionBoundary; }
199
200     void declareCallee(const Identifier* ident)
201     {
202         m_declaredVariables.add(ident->string().impl());
203     }
204
205     bool declareVariable(const Identifier* ident)
206     {
207         bool isValidStrictMode = m_vm->propertyNames->eval != *ident && m_vm->propertyNames->arguments != *ident;
208         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
209         m_declaredVariables.add(ident->string().impl());
210         return isValidStrictMode;
211     }
212
213     bool hasDeclaredVariable(const Identifier& ident)
214     {
215         return m_declaredVariables.contains(ident.impl());
216     }
217     
218     bool hasDeclaredParameter(const Identifier& ident)
219     {
220         return m_declaredParameters.contains(ident.impl()) || m_declaredVariables.contains(ident.impl());
221     }
222     
223     void declareWrite(const Identifier* ident)
224     {
225         ASSERT(m_strictMode);
226         m_writtenVariables.add(ident->impl());
227     }
228
229     void preventNewDecls() { m_allowsNewDecls = false; }
230     bool allowsNewDecls() const { return m_allowsNewDecls; }
231
232     bool declareParameter(const Identifier* ident)
233     {
234         bool isArguments = m_vm->propertyNames->arguments == *ident;
235         bool isValidStrictMode = m_declaredVariables.add(ident->string().impl()).isNewEntry && m_vm->propertyNames->eval != *ident && !isArguments;
236         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
237         m_declaredParameters.add(ident->string().impl());
238
239         if (isArguments)
240             m_shadowsArguments = true;
241         return isValidStrictMode;
242     }
243     
244     enum BindingResult {
245         BindingFailed,
246         StrictBindingFailed,
247         BindingSucceeded
248     };
249     BindingResult declareBoundParameter(const Identifier* ident)
250     {
251         bool isArguments = m_vm->propertyNames->arguments == *ident;
252         bool newEntry = m_declaredVariables.add(ident->string().impl()).isNewEntry;
253         bool isValidStrictMode = newEntry && m_vm->propertyNames->eval != *ident && !isArguments;
254         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
255     
256         if (isArguments)
257             m_shadowsArguments = true;
258         if (!newEntry)
259             return BindingFailed;
260         return isValidStrictMode ? BindingSucceeded : StrictBindingFailed;
261     }
262
263
264     void useVariable(const Identifier* ident, bool isEval)
265     {
266         m_usesEval |= isEval;
267         m_usedVariables.add(ident->string().impl());
268     }
269
270     void setNeedsFullActivation() { m_needsFullActivation = true; }
271
272     bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
273     {
274         if (nestedScope->m_usesEval)
275             m_usesEval = true;
276         IdentifierSet::iterator end = nestedScope->m_usedVariables.end();
277         for (IdentifierSet::iterator ptr = nestedScope->m_usedVariables.begin(); ptr != end; ++ptr) {
278             if (nestedScope->m_declaredVariables.contains(*ptr))
279                 continue;
280             m_usedVariables.add(*ptr);
281             if (shouldTrackClosedVariables)
282                 m_closedVariables.add(*ptr);
283         }
284         if (nestedScope->m_writtenVariables.size()) {
285             IdentifierSet::iterator end = nestedScope->m_writtenVariables.end();
286             for (IdentifierSet::iterator ptr = nestedScope->m_writtenVariables.begin(); ptr != end; ++ptr) {
287                 if (nestedScope->m_declaredVariables.contains(*ptr))
288                     continue;
289                 m_writtenVariables.add(*ptr);
290             }
291         }
292
293         return true;
294     }
295
296     void getCapturedVariables(IdentifierSet& capturedVariables, bool& modifiedParameter)
297     {
298         if (m_needsFullActivation || m_usesEval) {
299             modifiedParameter = true;
300             capturedVariables.swap(m_declaredVariables);
301             return;
302         }
303         for (IdentifierSet::iterator ptr = m_closedVariables.begin(); ptr != m_closedVariables.end(); ++ptr) {
304             if (!m_declaredVariables.contains(*ptr))
305                 continue;
306             capturedVariables.add(*ptr);
307         }
308         modifiedParameter = false;
309         if (m_declaredParameters.size()) {
310             IdentifierSet::iterator end = m_writtenVariables.end();
311             for (IdentifierSet::iterator ptr = m_writtenVariables.begin(); ptr != end; ++ptr) {
312                 if (!m_declaredParameters.contains(*ptr))
313                     continue;
314                 modifiedParameter = true;
315                 break;
316             }
317         }
318     }
319     void setStrictMode() { m_strictMode = true; }
320     bool strictMode() const { return m_strictMode; }
321     bool isValidStrictMode() const { return m_isValidStrictMode; }
322     bool shadowsArguments() const { return m_shadowsArguments; }
323
324     void copyCapturedVariablesToVector(const IdentifierSet& capturedVariables, Vector<RefPtr<StringImpl>>& vector)
325     {
326         IdentifierSet::iterator end = capturedVariables.end();
327         for (IdentifierSet::iterator it = capturedVariables.begin(); it != end; ++it) {
328             if (m_declaredVariables.contains(*it))
329                 continue;
330             vector.append(*it);
331         }
332     }
333
334     void fillParametersForSourceProviderCache(SourceProviderCacheItemCreationParameters& parameters)
335     {
336         ASSERT(m_isFunction);
337         parameters.usesEval = m_usesEval;
338         parameters.strictMode = m_strictMode;
339         parameters.needsFullActivation = m_needsFullActivation;
340         copyCapturedVariablesToVector(m_writtenVariables, parameters.writtenVariables);
341         copyCapturedVariablesToVector(m_usedVariables, parameters.usedVariables);
342     }
343
344     void restoreFromSourceProviderCache(const SourceProviderCacheItem* info)
345     {
346         ASSERT(m_isFunction);
347         m_usesEval = info->usesEval;
348         m_strictMode = info->strictMode;
349         m_needsFullActivation = info->needsFullActivation;
350         for (unsigned i = 0; i < info->usedVariablesCount; ++i)
351             m_usedVariables.add(info->usedVariables()[i]);
352         for (unsigned i = 0; i < info->writtenVariablesCount; ++i)
353             m_writtenVariables.add(info->writtenVariables()[i]);
354     }
355
356 private:
357     const VM* m_vm;
358     bool m_shadowsArguments : 1;
359     bool m_usesEval : 1;
360     bool m_needsFullActivation : 1;
361     bool m_allowsNewDecls : 1;
362     bool m_strictMode : 1;
363     bool m_isFunction : 1;
364     bool m_isFunctionBoundary : 1;
365     bool m_isValidStrictMode : 1;
366     int m_loopDepth;
367     int m_switchDepth;
368
369     typedef Vector<ScopeLabelInfo, 2> LabelStack;
370     OwnPtr<LabelStack> m_labels;
371     IdentifierSet m_declaredParameters;
372     IdentifierSet m_declaredVariables;
373     IdentifierSet m_usedVariables;
374     IdentifierSet m_closedVariables;
375     IdentifierSet m_writtenVariables;
376 };
377
378 typedef Vector<Scope, 10> ScopeStack;
379
380 struct ScopeRef {
381     ScopeRef(ScopeStack* scopeStack, unsigned index)
382         : m_scopeStack(scopeStack)
383         , m_index(index)
384     {
385     }
386     Scope* operator->() { return &m_scopeStack->at(m_index); }
387     unsigned index() const { return m_index; }
388
389     bool hasContainingScope()
390     {
391         return m_index && !m_scopeStack->at(m_index).isFunctionBoundary();
392     }
393
394     ScopeRef containingScope()
395     {
396         ASSERT(hasContainingScope());
397         return ScopeRef(m_scopeStack, m_index - 1);
398     }
399
400 private:
401     ScopeStack* m_scopeStack;
402     unsigned m_index;
403 };
404
405 template <typename LexerType>
406 class Parser {
407     WTF_MAKE_NONCOPYABLE(Parser);
408     WTF_MAKE_FAST_ALLOCATED;
409
410 public:
411     Parser(VM*, const SourceCode&, FunctionParameters*, const Identifier&, JSParserStrictness, JSParserMode);
412     ~Parser();
413
414     template <class ParsedNode>
415     PassRefPtr<ParsedNode> parse(ParserError&);
416
417 private:
418     struct AllowInOverride {
419         AllowInOverride(Parser* parser)
420             : m_parser(parser)
421             , m_oldAllowsIn(parser->m_allowsIn)
422         {
423             parser->m_allowsIn = true;
424         }
425         ~AllowInOverride()
426         {
427             m_parser->m_allowsIn = m_oldAllowsIn;
428         }
429         Parser* m_parser;
430         bool m_oldAllowsIn;
431     };
432
433     struct AutoPopScopeRef : public ScopeRef {
434         AutoPopScopeRef(Parser* parser, ScopeRef scope)
435         : ScopeRef(scope)
436         , m_parser(parser)
437         {
438         }
439         
440         ~AutoPopScopeRef()
441         {
442             if (m_parser)
443                 m_parser->popScope(*this, false);
444         }
445         
446         void setPopped()
447         {
448             m_parser = 0;
449         }
450         
451     private:
452         Parser* m_parser;
453     };
454
455     ScopeRef currentScope()
456     {
457         return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
458     }
459     
460     ScopeRef pushScope()
461     {
462         bool isFunction = false;
463         bool isStrict = false;
464         if (!m_scopeStack.isEmpty()) {
465             isStrict = m_scopeStack.last().strictMode();
466             isFunction = m_scopeStack.last().isFunction();
467         }
468         m_scopeStack.append(Scope(m_vm, isFunction, isStrict));
469         return currentScope();
470     }
471     
472     bool popScopeInternal(ScopeRef& scope, bool shouldTrackClosedVariables)
473     {
474         ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1);
475         ASSERT(m_scopeStack.size() > 1);
476         bool result = m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
477         m_scopeStack.removeLast();
478         return result;
479     }
480     
481     bool popScope(ScopeRef& scope, bool shouldTrackClosedVariables)
482     {
483         return popScopeInternal(scope, shouldTrackClosedVariables);
484     }
485     
486     bool popScope(AutoPopScopeRef& scope, bool shouldTrackClosedVariables)
487     {
488         scope.setPopped();
489         return popScopeInternal(scope, shouldTrackClosedVariables);
490     }
491     
492     bool declareVariable(const Identifier* ident)
493     {
494         unsigned i = m_scopeStack.size() - 1;
495         ASSERT(i < m_scopeStack.size());
496         while (!m_scopeStack[i].allowsNewDecls()) {
497             i--;
498             ASSERT(i < m_scopeStack.size());
499         }
500         return m_scopeStack[i].declareVariable(ident);
501     }
502     
503     NEVER_INLINE bool hasDeclaredVariable(const Identifier& ident)
504     {
505         unsigned i = m_scopeStack.size() - 1;
506         ASSERT(i < m_scopeStack.size());
507         while (!m_scopeStack[i].allowsNewDecls()) {
508             i--;
509             ASSERT(i < m_scopeStack.size());
510         }
511         return m_scopeStack[i].hasDeclaredVariable(ident);
512     }
513     
514     NEVER_INLINE bool hasDeclaredParameter(const Identifier& ident)
515     {
516         unsigned i = m_scopeStack.size() - 1;
517         ASSERT(i < m_scopeStack.size());
518         while (!m_scopeStack[i].allowsNewDecls()) {
519             i--;
520             ASSERT(i < m_scopeStack.size());
521         }
522         return m_scopeStack[i].hasDeclaredParameter(ident);
523     }
524     
525     void declareWrite(const Identifier* ident)
526     {
527         if (!m_syntaxAlreadyValidated || strictMode())
528             m_scopeStack.last().declareWrite(ident);
529     }
530     
531     ScopeStack m_scopeStack;
532     
533     const SourceProviderCacheItem* findCachedFunctionInfo(int openBracePos) 
534     {
535         return m_functionCache ? m_functionCache->get(openBracePos) : 0;
536     }
537
538     Parser();
539     String parseInner();
540
541     void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, 
542         ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures, int, IdentifierSet&);
543
544     // Used to determine type of error to report.
545     bool isFunctionBodyNode(ScopeNode*) { return false; }
546     bool isFunctionBodyNode(FunctionBodyNode*) { return true; }
547
548     ALWAYS_INLINE void next(unsigned lexerFlags = 0)
549     {
550         int lastLine = m_token.m_location.line;
551         int lastTokenEnd = m_token.m_location.endOffset;
552         int lastTokenLineStart = m_token.m_location.lineStartOffset;
553         m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
554         m_lexer->setLastLineNumber(lastLine);
555         m_token.m_type = m_lexer->lex(&m_token, lexerFlags, strictMode());
556     }
557
558     ALWAYS_INLINE void nextExpectIdentifier(unsigned lexerFlags = 0)
559     {
560         int lastLine = m_token.m_location.line;
561         int lastTokenEnd = m_token.m_location.endOffset;
562         int lastTokenLineStart = m_token.m_location.lineStartOffset;
563         m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
564         m_lexer->setLastLineNumber(lastLine);
565         m_token.m_type = m_lexer->lexExpectIdentifier(&m_token, lexerFlags, strictMode());
566     }
567
568     ALWAYS_INLINE bool nextTokenIsColon()
569     {
570         return m_lexer->nextTokenIsColon();
571     }
572
573     ALWAYS_INLINE bool consume(JSTokenType expected, unsigned flags = 0)
574     {
575         bool result = m_token.m_type == expected;
576         if (result)
577             next(flags);
578         return result;
579     }
580
581     void printUnexpectedTokenText(WTF::PrintStream&);
582     ALWAYS_INLINE String getToken() {
583         SourceProvider* sourceProvider = m_source->provider();
584         return sourceProvider->getRange(tokenStart(), tokenEndPosition().offset);
585     }
586     
587     ALWAYS_INLINE bool match(JSTokenType expected)
588     {
589         return m_token.m_type == expected;
590     }
591     
592     ALWAYS_INLINE bool isofToken()
593     {
594         return m_token.m_type == IDENT && *m_token.m_data.ident == m_vm->propertyNames->of;
595     }
596     
597     ALWAYS_INLINE unsigned tokenStart()
598     {
599         return m_token.m_location.startOffset;
600     }
601     
602     ALWAYS_INLINE const JSTextPosition& tokenStartPosition()
603     {
604         return m_token.m_startPosition;
605     }
606
607     ALWAYS_INLINE int tokenLine()
608     {
609         return m_token.m_location.line;
610     }
611     
612     ALWAYS_INLINE int tokenColumn()
613     {
614         return tokenStart() - tokenLineStart();
615     }
616
617     ALWAYS_INLINE const JSTextPosition& tokenEndPosition()
618     {
619         return m_token.m_endPosition;
620     }
621     
622     ALWAYS_INLINE unsigned tokenLineStart()
623     {
624         return m_token.m_location.lineStartOffset;
625     }
626     
627     ALWAYS_INLINE const JSTokenLocation& tokenLocation()
628     {
629         return m_token.m_location;
630     }
631
632     void setErrorMessage(String msg)
633     {
634         m_errorMessage = msg;
635     }
636     
637     NEVER_INLINE void logError(bool);
638     template <typename A> NEVER_INLINE void logError(bool, const A&);
639     template <typename A, typename B> NEVER_INLINE void logError(bool, const A&, const B&);
640     template <typename A, typename B, typename C> NEVER_INLINE void logError(bool, const A&, const B&, const C&);
641     template <typename A, typename B, typename C, typename D> NEVER_INLINE void logError(bool, const A&, const B&, const C&, const D&);
642     template <typename A, typename B, typename C, typename D, typename E> NEVER_INLINE void logError(bool, const A&, const B&, const C&, const D&, const E&);
643     template <typename A, typename B, typename C, typename D, typename E, typename F> NEVER_INLINE void logError(bool, const A&, const B&, const C&, const D&, const E&, const F&);
644     template <typename A, typename B, typename C, typename D, typename E, typename F, typename G> NEVER_INLINE void logError(bool, const A&, const B&, const C&, const D&, const E&, const F&, const G&);
645     
646     NEVER_INLINE void updateErrorWithNameAndMessage(const char* beforeMsg, String name, const char* afterMsg)
647     {
648         m_errorMessage = makeString(beforeMsg, " '", name, "' ", afterMsg);
649     }
650     
651     NEVER_INLINE void updateErrorMessage(const char* msg)
652     {
653         ASSERT(msg);
654         m_errorMessage = String(msg);
655         ASSERT(!m_errorMessage.isNull());
656     }
657     
658     void startLoop() { currentScope()->startLoop(); }
659     void endLoop() { currentScope()->endLoop(); }
660     void startSwitch() { currentScope()->startSwitch(); }
661     void endSwitch() { currentScope()->endSwitch(); }
662     void setStrictMode() { currentScope()->setStrictMode(); }
663     bool strictMode() { return currentScope()->strictMode(); }
664     bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
665     bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
666     Scope::BindingResult declareBoundParameter(const Identifier* ident) { return currentScope()->declareBoundParameter(ident); }
667     bool breakIsValid()
668     {
669         ScopeRef current = currentScope();
670         while (!current->breakIsValid()) {
671             if (!current.hasContainingScope())
672                 return false;
673             current = current.containingScope();
674         }
675         return true;
676     }
677     bool continueIsValid()
678     {
679         ScopeRef current = currentScope();
680         while (!current->continueIsValid()) {
681             if (!current.hasContainingScope())
682                 return false;
683             current = current.containingScope();
684         }
685         return true;
686     }
687     void pushLabel(const Identifier* label, bool isLoop) { currentScope()->pushLabel(label, isLoop); }
688     void popLabel() { currentScope()->popLabel(); }
689     ScopeLabelInfo* getLabel(const Identifier* label)
690     {
691         ScopeRef current = currentScope();
692         ScopeLabelInfo* result = 0;
693         while (!(result = current->getLabel(label))) {
694             if (!current.hasContainingScope())
695                 return 0;
696             current = current.containingScope();
697         }
698         return result;
699     }
700     
701     template <SourceElementsMode mode, class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&);
702     template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
703     template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&);
704     template <class TreeBuilder> TreeStatement parseVarDeclaration(TreeBuilder&);
705     template <class TreeBuilder> TreeStatement parseConstDeclaration(TreeBuilder&);
706     template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&);
707     template <class TreeBuilder> TreeStatement parseWhileStatement(TreeBuilder&);
708     template <class TreeBuilder> TreeStatement parseForStatement(TreeBuilder&);
709     template <class TreeBuilder> TreeStatement parseBreakStatement(TreeBuilder&);
710     template <class TreeBuilder> TreeStatement parseContinueStatement(TreeBuilder&);
711     template <class TreeBuilder> TreeStatement parseReturnStatement(TreeBuilder&);
712     template <class TreeBuilder> TreeStatement parseThrowStatement(TreeBuilder&);
713     template <class TreeBuilder> TreeStatement parseWithStatement(TreeBuilder&);
714     template <class TreeBuilder> TreeStatement parseSwitchStatement(TreeBuilder&);
715     template <class TreeBuilder> TreeClauseList parseSwitchClauses(TreeBuilder&);
716     template <class TreeBuilder> TreeClause parseSwitchDefaultClause(TreeBuilder&);
717     template <class TreeBuilder> TreeStatement parseTryStatement(TreeBuilder&);
718     template <class TreeBuilder> TreeStatement parseDebuggerStatement(TreeBuilder&);
719     template <class TreeBuilder> TreeStatement parseExpressionStatement(TreeBuilder&);
720     template <class TreeBuilder> TreeStatement parseExpressionOrLabelStatement(TreeBuilder&);
721     template <class TreeBuilder> TreeStatement parseIfStatement(TreeBuilder&);
722     template <class TreeBuilder> ALWAYS_INLINE TreeStatement parseBlockStatement(TreeBuilder&);
723     template <class TreeBuilder> TreeExpression parseExpression(TreeBuilder&);
724     template <class TreeBuilder> TreeExpression parseAssignmentExpression(TreeBuilder&);
725     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseConditionalExpression(TreeBuilder&);
726     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseBinaryExpression(TreeBuilder&);
727     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseUnaryExpression(TreeBuilder&);
728     template <class TreeBuilder> TreeExpression parseMemberExpression(TreeBuilder&);
729     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parsePrimaryExpression(TreeBuilder&);
730     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArrayLiteral(TreeBuilder&);
731     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseObjectLiteral(TreeBuilder&);
732     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&);
733     enum SpreadMode { AllowSpread, DontAllowSpread };
734     template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&, SpreadMode);
735     template <bool strict, class TreeBuilder> ALWAYS_INLINE TreeProperty parseProperty(TreeBuilder&);
736     template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&);
737     template <class TreeBuilder> ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&);
738     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, TreeDeconstructionPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd);
739     template <class TreeBuilder> ALWAYS_INLINE TreeConstDeclList parseConstDeclarationList(TreeBuilder&);
740
741     template <DeconstructionKind, class TreeBuilder> ALWAYS_INLINE TreeDeconstructionPattern createBindingPattern(TreeBuilder&, const Identifier&, int depth);
742     template <DeconstructionKind, class TreeBuilder> TreeDeconstructionPattern parseDeconstructionPattern(TreeBuilder&, int depth = 0);
743     template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern tryParseDeconstructionPatternExpression(TreeBuilder&);
744     template <FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, class TreeBuilder> bool parseFunctionInfo(TreeBuilder&, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, unsigned& openBraceOffset, unsigned& closeBraceOffset, int& bodyStartLine, unsigned& bodyStartColumn);
745     ALWAYS_INLINE int isBinaryOperator(JSTokenType);
746     bool allowAutomaticSemicolon();
747     
748     bool autoSemiColon()
749     {
750         if (m_token.m_type == SEMICOLON) {
751             next();
752             return true;
753         }
754         return allowAutomaticSemicolon();
755     }
756     
757     bool canRecurse()
758     {
759         return m_stack.isSafeToRecurse();
760     }
761     
762     const JSTextPosition& lastTokenEndPosition() const
763     {
764         return m_lastTokenEndPosition;
765     }
766
767     bool hasError() const
768     {
769         return !m_errorMessage.isNull();
770     }
771
772     struct SavePoint {
773         int startOffset;
774         unsigned oldLineStartOffset;
775         unsigned oldLastLineNumber;
776         unsigned oldLineNumber;
777     };
778     
779     ALWAYS_INLINE SavePoint createSavePoint()
780     {
781         ASSERT(!hasError());
782         SavePoint result;
783         result.startOffset = m_token.m_location.startOffset;
784         result.oldLineStartOffset = m_token.m_location.lineStartOffset;
785         result.oldLastLineNumber = m_lexer->lastLineNumber();
786         result.oldLineNumber = m_lexer->lineNumber();
787         return result;
788     }
789     
790     ALWAYS_INLINE void restoreSavePoint(const SavePoint& savePoint)
791     {
792         m_errorMessage = String();
793         m_lexer->setOffset(savePoint.startOffset, savePoint.oldLineStartOffset);
794         next();
795         m_lexer->setLastLineNumber(savePoint.oldLastLineNumber);
796         m_lexer->setLineNumber(savePoint.oldLineNumber);
797     }
798
799     struct ParserState {
800         int assignmentCount;
801         int nonLHSCount;
802         int nonTrivialExpressionCount;
803     };
804
805     ALWAYS_INLINE ParserState saveState()
806     {
807         ParserState result;
808         result.assignmentCount = m_assignmentCount;
809         result.nonLHSCount = m_nonLHSCount;
810         result.nonTrivialExpressionCount = m_nonTrivialExpressionCount;
811         return result;
812     }
813     
814     ALWAYS_INLINE void restoreState(const ParserState& state)
815     {
816         m_assignmentCount = state.assignmentCount;
817         m_nonLHSCount = state.nonLHSCount;
818         m_nonTrivialExpressionCount = state.nonTrivialExpressionCount;
819         
820     }
821     
822
823     VM* m_vm;
824     const SourceCode* m_source;
825     ParserArena* m_arena;
826     OwnPtr<LexerType> m_lexer;
827     
828     VMStackBounds m_stack;
829     bool m_hasStackOverflow;
830     String m_errorMessage;
831     JSToken m_token;
832     bool m_allowsIn;
833     JSTextPosition m_lastTokenEndPosition;
834     int m_assignmentCount;
835     int m_nonLHSCount;
836     bool m_syntaxAlreadyValidated;
837     int m_statementDepth;
838     int m_nonTrivialExpressionCount;
839     const Identifier* m_lastIdentifier;
840     const Identifier* m_lastFunctionName;
841     RefPtr<SourceProviderCache> m_functionCache;
842     SourceElements* m_sourceElements;
843     ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
844     ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
845     IdentifierSet m_capturedVariables;
846     CodeFeatures m_features;
847     int m_numConstants;
848     
849     struct DepthManager {
850         DepthManager(int* depth)
851         : m_originalDepth(*depth)
852         , m_depth(depth)
853         {
854         }
855         
856         ~DepthManager()
857         {
858             *m_depth = m_originalDepth;
859         }
860         
861     private:
862         int m_originalDepth;
863         int* m_depth;
864     };
865 };
866
867
868 template <typename LexerType>
869 template <class ParsedNode>
870 PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
871 {
872     int errLine;
873     String errMsg;
874
875     if (ParsedNode::scopeIsFunction)
876         m_lexer->setIsReparsing();
877
878     m_sourceElements = 0;
879
880     errLine = -1;
881     errMsg = String();
882
883     JSTokenLocation startLocation(tokenLocation());
884     unsigned startColumn = m_source->startColumn();
885
886     String parseError = parseInner();
887
888     int lineNumber = m_lexer->lineNumber();
889     bool lexError = m_lexer->sawError();
890     String lexErrorMessage = lexError ? m_lexer->getErrorMessage() : String();
891     ASSERT(lexErrorMessage.isNull() != lexError);
892     m_lexer->clear();
893
894     if (!parseError.isNull() || lexError) {
895         errLine = lineNumber;
896         errMsg = !lexErrorMessage.isNull() ? lexErrorMessage : parseError;
897         m_sourceElements = 0;
898     }
899
900     RefPtr<ParsedNode> result;
901     if (m_sourceElements) {
902         JSTokenLocation endLocation;
903         endLocation.line = m_lexer->lastLineNumber();
904         endLocation.lineStartOffset = m_lexer->currentLineStartOffset();
905         endLocation.startOffset = m_lexer->currentOffset();
906         result = ParsedNode::create(m_vm,
907                                     startLocation,
908                                     endLocation,
909                                     startColumn,
910                                     m_sourceElements,
911                                     m_varDeclarations ? &m_varDeclarations->data : 0,
912                                     m_funcDeclarations ? &m_funcDeclarations->data : 0,
913                                     m_capturedVariables,
914                                     *m_source,
915                                     m_features,
916                                     m_numConstants);
917         result->setLoc(m_source->firstLine(), m_lastTokenEndPosition.line, m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
918     } else {
919         // We can never see a syntax error when reparsing a function, since we should have
920         // reported the error when parsing the containing program or eval code. So if we're
921         // parsing a function body node, we assume that what actually happened here is that
922         // we ran out of stack while parsing. If we see an error while parsing eval or program
923         // code we assume that it was a syntax error since running out of stack is much less
924         // likely, and we are currently unable to distinguish between the two cases.
925         if (isFunctionBodyNode(static_cast<ParsedNode*>(0)) || m_hasStackOverflow)
926             error = ParserError(ParserError::StackOverflow, ParserError::SyntaxErrorNone, m_token);
927         else {
928             ParserError::SyntaxErrorType errorType = ParserError::SyntaxErrorIrrecoverable;
929             if (m_token.m_type == EOFTOK)
930                 errorType = ParserError::SyntaxErrorRecoverable;
931             else if (m_token.m_type & UnterminatedErrorTokenFlag)
932                 errorType = ParserError::SyntaxErrorUnterminatedLiteral;
933             
934             if (isEvalNode<ParsedNode>())
935                 error = ParserError(ParserError::EvalError, errorType, m_token, errMsg, errLine);
936             else
937                 error = ParserError(ParserError::SyntaxError, errorType, m_token, errMsg, errLine);
938         }
939     }
940
941     m_arena->reset();
942
943     return result.release();
944 }
945
946 template <class ParsedNode>
947 PassRefPtr<ParsedNode> parse(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, ParserError& error)
948 {
949     SamplingRegion samplingRegion("Parsing");
950
951     ASSERT(!source.provider()->source().isNull());
952     if (source.provider()->source().is8Bit()) {
953         Parser<Lexer<LChar>> parser(vm, source, parameters, name, strictness, parserMode);
954         return parser.parse<ParsedNode>(error);
955     }
956     Parser<Lexer<UChar>> parser(vm, source, parameters, name, strictness, parserMode);
957     return parser.parse<ParsedNode>(error);
958 }
959
960 } // namespace
961 #endif