Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: set ts=8 sts=4 et sw=4 tw=99:
3 : * This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : /* JS parser. */
8 :
9 : #ifndef frontend_Parser_h
10 : #define frontend_Parser_h
11 :
12 : #include "mozilla/Array.h"
13 : #include "mozilla/Maybe.h"
14 : #include "mozilla/TypeTraits.h"
15 :
16 : #include "jsiter.h"
17 : #include "jspubtd.h"
18 :
19 : #include "ds/Nestable.h"
20 : #include "frontend/BytecodeCompiler.h"
21 : #include "frontend/FullParseHandler.h"
22 : #include "frontend/LanguageExtensions.h"
23 : #include "frontend/NameAnalysisTypes.h"
24 : #include "frontend/NameCollections.h"
25 : #include "frontend/SharedContext.h"
26 : #include "frontend/SyntaxParseHandler.h"
27 :
28 : namespace js {
29 :
30 : class ModuleObject;
31 :
32 : namespace frontend {
33 :
34 : class ParserBase;
35 :
36 : template <class ParseHandler, typename CharT> class Parser;
37 :
38 : /*
39 : * The struct ParseContext stores information about the current parsing context,
40 : * which is part of the parser state (see the field Parser::pc). The current
41 : * parsing context is either the global context, or the function currently being
42 : * parsed. When the parser encounters a function definition, it creates a new
43 : * ParseContext, makes it the new current context.
44 : */
45 7641 : class ParseContext : public Nestable<ParseContext>
46 : {
47 : public:
48 : // The intra-function statement stack.
49 : //
50 : // Used for early error checking that depend on the nesting structure of
51 : // statements, such as continue/break targets, labels, and unbraced
52 : // lexical declarations.
53 19901 : class Statement : public Nestable<Statement>
54 : {
55 : StatementKind kind_;
56 :
57 : public:
58 : using Nestable<Statement>::enclosing;
59 : using Nestable<Statement>::findNearest;
60 :
61 19901 : Statement(ParseContext* pc, StatementKind kind)
62 19901 : : Nestable<Statement>(&pc->innermostStatement_),
63 19901 : kind_(kind)
64 19901 : { }
65 :
66 : template <typename T> inline bool is() const;
67 : template <typename T> inline T& as();
68 :
69 6753 : StatementKind kind() const {
70 6753 : return kind_;
71 : }
72 :
73 501 : void refineForKind(StatementKind newForKind) {
74 501 : MOZ_ASSERT(kind_ == StatementKind::ForLoop);
75 501 : MOZ_ASSERT(newForKind == StatementKind::ForInLoop ||
76 : newForKind == StatementKind::ForOfLoop);
77 501 : kind_ = newForKind;
78 501 : }
79 : };
80 :
81 0 : class LabelStatement : public Statement
82 : {
83 : RootedAtom label_;
84 :
85 : public:
86 0 : LabelStatement(ParseContext* pc, JSAtom* label)
87 0 : : Statement(pc, StatementKind::Label),
88 0 : label_(pc->sc_->context, label)
89 0 : { }
90 :
91 0 : HandleAtom label() const {
92 0 : return label_;
93 : }
94 : };
95 :
96 32 : struct ClassStatement : public Statement
97 : {
98 : FunctionBox* constructorBox;
99 :
100 32 : explicit ClassStatement(ParseContext* pc)
101 32 : : Statement(pc, StatementKind::Class),
102 32 : constructorBox(nullptr)
103 32 : { }
104 : };
105 :
106 : // The intra-function scope stack.
107 : //
108 : // Tracks declared and used names within a scope.
109 18834 : class Scope : public Nestable<Scope>
110 : {
111 : // Names declared in this scope. Corresponds to the union of
112 : // VarDeclaredNames and LexicallyDeclaredNames in the ES spec.
113 : //
114 : // A 'var' declared name is a member of the declared name set of every
115 : // scope in its scope contour.
116 : //
117 : // A lexically declared name is a member only of the declared name set of
118 : // the scope in which it is declared.
119 : PooledMapPtr<DeclaredNameMap> declared_;
120 :
121 : // FunctionBoxes in this scope that need to be considered for Annex
122 : // B.3.3 semantics. This is checked on Scope exit, as by then we have
123 : // all the declared names and would know if Annex B.3.3 is applicable.
124 : PooledVectorPtr<FunctionBoxVector> possibleAnnexBFunctionBoxes_;
125 :
126 : // Monotonically increasing id.
127 : uint32_t id_;
128 :
129 29316 : bool maybeReportOOM(ParseContext* pc, bool result) {
130 29316 : if (!result)
131 0 : ReportOutOfMemory(pc->sc()->context);
132 29316 : return result;
133 : }
134 :
135 : public:
136 : using DeclaredNamePtr = DeclaredNameMap::Ptr;
137 : using AddDeclaredNamePtr = DeclaredNameMap::AddPtr;
138 :
139 : using Nestable<Scope>::enclosing;
140 :
141 : explicit inline Scope(ParserBase* parser);
142 :
143 : void dump(ParseContext* pc);
144 :
145 92525 : uint32_t id() const {
146 92525 : return id_;
147 : }
148 :
149 18834 : MOZ_MUST_USE bool init(ParseContext* pc) {
150 18834 : if (id_ == UINT32_MAX) {
151 0 : pc->tokenStream_.reportErrorNoOffset(JSMSG_NEED_DIET, js_script_str);
152 0 : return false;
153 : }
154 :
155 18834 : return declared_.acquire(pc->sc()->context);
156 : }
157 :
158 13020 : DeclaredNamePtr lookupDeclaredName(JSAtom* name) {
159 13020 : return declared_->lookup(name);
160 : }
161 :
162 30228 : AddDeclaredNamePtr lookupDeclaredNameForAdd(JSAtom* name) {
163 30228 : return declared_->lookupForAdd(name);
164 : }
165 :
166 29316 : MOZ_MUST_USE bool addDeclaredName(ParseContext* pc, AddDeclaredNamePtr& p, JSAtom* name,
167 : DeclarationKind kind, uint32_t pos)
168 : {
169 29316 : return maybeReportOOM(pc, declared_->add(p, name, DeclaredNameInfo(kind, pos)));
170 : }
171 :
172 : // Add a FunctionBox as a possible candidate for Annex B.3.3 semantics.
173 : MOZ_MUST_USE bool addPossibleAnnexBFunctionBox(ParseContext* pc, FunctionBox* funbox);
174 :
175 : // Check if the candidate function boxes for Annex B.3.3 should in
176 : // fact get Annex B semantics. Checked on Scope exit.
177 : MOZ_MUST_USE bool propagateAndMarkAnnexBFunctionBoxes(ParseContext* pc);
178 :
179 : // Add and remove catch parameter names. Used to implement the odd
180 : // semantics of catch bodies.
181 : bool addCatchParameters(ParseContext* pc, Scope& catchParamScope);
182 : void removeCatchParameters(ParseContext* pc, Scope& catchParamScope);
183 :
184 7641 : void useAsVarScope(ParseContext* pc) {
185 7641 : MOZ_ASSERT(!pc->varScope_);
186 7641 : pc->varScope_ = this;
187 7641 : }
188 :
189 : // An iterator for the set of names a scope binds: the set of all
190 : // declared names for 'var' scopes, and the set of lexically declared
191 : // names for non-'var' scopes.
192 34161 : class BindingIter
193 : {
194 : friend class Scope;
195 :
196 : DeclaredNameMap::Range declaredRange_;
197 : mozilla::DebugOnly<uint32_t> count_;
198 : bool isVarScope_;
199 :
200 34161 : BindingIter(Scope& scope, bool isVarScope)
201 34161 : : declaredRange_(scope.declared_->all()),
202 : count_(0),
203 34161 : isVarScope_(isVarScope)
204 : {
205 34161 : settle();
206 34161 : }
207 :
208 90402 : void settle() {
209 : // Both var and lexically declared names are binding in a var
210 : // scope.
211 90402 : if (isVarScope_)
212 67992 : return;
213 :
214 : // Otherwise, pop only lexically declared names are
215 : // binding. Pop the range until we find such a name.
216 2956 : while (!declaredRange_.empty()) {
217 8536 : if (BindingKindIsLexical(kind()))
218 5580 : break;
219 2956 : declaredRange_.popFront();
220 : }
221 : }
222 :
223 : public:
224 293362 : bool done() const {
225 293362 : return declaredRange_.empty();
226 : }
227 :
228 90402 : explicit operator bool() const {
229 90402 : return !done();
230 : }
231 :
232 56806 : JSAtom* name() {
233 56806 : MOZ_ASSERT(!done());
234 56806 : return declaredRange_.front().key();
235 : }
236 :
237 52904 : DeclarationKind declarationKind() {
238 52904 : MOZ_ASSERT(!done());
239 52904 : return declaredRange_.front().value()->kind();
240 : }
241 :
242 44372 : BindingKind kind() {
243 44372 : return DeclarationKindToBindingKind(declarationKind());
244 : }
245 :
246 35797 : bool closedOver() {
247 35797 : MOZ_ASSERT(!done());
248 35797 : return declaredRange_.front().value()->closedOver();
249 : }
250 :
251 1212 : void setClosedOver() {
252 1212 : MOZ_ASSERT(!done());
253 1212 : return declaredRange_.front().value()->setClosedOver();
254 : }
255 :
256 56241 : void operator++(int) {
257 56241 : MOZ_ASSERT(!done());
258 56241 : MOZ_ASSERT(count_ != UINT32_MAX);
259 56241 : declaredRange_.popFront();
260 56241 : settle();
261 56241 : }
262 : };
263 :
264 : inline BindingIter bindings(ParseContext* pc);
265 : };
266 :
267 536 : class VarScope : public Scope
268 : {
269 : public:
270 : explicit inline VarScope(ParserBase* parser);
271 : };
272 :
273 : private:
274 : // Trace logging of parsing time.
275 : AutoFrontendTraceLog traceLog_;
276 :
277 : // Context shared between parsing and bytecode generation.
278 : SharedContext* sc_;
279 :
280 : // TokenStream used for error reporting.
281 : TokenStreamAnyChars& tokenStream_;
282 :
283 : // The innermost statement, i.e., top of the statement stack.
284 : Statement* innermostStatement_;
285 :
286 : // The innermost scope, i.e., top of the scope stack.
287 : //
288 : // The outermost scope in the stack is usually varScope_. In the case of
289 : // functions, the outermost scope is functionScope_, which may be
290 : // varScope_. See comment above functionScope_.
291 : Scope* innermostScope_;
292 :
293 : // If isFunctionBox() and the function is a named lambda, the DeclEnv
294 : // scope for named lambdas.
295 : mozilla::Maybe<Scope> namedLambdaScope_;
296 :
297 : // If isFunctionBox(), the scope for the function. If there are no
298 : // parameter expressions, this is scope for the entire function. If there
299 : // are parameter expressions, this holds the special function names
300 : // ('.this', 'arguments') and the formal parameers.
301 : mozilla::Maybe<Scope> functionScope_;
302 :
303 : // The body-level scope. This always exists, but not necessarily at the
304 : // beginning of parsing the script in the case of functions with parameter
305 : // expressions.
306 : Scope* varScope_;
307 :
308 : // Simple formal parameter names, in order of appearance. Only used when
309 : // isFunctionBox().
310 : PooledVectorPtr<AtomVector> positionalFormalParameterNames_;
311 :
312 : // Closed over binding names, in order of appearance. Null-delimited
313 : // between scopes. Only used when syntax parsing.
314 : PooledVectorPtr<AtomVector> closedOverBindingsForLazy_;
315 :
316 : // Monotonically increasing id.
317 : uint32_t scriptId_;
318 :
319 : // Set when compiling a function using Parser::standaloneFunctionBody via
320 : // the Function or Generator constructor.
321 : bool isStandaloneFunctionBody_;
322 :
323 : // Set when encountering a super.property inside a method. We need to mark
324 : // the nearest super scope as needing a home object.
325 : bool superScopeNeedsHomeObject_;
326 :
327 : public:
328 : // lastYieldOffset stores the offset of the last yield that was parsed.
329 : // NoYieldOffset is its initial value.
330 : static const uint32_t NoYieldOffset = UINT32_MAX;
331 : uint32_t lastYieldOffset;
332 :
333 : // lastAwaitOffset stores the offset of the last await that was parsed.
334 : // NoAwaitOffset is its initial value.
335 : static const uint32_t NoAwaitOffset = UINT32_MAX;
336 : uint32_t lastAwaitOffset;
337 :
338 : // All inner functions in this context. Only used when syntax parsing.
339 : Rooted<GCVector<JSFunction*, 8>> innerFunctionsForLazy;
340 :
341 : // In a function context, points to a Directive struct that can be updated
342 : // to reflect new directives encountered in the Directive Prologue that
343 : // require reparsing the function. In global/module/generator-tail contexts,
344 : // we don't need to reparse when encountering a DirectivePrologue so this
345 : // pointer may be nullptr.
346 : Directives* newDirectives;
347 :
348 : // Set when parsing a function and it has 'return <expr>;'
349 : bool funHasReturnExpr;
350 :
351 : // Set when parsing a function and it has 'return;'
352 : bool funHasReturnVoid;
353 :
354 : public:
355 : template <class ParseHandler, typename CharT>
356 7641 : ParseContext(Parser<ParseHandler, CharT>* prs, SharedContext* sc, Directives* newDirectives)
357 7641 : : Nestable<ParseContext>(&prs->pc),
358 7641 : traceLog_(sc->context,
359 : mozilla::IsSame<ParseHandler, FullParseHandler>::value
360 : ? TraceLogger_ParsingFull
361 : : TraceLogger_ParsingSyntax,
362 : prs->tokenStream),
363 : sc_(sc),
364 : tokenStream_(prs->tokenStream),
365 : innermostStatement_(nullptr),
366 : innermostScope_(nullptr),
367 : varScope_(nullptr),
368 7641 : positionalFormalParameterNames_(prs->context->frontendCollectionPool()),
369 7641 : closedOverBindingsForLazy_(prs->context->frontendCollectionPool()),
370 7641 : scriptId_(prs->usedNames.nextScriptId()),
371 : isStandaloneFunctionBody_(false),
372 : superScopeNeedsHomeObject_(false),
373 : lastYieldOffset(NoYieldOffset),
374 : lastAwaitOffset(NoAwaitOffset),
375 15282 : innerFunctionsForLazy(prs->context, GCVector<JSFunction*, 8>(prs->context)),
376 : newDirectives(newDirectives),
377 : funHasReturnExpr(false),
378 53487 : funHasReturnVoid(false)
379 : {
380 7641 : if (isFunctionBox()) {
381 7373 : if (functionBox()->function()->isNamedLambda())
382 714 : namedLambdaScope_.emplace(prs);
383 7373 : functionScope_.emplace(prs);
384 : }
385 7641 : }
386 :
387 : MOZ_MUST_USE bool init();
388 :
389 218396 : SharedContext* sc() {
390 218396 : return sc_;
391 : }
392 :
393 96987 : bool isFunctionBox() const {
394 96987 : return sc_->isFunctionBox();
395 : }
396 :
397 106753 : FunctionBox* functionBox() {
398 106753 : return sc_->asFunctionBox();
399 : }
400 :
401 9485 : Statement* innermostStatement() {
402 9485 : return innermostStatement_;
403 : }
404 :
405 95495 : Scope* innermostScope() {
406 : // There is always at least one scope: the 'var' scope.
407 95495 : MOZ_ASSERT(innermostScope_);
408 95495 : return innermostScope_;
409 : }
410 :
411 1101 : Scope& namedLambdaScope() {
412 1101 : MOZ_ASSERT(functionBox()->function()->isNamedLambda());
413 1101 : return *namedLambdaScope_;
414 : }
415 :
416 39535 : Scope& functionScope() {
417 39535 : MOZ_ASSERT(isFunctionBox());
418 39535 : return *functionScope_;
419 : }
420 :
421 33473 : Scope& varScope() {
422 33473 : MOZ_ASSERT(varScope_);
423 33473 : return *varScope_;
424 : }
425 :
426 7654 : bool isFunctionExtraBodyVarScopeInnermost() {
427 8056 : return isFunctionBox() && functionBox()->hasParameterExprs &&
428 8056 : innermostScope() == varScope_;
429 : }
430 :
431 : template <typename Predicate /* (Statement*) -> bool */>
432 6792 : Statement* findInnermostStatement(Predicate predicate) {
433 6792 : return Statement::findNearest(innermostStatement_, predicate);
434 : }
435 :
436 : template <typename T, typename Predicate /* (Statement*) -> bool */>
437 0 : T* findInnermostStatement(Predicate predicate) {
438 0 : return Statement::findNearest<T>(innermostStatement_, predicate);
439 : }
440 :
441 : template <typename T>
442 31 : T* findInnermostStatement() {
443 31 : return Statement::findNearest<T>(innermostStatement_);
444 : }
445 :
446 31264 : AtomVector& positionalFormalParameterNames() {
447 31264 : return *positionalFormalParameterNames_;
448 : }
449 :
450 9686 : AtomVector& closedOverBindingsForLazy() {
451 9686 : return *closedOverBindingsForLazy_;
452 : }
453 :
454 : // True if we are at the topmost level of a entire script or function body.
455 : // For example, while parsing this code we would encounter f1 and f2 at
456 : // body level, but we would not encounter f3 or f4 at body level:
457 : //
458 : // function f1() { function f2() { } }
459 : // if (cond) { function f3() { if (cond) { function f4() { } } } }
460 : //
461 17550 : bool atBodyLevel() {
462 17550 : return !innermostStatement_;
463 : }
464 :
465 : bool atGlobalLevel() {
466 : return atBodyLevel() && sc_->isGlobalContext();
467 : }
468 :
469 : // True if we are at the topmost level of a module only.
470 1831 : bool atModuleLevel() {
471 1831 : return atBodyLevel() && sc_->isModuleContext();
472 : }
473 :
474 15 : void setIsStandaloneFunctionBody() {
475 15 : isStandaloneFunctionBody_ = true;
476 15 : }
477 :
478 0 : bool isStandaloneFunctionBody() const {
479 0 : return isStandaloneFunctionBody_;
480 : }
481 :
482 13 : void setSuperScopeNeedsHomeObject() {
483 13 : MOZ_ASSERT(sc_->allowSuperProperty());
484 13 : superScopeNeedsHomeObject_ = true;
485 13 : }
486 :
487 8853 : bool superScopeNeedsHomeObject() const {
488 8853 : return superScopeNeedsHomeObject_;
489 : }
490 :
491 133479 : bool useAsmOrInsideUseAsm() const {
492 133479 : return sc_->isFunctionBox() && sc_->asFunctionBox()->useAsmOrInsideUseAsm();
493 : }
494 :
495 : // Most functions start off being parsed as non-generators.
496 : // Non-generators transition to LegacyGenerator on parsing "yield" in JS 1.7.
497 : // An ES6 generator is marked as a "star generator" before its body is parsed.
498 36807 : GeneratorKind generatorKind() const {
499 36807 : return sc_->isFunctionBox() ? sc_->asFunctionBox()->generatorKind() : NotGenerator;
500 : }
501 :
502 14664 : bool isLegacyGenerator() const {
503 14664 : return generatorKind() == LegacyGenerator;
504 : }
505 :
506 7373 : bool isStarGenerator() const {
507 7373 : return generatorKind() == StarGenerator;
508 : }
509 :
510 24018 : bool isAsync() const {
511 24018 : return sc_->isFunctionBox() && sc_->asFunctionBox()->isAsync();
512 : }
513 :
514 7373 : bool needsDotGeneratorName() const {
515 7373 : return isStarGenerator() || isLegacyGenerator() || isAsync();
516 : }
517 :
518 7373 : FunctionAsyncKind asyncKind() const {
519 7373 : return isAsync() ? AsyncFunction : SyncFunction;
520 : }
521 :
522 7 : bool isArrowFunction() const {
523 7 : return sc_->isFunctionBox() && sc_->asFunctionBox()->function()->isArrow();
524 : }
525 :
526 0 : bool isMethod() const {
527 0 : return sc_->isFunctionBox() && sc_->asFunctionBox()->function()->isMethod();
528 : }
529 :
530 98679 : uint32_t scriptId() const {
531 98679 : return scriptId_;
532 : }
533 :
534 : bool annexBAppliesToLexicalFunctionInInnermostScope(FunctionBox* funbox);
535 :
536 : bool tryDeclareVar(HandlePropertyName name, DeclarationKind kind, uint32_t beginPos,
537 : mozilla::Maybe<DeclarationKind>* redeclaredKind, uint32_t* prevPos);
538 :
539 : private:
540 : mozilla::Maybe<DeclarationKind> isVarRedeclaredInInnermostScope(HandlePropertyName name,
541 : DeclarationKind kind);
542 : mozilla::Maybe<DeclarationKind> isVarRedeclaredInEval(HandlePropertyName name,
543 : DeclarationKind kind);
544 :
545 : enum DryRunOption { NotDryRun, DryRunInnermostScopeOnly };
546 : template <DryRunOption dryRunOption>
547 : bool tryDeclareVarHelper(HandlePropertyName name, DeclarationKind kind, uint32_t beginPos,
548 : mozilla::Maybe<DeclarationKind>* redeclaredKind, uint32_t* prevPos);
549 :
550 : };
551 :
552 : template <>
553 : inline bool
554 0 : ParseContext::Statement::is<ParseContext::LabelStatement>() const
555 : {
556 0 : return kind_ == StatementKind::Label;
557 : }
558 :
559 : template <>
560 : inline bool
561 87 : ParseContext::Statement::is<ParseContext::ClassStatement>() const
562 : {
563 87 : return kind_ == StatementKind::Class;
564 : }
565 :
566 : template <typename T>
567 : inline T&
568 31 : ParseContext::Statement::as()
569 : {
570 31 : MOZ_ASSERT(is<T>());
571 31 : return static_cast<T&>(*this);
572 : }
573 :
574 : inline ParseContext::Scope::BindingIter
575 34161 : ParseContext::Scope::bindings(ParseContext* pc)
576 : {
577 : // In function scopes with parameter expressions, function special names
578 : // (like '.this') are declared as vars in the function scope, despite its
579 : // not being the var scope.
580 34161 : return BindingIter(*this, pc->varScope_ == this || pc->functionScope_.ptrOr(nullptr) == this);
581 : }
582 :
583 : inline
584 5951 : Directives::Directives(ParseContext* parent)
585 5951 : : strict_(parent->sc()->strict()),
586 5951 : asmJS_(parent->useAsmOrInsideUseAsm())
587 5951 : {}
588 :
589 : enum VarContext { HoistVars, DontHoistVars };
590 : enum PropListType { ObjectLiteral, ClassBody, DerivedClassBody };
591 : enum class PropertyType {
592 : Normal,
593 : Shorthand,
594 : CoverInitializedName,
595 : Getter,
596 : GetterNoExpressionClosure,
597 : Setter,
598 : SetterNoExpressionClosure,
599 : Method,
600 : GeneratorMethod,
601 : AsyncMethod,
602 : AsyncGeneratorMethod,
603 : Constructor,
604 : DerivedConstructor
605 : };
606 :
607 : // Specify a value for an ES6 grammar parametrization. We have no enum for
608 : // [Return] because its behavior is exactly equivalent to checking whether
609 : // we're in a function box -- easier and simpler than passing an extra
610 : // parameter everywhere.
611 : enum YieldHandling { YieldIsName, YieldIsKeyword };
612 : enum AwaitHandling : uint8_t { AwaitIsName, AwaitIsKeyword, AwaitIsModuleKeyword };
613 : enum InHandling { InAllowed, InProhibited };
614 : enum DefaultHandling { NameRequired, AllowDefaultName };
615 : enum TripledotHandling { TripledotAllowed, TripledotProhibited };
616 :
617 : // A data structure for tracking used names per parsing session in order to
618 : // compute which bindings are closed over. Scripts and scopes are numbered
619 : // monotonically in textual order and name uses are tracked by lists of
620 : // (script id, scope id) pairs of their use sites.
621 : //
622 : // Intuitively, in a pair (P,S), P tracks the most nested function that has a
623 : // use of u, and S tracks the most nested scope that is still being parsed.
624 : //
625 : // P is used to answer the question "is u used by a nested function?"
626 : // S is used to answer the question "is u used in any scopes currently being
627 : // parsed?"
628 : //
629 : // The algorithm:
630 : //
631 : // Let Used by a map of names to lists.
632 : //
633 : // 1. Number all scopes in monotonic increasing order in textual order.
634 : // 2. Number all scripts in monotonic increasing order in textual order.
635 : // 3. When an identifier u is used in scope numbered S in script numbered P,
636 : // and u is found in Used,
637 : // a. Append (P,S) to Used[u].
638 : // b. Otherwise, assign the the list [(P,S)] to Used[u].
639 : // 4. When we finish parsing a scope S in script P, for each declared name d in
640 : // Declared(S):
641 : // a. If d is found in Used, mark d as closed over if there is a value
642 : // (P_d, S_d) in Used[d] such that P_d > P and S_d > S.
643 : // b. Remove all values (P_d, S_d) in Used[d] such that S_d are >= S.
644 : //
645 : // Steps 1 and 2 are implemented by UsedNameTracker::next{Script,Scope}Id.
646 : // Step 3 is implemented by UsedNameTracker::noteUsedInScope.
647 : // Step 4 is implemented by UsedNameTracker::noteBoundInScope and
648 : // Parser::propagateFreeNamesAndMarkClosedOverBindings.
649 1697 : class UsedNameTracker
650 : {
651 : public:
652 : struct Use
653 : {
654 : uint32_t scriptId;
655 : uint32_t scopeId;
656 : };
657 :
658 36722 : class UsedNameInfo
659 : {
660 : friend class UsedNameTracker;
661 :
662 : Vector<Use, 6> uses_;
663 :
664 : void resetToScope(uint32_t scriptId, uint32_t scopeId);
665 :
666 : public:
667 11634 : explicit UsedNameInfo(JSContext* cx)
668 11634 : : uses_(cx)
669 11634 : { }
670 :
671 24954 : UsedNameInfo(UsedNameInfo&& other)
672 24954 : : uses_(mozilla::Move(other.uses_))
673 24954 : { }
674 :
675 77354 : bool noteUsedInScope(uint32_t scriptId, uint32_t scopeId) {
676 77354 : if (uses_.empty() || uses_.back().scopeId < scopeId)
677 45495 : return uses_.append(Use { scriptId, scopeId });
678 31859 : return true;
679 : }
680 :
681 18876 : void noteBoundInScope(uint32_t scriptId, uint32_t scopeId, bool* closedOver) {
682 18876 : *closedOver = false;
683 75746 : while (!uses_.empty()) {
684 29466 : Use& innermost = uses_.back();
685 29466 : if (innermost.scopeId < scopeId)
686 1031 : break;
687 28435 : if (innermost.scriptId > scriptId)
688 1997 : *closedOver = true;
689 28435 : uses_.popBack();
690 : }
691 18876 : }
692 :
693 6154 : bool isUsedInScript(uint32_t scriptId) const {
694 6154 : return !uses_.empty() && uses_.back().scriptId >= scriptId;
695 : }
696 : };
697 :
698 : using UsedNameMap = HashMap<JSAtom*,
699 : UsedNameInfo,
700 : DefaultHasher<JSAtom*>>;
701 :
702 : private:
703 : // The map of names to chains of uses.
704 : UsedNameMap map_;
705 :
706 : // Monotonically increasing id for all nested scripts.
707 : uint32_t scriptCounter_;
708 :
709 : // Monotonically increasing id for all nested scopes.
710 : uint32_t scopeCounter_;
711 :
712 : public:
713 1696 : explicit UsedNameTracker(JSContext* cx)
714 1696 : : map_(cx),
715 : scriptCounter_(0),
716 1696 : scopeCounter_(0)
717 1696 : { }
718 :
719 1696 : MOZ_MUST_USE bool init() {
720 1696 : return map_.init();
721 : }
722 :
723 7641 : uint32_t nextScriptId() {
724 7641 : MOZ_ASSERT(scriptCounter_ != UINT32_MAX,
725 : "ParseContext::Scope::init should have prevented wraparound");
726 7641 : return scriptCounter_++;
727 : }
728 :
729 18834 : uint32_t nextScopeId() {
730 18834 : MOZ_ASSERT(scopeCounter_ != UINT32_MAX);
731 18834 : return scopeCounter_++;
732 : }
733 :
734 30235 : UsedNameMap::Ptr lookup(JSAtom* name) const {
735 30235 : return map_.lookup(name);
736 : }
737 :
738 : MOZ_MUST_USE bool noteUse(JSContext* cx, JSAtom* name,
739 : uint32_t scriptId, uint32_t scopeId);
740 :
741 : struct RewindToken
742 : {
743 : private:
744 : friend class UsedNameTracker;
745 : uint32_t scriptId;
746 : uint32_t scopeId;
747 : };
748 :
749 1551 : RewindToken getRewindToken() const {
750 : RewindToken token;
751 1551 : token.scriptId = scriptCounter_;
752 1551 : token.scopeId = scopeCounter_;
753 1551 : return token;
754 : }
755 :
756 : // Resets state so that scriptId and scopeId are the innermost script and
757 : // scope, respectively. Used for rewinding state on syntax parse failure.
758 : void rewind(RewindToken token);
759 :
760 : // Resets state to beginning of compilation.
761 0 : void reset() {
762 0 : map_.clear();
763 : RewindToken token;
764 0 : token.scriptId = 0;
765 0 : token.scopeId = 0;
766 0 : rewind(token);
767 0 : }
768 : };
769 :
770 : template <class Parser>
771 : class AutoAwaitIsKeyword;
772 :
773 : class ParserBase : public StrictModeGetter
774 : {
775 : private:
776 1902 : ParserBase* thisForCtor() { return this; }
777 :
778 : public:
779 : JSContext* const context;
780 :
781 : LifoAlloc& alloc;
782 :
783 : TokenStream tokenStream;
784 : LifoAlloc::Mark tempPoolMark;
785 :
786 : /* list of parsed objects for GC tracing */
787 : ObjectBox* traceListHead;
788 :
789 : /* innermost parse context (stack-allocated) */
790 : ParseContext* pc;
791 :
792 : // For tracking used names in this parsing session.
793 : UsedNameTracker& usedNames;
794 :
795 : ScriptSource* ss;
796 :
797 : /* Root atoms and objects allocated for the parsed tree. */
798 : AutoKeepAtoms keepAtoms;
799 :
800 : /* Perform constant-folding; must be true when interfacing with the emitter. */
801 : const bool foldConstants:1;
802 :
803 : protected:
804 : #if DEBUG
805 : /* Our fallible 'checkOptions' member function has been called. */
806 : bool checkOptionsCalled:1;
807 : #endif
808 :
809 : /* Unexpected end of input, i.e. TOK_EOF not at top-level. */
810 : bool isUnexpectedEOF_:1;
811 :
812 : /* AwaitHandling */ uint8_t awaitHandling_:2;
813 :
814 : public:
815 1071 : bool awaitIsKeyword() const {
816 1071 : return awaitHandling_ != AwaitIsName;
817 : }
818 :
819 : ParserBase(JSContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options,
820 : const char16_t* chars, size_t length, bool foldConstants,
821 : UsedNameTracker& usedNames, LazyScript* lazyOuterFunction);
822 : ~ParserBase();
823 :
824 0 : const char* getFilename() const { return tokenStream.getFilename(); }
825 2071 : JSVersion versionNumber() const { return tokenStream.versionNumber(); }
826 749259 : TokenPos pos() const { return tokenStream.currentToken().pos; }
827 :
828 : // Determine whether |yield| is a valid name in the current context, or
829 : // whether it's prohibited due to strictness, JS version, or occurrence
830 : // inside a star generator.
831 48 : bool yieldExpressionsSupported() {
832 96 : return (versionNumber() >= JSVERSION_1_7 && !pc->isAsync()) ||
833 48 : pc->isStarGenerator() ||
834 48 : pc->isLegacyGenerator();
835 : }
836 :
837 1006 : bool asyncIterationSupported() {
838 : #ifdef RELEASE_OR_BETA
839 : return false;
840 : #else
841 : // Expose Async Iteration only to web content until the spec proposal
842 : // gets stable.
843 1006 : return !options().isProbablySystemOrAddonCode;
844 : #endif
845 : }
846 :
847 0 : virtual bool strictMode() { return pc->sc()->strict(); }
848 64 : bool setLocalStrictMode(bool strict) {
849 64 : MOZ_ASSERT(tokenStream.debugHasNoLookahead());
850 64 : return pc->sc()->setLocalStrictMode(strict);
851 : }
852 :
853 56490 : const ReadOnlyCompileOptions& options() const {
854 56490 : return tokenStream.options();
855 : }
856 :
857 0 : bool isUnexpectedEOF() const { return isUnexpectedEOF_; }
858 :
859 : bool reportNoOffset(ParseReportKind kind, bool strict, unsigned errorNumber, ...);
860 :
861 : /* Report the given error at the current offset. */
862 : void error(unsigned errorNumber, ...);
863 : void errorWithNotes(UniquePtr<JSErrorNotes> notes, unsigned errorNumber, ...);
864 :
865 : /* Report the given error at the given offset. */
866 : void errorAt(uint32_t offset, unsigned errorNumber, ...);
867 : void errorWithNotesAt(UniquePtr<JSErrorNotes> notes, uint32_t offset,
868 : unsigned errorNumber, ...);
869 :
870 : /*
871 : * Handle a strict mode error at the current offset. Report an error if in
872 : * strict mode code, or warn if not, using the given error number and
873 : * arguments.
874 : */
875 : MOZ_MUST_USE bool strictModeError(unsigned errorNumber, ...);
876 :
877 : /*
878 : * Handle a strict mode error at the given offset. Report an error if in
879 : * strict mode code, or warn if not, using the given error number and
880 : * arguments.
881 : */
882 : MOZ_MUST_USE bool strictModeErrorAt(uint32_t offset, unsigned errorNumber, ...);
883 :
884 : /* Report the given warning at the current offset. */
885 : MOZ_MUST_USE bool warning(unsigned errorNumber, ...);
886 :
887 : /* Report the given warning at the given offset. */
888 : MOZ_MUST_USE bool warningAt(uint32_t offset, unsigned errorNumber, ...);
889 :
890 : /*
891 : * If extra warnings are enabled, report the given warning at the current
892 : * offset.
893 : */
894 : MOZ_MUST_USE bool extraWarning(unsigned errorNumber, ...);
895 :
896 : /*
897 : * If extra warnings are enabled, report the given warning at the given
898 : * offset.
899 : */
900 : MOZ_MUST_USE bool extraWarningAt(uint32_t offset, unsigned errorNumber, ...);
901 :
902 : bool isValidStrictBinding(PropertyName* name);
903 :
904 : void addTelemetry(DeprecatedLanguageExtension e);
905 :
906 : bool warnOnceAboutExprClosure();
907 : bool warnOnceAboutForEach();
908 :
909 991 : bool allowsForEachIn() {
910 : #if !JS_HAS_FOR_EACH_IN
911 : return false;
912 : #else
913 991 : return options().forEachStatementOption && versionNumber() >= JSVERSION_1_6;
914 : #endif
915 : }
916 :
917 : bool hasValidSimpleStrictParameterNames();
918 :
919 :
920 : /*
921 : * Create a new function object given a name (which is optional if this is
922 : * a function expression).
923 : */
924 : JSFunction* newFunction(HandleAtom atom, FunctionSyntaxKind kind,
925 : GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
926 : HandleObject proto);
927 :
928 : // A Parser::Mark is the extension of the LifoAlloc::Mark to the entire
929 : // Parser's state. Note: clients must still take care that any ParseContext
930 : // that points into released ParseNodes is destroyed.
931 0 : class Mark
932 : {
933 : friend class ParserBase;
934 : LifoAlloc::Mark mark;
935 : ObjectBox* traceListHead;
936 : };
937 0 : Mark mark() const {
938 0 : Mark m;
939 0 : m.mark = alloc.mark();
940 0 : m.traceListHead = traceListHead;
941 0 : return m;
942 : }
943 0 : void release(Mark m) {
944 0 : alloc.release(m.mark);
945 0 : traceListHead = m.traceListHead;
946 0 : }
947 :
948 : ObjectBox* newObjectBox(JSObject* obj);
949 :
950 : mozilla::Maybe<GlobalScope::Data*> newGlobalScopeData(ParseContext::Scope& scope);
951 : mozilla::Maybe<ModuleScope::Data*> newModuleScopeData(ParseContext::Scope& scope);
952 : mozilla::Maybe<EvalScope::Data*> newEvalScopeData(ParseContext::Scope& scope);
953 : mozilla::Maybe<FunctionScope::Data*> newFunctionScopeData(ParseContext::Scope& scope,
954 : bool hasParameterExprs);
955 : mozilla::Maybe<VarScope::Data*> newVarScopeData(ParseContext::Scope& scope);
956 : mozilla::Maybe<LexicalScope::Data*> newLexicalScopeData(ParseContext::Scope& scope);
957 :
958 : protected:
959 : enum InvokedPrediction { PredictUninvoked = false, PredictInvoked = true };
960 : enum ForInitLocation { InForInit, NotInForInit };
961 : };
962 :
963 : inline
964 18834 : ParseContext::Scope::Scope(ParserBase* parser)
965 18834 : : Nestable<Scope>(&parser->pc->innermostScope_),
966 18834 : declared_(parser->context->frontendCollectionPool()),
967 18834 : possibleAnnexBFunctionBoxes_(parser->context->frontendCollectionPool()),
968 56502 : id_(parser->usedNames.nextScopeId())
969 18834 : { }
970 :
971 : inline
972 536 : ParseContext::VarScope::VarScope(ParserBase* parser)
973 536 : : Scope(parser)
974 : {
975 536 : useAsVarScope(parser->pc);
976 536 : }
977 :
978 : template <class ParseHandler, typename CharT>
979 : class Parser final : public ParserBase, private JS::AutoGCRooter
980 : {
981 : private:
982 : using Node = typename ParseHandler::Node;
983 :
984 : /*
985 : * A class for temporarily stashing errors while parsing continues.
986 : *
987 : * The ability to stash an error is useful for handling situations where we
988 : * aren't able to verify that an error has occurred until later in the parse.
989 : * For instance | ({x=1}) | is always parsed as an object literal with
990 : * a SyntaxError, however, in the case where it is followed by '=>' we rewind
991 : * and reparse it as a valid arrow function. Here a PossibleError would be
992 : * set to 'pending' when the initial SyntaxError was encountered then 'resolved'
993 : * just before rewinding the parser.
994 : *
995 : * There are currently two kinds of PossibleErrors: Expression and
996 : * Destructuring errors. Expression errors are used to mark a possible
997 : * syntax error when a grammar production is used in an expression context.
998 : * For example in |{x = 1}|, we mark the CoverInitializedName |x = 1| as a
999 : * possible expression error, because CoverInitializedName productions
1000 : * are disallowed when an actual ObjectLiteral is expected.
1001 : * Destructuring errors are used to record possible syntax errors in
1002 : * destructuring contexts. For example in |[...rest, ] = []|, we initially
1003 : * mark the trailing comma after the spread expression as a possible
1004 : * destructuring error, because the ArrayAssignmentPattern grammar
1005 : * production doesn't allow a trailing comma after the rest element.
1006 : *
1007 : * When using PossibleError one should set a pending error at the location
1008 : * where an error occurs. From that point, the error may be resolved
1009 : * (invalidated) or left until the PossibleError is checked.
1010 : *
1011 : * Ex:
1012 : * PossibleError possibleError(*this);
1013 : * possibleError.setPendingExpressionErrorAt(pos, JSMSG_BAD_PROP_ID);
1014 : * // A JSMSG_BAD_PROP_ID ParseError is reported, returns false.
1015 : * if (!possibleError.checkForExpressionError())
1016 : * return false; // we reach this point with a pending exception
1017 : *
1018 : * PossibleError possibleError(*this);
1019 : * possibleError.setPendingExpressionErrorAt(pos, JSMSG_BAD_PROP_ID);
1020 : * // Returns true, no error is reported.
1021 : * if (!possibleError.checkForDestructuringError())
1022 : * return false; // not reached, no pending exception
1023 : *
1024 : * PossibleError possibleError(*this);
1025 : * // Returns true, no error is reported.
1026 : * if (!possibleError.checkForExpressionError())
1027 : * return false; // not reached, no pending exception
1028 : */
1029 : class MOZ_STACK_CLASS PossibleError
1030 : {
1031 : private:
1032 : enum class ErrorKind { Expression, Destructuring, DestructuringWarning };
1033 :
1034 : enum class ErrorState { None, Pending };
1035 :
1036 217206 : struct Error {
1037 : ErrorState state_ = ErrorState::None;
1038 :
1039 : // Error reporting fields.
1040 : uint32_t offset_;
1041 : unsigned errorNumber_;
1042 : };
1043 :
1044 : Parser<ParseHandler, CharT>& parser_;
1045 : Error exprError_;
1046 : Error destructuringError_;
1047 : Error destructuringWarning_;
1048 :
1049 : // Returns the error report.
1050 : Error& error(ErrorKind kind);
1051 :
1052 : // Return true if an error is pending without reporting.
1053 : bool hasError(ErrorKind kind);
1054 :
1055 : // Resolve any pending error.
1056 : void setResolved(ErrorKind kind);
1057 :
1058 : // Set a pending error. Only a single error may be set per instance and
1059 : // error kind.
1060 : void setPending(ErrorKind kind, const TokenPos& pos, unsigned errorNumber);
1061 :
1062 : // If there is a pending error, report it and return false, otherwise
1063 : // return true.
1064 : MOZ_MUST_USE bool checkForError(ErrorKind kind);
1065 :
1066 : // If there is a pending warning, report it and return either false or
1067 : // true depending on the werror option, otherwise return true.
1068 : MOZ_MUST_USE bool checkForWarning(ErrorKind kind);
1069 :
1070 : // Transfer an existing error to another instance.
1071 : void transferErrorTo(ErrorKind kind, PossibleError* other);
1072 :
1073 : public:
1074 : explicit PossibleError(Parser<ParseHandler, CharT>& parser);
1075 :
1076 : // Return true if a pending destructuring error is present.
1077 : bool hasPendingDestructuringError();
1078 :
1079 : // Set a pending destructuring error. Only a single error may be set
1080 : // per instance, i.e. subsequent calls to this method are ignored and
1081 : // won't overwrite the existing pending error.
1082 : void setPendingDestructuringErrorAt(const TokenPos& pos, unsigned errorNumber);
1083 :
1084 : // Set a pending destructuring warning. Only a single warning may be
1085 : // set per instance, i.e. subsequent calls to this method are ignored
1086 : // and won't overwrite the existing pending warning.
1087 : void setPendingDestructuringWarningAt(const TokenPos& pos, unsigned errorNumber);
1088 :
1089 : // Set a pending expression error. Only a single error may be set per
1090 : // instance, i.e. subsequent calls to this method are ignored and won't
1091 : // overwrite the existing pending error.
1092 : void setPendingExpressionErrorAt(const TokenPos& pos, unsigned errorNumber);
1093 :
1094 : // If there is a pending destructuring error or warning, report it and
1095 : // return false, otherwise return true. Clears any pending expression
1096 : // error.
1097 : MOZ_MUST_USE bool checkForDestructuringErrorOrWarning();
1098 :
1099 : // If there is a pending expression error, report it and return false,
1100 : // otherwise return true. Clears any pending destructuring error or
1101 : // warning.
1102 : MOZ_MUST_USE bool checkForExpressionError();
1103 :
1104 : // Pass pending errors between possible error instances. This is useful
1105 : // for extending the lifetime of a pending error beyond the scope of
1106 : // the PossibleError where it was initially set (keeping in mind that
1107 : // PossibleError is a MOZ_STACK_CLASS).
1108 : void transferErrorsTo(PossibleError* other);
1109 : };
1110 :
1111 : // When ParseHandler is FullParseHandler:
1112 : //
1113 : // If non-null, this field holds the syntax parser used to attempt lazy
1114 : // parsing of inner functions. If null, then lazy parsing is disabled.
1115 : //
1116 : // When ParseHandler is SyntaxParseHandler:
1117 : //
1118 : // If non-null, this field must be a sentinel value signaling that the
1119 : // syntax parse was aborted. If null, then lazy parsing was aborted due
1120 : // to encountering unsupported language constructs.
1121 : using SyntaxParser = Parser<SyntaxParseHandler, CharT>;
1122 : SyntaxParser* syntaxParser_;
1123 :
1124 : public:
1125 : /* State specific to the kind of parse being performed. */
1126 : ParseHandler handler;
1127 :
1128 455 : void prepareNodeForMutation(Node node) { handler.prepareNodeForMutation(node); }
1129 3376 : void freeTree(Node node) { handler.freeTree(node); }
1130 :
1131 : public:
1132 : Parser(JSContext* cx, LifoAlloc& alloc, const ReadOnlyCompileOptions& options,
1133 : const CharT* chars, size_t length, bool foldConstants, UsedNameTracker& usedNames,
1134 : SyntaxParser* syntaxParser, LazyScript* lazyOuterFunction);
1135 : ~Parser();
1136 :
1137 : friend class AutoAwaitIsKeyword<Parser>;
1138 : void setAwaitHandling(AwaitHandling awaitHandling);
1139 :
1140 : // If ParseHandler is SyntaxParseHandler, whether the last syntax parse was
1141 : // aborted due to unsupported language constructs.
1142 : //
1143 : // If ParseHandler is FullParseHandler, false.
1144 : bool hadAbortedSyntaxParse();
1145 :
1146 : // If ParseHandler is SyntaxParseHandler, clear whether the last syntax
1147 : // parse was aborted.
1148 : //
1149 : // If ParseHandler is FullParseHandler, do nothing.
1150 : void clearAbortedSyntaxParse();
1151 :
1152 : bool checkOptions();
1153 :
1154 : friend void js::frontend::TraceParser(JSTracer* trc, JS::AutoGCRooter* parser);
1155 :
1156 : /*
1157 : * Parse a top-level JS script.
1158 : */
1159 : Node parse();
1160 :
1161 : FunctionBox* newFunctionBox(Node fn, JSFunction* fun, uint32_t toStringStart,
1162 : Directives directives,
1163 : GeneratorKind generatorKind, FunctionAsyncKind asyncKind);
1164 :
1165 : void trace(JSTracer* trc);
1166 :
1167 : private:
1168 0 : Parser* thisForCtor() { return this; }
1169 :
1170 : Node stringLiteral();
1171 : Node noSubstitutionTaggedTemplate();
1172 : Node noSubstitutionUntaggedTemplate();
1173 : Node templateLiteral(YieldHandling yieldHandling);
1174 : bool taggedTemplate(YieldHandling yieldHandling, Node nodeList, TokenKind tt);
1175 : bool appendToCallSiteObj(Node callSiteObj);
1176 : bool addExprAndGetNextTemplStrToken(YieldHandling yieldHandling, Node nodeList,
1177 : TokenKind* ttp);
1178 : bool checkStatementsEOF();
1179 :
1180 : inline Node newName(PropertyName* name);
1181 : inline Node newName(PropertyName* name, TokenPos pos);
1182 :
1183 : // If ParseHandler is SyntaxParseHandler, flag the current syntax parse as
1184 : // aborted due to unsupported language constructs and return
1185 : // false. Aborting the current syntax parse does not disable attempts to
1186 : // syntax parse future inner functions.
1187 : //
1188 : // If ParseHandler is FullParseHandler, disable syntax parsing of all
1189 : // future inner functions and return true.
1190 : inline bool abortIfSyntaxParser();
1191 :
1192 : // If ParseHandler is SyntaxParseHandler, do nothing.
1193 : //
1194 : // If ParseHandler is FullParseHandler, disable syntax parsing of all
1195 : // future inner functions.
1196 : void disableSyntaxParser();
1197 :
1198 : public:
1199 : /* Public entry points for parsing. */
1200 : Node statementListItem(YieldHandling yieldHandling, bool canHaveDirectives = false);
1201 :
1202 : // Parse the body of an eval.
1203 : //
1204 : // Eval scripts are distinguished from global scripts in that in ES6, per
1205 : // 18.2.1.1 steps 9 and 10, all eval scripts are executed under a fresh
1206 : // lexical scope.
1207 : Node evalBody(EvalSharedContext* evalsc);
1208 :
1209 : // Parse the body of a global script.
1210 : Node globalBody(GlobalSharedContext* globalsc);
1211 :
1212 : // Parse a module.
1213 : Node moduleBody(ModuleSharedContext* modulesc);
1214 :
1215 : // Parse a function, used for the Function, GeneratorFunction, and
1216 : // AsyncFunction constructors.
1217 : Node standaloneFunction(HandleFunction fun, HandleScope enclosingScope,
1218 : const mozilla::Maybe<uint32_t>& parameterListEnd,
1219 : GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
1220 : Directives inheritedDirectives, Directives* newDirectives);
1221 :
1222 : // Parse a function, given only its arguments and body. Used for lazily
1223 : // parsed functions.
1224 : Node standaloneLazyFunction(HandleFunction fun, uint32_t toStringStart, bool strict,
1225 : GeneratorKind generatorKind, FunctionAsyncKind asyncKind);
1226 :
1227 : // Parse an inner function given an enclosing ParseContext and a
1228 : // FunctionBox for the inner function.
1229 : bool innerFunction(Node pn, ParseContext* outerpc, FunctionBox* funbox, uint32_t toStringStart,
1230 : InHandling inHandling, YieldHandling yieldHandling,
1231 : FunctionSyntaxKind kind,
1232 : Directives inheritedDirectives, Directives* newDirectives);
1233 :
1234 : // Parse a function's formal parameters and its body assuming its function
1235 : // ParseContext is already on the stack.
1236 : bool functionFormalParametersAndBody(InHandling inHandling, YieldHandling yieldHandling,
1237 : Node pn, FunctionSyntaxKind kind,
1238 : const mozilla::Maybe<uint32_t>& parameterListEnd = mozilla::Nothing(),
1239 : bool isStandaloneFunction = false);
1240 :
1241 : // Match the current token against the BindingIdentifier production with
1242 : // the given Yield parameter. If there is no match, report a syntax
1243 : // error.
1244 : PropertyName* bindingIdentifier(YieldHandling yieldHandling);
1245 :
1246 : private:
1247 : /*
1248 : * JS parsers, from lowest to highest precedence.
1249 : *
1250 : * Each parser must be called during the dynamic scope of a ParseContext
1251 : * object, pointed to by this->pc.
1252 : *
1253 : * Each returns a parse node tree or null on error.
1254 : *
1255 : * Parsers whose name has a '1' suffix leave the TokenStream state
1256 : * pointing to the token one past the end of the parsed fragment. For a
1257 : * number of the parsers this is convenient and avoids a lot of
1258 : * unnecessary ungetting and regetting of tokens.
1259 : *
1260 : * Some parsers have two versions: an always-inlined version (with an 'i'
1261 : * suffix) and a never-inlined version (with an 'n' suffix).
1262 : */
1263 : Node functionStmt(uint32_t toStringStart,
1264 : YieldHandling yieldHandling, DefaultHandling defaultHandling,
1265 : FunctionAsyncKind asyncKind = SyncFunction);
1266 : Node functionExpr(uint32_t toStringStart, InvokedPrediction invoked = PredictUninvoked,
1267 : FunctionAsyncKind asyncKind = SyncFunction);
1268 :
1269 : Node statementList(YieldHandling yieldHandling);
1270 : Node statement(YieldHandling yieldHandling);
1271 : bool maybeParseDirective(Node list, Node pn, bool* cont);
1272 :
1273 : Node blockStatement(YieldHandling yieldHandling,
1274 : unsigned errorNumber = JSMSG_CURLY_IN_COMPOUND);
1275 : Node doWhileStatement(YieldHandling yieldHandling);
1276 : Node whileStatement(YieldHandling yieldHandling);
1277 :
1278 : Node forStatement(YieldHandling yieldHandling);
1279 : bool forHeadStart(YieldHandling yieldHandling,
1280 : IteratorKind iterKind,
1281 : ParseNodeKind* forHeadKind,
1282 : Node* forInitialPart,
1283 : mozilla::Maybe<ParseContext::Scope>& forLetImpliedScope,
1284 : Node* forInOrOfExpression);
1285 : Node expressionAfterForInOrOf(ParseNodeKind forHeadKind, YieldHandling yieldHandling);
1286 :
1287 : Node switchStatement(YieldHandling yieldHandling);
1288 : Node continueStatement(YieldHandling yieldHandling);
1289 : Node breakStatement(YieldHandling yieldHandling);
1290 : Node returnStatement(YieldHandling yieldHandling);
1291 : Node withStatement(YieldHandling yieldHandling);
1292 : Node throwStatement(YieldHandling yieldHandling);
1293 : Node tryStatement(YieldHandling yieldHandling);
1294 : Node catchBlockStatement(YieldHandling yieldHandling, ParseContext::Scope& catchParamScope);
1295 : Node debuggerStatement();
1296 :
1297 : Node variableStatement(YieldHandling yieldHandling);
1298 :
1299 : Node labeledStatement(YieldHandling yieldHandling);
1300 : Node labeledItem(YieldHandling yieldHandling);
1301 :
1302 : Node ifStatement(YieldHandling yieldHandling);
1303 : Node consequentOrAlternative(YieldHandling yieldHandling);
1304 :
1305 : // While on a |let| TOK_NAME token, examine |next|. Indicate whether
1306 : // |next|, the next token already gotten with modifier TokenStream::None,
1307 : // continues a LexicalDeclaration.
1308 : bool nextTokenContinuesLetDeclaration(TokenKind next, YieldHandling yieldHandling);
1309 :
1310 : Node lexicalDeclaration(YieldHandling yieldHandling, DeclarationKind kind);
1311 :
1312 : Node importDeclaration();
1313 :
1314 : bool processExport(Node node);
1315 : bool processExportFrom(Node node);
1316 :
1317 : Node exportFrom(uint32_t begin, Node specList);
1318 : Node exportBatch(uint32_t begin);
1319 : bool checkLocalExportNames(Node node);
1320 : Node exportClause(uint32_t begin);
1321 : Node exportFunctionDeclaration(uint32_t begin, uint32_t toStringStart,
1322 : FunctionAsyncKind asyncKind = SyncFunction);
1323 : Node exportVariableStatement(uint32_t begin);
1324 : Node exportClassDeclaration(uint32_t begin);
1325 : Node exportLexicalDeclaration(uint32_t begin, DeclarationKind kind);
1326 : Node exportDefaultFunctionDeclaration(uint32_t begin, uint32_t toStringStart,
1327 : FunctionAsyncKind asyncKind = SyncFunction);
1328 : Node exportDefaultClassDeclaration(uint32_t begin);
1329 : Node exportDefaultAssignExpr(uint32_t begin);
1330 : Node exportDefault(uint32_t begin);
1331 : Node exportDeclaration();
1332 :
1333 : Node expressionStatement(YieldHandling yieldHandling,
1334 : InvokedPrediction invoked = PredictUninvoked);
1335 :
1336 : // Declaration parsing. The main entrypoint is Parser::declarationList,
1337 : // with sub-functionality split out into the remaining methods.
1338 :
1339 : // |blockScope| may be non-null only when |kind| corresponds to a lexical
1340 : // declaration (that is, PNK_LET or PNK_CONST).
1341 : //
1342 : // The for* parameters, for normal declarations, should be null/ignored.
1343 : // They should be non-null only when Parser::forHeadStart parses a
1344 : // declaration at the start of a for-loop head.
1345 : //
1346 : // In this case, on success |*forHeadKind| is PNK_FORHEAD, PNK_FORIN, or
1347 : // PNK_FOROF, corresponding to the three for-loop kinds. The precise value
1348 : // indicates what was parsed.
1349 : //
1350 : // If parsing recognized a for(;;) loop, the next token is the ';' within
1351 : // the loop-head that separates the init/test parts.
1352 : //
1353 : // Otherwise, for for-in/of loops, the next token is the ')' ending the
1354 : // loop-head. Additionally, the expression that the loop iterates over was
1355 : // parsed into |*forInOrOfExpression|.
1356 : Node declarationList(YieldHandling yieldHandling,
1357 : ParseNodeKind kind,
1358 : ParseNodeKind* forHeadKind = nullptr,
1359 : Node* forInOrOfExpression = nullptr);
1360 :
1361 : // The items in a declaration list are either patterns or names, with or
1362 : // without initializers. These two methods parse a single pattern/name and
1363 : // any associated initializer -- and if parsing an |initialDeclaration|
1364 : // will, if parsing in a for-loop head (as specified by |forHeadKind| being
1365 : // non-null), consume additional tokens up to the closing ')' in a
1366 : // for-in/of loop head, returning the iterated expression in
1367 : // |*forInOrOfExpression|. (An "initial declaration" is the first
1368 : // declaration in a declaration list: |a| but not |b| in |var a, b|, |{c}|
1369 : // but not |d| in |let {c} = 3, d|.)
1370 : Node declarationPattern(Node decl, DeclarationKind declKind, TokenKind tt,
1371 : bool initialDeclaration, YieldHandling yieldHandling,
1372 : ParseNodeKind* forHeadKind, Node* forInOrOfExpression);
1373 : Node declarationName(Node decl, DeclarationKind declKind, TokenKind tt,
1374 : bool initialDeclaration, YieldHandling yieldHandling,
1375 : ParseNodeKind* forHeadKind, Node* forInOrOfExpression);
1376 :
1377 : // Having parsed a name (not found in a destructuring pattern) declared by
1378 : // a declaration, with the current token being the '=' separating the name
1379 : // from its initializer, parse and bind that initializer -- and possibly
1380 : // consume trailing in/of and subsequent expression, if so directed by
1381 : // |forHeadKind|.
1382 : bool initializerInNameDeclaration(Node decl, Node binding, Handle<PropertyName*> name,
1383 : DeclarationKind declKind, bool initialDeclaration,
1384 : YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
1385 : Node* forInOrOfExpression);
1386 :
1387 : Node expr(InHandling inHandling, YieldHandling yieldHandling,
1388 : TripledotHandling tripledotHandling, PossibleError* possibleError = nullptr,
1389 : InvokedPrediction invoked = PredictUninvoked);
1390 : Node assignExpr(InHandling inHandling, YieldHandling yieldHandling,
1391 : TripledotHandling tripledotHandling, PossibleError* possibleError = nullptr,
1392 : InvokedPrediction invoked = PredictUninvoked);
1393 : Node assignExprWithoutYieldOrAwait(YieldHandling yieldHandling);
1394 : Node yieldExpression(InHandling inHandling);
1395 : Node condExpr1(InHandling inHandling, YieldHandling yieldHandling,
1396 : TripledotHandling tripledotHandling,
1397 : PossibleError* possibleError,
1398 : InvokedPrediction invoked = PredictUninvoked);
1399 : Node orExpr1(InHandling inHandling, YieldHandling yieldHandling,
1400 : TripledotHandling tripledotHandling,
1401 : PossibleError* possibleError,
1402 : InvokedPrediction invoked = PredictUninvoked);
1403 : Node unaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
1404 : PossibleError* possibleError = nullptr,
1405 : InvokedPrediction invoked = PredictUninvoked);
1406 : Node memberExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
1407 : TokenKind tt, bool allowCallSyntax = true,
1408 : PossibleError* possibleError = nullptr,
1409 : InvokedPrediction invoked = PredictUninvoked);
1410 : Node primaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
1411 : TokenKind tt, PossibleError* possibleError,
1412 : InvokedPrediction invoked = PredictUninvoked);
1413 : Node exprInParens(InHandling inHandling, YieldHandling yieldHandling,
1414 : TripledotHandling tripledotHandling, PossibleError* possibleError = nullptr);
1415 :
1416 : bool tryNewTarget(Node& newTarget);
1417 : bool checkAndMarkSuperScope();
1418 :
1419 : Node methodDefinition(uint32_t toStringStart, PropertyType propType, HandleAtom funName);
1420 :
1421 : /*
1422 : * Additional JS parsers.
1423 : */
1424 : bool functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind,
1425 : Node funcpn);
1426 :
1427 : Node functionDefinition(Node func, uint32_t toStringStart,
1428 : InHandling inHandling, YieldHandling yieldHandling,
1429 : HandleAtom name, FunctionSyntaxKind kind,
1430 : GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
1431 : bool tryAnnexB = false);
1432 :
1433 : // Parse a function body. Pass StatementListBody if the body is a list of
1434 : // statements; pass ExpressionBody if the body is a single expression.
1435 : enum FunctionBodyType { StatementListBody, ExpressionBody };
1436 : Node functionBody(InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind,
1437 : FunctionBodyType type);
1438 :
1439 : Node unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind, JSOp op, uint32_t begin);
1440 :
1441 : Node condition(InHandling inHandling, YieldHandling yieldHandling);
1442 :
1443 : /* comprehensions */
1444 : Node generatorComprehensionLambda(unsigned begin);
1445 : Node comprehensionFor(GeneratorKind comprehensionKind);
1446 : Node comprehensionIf(GeneratorKind comprehensionKind);
1447 : Node comprehensionTail(GeneratorKind comprehensionKind);
1448 : Node comprehension(GeneratorKind comprehensionKind);
1449 : Node arrayComprehension(uint32_t begin);
1450 : Node generatorComprehension(uint32_t begin);
1451 :
1452 : bool argumentList(YieldHandling yieldHandling, Node listNode, bool* isSpread,
1453 : PossibleError* possibleError = nullptr);
1454 : Node destructuringDeclaration(DeclarationKind kind, YieldHandling yieldHandling,
1455 : TokenKind tt);
1456 : Node destructuringDeclarationWithoutYieldOrAwait(DeclarationKind kind, YieldHandling yieldHandling,
1457 : TokenKind tt);
1458 :
1459 : bool namedImportsOrNamespaceImport(TokenKind tt, Node importSpecSet);
1460 : bool checkExportedName(JSAtom* exportName);
1461 : bool checkExportedNamesForDeclaration(Node node);
1462 : bool checkExportedNameForClause(Node node);
1463 : bool checkExportedNameForFunction(Node node);
1464 : bool checkExportedNameForClass(Node node);
1465 :
1466 : enum ClassContext { ClassStatement, ClassExpression };
1467 : Node classDefinition(YieldHandling yieldHandling, ClassContext classContext,
1468 : DefaultHandling defaultHandling);
1469 :
1470 : bool checkLabelOrIdentifierReference(PropertyName* ident,
1471 : uint32_t offset,
1472 : YieldHandling yieldHandling,
1473 : TokenKind hint = TOK_LIMIT);
1474 :
1475 0 : bool checkLocalExportName(PropertyName* ident, uint32_t offset) {
1476 0 : return checkLabelOrIdentifierReference(ident, offset, YieldIsName);
1477 : }
1478 :
1479 : bool checkBindingIdentifier(PropertyName* ident,
1480 : uint32_t offset,
1481 : YieldHandling yieldHandling,
1482 : TokenKind hint = TOK_LIMIT);
1483 :
1484 : PropertyName* labelOrIdentifierReference(YieldHandling yieldHandling);
1485 :
1486 0 : PropertyName* labelIdentifier(YieldHandling yieldHandling) {
1487 0 : return labelOrIdentifierReference(yieldHandling);
1488 : }
1489 :
1490 82073 : PropertyName* identifierReference(YieldHandling yieldHandling) {
1491 82073 : return labelOrIdentifierReference(yieldHandling);
1492 : }
1493 :
1494 0 : PropertyName* importedBinding() {
1495 0 : return bindingIdentifier(YieldIsName);
1496 : }
1497 :
1498 : Node identifierReference(Handle<PropertyName*> name);
1499 :
1500 : bool matchLabel(YieldHandling yieldHandling, MutableHandle<PropertyName*> label);
1501 :
1502 : bool matchInOrOf(bool* isForInp, bool* isForOfp);
1503 :
1504 : bool hasUsedFunctionSpecialName(HandlePropertyName name);
1505 : bool declareFunctionArgumentsObject();
1506 : bool declareFunctionThis();
1507 : Node newInternalDotName(HandlePropertyName name);
1508 : Node newThisName();
1509 : Node newDotGeneratorName();
1510 : bool declareDotGeneratorName();
1511 :
1512 : bool skipLazyInnerFunction(Node pn, uint32_t toStringStart, FunctionSyntaxKind kind,
1513 : bool tryAnnexB);
1514 : bool innerFunction(Node pn, ParseContext* outerpc, HandleFunction fun, uint32_t toStringStart,
1515 : InHandling inHandling, YieldHandling yieldHandling,
1516 : FunctionSyntaxKind kind,
1517 : GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
1518 : Directives inheritedDirectives, Directives* newDirectives);
1519 : bool trySyntaxParseInnerFunction(Node pn, HandleFunction fun, uint32_t toStringStart,
1520 : InHandling inHandling, YieldHandling yieldHandling,
1521 : FunctionSyntaxKind kind,
1522 : GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
1523 : bool tryAnnexB,
1524 : Directives inheritedDirectives, Directives* newDirectives);
1525 : bool finishFunctionScopes(bool isStandaloneFunction);
1526 : bool finishFunction(bool isStandaloneFunction = false);
1527 : bool leaveInnerFunction(ParseContext* outerpc);
1528 :
1529 : bool matchOrInsertSemicolonHelper(TokenStream::Modifier modifier);
1530 : bool matchOrInsertSemicolonAfterExpression();
1531 : bool matchOrInsertSemicolonAfterNonExpression();
1532 :
1533 : public:
1534 : enum FunctionCallBehavior {
1535 : PermitAssignmentToFunctionCalls,
1536 : ForbidAssignmentToFunctionCalls
1537 : };
1538 :
1539 : bool isValidSimpleAssignmentTarget(Node node,
1540 : FunctionCallBehavior behavior = ForbidAssignmentToFunctionCalls);
1541 :
1542 : private:
1543 : bool checkIncDecOperand(Node operand, uint32_t operandOffset);
1544 : bool checkStrictAssignment(Node lhs);
1545 :
1546 : void reportMissingClosing(unsigned errorNumber, unsigned noteNumber, uint32_t openedPos);
1547 :
1548 : void reportRedeclaration(HandlePropertyName name, DeclarationKind prevKind, TokenPos pos,
1549 : uint32_t prevPos);
1550 : bool notePositionalFormalParameter(Node fn, HandlePropertyName name, uint32_t beginPos,
1551 : bool disallowDuplicateParams, bool* duplicatedParam);
1552 : bool noteDestructuredPositionalFormalParameter(Node fn, Node destruct);
1553 :
1554 : bool checkLexicalDeclarationDirectlyWithinBlock(ParseContext::Statement& stmt,
1555 : DeclarationKind kind, TokenPos pos);
1556 : bool noteDeclaredName(HandlePropertyName name, DeclarationKind kind, TokenPos pos);
1557 : bool noteUsedName(HandlePropertyName name);
1558 : bool hasUsedName(HandlePropertyName name);
1559 :
1560 : // Required on Scope exit.
1561 : bool propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope);
1562 :
1563 : Node finishLexicalScope(ParseContext::Scope& scope, Node body);
1564 :
1565 : Node propertyName(YieldHandling yieldHandling,
1566 : const mozilla::Maybe<DeclarationKind>& maybeDecl, Node propList,
1567 : PropertyType* propType, MutableHandleAtom propAtom);
1568 : Node computedPropertyName(YieldHandling yieldHandling,
1569 : const mozilla::Maybe<DeclarationKind>& maybeDecl, Node literal);
1570 : Node arrayInitializer(YieldHandling yieldHandling, PossibleError* possibleError);
1571 : Node newRegExp();
1572 :
1573 : Node objectLiteral(YieldHandling yieldHandling, PossibleError* possibleError);
1574 :
1575 : Node bindingInitializer(Node lhs, DeclarationKind kind, YieldHandling yieldHandling);
1576 : Node bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling);
1577 : Node bindingIdentifierOrPattern(DeclarationKind kind, YieldHandling yieldHandling,
1578 : TokenKind tt);
1579 : Node objectBindingPattern(DeclarationKind kind, YieldHandling yieldHandling);
1580 : Node arrayBindingPattern(DeclarationKind kind, YieldHandling yieldHandling);
1581 :
1582 : void checkDestructuringAssignmentTarget(Node expr, TokenPos exprPos,
1583 : PossibleError* possibleError);
1584 : void checkDestructuringAssignmentElement(Node expr, TokenPos exprPos,
1585 : PossibleError* possibleError);
1586 :
1587 9971 : Node newNumber(const Token& tok) {
1588 9971 : return handler.newNumber(tok.number(), tok.decimalPoint(), tok.pos);
1589 : }
1590 :
1591 24440 : static Node null() { return ParseHandler::null(); }
1592 :
1593 : JSAtom* prefixAccessorName(PropertyType propType, HandleAtom propAtom);
1594 :
1595 : bool asmJS(Node list);
1596 : };
1597 :
1598 : template <class Parser>
1599 : class MOZ_STACK_CLASS AutoAwaitIsKeyword
1600 : {
1601 : private:
1602 : Parser* parser_;
1603 : AwaitHandling oldAwaitHandling_;
1604 :
1605 : public:
1606 15950 : AutoAwaitIsKeyword(Parser* parser, AwaitHandling awaitHandling) {
1607 15950 : parser_ = parser;
1608 15950 : oldAwaitHandling_ = static_cast<AwaitHandling>(parser_->awaitHandling_);
1609 :
1610 : // 'await' is always a keyword in module contexts, so we don't modify
1611 : // the state when the original handling is AwaitIsModuleKeyword.
1612 15950 : if (oldAwaitHandling_ != AwaitIsModuleKeyword)
1613 15950 : parser_->setAwaitHandling(awaitHandling);
1614 15950 : }
1615 :
1616 15950 : ~AutoAwaitIsKeyword() {
1617 15950 : parser_->setAwaitHandling(oldAwaitHandling_);
1618 15950 : }
1619 : };
1620 :
1621 : } /* namespace frontend */
1622 : } /* namespace js */
1623 :
1624 : #endif /* frontend_Parser_h */
|