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