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 "VariableEnvironment.h"
40 #include <wtf/Forward.h>
41 #include <wtf/Noncopyable.h>
42 #include <wtf/RefPtr.h>
48 template <> struct VectorTraits<JSC::Scope> : SimpleClassVectorTraits {
49 static const bool canInitializeWithMemset = false; // Not all Scope data members initialize to 0.
56 class FunctionBodyNode;
57 class FunctionParameters;
63 // Macros to make the more common TreeBuilder types a little less verbose
64 #define TreeStatement typename TreeBuilder::Statement
65 #define TreeExpression typename TreeBuilder::Expression
66 #define TreeFormalParameterList typename TreeBuilder::FormalParameterList
67 #define TreeSourceElements typename TreeBuilder::SourceElements
68 #define TreeClause typename TreeBuilder::Clause
69 #define TreeClauseList typename TreeBuilder::ClauseList
70 #define TreeConstDeclList typename TreeBuilder::ConstDeclList
71 #define TreeArguments typename TreeBuilder::Arguments
72 #define TreeArgumentsList typename TreeBuilder::ArgumentsList
73 #define TreeFunctionBody typename TreeBuilder::FunctionBody
74 #if ENABLE(ES6_CLASS_SYNTAX)
75 #define TreeClassExpression typename TreeBuilder::ClassExpression
77 #define TreeProperty typename TreeBuilder::Property
78 #define TreePropertyList typename TreeBuilder::PropertyList
79 #define TreeDestructuringPattern typename TreeBuilder::DestructuringPattern
81 COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
83 enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
84 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
85 enum FunctionParseType { StandardFunctionParseType, ArrowFunctionParseType };
87 enum FunctionParseType { StandardFunctionParseType};
89 enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName };
90 enum FunctionParseMode {
95 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
99 enum DestructuringKind {
100 DestructureToVariables,
101 DestructureToLexicalVariables,
102 DestructureToParameters,
103 DestructureToExpressions
106 template <typename T> inline bool isEvalNode() { return false; }
107 template <> inline bool isEvalNode<EvalNode>() { return true; }
109 struct ScopeLabelInfo {
110 UniquedStringImpl* uid;
115 Scope(const VM* vm, bool isFunction, bool strictMode)
117 , m_shadowsArguments(false)
119 , m_needsFullActivation(false)
120 , m_hasDirectSuper(false)
121 , m_needsSuperBinding(false)
122 , m_allowsVarDeclarations(true)
123 , m_allowsLexicalDeclarations(true)
124 , m_strictMode(strictMode)
125 , m_isFunction(isFunction)
126 , m_isLexicalScope(false)
127 , m_isFunctionBoundary(false)
128 , m_isValidStrictMode(true)
134 Scope(const Scope& rhs)
136 , m_shadowsArguments(rhs.m_shadowsArguments)
137 , m_usesEval(rhs.m_usesEval)
138 , m_needsFullActivation(rhs.m_needsFullActivation)
139 , m_hasDirectSuper(rhs.m_hasDirectSuper)
140 , m_needsSuperBinding(rhs.m_needsSuperBinding)
141 , m_allowsVarDeclarations(rhs.m_allowsVarDeclarations)
142 , m_allowsLexicalDeclarations(rhs.m_allowsLexicalDeclarations)
143 , m_strictMode(rhs.m_strictMode)
144 , m_isFunction(rhs.m_isFunction)
145 , m_isLexicalScope(rhs.m_isLexicalScope)
146 , m_isFunctionBoundary(rhs.m_isFunctionBoundary)
147 , m_isValidStrictMode(rhs.m_isValidStrictMode)
148 , m_loopDepth(rhs.m_loopDepth)
149 , m_switchDepth(rhs.m_switchDepth)
152 m_labels = std::make_unique<LabelStack>();
154 typedef LabelStack::const_iterator iterator;
155 iterator end = rhs.m_labels->end();
156 for (iterator it = rhs.m_labels->begin(); it != end; ++it)
157 m_labels->append(ScopeLabelInfo { it->uid, it->isLoop });
161 void startSwitch() { m_switchDepth++; }
162 void endSwitch() { m_switchDepth--; }
163 void startLoop() { m_loopDepth++; }
164 void endLoop() { ASSERT(m_loopDepth); m_loopDepth--; }
165 bool inLoop() { return !!m_loopDepth; }
166 bool breakIsValid() { return m_loopDepth || m_switchDepth; }
167 bool continueIsValid() { return m_loopDepth; }
169 void pushLabel(const Identifier* label, bool isLoop)
172 m_labels = std::make_unique<LabelStack>();
173 m_labels->append(ScopeLabelInfo { label->impl(), isLoop });
179 ASSERT(m_labels->size());
180 m_labels->removeLast();
183 ScopeLabelInfo* getLabel(const Identifier* label)
187 for (int i = m_labels->size(); i > 0; i--) {
188 if (m_labels->at(i - 1).uid == label->impl())
189 return &m_labels->at(i - 1);
197 m_isFunctionBoundary = true;
201 bool isFunction() const { return m_isFunction; }
202 bool isFunctionBoundary() const { return m_isFunctionBoundary; }
204 void setIsLexicalScope()
206 m_isLexicalScope = true;
207 m_allowsLexicalDeclarations = true;
209 bool isLexicalScope() { return m_isLexicalScope; }
211 VariableEnvironment& declaredVariables() { return m_declaredVariables; }
212 VariableEnvironment& finalizeLexicalEnvironment()
214 if (m_usesEval || m_needsFullActivation)
215 m_lexicalVariables.markAllVariablesAsCaptured();
217 computeLexicallyCapturedVariablesAndPurgeCandidates();
219 return m_lexicalVariables;
222 void computeLexicallyCapturedVariablesAndPurgeCandidates()
224 // Because variables may be defined at any time in the range of a lexical scope, we must
225 // track lexical variables that might be captured. Then, when we're preparing to pop the top
226 // lexical scope off the stack, we should find which variables are truly captured, and which
227 // variable still may be captured in a parent scope.
228 if (m_lexicalVariables.size() && m_closedVariableCandidates.size()) {
229 auto end = m_closedVariableCandidates.end();
230 for (auto iter = m_closedVariableCandidates.begin(); iter != end; ++iter)
231 m_lexicalVariables.markVariableAsCapturedIfDefined(iter->get());
234 // We can now purge values from the captured candidates because they're captured in this scope.
236 for (auto entry : m_lexicalVariables) {
237 if (entry.value.isCaptured())
238 m_closedVariableCandidates.remove(entry.key);
243 void declareCallee(const Identifier* ident)
245 auto addResult = m_declaredVariables.add(ident->impl());
246 // We want to track if callee is captured, but we don't want to act like it's a 'var'
247 // because that would cause the BytecodeGenerator to emit bad code.
248 addResult.iterator->value.clearIsVar();
251 bool declareVariable(const Identifier* ident, bool isConstant = false)
253 ASSERT(m_allowsVarDeclarations);
254 bool isValidStrictMode = m_vm->propertyNames->eval != *ident && m_vm->propertyNames->arguments != *ident;
255 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
256 auto addResult = m_declaredVariables.add(ident->impl());
257 addResult.iterator->value.setIsVar();
259 addResult.iterator->value.setIsConstant();
261 return isValidStrictMode;
264 bool declareLexicalVariable(const Identifier* ident)
266 ASSERT(m_allowsLexicalDeclarations);
267 bool isValidStrictMode = m_vm->propertyNames->eval != *ident && m_vm->propertyNames->arguments != *ident;
268 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
269 auto addResult = m_lexicalVariables.add(ident->impl());
270 addResult.iterator->value.setIsLet();
271 bool successfulDeclaration = addResult.isNewEntry && isValidStrictMode;
272 return successfulDeclaration;
275 bool hasDeclaredVariable(const Identifier& ident)
277 return hasDeclaredVariable(ident.impl());
280 bool hasDeclaredVariable(const RefPtr<UniquedStringImpl>& ident)
282 return m_declaredVariables.contains(ident.get());
285 bool hasLexicallyDeclaredVariable(const RefPtr<UniquedStringImpl>& ident) const
287 return m_lexicalVariables.contains(ident.get());
290 ALWAYS_INLINE bool hasDeclaredParameter(const Identifier& ident)
292 return hasDeclaredParameter(ident.impl());
295 bool hasDeclaredParameter(const RefPtr<UniquedStringImpl>& ident)
297 return m_declaredParameters.contains(ident) || m_declaredVariables.contains(ident.get());
300 void declareWrite(const Identifier* ident)
302 ASSERT(m_strictMode);
303 m_writtenVariables.add(ident->impl());
306 void preventAllVariableDeclarations()
308 m_allowsVarDeclarations = false;
309 m_allowsLexicalDeclarations = false;
311 void preventVarDeclarations() { m_allowsVarDeclarations = false; }
312 bool allowsVarDeclarations() const { return m_allowsVarDeclarations; }
313 bool allowsLexicalDeclarations() const { return m_allowsLexicalDeclarations; }
315 bool declareParameter(const Identifier* ident)
317 ASSERT(m_allowsVarDeclarations);
318 bool isArguments = m_vm->propertyNames->arguments == *ident;
319 auto addResult = m_declaredVariables.add(ident->impl());
320 addResult.iterator->value.clearIsVar();
321 bool isValidStrictMode = addResult.isNewEntry && m_vm->propertyNames->eval != *ident && !isArguments;
322 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
323 m_declaredParameters.add(ident->impl());
326 m_shadowsArguments = true;
327 return isValidStrictMode;
335 BindingResult declareBoundParameter(const Identifier* ident)
337 bool isArguments = m_vm->propertyNames->arguments == *ident;
338 auto addResult = m_declaredVariables.add(ident->impl());
339 addResult.iterator->value.setIsVar(); // Treat destructuring parameters as "var"s.
340 bool isValidStrictMode = addResult.isNewEntry && m_vm->propertyNames->eval != *ident && !isArguments;
341 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
344 m_shadowsArguments = true;
345 if (!addResult.isNewEntry)
346 return BindingFailed;
347 return isValidStrictMode ? BindingSucceeded : StrictBindingFailed;
350 void getUsedVariables(IdentifierSet& usedVariables)
352 usedVariables.swap(m_usedVariables);
355 void useVariable(const Identifier* ident, bool isEval)
357 m_usesEval |= isEval;
358 m_usedVariables.add(ident->impl());
361 void setNeedsFullActivation() { m_needsFullActivation = true; }
362 bool needsFullActivation() const { return m_needsFullActivation; }
364 #if ENABLE(ES6_CLASS_SYNTAX)
365 bool hasDirectSuper() { return m_hasDirectSuper; }
367 bool hasDirectSuper() { return false; }
369 void setHasDirectSuper() { m_hasDirectSuper = true; }
371 #if ENABLE(ES6_CLASS_SYNTAX)
372 bool needsSuperBinding() { return m_needsSuperBinding; }
374 bool needsSuperBinding() { return false; }
376 void setNeedsSuperBinding() { m_needsSuperBinding = true; }
378 void collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
380 if (nestedScope->m_usesEval)
384 IdentifierSet::iterator end = nestedScope->m_usedVariables.end();
385 for (IdentifierSet::iterator ptr = nestedScope->m_usedVariables.begin(); ptr != end; ++ptr) {
386 if (nestedScope->m_declaredVariables.contains(*ptr) || nestedScope->m_lexicalVariables.contains(*ptr))
388 m_usedVariables.add(*ptr);
389 // We don't want a declared variable that is used in an inner scope to be thought of as captured if
390 // that inner scope is both a lexical scope and not a function. Only inner functions and "catch"
391 // statements can cause variables to be captured.
392 if (shouldTrackClosedVariables && (nestedScope->m_isFunctionBoundary || !nestedScope->m_isLexicalScope))
393 m_closedVariableCandidates.add(*ptr);
396 // Propagate closed variable candidates downwards within the same function.
397 // Cross function captures will be realized via m_usedVariables propagation.
398 if (shouldTrackClosedVariables && !nestedScope->m_isFunctionBoundary && nestedScope->m_closedVariableCandidates.size()) {
399 IdentifierSet::iterator end = nestedScope->m_closedVariableCandidates.end();
400 IdentifierSet::iterator begin = nestedScope->m_closedVariableCandidates.begin();
401 m_closedVariableCandidates.add(begin, end);
404 if (nestedScope->m_writtenVariables.size()) {
405 IdentifierSet::iterator end = nestedScope->m_writtenVariables.end();
406 for (IdentifierSet::iterator ptr = nestedScope->m_writtenVariables.begin(); ptr != end; ++ptr) {
407 if (nestedScope->m_declaredVariables.contains(*ptr) || nestedScope->m_lexicalVariables.contains(*ptr))
409 m_writtenVariables.add(*ptr);
414 void getCapturedVars(IdentifierSet& capturedVariables, bool& modifiedParameter, bool& modifiedArguments)
416 if (m_needsFullActivation || m_usesEval) {
417 modifiedParameter = true;
418 for (auto& entry : m_declaredVariables)
419 capturedVariables.add(entry.key);
422 for (IdentifierSet::iterator ptr = m_closedVariableCandidates.begin(); ptr != m_closedVariableCandidates.end(); ++ptr) {
423 if (!m_declaredVariables.contains(*ptr))
425 capturedVariables.add(*ptr);
427 modifiedParameter = false;
428 if (shadowsArguments())
429 modifiedArguments = true;
430 if (m_declaredParameters.size()) {
431 IdentifierSet::iterator end = m_writtenVariables.end();
432 for (IdentifierSet::iterator ptr = m_writtenVariables.begin(); ptr != end; ++ptr) {
433 if (*ptr == m_vm->propertyNames->arguments.impl())
434 modifiedArguments = true;
435 if (!m_declaredParameters.contains(*ptr))
437 modifiedParameter = true;
442 void setStrictMode() { m_strictMode = true; }
443 bool strictMode() const { return m_strictMode; }
444 bool isValidStrictMode() const { return m_isValidStrictMode; }
445 bool shadowsArguments() const { return m_shadowsArguments; }
447 void copyCapturedVariablesToVector(const IdentifierSet& capturedVariables, Vector<RefPtr<UniquedStringImpl>>& vector)
449 IdentifierSet::iterator end = capturedVariables.end();
450 for (IdentifierSet::iterator it = capturedVariables.begin(); it != end; ++it) {
451 if (m_declaredVariables.contains(*it) || m_lexicalVariables.contains(*it))
457 void fillParametersForSourceProviderCache(SourceProviderCacheItemCreationParameters& parameters)
459 ASSERT(m_isFunction);
460 parameters.usesEval = m_usesEval;
461 parameters.strictMode = m_strictMode;
462 parameters.needsFullActivation = m_needsFullActivation;
463 copyCapturedVariablesToVector(m_writtenVariables, parameters.writtenVariables);
464 copyCapturedVariablesToVector(m_usedVariables, parameters.usedVariables);
467 void restoreFromSourceProviderCache(const SourceProviderCacheItem* info)
469 ASSERT(m_isFunction);
470 m_usesEval = info->usesEval;
471 m_strictMode = info->strictMode;
472 m_needsFullActivation = info->needsFullActivation;
473 for (unsigned i = 0; i < info->usedVariablesCount; ++i)
474 m_usedVariables.add(info->usedVariables()[i]);
475 for (unsigned i = 0; i < info->writtenVariablesCount; ++i)
476 m_writtenVariables.add(info->writtenVariables()[i]);
481 bool m_shadowsArguments : 1;
483 bool m_needsFullActivation : 1;
484 bool m_hasDirectSuper : 1;
485 bool m_needsSuperBinding : 1;
486 bool m_allowsVarDeclarations : 1;
487 bool m_allowsLexicalDeclarations : 1;
488 bool m_strictMode : 1;
489 bool m_isFunction : 1;
490 bool m_isLexicalScope : 1;
491 bool m_isFunctionBoundary : 1;
492 bool m_isValidStrictMode : 1;
496 typedef Vector<ScopeLabelInfo, 2> LabelStack;
497 std::unique_ptr<LabelStack> m_labels;
498 IdentifierSet m_declaredParameters;
499 VariableEnvironment m_declaredVariables;
500 VariableEnvironment m_lexicalVariables;
501 IdentifierSet m_usedVariables;
502 IdentifierSet m_closedVariableCandidates;
503 IdentifierSet m_writtenVariables;
506 typedef Vector<Scope, 10> ScopeStack;
509 ScopeRef(ScopeStack* scopeStack, unsigned index)
510 : m_scopeStack(scopeStack)
514 Scope* operator->() { return &m_scopeStack->at(m_index); }
515 unsigned index() const { return m_index; }
517 bool hasContainingScope()
519 return m_index && !m_scopeStack->at(m_index).isFunctionBoundary();
522 ScopeRef containingScope()
524 ASSERT(hasContainingScope());
525 return ScopeRef(m_scopeStack, m_index - 1);
529 ScopeStack* m_scopeStack;
533 template <typename LexerType>
535 WTF_MAKE_NONCOPYABLE(Parser);
536 WTF_MAKE_FAST_ALLOCATED;
540 VM*, const SourceCode&, FunctionParameters*, const Identifier&,
541 JSParserBuiltinMode, JSParserStrictMode, JSParserCodeType,
542 ConstructorKind defaultConstructorKind = ConstructorKind::None, ThisTDZMode = ThisTDZMode::CheckIfNeeded);
545 template <class ParsedNode>
546 std::unique_ptr<ParsedNode> parse(ParserError&);
548 JSTextPosition positionBeforeLastNewline() const { return m_lexer->positionBeforeLastNewline(); }
549 JSTokenLocation locationBeforeLastToken() const { return m_lexer->lastTokenLocation(); }
550 Vector<RefPtr<UniquedStringImpl>>&& closedVariables() { return WTF::move(m_closedVariables); }
553 struct AllowInOverride {
554 AllowInOverride(Parser* parser)
556 , m_oldAllowsIn(parser->m_allowsIn)
558 parser->m_allowsIn = true;
562 m_parser->m_allowsIn = m_oldAllowsIn;
568 struct AutoPopScopeRef : public ScopeRef {
569 AutoPopScopeRef(Parser* parser, ScopeRef scope)
578 m_parser->popScope(*this, false);
590 struct AutoCleanupLexicalScope {
591 // We can allocate this object on the stack without actually knowing beforehand if we're
592 // going to create a new lexical scope. If we decide to create a new lexical scope, we
593 // can pass the scope into this obejct and it will take care of the cleanup for us if the parse fails.
594 // This is helpful if we may fail from syntax errors after creating a lexical scope conditionally.
595 AutoCleanupLexicalScope()
596 : m_scope(nullptr, UINT_MAX)
601 ~AutoCleanupLexicalScope()
603 // This should only ever be called if we fail from a syntax error. Otherwise
604 // it's the intention that a user of this class pops this scope manually on a
607 m_parser->popScope(*this, false);
610 void setIsValid(ScopeRef& scope, Parser* parser)
612 RELEASE_ASSERT(scope->isLexicalScope());
617 bool isValid() const { return !!m_parser; }
624 ScopeRef& scope() { return m_scope; }
631 ScopeRef currentScope()
633 return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
638 bool isFunction = false;
639 bool isStrict = false;
640 if (!m_scopeStack.isEmpty()) {
641 isStrict = m_scopeStack.last().strictMode();
642 isFunction = m_scopeStack.last().isFunction();
644 m_scopeStack.append(Scope(m_vm, isFunction, isStrict));
645 return currentScope();
648 void popScopeInternal(ScopeRef& scope, bool shouldTrackClosedVariables)
650 ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1);
651 ASSERT(m_scopeStack.size() > 1);
652 m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
653 if (!m_scopeStack.last().isFunctionBoundary() && m_scopeStack.last().needsFullActivation())
654 m_scopeStack[m_scopeStack.size() - 2].setNeedsFullActivation();
655 m_scopeStack.removeLast();
658 ALWAYS_INLINE void popScope(ScopeRef& scope, bool shouldTrackClosedVariables)
660 popScopeInternal(scope, shouldTrackClosedVariables);
663 ALWAYS_INLINE void popScope(AutoPopScopeRef& scope, bool shouldTrackClosedVariables)
666 popScopeInternal(scope, shouldTrackClosedVariables);
669 ALWAYS_INLINE void popScope(AutoCleanupLexicalScope& cleanupScope, bool shouldTrackClosedVariables)
671 RELEASE_ASSERT(cleanupScope.isValid());
672 ScopeRef& scope = cleanupScope.scope();
673 cleanupScope.setPopped();
674 popScopeInternal(scope, shouldTrackClosedVariables);
677 enum class DeclarationType { VarDeclaration, LexicalDeclaration };
678 bool declareVariable(const Identifier* ident, typename Parser::DeclarationType type = DeclarationType::VarDeclaration, bool isConstant = false)
680 unsigned i = m_scopeStack.size() - 1;
681 ASSERT(i < m_scopeStack.size());
683 if (type == DeclarationType::VarDeclaration) {
684 while (!m_scopeStack[i].allowsVarDeclarations()) {
686 ASSERT(i < m_scopeStack.size());
689 return m_scopeStack[i].declareVariable(ident, isConstant);
692 ASSERT(type == DeclarationType::LexicalDeclaration);
694 // Lexical variables declared at a top level scope that shadow arguments or vars are not allowed.
695 if (m_statementDepth == 1 && (hasDeclaredParameter(*ident) || hasDeclaredVariable(*ident)))
698 while (!m_scopeStack[i].allowsLexicalDeclarations()) {
700 ASSERT(i < m_scopeStack.size());
703 return m_scopeStack[i].declareLexicalVariable(ident);
706 NEVER_INLINE bool hasDeclaredVariable(const Identifier& ident)
708 unsigned i = m_scopeStack.size() - 1;
709 ASSERT(i < m_scopeStack.size());
710 while (!m_scopeStack[i].allowsVarDeclarations()) {
712 ASSERT(i < m_scopeStack.size());
714 return m_scopeStack[i].hasDeclaredVariable(ident);
717 NEVER_INLINE bool hasDeclaredParameter(const Identifier& ident)
719 unsigned i = m_scopeStack.size() - 1;
720 ASSERT(i < m_scopeStack.size());
721 while (!m_scopeStack[i].allowsVarDeclarations()) {
723 ASSERT(i < m_scopeStack.size());
725 return m_scopeStack[i].hasDeclaredParameter(ident);
728 void declareWrite(const Identifier* ident)
730 if (!m_syntaxAlreadyValidated || strictMode())
731 m_scopeStack.last().declareWrite(ident);
734 ScopeStack m_scopeStack;
736 const SourceProviderCacheItem* findCachedFunctionInfo(int openBracePos)
738 return m_functionCache ? m_functionCache->get(openBracePos) : 0;
744 void didFinishParsing(SourceElements*, DeclarationStacks::FunctionStack&, VariableEnvironment&, CodeFeatures, int, const Vector<RefPtr<UniquedStringImpl>>&&);
746 // Used to determine type of error to report.
747 bool isFunctionBodyNode(ScopeNode*) { return false; }
748 bool isFunctionBodyNode(FunctionBodyNode*) { return true; }
750 ALWAYS_INLINE void next(unsigned lexerFlags = 0)
752 int lastLine = m_token.m_location.line;
753 int lastTokenEnd = m_token.m_location.endOffset;
754 int lastTokenLineStart = m_token.m_location.lineStartOffset;
755 m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
756 m_lexer->setLastLineNumber(lastLine);
757 m_token.m_type = m_lexer->lex(&m_token, lexerFlags, strictMode());
760 ALWAYS_INLINE void nextExpectIdentifier(unsigned lexerFlags = 0)
762 int lastLine = m_token.m_location.line;
763 int lastTokenEnd = m_token.m_location.endOffset;
764 int lastTokenLineStart = m_token.m_location.lineStartOffset;
765 m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
766 m_lexer->setLastLineNumber(lastLine);
767 m_token.m_type = m_lexer->lexExpectIdentifier(&m_token, lexerFlags, strictMode());
770 ALWAYS_INLINE bool nextTokenIsColon()
772 return m_lexer->nextTokenIsColon();
775 ALWAYS_INLINE bool consume(JSTokenType expected, unsigned flags = 0)
777 bool result = m_token.m_type == expected;
783 void printUnexpectedTokenText(WTF::PrintStream&);
784 ALWAYS_INLINE String getToken() {
785 SourceProvider* sourceProvider = m_source->provider();
786 return sourceProvider->getRange(tokenStart(), tokenEndPosition().offset);
789 ALWAYS_INLINE bool match(JSTokenType expected)
791 return m_token.m_type == expected;
794 ALWAYS_INLINE bool isofToken()
796 return m_token.m_type == IDENT && *m_token.m_data.ident == m_vm->propertyNames->of;
799 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
800 ALWAYS_INLINE bool isEndOfArrowFunction()
802 return match(SEMICOLON) || match(COMMA) || match(CLOSEPAREN) || match(CLOSEBRACE) || match(CLOSEBRACKET) || match(EOFTOK) || m_lexer->prevTerminator();
805 ALWAYS_INLINE bool isArrowFunctionParamters()
807 bool isArrowFunction = false;
810 return isArrowFunction;
812 SavePoint saveArrowFunctionPoint = createSavePoint();
814 if (consume(OPENPAREN)) {
815 bool isArrowFunctionParamters = true;
817 while (consume(IDENT)) {
818 if (consume(COMMA)) {
820 isArrowFunctionParamters = false;
827 if (isArrowFunctionParamters) {
828 if (consume(CLOSEPAREN) && match(ARROWFUNCTION))
829 isArrowFunction = true;
831 } else if (consume(IDENT) && match(ARROWFUNCTION))
832 isArrowFunction = true;
834 restoreSavePoint(saveArrowFunctionPoint);
836 return isArrowFunction;
840 ALWAYS_INLINE unsigned tokenStart()
842 return m_token.m_location.startOffset;
845 ALWAYS_INLINE const JSTextPosition& tokenStartPosition()
847 return m_token.m_startPosition;
850 ALWAYS_INLINE int tokenLine()
852 return m_token.m_location.line;
855 ALWAYS_INLINE int tokenColumn()
857 return tokenStart() - tokenLineStart();
860 ALWAYS_INLINE const JSTextPosition& tokenEndPosition()
862 return m_token.m_endPosition;
865 ALWAYS_INLINE unsigned tokenLineStart()
867 return m_token.m_location.lineStartOffset;
870 ALWAYS_INLINE const JSTokenLocation& tokenLocation()
872 return m_token.m_location;
875 void setErrorMessage(const String& message)
877 m_errorMessage = message;
880 NEVER_INLINE void logError(bool);
881 template <typename A> NEVER_INLINE void logError(bool, const A&);
882 template <typename A, typename B> NEVER_INLINE void logError(bool, const A&, const B&);
883 template <typename A, typename B, typename C> NEVER_INLINE void logError(bool, const A&, const B&, const C&);
884 template <typename A, typename B, typename C, typename D> NEVER_INLINE void logError(bool, const A&, const B&, const C&, const D&);
885 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&);
886 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&);
887 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&);
889 NEVER_INLINE void updateErrorWithNameAndMessage(const char* beforeMessage, const String& name, const char* afterMessage)
891 m_errorMessage = makeString(beforeMessage, " '", name, "' ", afterMessage);
894 NEVER_INLINE void updateErrorMessage(const char* msg)
897 m_errorMessage = String(msg);
898 ASSERT(!m_errorMessage.isNull());
901 void startLoop() { currentScope()->startLoop(); }
902 void endLoop() { currentScope()->endLoop(); }
903 void startSwitch() { currentScope()->startSwitch(); }
904 void endSwitch() { currentScope()->endSwitch(); }
905 void setStrictMode() { currentScope()->setStrictMode(); }
906 bool strictMode() { return currentScope()->strictMode(); }
907 bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
908 bool declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
909 Scope::BindingResult declareBoundParameter(const Identifier* ident) { return currentScope()->declareBoundParameter(ident); }
912 ScopeRef current = currentScope();
913 while (!current->breakIsValid()) {
914 if (!current.hasContainingScope())
916 current = current.containingScope();
920 bool continueIsValid()
922 ScopeRef current = currentScope();
923 while (!current->continueIsValid()) {
924 if (!current.hasContainingScope())
926 current = current.containingScope();
930 void pushLabel(const Identifier* label, bool isLoop) { currentScope()->pushLabel(label, isLoop); }
931 void popLabel(ScopeRef scope) { scope->popLabel(); }
932 ScopeLabelInfo* getLabel(const Identifier* label)
934 ScopeRef current = currentScope();
935 ScopeLabelInfo* result = 0;
936 while (!(result = current->getLabel(label))) {
937 if (!current.hasContainingScope())
939 current = current.containingScope();
944 ALWAYS_INLINE bool isLETMaskedAsIDENT()
946 return match(LET) && !strictMode();
949 template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode, FunctionParseType);
950 template <class TreeBuilder> TreeStatement parseStatementListItem(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength);
951 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
952 #if ENABLE(ES6_CLASS_SYNTAX)
953 template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&);
955 template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&);
956 template <class TreeBuilder> TreeStatement parseVariableDeclaration(TreeBuilder&, DeclarationType);
957 template <class TreeBuilder> TreeStatement parseConstDeclaration(TreeBuilder&);
958 template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&);
959 template <class TreeBuilder> TreeStatement parseWhileStatement(TreeBuilder&);
960 template <class TreeBuilder> TreeStatement parseForStatement(TreeBuilder&);
961 template <class TreeBuilder> TreeStatement parseBreakStatement(TreeBuilder&);
962 template <class TreeBuilder> TreeStatement parseContinueStatement(TreeBuilder&);
963 template <class TreeBuilder> TreeStatement parseReturnStatement(TreeBuilder&);
964 template <class TreeBuilder> TreeStatement parseThrowStatement(TreeBuilder&);
965 template <class TreeBuilder> TreeStatement parseWithStatement(TreeBuilder&);
966 template <class TreeBuilder> TreeStatement parseSwitchStatement(TreeBuilder&);
967 template <class TreeBuilder> TreeClauseList parseSwitchClauses(TreeBuilder&);
968 template <class TreeBuilder> TreeClause parseSwitchDefaultClause(TreeBuilder&);
969 template <class TreeBuilder> TreeStatement parseTryStatement(TreeBuilder&);
970 template <class TreeBuilder> TreeStatement parseDebuggerStatement(TreeBuilder&);
971 template <class TreeBuilder> TreeStatement parseExpressionStatement(TreeBuilder&);
972 template <class TreeBuilder> TreeStatement parseExpressionOrLabelStatement(TreeBuilder&);
973 template <class TreeBuilder> TreeStatement parseIfStatement(TreeBuilder&);
974 template <class TreeBuilder> TreeStatement parseBlockStatement(TreeBuilder&);
975 template <class TreeBuilder> TreeExpression parseExpression(TreeBuilder&);
976 template <class TreeBuilder> TreeExpression parseAssignmentExpression(TreeBuilder&);
977 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseConditionalExpression(TreeBuilder&);
978 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseBinaryExpression(TreeBuilder&);
979 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseUnaryExpression(TreeBuilder&);
980 template <class TreeBuilder> TreeExpression parseMemberExpression(TreeBuilder&);
981 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parsePrimaryExpression(TreeBuilder&);
982 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArrayLiteral(TreeBuilder&);
983 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseObjectLiteral(TreeBuilder&);
984 template <class TreeBuilder> NEVER_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&);
985 enum SpreadMode { AllowSpread, DontAllowSpread };
986 template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&, SpreadMode);
987 template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict);
988 template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName);
989 template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind = ConstructorKind::None, SuperBinding = SuperBinding::NotNeeded);
990 template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, FunctionParseType);
991 template <class TreeBuilder> ALWAYS_INLINE TreeFormalParameterList parseFormalParameters(TreeBuilder&);
992 enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext };
993 template <class TreeBuilder> TreeExpression parseVariableDeclarationList(TreeBuilder&, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext, DeclarationType);
994 template <class TreeBuilder> NEVER_INLINE TreeConstDeclList parseConstDeclarationList(TreeBuilder&);
996 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
997 template <class TreeBuilder> TreeStatement parseArrowFunctionSingleExpressionBody(TreeBuilder&, FunctionParseType);
998 template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&);
1001 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, const Identifier&, int depth, JSToken, AssignmentContext);
1002 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseDestructuringPattern(TreeBuilder&, DestructuringKind, AssignmentContext = AssignmentContext::DeclarationStatement, int depth = 0);
1003 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern tryParseDestructuringPatternExpression(TreeBuilder&, AssignmentContext);
1004 template <class TreeBuilder> NEVER_INLINE TreeExpression parseDefaultValueForDestructuringPattern(TreeBuilder&);
1006 template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, FunctionParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&, FunctionParseType);
1008 template <class TreeBuilder> NEVER_INLINE int parseFunctionParameters(TreeBuilder&, FunctionParseMode, ParserFunctionInfo<TreeBuilder>&);
1010 #if ENABLE(ES6_CLASS_SYNTAX)
1011 template <class TreeBuilder> NEVER_INLINE TreeClassExpression parseClass(TreeBuilder&, FunctionRequirements, ParserClassInfo<TreeBuilder>&);
1014 #if ENABLE(ES6_TEMPLATE_LITERAL_SYNTAX)
1015 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::TemplateString parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode, bool& elementIsTail);
1016 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::TemplateLiteral parseTemplateLiteral(TreeBuilder&, typename LexerType::RawStringsBuildMode);
1019 template <class TreeBuilder> ALWAYS_INLINE bool shouldCheckPropertyForUnderscoreProtoDuplicate(TreeBuilder&, const TreeProperty&);
1021 ALWAYS_INLINE int isBinaryOperator(JSTokenType);
1022 bool allowAutomaticSemicolon();
1024 bool autoSemiColon()
1026 if (m_token.m_type == SEMICOLON) {
1030 return allowAutomaticSemicolon();
1034 #if ENABLE(ES6_ARROWFUNCTION_SYNTAX)
1035 void setEndOfStatement()
1037 m_lexer->setTokenPosition(&m_token);
1043 return m_vm->isSafeToRecurse();
1046 const JSTextPosition& lastTokenEndPosition() const
1048 return m_lastTokenEndPosition;
1051 bool hasError() const
1053 return !m_errorMessage.isNull();
1058 unsigned oldLineStartOffset;
1059 unsigned oldLastLineNumber;
1060 unsigned oldLineNumber;
1063 ALWAYS_INLINE SavePoint createSavePoint()
1065 ASSERT(!hasError());
1067 result.startOffset = m_token.m_location.startOffset;
1068 result.oldLineStartOffset = m_token.m_location.lineStartOffset;
1069 result.oldLastLineNumber = m_lexer->lastLineNumber();
1070 result.oldLineNumber = m_lexer->lineNumber();
1074 ALWAYS_INLINE void restoreSavePoint(const SavePoint& savePoint)
1076 m_errorMessage = String();
1077 m_lexer->setOffset(savePoint.startOffset, savePoint.oldLineStartOffset);
1079 m_lexer->setLastLineNumber(savePoint.oldLastLineNumber);
1080 m_lexer->setLineNumber(savePoint.oldLineNumber);
1083 struct ParserState {
1084 int assignmentCount;
1086 int nonTrivialExpressionCount;
1089 ALWAYS_INLINE ParserState saveState()
1092 result.assignmentCount = m_assignmentCount;
1093 result.nonLHSCount = m_nonLHSCount;
1094 result.nonTrivialExpressionCount = m_nonTrivialExpressionCount;
1098 ALWAYS_INLINE void restoreState(const ParserState& state)
1100 m_assignmentCount = state.assignmentCount;
1101 m_nonLHSCount = state.nonLHSCount;
1102 m_nonTrivialExpressionCount = state.nonTrivialExpressionCount;
1108 const SourceCode* m_source;
1109 ParserArena m_parserArena;
1110 std::unique_ptr<LexerType> m_lexer;
1112 bool m_hasStackOverflow;
1113 String m_errorMessage;
1116 JSTextPosition m_lastTokenEndPosition;
1117 int m_assignmentCount;
1119 bool m_syntaxAlreadyValidated;
1120 int m_statementDepth;
1121 int m_nonTrivialExpressionCount;
1122 const Identifier* m_lastIdentifier;
1123 const Identifier* m_lastFunctionName;
1124 RefPtr<SourceProviderCache> m_functionCache;
1125 SourceElements* m_sourceElements;
1126 bool m_parsingBuiltin;
1127 ConstructorKind m_defaultConstructorKind;
1128 ThisTDZMode m_thisTDZMode;
1129 VariableEnvironment m_varDeclarations;
1130 DeclarationStacks::FunctionStack m_funcDeclarations;
1131 Vector<RefPtr<UniquedStringImpl>> m_closedVariables;
1132 CodeFeatures m_features;
1135 struct DepthManager {
1136 DepthManager(int* depth)
1137 : m_originalDepth(*depth)
1144 *m_depth = m_originalDepth;
1148 int m_originalDepth;
1154 template <typename LexerType>
1155 template <class ParsedNode>
1156 std::unique_ptr<ParsedNode> Parser<LexerType>::parse(ParserError& error)
1161 if (ParsedNode::scopeIsFunction)
1162 m_lexer->setIsReparsing();
1164 m_sourceElements = 0;
1169 JSTokenLocation startLocation(tokenLocation());
1170 ASSERT(m_source->startColumn() > 0);
1171 unsigned startColumn = m_source->startColumn() - 1;
1173 String parseError = parseInner();
1175 int lineNumber = m_lexer->lineNumber();
1176 bool lexError = m_lexer->sawError();
1177 String lexErrorMessage = lexError ? m_lexer->getErrorMessage() : String();
1178 ASSERT(lexErrorMessage.isNull() != lexError);
1181 if (!parseError.isNull() || lexError) {
1182 errLine = lineNumber;
1183 errMsg = !lexErrorMessage.isNull() ? lexErrorMessage : parseError;
1184 m_sourceElements = 0;
1187 std::unique_ptr<ParsedNode> result;
1188 if (m_sourceElements) {
1189 JSTokenLocation endLocation;
1190 endLocation.line = m_lexer->lineNumber();
1191 endLocation.lineStartOffset = m_lexer->currentLineStartOffset();
1192 endLocation.startOffset = m_lexer->currentOffset();
1193 unsigned endColumn = endLocation.startOffset - endLocation.lineStartOffset;
1194 result = std::make_unique<ParsedNode>(m_parserArena,
1202 currentScope()->finalizeLexicalEnvironment(),
1206 result->setLoc(m_source->firstLine(), m_lexer->lineNumber(), m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
1207 result->setEndOffset(m_lexer->currentOffset());
1209 // We can never see a syntax error when reparsing a function, since we should have
1210 // reported the error when parsing the containing program or eval code. So if we're
1211 // parsing a function body node, we assume that what actually happened here is that
1212 // we ran out of stack while parsing. If we see an error while parsing eval or program
1213 // code we assume that it was a syntax error since running out of stack is much less
1214 // likely, and we are currently unable to distinguish between the two cases.
1215 if (isFunctionBodyNode(static_cast<ParsedNode*>(0)) || m_hasStackOverflow)
1216 error = ParserError(ParserError::StackOverflow, ParserError::SyntaxErrorNone, m_token);
1218 ParserError::SyntaxErrorType errorType = ParserError::SyntaxErrorIrrecoverable;
1219 if (m_token.m_type == EOFTOK)
1220 errorType = ParserError::SyntaxErrorRecoverable;
1221 else if (m_token.m_type & UnterminatedErrorTokenFlag)
1222 errorType = ParserError::SyntaxErrorUnterminatedLiteral;
1224 if (isEvalNode<ParsedNode>())
1225 error = ParserError(ParserError::EvalError, errorType, m_token, errMsg, errLine);
1227 error = ParserError(ParserError::SyntaxError, errorType, m_token, errMsg, errLine);
1234 template <class ParsedNode>
1235 std::unique_ptr<ParsedNode> parse(
1236 VM* vm, const SourceCode& source, FunctionParameters* parameters,
1237 const Identifier& name, JSParserBuiltinMode builtinMode,
1238 JSParserStrictMode strictMode, JSParserCodeType codeType,
1239 ParserError& error, JSTextPosition* positionBeforeLastNewline = 0,
1240 ConstructorKind defaultConstructorKind = ConstructorKind::None, ThisTDZMode thisTDZMode = ThisTDZMode::CheckIfNeeded)
1242 SamplingRegion samplingRegion("Parsing");
1244 ASSERT(!source.provider()->source().isNull());
1245 if (source.provider()->source().is8Bit()) {
1246 Parser<Lexer<LChar>> parser(vm, source, parameters, name, builtinMode, strictMode, codeType, defaultConstructorKind, thisTDZMode);
1247 std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error);
1248 if (positionBeforeLastNewline)
1249 *positionBeforeLastNewline = parser.positionBeforeLastNewline();
1250 if (builtinMode == JSParserBuiltinMode::Builtin) {
1252 WTF::dataLog("Error compiling builtin: ", error.message(), "\n");
1253 RELEASE_ASSERT(result);
1254 result->setClosedVariables(parser.closedVariables());
1258 ASSERT_WITH_MESSAGE(defaultConstructorKind == ConstructorKind::None, "BuiltinExecutables::createDefaultConstructor should always use a 8-bit string");
1259 Parser<Lexer<UChar>> parser(vm, source, parameters, name, builtinMode, strictMode, codeType, defaultConstructorKind, thisTDZMode);
1260 std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error);
1261 if (positionBeforeLastNewline)
1262 *positionBeforeLastNewline = parser.positionBeforeLastNewline();