Source/JavaScriptCore:
[WebKit-https.git] / Source / JavaScriptCore / parser / Parser.h
1 /*
2  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4  *  Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Library General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Library General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Library General Public License
17  *  along with this library; see the file COPYING.LIB.  If not, write to
18  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #ifndef Parser_h
24 #define Parser_h
25
26 #include "Debugger.h"
27 #include "ExceptionHelpers.h"
28 #include "Executable.h"
29 #include "JSGlobalObject.h"
30 #include "Lexer.h"
31 #include "Nodes.h"
32 #include "ParserArena.h"
33 #include "ParserError.h"
34 #include "ParserTokens.h"
35 #include "SourceProvider.h"
36 #include "SourceProviderCache.h"
37 #include "SourceProviderCacheItem.h"
38 #include <wtf/Forward.h>
39 #include <wtf/Noncopyable.h>
40 #include <wtf/OwnPtr.h>
41 #include <wtf/RefPtr.h>
42 namespace JSC {
43 struct Scope;
44 }
45
46 namespace WTF {
47 template <> struct VectorTraits<JSC::Scope> : SimpleClassVectorTraits {
48     static const bool canInitializeWithMemset = false; // Not all Scope data members initialize to 0.
49 };
50 }
51
52 namespace JSC {
53
54 class ExecState;
55 class FunctionBodyNode;
56 class FunctionParameters;
57 class Identifier;
58 class VM;
59 class ProgramNode;
60 class SourceCode;
61
62 // Macros to make the more common TreeBuilder types a little less verbose
63 #define TreeStatement typename TreeBuilder::Statement
64 #define TreeExpression typename TreeBuilder::Expression
65 #define TreeFormalParameterList typename TreeBuilder::FormalParameterList
66 #define TreeSourceElements typename TreeBuilder::SourceElements
67 #define TreeClause typename TreeBuilder::Clause
68 #define TreeClauseList typename TreeBuilder::ClauseList
69 #define TreeConstDeclList typename TreeBuilder::ConstDeclList
70 #define TreeArguments typename TreeBuilder::Arguments
71 #define TreeArgumentsList typename TreeBuilder::ArgumentsList
72 #define TreeFunctionBody typename TreeBuilder::FunctionBody
73 #define TreeProperty typename TreeBuilder::Property
74 #define TreePropertyList typename TreeBuilder::PropertyList
75 #define TreeDeconstructionPattern typename TreeBuilder::DeconstructionPattern
76
77 COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
78
79 enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
80 enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName };
81 enum FunctionParseMode { FunctionMode, GetterMode, SetterMode };
82 enum DeconstructionKind {
83     DeconstructToVariables,
84     DeconstructToParameters,
85     DeconstructToExpressions
86 };
87
88 template <typename T> inline bool isEvalNode() { return false; }
89 template <> inline bool isEvalNode<EvalNode>() { return true; }
90
91 struct ScopeLabelInfo {
92     ScopeLabelInfo(StringImpl* ident, bool isLoop)
93         : m_ident(ident)
94         , m_isLoop(isLoop)
95     {
96     }
97
98     StringImpl* m_ident;
99     bool m_isLoop;
100 };
101
102 struct Scope {
103     Scope(const VM* vm, bool isFunction, bool strictMode)
104         : m_vm(vm)
105         , m_shadowsArguments(false)
106         , m_usesEval(false)
107         , m_needsFullActivation(false)
108         , m_allowsNewDecls(true)
109         , m_strictMode(strictMode)
110         , m_isFunction(isFunction)
111         , m_isFunctionBoundary(false)
112         , m_isValidStrictMode(true)
113         , m_loopDepth(0)
114         , m_switchDepth(0)
115     {
116     }
117
118     Scope(const Scope& rhs)
119         : m_vm(rhs.m_vm)
120         , m_shadowsArguments(rhs.m_shadowsArguments)
121         , m_usesEval(rhs.m_usesEval)
122         , m_needsFullActivation(rhs.m_needsFullActivation)
123         , m_allowsNewDecls(rhs.m_allowsNewDecls)
124         , m_strictMode(rhs.m_strictMode)
125         , m_isFunction(rhs.m_isFunction)
126         , m_isFunctionBoundary(rhs.m_isFunctionBoundary)
127         , m_isValidStrictMode(rhs.m_isValidStrictMode)
128         , m_loopDepth(rhs.m_loopDepth)
129         , m_switchDepth(rhs.m_switchDepth)
130     {
131         if (rhs.m_labels) {
132             m_labels = adoptPtr(new LabelStack);
133
134             typedef LabelStack::const_iterator iterator;
135             iterator end = rhs.m_labels->end();
136             for (iterator it = rhs.m_labels->begin(); it != end; ++it)
137                 m_labels->append(ScopeLabelInfo(it->m_ident, it->m_isLoop));
138         }
139     }
140
141     void startSwitch() { m_switchDepth++; }
142     void endSwitch() { m_switchDepth--; }
143     void startLoop() { m_loopDepth++; }
144     void endLoop() { ASSERT(m_loopDepth); m_loopDepth--; }
145     bool inLoop() { return !!m_loopDepth; }
146     bool breakIsValid() { return m_loopDepth || m_switchDepth; }
147     bool continueIsValid() { return m_loopDepth; }
148
149     void pushLabel(const Identifier* label, bool isLoop)
150     {
151         if (!m_labels)
152             m_labels = adoptPtr(new LabelStack);
153         m_labels->append(ScopeLabelInfo(label->impl(), isLoop));
154     }
155
156     void popLabel()
157     {
158         ASSERT(m_labels);
159         ASSERT(m_labels->size());
160         m_labels->removeLast();
161     }
162
163     ScopeLabelInfo* getLabel(const Identifier* label)
164     {
165         if (!m_labels)
166             return 0;
167         for (int i = m_labels->size(); i > 0; i--) {
168             if (m_labels->at(i - 1).m_ident == label->impl())
169                 return &m_labels->at(i - 1);
170         }
171         return 0;
172     }
173
174     void setIsFunction()
175     {
176         m_isFunction = true;
177         m_isFunctionBoundary = true;
178     }
179     bool isFunction() { return m_isFunction; }
180     bool isFunctionBoundary() { return m_isFunctionBoundary; }
181
182     void declareCallee(const Identifier* ident)
183     {
184         m_declaredVariables.add(ident->string().impl());
185     }
186
187     bool declareVariable(const Identifier* ident)
188     {
189         bool isValidStrictMode = m_vm->propertyNames->eval != *ident && m_vm->propertyNames->arguments != *ident;
190         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
191         m_declaredVariables.add(ident->string().impl());
192         return isValidStrictMode;
193     }
194
195     bool hasDeclaredVariable(const Identifier& ident)
196     {
197         return m_declaredVariables.contains(ident.impl());
198     }
199     
200     bool hasDeclaredParameter(const Identifier& ident)
201     {
202         return m_declaredParameters.contains(ident.impl()) || m_declaredVariables.contains(ident.impl());
203     }
204     
205     void declareWrite(const Identifier* ident)
206     {
207         ASSERT(m_strictMode);
208         m_writtenVariables.add(ident->impl());
209     }
210
211     void preventNewDecls() { m_allowsNewDecls = false; }
212     bool allowsNewDecls() const { return m_allowsNewDecls; }
213
214     bool declareParameter(const Identifier* ident)
215     {
216         bool isArguments = m_vm->propertyNames->arguments == *ident;
217         bool isValidStrictMode = m_declaredVariables.add(ident->string().impl()).isNewEntry && m_vm->propertyNames->eval != *ident && !isArguments;
218         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
219         m_declaredParameters.add(ident->string().impl());
220
221         if (isArguments)
222             m_shadowsArguments = true;
223         return isValidStrictMode;
224     }
225     
226     enum BindingResult {
227         BindingFailed,
228         StrictBindingFailed,
229         BindingSucceeded
230     };
231     BindingResult declareBoundParameter(const Identifier* ident)
232     {
233         bool isArguments = m_vm->propertyNames->arguments == *ident;
234         bool newEntry = m_declaredVariables.add(ident->string().impl()).isNewEntry;
235         bool isValidStrictMode = newEntry && m_vm->propertyNames->eval != *ident && !isArguments;
236         m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
237     
238         if (isArguments)
239             m_shadowsArguments = true;
240         if (!newEntry)
241             return BindingFailed;
242         return isValidStrictMode ? BindingSucceeded : StrictBindingFailed;
243     }
244
245     void getUsedVariables(IdentifierSet& usedVariables)
246     {
247         usedVariables.swap(m_usedVariables);
248     }
249
250     void useVariable(const Identifier* ident, bool isEval)
251     {
252         m_usesEval |= isEval;
253         m_usedVariables.add(ident->string().impl());
254     }
255
256     void setNeedsFullActivation() { m_needsFullActivation = true; }
257
258     bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
259     {
260         if (nestedScope->m_usesEval)
261             m_usesEval = true;
262         IdentifierSet::iterator end = nestedScope->m_usedVariables.end();
263         for (IdentifierSet::iterator ptr = nestedScope->m_usedVariables.begin(); ptr != end; ++ptr) {
264             if (nestedScope->m_declaredVariables.contains(*ptr))
265                 continue;
266             m_usedVariables.add(*ptr);
267             if (shouldTrackClosedVariables)
268                 m_closedVariables.add(*ptr);
269         }
270         if (nestedScope->m_writtenVariables.size()) {
271             IdentifierSet::iterator end = nestedScope->m_writtenVariables.end();
272             for (IdentifierSet::iterator ptr = nestedScope->m_writtenVariables.begin(); ptr != end; ++ptr) {
273                 if (nestedScope->m_declaredVariables.contains(*ptr))
274                     continue;
275                 m_writtenVariables.add(*ptr);
276             }
277         }
278
279         return true;
280     }
281
282     void getCapturedVariables(IdentifierSet& capturedVariables, bool& modifiedParameter, 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     OwnPtr<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     template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, unsigned& openBraceOffset, unsigned& closeBraceOffset, int& bodyStartLine, unsigned& bodyStartColumn);
738     ALWAYS_INLINE int isBinaryOperator(JSTokenType);
739     bool allowAutomaticSemicolon();
740     
741     bool autoSemiColon()
742     {
743         if (m_token.m_type == SEMICOLON) {
744             next();
745             return true;
746         }
747         return allowAutomaticSemicolon();
748     }
749     
750     bool canRecurse()
751     {
752         return m_vm->isSafeToRecurse();
753     }
754     
755     const JSTextPosition& lastTokenEndPosition() const
756     {
757         return m_lastTokenEndPosition;
758     }
759
760     bool hasError() const
761     {
762         return !m_errorMessage.isNull();
763     }
764
765     struct SavePoint {
766         int startOffset;
767         unsigned oldLineStartOffset;
768         unsigned oldLastLineNumber;
769         unsigned oldLineNumber;
770     };
771     
772     ALWAYS_INLINE SavePoint createSavePoint()
773     {
774         ASSERT(!hasError());
775         SavePoint result;
776         result.startOffset = m_token.m_location.startOffset;
777         result.oldLineStartOffset = m_token.m_location.lineStartOffset;
778         result.oldLastLineNumber = m_lexer->lastLineNumber();
779         result.oldLineNumber = m_lexer->lineNumber();
780         return result;
781     }
782     
783     ALWAYS_INLINE void restoreSavePoint(const SavePoint& savePoint)
784     {
785         m_errorMessage = String();
786         m_lexer->setOffset(savePoint.startOffset, savePoint.oldLineStartOffset);
787         next();
788         m_lexer->setLastLineNumber(savePoint.oldLastLineNumber);
789         m_lexer->setLineNumber(savePoint.oldLineNumber);
790     }
791
792     struct ParserState {
793         int assignmentCount;
794         int nonLHSCount;
795         int nonTrivialExpressionCount;
796     };
797
798     ALWAYS_INLINE ParserState saveState()
799     {
800         ParserState result;
801         result.assignmentCount = m_assignmentCount;
802         result.nonLHSCount = m_nonLHSCount;
803         result.nonTrivialExpressionCount = m_nonTrivialExpressionCount;
804         return result;
805     }
806     
807     ALWAYS_INLINE void restoreState(const ParserState& state)
808     {
809         m_assignmentCount = state.assignmentCount;
810         m_nonLHSCount = state.nonLHSCount;
811         m_nonTrivialExpressionCount = state.nonTrivialExpressionCount;
812         
813     }
814     
815
816     VM* m_vm;
817     const SourceCode* m_source;
818     ParserArena m_parserArena;
819     OwnPtr<LexerType> m_lexer;
820     
821     bool m_hasStackOverflow;
822     String m_errorMessage;
823     JSToken m_token;
824     bool m_allowsIn;
825     JSTextPosition m_lastTokenEndPosition;
826     int m_assignmentCount;
827     int m_nonLHSCount;
828     bool m_syntaxAlreadyValidated;
829     int m_statementDepth;
830     int m_nonTrivialExpressionCount;
831     const Identifier* m_lastIdentifier;
832     const Identifier* m_lastFunctionName;
833     RefPtr<SourceProviderCache> m_functionCache;
834     SourceElements* m_sourceElements;
835     bool m_parsingBuiltin;
836     DeclarationStacks::VarStack m_varDeclarations;
837     DeclarationStacks::FunctionStack m_funcDeclarations;
838     IdentifierSet m_capturedVariables;
839     Vector<RefPtr<StringImpl>> m_closedVariables;
840     CodeFeatures m_features;
841     int m_numConstants;
842     
843     struct DepthManager {
844         DepthManager(int* depth)
845         : m_originalDepth(*depth)
846         , m_depth(depth)
847         {
848         }
849         
850         ~DepthManager()
851         {
852             *m_depth = m_originalDepth;
853         }
854         
855     private:
856         int m_originalDepth;
857         int* m_depth;
858     };
859 };
860
861
862 template <typename LexerType>
863 template <class ParsedNode>
864 std::unique_ptr<ParsedNode> Parser<LexerType>::parse(ParserError& error, bool needReparsingAdjustment)
865 {
866     int errLine;
867     String errMsg;
868
869     if (ParsedNode::scopeIsFunction && needReparsingAdjustment)
870         m_lexer->setIsReparsing();
871
872     m_sourceElements = 0;
873
874     errLine = -1;
875     errMsg = String();
876
877     JSTokenLocation startLocation(tokenLocation());
878     ASSERT(m_source->startColumn() > 0);
879     unsigned startColumn = m_source->startColumn() - 1;
880
881     String parseError = parseInner();
882
883     int lineNumber = m_lexer->lineNumber();
884     bool lexError = m_lexer->sawError();
885     String lexErrorMessage = lexError ? m_lexer->getErrorMessage() : String();
886     ASSERT(lexErrorMessage.isNull() != lexError);
887     m_lexer->clear();
888
889     if (!parseError.isNull() || lexError) {
890         errLine = lineNumber;
891         errMsg = !lexErrorMessage.isNull() ? lexErrorMessage : parseError;
892         m_sourceElements = 0;
893     }
894
895     std::unique_ptr<ParsedNode> result;
896     if (m_sourceElements) {
897         JSTokenLocation endLocation;
898         endLocation.line = m_lexer->lineNumber();
899         endLocation.lineStartOffset = m_lexer->currentLineStartOffset();
900         endLocation.startOffset = m_lexer->currentOffset();
901         unsigned endColumn = endLocation.startOffset - endLocation.lineStartOffset;
902         result = std::make_unique<ParsedNode>(m_parserArena,
903                                     startLocation,
904                                     endLocation,
905                                     startColumn,
906                                     endColumn,
907                                     m_sourceElements,
908                                     m_varDeclarations,
909                                     m_funcDeclarations,
910                                     m_capturedVariables,
911                                     *m_source,
912                                     m_features,
913                                     m_numConstants);
914         result->setLoc(m_source->firstLine(), m_lexer->lineNumber(), m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
915         result->setEndOffset(m_lexer->currentOffset());
916     } else {
917         // We can never see a syntax error when reparsing a function, since we should have
918         // reported the error when parsing the containing program or eval code. So if we're
919         // parsing a function body node, we assume that what actually happened here is that
920         // we ran out of stack while parsing. If we see an error while parsing eval or program
921         // code we assume that it was a syntax error since running out of stack is much less
922         // likely, and we are currently unable to distinguish between the two cases.
923         if (isFunctionBodyNode(static_cast<ParsedNode*>(0)) || m_hasStackOverflow)
924             error = ParserError(ParserError::StackOverflow, ParserError::SyntaxErrorNone, m_token);
925         else {
926             ParserError::SyntaxErrorType errorType = ParserError::SyntaxErrorIrrecoverable;
927             if (m_token.m_type == EOFTOK)
928                 errorType = ParserError::SyntaxErrorRecoverable;
929             else if (m_token.m_type & UnterminatedErrorTokenFlag)
930                 errorType = ParserError::SyntaxErrorUnterminatedLiteral;
931             
932             if (isEvalNode<ParsedNode>())
933                 error = ParserError(ParserError::EvalError, errorType, m_token, errMsg, errLine);
934             else
935                 error = ParserError(ParserError::SyntaxError, errorType, m_token, errMsg, errLine);
936         }
937     }
938
939     return result;
940 }
941
942 template <class ParsedNode>
943 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)
944 {
945     SamplingRegion samplingRegion("Parsing");
946
947     ASSERT(!source.provider()->source().isNull());
948     if (source.provider()->source().is8Bit()) {
949         Parser<Lexer<LChar>> parser(vm, source, parameters, name, strictness, parserMode);
950         std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, needReparsingAdjustment);
951         if (positionBeforeLastNewline)
952             *positionBeforeLastNewline = parser.positionBeforeLastNewline();
953         if (strictness == JSParseBuiltin) {
954             if (!result)
955                 WTF::dataLog("Error compiling builtin: ", error.m_message, "\n");
956             RELEASE_ASSERT(result);
957             result->setClosedVariables(parser.closedVariables());
958         }
959         return result;
960     }
961     Parser<Lexer<UChar>> parser(vm, source, parameters, name, strictness, parserMode);
962     std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, needReparsingAdjustment);
963     if (positionBeforeLastNewline)
964         *positionBeforeLastNewline = parser.positionBeforeLastNewline();
965     return result;
966 }
967
968 } // namespace
969 #endif