1/*
2 * Copyright (C) 1999-2001 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2013 Apple Inc. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 *
21 */
22
23#pragma once
24
25#include "ExecutableInfo.h"
26#include "Lexer.h"
27#include "ModuleScopeData.h"
28#include "Nodes.h"
29#include "ParseHash.h"
30#include "ParserArena.h"
31#include "ParserError.h"
32#include "ParserFunctionInfo.h"
33#include "ParserTokens.h"
34#include "SourceProvider.h"
35#include "SourceProviderCache.h"
36#include "SourceProviderCacheItem.h"
37#include "VariableEnvironment.h"
38#include <wtf/Forward.h>
39#include <wtf/Noncopyable.h>
40#include <wtf/RefPtr.h>
41
42namespace JSC {
43
44class FunctionMetadataNode;
45class FunctionParameters;
46class Identifier;
47class VM;
48class SourceCode;
49class SyntaxChecker;
50struct DebuggerParseData;
51
52// Macros to make the more common TreeBuilder types a little less verbose
53#define TreeStatement typename TreeBuilder::Statement
54#define TreeExpression typename TreeBuilder::Expression
55#define TreeFormalParameterList typename TreeBuilder::FormalParameterList
56#define TreeSourceElements typename TreeBuilder::SourceElements
57#define TreeClause typename TreeBuilder::Clause
58#define TreeClauseList typename TreeBuilder::ClauseList
59#define TreeArguments typename TreeBuilder::Arguments
60#define TreeArgumentsList typename TreeBuilder::ArgumentsList
61#define TreeFunctionBody typename TreeBuilder::FunctionBody
62#define TreeClassExpression typename TreeBuilder::ClassExpression
63#define TreeProperty typename TreeBuilder::Property
64#define TreePropertyList typename TreeBuilder::PropertyList
65#define TreeDestructuringPattern typename TreeBuilder::DestructuringPattern
66
67COMPILE_ASSERT(LastUntaggedToken < 64, LessThan64UntaggedTokens);
68
69enum SourceElementsMode { CheckForStrictMode, DontCheckForStrictMode };
70enum FunctionBodyType { ArrowFunctionBodyExpression, ArrowFunctionBodyBlock, StandardFunctionBodyBlock };
71enum class FunctionNameRequirements { None, Named, Unnamed };
72
73enum class DestructuringKind {
74 DestructureToVariables,
75 DestructureToLet,
76 DestructureToConst,
77 DestructureToCatchParameters,
78 DestructureToParameters,
79 DestructureToExpressions
80};
81
82enum class DeclarationType {
83 VarDeclaration,
84 LetDeclaration,
85 ConstDeclaration
86};
87
88enum class DeclarationImportType {
89 Imported,
90 ImportedNamespace,
91 NotImported
92};
93
94enum DeclarationResult {
95 Valid = 0,
96 InvalidStrictMode = 1 << 0,
97 InvalidDuplicateDeclaration = 1 << 1
98};
99
100typedef uint8_t DeclarationResultMask;
101
102enum class DeclarationDefaultContext {
103 Standard,
104 ExportDefault,
105};
106
107enum class InferName {
108 Allowed,
109 Disallowed,
110};
111
112template <typename T> inline bool isEvalNode() { return false; }
113template <> inline bool isEvalNode<EvalNode>() { return true; }
114
115struct ScopeLabelInfo {
116 UniquedStringImpl* uid;
117 bool isLoop;
118};
119
120ALWAYS_INLINE static bool isArguments(const VM* vm, const Identifier* ident)
121{
122 return vm->propertyNames->arguments == *ident;
123}
124ALWAYS_INLINE static bool isEval(const VM* vm, const Identifier* ident)
125{
126 return vm->propertyNames->eval == *ident;
127}
128ALWAYS_INLINE static bool isEvalOrArgumentsIdentifier(const VM* vm, const Identifier* ident)
129{
130 return isEval(vm, ident) || isArguments(vm, ident);
131}
132ALWAYS_INLINE static bool isIdentifierOrKeyword(const JSToken& token)
133{
134 return token.m_type == IDENT || token.m_type & KeywordTokenFlag;
135}
136// _Any_ContextualKeyword includes keywords such as "let" or "yield", which have a specific meaning depending on the current parse mode
137// or strict mode. These helpers allow to treat all contextual keywords as identifiers as required.
138ALWAYS_INLINE static bool isAnyContextualKeyword(const JSToken& token)
139{
140 return token.m_type >= FirstContextualKeywordToken && token.m_type <= LastContextualKeywordToken;
141}
142ALWAYS_INLINE static bool isIdentifierOrAnyContextualKeyword(const JSToken& token)
143{
144 return token.m_type == IDENT || isAnyContextualKeyword(token);
145}
146// _Safe_ContextualKeyword includes only contextual keywords which can be treated as identifiers independently from parse mode. The exeption
147// to this rule is `await`, but matchSpecIdentifier() always treats it as an identifier regardless.
148ALWAYS_INLINE static bool isSafeContextualKeyword(const JSToken& token)
149{
150 return token.m_type >= FirstSafeContextualKeywordToken && token.m_type <= LastSafeContextualKeywordToken;
151}
152
153struct Scope {
154 WTF_MAKE_NONCOPYABLE(Scope);
155
156public:
157 Scope(const VM* vm, bool isFunction, bool isGenerator, bool strictMode, bool isArrowFunction, bool isAsyncFunction)
158 : m_vm(vm)
159 , m_shadowsArguments(false)
160 , m_usesEval(false)
161 , m_needsFullActivation(false)
162 , m_hasDirectSuper(false)
163 , m_needsSuperBinding(false)
164 , m_allowsVarDeclarations(true)
165 , m_allowsLexicalDeclarations(true)
166 , m_strictMode(strictMode)
167 , m_isFunction(isFunction)
168 , m_isGenerator(isGenerator)
169 , m_isGeneratorBoundary(false)
170 , m_isArrowFunction(isArrowFunction)
171 , m_isArrowFunctionBoundary(false)
172 , m_isAsyncFunction(isAsyncFunction)
173 , m_isAsyncFunctionBoundary(false)
174 , m_isLexicalScope(false)
175 , m_isGlobalCodeScope(false)
176 , m_isSimpleCatchParameterScope(false)
177 , m_isFunctionBoundary(false)
178 , m_isValidStrictMode(true)
179 , m_hasArguments(false)
180 , m_isEvalContext(false)
181 , m_hasNonSimpleParameterList(false)
182 , m_evalContextType(EvalContextType::None)
183 , m_constructorKind(static_cast<unsigned>(ConstructorKind::None))
184 , m_expectedSuperBinding(static_cast<unsigned>(SuperBinding::NotNeeded))
185 , m_loopDepth(0)
186 , m_switchDepth(0)
187 , m_innerArrowFunctionFeatures(0)
188 {
189 m_usedVariables.append(UniquedStringImplPtrSet());
190 }
191
192 Scope(Scope&&) = default;
193
194 void startSwitch() { m_switchDepth++; }
195 void endSwitch() { m_switchDepth--; }
196 void startLoop() { m_loopDepth++; }
197 void endLoop() { ASSERT(m_loopDepth); m_loopDepth--; }
198 bool inLoop() { return !!m_loopDepth; }
199 bool breakIsValid() { return m_loopDepth || m_switchDepth; }
200 bool continueIsValid() { return m_loopDepth; }
201
202 void pushLabel(const Identifier* label, bool isLoop)
203 {
204 if (!m_labels)
205 m_labels = std::make_unique<LabelStack>();
206 m_labels->append(ScopeLabelInfo { label->impl(), isLoop });
207 }
208
209 void popLabel()
210 {
211 ASSERT(m_labels);
212 ASSERT(m_labels->size());
213 m_labels->removeLast();
214 }
215
216 ScopeLabelInfo* getLabel(const Identifier* label)
217 {
218 if (!m_labels)
219 return 0;
220 for (int i = m_labels->size(); i > 0; i--) {
221 if (m_labels->at(i - 1).uid == label->impl())
222 return &m_labels->at(i - 1);
223 }
224 return 0;
225 }
226
227 void setSourceParseMode(SourceParseMode mode)
228 {
229 switch (mode) {
230 case SourceParseMode::AsyncGeneratorBodyMode:
231 setIsAsyncGeneratorFunctionBody();
232 break;
233 case SourceParseMode::AsyncArrowFunctionBodyMode:
234 setIsAsyncArrowFunctionBody();
235 break;
236
237 case SourceParseMode::AsyncFunctionBodyMode:
238 setIsAsyncFunctionBody();
239 break;
240
241 case SourceParseMode::GeneratorBodyMode:
242 setIsGenerator();
243 break;
244
245 case SourceParseMode::GeneratorWrapperFunctionMode:
246 case SourceParseMode::GeneratorWrapperMethodMode:
247 setIsGeneratorFunction();
248 break;
249
250 case SourceParseMode::AsyncGeneratorWrapperMethodMode:
251 case SourceParseMode::AsyncGeneratorWrapperFunctionMode:
252 setIsAsyncGeneratorFunction();
253 break;
254
255 case SourceParseMode::NormalFunctionMode:
256 case SourceParseMode::GetterMode:
257 case SourceParseMode::SetterMode:
258 case SourceParseMode::MethodMode:
259 setIsFunction();
260 break;
261
262 case SourceParseMode::ArrowFunctionMode:
263 setIsArrowFunction();
264 break;
265
266 case SourceParseMode::AsyncFunctionMode:
267 case SourceParseMode::AsyncMethodMode:
268 setIsAsyncFunction();
269 break;
270
271 case SourceParseMode::AsyncArrowFunctionMode:
272 setIsAsyncArrowFunction();
273 break;
274
275 case SourceParseMode::ProgramMode:
276 case SourceParseMode::ModuleAnalyzeMode:
277 case SourceParseMode::ModuleEvaluateMode:
278 break;
279 }
280 }
281
282 bool isFunction() const { return m_isFunction; }
283 bool isFunctionBoundary() const { return m_isFunctionBoundary; }
284 bool isGenerator() const { return m_isGenerator; }
285 bool isGeneratorBoundary() const { return m_isGeneratorBoundary; }
286 bool isAsyncFunction() const { return m_isAsyncFunction; }
287 bool isAsyncFunctionBoundary() const { return m_isAsyncFunctionBoundary; }
288
289 bool hasArguments() const { return m_hasArguments; }
290
291 void setIsGlobalCodeScope() { m_isGlobalCodeScope = true; }
292 bool isGlobalCodeScope() const { return m_isGlobalCodeScope; }
293
294 void setIsSimpleCatchParameterScope() { m_isSimpleCatchParameterScope = true; }
295 bool isSimpleCatchParameterScope() { return m_isSimpleCatchParameterScope; }
296
297 void setIsLexicalScope()
298 {
299 m_isLexicalScope = true;
300 m_allowsLexicalDeclarations = true;
301 }
302 bool isLexicalScope() { return m_isLexicalScope; }
303 bool usesEval() { return m_usesEval; }
304
305 const HashSet<UniquedStringImpl*>& closedVariableCandidates() const { return m_closedVariableCandidates; }
306 VariableEnvironment& declaredVariables() { return m_declaredVariables; }
307 VariableEnvironment& lexicalVariables() { return m_lexicalVariables; }
308 VariableEnvironment& finalizeLexicalEnvironment()
309 {
310 if (m_usesEval || m_needsFullActivation)
311 m_lexicalVariables.markAllVariablesAsCaptured();
312 else
313 computeLexicallyCapturedVariablesAndPurgeCandidates();
314
315 return m_lexicalVariables;
316 }
317
318 void computeLexicallyCapturedVariablesAndPurgeCandidates()
319 {
320 // Because variables may be defined at any time in the range of a lexical scope, we must
321 // track lexical variables that might be captured. Then, when we're preparing to pop the top
322 // lexical scope off the stack, we should find which variables are truly captured, and which
323 // variable still may be captured in a parent scope.
324 if (m_lexicalVariables.size() && m_closedVariableCandidates.size()) {
325 for (UniquedStringImpl* impl : m_closedVariableCandidates)
326 m_lexicalVariables.markVariableAsCapturedIfDefined(impl);
327 }
328
329 // We can now purge values from the captured candidates because they're captured in this scope.
330 {
331 for (auto entry : m_lexicalVariables) {
332 if (entry.value.isCaptured())
333 m_closedVariableCandidates.remove(entry.key.get());
334 }
335 }
336 }
337
338 DeclarationResultMask declareCallee(const Identifier* ident)
339 {
340 auto addResult = m_declaredVariables.add(ident->impl());
341 // We want to track if callee is captured, but we don't want to act like it's a 'var'
342 // because that would cause the BytecodeGenerator to emit bad code.
343 addResult.iterator->value.clearIsVar();
344
345 DeclarationResultMask result = DeclarationResult::Valid;
346 if (isEvalOrArgumentsIdentifier(m_vm, ident))
347 result |= DeclarationResult::InvalidStrictMode;
348 return result;
349 }
350
351 DeclarationResultMask declareVariable(const Identifier* ident)
352 {
353 ASSERT(m_allowsVarDeclarations);
354 DeclarationResultMask result = DeclarationResult::Valid;
355 bool isValidStrictMode = !isEvalOrArgumentsIdentifier(m_vm, ident);
356 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
357 auto addResult = m_declaredVariables.add(ident->impl());
358 addResult.iterator->value.setIsVar();
359 if (!isValidStrictMode)
360 result |= DeclarationResult::InvalidStrictMode;
361 return result;
362 }
363
364 DeclarationResultMask declareFunction(const Identifier* ident, bool declareAsVar, bool isSloppyModeHoistingCandidate)
365 {
366 ASSERT(m_allowsVarDeclarations || m_allowsLexicalDeclarations);
367 DeclarationResultMask result = DeclarationResult::Valid;
368 bool isValidStrictMode = !isEvalOrArgumentsIdentifier(m_vm, ident);
369 if (!isValidStrictMode)
370 result |= DeclarationResult::InvalidStrictMode;
371 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
372 auto addResult = declareAsVar ? m_declaredVariables.add(ident->impl()) : m_lexicalVariables.add(ident->impl());
373 if (isSloppyModeHoistingCandidate)
374 addResult.iterator->value.setIsSloppyModeHoistingCandidate();
375 if (declareAsVar) {
376 addResult.iterator->value.setIsVar();
377 if (m_lexicalVariables.contains(ident->impl()))
378 result |= DeclarationResult::InvalidDuplicateDeclaration;
379 } else {
380 addResult.iterator->value.setIsLet();
381 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.");
382 if (!addResult.isNewEntry) {
383 if (!isSloppyModeHoistingCandidate || !addResult.iterator->value.isFunction())
384 result |= DeclarationResult::InvalidDuplicateDeclaration;
385 }
386 }
387
388 addResult.iterator->value.setIsFunction();
389
390 return result;
391 }
392
393 void addVariableBeingHoisted(const Identifier* ident)
394 {
395 ASSERT(!m_allowsVarDeclarations);
396 m_variablesBeingHoisted.add(ident->impl());
397 }
398
399 void addSloppyModeHoistableFunctionCandidate(const Identifier* ident)
400 {
401 ASSERT(m_allowsVarDeclarations);
402 m_sloppyModeHoistableFunctionCandidates.add(ident->impl());
403 }
404
405 void appendFunction(FunctionMetadataNode* node)
406 {
407 ASSERT(node);
408 m_functionDeclarations.append(node);
409 }
410 DeclarationStacks::FunctionStack&& takeFunctionDeclarations() { return WTFMove(m_functionDeclarations); }
411
412
413 DeclarationResultMask declareLexicalVariable(const Identifier* ident, bool isConstant, DeclarationImportType importType = DeclarationImportType::NotImported)
414 {
415 ASSERT(m_allowsLexicalDeclarations);
416 DeclarationResultMask result = DeclarationResult::Valid;
417 bool isValidStrictMode = !isEvalOrArgumentsIdentifier(m_vm, ident);
418 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
419 auto addResult = m_lexicalVariables.add(ident->impl());
420 if (isConstant)
421 addResult.iterator->value.setIsConst();
422 else
423 addResult.iterator->value.setIsLet();
424
425 if (importType == DeclarationImportType::Imported)
426 addResult.iterator->value.setIsImported();
427 else if (importType == DeclarationImportType::ImportedNamespace) {
428 addResult.iterator->value.setIsImported();
429 addResult.iterator->value.setIsImportedNamespace();
430 }
431
432 if (!addResult.isNewEntry || m_variablesBeingHoisted.contains(ident->impl()))
433 result |= DeclarationResult::InvalidDuplicateDeclaration;
434 if (!isValidStrictMode)
435 result |= DeclarationResult::InvalidStrictMode;
436
437 return result;
438 }
439
440 ALWAYS_INLINE bool hasDeclaredVariable(const Identifier& ident)
441 {
442 return hasDeclaredVariable(ident.impl());
443 }
444
445 bool hasDeclaredVariable(const RefPtr<UniquedStringImpl>& ident)
446 {
447 auto iter = m_declaredVariables.find(ident.get());
448 if (iter == m_declaredVariables.end())
449 return false;
450 VariableEnvironmentEntry entry = iter->value;
451 return entry.isVar(); // The callee isn't a "var".
452 }
453
454 ALWAYS_INLINE bool hasLexicallyDeclaredVariable(const Identifier& ident)
455 {
456 return hasLexicallyDeclaredVariable(ident.impl());
457 }
458
459 bool hasLexicallyDeclaredVariable(const RefPtr<UniquedStringImpl>& ident) const
460 {
461 return m_lexicalVariables.contains(ident.get());
462 }
463
464 ALWAYS_INLINE bool hasDeclaredParameter(const Identifier& ident)
465 {
466 return hasDeclaredParameter(ident.impl());
467 }
468
469 bool hasDeclaredParameter(const RefPtr<UniquedStringImpl>& ident)
470 {
471 return m_declaredParameters.contains(ident.get()) || hasDeclaredVariable(ident);
472 }
473
474 void preventAllVariableDeclarations()
475 {
476 m_allowsVarDeclarations = false;
477 m_allowsLexicalDeclarations = false;
478 }
479 void preventVarDeclarations() { m_allowsVarDeclarations = false; }
480 bool allowsVarDeclarations() const { return m_allowsVarDeclarations; }
481 bool allowsLexicalDeclarations() const { return m_allowsLexicalDeclarations; }
482
483 DeclarationResultMask declareParameter(const Identifier* ident)
484 {
485 ASSERT(m_allowsVarDeclarations);
486 DeclarationResultMask result = DeclarationResult::Valid;
487 bool isArgumentsIdent = isArguments(m_vm, ident);
488 auto addResult = m_declaredVariables.add(ident->impl());
489 bool isValidStrictMode = (addResult.isNewEntry || !addResult.iterator->value.isParameter())
490 && m_vm->propertyNames->eval != *ident && !isArgumentsIdent;
491 addResult.iterator->value.clearIsVar();
492 addResult.iterator->value.setIsParameter();
493 m_isValidStrictMode = m_isValidStrictMode && isValidStrictMode;
494 m_declaredParameters.add(ident->impl());
495 if (!isValidStrictMode)
496 result |= DeclarationResult::InvalidStrictMode;
497 if (isArgumentsIdent)
498 m_shadowsArguments = true;
499 if (!addResult.isNewEntry)
500 result |= DeclarationResult::InvalidDuplicateDeclaration;
501
502 return result;
503 }
504
505 bool usedVariablesContains(UniquedStringImpl* impl) const
506 {
507 for (const UniquedStringImplPtrSet& set : m_usedVariables) {
508 if (set.contains(impl))
509 return true;
510 }
511 return false;
512 }
513 template <typename Func>
514 void forEachUsedVariable(const Func& func)
515 {
516 for (const UniquedStringImplPtrSet& set : m_usedVariables) {
517 for (UniquedStringImpl* impl : set)
518 func(impl);
519 }
520 }
521 void useVariable(const Identifier* ident, bool isEval)
522 {
523 useVariable(ident->impl(), isEval);
524 }
525 void useVariable(UniquedStringImpl* impl, bool isEval)
526 {
527 m_usesEval |= isEval;
528 m_usedVariables.last().add(impl);
529 }
530
531 void pushUsedVariableSet() { m_usedVariables.append(UniquedStringImplPtrSet()); }
532 size_t currentUsedVariablesSize() { return m_usedVariables.size(); }
533
534 void revertToPreviousUsedVariables(size_t size) { m_usedVariables.resize(size); }
535
536 void setNeedsFullActivation() { m_needsFullActivation = true; }
537 bool needsFullActivation() const { return m_needsFullActivation; }
538 bool isArrowFunctionBoundary() { return m_isArrowFunctionBoundary; }
539 bool isArrowFunction() { return m_isArrowFunction; }
540
541 bool hasDirectSuper() const { return m_hasDirectSuper; }
542 bool setHasDirectSuper() { return std::exchange(m_hasDirectSuper, true); }
543
544 bool needsSuperBinding() const { return m_needsSuperBinding; }
545 bool setNeedsSuperBinding() { return std::exchange(m_needsSuperBinding, true); }
546
547 void setEvalContextType(EvalContextType evalContextType) { m_evalContextType = evalContextType; }
548 EvalContextType evalContextType() { return m_evalContextType; }
549
550 InnerArrowFunctionCodeFeatures innerArrowFunctionFeatures() { return m_innerArrowFunctionFeatures; }
551
552 void setExpectedSuperBinding(SuperBinding superBinding) { m_expectedSuperBinding = static_cast<unsigned>(superBinding); }
553 SuperBinding expectedSuperBinding() const { return static_cast<SuperBinding>(m_expectedSuperBinding); }
554 void setConstructorKind(ConstructorKind constructorKind) { m_constructorKind = static_cast<unsigned>(constructorKind); }
555 ConstructorKind constructorKind() const { return static_cast<ConstructorKind>(m_constructorKind); }
556
557 void setInnerArrowFunctionUsesSuperCall() { m_innerArrowFunctionFeatures |= SuperCallInnerArrowFunctionFeature; }
558 void setInnerArrowFunctionUsesSuperProperty() { m_innerArrowFunctionFeatures |= SuperPropertyInnerArrowFunctionFeature; }
559 void setInnerArrowFunctionUsesEval() { m_innerArrowFunctionFeatures |= EvalInnerArrowFunctionFeature; }
560 void setInnerArrowFunctionUsesThis() { m_innerArrowFunctionFeatures |= ThisInnerArrowFunctionFeature; }
561 void setInnerArrowFunctionUsesNewTarget() { m_innerArrowFunctionFeatures |= NewTargetInnerArrowFunctionFeature; }
562 void setInnerArrowFunctionUsesArguments() { m_innerArrowFunctionFeatures |= ArgumentsInnerArrowFunctionFeature; }
563
564 bool isEvalContext() const { return m_isEvalContext; }
565 void setIsEvalContext(bool isEvalContext) { m_isEvalContext = isEvalContext; }
566
567 void setInnerArrowFunctionUsesEvalAndUseArgumentsIfNeeded()
568 {
569 ASSERT(m_isArrowFunction);
570
571 if (m_usesEval)
572 setInnerArrowFunctionUsesEval();
573
574 if (usedVariablesContains(m_vm->propertyNames->arguments.impl()))
575 setInnerArrowFunctionUsesArguments();
576 }
577
578 void addClosedVariableCandidateUnconditionally(UniquedStringImpl* impl)
579 {
580 m_closedVariableCandidates.add(impl);
581 }
582
583 void collectFreeVariables(Scope* nestedScope, bool shouldTrackClosedVariables)
584 {
585 if (nestedScope->m_usesEval)
586 m_usesEval = true;
587
588 {
589 UniquedStringImplPtrSet& destinationSet = m_usedVariables.last();
590 for (const UniquedStringImplPtrSet& usedVariablesSet : nestedScope->m_usedVariables) {
591 for (UniquedStringImpl* impl : usedVariablesSet) {
592 if (nestedScope->m_declaredVariables.contains(impl) || nestedScope->m_lexicalVariables.contains(impl))
593 continue;
594
595 // "arguments" reference should be resolved at function boudary.
596 if (nestedScope->isFunctionBoundary() && nestedScope->hasArguments() && impl == m_vm->propertyNames->arguments.impl() && !nestedScope->isArrowFunctionBoundary())
597 continue;
598
599 destinationSet.add(impl);
600 // We don't want a declared variable that is used in an inner scope to be thought of as captured if
601 // that inner scope is both a lexical scope and not a function. Only inner functions and "catch"
602 // statements can cause variables to be captured.
603 if (shouldTrackClosedVariables && (nestedScope->m_isFunctionBoundary || !nestedScope->m_isLexicalScope))
604 m_closedVariableCandidates.add(impl);
605 }
606 }
607 }
608 // Propagate closed variable candidates downwards within the same function.
609 // Cross function captures will be realized via m_usedVariables propagation.
610 if (shouldTrackClosedVariables && !nestedScope->m_isFunctionBoundary && nestedScope->m_closedVariableCandidates.size()) {
611 auto end = nestedScope->m_closedVariableCandidates.end();
612 auto begin = nestedScope->m_closedVariableCandidates.begin();
613 m_closedVariableCandidates.add(begin, end);
614 }
615 }
616
617 void mergeInnerArrowFunctionFeatures(InnerArrowFunctionCodeFeatures arrowFunctionCodeFeatures)
618 {
619 m_innerArrowFunctionFeatures = m_innerArrowFunctionFeatures | arrowFunctionCodeFeatures;
620 }
621
622 void getSloppyModeHoistedFunctions(UniquedStringImplPtrSet& sloppyModeHoistedFunctions)
623 {
624 for (UniquedStringImpl* function : m_sloppyModeHoistableFunctionCandidates) {
625 // ES6 Annex B.3.3. The only time we can't hoist a function is if a syntax error would
626 // be caused by declaring a var with that function's name or if we have a parameter with
627 // that function's name. Note that we would only cause a syntax error if we had a let/const/class
628 // variable with the same name.
629 if (!m_lexicalVariables.contains(function)) {
630 auto iter = m_declaredVariables.find(function);
631 bool isParameter = iter != m_declaredVariables.end() && iter->value.isParameter();
632 if (!isParameter) {
633 auto addResult = m_declaredVariables.add(function);
634 addResult.iterator->value.setIsVar();
635 addResult.iterator->value.setIsSloppyModeHoistingCandidate();
636 sloppyModeHoistedFunctions.add(function);
637 }
638 }
639 }
640 }
641
642 void getCapturedVars(IdentifierSet& capturedVariables)
643 {
644 if (m_needsFullActivation || m_usesEval) {
645 for (auto& entry : m_declaredVariables)
646 capturedVariables.add(entry.key);
647 return;
648 }
649 for (UniquedStringImpl* impl : m_closedVariableCandidates) {
650 // We refer to m_declaredVariables here directly instead of a hasDeclaredVariable because we want to mark the callee as captured.
651 if (!m_declaredVariables.contains(impl))
652 continue;
653 capturedVariables.add(impl);
654 }
655 }
656 void setStrictMode() { m_strictMode = true; }
657 bool strictMode() const { return m_strictMode; }
658 bool isValidStrictMode() const { return m_isValidStrictMode; }
659 bool shadowsArguments() const { return m_shadowsArguments; }
660 void setHasNonSimpleParameterList()
661 {
662 m_isValidStrictMode = false;
663 m_hasNonSimpleParameterList = true;
664 }
665 bool hasNonSimpleParameterList() const { return m_hasNonSimpleParameterList; }
666
667 void copyCapturedVariablesToVector(const UniquedStringImplPtrSet& usedVariables, Vector<UniquedStringImpl*, 8>& vector)
668 {
669 for (UniquedStringImpl* impl : usedVariables) {
670 if (m_declaredVariables.contains(impl) || m_lexicalVariables.contains(impl))
671 continue;
672 vector.append(impl);
673 }
674 }
675
676 void fillParametersForSourceProviderCache(SourceProviderCacheItemCreationParameters& parameters, const UniquedStringImplPtrSet& capturesFromParameterExpressions)
677 {
678 ASSERT(m_isFunction);
679 parameters.usesEval = m_usesEval;
680 parameters.strictMode = m_strictMode;
681 parameters.needsFullActivation = m_needsFullActivation;
682 parameters.innerArrowFunctionFeatures = m_innerArrowFunctionFeatures;
683 parameters.needsSuperBinding = m_needsSuperBinding;
684 for (const UniquedStringImplPtrSet& set : m_usedVariables)
685 copyCapturedVariablesToVector(set, parameters.usedVariables);
686
687 // FIXME: https://bugs.webkit.org/show_bug.cgi?id=156962
688 // We add these unconditionally because we currently don't keep a separate
689 // declaration scope for a function's parameters and its var/let/const declarations.
690 // This is somewhat unfortunate and we should refactor to do this at some point
691 // because parameters logically form a parent scope to var/let/const variables.
692 // But because we don't do this, we must grab capture candidates from a parameter
693 // list before we parse the body of a function because the body's declarations
694 // might make us believe something isn't actually a capture candidate when it really
695 // is.
696 for (UniquedStringImpl* impl : capturesFromParameterExpressions)
697 parameters.usedVariables.append(impl);
698 }
699
700 void restoreFromSourceProviderCache(const SourceProviderCacheItem* info)
701 {
702 ASSERT(m_isFunction);
703 m_usesEval = info->usesEval;
704 m_strictMode = info->strictMode;
705 m_innerArrowFunctionFeatures = info->innerArrowFunctionFeatures;
706 m_needsFullActivation = info->needsFullActivation;
707 m_needsSuperBinding = info->needsSuperBinding;
708 UniquedStringImplPtrSet& destSet = m_usedVariables.last();
709 for (unsigned i = 0; i < info->usedVariablesCount; ++i)
710 destSet.add(info->usedVariables()[i]);
711 }
712
713 class MaybeParseAsGeneratorForScope;
714
715private:
716 void setIsFunction()
717 {
718 m_isFunction = true;
719 m_isFunctionBoundary = true;
720 m_hasArguments = true;
721 setIsLexicalScope();
722 m_isGenerator = false;
723 m_isGeneratorBoundary = false;
724 m_isArrowFunctionBoundary = false;
725 m_isArrowFunction = false;
726 m_isAsyncFunction = false;
727 m_isAsyncFunctionBoundary = false;
728 }
729
730 void setIsGeneratorFunction()
731 {
732 setIsFunction();
733 m_isGenerator = true;
734 }
735
736 void setIsGenerator()
737 {
738 setIsFunction();
739 m_isGenerator = true;
740 m_isGeneratorBoundary = true;
741 m_hasArguments = false;
742 }
743
744 void setIsArrowFunction()
745 {
746 setIsFunction();
747 m_isArrowFunctionBoundary = true;
748 m_isArrowFunction = true;
749 }
750
751 void setIsAsyncArrowFunction()
752 {
753 setIsArrowFunction();
754 m_isAsyncFunction = true;
755 }
756
757 void setIsAsyncFunction()
758 {
759 setIsFunction();
760 m_isAsyncFunction = true;
761 }
762
763 void setIsAsyncGeneratorFunction()
764 {
765 setIsFunction();
766 m_isAsyncFunction = true;
767 m_isGenerator = true;
768 }
769
770 void setIsAsyncGeneratorFunctionBody()
771 {
772 setIsFunction();
773 m_hasArguments = false;
774 m_isGenerator = true;
775 m_isGeneratorBoundary = true;
776 m_isAsyncFunction = true;
777 m_isAsyncFunctionBoundary = true;
778 }
779
780 void setIsAsyncFunctionBody()
781 {
782 setIsFunction();
783 m_hasArguments = false;
784 m_isAsyncFunction = true;
785 m_isAsyncFunctionBoundary = true;
786 }
787
788 void setIsAsyncArrowFunctionBody()
789 {
790 setIsArrowFunction();
791 m_hasArguments = false;
792 m_isAsyncFunction = true;
793 m_isAsyncFunctionBoundary = true;
794 }
795
796 const VM* m_vm;
797 bool m_shadowsArguments;
798 bool m_usesEval;
799 bool m_needsFullActivation;
800 bool m_hasDirectSuper;
801 bool m_needsSuperBinding;
802 bool m_allowsVarDeclarations;
803 bool m_allowsLexicalDeclarations;
804 bool m_strictMode;
805 bool m_isFunction;
806 bool m_isGenerator;
807 bool m_isGeneratorBoundary;
808 bool m_isArrowFunction;
809 bool m_isArrowFunctionBoundary;
810 bool m_isAsyncFunction;
811 bool m_isAsyncFunctionBoundary;
812 bool m_isLexicalScope;
813 bool m_isGlobalCodeScope;
814 bool m_isSimpleCatchParameterScope;
815 bool m_isFunctionBoundary;
816 bool m_isValidStrictMode;
817 bool m_hasArguments;
818 bool m_isEvalContext;
819 bool m_hasNonSimpleParameterList;
820 EvalContextType m_evalContextType;
821 unsigned m_constructorKind;
822 unsigned m_expectedSuperBinding;
823 int m_loopDepth;
824 int m_switchDepth;
825 InnerArrowFunctionCodeFeatures m_innerArrowFunctionFeatures;
826
827 typedef Vector<ScopeLabelInfo, 2> LabelStack;
828 std::unique_ptr<LabelStack> m_labels;
829 UniquedStringImplPtrSet m_declaredParameters;
830 VariableEnvironment m_declaredVariables;
831 VariableEnvironment m_lexicalVariables;
832 Vector<UniquedStringImplPtrSet, 6> m_usedVariables;
833 UniquedStringImplPtrSet m_variablesBeingHoisted;
834 UniquedStringImplPtrSet m_sloppyModeHoistableFunctionCandidates;
835 HashSet<UniquedStringImpl*> m_closedVariableCandidates;
836 DeclarationStacks::FunctionStack m_functionDeclarations;
837};
838
839typedef Vector<Scope, 10> ScopeStack;
840
841struct ScopeRef {
842 ScopeRef(ScopeStack* scopeStack, unsigned index)
843 : m_scopeStack(scopeStack)
844 , m_index(index)
845 {
846 }
847 Scope* operator->() { return &m_scopeStack->at(m_index); }
848 unsigned index() const { return m_index; }
849
850 bool hasContainingScope()
851 {
852 return m_index && !m_scopeStack->at(m_index).isFunctionBoundary();
853 }
854
855 ScopeRef containingScope()
856 {
857 ASSERT(hasContainingScope());
858 return ScopeRef(m_scopeStack, m_index - 1);
859 }
860
861 bool operator==(const ScopeRef& other)
862 {
863 ASSERT(other.m_scopeStack == m_scopeStack);
864 return m_index == other.m_index;
865 }
866
867 bool operator!=(const ScopeRef& other)
868 {
869 return !(*this == other);
870 }
871
872private:
873 ScopeStack* m_scopeStack;
874 unsigned m_index;
875};
876
877enum class ArgumentType { Normal, Spread };
878enum class ParsingContext { Program, FunctionConstructor, Eval };
879
880template <typename LexerType>
881class Parser {
882 WTF_MAKE_NONCOPYABLE(Parser);
883 WTF_MAKE_FAST_ALLOCATED;
884
885public:
886 Parser(VM*, const SourceCode&, JSParserBuiltinMode, JSParserStrictMode, JSParserScriptMode, SourceParseMode, SuperBinding, ConstructorKind defaultConstructorKind = ConstructorKind::None, DerivedContextType = DerivedContextType::None, bool isEvalContext = false, EvalContextType = EvalContextType::None, DebuggerParseData* = nullptr);
887 ~Parser();
888
889 template <class ParsedNode>
890 std::unique_ptr<ParsedNode> parse(ParserError&, const Identifier&, SourceParseMode, ParsingContext, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt);
891
892 JSTextPosition positionBeforeLastNewline() const { return m_lexer->positionBeforeLastNewline(); }
893 JSTokenLocation locationBeforeLastToken() const { return m_lexer->lastTokenLocation(); }
894
895 struct CallOrApplyDepthScope {
896 CallOrApplyDepthScope(Parser* parser)
897 : m_parser(parser)
898 , m_parent(parser->m_callOrApplyDepthScope)
899 , m_depth(m_parent ? m_parent->m_depth + 1 : 0)
900 , m_depthOfInnermostChild(m_depth)
901 {
902 parser->m_callOrApplyDepthScope = this;
903 }
904
905 size_t distanceToInnermostChild() const
906 {
907 ASSERT(m_depthOfInnermostChild >= m_depth);
908 return m_depthOfInnermostChild - m_depth;
909 }
910
911 ~CallOrApplyDepthScope()
912 {
913 if (m_parent)
914 m_parent->m_depthOfInnermostChild = std::max(m_depthOfInnermostChild, m_parent->m_depthOfInnermostChild);
915 m_parser->m_callOrApplyDepthScope = m_parent;
916 }
917
918 private:
919
920 Parser* m_parser;
921 CallOrApplyDepthScope* m_parent;
922 size_t m_depth;
923 size_t m_depthOfInnermostChild;
924 };
925
926private:
927 struct AllowInOverride {
928 AllowInOverride(Parser* parser)
929 : m_parser(parser)
930 , m_oldAllowsIn(parser->m_allowsIn)
931 {
932 parser->m_allowsIn = true;
933 }
934 ~AllowInOverride()
935 {
936 m_parser->m_allowsIn = m_oldAllowsIn;
937 }
938 Parser* m_parser;
939 bool m_oldAllowsIn;
940 };
941
942 struct AutoPopScopeRef : public ScopeRef {
943 AutoPopScopeRef(Parser* parser, ScopeRef scope)
944 : ScopeRef(scope)
945 , m_parser(parser)
946 {
947 }
948
949 ~AutoPopScopeRef()
950 {
951 if (m_parser)
952 m_parser->popScope(*this, false);
953 }
954
955 void setPopped()
956 {
957 m_parser = 0;
958 }
959
960 private:
961 Parser* m_parser;
962 };
963
964 struct AutoCleanupLexicalScope {
965 // We can allocate this object on the stack without actually knowing beforehand if we're
966 // going to create a new lexical scope. If we decide to create a new lexical scope, we
967 // can pass the scope into this obejct and it will take care of the cleanup for us if the parse fails.
968 // This is helpful if we may fail from syntax errors after creating a lexical scope conditionally.
969 AutoCleanupLexicalScope()
970 : m_scope(nullptr, UINT_MAX)
971 , m_parser(nullptr)
972 {
973 }
974
975 ~AutoCleanupLexicalScope()
976 {
977 // This should only ever be called if we fail from a syntax error. Otherwise
978 // it's the intention that a user of this class pops this scope manually on a
979 // successful parse.
980 if (isValid())
981 m_parser->popScope(*this, false);
982 }
983
984 void setIsValid(ScopeRef& scope, Parser* parser)
985 {
986 RELEASE_ASSERT(scope->isLexicalScope());
987 m_scope = scope;
988 m_parser = parser;
989 }
990
991 bool isValid() const { return !!m_parser; }
992
993 void setPopped()
994 {
995 m_parser = nullptr;
996 }
997
998 ScopeRef& scope() { return m_scope; }
999
1000 private:
1001 ScopeRef m_scope;
1002 Parser* m_parser;
1003 };
1004
1005 enum ExpressionErrorClass {
1006 ErrorIndicatesNothing = 0,
1007 ErrorIndicatesPattern,
1008 ErrorIndicatesAsyncArrowFunction
1009 };
1010
1011 struct ExpressionErrorClassifier {
1012 ExpressionErrorClassifier(Parser* parser)
1013 : m_class(ErrorIndicatesNothing)
1014 , m_previous(parser->m_expressionErrorClassifier)
1015 , m_parser(parser)
1016 {
1017 m_parser->m_expressionErrorClassifier = this;
1018 }
1019
1020 ~ExpressionErrorClassifier()
1021 {
1022 m_parser->m_expressionErrorClassifier = m_previous;
1023 }
1024
1025 void classifyExpressionError(ExpressionErrorClass classification)
1026 {
1027 if (m_class != ErrorIndicatesNothing)
1028 return;
1029 m_class = classification;
1030 }
1031
1032 void forceClassifyExpressionError(ExpressionErrorClass classification)
1033 {
1034 m_class = classification;
1035 }
1036
1037 void reclassifyExpressionError(ExpressionErrorClass oldClassification, ExpressionErrorClass classification)
1038 {
1039 if (m_class != oldClassification)
1040 return;
1041 m_class = classification;
1042 }
1043
1044 void propagateExpressionErrorClass()
1045 {
1046 if (m_previous)
1047 m_previous->m_class = m_class;
1048 }
1049
1050 bool indicatesPossiblePattern() const { return m_class == ErrorIndicatesPattern; }
1051 bool indicatesPossibleAsyncArrowFunction() const { return m_class == ErrorIndicatesAsyncArrowFunction; }
1052
1053 private:
1054 ExpressionErrorClass m_class;
1055 ExpressionErrorClassifier* m_previous;
1056 Parser* m_parser;
1057 };
1058
1059 ALWAYS_INLINE void classifyExpressionError(ExpressionErrorClass classification)
1060 {
1061 if (m_expressionErrorClassifier)
1062 m_expressionErrorClassifier->classifyExpressionError(classification);
1063 }
1064
1065 ALWAYS_INLINE void forceClassifyExpressionError(ExpressionErrorClass classification)
1066 {
1067 if (m_expressionErrorClassifier)
1068 m_expressionErrorClassifier->forceClassifyExpressionError(classification);
1069 }
1070
1071 ALWAYS_INLINE void reclassifyExpressionError(ExpressionErrorClass oldClassification, ExpressionErrorClass classification)
1072 {
1073 if (m_expressionErrorClassifier)
1074 m_expressionErrorClassifier->reclassifyExpressionError(oldClassification, classification);
1075 }
1076
1077 ALWAYS_INLINE DestructuringKind destructuringKindFromDeclarationType(DeclarationType type)
1078 {
1079 switch (type) {
1080 case DeclarationType::VarDeclaration:
1081 return DestructuringKind::DestructureToVariables;
1082 case DeclarationType::LetDeclaration:
1083 return DestructuringKind::DestructureToLet;
1084 case DeclarationType::ConstDeclaration:
1085 return DestructuringKind::DestructureToConst;
1086 }
1087
1088 RELEASE_ASSERT_NOT_REACHED();
1089 return DestructuringKind::DestructureToVariables;
1090 }
1091
1092 ALWAYS_INLINE const char* declarationTypeToVariableKind(DeclarationType type)
1093 {
1094 switch (type) {
1095 case DeclarationType::VarDeclaration:
1096 return "variable name";
1097 case DeclarationType::LetDeclaration:
1098 case DeclarationType::ConstDeclaration:
1099 return "lexical variable name";
1100 }
1101 RELEASE_ASSERT_NOT_REACHED();
1102 return "invalid";
1103 }
1104
1105 ALWAYS_INLINE AssignmentContext assignmentContextFromDeclarationType(DeclarationType type)
1106 {
1107 switch (type) {
1108 case DeclarationType::ConstDeclaration:
1109 return AssignmentContext::ConstDeclarationStatement;
1110 default:
1111 return AssignmentContext::DeclarationStatement;
1112 }
1113 }
1114
1115 ALWAYS_INLINE bool isEvalOrArguments(const Identifier* ident) { return isEvalOrArgumentsIdentifier(m_vm, ident); }
1116
1117 ScopeRef upperScope(int n)
1118 {
1119 ASSERT(m_scopeStack.size() >= size_t(1 + n));
1120 return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1 - n);
1121 }
1122
1123 ScopeRef currentScope()
1124 {
1125 return ScopeRef(&m_scopeStack, m_scopeStack.size() - 1);
1126 }
1127
1128 ScopeRef currentVariableScope()
1129 {
1130 unsigned i = m_scopeStack.size() - 1;
1131 ASSERT(i < m_scopeStack.size());
1132 while (!m_scopeStack[i].allowsVarDeclarations()) {
1133 i--;
1134 ASSERT(i < m_scopeStack.size());
1135 }
1136 return ScopeRef(&m_scopeStack, i);
1137 }
1138
1139 ScopeRef currentLexicalDeclarationScope()
1140 {
1141 unsigned i = m_scopeStack.size() - 1;
1142 ASSERT(i < m_scopeStack.size());
1143 while (!m_scopeStack[i].allowsLexicalDeclarations()) {
1144 i--;
1145 ASSERT(i < m_scopeStack.size());
1146 }
1147
1148 return ScopeRef(&m_scopeStack, i);
1149 }
1150
1151 ScopeRef currentFunctionScope()
1152 {
1153 unsigned i = m_scopeStack.size() - 1;
1154 ASSERT(i < m_scopeStack.size());
1155 while (i && !m_scopeStack[i].isFunctionBoundary()) {
1156 i--;
1157 ASSERT(i < m_scopeStack.size());
1158 }
1159 // When reaching the top level scope (it can be non function scope), we return it.
1160 return ScopeRef(&m_scopeStack, i);
1161 }
1162
1163 ScopeRef closestParentOrdinaryFunctionNonLexicalScope()
1164 {
1165 unsigned i = m_scopeStack.size() - 1;
1166 ASSERT(i < m_scopeStack.size() && m_scopeStack.size());
1167 while (i && (!m_scopeStack[i].isFunctionBoundary() || m_scopeStack[i].isGeneratorBoundary() || m_scopeStack[i].isAsyncFunctionBoundary() || m_scopeStack[i].isArrowFunctionBoundary()))
1168 i--;
1169 // When reaching the top level scope (it can be non ordinary function scope), we return it.
1170 return ScopeRef(&m_scopeStack, i);
1171 }
1172
1173 ScopeRef pushScope()
1174 {
1175 bool isFunction = false;
1176 bool isStrict = false;
1177 bool isGenerator = false;
1178 bool isArrowFunction = false;
1179 bool isAsyncFunction = false;
1180 if (!m_scopeStack.isEmpty()) {
1181 isStrict = m_scopeStack.last().strictMode();
1182 isFunction = m_scopeStack.last().isFunction();
1183 isGenerator = m_scopeStack.last().isGenerator();
1184 isArrowFunction = m_scopeStack.last().isArrowFunction();
1185 isAsyncFunction = m_scopeStack.last().isAsyncFunction();
1186 }
1187 m_scopeStack.constructAndAppend(m_vm, isFunction, isGenerator, isStrict, isArrowFunction, isAsyncFunction);
1188 return currentScope();
1189 }
1190
1191 void popScopeInternal(ScopeRef& scope, bool shouldTrackClosedVariables)
1192 {
1193 EXCEPTION_ASSERT_UNUSED(scope, scope.index() == m_scopeStack.size() - 1);
1194 ASSERT(m_scopeStack.size() > 1);
1195 m_scopeStack[m_scopeStack.size() - 2].collectFreeVariables(&m_scopeStack.last(), shouldTrackClosedVariables);
1196
1197 if (m_scopeStack.last().isArrowFunction())
1198 m_scopeStack.last().setInnerArrowFunctionUsesEvalAndUseArgumentsIfNeeded();
1199
1200 if (!(m_scopeStack.last().isFunctionBoundary() && !m_scopeStack.last().isArrowFunctionBoundary()))
1201 m_scopeStack[m_scopeStack.size() - 2].mergeInnerArrowFunctionFeatures(m_scopeStack.last().innerArrowFunctionFeatures());
1202
1203 if (!m_scopeStack.last().isFunctionBoundary() && m_scopeStack.last().needsFullActivation())
1204 m_scopeStack[m_scopeStack.size() - 2].setNeedsFullActivation();
1205 m_scopeStack.removeLast();
1206 }
1207
1208 ALWAYS_INLINE void popScope(ScopeRef& scope, bool shouldTrackClosedVariables)
1209 {
1210 popScopeInternal(scope, shouldTrackClosedVariables);
1211 }
1212
1213 ALWAYS_INLINE void popScope(AutoPopScopeRef& scope, bool shouldTrackClosedVariables)
1214 {
1215 scope.setPopped();
1216 popScopeInternal(scope, shouldTrackClosedVariables);
1217 }
1218
1219 ALWAYS_INLINE void popScope(AutoCleanupLexicalScope& cleanupScope, bool shouldTrackClosedVariables)
1220 {
1221 RELEASE_ASSERT(cleanupScope.isValid());
1222 ScopeRef& scope = cleanupScope.scope();
1223 cleanupScope.setPopped();
1224 popScopeInternal(scope, shouldTrackClosedVariables);
1225 }
1226
1227 NEVER_INLINE DeclarationResultMask declareHoistedVariable(const Identifier* ident)
1228 {
1229 unsigned i = m_scopeStack.size() - 1;
1230 ASSERT(i < m_scopeStack.size());
1231 while (true) {
1232 // Annex B.3.5 exempts `try {} catch (e) { var e; }` from being a syntax error.
1233 if (m_scopeStack[i].hasLexicallyDeclaredVariable(*ident) && !m_scopeStack[i].isSimpleCatchParameterScope())
1234 return DeclarationResult::InvalidDuplicateDeclaration;
1235
1236 if (m_scopeStack[i].allowsVarDeclarations())
1237 return m_scopeStack[i].declareVariable(ident);
1238
1239 m_scopeStack[i].addVariableBeingHoisted(ident);
1240
1241 i--;
1242 ASSERT(i < m_scopeStack.size());
1243 }
1244 }
1245
1246 DeclarationResultMask declareVariable(const Identifier* ident, DeclarationType type = DeclarationType::VarDeclaration, DeclarationImportType importType = DeclarationImportType::NotImported)
1247 {
1248 if (type == DeclarationType::VarDeclaration)
1249 return declareHoistedVariable(ident);
1250
1251 ASSERT(type == DeclarationType::LetDeclaration || type == DeclarationType::ConstDeclaration);
1252 // Lexical variables declared at a top level scope that shadow arguments or vars are not allowed.
1253 if (!m_lexer->isReparsingFunction() && m_statementDepth == 1 && (hasDeclaredParameter(*ident) || hasDeclaredVariable(*ident)))
1254 return DeclarationResult::InvalidDuplicateDeclaration;
1255
1256 return currentLexicalDeclarationScope()->declareLexicalVariable(ident, type == DeclarationType::ConstDeclaration, importType);
1257 }
1258
1259 std::pair<DeclarationResultMask, ScopeRef> declareFunction(const Identifier* ident)
1260 {
1261 if ((m_statementDepth == 1) || (!strictMode() && !currentScope()->isFunction() && !closestParentOrdinaryFunctionNonLexicalScope()->isEvalContext())) {
1262 // Functions declared at the top-most scope (both in sloppy and strict mode) are declared as vars
1263 // for backwards compatibility. This allows us to declare functions with the same name more than once.
1264 // In sloppy mode, we always declare functions as vars.
1265 bool declareAsVar = true;
1266 bool isSloppyModeHoistingCandidate = false;
1267 ScopeRef variableScope = currentVariableScope();
1268 return std::make_pair(variableScope->declareFunction(ident, declareAsVar, isSloppyModeHoistingCandidate), variableScope);
1269 }
1270
1271 if (!strictMode()) {
1272 ASSERT(currentScope()->isFunction() || closestParentOrdinaryFunctionNonLexicalScope()->isEvalContext());
1273
1274 // Functions declared inside a function inside a nested block scope in sloppy mode are subject to this
1275 // crazy rule defined inside Annex B.3.3 in the ES6 spec. It basically states that we will create
1276 // the function as a local block scoped variable, but when we evaluate the block that the function is
1277 // contained in, we will assign the function to a "var" variable only if declaring such a "var" wouldn't
1278 // be a syntax error and if there isn't a parameter with the same name. (It would only be a syntax error if
1279 // there are is a let/class/const with the same name). Note that this mean we only do the "var" hoisting
1280 // binding if the block evaluates. For example, this means we wont won't perform the binding if it's inside
1281 // the untaken branch of an if statement.
1282 bool declareAsVar = false;
1283 bool isSloppyModeHoistingCandidate = true;
1284 ScopeRef lexicalVariableScope = currentLexicalDeclarationScope();
1285 ScopeRef varScope = currentVariableScope();
1286 varScope->addSloppyModeHoistableFunctionCandidate(ident);
1287 ASSERT(varScope != lexicalVariableScope);
1288 return std::make_pair(lexicalVariableScope->declareFunction(ident, declareAsVar, isSloppyModeHoistingCandidate), lexicalVariableScope);
1289 }
1290
1291 bool declareAsVar = false;
1292 bool isSloppyModeHoistingCandidate = false;
1293 ScopeRef lexicalVariableScope = currentLexicalDeclarationScope();
1294 return std::make_pair(lexicalVariableScope->declareFunction(ident, declareAsVar, isSloppyModeHoistingCandidate), lexicalVariableScope);
1295 }
1296
1297 NEVER_INLINE bool hasDeclaredVariable(const Identifier& ident)
1298 {
1299 unsigned i = m_scopeStack.size() - 1;
1300 ASSERT(i < m_scopeStack.size());
1301 while (!m_scopeStack[i].allowsVarDeclarations()) {
1302 i--;
1303 ASSERT(i < m_scopeStack.size());
1304 }
1305 return m_scopeStack[i].hasDeclaredVariable(ident);
1306 }
1307
1308 NEVER_INLINE bool hasDeclaredParameter(const Identifier& ident)
1309 {
1310 // FIXME: hasDeclaredParameter() is not valid during reparsing of generator or async function bodies, because their formal
1311 // parameters are declared in a scope unavailable during reparsing. Note that it is redundant to call this function during
1312 // reparsing anyways, as the function is already guaranteed to be valid by the original parsing.
1313 // https://bugs.webkit.org/show_bug.cgi?id=164087
1314 ASSERT(!m_lexer->isReparsingFunction());
1315
1316 unsigned i = m_scopeStack.size() - 1;
1317 ASSERT(i < m_scopeStack.size());
1318 while (!m_scopeStack[i].allowsVarDeclarations()) {
1319 i--;
1320 ASSERT(i < m_scopeStack.size());
1321 }
1322
1323 if (m_scopeStack[i].isGeneratorBoundary() || m_scopeStack[i].isAsyncFunctionBoundary()) {
1324 // The formal parameters which need to be verified for Generators and Async Function bodies occur
1325 // in the outer wrapper function, so pick the outer scope here.
1326 i--;
1327 ASSERT(i < m_scopeStack.size());
1328 }
1329 return m_scopeStack[i].hasDeclaredParameter(ident);
1330 }
1331
1332 bool exportName(const Identifier& ident)
1333 {
1334 ASSERT(currentScope().index() == 0);
1335 ASSERT(m_moduleScopeData);
1336 return m_moduleScopeData->exportName(ident);
1337 }
1338
1339 ScopeStack m_scopeStack;
1340
1341 const SourceProviderCacheItem* findCachedFunctionInfo(int openBracePos)
1342 {
1343 return m_functionCache ? m_functionCache->get(openBracePos) : 0;
1344 }
1345
1346 Parser();
1347
1348 String parseInner(const Identifier&, SourceParseMode, ParsingContext, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt);
1349
1350 void didFinishParsing(SourceElements*, DeclarationStacks::FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, CodeFeatures, int);
1351
1352 // Used to determine type of error to report.
1353 bool isFunctionMetadataNode(ScopeNode*) { return false; }
1354 bool isFunctionMetadataNode(FunctionMetadataNode*) { return true; }
1355
1356 ALWAYS_INLINE void next(unsigned lexerFlags = 0)
1357 {
1358 int lastLine = m_token.m_location.line;
1359 int lastTokenEnd = m_token.m_location.endOffset;
1360 int lastTokenLineStart = m_token.m_location.lineStartOffset;
1361 m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
1362 m_lexer->setLastLineNumber(lastLine);
1363 m_token.m_type = m_lexer->lex(&m_token, lexerFlags, strictMode());
1364 }
1365
1366 ALWAYS_INLINE void nextWithoutClearingLineTerminator(unsigned lexerFlags = 0)
1367 {
1368 int lastLine = m_token.m_location.line;
1369 int lastTokenEnd = m_token.m_location.endOffset;
1370 int lastTokenLineStart = m_token.m_location.lineStartOffset;
1371 m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
1372 m_lexer->setLastLineNumber(lastLine);
1373 m_token.m_type = m_lexer->lexWithoutClearingLineTerminator(&m_token, lexerFlags, strictMode());
1374 }
1375
1376 ALWAYS_INLINE void nextExpectIdentifier(unsigned lexerFlags = 0)
1377 {
1378 int lastLine = m_token.m_location.line;
1379 int lastTokenEnd = m_token.m_location.endOffset;
1380 int lastTokenLineStart = m_token.m_location.lineStartOffset;
1381 m_lastTokenEndPosition = JSTextPosition(lastLine, lastTokenEnd, lastTokenLineStart);
1382 m_lexer->setLastLineNumber(lastLine);
1383 m_token.m_type = m_lexer->lexExpectIdentifier(&m_token, lexerFlags, strictMode());
1384 }
1385
1386 ALWAYS_INLINE void lexCurrentTokenAgainUnderCurrentContext()
1387 {
1388 auto savePoint = createSavePoint();
1389 restoreSavePoint(savePoint);
1390 }
1391
1392 ALWAYS_INLINE bool nextTokenIsColon()
1393 {
1394 return m_lexer->nextTokenIsColon();
1395 }
1396
1397 ALWAYS_INLINE bool consume(JSTokenType expected, unsigned flags = 0)
1398 {
1399 bool result = m_token.m_type == expected;
1400 if (result)
1401 next(flags);
1402 return result;
1403 }
1404
1405 void printUnexpectedTokenText(WTF::PrintStream&);
1406 ALWAYS_INLINE StringView getToken()
1407 {
1408 return m_lexer->getToken(m_token);
1409 }
1410
1411 ALWAYS_INLINE StringView getToken(const JSToken& token)
1412 {
1413 return m_lexer->getToken(token);
1414 }
1415
1416 ALWAYS_INLINE bool match(JSTokenType expected)
1417 {
1418 return m_token.m_type == expected;
1419 }
1420
1421 ALWAYS_INLINE bool matchContextualKeyword(const Identifier& identifier)
1422 {
1423 return m_token.m_type == IDENT && *m_token.m_data.ident == identifier && !m_token.m_data.escaped;
1424 }
1425
1426 ALWAYS_INLINE bool matchIdentifierOrKeyword()
1427 {
1428 return isIdentifierOrKeyword(m_token);
1429 }
1430
1431 ALWAYS_INLINE unsigned tokenStart()
1432 {
1433 return m_token.m_location.startOffset;
1434 }
1435
1436 ALWAYS_INLINE const JSTextPosition& tokenStartPosition()
1437 {
1438 return m_token.m_startPosition;
1439 }
1440
1441 ALWAYS_INLINE int tokenLine()
1442 {
1443 return m_token.m_location.line;
1444 }
1445
1446 ALWAYS_INLINE int tokenColumn()
1447 {
1448 return tokenStart() - tokenLineStart();
1449 }
1450
1451 ALWAYS_INLINE const JSTextPosition& tokenEndPosition()
1452 {
1453 return m_token.m_endPosition;
1454 }
1455
1456 ALWAYS_INLINE unsigned tokenLineStart()
1457 {
1458 return m_token.m_location.lineStartOffset;
1459 }
1460
1461 ALWAYS_INLINE const JSTokenLocation& tokenLocation()
1462 {
1463 return m_token.m_location;
1464 }
1465
1466 void setErrorMessage(const String& message)
1467 {
1468 ASSERT_WITH_MESSAGE(!message.isEmpty(), "Attempted to set the empty string as an error message. Likely caused by invalid UTF8 used when creating the message.");
1469 m_errorMessage = message;
1470 if (m_errorMessage.isEmpty())
1471 m_errorMessage = "Unparseable script"_s;
1472 }
1473
1474 NEVER_INLINE void logError(bool);
1475 template <typename... Args>
1476 NEVER_INLINE void logError(bool, Args&&...);
1477
1478 NEVER_INLINE void updateErrorWithNameAndMessage(const char* beforeMessage, const String& name, const char* afterMessage)
1479 {
1480 m_errorMessage = makeString(beforeMessage, " '", name, "' ", afterMessage);
1481 }
1482
1483 NEVER_INLINE void updateErrorMessage(const char* msg)
1484 {
1485 ASSERT(msg);
1486 m_errorMessage = String(msg);
1487 ASSERT(!m_errorMessage.isNull());
1488 }
1489
1490 ALWAYS_INLINE void recordPauseLocation(const JSTextPosition&);
1491 ALWAYS_INLINE void recordFunctionEntryLocation(const JSTextPosition&);
1492 ALWAYS_INLINE void recordFunctionLeaveLocation(const JSTextPosition&);
1493
1494 void startLoop() { currentScope()->startLoop(); }
1495 void endLoop() { currentScope()->endLoop(); }
1496 void startSwitch() { currentScope()->startSwitch(); }
1497 void endSwitch() { currentScope()->endSwitch(); }
1498 void setStrictMode() { currentScope()->setStrictMode(); }
1499 bool strictMode() { return currentScope()->strictMode(); }
1500 bool isValidStrictMode()
1501 {
1502 int i = m_scopeStack.size() - 1;
1503 if (!m_scopeStack[i].isValidStrictMode())
1504 return false;
1505
1506 // In the case of Generator or Async function bodies, also check the wrapper function, whose name or
1507 // arguments may be invalid.
1508 if (UNLIKELY((m_scopeStack[i].isGeneratorBoundary() || m_scopeStack[i].isAsyncFunctionBoundary()) && i))
1509 return m_scopeStack[i - 1].isValidStrictMode();
1510 return true;
1511 }
1512 DeclarationResultMask declareParameter(const Identifier* ident) { return currentScope()->declareParameter(ident); }
1513 bool declareRestOrNormalParameter(const Identifier&, const Identifier**);
1514
1515 bool breakIsValid()
1516 {
1517 ScopeRef current = currentScope();
1518 while (!current->breakIsValid()) {
1519 if (!current.hasContainingScope())
1520 return false;
1521 current = current.containingScope();
1522 }
1523 return true;
1524 }
1525 bool continueIsValid()
1526 {
1527 ScopeRef current = currentScope();
1528 while (!current->continueIsValid()) {
1529 if (!current.hasContainingScope())
1530 return false;
1531 current = current.containingScope();
1532 }
1533 return true;
1534 }
1535 void pushLabel(const Identifier* label, bool isLoop) { currentScope()->pushLabel(label, isLoop); }
1536 void popLabel(ScopeRef scope) { scope->popLabel(); }
1537 ScopeLabelInfo* getLabel(const Identifier* label)
1538 {
1539 ScopeRef current = currentScope();
1540 ScopeLabelInfo* result = 0;
1541 while (!(result = current->getLabel(label))) {
1542 if (!current.hasContainingScope())
1543 return 0;
1544 current = current.containingScope();
1545 }
1546 return result;
1547 }
1548
1549 // http://ecma-international.org/ecma-262/6.0/#sec-identifiers-static-semantics-early-errors
1550 ALWAYS_INLINE bool isLETMaskedAsIDENT()
1551 {
1552 return match(LET) && !strictMode();
1553 }
1554
1555 // http://ecma-international.org/ecma-262/6.0/#sec-identifiers-static-semantics-early-errors
1556 ALWAYS_INLINE bool isYIELDMaskedAsIDENT(bool inGenerator)
1557 {
1558 return match(YIELD) && !strictMode() && !inGenerator;
1559 }
1560
1561 // http://ecma-international.org/ecma-262/6.0/#sec-generator-function-definitions-static-semantics-early-errors
1562 ALWAYS_INLINE bool matchSpecIdentifier(bool inGenerator)
1563 {
1564 return match(IDENT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(inGenerator) || isSafeContextualKeyword(m_token);
1565 }
1566
1567 ALWAYS_INLINE bool matchSpecIdentifier()
1568 {
1569 return match(IDENT) || isLETMaskedAsIDENT() || isYIELDMaskedAsIDENT(currentScope()->isGenerator()) || isSafeContextualKeyword(m_token);
1570 }
1571
1572 template <class TreeBuilder> TreeSourceElements parseSourceElements(TreeBuilder&, SourceElementsMode);
1573 template <class TreeBuilder> TreeSourceElements parseGeneratorFunctionSourceElements(TreeBuilder&, const Identifier& name, SourceElementsMode);
1574 template <class TreeBuilder> TreeSourceElements parseAsyncFunctionSourceElements(TreeBuilder&, SourceParseMode, bool isArrowFunctionBodyExpression, SourceElementsMode);
1575 template <class TreeBuilder> TreeSourceElements parseAsyncGeneratorFunctionSourceElements(TreeBuilder&, SourceParseMode, bool isArrowFunctionBodyExpression, SourceElementsMode);
1576 template <class TreeBuilder> TreeSourceElements parseSingleFunction(TreeBuilder&, Optional<int> functionConstructorParametersEndPosition);
1577 template <class TreeBuilder> TreeStatement parseStatementListItem(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength);
1578 template <class TreeBuilder> TreeStatement parseStatement(TreeBuilder&, const Identifier*& directive, unsigned* directiveLiteralLength = 0);
1579 enum class ExportType { Exported, NotExported };
1580 template <class TreeBuilder> TreeStatement parseClassDeclaration(TreeBuilder&, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard);
1581 template <class TreeBuilder> TreeStatement parseFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt);
1582 template <class TreeBuilder> TreeStatement parseFunctionDeclarationStatement(TreeBuilder&, bool isAsync, bool parentAllowsFunctionDeclarationAsStatement);
1583 template <class TreeBuilder> TreeStatement parseAsyncFunctionDeclaration(TreeBuilder&, ExportType = ExportType::NotExported, DeclarationDefaultContext = DeclarationDefaultContext::Standard, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt);
1584 template <class TreeBuilder> NEVER_INLINE bool maybeParseAsyncFunctionDeclarationStatement(TreeBuilder& context, TreeStatement& result, bool parentAllowsFunctionDeclarationAsStatement);
1585 template <class TreeBuilder> TreeStatement parseVariableDeclaration(TreeBuilder&, DeclarationType, ExportType = ExportType::NotExported);
1586 template <class TreeBuilder> TreeStatement parseDoWhileStatement(TreeBuilder&);
1587 template <class TreeBuilder> TreeStatement parseWhileStatement(TreeBuilder&);
1588 template <class TreeBuilder> TreeStatement parseForStatement(TreeBuilder&);
1589 template <class TreeBuilder> TreeStatement parseBreakStatement(TreeBuilder&);
1590 template <class TreeBuilder> TreeStatement parseContinueStatement(TreeBuilder&);
1591 template <class TreeBuilder> TreeStatement parseReturnStatement(TreeBuilder&);
1592 template <class TreeBuilder> TreeStatement parseThrowStatement(TreeBuilder&);
1593 template <class TreeBuilder> TreeStatement parseWithStatement(TreeBuilder&);
1594 template <class TreeBuilder> TreeStatement parseSwitchStatement(TreeBuilder&);
1595 template <class TreeBuilder> TreeClauseList parseSwitchClauses(TreeBuilder&);
1596 template <class TreeBuilder> TreeClause parseSwitchDefaultClause(TreeBuilder&);
1597 template <class TreeBuilder> TreeStatement parseTryStatement(TreeBuilder&);
1598 template <class TreeBuilder> TreeStatement parseDebuggerStatement(TreeBuilder&);
1599 template <class TreeBuilder> TreeStatement parseExpressionStatement(TreeBuilder&);
1600 template <class TreeBuilder> TreeStatement parseExpressionOrLabelStatement(TreeBuilder&, bool allowFunctionDeclarationAsStatement);
1601 template <class TreeBuilder> TreeStatement parseIfStatement(TreeBuilder&);
1602 template <class TreeBuilder> TreeStatement parseBlockStatement(TreeBuilder&);
1603 template <class TreeBuilder> TreeExpression parseExpression(TreeBuilder&);
1604 template <class TreeBuilder> TreeExpression parseAssignmentExpression(TreeBuilder&, ExpressionErrorClassifier&);
1605 template <class TreeBuilder> TreeExpression parseAssignmentExpression(TreeBuilder&);
1606 template <class TreeBuilder> TreeExpression parseAssignmentExpressionOrPropagateErrorClass(TreeBuilder&);
1607 template <class TreeBuilder> TreeExpression parseYieldExpression(TreeBuilder&);
1608 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseConditionalExpression(TreeBuilder&);
1609 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseBinaryExpression(TreeBuilder&);
1610 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseUnaryExpression(TreeBuilder&);
1611 template <class TreeBuilder> NEVER_INLINE TreeExpression parseAwaitExpression(TreeBuilder&);
1612 template <class TreeBuilder> TreeExpression parseMemberExpression(TreeBuilder&);
1613 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parsePrimaryExpression(TreeBuilder&);
1614 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArrayLiteral(TreeBuilder&);
1615 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseObjectLiteral(TreeBuilder&);
1616 template <class TreeBuilder> NEVER_INLINE TreeExpression parseStrictObjectLiteral(TreeBuilder&);
1617 template <class TreeBuilder> ALWAYS_INLINE TreeClassExpression parseClassExpression(TreeBuilder&);
1618 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseFunctionExpression(TreeBuilder&);
1619 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseAsyncFunctionExpression(TreeBuilder&);
1620 template <class TreeBuilder> ALWAYS_INLINE TreeArguments parseArguments(TreeBuilder&);
1621 template <class TreeBuilder> ALWAYS_INLINE TreeExpression parseArgument(TreeBuilder&, ArgumentType&);
1622 template <class TreeBuilder> TreeProperty parseProperty(TreeBuilder&, bool strict);
1623 template <class TreeBuilder> TreeExpression parsePropertyMethod(TreeBuilder& context, const Identifier* methodName, SourceParseMode);
1624 template <class TreeBuilder> TreeProperty parseGetterSetter(TreeBuilder&, bool strict, PropertyNode::Type, unsigned getterOrSetterStartOffset, ConstructorKind, ClassElementTag);
1625 template <class TreeBuilder> ALWAYS_INLINE TreeFunctionBody parseFunctionBody(TreeBuilder&, SyntaxChecker&, const JSTokenLocation&, int, int functionKeywordStart, int functionNameStart, int parametersStart, ConstructorKind, SuperBinding, FunctionBodyType, unsigned, SourceParseMode);
1626 template <class TreeBuilder> ALWAYS_INLINE bool parseFormalParameters(TreeBuilder&, TreeFormalParameterList, bool isArrowFunction, bool isMethod, unsigned&);
1627 enum VarDeclarationListContext { ForLoopContext, VarDeclarationContext };
1628 template <class TreeBuilder> TreeExpression parseVariableDeclarationList(TreeBuilder&, int& declarations, TreeDestructuringPattern& lastPattern, TreeExpression& lastInitializer, JSTextPosition& identStart, JSTextPosition& initStart, JSTextPosition& initEnd, VarDeclarationListContext, DeclarationType, ExportType, bool& forLoopConstDoesNotHaveInitializer);
1629 template <class TreeBuilder> TreeSourceElements parseArrowFunctionSingleExpressionBodySourceElements(TreeBuilder&);
1630 template <class TreeBuilder> TreeExpression parseArrowFunctionExpression(TreeBuilder&, bool isAsync);
1631 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createBindingPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier&, JSToken, AssignmentContext, const Identifier** duplicateIdentifier);
1632 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern createAssignmentElement(TreeBuilder&, TreeExpression&, const JSTextPosition&, const JSTextPosition&);
1633 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseObjectRestBindingOrAssignmentElement(TreeBuilder& context, DestructuringKind, ExportType, const Identifier** duplicateIdentifier, AssignmentContext bindingContext);
1634 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseBindingOrAssignmentElement(TreeBuilder& context, DestructuringKind, ExportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth);
1635 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseObjectRestAssignmentElement(TreeBuilder& context);
1636 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseAssignmentElement(TreeBuilder& context, DestructuringKind, ExportType, const Identifier** duplicateIdentifier, bool* hasDestructuringPattern, AssignmentContext bindingContext, int depth);
1637 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseObjectRestElement(TreeBuilder&, DestructuringKind, ExportType, const Identifier** duplicateIdentifier = nullptr, AssignmentContext = AssignmentContext::DeclarationStatement);
1638 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern parseDestructuringPattern(TreeBuilder&, DestructuringKind, ExportType, const Identifier** duplicateIdentifier = nullptr, bool* hasDestructuringPattern = nullptr, AssignmentContext = AssignmentContext::DeclarationStatement, int depth = 0);
1639 template <class TreeBuilder> NEVER_INLINE TreeDestructuringPattern tryParseDestructuringPatternExpression(TreeBuilder&, AssignmentContext);
1640 template <class TreeBuilder> NEVER_INLINE TreeExpression parseDefaultValueForDestructuringPattern(TreeBuilder&);
1641 template <class TreeBuilder> TreeSourceElements parseModuleSourceElements(TreeBuilder&, SourceParseMode);
1642 enum class ImportSpecifierType { NamespaceImport, NamedImport, DefaultImport };
1643 template <class TreeBuilder> typename TreeBuilder::ImportSpecifier parseImportClauseItem(TreeBuilder&, ImportSpecifierType);
1644 template <class TreeBuilder> typename TreeBuilder::ModuleName parseModuleName(TreeBuilder&);
1645 template <class TreeBuilder> TreeStatement parseImportDeclaration(TreeBuilder&);
1646 template <class TreeBuilder> typename TreeBuilder::ExportSpecifier parseExportSpecifier(TreeBuilder& context, Vector<std::pair<const Identifier*, const Identifier*>>& maybeExportedLocalNames, bool& hasKeywordForLocalBindings);
1647 template <class TreeBuilder> TreeStatement parseExportDeclaration(TreeBuilder&);
1648
1649 template <class TreeBuilder> ALWAYS_INLINE TreeExpression createResolveAndUseVariable(TreeBuilder&, const Identifier*, bool isEval, const JSTextPosition&, const JSTokenLocation&);
1650
1651 enum class FunctionDefinitionType { Expression, Declaration, Method };
1652 template <class TreeBuilder> NEVER_INLINE bool parseFunctionInfo(TreeBuilder&, FunctionNameRequirements, SourceParseMode, bool nameIsInContainingScope, ConstructorKind, SuperBinding, int functionKeywordStart, ParserFunctionInfo<TreeBuilder>&, FunctionDefinitionType, Optional<int> functionConstructorParametersEndPosition = WTF::nullopt);
1653
1654 ALWAYS_INLINE bool isArrowFunctionParameters();
1655
1656 template <class TreeBuilder, class FunctionInfoType> NEVER_INLINE typename TreeBuilder::FormalParameterList parseFunctionParameters(TreeBuilder&, SourceParseMode, FunctionInfoType&);
1657 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::FormalParameterList createGeneratorParameters(TreeBuilder&, unsigned& parameterCount);
1658
1659 template <class TreeBuilder> NEVER_INLINE TreeClassExpression parseClass(TreeBuilder&, FunctionNameRequirements, ParserClassInfo<TreeBuilder>&);
1660
1661 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::TemplateString parseTemplateString(TreeBuilder& context, bool isTemplateHead, typename LexerType::RawStringsBuildMode, bool& elementIsTail);
1662 template <class TreeBuilder> NEVER_INLINE typename TreeBuilder::TemplateLiteral parseTemplateLiteral(TreeBuilder&, typename LexerType::RawStringsBuildMode);
1663
1664 template <class TreeBuilder> ALWAYS_INLINE bool shouldCheckPropertyForUnderscoreProtoDuplicate(TreeBuilder&, const TreeProperty&);
1665
1666 template <class TreeBuilder> NEVER_INLINE const char* metaPropertyName(TreeBuilder&, TreeExpression);
1667
1668 template <class TreeBuilder> ALWAYS_INLINE bool isSimpleAssignmentTarget(TreeBuilder&, TreeExpression);
1669
1670 ALWAYS_INLINE int isBinaryOperator(JSTokenType);
1671 bool allowAutomaticSemicolon();
1672
1673 bool autoSemiColon()
1674 {
1675 if (m_token.m_type == SEMICOLON) {
1676 next();
1677 return true;
1678 }
1679 return allowAutomaticSemicolon();
1680 }
1681
1682 bool canRecurse()
1683 {
1684 return m_vm->isSafeToRecurse();
1685 }
1686
1687 const JSTextPosition& lastTokenEndPosition() const
1688 {
1689 return m_lastTokenEndPosition;
1690 }
1691
1692 bool hasError() const
1693 {
1694 return !m_errorMessage.isNull();
1695 }
1696
1697 bool isDisallowedIdentifierLet(const JSToken& token)
1698 {
1699 return token.m_type == LET && strictMode();
1700 }
1701
1702 bool isDisallowedIdentifierAwait(const JSToken& token)
1703 {
1704 return token.m_type == AWAIT && (!m_parserState.allowAwait || currentScope()->isAsyncFunctionBoundary() || m_scriptMode == JSParserScriptMode::Module);
1705 }
1706
1707 bool isDisallowedIdentifierYield(const JSToken& token)
1708 {
1709 return token.m_type == YIELD && (strictMode() || currentScope()->isGenerator());
1710 }
1711
1712 ALWAYS_INLINE SuperBinding adjustSuperBindingForBaseConstructor(ConstructorKind constructorKind, SuperBinding superBinding, ScopeRef functionScope)
1713 {
1714 return adjustSuperBindingForBaseConstructor(constructorKind, superBinding, functionScope->needsSuperBinding(), functionScope->usesEval(), functionScope->innerArrowFunctionFeatures());
1715 }
1716
1717 ALWAYS_INLINE SuperBinding adjustSuperBindingForBaseConstructor(ConstructorKind constructorKind, SuperBinding superBinding, bool scopeNeedsSuperBinding, bool currentScopeUsesEval, InnerArrowFunctionCodeFeatures innerArrowFunctionFeatures)
1718 {
1719 SuperBinding methodSuperBinding = superBinding;
1720
1721 if (constructorKind == ConstructorKind::Base) {
1722 bool isSuperUsedInInnerArrowFunction = innerArrowFunctionFeatures & SuperPropertyInnerArrowFunctionFeature;
1723 methodSuperBinding = (scopeNeedsSuperBinding || isSuperUsedInInnerArrowFunction || currentScopeUsesEval) ? SuperBinding::Needed : SuperBinding::NotNeeded;
1724 }
1725
1726 return methodSuperBinding;
1727 }
1728
1729 const char* disallowedIdentifierLetReason()
1730 {
1731 ASSERT(strictMode());
1732 return "in strict mode";
1733 }
1734
1735 const char* disallowedIdentifierAwaitReason()
1736 {
1737 if (!m_parserState.allowAwait || currentScope()->isAsyncFunctionBoundary())
1738 return "in an async function";
1739 if (m_scriptMode == JSParserScriptMode::Module)
1740 return "in a module";
1741 RELEASE_ASSERT_NOT_REACHED();
1742 return nullptr;
1743 }
1744
1745 const char* disallowedIdentifierYieldReason()
1746 {
1747 if (strictMode())
1748 return "in strict mode";
1749 if (currentScope()->isGenerator())
1750 return "in a generator function";
1751 RELEASE_ASSERT_NOT_REACHED();
1752 return nullptr;
1753 }
1754
1755 enum class FunctionParsePhase { Parameters, Body };
1756 struct ParserState {
1757 int assignmentCount { 0 };
1758 int nonLHSCount { 0 };
1759 int nonTrivialExpressionCount { 0 };
1760 FunctionParsePhase functionParsePhase { FunctionParsePhase::Body };
1761 const Identifier* lastIdentifier { nullptr };
1762 const Identifier* lastFunctionName { nullptr };
1763 bool allowAwait { true };
1764 };
1765
1766 // If you're using this directly, you probably should be using
1767 // createSavePoint() instead.
1768 ALWAYS_INLINE ParserState internalSaveParserState()
1769 {
1770 return m_parserState;
1771 }
1772
1773 ALWAYS_INLINE void restoreParserState(const ParserState& state)
1774 {
1775 m_parserState = state;
1776 }
1777
1778 struct LexerState {
1779 int startOffset;
1780 unsigned oldLineStartOffset;
1781 unsigned oldLastLineNumber;
1782 unsigned oldLineNumber;
1783 bool hasLineTerminatorBeforeToken;
1784 };
1785
1786 // If you're using this directly, you probably should be using
1787 // createSavePoint() instead.
1788 // i.e, if you parse any kind of AssignmentExpression between
1789 // saving/restoring, you should definitely not be using this directly.
1790 ALWAYS_INLINE LexerState internalSaveLexerState()
1791 {
1792 LexerState result;
1793 result.startOffset = m_token.m_location.startOffset;
1794 result.oldLineStartOffset = m_token.m_location.lineStartOffset;
1795 result.oldLastLineNumber = m_lexer->lastLineNumber();
1796 result.oldLineNumber = m_lexer->lineNumber();
1797 result.hasLineTerminatorBeforeToken = m_lexer->hasLineTerminatorBeforeToken();
1798 ASSERT(static_cast<unsigned>(result.startOffset) >= result.oldLineStartOffset);
1799 return result;
1800 }
1801
1802 ALWAYS_INLINE void restoreLexerState(const LexerState& lexerState)
1803 {
1804 // setOffset clears lexer errors.
1805 m_lexer->setOffset(lexerState.startOffset, lexerState.oldLineStartOffset);
1806 m_lexer->setLineNumber(lexerState.oldLineNumber);
1807 m_lexer->setHasLineTerminatorBeforeToken(lexerState.hasLineTerminatorBeforeToken);
1808 nextWithoutClearingLineTerminator();
1809 m_lexer->setLastLineNumber(lexerState.oldLastLineNumber);
1810 }
1811
1812 struct SavePoint {
1813 ParserState parserState;
1814 LexerState lexerState;
1815 };
1816
1817 struct SavePointWithError : public SavePoint {
1818 bool lexerError;
1819 String lexerErrorMessage;
1820 String parserErrorMessage;
1821 };
1822
1823 ALWAYS_INLINE void internalSaveState(SavePoint& savePoint)
1824 {
1825 savePoint.parserState = internalSaveParserState();
1826 savePoint.lexerState = internalSaveLexerState();
1827 }
1828
1829 ALWAYS_INLINE SavePointWithError createSavePointForError()
1830 {
1831 SavePointWithError savePoint;
1832 internalSaveState(savePoint);
1833 savePoint.lexerError = m_lexer->sawError();
1834 savePoint.lexerErrorMessage = m_lexer->getErrorMessage();
1835 savePoint.parserErrorMessage = m_errorMessage;
1836 return savePoint;
1837 }
1838
1839 ALWAYS_INLINE SavePoint createSavePoint()
1840 {
1841 ASSERT(!hasError());
1842 SavePoint savePoint;
1843 internalSaveState(savePoint);
1844 return savePoint;
1845 }
1846
1847 ALWAYS_INLINE void internalRestoreState(const SavePoint& savePoint)
1848 {
1849 restoreLexerState(savePoint.lexerState);
1850 restoreParserState(savePoint.parserState);
1851 }
1852
1853 ALWAYS_INLINE void restoreSavePointWithError(const SavePointWithError& savePoint)
1854 {
1855 internalRestoreState(savePoint);
1856 m_lexer->setSawError(savePoint.lexerError);
1857 m_lexer->setErrorMessage(savePoint.lexerErrorMessage);
1858 m_errorMessage = savePoint.parserErrorMessage;
1859 }
1860
1861 ALWAYS_INLINE void restoreSavePoint(const SavePoint& savePoint)
1862 {
1863 internalRestoreState(savePoint);
1864 m_errorMessage = String();
1865 }
1866
1867 VM* m_vm;
1868 const SourceCode* m_source;
1869 ParserArena m_parserArena;
1870 std::unique_ptr<LexerType> m_lexer;
1871 FunctionParameters* m_parameters { nullptr };
1872
1873 ParserState m_parserState;
1874
1875 bool m_hasStackOverflow;
1876 String m_errorMessage;
1877 JSToken m_token;
1878 bool m_allowsIn;
1879 JSTextPosition m_lastTokenEndPosition;
1880 int m_statementDepth;
1881 RefPtr<SourceProviderCache> m_functionCache;
1882 SourceElements* m_sourceElements;
1883 bool m_parsingBuiltin;
1884 JSParserScriptMode m_scriptMode;
1885 SuperBinding m_superBinding;
1886 ConstructorKind m_defaultConstructorKind;
1887 VariableEnvironment m_varDeclarations;
1888 DeclarationStacks::FunctionStack m_funcDeclarations;
1889 UniquedStringImplPtrSet m_sloppyModeHoistedFunctions;
1890 CodeFeatures m_features;
1891 int m_numConstants;
1892 ExpressionErrorClassifier* m_expressionErrorClassifier;
1893 bool m_isEvalContext;
1894 bool m_immediateParentAllowsFunctionDeclarationInStatement;
1895 RefPtr<ModuleScopeData> m_moduleScopeData;
1896 DebuggerParseData* m_debuggerParseData;
1897 CallOrApplyDepthScope* m_callOrApplyDepthScope { nullptr };
1898 bool m_seenTaggedTemplate { false };
1899};
1900
1901
1902template <typename LexerType>
1903template <class ParsedNode>
1904std::unique_ptr<ParsedNode> Parser<LexerType>::parse(ParserError& error, const Identifier& calleeName, SourceParseMode parseMode, ParsingContext parsingContext, Optional<int> functionConstructorParametersEndPosition)
1905{
1906 int errLine;
1907 String errMsg;
1908
1909 if (ParsedNode::scopeIsFunction)
1910 m_lexer->setIsReparsingFunction();
1911
1912 m_sourceElements = 0;
1913
1914 errLine = -1;
1915 errMsg = String();
1916
1917 JSTokenLocation startLocation(tokenLocation());
1918 ASSERT(m_source->startColumn() > OrdinalNumber::beforeFirst());
1919 unsigned startColumn = m_source->startColumn().zeroBasedInt();
1920
1921 String parseError = parseInner(calleeName, parseMode, parsingContext, functionConstructorParametersEndPosition);
1922
1923 int lineNumber = m_lexer->lineNumber();
1924 bool lexError = m_lexer->sawError();
1925 String lexErrorMessage = lexError ? m_lexer->getErrorMessage() : String();
1926 ASSERT(lexErrorMessage.isNull() != lexError);
1927 m_lexer->clear();
1928
1929 if (!parseError.isNull() || lexError) {
1930 errLine = lineNumber;
1931 errMsg = !lexErrorMessage.isNull() ? lexErrorMessage : parseError;
1932 m_sourceElements = 0;
1933 }
1934
1935 std::unique_ptr<ParsedNode> result;
1936 if (m_sourceElements) {
1937 JSTokenLocation endLocation;
1938 endLocation.line = m_lexer->lineNumber();
1939 endLocation.lineStartOffset = m_lexer->currentLineStartOffset();
1940 endLocation.startOffset = m_lexer->currentOffset();
1941 unsigned endColumn = endLocation.startOffset - endLocation.lineStartOffset;
1942 result = std::make_unique<ParsedNode>(m_parserArena,
1943 startLocation,
1944 endLocation,
1945 startColumn,
1946 endColumn,
1947 m_sourceElements,
1948 m_varDeclarations,
1949 WTFMove(m_funcDeclarations),
1950 currentScope()->finalizeLexicalEnvironment(),
1951 WTFMove(m_sloppyModeHoistedFunctions),
1952 m_parameters,
1953 *m_source,
1954 m_features,
1955 currentScope()->innerArrowFunctionFeatures(),
1956 m_numConstants,
1957 WTFMove(m_moduleScopeData));
1958 result->setLoc(m_source->firstLine().oneBasedInt(), m_lexer->lineNumber(), m_lexer->currentOffset(), m_lexer->currentLineStartOffset());
1959 result->setEndOffset(m_lexer->currentOffset());
1960
1961 if (!isFunctionParseMode(parseMode)) {
1962 m_source->provider()->setSourceURLDirective(m_lexer->sourceURLDirective());
1963 m_source->provider()->setSourceMappingURLDirective(m_lexer->sourceMappingURLDirective());
1964 }
1965 } else {
1966 // We can never see a syntax error when reparsing a function, since we should have
1967 // reported the error when parsing the containing program or eval code. So if we're
1968 // parsing a function body node, we assume that what actually happened here is that
1969 // we ran out of stack while parsing. If we see an error while parsing eval or program
1970 // code we assume that it was a syntax error since running out of stack is much less
1971 // likely, and we are currently unable to distinguish between the two cases.
1972 if (isFunctionMetadataNode(static_cast<ParsedNode*>(0)) || m_hasStackOverflow)
1973 error = ParserError(ParserError::StackOverflow, ParserError::SyntaxErrorNone, m_token);
1974 else {
1975 ParserError::SyntaxErrorType errorType = ParserError::SyntaxErrorIrrecoverable;
1976 if (m_token.m_type == EOFTOK)
1977 errorType = ParserError::SyntaxErrorRecoverable;
1978 else if (m_token.m_type & UnterminatedErrorTokenFlag) {
1979 // Treat multiline capable unterminated literals as recoverable.
1980 if (m_token.m_type == UNTERMINATED_MULTILINE_COMMENT_ERRORTOK || m_token.m_type == UNTERMINATED_TEMPLATE_LITERAL_ERRORTOK)
1981 errorType = ParserError::SyntaxErrorRecoverable;
1982 else
1983 errorType = ParserError::SyntaxErrorUnterminatedLiteral;
1984 }
1985
1986 if (isEvalNode<ParsedNode>())
1987 error = ParserError(ParserError::EvalError, errorType, m_token, errMsg, errLine);
1988 else
1989 error = ParserError(ParserError::SyntaxError, errorType, m_token, errMsg, errLine);
1990 }
1991 }
1992
1993 return result;
1994}
1995
1996template <class ParsedNode>
1997std::unique_ptr<ParsedNode> parse(
1998 VM* vm, const SourceCode& source,
1999 const Identifier& name, JSParserBuiltinMode builtinMode,
2000 JSParserStrictMode strictMode, JSParserScriptMode scriptMode, SourceParseMode parseMode, SuperBinding superBinding,
2001 ParserError& error, JSTextPosition* positionBeforeLastNewline = nullptr,
2002 ConstructorKind defaultConstructorKind = ConstructorKind::None,
2003 DerivedContextType derivedContextType = DerivedContextType::None,
2004 EvalContextType evalContextType = EvalContextType::None,
2005 DebuggerParseData* debuggerParseData = nullptr)
2006{
2007 ASSERT(!source.provider()->source().isNull());
2008
2009 MonotonicTime before;
2010 if (UNLIKELY(Options::reportParseTimes()))
2011 before = MonotonicTime::now();
2012
2013 std::unique_ptr<ParsedNode> result;
2014 if (source.provider()->source().is8Bit()) {
2015 Parser<Lexer<LChar>> parser(vm, source, builtinMode, strictMode, scriptMode, parseMode, superBinding, defaultConstructorKind, derivedContextType, isEvalNode<ParsedNode>(), evalContextType, debuggerParseData);
2016 result = parser.parse<ParsedNode>(error, name, parseMode, isEvalNode<ParsedNode>() ? ParsingContext::Eval : ParsingContext::Program);
2017 if (positionBeforeLastNewline)
2018 *positionBeforeLastNewline = parser.positionBeforeLastNewline();
2019 if (builtinMode == JSParserBuiltinMode::Builtin) {
2020 if (!result) {
2021 ASSERT(error.isValid());
2022 if (error.type() != ParserError::StackOverflow)
2023 dataLogLn("Unexpected error compiling builtin: ", error.message());
2024 }
2025 }
2026 } else {
2027 ASSERT_WITH_MESSAGE(defaultConstructorKind == ConstructorKind::None, "BuiltinExecutables::createDefaultConstructor should always use a 8-bit string");
2028 Parser<Lexer<UChar>> parser(vm, source, builtinMode, strictMode, scriptMode, parseMode, superBinding, defaultConstructorKind, derivedContextType, isEvalNode<ParsedNode>(), evalContextType, debuggerParseData);
2029 result = parser.parse<ParsedNode>(error, name, parseMode, isEvalNode<ParsedNode>() ? ParsingContext::Eval : ParsingContext::Program);
2030 if (positionBeforeLastNewline)
2031 *positionBeforeLastNewline = parser.positionBeforeLastNewline();
2032 }
2033
2034 if (UNLIKELY(Options::reportParseTimes())) {
2035 MonotonicTime after = MonotonicTime::now();
2036 ParseHash hash(source);
2037 dataLogLn(result ? "Parsed #" : "Failed to parse #", hash.hashForCall(), "/#", hash.hashForConstruct(), " in ", (after - before).milliseconds(), " ms.");
2038 }
2039
2040 return result;
2041}
2042
2043inline std::unique_ptr<ProgramNode> parseFunctionForFunctionConstructor(VM& vm, const SourceCode& source, ParserError& error, JSTextPosition* positionBeforeLastNewline, Optional<int> functionConstructorParametersEndPosition)
2044{
2045 ASSERT(!source.provider()->source().isNull());
2046
2047 MonotonicTime before;
2048 if (UNLIKELY(Options::reportParseTimes()))
2049 before = MonotonicTime::now();
2050
2051 Identifier name;
2052 bool isEvalNode = false;
2053 std::unique_ptr<ProgramNode> result;
2054 if (source.provider()->source().is8Bit()) {
2055 Parser<Lexer<LChar>> parser(&vm, source, JSParserBuiltinMode::NotBuiltin, JSParserStrictMode::NotStrict, JSParserScriptMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, ConstructorKind::None, DerivedContextType::None, isEvalNode, EvalContextType::None, nullptr);
2056 result = parser.parse<ProgramNode>(error, name, SourceParseMode::ProgramMode, ParsingContext::FunctionConstructor, functionConstructorParametersEndPosition);
2057 if (positionBeforeLastNewline)
2058 *positionBeforeLastNewline = parser.positionBeforeLastNewline();
2059 } else {
2060 Parser<Lexer<UChar>> parser(&vm, source, JSParserBuiltinMode::NotBuiltin, JSParserStrictMode::NotStrict, JSParserScriptMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, ConstructorKind::None, DerivedContextType::None, isEvalNode, EvalContextType::None, nullptr);
2061 result = parser.parse<ProgramNode>(error, name, SourceParseMode::ProgramMode, ParsingContext::FunctionConstructor, functionConstructorParametersEndPosition);
2062 if (positionBeforeLastNewline)
2063 *positionBeforeLastNewline = parser.positionBeforeLastNewline();
2064 }
2065
2066 if (UNLIKELY(Options::reportParseTimes())) {
2067 MonotonicTime after = MonotonicTime::now();
2068 ParseHash hash(source);
2069 dataLogLn(result ? "Parsed #" : "Failed to parse #", hash.hashForCall(), "/#", hash.hashForConstruct(), " in ", (after - before).milliseconds(), " ms.");
2070 }
2071
2072 return result;
2073}
2074
2075
2076} // namespace
2077