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