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