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