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