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