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