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