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>
47 class FunctionMetadataNode;
48 class FunctionParameters;
54 // Macros to make the more common TreeBuilder types a little less verbose
55 #define TreeStatement typename TreeBuilder::Statement
56 #define TreeExpression typename TreeBuilder::Expression
57 #define TreeFormalParameterList typename TreeBuilder::FormalParameterList
58 #define TreeSourceElements typename TreeBuilder::SourceElements
59 #define TreeClause typename TreeBuilder::Clause
60 #define TreeClauseList typename TreeBuilder::ClauseList
61 #define TreeArguments typename TreeBuilder::Arguments
62 #define TreeArgumentsList typename TreeBuilder::ArgumentsList
63 #define TreeFunctionBody typename TreeBuilder::FunctionBody
64 #define TreeClassExpression typename TreeBuilder::ClassExpression
65 #define TreeProperty typename TreeBuilder::Property
66 #define TreePropertyList typename TreeBuilder::PropertyList
67 #define TreeDestructuringPattern typename TreeBuilder::DestructuringPattern
69 COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
71 enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
72 enum FunctionBodyType { ArrowFunctionBodyExpression, ArrowFunctionBodyBlock, StandardFunctionBodyBlock };
73 enum FunctionRequirements { FunctionNoRequirements, FunctionNeedsName };
75 enum class DestructuringKind {
76 DestructureToVariables,
79 DestructureToCatchParameters,
80 DestructureToParameters,
81 DestructureToExpressions
84 enum class DeclarationType {
90 enum class DeclarationImportType {
96 enum DeclarationResult {
98 InvalidStrictMode = 1 << 0,
99 InvalidDuplicateDeclaration = 1 << 1
102 typedef uint8_t DeclarationResultMask;
105 template <typename T> inline bool isEvalNode() { return false; }
106 template <> inline bool isEvalNode<EvalNode>() { return true; }
108 struct ScopeLabelInfo {
109 UniquedStringImpl* uid;
113 ALWAYS_INLINE static bool isArguments(const VM* vm, const Identifier* ident)
115 return vm->propertyNames->arguments == *ident;
117 ALWAYS_INLINE static bool isEval(const VM* vm, const Identifier* ident)
119 return vm->propertyNames->eval == *ident;
121 ALWAYS_INLINE static bool isEvalOrArgumentsIdentifier(const VM* vm, const Identifier* ident)
123 return isEval(vm, ident) || isArguments(vm, ident);
125 ALWAYS_INLINE static bool isIdentifierOrKeyword(const JSToken& token)
127 return token.m_type == IDENT || token.m_type & KeywordTokenFlag;
130 class ModuleScopeData : public RefCounted<ModuleScopeData> {
132 static Ref<ModuleScopeData> create() { return adoptRef(*new ModuleScopeData); }
134 const IdentifierSet& exportedBindings() const { return m_exportedBindings; }
136 bool exportName(const Identifier& exportedName)
138 return m_exportedNames.add(exportedName.impl()).isNewEntry;
141 void exportBinding(const Identifier& localName)
143 m_exportedBindings.add(localName.impl());
147 IdentifierSet m_exportedNames { };
148 IdentifierSet m_exportedBindings { };
152 WTF_MAKE_NONCOPYABLE(Scope);
155 Scope(const VM* vm, bool isFunction, bool isGenerator, bool strictMode, bool isArrowFunction)
157 , m_shadowsArguments(false)
159 , m_needsFullActivation(false)
160 , m_hasDirectSuper(false)
161 , m_needsSuperBinding(false)
162 , m_allowsVarDeclarations(true)
163 , m_allowsLexicalDeclarations(true)
164 , m_strictMode(strictMode)
165 , m_isFunction(isFunction)
166 , m_isGenerator(isGenerator)
167 , m_isGeneratorBoundary(false)
168 , m_isArrowFunction(isArrowFunction)
169 , m_isArrowFunctionBoundary(false)
170 , m_isLexicalScope(false)
171 , m_isFunctionBoundary(false)
172 , m_isValidStrictMode(true)
173 , m_hasArguments(false)
174 , m_isEvalContext(false)
175 , m_evalContextType(EvalContextType::None)
176 , m_constructorKind(static_cast<unsigned>(ConstructorKind::None))
177 , m_expectedSuperBinding(static_cast<unsigned>(SuperBinding::NotNeeded))
180 , m_innerArrowFunctionFeatures(0)
182 m_usedVariables.append(UniquedStringImplPtrSet());
187 , m_shadowsArguments(other.m_shadowsArguments)
188 , m_usesEval(other.m_usesEval)
189 , m_needsFullActivation(other.m_needsFullActivation)
190 , m_hasDirectSuper(other.m_hasDirectSuper)
191 , m_needsSuperBinding(other.m_needsSuperBinding)
192 , m_allowsVarDeclarations(other.m_allowsVarDeclarations)
193 , m_allowsLexicalDeclarations(other.m_allowsLexicalDeclarations)
194 , m_strictMode(other.m_strictMode)
195 , m_isFunction(other.m_isFunction)
196 , m_isGenerator(other.m_isGenerator)
197 , m_isGeneratorBoundary(other.m_isGeneratorBoundary)
198 , m_isArrowFunction(other.m_isArrowFunction)
199 , m_isArrowFunctionBoundary(other.m_isArrowFunctionBoundary)
200 , m_isLexicalScope(other.m_isLexicalScope)
201 , m_isFunctionBoundary(other.m_isFunctionBoundary)
202 , m_isValidStrictMode(other.m_isValidStrictMode)
203 , m_hasArguments(other.m_hasArguments)
204 , m_isEvalContext(other.m_isEvalContext)
205 , m_constructorKind(other.m_constructorKind)
206 , m_expectedSuperBinding(other.m_expectedSuperBinding)
207 , m_loopDepth(other.m_loopDepth)
208 , m_switchDepth(other.m_switchDepth)
209 , m_innerArrowFunctionFeatures(other.m_innerArrowFunctionFeatures)
210 , m_labels(WTFMove(other.m_labels))
211 , m_declaredParameters(WTFMove(other.m_declaredParameters))
212 , m_declaredVariables(WTFMove(other.m_declaredVariables))
213 , m_lexicalVariables(WTFMove(other.m_lexicalVariables))
214 , m_usedVariables(WTFMove(other.m_usedVariables))
215 , m_closedVariableCandidates(WTFMove(other.m_closedVariableCandidates))
216 , m_moduleScopeData(WTFMove(other.m_moduleScopeData))
217 , m_functionDeclarations(WTFMove(other.m_functionDeclarations))
221 void startSwitch() { m_switchDepth++; }
222 void endSwitch() { m_switchDepth--; }
223 void startLoop() { m_loopDepth++; }
224 void endLoop() { ASSERT(m_loopDepth); m_loopDepth--; }
225 bool inLoop() { return !!m_loopDepth; }
226 bool breakIsValid() { return m_loopDepth || m_switchDepth; }
227 bool continueIsValid() { return m_loopDepth; }
229 void pushLabel(const Identifier* label, bool isLoop)
232 m_labels = std::make_unique<LabelStack>();
233 m_labels->append(ScopeLabelInfo { label->impl(), isLoop });
239 ASSERT(m_labels->size());
240 m_labels->removeLast();
243 ScopeLabelInfo* getLabel(const Identifier* label)
247 for (int i = m_labels->size(); i > 0; i--) {
248 if (m_labels->at(i - 1).uid == label->impl())
249 return &m_labels->at(i - 1);
254 void setSourceParseMode(SourceParseMode mode)
257 case SourceParseMode::GeneratorBodyMode:
261 case SourceParseMode::GeneratorWrapperFunctionMode:
262 setIsGeneratorFunction();
265 case SourceParseMode::NormalFunctionMode:
266 case SourceParseMode::GetterMode:
267 case SourceParseMode::SetterMode:
268 case SourceParseMode::MethodMode:
272 case SourceParseMode::ArrowFunctionMode:
273 setIsArrowFunction();
276 case SourceParseMode::ProgramMode:
279 case SourceParseMode::ModuleAnalyzeMode:
280 case SourceParseMode::ModuleEvaluateMode:
286 bool isFunction() const { return m_isFunction; }
287 bool isFunctionBoundary() const { return m_isFunctionBoundary; }
288 bool isGenerator() const { return m_isGenerator; }
289 bool isGeneratorBoundary() const { return m_isGeneratorBoundary; }
291 bool hasArguments() const { return m_hasArguments; }
293 void setIsLexicalScope()
295 m_isLexicalScope = true;
296 m_allowsLexicalDeclarations = true;
298 bool isLexicalScope() { return m_isLexicalScope; }
300 const IdentifierSet& closedVariableCandidates() const { return m_closedVariableCandidates; }
301 VariableEnvironment& declaredVariables() { return m_declaredVariables; }
302 VariableEnvironment& lexicalVariables() { return m_lexicalVariables; }
303 VariableEnvironment& finalizeLexicalEnvironment()
305 if (m_usesEval || m_needsFullActivation)
306 m_lexicalVariables.markAllVariablesAsCaptured();
308 computeLexicallyCapturedVariablesAndPurgeCandidates();
310 return m_lexicalVariables;
313 ModuleScopeData& moduleScopeData() const
315 ASSERT(m_moduleScopeData);
316 return *m_moduleScopeData;
319 void computeLexicallyCapturedVariablesAndPurgeCandidates()
321 // Because variables may be defined at any time in the range of a lexical scope, we must
322 // track lexical variables that might be captured. Then, when we're preparing to pop the top
323 // lexical scope off the stack, we should find which variables are truly captured, and which
324 // variable still may be captured in a parent scope.
325 if (m_lexicalVariables.size() && m_closedVariableCandidates.size()) {
326 auto end = m_closedVariableCandidates.end();
327 for (auto iter = m_closedVariableCandidates.begin(); iter != end; ++iter)
328 m_lexicalVariables.markVariableAsCapturedIfDefined(iter->get());
331 // We can now purge values from the captured candidates because they're captured in this scope.
333 for (auto entry : m_lexicalVariables) {
334 if (entry.value.isCaptured())
335 m_closedVariableCandidates.remove(entry.key);
340 DeclarationResultMask declareCallee(const Identifier* ident)
342 auto addResult = m_declaredVariables.add(ident->impl());
343 // We want to track if callee is captured, but we don't want to act like it's a 'var'
344 // because that would cause the BytecodeGenerator to emit bad code.
345 addResult.iterator->value.clearIsVar();
347 DeclarationResultMask result = DeclarationResult::Valid;
348 if (isEvalOrArgumentsIdentifier(m_vm, ident))
349 result |= DeclarationResult::InvalidStrictMode;
353 DeclarationResultMask declareVariable(const Identifier* ident)
355 ASSERT(m_allowsVarDeclarations);
356 DeclarationResultMask result = DeclarationResult::Valid;
357 bool isValidStrictMode = !isEvalOrArgumentsIdentifier(m_vm, ident);
358 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
359 auto addResult = m_declaredVariables.add(ident->impl());
360 addResult.iterator->value.setIsVar();
361 if (!isValidStrictMode)
362 result |= DeclarationResult::InvalidStrictMode;
363 if (m_lexicalVariables.contains(ident->impl()))
364 result |= DeclarationResult::InvalidDuplicateDeclaration;
368 DeclarationResultMask declareFunction(const Identifier* ident, bool declareAsVar, bool isSloppyModeHoistingCandidate)
370 ASSERT(m_allowsVarDeclarations || m_allowsLexicalDeclarations);
371 DeclarationResultMask result = DeclarationResult::Valid;
372 bool isValidStrictMode = !isEvalOrArgumentsIdentifier(m_vm, ident);
373 if (!isValidStrictMode)
374 result |= DeclarationResult::InvalidStrictMode;
375 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
376 auto addResult = declareAsVar ? m_declaredVariables.add(ident->impl()) : m_lexicalVariables.add(ident->impl());
377 if (isSloppyModeHoistingCandidate)
378 addResult.iterator->value.setIsSloppyModeHoistingCandidate();
380 addResult.iterator->value.setIsVar();
381 if (m_lexicalVariables.contains(ident->impl()))
382 result |= DeclarationResult::InvalidDuplicateDeclaration;
384 addResult.iterator->value.setIsLet();
385 ASSERT_WITH_MESSAGE(!m_declaredVariables.size(), "We should only declare a function as a lexically scoped variable in scopes where var declarations aren't allowed. I.e, in strict mode and not at the top-level scope of a function or program.");
386 if (!addResult.isNewEntry) {
387 if (!isSloppyModeHoistingCandidate || !addResult.iterator->value.isFunction())
388 result |= DeclarationResult::InvalidDuplicateDeclaration;
392 addResult.iterator->value.setIsFunction();
397 void addSloppyModeHoistableFunctionCandidate(const Identifier* ident)
399 ASSERT(m_allowsVarDeclarations);
400 m_sloppyModeHoistableFunctionCandidates.add(ident->impl());
403 void appendFunction(FunctionMetadataNode* node)
406 m_functionDeclarations.append(node);
408 DeclarationStacks::FunctionStack&& takeFunctionDeclarations() { return WTFMove(m_functionDeclarations); }
411 DeclarationResultMask declareLexicalVariable(const Identifier* ident, bool isConstant, DeclarationImportType importType = DeclarationImportType::NotImported)
413 ASSERT(m_allowsLexicalDeclarations);
414 DeclarationResultMask result = DeclarationResult::Valid;
415 bool isValidStrictMode = !isEvalOrArgumentsIdentifier(m_vm, ident);
416 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
417 auto addResult = m_lexicalVariables.add(ident->impl());
419 addResult.iterator->value.setIsConst();
421 addResult.iterator->value.setIsLet();
423 if (importType == DeclarationImportType::Imported)
424 addResult.iterator->value.setIsImported();
425 else if (importType == DeclarationImportType::ImportedNamespace) {
426 addResult.iterator->value.setIsImported();
427 addResult.iterator->value.setIsImportedNamespace();
430 if (!addResult.isNewEntry)
431 result |= DeclarationResult::InvalidDuplicateDeclaration;
432 if (!isValidStrictMode)
433 result |= DeclarationResult::InvalidStrictMode;
438 bool hasDeclaredVariable(const Identifier& ident)
440 return hasDeclaredVariable(ident.impl());
443 bool hasDeclaredVariable(const RefPtr<UniquedStringImpl>& ident)
445 auto iter = m_declaredVariables.find(ident.get());
446 if (iter == m_declaredVariables.end())
448 VariableEnvironmentEntry entry = iter->value;
449 return entry.isVar(); // The callee isn't a "var".
452 bool hasLexicallyDeclaredVariable(const RefPtr<UniquedStringImpl>& ident) const
454 return m_lexicalVariables.contains(ident.get());
457 ALWAYS_INLINE bool hasDeclaredParameter(const Identifier& ident)
459 return hasDeclaredParameter(ident.impl());
462 bool hasDeclaredParameter(const RefPtr<UniquedStringImpl>& ident)
464 return m_declaredParameters.contains(ident.get()) || hasDeclaredVariable(ident);
467 void preventAllVariableDeclarations()
469 m_allowsVarDeclarations = false;
470 m_allowsLexicalDeclarations = false;
472 void preventVarDeclarations() { m_allowsVarDeclarations = false; }
473 bool allowsVarDeclarations() const { return m_allowsVarDeclarations; }
474 bool allowsLexicalDeclarations() const { return m_allowsLexicalDeclarations; }
476 DeclarationResultMask declareParameter(const Identifier* ident)
478 ASSERT(m_allowsVarDeclarations);
479 DeclarationResultMask result = DeclarationResult::Valid;
480 bool isArgumentsIdent = isArguments(m_vm, ident);
481 auto addResult = m_declaredVariables.add(ident->impl());
482 addResult.iterator->value.clearIsVar();
483 addResult.iterator->value.setIsParameter();
484 bool isValidStrictMode = addResult.isNewEntry && m_vm->propertyNames->eval != *ident && !isArgumentsIdent;
485 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
486 m_declaredParameters.add(ident->impl());
487 if (!isValidStrictMode)
488 result |= DeclarationResult::InvalidStrictMode;
489 if (isArgumentsIdent)
490 m_shadowsArguments = true;
491 if (!addResult.isNewEntry)
492 result |= DeclarationResult::InvalidDuplicateDeclaration;
497 bool usedVariablesContains(UniquedStringImpl* impl) const
499 for (const UniquedStringImplPtrSet& set : m_usedVariables) {
500 if (set.contains(impl))
505 void useVariable(const Identifier* ident, bool isEval)
507 useVariable(ident->impl(), isEval);
509 void useVariable(UniquedStringImpl* impl, bool isEval)
511 m_usesEval |= isEval;
512 m_usedVariables.last().add(impl);
515 void pushUsedVariableSet() { m_usedVariables.append(UniquedStringImplPtrSet()); }
516 size_t currentUsedVariablesSize() { return m_usedVariables.size(); }
518 void revertToPreviousUsedVariables(size_t size) { m_usedVariables.resize(size); }
520 void setNeedsFullActivation() { m_needsFullActivation = true; }
521 bool needsFullActivation() const { return m_needsFullActivation; }
522 bool isArrowFunctionBoundary() { return m_isArrowFunctionBoundary; }
523 bool isArrowFunction() { return m_isArrowFunction; }
525 bool hasDirectSuper() { return m_hasDirectSuper; }
526 void setHasDirectSuper() { m_hasDirectSuper = true; }
528 bool needsSuperBinding() { return m_needsSuperBinding; }
529 void setNeedsSuperBinding() { m_needsSuperBinding = true; }
531 void setEvalContextType(EvalContextType evalContextType) { m_evalContextType = evalContextType; }
532 EvalContextType evalContextType() { return m_evalContextType; }
534 InnerArrowFunctionCodeFeatures innerArrowFunctionFeatures() { return m_innerArrowFunctionFeatures; }
536 void setExpectedSuperBinding(SuperBinding superBinding) { m_expectedSuperBinding = static_cast<unsigned>(superBinding); }
537 SuperBinding expectedSuperBinding() const { return static_cast<SuperBinding>(m_expectedSuperBinding); }
538 void setConstructorKind(ConstructorKind constructorKind) { m_constructorKind = static_cast<unsigned>(constructorKind); }
539 ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); }
541 void setInnerArrowFunctionUsesSuperCall() { m_innerArrowFunctionFeatures |= SuperCallInnerArrowFunctionFeature; }
542 void setInnerArrowFunctionUsesSuperProperty() { m_innerArrowFunctionFeatures |= SuperPropertyInnerArrowFunctionFeature; }
543 void setInnerArrowFunctionUsesEval() { m_innerArrowFunctionFeatures |= EvalInnerArrowFunctionFeature; }
544 void setInnerArrowFunctionUsesThis() { m_innerArrowFunctionFeatures |= ThisInnerArrowFunctionFeature; }
545 void setInnerArrowFunctionUsesNewTarget() { m_innerArrowFunctionFeatures |= NewTargetInnerArrowFunctionFeature; }
546 void setInnerArrowFunctionUsesArguments() { m_innerArrowFunctionFeatures |= ArgumentsInnerArrowFunctionFeature; }
548 bool isEvalContext() const { return m_isEvalContext; }
549 void setIsEvalContext(bool isEvalContext) { m_isEvalContext = isEvalContext; }
551 void setInnerArrowFunctionUsesEvalAndUseArgumentsIfNeeded()
553 ASSERT(m_isArrowFunction);
556 setInnerArrowFunctionUsesEval();
558 if (usedVariablesContains(m_vm->propertyNames->arguments.impl()))
559 setInnerArrowFunctionUsesArguments();
562 void collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
564 if (nestedScope->m_usesEval)
568 UniquedStringImplPtrSet& destinationSet = m_usedVariables.last();
569 for (const UniquedStringImplPtrSet& usedVariablesSet : nestedScope->m_usedVariables) {
570 for (UniquedStringImpl* impl : usedVariablesSet) {
571 if (nestedScope->m_declaredVariables.contains(impl) || nestedScope->m_lexicalVariables.contains(impl))
574 // "arguments" reference should be resolved at function boudary.
575 if (nestedScope->isFunctionBoundary() && nestedScope->hasArguments() && impl == m_vm->propertyNames->arguments.impl() && !nestedScope->isArrowFunctionBoundary())
578 destinationSet.add(impl);
579 // We don't want a declared variable that is used in an inner scope to be thought of as captured if
580 // that inner scope is both a lexical scope and not a function. Only inner functions and "catch"
581 // statements can cause variables to be captured.
582 if (shouldTrackClosedVariables && (nestedScope->m_isFunctionBoundary || !nestedScope->m_isLexicalScope))
583 m_closedVariableCandidates.add(impl);
587 // Propagate closed variable candidates downwards within the same function.
588 // Cross function captures will be realized via m_usedVariables propagation.
589 if (shouldTrackClosedVariables && !nestedScope->m_isFunctionBoundary && nestedScope->m_closedVariableCandidates.size()) {
590 IdentifierSet::iterator end = nestedScope->m_closedVariableCandidates.end();
591 IdentifierSet::iterator begin = nestedScope->m_closedVariableCandidates.begin();
592 m_closedVariableCandidates.add(begin, end);
596 void mergeInnerArrowFunctionFeatures(InnerArrowFunctionCodeFeatures arrowFunctionCodeFeatures)
598 m_innerArrowFunctionFeatures = m_innerArrowFunctionFeatures | arrowFunctionCodeFeatures;
601 void getSloppyModeHoistedFunctions(UniquedStringImplPtrSet& sloppyModeHoistedFunctions)
603 for (UniquedStringImpl* function : m_sloppyModeHoistableFunctionCandidates) {
604 // ES6 Annex B.3.3. The only time we can't hoist a function is if a syntax error would
605 // be caused by declaring a var with that function's name or if we have a parameter with
606 // that function's name. Note that we would only cause a syntax error if we had a let/const/class
607 // variable with the same name.
608 if (!m_lexicalVariables.contains(function)) {
609 auto iter = m_declaredVariables.find(function);
610 bool isParameter = iter != m_declaredVariables.end() && iter->value.isParameter();
612 auto addResult = m_declaredVariables.add(function);
613 addResult.iterator->value.setIsVar();
614 sloppyModeHoistedFunctions.add(function);
620 void getCapturedVars(IdentifierSet& capturedVariables)
622 if (m_needsFullActivation || m_usesEval) {
623 for (auto& entry : m_declaredVariables)
624 capturedVariables.add(entry.key);
627 for (IdentifierSet::iterator ptr = m_closedVariableCandidates.begin(); ptr != m_closedVariableCandidates.end(); ++ptr) {
628 // We refer to m_declaredVariables here directly instead of a hasDeclaredVariable because we want to mark the callee as captured.
629 if (!m_declaredVariables.contains(*ptr))
631 capturedVariables.add(*ptr);
634 void setStrictMode() { m_strictMode = true; }
635 bool strictMode() const { return m_strictMode; }
636 bool isValidStrictMode() const { return m_isValidStrictMode; }
637 bool shadowsArguments() const { return m_shadowsArguments; }
639 void copyCapturedVariablesToVector(const UniquedStringImplPtrSet& capturedVariables, Vector<RefPtr<UniquedStringImpl>>& vector)
641 for (UniquedStringImpl* impl : capturedVariables) {
642 if (m_declaredVariables.contains(impl) || m_lexicalVariables.contains(impl))
648 void fillParametersForSourceProviderCache(SourceProviderCacheItemCreationParameters& parameters)
650 ASSERT(m_isFunction);
651 parameters.usesEval = m_usesEval;
652 parameters.strictMode = m_strictMode;
653 parameters.needsFullActivation = m_needsFullActivation;
654 parameters.innerArrowFunctionFeatures = m_innerArrowFunctionFeatures;
655 for (const UniquedStringImplPtrSet& set : m_usedVariables)
656 copyCapturedVariablesToVector(set, parameters.usedVariables);
659 void restoreFromSourceProviderCache(const SourceProviderCacheItem* info)
661 ASSERT(m_isFunction);
662 m_usesEval = info->usesEval;
663 m_strictMode = info->strictMode;
664 m_innerArrowFunctionFeatures = info->innerArrowFunctionFeatures;
665 m_needsFullActivation = info->needsFullActivation;
666 UniquedStringImplPtrSet& destSet = m_usedVariables.last();
667 for (unsigned i = 0; i < info->usedVariablesCount; ++i)
668 destSet.add(info->usedVariables()[i]);
675 m_isFunctionBoundary = true;
676 m_hasArguments = true;
678 m_isGenerator = false;
679 m_isGeneratorBoundary = false;
680 m_isArrowFunctionBoundary = false;
681 m_isArrowFunction = false;
684 void setIsGeneratorFunction()
687 m_isGenerator = true;
690 void setIsGenerator()
693 m_isGenerator = true;
694 m_isGeneratorBoundary = true;
695 m_hasArguments = false;
698 void setIsArrowFunction()
701 m_isArrowFunctionBoundary = true;
702 m_isArrowFunction = true;
707 m_moduleScopeData = ModuleScopeData::create();
711 bool m_shadowsArguments;
713 bool m_needsFullActivation;
714 bool m_hasDirectSuper;
715 bool m_needsSuperBinding;
716 bool m_allowsVarDeclarations;
717 bool m_allowsLexicalDeclarations;
721 bool m_isGeneratorBoundary;
722 bool m_isArrowFunction;
723 bool m_isArrowFunctionBoundary;
724 bool m_isLexicalScope;
725 bool m_isFunctionBoundary;
726 bool m_isValidStrictMode;
728 bool m_isEvalContext;
729 EvalContextType m_evalContextType;
730 unsigned m_constructorKind;
731 unsigned m_expectedSuperBinding;
734 InnerArrowFunctionCodeFeatures m_innerArrowFunctionFeatures;
736 typedef Vector<ScopeLabelInfo, 2> LabelStack;
737 std::unique_ptr<LabelStack> m_labels;
738 UniquedStringImplPtrSet m_declaredParameters;
739 VariableEnvironment m_declaredVariables;
740 VariableEnvironment m_lexicalVariables;
741 Vector<UniquedStringImplPtrSet, 6> m_usedVariables;
742 UniquedStringImplPtrSet m_sloppyModeHoistableFunctionCandidates;
743 IdentifierSet m_closedVariableCandidates;
744 RefPtr<ModuleScopeData> m_moduleScopeData;
745 DeclarationStacks::FunctionStack m_functionDeclarations;
748 typedef Vector<Scope, 10> ScopeStack;
751 ScopeRef(ScopeStack* scopeStack, unsigned index)
752 : m_scopeStack(scopeStack)
756 Scope* operator->() { return &m_scopeStack->at(m_index); }
757 unsigned index() const { return m_index; }
759 bool hasContainingScope()
761 return m_index && !m_scopeStack->at(m_index).isFunctionBoundary();
764 ScopeRef containingScope()
766 ASSERT(hasContainingScope());
767 return ScopeRef(m_scopeStack, m_index - 1);
770 bool operator==(const ScopeRef& other)
772 ASSERT(other.m_scopeStack == m_scopeStack);
773 return m_index == other.m_index;
776 bool operator!=(const ScopeRef& other)
778 return !(*this == other);
782 ScopeStack* m_scopeStack;
786 enum class ArgumentType {
791 template <typename LexerType>
793 WTF_MAKE_NONCOPYABLE(Parser);
794 WTF_MAKE_FAST_ALLOCATED;
797 Parser(VM*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, SourceParseMode, SuperBinding, ConstructorKind defaultConstructorKind = ConstructorKind::None, ThisTDZMode = ThisTDZMode::CheckIfNeeded, DerivedContextType = DerivedContextType::None, bool isEvalContext = false, EvalContextType = EvalContextType::None);
800 template <class ParsedNode>
801 std::unique_ptr<ParsedNode> parse(ParserError&, const Identifier&, SourceParseMode);
803 JSTextPosition positionBeforeLastNewline() const { return m_lexer->positionBeforeLastNewline(); }
804 JSTokenLocation locationBeforeLastToken() const { return m_lexer->lastTokenLocation(); }
807 struct AllowInOverride {
808 AllowInOverride(Parser* parser)
810 , m_oldAllowsIn(parser->m_allowsIn)
812 parser->m_allowsIn = true;
816 m_parser->m_allowsIn = m_oldAllowsIn;
822 struct AutoPopScopeRef : public ScopeRef {
823 AutoPopScopeRef(Parser* parser, ScopeRef scope)
832 m_parser->popScope(*this, false);
844 struct AutoCleanupLexicalScope {
845 // We can allocate this object on the stack without actually knowing beforehand if we're
846 // going to create a new lexical scope. If we decide to create a new lexical scope, we
847 // can pass the scope into this obejct and it will take care of the cleanup for us if the parse fails.
848 // This is helpful if we may fail from syntax errors after creating a lexical scope conditionally.
849 AutoCleanupLexicalScope()
850 : m_scope(nullptr, UINT_MAX)
855 ~AutoCleanupLexicalScope()
857 // This should only ever be called if we fail from a syntax error. Otherwise
858 // it's the intention that a user of this class pops this scope manually on a
861 m_parser->popScope(*this, false);
864 void setIsValid(ScopeRef& scope, Parser* parser)
866 RELEASE_ASSERT(scope->isLexicalScope());
871 bool isValid() const { return !!m_parser; }
878 ScopeRef& scope() { return m_scope; }
885 enum ExpressionErrorClass {
886 ErrorIndicatesNothing,
887 ErrorIndicatesPattern
890 struct ExpressionErrorClassifier {
891 ExpressionErrorClassifier(Parser* parser)
892 : m_class(ErrorIndicatesNothing)
893 , m_previous(parser->m_expressionErrorClassifier)
896 m_parser->m_expressionErrorClassifier = this;
899 ~ExpressionErrorClassifier()
901 m_parser->m_expressionErrorClassifier = m_previous;
904 void classifyExpressionError(ExpressionErrorClass classification)
906 if (m_class != ErrorIndicatesNothing)
908 m_class = classification;
911 void reclassifyExpressionError(ExpressionErrorClass oldClassification, ExpressionErrorClass classification)
913 if (m_class != oldClassification)
915 m_class = classification;
918 void propagateExpressionErrorClass()
920 if (m_previous && m_class != ErrorIndicatesNothing)
921 m_previous->m_class = m_class;
924 bool indicatesPossiblePattern() const { return m_class == ErrorIndicatesPattern; }
927 ExpressionErrorClass m_class;
928 ExpressionErrorClassifier* m_previous;
932 ALWAYS_INLINE void classifyExpressionError(ExpressionErrorClass classification)
934 if (m_expressionErrorClassifier)
935 m_expressionErrorClassifier->classifyExpressionError(classification);
938 ALWAYS_INLINE void reclassifyExpressionError(ExpressionErrorClass oldClassification, ExpressionErrorClass classification)
940 if (m_expressionErrorClassifier)
941 m_expressionErrorClassifier->reclassifyExpressionError(oldClassification, classification);
944 ALWAYS_INLINE DestructuringKind destructuringKindFromDeclarationType(DeclarationType type)
947 case DeclarationType::VarDeclaration:
948 return DestructuringKind::DestructureToVariables;
949 case DeclarationType::LetDeclaration:
950 return DestructuringKind::DestructureToLet;
951 case DeclarationType::ConstDeclaration:
952 return DestructuringKind::DestructureToConst;
955 RELEASE_ASSERT_NOT_REACHED();
956 return DestructuringKind::DestructureToVariables;
959 ALWAYS_INLINE AssignmentContext assignmentContextFromDeclarationType(DeclarationType type)
962 case DeclarationType::ConstDeclaration:
963 return AssignmentContext::ConstDeclarationStatement;
965 return AssignmentContext::DeclarationStatement;
969 ALWAYS_INLINE bool isEvalOrArguments(const Identifier* ident) { return isEvalOrArgumentsIdentifier(m_vm, ident); }
971 ScopeRef currentScope()
973 return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
976 ScopeRef currentVariableScope()
978 unsigned i = m_scopeStack.size() - 1;
979 ASSERT(i < m_scopeStack.size());
980 while (!m_scopeStack[i].allowsVarDeclarations()) {
982 ASSERT(i < m_scopeStack.size());
984 return ScopeRef(&m_scopeStack, i);
987 ScopeRef currentLexicalDeclarationScope()
989 unsigned i = m_scopeStack.size() - 1;
990 ASSERT(i < m_scopeStack.size());
991 while (!m_scopeStack[i].allowsLexicalDeclarations()) {
993 ASSERT(i < m_scopeStack.size());
996 return ScopeRef(&m_scopeStack, i);
999 ScopeRef currentFunctionScope()
1001 unsigned i = m_scopeStack.size() - 1;
1002 ASSERT(i < m_scopeStack.size());
1003 while (i && !m_scopeStack[i].isFunctionBoundary()) {
1005 ASSERT(i < m_scopeStack.size());
1007 // When reaching the top level scope (it can be non function scope), we return it.
1008 return ScopeRef(&m_scopeStack, i);
1011 ScopeRef closestParentOrdinaryFunctionNonLexicalScope()
1013 unsigned i = m_scopeStack.size() - 1;
1014 ASSERT(i < m_scopeStack.size() && m_scopeStack.size());
1015 while (i && (!m_scopeStack[i].isFunctionBoundary() || m_scopeStack[i].isGeneratorBoundary() || m_scopeStack[i].isArrowFunctionBoundary()))
1017 return ScopeRef(&m_scopeStack, i);
1020 ScopeRef pushScope()
1022 bool isFunction = false;
1023 bool isStrict = false;
1024 bool isGenerator = false;
1025 bool isArrowFunction = false;
1026 if (!m_scopeStack.isEmpty()) {
1027 isStrict = m_scopeStack.last().strictMode();
1028 isFunction = m_scopeStack.last().isFunction();
1029 isGenerator = m_scopeStack.last().isGenerator();
1030 isArrowFunction = m_scopeStack.last().isArrowFunction();
1032 m_scopeStack.constructAndAppend(m_vm, isFunction, isGenerator, isStrict, isArrowFunction);
1033 return currentScope();
1036 void popScopeInternal(ScopeRef& scope, bool shouldTrackClosedVariables)
1038 ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1);
1039 ASSERT(m_scopeStack.size() > 1);
1040 m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
1042 if (m_scopeStack.last().isArrowFunction())
1043 m_scopeStack.last().setInnerArrowFunctionUsesEvalAndUseArgumentsIfNeeded();
1045 if (!(m_scopeStack.last().isFunctionBoundary() && !m_scopeStack.last().isArrowFunctionBoundary()))
1046 m_scopeStack[m_scopeStack.size() - 2].mergeInnerArrowFunctionFeatures(m_scopeStack.last().innerArrowFunctionFeatures());
1048 if (!m_scopeStack.last().isFunctionBoundary() && m_scopeStack.last().needsFullActivation())
1049 m_scopeStack[m_scopeStack.size() - 2].setNeedsFullActivation();
1050 m_scopeStack.removeLast();
1053 ALWAYS_INLINE void popScope(ScopeRef& scope, bool shouldTrackClosedVariables)
1055 popScopeInternal(scope, shouldTrackClosedVariables);
1058 ALWAYS_INLINE void popScope(AutoPopScopeRef& scope, bool shouldTrackClosedVariables)
1061 popScopeInternal(scope, shouldTrackClosedVariables);
1064 ALWAYS_INLINE void popScope(AutoCleanupLexicalScope& cleanupScope, bool shouldTrackClosedVariables)
1066 RELEASE_ASSERT(cleanupScope.isValid());
1067 ScopeRef& scope = cleanupScope.scope();
1068 cleanupScope.setPopped();
1069 popScopeInternal(scope, shouldTrackClosedVariables);
1072 DeclarationResultMask declareVariable(const Identifier* ident, DeclarationType type = DeclarationType::VarDeclaration, DeclarationImportType importType = DeclarationImportType::NotImported)
1074 if (type == DeclarationType::VarDeclaration)
1075 return currentVariableScope()->declareVariable(ident);
1077 ASSERT(type == DeclarationType::LetDeclaration || type == DeclarationType::ConstDeclaration);
1078 // Lexical variables declared at a top level scope that shadow arguments or vars are not allowed.
1079 if (m_statementDepth == 1 && (hasDeclaredParameter(*ident) || hasDeclaredVariable(*ident)))
1080 return DeclarationResult::InvalidDuplicateDeclaration;
1082 return currentLexicalDeclarationScope()->declareLexicalVariable(ident, type == DeclarationType::ConstDeclaration, importType);
1085 std::pair<DeclarationResultMask, ScopeRef> declareFunction(const Identifier* ident)
1087 if (m_statementDepth == 1 || (!strictMode() && !currentScope()->isFunction())) {
1088 // Functions declared at the top-most scope (both in sloppy and strict mode) are declared as vars
1089 // for backwards compatibility. This allows us to declare functions with the same name more than once.
1090 // In sloppy mode, we always declare functions as vars.
1091 bool declareAsVar = true;
1092 bool isSloppyModeHoistingCandidate = false;
1093 ScopeRef variableScope = currentVariableScope();
1094 return std::make_pair(variableScope->declareFunction(ident, declareAsVar, isSloppyModeHoistingCandidate), variableScope);
1097 if (!strictMode()) {
1098 ASSERT(currentScope()->isFunction());
1100 // Functions declared inside a function inside a nested block scope in sloppy mode are subject to this
1101 // crazy rule defined inside Annex B.3.3 in the ES6 spec. It basically states that we will create
1102 // the function as a local block scoped variable, but when we evaluate the block that the function is
1103 // contained in, we will assign the function to a "var" variable only if declaring such a "var" wouldn't
1104 // be a syntax error and if there isn't a parameter with the same name. (It would only be a syntax error if
1105 // there are is a let/class/const with the same name). Note that this mean we only do the "var" hoisting
1106 // binding if the block evaluates. For example, this means we wont won't perform the binding if it's inside
1107 // the untaken branch of an if statement.
1108 bool declareAsVar = false;
1109 bool isSloppyModeHoistingCandidate = true;
1110 ScopeRef lexicalVariableScope = currentLexicalDeclarationScope();
1111 ScopeRef varScope = currentVariableScope();
1112 varScope->addSloppyModeHoistableFunctionCandidate(ident);
1113 ASSERT(varScope != lexicalVariableScope);
1114 return std::make_pair(lexicalVariableScope->declareFunction(ident, declareAsVar, isSloppyModeHoistingCandidate), lexicalVariableScope);
1117 bool declareAsVar = false;
1118 bool isSloppyModeHoistingCandidate = false;
1119 ScopeRef lexicalVariableScope = currentLexicalDeclarationScope();
1120 return std::make_pair(lexicalVariableScope->declareFunction(ident, declareAsVar, isSloppyModeHoistingCandidate), lexicalVariableScope);
1123 NEVER_INLINE bool hasDeclaredVariable(const Identifier& ident)
1125 unsigned i = m_scopeStack.size() - 1;
1126 ASSERT(i < m_scopeStack.size());
1127 while (!m_scopeStack[i].allowsVarDeclarations()) {
1129 ASSERT(i < m_scopeStack.size());
1131 return m_scopeStack[i].hasDeclaredVariable(ident);
1134 NEVER_INLINE bool hasDeclaredParameter(const Identifier& ident)
1136 unsigned i = m_scopeStack.size() - 1;
1137 ASSERT(i < m_scopeStack.size());
1138 while (!m_scopeStack[i].allowsVarDeclarations()) {
1140 ASSERT(i < m_scopeStack.size());
1142 return m_scopeStack[i].hasDeclaredParameter(ident);
1145 bool exportName(const Identifier& ident)
1147 ASSERT(currentScope().index() == 0);
1148 return currentScope()->moduleScopeData().exportName(ident);
1151 ScopeStack m_scopeStack;
1153 const SourceProviderCacheItem* findCachedFunctionInfo(int openBracePos)
1155 return m_functionCache ? m_functionCache->get(openBracePos) : 0;
1159 String parseInner(const Identifier&, SourceParseMode);
1161 void didFinishParsing(SourceElements*, DeclarationStacks::FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, CodeFeatures, int);
1163 // Used to determine type of error to report.
1164 bool isFunctionMetadataNode(ScopeNode*) { return false; }
1165 bool isFunctionMetadataNode(FunctionMetadataNode*) { return true; }
1167 ALWAYS_INLINE void next(unsigned lexerFlags = 0)
1169 int lastLine = m_token.m_location.line;
1170 int lastTokenEnd = m_token.m_location.endOffset;
1171 int lastTokenLineStart = m_token.m_location.lineStartOffset;
1172 m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
1173 m_lexer->setLastLineNumber(lastLine);
1174 m_token.m_type = m_lexer->lex(&m_token, lexerFlags, strictMode());
1177 ALWAYS_INLINE void nextExpectIdentifier(unsigned lexerFlags = 0)
1179 int lastLine = m_token.m_location.line;
1180 int lastTokenEnd = m_token.m_location.endOffset;
1181 int lastTokenLineStart = m_token.m_location.lineStartOffset;
1182 m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
1183 m_lexer->setLastLineNumber(lastLine);
1184 m_token.m_type = m_lexer->lexExpectIdentifier(&m_token, lexerFlags, strictMode());
1187 ALWAYS_INLINE bool nextTokenIsColon()
1189 return m_lexer->nextTokenIsColon();
1192 ALWAYS_INLINE bool consume(JSTokenType expected, unsigned flags = 0)
1194 bool result = m_token.m_type == expected;
1200 void printUnexpectedTokenText(WTF::PrintStream&);
1201 ALWAYS_INLINE StringView getToken() {
1202 SourceProvider* sourceProvider = m_source->provider();
1203 return sourceProvider->getRange(tokenStart(), tokenEndPosition().offset);
1206 ALWAYS_INLINE bool match(JSTokenType expected)
1208 return m_token.m_type == expected;
1211 ALWAYS_INLINE bool matchContextualKeyword(const Identifier& identifier)
1213 return m_token.m_type == IDENT && *m_token.m_data.ident == identifier;
1216 ALWAYS_INLINE bool matchIdentifierOrKeyword()
1218 return isIdentifierOrKeyword(m_token);
1221 ALWAYS_INLINE unsigned tokenStart()
1223 return m_token.m_location.startOffset;
1226 ALWAYS_INLINE const JSTextPosition& tokenStartPosition()
1228 return m_token.m_startPosition;
1231 ALWAYS_INLINE int tokenLine()
1233 return m_token.m_location.line;
1236 ALWAYS_INLINE int tokenColumn()
1238 return tokenStart() - tokenLineStart();
1241 ALWAYS_INLINE const JSTextPosition& tokenEndPosition()
1243 return m_token.m_endPosition;
1246 ALWAYS_INLINE unsigned tokenLineStart()
1248 return m_token.m_location.lineStartOffset;
1251 ALWAYS_INLINE const JSTokenLocation& tokenLocation()
1253 return m_token.m_location;
1256 void setErrorMessage(const String& message)
1258 m_errorMessage = message;
1261 NEVER_INLINE void logError(bool);
1262 template <typename A> NEVER_INLINE void logError(bool, const A&);
1263 template <typename A, typename B> NEVER_INLINE void logError(bool, const A&, const B&);
1264 template <typename A, typename B, typename C> NEVER_INLINE void logError(bool, const A&, const B&, const C&);
1265 template <typename A, typename B, typename C, typename D> NEVER_INLINE void logError(bool, const A&, const B&, const C&, const D&);
1266 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&);
1267 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&);
1268 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&);
1270 NEVER_INLINE void updateErrorWithNameAndMessage(const char* beforeMessage, const String& name, const char* afterMessage)
1272 m_errorMessage = makeString(beforeMessage, " '", name, "' ", afterMessage);
1275 NEVER_INLINE void updateErrorMessage(const char* msg)
1278 m_errorMessage = String(msg);
1279 ASSERT(!m_errorMessage.isNull());
1282 void startLoop() { currentScope()->startLoop(); }
1283 void endLoop() { currentScope()->endLoop(); }
1284 void startSwitch() { currentScope()->startSwitch(); }
1285 void endSwitch() { currentScope()->endSwitch(); }
1286 void setStrictMode() { currentScope()->setStrictMode(); }
1287 bool strictMode() { return currentScope()->strictMode(); }
1288 bool isValidStrictMode() { return currentScope()->isValidStrictMode(); }
1289 DeclarationResultMask declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
1290 bool declareRestOrNormalParameter(const Identifier&, const Identifier**);
1294 ScopeRef current = currentScope();
1295 while (!current->breakIsValid()) {
1296 if (!current.hasContainingScope())
1298 current = current.containingScope();
1302 bool continueIsValid()
1304 ScopeRef current = currentScope();
1305 while (!current->continueIsValid()) {
1306 if (!current.hasContainingScope())
1308 current = current.containingScope();
1312 void pushLabel(const Identifier* label, bool isLoop) { currentScope()->pushLabel(label, isLoop); }
1313 void popLabel(ScopeRef scope) { scope->popLabel(); }
1314 ScopeLabelInfo* getLabel(const Identifier* label)
1316 ScopeRef current = currentScope();
1317 ScopeLabelInfo* result = 0;
1318 while (!(result = current->getLabel(label))) {
1319 if (!current.hasContainingScope())
1321 current = current.containingScope();
1326 // http://ecma-international.org/ecma-262/6.0/#sec-identifiers-static-semantics-early-errors
1327 ALWAYS_INLINE bool isLETMaskedAsIDENT()
1329 return match(LET) && !strictMode();
1332 // http://ecma-international.org/ecma-262/6.0/#sec-identifiers-static-semantics-early-errors
1333 ALWAYS_INLINE bool isYIELDMaskedAsIDENT(bool inGenerator)
1335 return match(YIELD) && !strictMode() && !inGenerator;
1338 // http://ecma-international.org/ecma-262/6.0/#sec-generator-function-definitions-static-semantics-early-errors
1339 ALWAYS_INLINE bool matchSpecIdentifier(bool inGenerator)
1341 return match(IDENT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(inGenerator);
1344 ALWAYS_INLINE bool matchSpecIdentifier()
1346 return matchSpecIdentifier(currentScope()->isGenerator());
1349 template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode);
1350 template <class TreeBuilder> TreeSourceElements parseGeneratorFunctionSourceElements(TreeBuilder&, SourceElementsMode);
1351 template <class TreeBuilder> TreeStatement parseStatementListItem(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength);
1352 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
1353 enum class ExportType { Exported, NotExported };
1354 template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&, ExportType = ExportType::NotExported);
1355 template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported);
1356 template <class TreeBuilder> TreeStatement parseVariableDeclaration(TreeBuilder&, DeclarationType, ExportType = ExportType::NotExported);
1357 template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&);
1358 template <class TreeBuilder> TreeStatement parseWhileStatement(TreeBuilder&);
1359 template <class TreeBuilder> TreeStatement parseForStatement(TreeBuilder&);
1360 template <class TreeBuilder> TreeStatement parseBreakStatement(TreeBuilder&);
1361 template <class TreeBuilder> TreeStatement parseContinueStatement(TreeBuilder&);
1362 template <class TreeBuilder> TreeStatement parseReturnStatement(TreeBuilder&);
1363 template <class TreeBuilder> TreeStatement parseThrowStatement(TreeBuilder&);
1364 template <class TreeBuilder> TreeStatement parseWithStatement(TreeBuilder&);
1365 template <class TreeBuilder> TreeStatement parseSwitchStatement(TreeBuilder&);
1366 template <class TreeBuilder> TreeClauseList parseSwitchClauses(TreeBuilder&);
1367 template <class TreeBuilder> TreeClause parseSwitchDefaultClause(TreeBuilder&);
1368 template <class TreeBuilder> TreeStatement parseTryStatement(TreeBuilder&);
1369 template <class TreeBuilder> TreeStatement parseDebuggerStatement(TreeBuilder&);
1370 template <class TreeBuilder> TreeStatement parseExpressionStatement(TreeBuilder&);
1371 template <class TreeBuilder> TreeStatement parseExpressionOrLabelStatement(TreeBuilder&, bool allowFunctionDeclarationAsStatement);
1372 template <class TreeBuilder> TreeStatement parseIfStatement(TreeBuilder&);
1373 template <class TreeBuilder> TreeStatement parseBlockStatement(TreeBuilder&);
1374 template <class TreeBuilder> TreeExpression parseExpression(TreeBuilder&);
1375 template <class TreeBuilder> TreeExpression parseAssignmentExpression(TreeBuilder&, ExpressionErrorClassifier&);
1376 template <class TreeBuilder> TreeExpression parseAssignmentExpression(TreeBuilder&);
1377 template <class TreeBuilder> TreeExpression parseAssignmentExpressionOrPropagateErrorClass(TreeBuilder&);
1378 template <class TreeBuilder> TreeExpression parseYieldExpression(TreeBuilder&);
1379 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseConditionalExpression(TreeBuilder&);
1380 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseBinaryExpression(TreeBuilder&);
1381 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseUnaryExpression(TreeBuilder&);
1382 template <class TreeBuilder> TreeExpression parseMemberExpression(TreeBuilder&);
1383 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parsePrimaryExpression(TreeBuilder&);
1384 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArrayLiteral(TreeBuilder&);
1385 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseObjectLiteral(TreeBuilder&);
1386 template <class TreeBuilder> NEVER_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&);
1387 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseFunctionExpression(TreeBuilder&);
1388 template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&);
1389 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArgument(TreeBuilder&, ArgumentType&);
1390 template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict);
1391 template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, bool isGenerator);
1392 template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind = ConstructorKind::None, SuperBinding = SuperBinding::NotNeeded);
1393 template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, const JSTokenLocation&, int, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, SuperBinding, FunctionBodyType, unsigned, SourceParseMode);
1394 template <class TreeBuilder> ALWAYS_INLINE bool parseFormalParameters(TreeBuilder&, TreeFormalParameterList, unsigned&);
1395 enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext };
1396 template <class TreeBuilder> TreeExpression parseVariableDeclarationList(TreeBuilder&, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext, DeclarationType, ExportType, bool& forLoopConstDoesNotHaveInitializer);
1397 template <class TreeBuilder> TreeSourceElements parseArrowFunctionSingleExpressionBodySourceElements(TreeBuilder&);
1398 template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&);
1399 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier&, JSToken, AssignmentContext, const Identifier** duplicateIdentifier);
1400 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createAssignmentElement(TreeBuilder&, TreeExpression&, const JSTextPosition&, const JSTextPosition&);
1401 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseBindingOrAssignmentElement(TreeBuilder& context, DestructuringKind, ExportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth);
1402 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseAssignmentElement(TreeBuilder& context, DestructuringKind, ExportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth);
1403 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseDestructuringPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier** duplicateIdentifier = nullptr, bool* hasDestructuringPattern = nullptr, AssignmentContext = AssignmentContext::DeclarationStatement, int depth = 0);
1404 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern tryParseDestructuringPatternExpression(TreeBuilder&, AssignmentContext);
1405 template <class TreeBuilder> NEVER_INLINE TreeExpression parseDefaultValueForDestructuringPattern(TreeBuilder&);
1406 template <class TreeBuilder> TreeSourceElements parseModuleSourceElements(TreeBuilder&, SourceParseMode);
1407 enum class ImportSpecifierType { NamespaceImport, NamedImport, DefaultImport };
1408 template <class TreeBuilder> typename TreeBuilder::ImportSpecifier parseImportClauseItem(TreeBuilder&, ImportSpecifierType);
1409 template <class TreeBuilder> typename TreeBuilder::ModuleName parseModuleName(TreeBuilder&);
1410 template <class TreeBuilder> TreeStatement parseImportDeclaration(TreeBuilder&);
1411 template <class TreeBuilder> typename TreeBuilder::ExportSpecifier parseExportSpecifier(TreeBuilder& context, Vector<const Identifier*>& maybeLocalNames, bool& hasKeywordForLocalBindings);
1412 template <class TreeBuilder> TreeStatement parseExportDeclaration(TreeBuilder&);
1414 enum class FunctionDefinitionType { Expression, Declaration, Method };
1415 template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionRequirements, SourceParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&, FunctionDefinitionType);
1417 ALWAYS_INLINE bool isArrowFunctionParameters();
1419 template <class TreeBuilder> NEVER_INLINE int parseFunctionParameters(TreeBuilder&, SourceParseMode, ParserFunctionInfo<TreeBuilder>&);
1420 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::FormalParameterList createGeneratorParameters(TreeBuilder&);
1422 template <class TreeBuilder> NEVER_INLINE TreeClassExpression parseClass(TreeBuilder&, FunctionRequirements, ParserClassInfo<TreeBuilder>&);
1424 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::TemplateString parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode, bool& elementIsTail);
1425 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::TemplateLiteral parseTemplateLiteral(TreeBuilder&, typename LexerType::RawStringsBuildMode);
1427 template <class TreeBuilder> ALWAYS_INLINE bool shouldCheckPropertyForUnderscoreProtoDuplicate(TreeBuilder&, const TreeProperty&);
1429 ALWAYS_INLINE int isBinaryOperator(JSTokenType);
1430 bool allowAutomaticSemicolon();
1432 bool autoSemiColon()
1434 if (m_token.m_type == SEMICOLON) {
1438 return allowAutomaticSemicolon();
1443 return m_vm->isSafeToRecurse();
1446 const JSTextPosition& lastTokenEndPosition() const
1448 return m_lastTokenEndPosition;
1451 bool hasError() const
1453 return !m_errorMessage.isNull();
1456 enum class FunctionParsePhase { Parameters, Body };
1457 struct ParserState {
1458 int assignmentCount { 0 };
1459 int nonLHSCount { 0 };
1460 int nonTrivialExpressionCount { 0 };
1461 FunctionParsePhase functionParsePhase { FunctionParsePhase::Body };
1462 const Identifier* lastIdentifier { nullptr };
1463 const Identifier* lastFunctionName { nullptr };
1466 // If you're using this directly, you probably should be using
1467 // createSavePoint() instead.
1468 ALWAYS_INLINE ParserState internalSaveParserState()
1470 return m_parserState;
1473 ALWAYS_INLINE void restoreParserState(const ParserState& state)
1475 m_parserState = state;
1480 unsigned oldLineStartOffset;
1481 unsigned oldLastLineNumber;
1482 unsigned oldLineNumber;
1485 // If you're using this directly, you probably should be using
1486 // createSavePoint() instead.
1487 // i.e, if you parse any kind of AssignmentExpression between
1488 // saving/restoring, you should definitely not be using this directly.
1489 ALWAYS_INLINE LexerState internalSaveLexerState()
1492 result.startOffset = m_token.m_location.startOffset;
1493 result.oldLineStartOffset = m_token.m_location.lineStartOffset;
1494 result.oldLastLineNumber = m_lexer->lastLineNumber();
1495 result.oldLineNumber = m_lexer->lineNumber();
1499 ALWAYS_INLINE void restoreLexerState(const LexerState& lexerState)
1501 m_lexer->setOffset(lexerState.startOffset, lexerState.oldLineStartOffset);
1503 m_lexer->setLastLineNumber(lexerState.oldLastLineNumber);
1504 m_lexer->setLineNumber(lexerState.oldLineNumber);
1508 ParserState parserState;
1509 LexerState lexerState;
1512 ALWAYS_INLINE SavePoint createSavePointForError()
1515 result.parserState = internalSaveParserState();
1516 result.lexerState = internalSaveLexerState();
1520 ALWAYS_INLINE SavePoint createSavePoint()
1522 ASSERT(!hasError());
1523 return createSavePointForError();
1526 ALWAYS_INLINE void restoreSavePointWithError(const SavePoint& savePoint, const String& message)
1528 m_errorMessage = message;
1529 restoreLexerState(savePoint.lexerState);
1530 restoreParserState(savePoint.parserState);
1533 ALWAYS_INLINE void restoreSavePoint(const SavePoint& savePoint)
1535 restoreSavePointWithError(savePoint, String());
1539 const SourceCode* m_source;
1540 ParserArena m_parserArena;
1541 std::unique_ptr<LexerType> m_lexer;
1542 FunctionParameters* m_parameters { nullptr };
1544 ParserState m_parserState;
1546 bool m_hasStackOverflow;
1547 String m_errorMessage;
1550 JSTextPosition m_lastTokenEndPosition;
1551 bool m_syntaxAlreadyValidated;
1552 int m_statementDepth;
1553 RefPtr<SourceProviderCache> m_functionCache;
1554 SourceElements* m_sourceElements;
1555 bool m_parsingBuiltin;
1556 SuperBinding m_superBinding;
1557 ConstructorKind m_defaultConstructorKind;
1558 ThisTDZMode m_thisTDZMode;
1559 VariableEnvironment m_varDeclarations;
1560 DeclarationStacks::FunctionStack m_funcDeclarations;
1561 UniquedStringImplPtrSet m_sloppyModeHoistedFunctions;
1562 CodeFeatures m_features;
1564 ExpressionErrorClassifier* m_expressionErrorClassifier;
1565 bool m_isEvalContext;
1566 bool m_immediateParentAllowsFunctionDeclarationInStatement;
1568 struct DepthManager {
1569 DepthManager(int* depth)
1570 : m_originalDepth(*depth)
1577 *m_depth = m_originalDepth;
1581 int m_originalDepth;
1587 template <typename LexerType>
1588 template <class ParsedNode>
1589 std::unique_ptr<ParsedNode> Parser<LexerType>::parse(ParserError& error, const Identifier& calleeName, SourceParseMode parseMode)
1594 if (ParsedNode::scopeIsFunction)
1595 m_lexer->setIsReparsingFunction();
1597 m_sourceElements = 0;
1602 JSTokenLocation startLocation(tokenLocation());
1603 ASSERT(m_source->startColumn() > 0);
1604 unsigned startColumn = m_source->startColumn() - 1;
1606 String parseError = parseInner(calleeName, parseMode);
1608 int lineNumber = m_lexer->lineNumber();
1609 bool lexError = m_lexer->sawError();
1610 String lexErrorMessage = lexError ? m_lexer->getErrorMessage() : String();
1611 ASSERT(lexErrorMessage.isNull() != lexError);
1614 if (!parseError.isNull() || lexError) {
1615 errLine = lineNumber;
1616 errMsg = !lexErrorMessage.isNull() ? lexErrorMessage : parseError;
1617 m_sourceElements = 0;
1620 std::unique_ptr<ParsedNode> result;
1621 if (m_sourceElements) {
1622 JSTokenLocation endLocation;
1623 endLocation.line = m_lexer->lineNumber();
1624 endLocation.lineStartOffset = m_lexer->currentLineStartOffset();
1625 endLocation.startOffset = m_lexer->currentOffset();
1626 unsigned endColumn = endLocation.startOffset - endLocation.lineStartOffset;
1627 result = std::make_unique<ParsedNode>(m_parserArena,
1634 WTFMove(m_funcDeclarations),
1635 currentScope()->finalizeLexicalEnvironment(),
1636 WTFMove(m_sloppyModeHoistedFunctions),
1640 currentScope()->innerArrowFunctionFeatures(),
1642 result->setLoc(m_source->firstLine(), m_lexer->lineNumber(), m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
1643 result->setEndOffset(m_lexer->currentOffset());
1645 if (!isFunctionParseMode(parseMode)) {
1646 m_source->provider()->setSourceURLDirective(m_lexer->sourceURL());
1647 m_source->provider()->setSourceMappingURLDirective(m_lexer->sourceMappingURL());
1650 // We can never see a syntax error when reparsing a function, since we should have
1651 // reported the error when parsing the containing program or eval code. So if we're
1652 // parsing a function body node, we assume that what actually happened here is that
1653 // we ran out of stack while parsing. If we see an error while parsing eval or program
1654 // code we assume that it was a syntax error since running out of stack is much less
1655 // likely, and we are currently unable to distinguish between the two cases.
1656 if (isFunctionMetadataNode(static_cast<ParsedNode*>(0)) || m_hasStackOverflow)
1657 error = ParserError(ParserError::StackOverflow, ParserError::SyntaxErrorNone, m_token);
1659 ParserError::SyntaxErrorType errorType = ParserError::SyntaxErrorIrrecoverable;
1660 if (m_token.m_type == EOFTOK)
1661 errorType = ParserError::SyntaxErrorRecoverable;
1662 else if (m_token.m_type & UnterminatedErrorTokenFlag) {
1663 // Treat multiline capable unterminated literals as recoverable.
1664 if (m_token.m_type == UNTERMINATED_MULTILINE_COMMENT_ERRORTOK || m_token.m_type == UNTERMINATED_TEMPLATE_LITERAL_ERRORTOK)
1665 errorType = ParserError::SyntaxErrorRecoverable;
1667 errorType = ParserError::SyntaxErrorUnterminatedLiteral;
1670 if (isEvalNode<ParsedNode>())
1671 error = ParserError(ParserError::EvalError, errorType, m_token, errMsg, errLine);
1673 error = ParserError(ParserError::SyntaxError, errorType, m_token, errMsg, errLine);
1680 template <class ParsedNode>
1681 std::unique_ptr<ParsedNode> parse(
1682 VM* vm, const SourceCode& source,
1683 const Identifier& name, JSParserBuiltinMode builtinMode,
1684 JSParserStrictMode strictMode, SourceParseMode parseMode, SuperBinding superBinding,
1685 ParserError& error, JSTextPosition* positionBeforeLastNewline = nullptr,
1686 ConstructorKind defaultConstructorKind = ConstructorKind::None, ThisTDZMode thisTDZMode = ThisTDZMode::CheckIfNeeded,
1687 DerivedContextType derivedContextType = DerivedContextType::None, EvalContextType evalContextType = EvalContextType::None)
1689 ASSERT(!source.provider()->source().isNull());
1690 if (source.provider()->source().is8Bit()) {
1691 Parser<Lexer<LChar>> parser(vm, source, builtinMode, strictMode, parseMode, superBinding, defaultConstructorKind, thisTDZMode, derivedContextType, isEvalNode<ParsedNode>(), evalContextType);
1692 std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, name, parseMode);
1693 if (positionBeforeLastNewline)
1694 *positionBeforeLastNewline = parser.positionBeforeLastNewline();
1695 if (builtinMode == JSParserBuiltinMode::Builtin) {
1697 WTF::dataLog("Error compiling builtin: ", error.message(), "\n");
1701 ASSERT_WITH_MESSAGE(defaultConstructorKind == ConstructorKind::None, "BuiltinExecutables::createDefaultConstructor should always use a 8-bit string");
1702 Parser<Lexer<UChar>> parser(vm, source, builtinMode, strictMode, parseMode, superBinding, defaultConstructorKind, thisTDZMode, derivedContextType, isEvalNode<ParsedNode>(), evalContextType);
1703 std::unique_ptr<ParsedNode> result = parser.parse<ParsedNode>(error, name, parseMode);
1704 if (positionBeforeLastNewline)
1705 *positionBeforeLastNewline = parser.positionBeforeLastNewline();