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.
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.
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.
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.
27 #include "ExceptionHelpers.h"
28 #include "Executable.h"
29 #include "JSGlobalObject.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>
47 template <> struct VectorTraits<JSC::Scope> : SimpleClassVectorTraits {
48 static const bool canInitializeWithMemset = false; // Not all Scope data members initialize to 0.
55 class FunctionBodyNode;
56 class FunctionParameters;
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
76 #define TreeProperty typename TreeBuilder::Property
77 #define TreePropertyList typename TreeBuilder::PropertyList
78 #define TreeDestructuringPattern typename TreeBuilder::DestructuringPattern
80 COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
82 enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
83 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
84 enum FunctionParseType { StandardFunctionParseType, ArrowFunctionParseType };
86 enum FunctionParseType { StandardFunctionParseType};
88 enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName };
89 enum FunctionParseMode {
94 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
98 enum DestructuringKind {
99 DestructureToVariables,
100 DestructureToParameters,
101 DestructureToExpressions
104 template <typename T> inline bool isEvalNode() { return false; }
105 template <> inline bool isEvalNode<EvalNode>() { return true; }
107 struct ScopeLabelInfo {
108 UniquedStringImpl* uid;
113 Scope(const VM* vm, bool isFunction, bool strictMode)
115 , m_shadowsArguments(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)
130 Scope(const Scope& rhs)
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)
146 m_labels = std::make_unique<LabelStack>();
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 });
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; }
163 void pushLabel(const Identifier* label, bool isLoop)
166 m_labels = std::make_unique<LabelStack>();
167 m_labels->append(ScopeLabelInfo { label->impl(), isLoop });
173 ASSERT(m_labels->size());
174 m_labels->removeLast();
177 ScopeLabelInfo* getLabel(const Identifier* label)
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);
191 m_isFunctionBoundary = true;
193 bool isFunction() { return m_isFunction; }
194 bool isFunctionBoundary() { return m_isFunctionBoundary; }
196 void declareCallee(const Identifier* ident)
198 m_declaredVariables.add(ident->impl());
201 bool declareVariable(const Identifier* ident)
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;
209 bool hasDeclaredVariable(const Identifier& ident)
211 return m_declaredVariables.contains(ident.impl());
214 bool hasDeclaredParameter(const Identifier& ident)
216 return m_declaredParameters.contains(ident.impl()) || m_declaredVariables.contains(ident.impl());
219 void declareWrite(const Identifier* ident)
221 ASSERT(m_strictMode);
222 m_writtenVariables.add(ident->impl());
225 void preventNewDecls() { m_allowsNewDecls = false; }
226 bool allowsNewDecls() const { return m_allowsNewDecls; }
228 bool declareParameter(const Identifier* ident)
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());
236 m_shadowsArguments = true;
237 return isValidStrictMode;
245 BindingResult declareBoundParameter(const Identifier* ident)
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;
253 m_shadowsArguments = true;
255 return BindingFailed;
256 return isValidStrictMode ? BindingSucceeded : StrictBindingFailed;
259 void getUsedVariables(IdentifierSet& usedVariables)
261 usedVariables.swap(m_usedVariables);
264 void useVariable(const Identifier* ident, bool isEval)
266 m_usesEval |= isEval;
267 m_usedVariables.add(ident->impl());
270 void setNeedsFullActivation() { m_needsFullActivation = true; }
272 #if ENABLE(ES6_CLASS_SYNTAX)
273 bool hasDirectSuper() { return m_hasDirectSuper; }
275 bool hasDirectSuper() { return false; }
277 void setHasDirectSuper() { m_hasDirectSuper = true; }
279 #if ENABLE(ES6_CLASS_SYNTAX)
280 bool needsSuperBinding() { return m_needsSuperBinding; }
282 bool needsSuperBinding() { return false; }
284 void setNeedsSuperBinding() { m_needsSuperBinding = true; }
286 bool collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
288 if (nestedScope->m_usesEval)
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))
294 m_usedVariables.add(*ptr);
295 if (shouldTrackClosedVariables)
296 m_closedVariables.add(*ptr);
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))
303 m_writtenVariables.add(*ptr);
310 void getCapturedVariables(IdentifierSet& capturedVariables, bool& modifiedParameter, bool& modifiedArguments)
312 if (m_needsFullActivation || m_usesEval) {
313 modifiedParameter = true;
314 capturedVariables = m_declaredVariables;
317 for (IdentifierSet::iterator ptr = m_closedVariables.begin(); ptr != m_closedVariables.end(); ++ptr) {
318 if (!m_declaredVariables.contains(*ptr))
320 capturedVariables.add(*ptr);
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))
332 modifiedParameter = true;
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; }
342 void copyCapturedVariablesToVector(const IdentifierSet& capturedVariables, Vector<RefPtr<UniquedStringImpl>>& vector)
344 IdentifierSet::iterator end = capturedVariables.end();
345 for (IdentifierSet::iterator it = capturedVariables.begin(); it != end; ++it) {
346 if (m_declaredVariables.contains(*it))
352 void fillParametersForSourceProviderCache(SourceProviderCacheItemCreationParameters& parameters)
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);
362 void restoreFromSourceProviderCache(const SourceProviderCacheItem* info)
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]);
376 bool m_shadowsArguments : 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;
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;
398 typedef Vector<Scope, 10> ScopeStack;
401 ScopeRef(ScopeStack* scopeStack, unsigned index)
402 : m_scopeStack(scopeStack)
406 Scope* operator->() { return &m_scopeStack->at(m_index); }
407 unsigned index() const { return m_index; }
409 bool hasContainingScope()
411 return m_index && !m_scopeStack->at(m_index).isFunctionBoundary();
414 ScopeRef containingScope()
416 ASSERT(hasContainingScope());
417 return ScopeRef(m_scopeStack, m_index - 1);
421 ScopeStack* m_scopeStack;
425 template <typename LexerType>
427 WTF_MAKE_NONCOPYABLE(Parser);
428 WTF_MAKE_FAST_ALLOCATED;
432 VM*, const SourceCode&, FunctionParameters*, const Identifier&,
433 JSParserBuiltinMode, JSParserStrictMode, JSParserCodeType,
434 ConstructorKind defaultConstructorKind = ConstructorKind::None, ThisTDZMode = ThisTDZMode::CheckIfNeeded);
437 template <class ParsedNode>
438 std::unique_ptr<ParsedNode> parse(ParserError&);
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); }
445 struct AllowInOverride {
446 AllowInOverride(Parser* parser)
448 , m_oldAllowsIn(parser->m_allowsIn)
450 parser->m_allowsIn = true;
454 m_parser->m_allowsIn = m_oldAllowsIn;
460 struct AutoPopScopeRef : public ScopeRef {
461 AutoPopScopeRef(Parser* parser, ScopeRef scope)
470 m_parser->popScope(*this, false);
482 ScopeRef currentScope()
484 return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
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();
495 m_scopeStack.append(Scope(m_vm, isFunction, isStrict));
496 return currentScope();
499 bool popScopeInternal(ScopeRef& scope, bool shouldTrackClosedVariables)
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();
508 bool popScope(ScopeRef& scope, bool shouldTrackClosedVariables)
510 return popScopeInternal(scope, shouldTrackClosedVariables);
513 bool popScope(AutoPopScopeRef& scope, bool shouldTrackClosedVariables)
516 return popScopeInternal(scope, shouldTrackClosedVariables);
519 bool declareVariable(const Identifier* ident)
521 unsigned i = m_scopeStack.size() - 1;
522 ASSERT(i < m_scopeStack.size());
523 while (!m_scopeStack[i].allowsNewDecls()) {
525 ASSERT(i < m_scopeStack.size());
527 return m_scopeStack[i].declareVariable(ident);
530 NEVER_INLINE bool hasDeclaredVariable(const Identifier& ident)
532 unsigned i = m_scopeStack.size() - 1;
533 ASSERT(i < m_scopeStack.size());
534 while (!m_scopeStack[i].allowsNewDecls()) {
536 ASSERT(i < m_scopeStack.size());
538 return m_scopeStack[i].hasDeclaredVariable(ident);
541 NEVER_INLINE bool hasDeclaredParameter(const Identifier& ident)
543 unsigned i = m_scopeStack.size() - 1;
544 ASSERT(i < m_scopeStack.size());
545 while (!m_scopeStack[i].allowsNewDecls()) {
547 ASSERT(i < m_scopeStack.size());
549 return m_scopeStack[i].hasDeclaredParameter(ident);
552 void declareWrite(const Identifier* ident)
554 if (!m_syntaxAlreadyValidated || strictMode())
555 m_scopeStack.last().declareWrite(ident);
558 ScopeStack m_scopeStack;
560 const SourceProviderCacheItem* findCachedFunctionInfo(int openBracePos)
562 return m_functionCache ? m_functionCache->get(openBracePos) : 0;
568 void didFinishParsing(SourceElements*, DeclarationStacks::VarStack&,
569 DeclarationStacks::FunctionStack&, CodeFeatures, int, IdentifierSet&, const Vector<RefPtr<UniquedStringImpl>>&&);
571 // Used to determine type of error to report.
572 bool isFunctionBodyNode(ScopeNode*) { return false; }
573 bool isFunctionBodyNode(FunctionBodyNode*) { return true; }
575 ALWAYS_INLINE void next(unsigned lexerFlags = 0)
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());
585 ALWAYS_INLINE void nextExpectIdentifier(unsigned lexerFlags = 0)
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());
595 ALWAYS_INLINE bool nextTokenIsColon()
597 return m_lexer->nextTokenIsColon();
600 ALWAYS_INLINE bool consume(JSTokenType expected, unsigned flags = 0)
602 bool result = m_token.m_type == expected;
608 void printUnexpectedTokenText(WTF::PrintStream&);
609 ALWAYS_INLINE String getToken() {
610 SourceProvider* sourceProvider = m_source->provider();
611 return sourceProvider->getRange(tokenStart(), tokenEndPosition().offset);
614 ALWAYS_INLINE bool match(JSTokenType expected)
616 return m_token.m_type == expected;
619 ALWAYS_INLINE bool isofToken()
621 return m_token.m_type == IDENT && *m_token.m_data.ident == m_vm->propertyNames->of;
624 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
625 ALWAYS_INLINE bool isEndOfArrowFunction()
627 return match(SEMICOLON) || match(COMMA) || match(CLOSEPAREN) || match(CLOSEBRACE) || match(CLOSEBRACKET) || match(EOFTOK) || m_lexer->prevTerminator();
630 ALWAYS_INLINE bool isArrowFunctionParamters()
632 bool isArrowFunction = false;
635 return isArrowFunction;
637 SavePoint saveArrowFunctionPoint = createSavePoint();
639 if (consume(OPENPAREN)) {
640 bool isArrowFunctionParamters = true;
642 while (consume(IDENT)) {
643 if (consume(COMMA)) {
645 isArrowFunctionParamters = false;
652 if (isArrowFunctionParamters) {
653 if (consume(CLOSEPAREN) && match(ARROWFUNCTION))
654 isArrowFunction = true;
656 } else if (consume(IDENT) && match(ARROWFUNCTION))
657 isArrowFunction = true;
659 restoreSavePoint(saveArrowFunctionPoint);
661 return isArrowFunction;
665 ALWAYS_INLINE unsigned tokenStart()
667 return m_token.m_location.startOffset;
670 ALWAYS_INLINE const JSTextPosition& tokenStartPosition()
672 return m_token.m_startPosition;
675 ALWAYS_INLINE int tokenLine()
677 return m_token.m_location.line;
680 ALWAYS_INLINE int tokenColumn()
682 return tokenStart() - tokenLineStart();
685 ALWAYS_INLINE const JSTextPosition& tokenEndPosition()
687 return m_token.m_endPosition;
690 ALWAYS_INLINE unsigned tokenLineStart()
692 return m_token.m_location.lineStartOffset;
695 ALWAYS_INLINE const JSTokenLocation& tokenLocation()
697 return m_token.m_location;
700 void setErrorMessage(const String& message)
702 m_errorMessage = message;
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&);
714 NEVER_INLINE void updateErrorWithNameAndMessage(const char* beforeMessage, const String& name, const char* afterMessage)
716 m_errorMessage = makeString(beforeMessage, " '", name, "' ", afterMessage);
719 NEVER_INLINE void updateErrorMessage(const char* msg)
722 m_errorMessage = String(msg);
723 ASSERT(!m_errorMessage.isNull());
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); }
737 ScopeRef current = currentScope();
738 while (!current->breakIsValid()) {
739 if (!current.hasContainingScope())
741 current = current.containingScope();
745 bool continueIsValid()
747 ScopeRef current = currentScope();
748 while (!current->continueIsValid()) {
749 if (!current.hasContainingScope())
751 current = current.containingScope();
755 void pushLabel(const Identifier* label, bool isLoop) { currentScope()->pushLabel(label, isLoop); }
756 void popLabel() { currentScope()->popLabel(); }
757 ScopeLabelInfo* getLabel(const Identifier* label)
759 ScopeRef current = currentScope();
760 ScopeLabelInfo* result = 0;
761 while (!(result = current->getLabel(label))) {
762 if (!current.hasContainingScope())
764 current = current.containingScope();
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&);
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&);
816 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
817 template <class TreeBuilder> TreeStatement parseArrowFunctionSingleExpressionBody(TreeBuilder&, FunctionParseType);
818 template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&);
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&);
826 template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&, FunctionParseType);
828 template <class TreeBuilder> NEVER_INLINE int parseFunctionParameters(TreeBuilder&, FunctionParseMode, ParserFunctionInfo<TreeBuilder>&);
830 #if ENABLE(ES6_CLASS_SYNTAX)
831 template <class TreeBuilder> NEVER_INLINE TreeClassExpression parseClass(TreeBuilder&, FunctionRequirements, ParserClassInfo<TreeBuilder>&);
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);
839 template <class TreeBuilder> ALWAYS_INLINE bool shouldCheckPropertyForUnderscoreProtoDuplicate(TreeBuilder&, const TreeProperty&);
841 ALWAYS_INLINE int isBinaryOperator(JSTokenType);
842 bool allowAutomaticSemicolon();
846 if (m_token.m_type == SEMICOLON) {
850 return allowAutomaticSemicolon();
854 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
855 void setEndOfStatement()
857 m_lexer->setTokenPosition(&m_token);
863 return m_vm->isSafeToRecurse();
866 const JSTextPosition& lastTokenEndPosition() const
868 return m_lastTokenEndPosition;
871 bool hasError() const
873 return !m_errorMessage.isNull();
878 unsigned oldLineStartOffset;
879 unsigned oldLastLineNumber;
880 unsigned oldLineNumber;
883 ALWAYS_INLINE SavePoint createSavePoint()
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();
894 ALWAYS_INLINE void restoreSavePoint(const SavePoint& savePoint)
896 m_errorMessage = String();
897 m_lexer->setOffset(savePoint.startOffset, savePoint.oldLineStartOffset);
899 m_lexer->setLastLineNumber(savePoint.oldLastLineNumber);
900 m_lexer->setLineNumber(savePoint.oldLineNumber);
906 int nonTrivialExpressionCount;
909 ALWAYS_INLINE ParserState saveState()
912 result.assignmentCount = m_assignmentCount;
913 result.nonLHSCount = m_nonLHSCount;
914 result.nonTrivialExpressionCount = m_nonTrivialExpressionCount;
918 ALWAYS_INLINE void restoreState(const ParserState& state)
920 m_assignmentCount = state.assignmentCount;
921 m_nonLHSCount = state.nonLHSCount;
922 m_nonTrivialExpressionCount = state.nonTrivialExpressionCount;
928 const SourceCode* m_source;
929 ParserArena m_parserArena;
930 std::unique_ptr<LexerType> m_lexer;
932 bool m_hasStackOverflow;
933 String m_errorMessage;
936 JSTextPosition m_lastTokenEndPosition;
937 int m_assignmentCount;
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;
956 struct DepthManager {
957 DepthManager(int* depth)
958 : m_originalDepth(*depth)
965 *m_depth = m_originalDepth;
975 template <typename LexerType>
976 template <class ParsedNode>
977 std::unique_ptr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
982 if (ParsedNode::scopeIsFunction)
983 m_lexer->setIsReparsing();
985 m_sourceElements = 0;
990 JSTokenLocation startLocation(tokenLocation());
991 ASSERT(m_source->startColumn() > 0);
992 unsigned startColumn = m_source->startColumn() - 1;
994 String parseError = parseInner();
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);
1002 if (!parseError.isNull() || lexError) {
1003 errLine = lineNumber;
1004 errMsg = !lexErrorMessage.isNull() ? lexErrorMessage : parseError;
1005 m_sourceElements = 0;
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,
1023 m_capturedVariables,
1027 result->setLoc(m_source->firstLine(), m_lexer->lineNumber(), m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
1028 result->setEndOffset(m_lexer->currentOffset());
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);
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;
1045 if (isEvalNode<ParsedNode>())
1046 error = ParserError(ParserError::EvalError, errorType, m_token, errMsg, errLine);
1048 error = ParserError(ParserError::SyntaxError, errorType, m_token, errMsg, errLine);
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)
1063 SamplingRegion samplingRegion("Parsing");
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) {
1073 WTF::dataLog("Error compiling builtin: ", error.message(), "\n");
1074 RELEASE_ASSERT(result);
1075 result->setClosedVariables(parser.closedVariables());
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();