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