Make it possible to implement JS builtins in JS
[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
413 public:
414     Parser(VM*, const SourceCode&, FunctionParameters*, const Identifier&, JSParserStrictness, JSParserMode);
415     ~Parser();
416
417     template <class ParsedNode>
418     PassRefPtr<ParsedNode> parse(ParserError&);
419
420     JSTextPosition positionBeforeLastNewline() const { return m_lexer->positionBeforeLastNewline(); }
421     const Vector<RefPtr<StringImpl>>&& closedVariables() { return std::move(m_closedVariables); }
422
423 private:
424     struct AllowInOverride {
425         AllowInOverride(Parser* parser)
426             : m_parser(parser)
427             , m_oldAllowsIn(parser->m_allowsIn)
428         {
429             parser->m_allowsIn = true;
430         }
431         ~AllowInOverride()
432         {
433             m_parser->m_allowsIn = m_oldAllowsIn;
434         }
435         Parser* m_parser;
436         bool m_oldAllowsIn;
437     };
438
439     struct AutoPopScopeRef : public ScopeRef {
440         AutoPopScopeRef(Parser* parser, ScopeRef scope)
441         : ScopeRef(scope)
442         , m_parser(parser)
443         {
444         }
445         
446         ~AutoPopScopeRef()
447         {
448             if (m_parser)
449                 m_parser->popScope(*this, false);
450         }
451         
452         void setPopped()
453         {
454             m_parser = 0;
455         }
456         
457     private:
458         Parser* m_parser;
459     };
460
461     ScopeRef currentScope()
462     {
463         return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
464     }
465     
466     ScopeRef pushScope()
467     {
468         bool isFunction = false;
469         bool isStrict = false;
470         if (!m_scopeStack.isEmpty()) {
471             isStrict = m_scopeStack.last().strictMode();
472             isFunction = m_scopeStack.last().isFunction();
473         }
474         m_scopeStack.append(Scope(m_vm, isFunction, isStrict));
475         return currentScope();
476     }
477     
478     bool popScopeInternal(ScopeRef& scope, bool shouldTrackClosedVariables)
479     {
480         ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1);
481         ASSERT(m_scopeStack.size() > 1);
482         bool result = m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
483         m_scopeStack.removeLast();
484         return result;
485     }
486     
487     bool popScope(ScopeRef& scope, bool shouldTrackClosedVariables)
488     {
489         return popScopeInternal(scope, shouldTrackClosedVariables);
490     }
491     
492     bool popScope(AutoPopScopeRef& scope, bool shouldTrackClosedVariables)
493     {
494         scope.setPopped();
495         return popScopeInternal(scope, shouldTrackClosedVariables);
496     }
497     
498     bool declareVariable(const Identifier* ident)
499     {
500         unsigned i = m_scopeStack.size() - 1;
501         ASSERT(i < m_scopeStack.size());
502         while (!m_scopeStack[i].allowsNewDecls()) {
503             i--;
504             ASSERT(i < m_scopeStack.size());
505         }
506         return m_scopeStack[i].declareVariable(ident);
507     }
508     
509     NEVER_INLINE bool hasDeclaredVariable(const Identifier& ident)
510     {
511         unsigned i = m_scopeStack.size() - 1;
512         ASSERT(i < m_scopeStack.size());
513         while (!m_scopeStack[i].allowsNewDecls()) {
514             i--;
515             ASSERT(i < m_scopeStack.size());
516         }
517         return m_scopeStack[i].hasDeclaredVariable(ident);
518     }
519     
520     NEVER_INLINE bool hasDeclaredParameter(const Identifier& ident)
521     {
522         unsigned i = m_scopeStack.size() - 1;
523         ASSERT(i < m_scopeStack.size());
524         while (!m_scopeStack[i].allowsNewDecls()) {
525             i--;
526             ASSERT(i < m_scopeStack.size());
527         }
528         return m_scopeStack[i].hasDeclaredParameter(ident);
529     }
530     
531     void declareWrite(const Identifier* ident)
532     {
533         if (!m_syntaxAlreadyValidated || strictMode())
534             m_scopeStack.last().declareWrite(ident);
535     }
536     
537     ScopeStack m_scopeStack;
538     
539     const SourceProviderCacheItem* findCachedFunctionInfo(int openBracePos) 
540     {
541         return m_functionCache ? m_functionCache->get(openBracePos) : 0;
542     }
543
544     Parser();
545     String parseInner();
546
547     void didFinishParsing(SourceElements*, ParserArenaData<DeclarationStacks::VarStack>*, 
548         ParserArenaData<DeclarationStacks::FunctionStack>*, CodeFeatures, int, IdentifierSet&, const Vector<RefPtr<StringImpl>>&&);
549
550     // Used to determine type of error to report.
551     bool isFunctionBodyNode(ScopeNode*) { return false; }
552     bool isFunctionBodyNode(FunctionBodyNode*) { return true; }
553
554     ALWAYS_INLINE void next(unsigned lexerFlags = 0)
555     {
556         int lastLine = m_token.m_location.line;
557         int lastTokenEnd = m_token.m_location.endOffset;
558         int lastTokenLineStart = m_token.m_location.lineStartOffset;
559         m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
560         m_lexer->setLastLineNumber(lastLine);
561         m_token.m_type = m_lexer->lex(&m_token, lexerFlags, strictMode());
562     }
563
564     ALWAYS_INLINE void nextExpectIdentifier(unsigned lexerFlags = 0)
565     {
566         int lastLine = m_token.m_location.line;
567         int lastTokenEnd = m_token.m_location.endOffset;
568         int lastTokenLineStart = m_token.m_location.lineStartOffset;
569         m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
570         m_lexer->setLastLineNumber(lastLine);
571         m_token.m_type = m_lexer->lexExpectIdentifier(&m_token, lexerFlags, strictMode());
572     }
573
574     ALWAYS_INLINE bool nextTokenIsColon()
575     {
576         return m_lexer->nextTokenIsColon();
577     }
578
579     ALWAYS_INLINE bool consume(JSTokenType expected, unsigned flags = 0)
580     {
581         bool result = m_token.m_type == expected;
582         if (result)
583             next(flags);
584         return result;
585     }
586
587     void printUnexpectedTokenText(WTF::PrintStream&);
588     ALWAYS_INLINE String getToken() {
589         SourceProvider* sourceProvider = m_source->provider();
590         return sourceProvider->getRange(tokenStart(), tokenEndPosition().offset);
591     }
592     
593     ALWAYS_INLINE bool match(JSTokenType expected)
594     {
595         return m_token.m_type == expected;
596     }
597     
598     ALWAYS_INLINE bool isofToken()
599     {
600         return m_token.m_type == IDENT && *m_token.m_data.ident == m_vm->propertyNames->of;
601     }
602     
603     ALWAYS_INLINE unsigned tokenStart()
604     {
605         return m_token.m_location.startOffset;
606     }
607     
608     ALWAYS_INLINE const JSTextPosition& tokenStartPosition()
609     {
610         return m_token.m_startPosition;
611     }
612
613     ALWAYS_INLINE int tokenLine()
614     {
615         return m_token.m_location.line;
616     }
617     
618     ALWAYS_INLINE int tokenColumn()
619     {
620         return tokenStart() - tokenLineStart();
621     }
622
623     ALWAYS_INLINE const JSTextPosition& tokenEndPosition()
624     {
625         return m_token.m_endPosition;
626     }
627     
628     ALWAYS_INLINE unsigned tokenLineStart()
629     {
630         return m_token.m_location.lineStartOffset;
631     }
632     
633     ALWAYS_INLINE const JSTokenLocation& tokenLocation()
634     {
635         return m_token.m_location;
636     }
637
638     void setErrorMessage(String msg)
639     {
640         m_errorMessage = msg;
641     }
642     
643     NEVER_INLINE void logError(bool);
644     template <typename A> NEVER_INLINE void logError(bool, const A&);
645     template <typename A, typename B> NEVER_INLINE void logError(bool, const A&, const B&);
646     template <typename A, typename B, typename C> NEVER_INLINE void logError(bool, const A&, const B&, const C&);
647     template <typename A, typename B, typename C, typename D> NEVER_INLINE void logError(bool, const A&, const B&, const C&, const D&);
648     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&);
649     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&);
650     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&);
651     
652     NEVER_INLINE void updateErrorWithNameAndMessage(const char* beforeMsg, String name, const char* afterMsg)
653     {
654         m_errorMessage = makeString(beforeMsg, " '", name, "' ", afterMsg);
655     }
656     
657     NEVER_INLINE void updateErrorMessage(const char* msg)
658     {
659         ASSERT(msg);
660         m_errorMessage = String(msg);
661         ASSERT(!m_errorMessage.isNull());
662     }
663     
664     void startLoop() { currentScope()->startLoop(); }
665     void endLoop() { currentScope()->endLoop(); }
666     void startSwitch() { currentScope()->startSwitch(); }
667     void endSwitch() { currentScope()->endSwitch(); }
668     void setStrictMode() { currentScope()->setStrictMode(); }
669     bool strictMode() { return currentScope()->strictMode(); }
670     bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
671     bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
672     Scope::BindingResult declareBoundParameter(const Identifier* ident) { return currentScope()->declareBoundParameter(ident); }
673     bool breakIsValid()
674     {
675         ScopeRef current = currentScope();
676         while (!current->breakIsValid()) {
677             if (!current.hasContainingScope())
678                 return false;
679             current = current.containingScope();
680         }
681         return true;
682     }
683     bool continueIsValid()
684     {
685         ScopeRef current = currentScope();
686         while (!current->continueIsValid()) {
687             if (!current.hasContainingScope())
688                 return false;
689             current = current.containingScope();
690         }
691         return true;
692     }
693     void pushLabel(const Identifier* label, bool isLoop) { currentScope()->pushLabel(label, isLoop); }
694     void popLabel() { currentScope()->popLabel(); }
695     ScopeLabelInfo* getLabel(const Identifier* label)
696     {
697         ScopeRef current = currentScope();
698         ScopeLabelInfo* result = 0;
699         while (!(result = current->getLabel(label))) {
700             if (!current.hasContainingScope())
701                 return 0;
702             current = current.containingScope();
703         }
704         return result;
705     }
706     
707     template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode);
708     template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
709     template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&);
710     template <class TreeBuilder> TreeStatement parseVarDeclaration(TreeBuilder&);
711     template <class TreeBuilder> TreeStatement parseConstDeclaration(TreeBuilder&);
712     template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&);
713     template <class TreeBuilder> TreeStatement parseWhileStatement(TreeBuilder&);
714     template <class TreeBuilder> TreeStatement parseForStatement(TreeBuilder&);
715     template <class TreeBuilder> TreeStatement parseBreakStatement(TreeBuilder&);
716     template <class TreeBuilder> TreeStatement parseContinueStatement(TreeBuilder&);
717     template <class TreeBuilder> TreeStatement parseReturnStatement(TreeBuilder&);
718     template <class TreeBuilder> TreeStatement parseThrowStatement(TreeBuilder&);
719     template <class TreeBuilder> TreeStatement parseWithStatement(TreeBuilder&);
720     template <class TreeBuilder> TreeStatement parseSwitchStatement(TreeBuilder&);
721     template <class TreeBuilder> TreeClauseList parseSwitchClauses(TreeBuilder&);
722     template <class TreeBuilder> TreeClause parseSwitchDefaultClause(TreeBuilder&);
723     template <class TreeBuilder> TreeStatement parseTryStatement(TreeBuilder&);
724     template <class TreeBuilder> TreeStatement parseDebuggerStatement(TreeBuilder&);
725     template <class TreeBuilder> TreeStatement parseExpressionStatement(TreeBuilder&);
726     template <class TreeBuilder> TreeStatement parseExpressionOrLabelStatement(TreeBuilder&);
727     template <class TreeBuilder> TreeStatement parseIfStatement(TreeBuilder&);
728     template <class TreeBuilder> TreeStatement parseBlockStatement(TreeBuilder&);
729     template <class TreeBuilder> TreeExpression parseExpression(TreeBuilder&);
730     template <class TreeBuilder> TreeExpression parseAssignmentExpression(TreeBuilder&);
731     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseConditionalExpression(TreeBuilder&);
732     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseBinaryExpression(TreeBuilder&);
733     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseUnaryExpression(TreeBuilder&);
734     template <class TreeBuilder> TreeExpression parseMemberExpression(TreeBuilder&);
735     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parsePrimaryExpression(TreeBuilder&);
736     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArrayLiteral(TreeBuilder&);
737     template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseObjectLiteral(TreeBuilder&);
738     template <class TreeBuilder> NEVER_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&);
739     enum SpreadMode { AllowSpread, DontAllowSpread };
740     template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&, SpreadMode);
741     template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict);
742     template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&);
743     template <class TreeBuilder> ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&);
744     template <class TreeBuilder> TreeExpression parseVarDeclarationList(TreeBuilder&, int& declarations, TreeDeconstructionPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd);
745     template <class TreeBuilder> NEVER_INLINE TreeConstDeclList parseConstDeclarationList(TreeBuilder&);
746
747     template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern createBindingPattern(TreeBuilder&, DeconstructionKind, const Identifier&, int depth);
748     template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern parseDeconstructionPattern(TreeBuilder&, DeconstructionKind, int depth = 0);
749     template <class TreeBuilder> NEVER_INLINE TreeDeconstructionPattern tryParseDeconstructionPatternExpression(TreeBuilder&);
750     template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, const Identifier*&, TreeFormalParameterList&, TreeFunctionBody&, unsigned& openBraceOffset, unsigned& closeBraceOffset, int& bodyStartLine, unsigned& bodyStartColumn);
751     ALWAYS_INLINE int isBinaryOperator(JSTokenType);
752     bool allowAutomaticSemicolon();
753     
754     bool autoSemiColon()
755     {
756         if (m_token.m_type == SEMICOLON) {
757             next();
758             return true;
759         }
760         return allowAutomaticSemicolon();
761     }
762     
763     bool canRecurse()
764     {
765         return m_vm->isSafeToRecurse();
766     }
767     
768     const JSTextPosition& lastTokenEndPosition() const
769     {
770         return m_lastTokenEndPosition;
771     }
772
773     bool hasError() const
774     {
775         return !m_errorMessage.isNull();
776     }
777
778     struct SavePoint {
779         int startOffset;
780         unsigned oldLineStartOffset;
781         unsigned oldLastLineNumber;
782         unsigned oldLineNumber;
783     };
784     
785     ALWAYS_INLINE SavePoint createSavePoint()
786     {
787         ASSERT(!hasError());
788         SavePoint result;
789         result.startOffset = m_token.m_location.startOffset;
790         result.oldLineStartOffset = m_token.m_location.lineStartOffset;
791         result.oldLastLineNumber = m_lexer->lastLineNumber();
792         result.oldLineNumber = m_lexer->lineNumber();
793         return result;
794     }
795     
796     ALWAYS_INLINE void restoreSavePoint(const SavePoint& savePoint)
797     {
798         m_errorMessage = String();
799         m_lexer->setOffset(savePoint.startOffset, savePoint.oldLineStartOffset);
800         next();
801         m_lexer->setLastLineNumber(savePoint.oldLastLineNumber);
802         m_lexer->setLineNumber(savePoint.oldLineNumber);
803     }
804
805     struct ParserState {
806         int assignmentCount;
807         int nonLHSCount;
808         int nonTrivialExpressionCount;
809     };
810
811     ALWAYS_INLINE ParserState saveState()
812     {
813         ParserState result;
814         result.assignmentCount = m_assignmentCount;
815         result.nonLHSCount = m_nonLHSCount;
816         result.nonTrivialExpressionCount = m_nonTrivialExpressionCount;
817         return result;
818     }
819     
820     ALWAYS_INLINE void restoreState(const ParserState& state)
821     {
822         m_assignmentCount = state.assignmentCount;
823         m_nonLHSCount = state.nonLHSCount;
824         m_nonTrivialExpressionCount = state.nonTrivialExpressionCount;
825         
826     }
827     
828
829     VM* m_vm;
830     const SourceCode* m_source;
831     ParserArena* m_arena;
832     OwnPtr<LexerType> m_lexer;
833     
834     bool m_hasStackOverflow;
835     String m_errorMessage;
836     JSToken m_token;
837     bool m_allowsIn;
838     JSTextPosition m_lastTokenEndPosition;
839     int m_assignmentCount;
840     int m_nonLHSCount;
841     bool m_syntaxAlreadyValidated;
842     int m_statementDepth;
843     int m_nonTrivialExpressionCount;
844     const Identifier* m_lastIdentifier;
845     const Identifier* m_lastFunctionName;
846     RefPtr<SourceProviderCache> m_functionCache;
847     SourceElements* m_sourceElements;
848     bool m_parsingBuiltin;
849     ParserArenaData<DeclarationStacks::VarStack>* m_varDeclarations;
850     ParserArenaData<DeclarationStacks::FunctionStack>* m_funcDeclarations;
851     IdentifierSet m_capturedVariables;
852     Vector<RefPtr<StringImpl>> m_closedVariables;
853     CodeFeatures m_features;
854     int m_numConstants;
855     
856     struct DepthManager {
857         DepthManager(int* depth)
858         : m_originalDepth(*depth)
859         , m_depth(depth)
860         {
861         }
862         
863         ~DepthManager()
864         {
865             *m_depth = m_originalDepth;
866         }
867         
868     private:
869         int m_originalDepth;
870         int* m_depth;
871     };
872 };
873
874
875 template <typename LexerType>
876 template <class ParsedNode>
877 PassRefPtr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
878 {
879     int errLine;
880     String errMsg;
881
882     if (ParsedNode::scopeIsFunction)
883         m_lexer->setIsReparsing();
884
885     m_sourceElements = 0;
886
887     errLine = -1;
888     errMsg = String();
889
890     JSTokenLocation startLocation(tokenLocation());
891     ASSERT(m_source->startColumn() > 0);
892     unsigned startColumn = m_source->startColumn() - 1;
893
894     String parseError = parseInner();
895
896     int lineNumber = m_lexer->lineNumber();
897     bool lexError = m_lexer->sawError();
898     String lexErrorMessage = lexError ? m_lexer->getErrorMessage() : String();
899     ASSERT(lexErrorMessage.isNull() != lexError);
900     m_lexer->clear();
901
902     if (!parseError.isNull() || lexError) {
903         errLine = lineNumber;
904         errMsg = !lexErrorMessage.isNull() ? lexErrorMessage : parseError;
905         m_sourceElements = 0;
906     }
907
908     RefPtr<ParsedNode> result;
909     if (m_sourceElements) {
910         JSTokenLocation endLocation;
911         endLocation.line = m_lexer->lineNumber();
912         endLocation.lineStartOffset = m_lexer->currentLineStartOffset();
913         endLocation.startOffset = m_lexer->currentOffset();
914         unsigned endColumn = endLocation.startOffset - endLocation.lineStartOffset;
915         result = ParsedNode::create(m_vm,
916                                     startLocation,
917                                     endLocation,
918                                     startColumn,
919                                     endColumn,
920                                     m_sourceElements,
921                                     m_varDeclarations ? &m_varDeclarations->data : 0,
922                                     m_funcDeclarations ? &m_funcDeclarations->data : 0,
923                                     m_capturedVariables,
924                                     *m_source,
925                                     m_features,
926                                     m_numConstants);
927         result->setLoc(m_source->firstLine(), m_lexer->lineNumber(), m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
928     } else {
929         // We can never see a syntax error when reparsing a function, since we should have
930         // reported the error when parsing the containing program or eval code. So if we're
931         // parsing a function body node, we assume that what actually happened here is that
932         // we ran out of stack while parsing. If we see an error while parsing eval or program
933         // code we assume that it was a syntax error since running out of stack is much less
934         // likely, and we are currently unable to distinguish between the two cases.
935         if (isFunctionBodyNode(static_cast<ParsedNode*>(0)) || m_hasStackOverflow)
936             error = ParserError(ParserError::StackOverflow, ParserError::SyntaxErrorNone, m_token);
937         else {
938             ParserError::SyntaxErrorType errorType = ParserError::SyntaxErrorIrrecoverable;
939             if (m_token.m_type == EOFTOK)
940                 errorType = ParserError::SyntaxErrorRecoverable;
941             else if (m_token.m_type & UnterminatedErrorTokenFlag)
942                 errorType = ParserError::SyntaxErrorUnterminatedLiteral;
943             
944             if (isEvalNode<ParsedNode>())
945                 error = ParserError(ParserError::EvalError, errorType, m_token, errMsg, errLine);
946             else
947                 error = ParserError(ParserError::SyntaxError, errorType, m_token, errMsg, errLine);
948         }
949     }
950
951     m_arena->reset();
952
953     return result.release();
954 }
955
956 template <class ParsedNode>
957 PassRefPtr<ParsedNode> parse(VM* vm, const SourceCode& source, FunctionParameters* parameters, const Identifier& name, JSParserStrictness strictness, JSParserMode parserMode, ParserError& error, JSTextPosition* positionBeforeLastNewline = 0)
958 {
959     SamplingRegion samplingRegion("Parsing");
960
961     ASSERT(!source.provider()->source().isNull());
962     if (source.provider()->source().is8Bit()) {
963         Parser<Lexer<LChar>> parser(vm, source, parameters, name, strictness, parserMode);
964         RefPtr<ParsedNode> result = parser.parse<ParsedNode>(error);
965         if (positionBeforeLastNewline)
966             *positionBeforeLastNewline = parser.positionBeforeLastNewline();
967         if (strictness == JSParseBuiltin) {
968             if (!result)
969                 WTF::dataLog("Error compiling builtin: ", error.m_message, "\n");
970             RELEASE_ASSERT(result);
971             result->setClosedVariables(std::move(parser.closedVariables()));
972         }
973         return result.release();
974     }
975     Parser<Lexer<UChar>> parser(vm, source, parameters, name, strictness, parserMode);
976     RefPtr<ParsedNode> result = parser.parse<ParsedNode>(error);
977     if (positionBeforeLastNewline)
978         *positionBeforeLastNewline = parser.positionBeforeLastNewline();
979     return result.release();
980 }
981
982 } // namespace
983 #endif