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