Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/js/src/frontend/Parser.h
Line
Count
Source (jump to first uncovered line)
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
/*
13
 * [SMDOC] JS Parser
14
 *
15
 * JS parsers capable of generating ASTs from source text.
16
 *
17
 * A parser embeds token stream information, then gets and matches tokens to
18
 * generate a syntax tree that, if desired, BytecodeEmitter will use to compile
19
 * bytecode.
20
 *
21
 * Like token streams (see the comment near the top of TokenStream.h), parser
22
 * classes are heavily templatized -- along the token stream's character-type
23
 * axis, and also along a full-parse/syntax-parse axis.  Certain limitations of
24
 * C++ (primarily the inability to partially specialize function templates),
25
 * plus the desire to minimize compiled code size in duplicate function
26
 * template instantiations wherever possible, mean that Parser exhibits much of
27
 * the same unholy template/inheritance complexity as token streams.
28
 *
29
 * == ParserBase → JS::AutoGCRooter, StrictModeGetter ==
30
 *
31
 * ParserBase is the base parser class, shared by all parsers of all character
32
 * types and parse-handling behavior.  It stores everything character- and
33
 * handler-agnostic.
34
 *
35
 * ParserBase's most important field is the parser's token stream's
36
 * |TokenStreamAnyChars| component, for all tokenizing aspects that are
37
 * character-type-agnostic.  The character-type-sensitive components residing
38
 * in |TokenStreamSpecific| (see the comment near the top of TokenStream.h)
39
 * live elsewhere in this hierarchy.  These separate locations are the reason
40
 * for the |AnyCharsAccess| template parameter to |TokenStreamChars| and
41
 * |TokenStreamSpecific|.
42
 *
43
 * Of particular note: making ParserBase inherit JS::AutoGCRooter (rather than
44
 * placing it under one of the more-derived parser classes) means that all
45
 * parsers can be traced using the same AutoGCRooter mechanism: it's not
46
 * necessary to have separate tracing functionality for syntax/full parsers or
47
 * parsers of different character types.
48
 *
49
 * == PerHandlerParser<ParseHandler> → ParserBase ==
50
 *
51
 * Certain parsing behavior varies between full parsing and syntax-only parsing
52
 * but does not vary across source-text character types.  For example, the work
53
 * to "create an arguments object for a function" obviously varies between
54
 * syntax and full parsing but (because no source characters are examined) does
55
 * not vary by source text character type.  Such functionality is implemented
56
 * through functions in PerHandlerParser.
57
 *
58
 * Functionality only used by syntax parsing or full parsing doesn't live here:
59
 * it should be implemented in the appropriate Parser<ParseHandler> (described
60
 * further below).
61
 *
62
 * == GeneralParser<ParseHandler, CharT> → PerHandlerParser<ParseHandler> ==
63
 *
64
 * Most parsing behavior varies across the character-type axis (and possibly
65
 * along the full/syntax axis).  For example:
66
 *
67
 *   * Parsing ECMAScript's Expression production, implemented by
68
 *     GeneralParser::expr, varies in this manner: different types are used to
69
 *     represent nodes in full and syntax parsing (ParseNode* versus an enum),
70
 *     and reading the tokens comprising the expression requires inspecting
71
 *     individual characters (necessarily dependent upon character type).
72
 *   * Reporting an error or warning does not depend on the full/syntax parsing
73
 *     distinction.  But error reports and warnings include a line of context
74
 *     (or a slice of one), for pointing out where a mistake was made.
75
 *     Computing such line of context requires inspecting the source text to
76
 *     make that line/slice of context, which requires knowing the source text
77
 *     character type.
78
 *
79
 * Such functionality, implemented using identical function code across these
80
 * axes, should live in GeneralParser.
81
 *
82
 * GeneralParser's most important field is the parser's token stream's
83
 * |TokenStreamSpecific| component, for all aspects of tokenizing that (contra
84
 * |TokenStreamAnyChars| in ParserBase above) are character-type-sensitive.  As
85
 * noted above, this field's existence separate from that in ParserBase
86
 * motivates the |AnyCharsAccess| template parameters on various token stream
87
 * classes.
88
 *
89
 * Everything in PerHandlerParser *could* be folded into GeneralParser (below)
90
 * if desired.  We don't fold in this manner because all such functions would
91
 * be instantiated once per CharT -- but if exactly equivalent code would be
92
 * generated (because PerHandlerParser functions have no awareness of CharT),
93
 * it's risky to *depend* upon the compiler coalescing the instantiations into
94
 * one in the final binary.  PerHandlerParser guarantees no duplication.
95
 *
96
 * == Parser<ParseHandler, CharT> final → GeneralParser<ParseHandler, CharT> ==
97
 *
98
 * The final (pun intended) axis of complexity lies in Parser.
99
 *
100
 * Some functionality depends on character type, yet also is defined in
101
 * significantly different form in full and syntax parsing.  For example,
102
 * attempting to parse the source text of a module will do so in full parsing
103
 * but immediately fail in syntax parsing -- so the former is a mess'o'code
104
 * while the latter is effectively |return null();|.  Such functionality is
105
 * defined in Parser<SyntaxParseHandler or FullParseHandler, CharT> as
106
 * appropriate.
107
 *
108
 * There's a crucial distinction between GeneralParser and Parser, that
109
 * explains why both must exist (despite taking exactly the same template
110
 * parameters, and despite GeneralParser and Parser existing in a one-to-one
111
 * relationship).  GeneralParser is one unspecialized template class:
112
 *
113
 *   template<class ParseHandler, typename CharT>
114
 *   class GeneralParser : ...
115
 *   {
116
 *     ...parsing functions...
117
 *   };
118
 *
119
 * but Parser is one undefined template class with two separate
120
 * specializations:
121
 *
122
 *   // Declare, but do not define.
123
 *   template<class ParseHandler, typename CharT> class Parser;
124
 *
125
 *   // Define a syntax-parsing specialization.
126
 *   template<typename CharT>
127
 *   class Parser<SyntaxParseHandler, CharT> final
128
 *     : public GeneralParser<SyntaxParseHandler, CharT>
129
 *   {
130
 *     ...parsing functions...
131
 *   };
132
 *
133
 *   // Define a full-parsing specialization.
134
 *   template<typename CharT>
135
 *   class Parser<SyntaxParseHandler, CharT> final
136
 *     : public GeneralParser<SyntaxParseHandler, CharT>
137
 *   {
138
 *     ...parsing functions...
139
 *   };
140
 *
141
 * This odd distinction is necessary because C++ unfortunately doesn't allow
142
 * partial function specialization:
143
 *
144
 *   // BAD: You can only specialize a template function if you specify *every*
145
 *   //      template parameter, i.e. ParseHandler *and* CharT.
146
 *   template<typename CharT>
147
 *   void
148
 *   GeneralParser<SyntaxParseHandler, CharT>::foo() {}
149
 *
150
 * But if you specialize Parser *as a class*, then this is allowed:
151
 *
152
 *   template<typename CharT>
153
 *   void
154
 *   Parser<SyntaxParseHandler, CharT>::foo() {}
155
 *
156
 *   template<typename CharT>
157
 *   void
158
 *   Parser<FullParseHandler, CharT>::foo() {}
159
 *
160
 * because the only template parameter on the function is CharT -- and so all
161
 * template parameters *are* varying, not a strict subset of them.
162
 *
163
 * So -- any parsing functionality that is differently defined for different
164
 * ParseHandlers, *but* is defined textually identically for different CharT
165
 * (even if different code ends up generated for them by the compiler), should
166
 * reside in Parser.
167
 */
168
169
#include "mozilla/Array.h"
170
#include "mozilla/Maybe.h"
171
#include "mozilla/TypeTraits.h"
172
173
#include "jspubtd.h"
174
175
#include "ds/Nestable.h"
176
#include "frontend/BytecodeCompiler.h"
177
#include "frontend/FullParseHandler.h"
178
#include "frontend/NameAnalysisTypes.h"
179
#include "frontend/NameCollections.h"
180
#include "frontend/ParseContext.h"
181
#include "frontend/SharedContext.h"
182
#include "frontend/SyntaxParseHandler.h"
183
#include "frontend/TokenStream.h"
184
185
namespace js {
186
187
class ModuleObject;
188
189
namespace frontend {
190
191
class ParserBase;
192
193
template <class ParseHandler, typename CharT>
194
class GeneralParser;
195
196
class SourceParseContext: public ParseContext
197
{
198
public:
199
    template<typename ParseHandler, typename CharT>
200
    SourceParseContext(GeneralParser<ParseHandler, CharT>* prs, SharedContext* sc,
201
                       Directives* newDirectives)
202
      : ParseContext(prs->context, prs->pc, sc, prs->tokenStream, prs->usedNames, newDirectives,
203
                     mozilla::IsSame<ParseHandler, FullParseHandler>::value)
204
1.48k
    { }
js::frontend::SourceParseContext::SourceParseContext<js::frontend::FullParseHandler, char16_t>(js::frontend::GeneralParser<js::frontend::FullParseHandler, char16_t>*, js::frontend::SharedContext*, js::frontend::Directives*)
Line
Count
Source
204
1.48k
    { }
Unexecuted instantiation: js::frontend::SourceParseContext::SourceParseContext<js::frontend::FullParseHandler, mozilla::Utf8Unit>(js::frontend::GeneralParser<js::frontend::FullParseHandler, mozilla::Utf8Unit>*, js::frontend::SharedContext*, js::frontend::Directives*)
Unexecuted instantiation: js::frontend::SourceParseContext::SourceParseContext<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>(js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>*, js::frontend::SharedContext*, js::frontend::Directives*)
Unexecuted instantiation: js::frontend::SourceParseContext::SourceParseContext<js::frontend::SyntaxParseHandler, char16_t>(js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, char16_t>*, js::frontend::SharedContext*, js::frontend::Directives*)
205
};
206
207
template <typename T>
208
inline T&
209
ParseContext::Statement::as()
210
7
{
211
7
    MOZ_ASSERT(is<T>());
212
7
    return static_cast<T&>(*this);
213
7
}
Unexecuted instantiation: js::frontend::ParseContext::LabelStatement& js::frontend::ParseContext::Statement::as<js::frontend::ParseContext::LabelStatement>()
js::frontend::ParseContext::ClassStatement& js::frontend::ParseContext::Statement::as<js::frontend::ParseContext::ClassStatement>()
Line
Count
Source
210
7
{
211
7
    MOZ_ASSERT(is<T>());
212
7
    return static_cast<T&>(*this);
213
7
}
214
215
inline ParseContext::Scope::BindingIter
216
ParseContext::Scope::bindings(ParseContext* pc)
217
8.73k
{
218
8.73k
    // In function scopes with parameter expressions, function special names
219
8.73k
    // (like '.this') are declared as vars in the function scope, despite its
220
8.73k
    // not being the var scope.
221
8.73k
    return BindingIter(*this, pc->varScope_ == this || pc->functionScope_.ptrOr(nullptr) == this);
222
8.73k
}
223
224
inline
225
Directives::Directives(ParseContext* parent)
226
  : strict_(parent->sc()->strict()),
227
    asmJS_(parent->useAsmOrInsideUseAsm())
228
1.48k
{}
229
230
enum VarContext { HoistVars, DontHoistVars };
231
enum PropListType { ObjectLiteral, ClassBody, DerivedClassBody };
232
enum class PropertyType {
233
    Normal,
234
    Shorthand,
235
    CoverInitializedName,
236
    Getter,
237
    Setter,
238
    Method,
239
    GeneratorMethod,
240
    AsyncMethod,
241
    AsyncGeneratorMethod,
242
    Constructor,
243
    DerivedConstructor
244
};
245
246
enum AwaitHandling : uint8_t { AwaitIsName, AwaitIsKeyword, AwaitIsModuleKeyword };
247
248
template <class ParseHandler, typename CharT>
249
class AutoAwaitIsKeyword;
250
251
template <class ParseHandler, typename CharT>
252
class AutoInParametersOfAsyncFunction;
253
254
class MOZ_STACK_CLASS ParserBase
255
  : public StrictModeGetter,
256
    private JS::AutoGCRooter
257
{
258
  private:
259
8
    ParserBase* thisForCtor() { return this; }
260
261
    // This is needed to cast a parser to JS::AutoGCRooter.
262
    friend void js::frontend::TraceParser(JSTracer* trc, JS::AutoGCRooter* parser);
263
264
  public:
265
    JSContext* const context;
266
267
    LifoAlloc& alloc;
268
269
    TokenStreamAnyChars anyChars;
270
    LifoAlloc::Mark tempPoolMark;
271
272
    /* list of parsed objects for GC tracing */
273
    ObjectBox* traceListHead;
274
275
    /* innermost parse context (stack-allocated) */
276
    ParseContext* pc;
277
278
    // For tracking used names in this parsing session.
279
    UsedNameTracker& usedNames;
280
281
    ScriptSource*       ss;
282
283
    RootedScriptSourceObject sourceObject;
284
285
    /* Root atoms and objects allocated for the parsed tree. */
286
    AutoKeepAtoms       keepAtoms;
287
288
    /* Perform constant-folding; must be true when interfacing with the emitter. */
289
    const bool          foldConstants:1;
290
291
  protected:
292
#if DEBUG
293
    /* Our fallible 'checkOptions' member function has been called. */
294
    bool checkOptionsCalled:1;
295
#endif
296
297
    /* Unexpected end of input, i.e. Eof not at top-level. */
298
    bool isUnexpectedEOF_:1;
299
300
    /* AwaitHandling */ uint8_t awaitHandling_:2;
301
302
    bool inParametersOfAsyncFunction_:1;
303
304
    /* ParseGoal */ uint8_t parseGoal_:1;
305
306
  public:
307
12
    bool awaitIsKeyword() const {
308
12
      return awaitHandling_ != AwaitIsName;
309
12
    }
310
311
0
    bool inParametersOfAsyncFunction() const {
312
0
        return inParametersOfAsyncFunction_;
313
0
    }
314
315
0
    ParseGoal parseGoal() const {
316
0
        return ParseGoal(parseGoal_);
317
0
    }
318
319
    template<class, typename> friend class AutoAwaitIsKeyword;
320
    template<class, typename> friend class AutoInParametersOfAsyncFunction;
321
322
    ParserBase(JSContext* cx, LifoAlloc& alloc, const JS::ReadOnlyCompileOptions& options,
323
               bool foldConstants, UsedNameTracker& usedNames,
324
               ScriptSourceObject* sourceObject, ParseGoal parseGoal);
325
    ~ParserBase();
326
327
    bool checkOptions();
328
329
    void trace(JSTracer* trc);
330
331
0
    const char* getFilename() const { return anyChars.getFilename(); }
332
218k
    TokenPos pos() const { return anyChars.currentToken().pos; }
333
334
    // Determine whether |yield| is a valid name in the current context.
335
0
    bool yieldExpressionsSupported() const {
336
0
        return pc->isGenerator();
337
0
    }
338
339
0
    virtual bool strictMode() override { return pc->sc()->strict(); }
340
14
    bool setLocalStrictMode(bool strict) {
341
14
        MOZ_ASSERT(anyChars.debugHasNoLookahead());
342
14
        return pc->sc()->setLocalStrictMode(strict);
343
14
    }
344
345
11.4k
    const JS::ReadOnlyCompileOptions& options() const {
346
11.4k
        return anyChars.options();
347
11.4k
    }
348
349
0
    bool isUnexpectedEOF() const { return isUnexpectedEOF_; }
350
351
    MOZ_MUST_USE bool warningNoOffset(unsigned errorNumber, ...);
352
    void errorNoOffset(unsigned errorNumber, ...);
353
354
    bool isValidStrictBinding(PropertyName* name);
355
356
    bool hasValidSimpleStrictParameterNames();
357
358
    /*
359
     * Create a new function object given a name (which is optional if this is
360
     * a function expression).
361
     */
362
    JSFunction* newFunction(HandleAtom atom, FunctionSyntaxKind kind,
363
                            GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
364
                            HandleObject proto);
365
366
    // A Parser::Mark is the extension of the LifoAlloc::Mark to the entire
367
    // Parser's state. Note: clients must still take care that any ParseContext
368
    // that points into released ParseNodes is destroyed.
369
    class Mark
370
    {
371
        friend class ParserBase;
372
        LifoAlloc::Mark mark;
373
        ObjectBox* traceListHead;
374
    };
375
0
    Mark mark() const {
376
0
        Mark m;
377
0
        m.mark = alloc.mark();
378
0
        m.traceListHead = traceListHead;
379
0
        return m;
380
0
    }
381
0
    void release(Mark m) {
382
0
        alloc.release(m.mark);
383
0
        traceListHead = m.traceListHead;
384
0
    }
385
386
    ObjectBox* newObjectBox(JSObject* obj);
387
388
    mozilla::Maybe<GlobalScope::Data*> newGlobalScopeData(ParseContext::Scope& scope);
389
    mozilla::Maybe<ModuleScope::Data*> newModuleScopeData(ParseContext::Scope& scope);
390
    mozilla::Maybe<EvalScope::Data*> newEvalScopeData(ParseContext::Scope& scope);
391
    mozilla::Maybe<FunctionScope::Data*> newFunctionScopeData(ParseContext::Scope& scope,
392
                                                              bool hasParameterExprs);
393
    mozilla::Maybe<VarScope::Data*> newVarScopeData(ParseContext::Scope& scope);
394
    mozilla::Maybe<LexicalScope::Data*> newLexicalScopeData(ParseContext::Scope& scope);
395
396
  protected:
397
    enum InvokedPrediction { PredictUninvoked = false, PredictInvoked = true };
398
    enum ForInitLocation { InForInit, NotInForInit };
399
400
    // While on a |let| Name token, examine |next| (which must already be
401
    // gotten).  Indicate whether |next|, the next token already gotten with
402
    // modifier TokenStream::None, continues a LexicalDeclaration.
403
    bool nextTokenContinuesLetDeclaration(TokenKind next);
404
405
    bool noteUsedNameInternal(HandlePropertyName name);
406
    bool hasUsedName(HandlePropertyName name);
407
    bool hasUsedFunctionSpecialName(HandlePropertyName name);
408
409
    bool checkAndMarkSuperScope();
410
411
    bool declareDotGeneratorName();
412
413
    bool leaveInnerFunction(ParseContext* outerpc);
414
415
    JSAtom* prefixAccessorName(PropertyType propType, HandleAtom propAtom);
416
417
    MOZ_MUST_USE bool setSourceMapInfo();
418
};
419
420
inline
421
ParseContext::Scope::Scope(ParserBase* parser)
422
  : Nestable<Scope>(&parser->pc->innermostScope_),
423
    declared_(parser->context->frontendCollectionPool()),
424
    possibleAnnexBFunctionBoxes_(parser->context->frontendCollectionPool()),
425
    id_(parser->usedNames.nextScopeId())
426
2.11k
{ }
427
428
inline
429
ParseContext::Scope::Scope(JSContext* cx, ParseContext* pc, UsedNameTracker& usedNames)
430
  : Nestable<Scope>(&pc->innermostScope_),
431
    declared_(cx->frontendCollectionPool()),
432
    possibleAnnexBFunctionBoxes_(cx->frontendCollectionPool()),
433
    id_(usedNames.nextScopeId())
434
1.52k
{ }
435
436
inline
437
ParseContext::VarScope::VarScope(ParserBase* parser)
438
  : Scope(parser)
439
61
{
440
61
    useAsVarScope(parser->pc);
441
61
}
442
443
inline
444
ParseContext::VarScope::VarScope(JSContext* cx, ParseContext* pc, UsedNameTracker& usedNames)
445
  : Scope(cx, pc, usedNames)
446
0
{
447
0
    useAsVarScope(pc);
448
0
}
449
450
enum FunctionCallBehavior {
451
    PermitAssignmentToFunctionCalls,
452
    ForbidAssignmentToFunctionCalls
453
};
454
455
template <class ParseHandler>
456
class MOZ_STACK_CLASS PerHandlerParser
457
  : public ParserBase
458
{
459
  private:
460
    using Node = typename ParseHandler::Node;
461
462
#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \
463
    using longTypeName = typename ParseHandler::longTypeName;
464
FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
465
#undef DECLARE_TYPE
466
467
  protected:
468
    /* State specific to the kind of parse being performed. */
469
    ParseHandler handler;
470
471
    // When ParseHandler is FullParseHandler:
472
    //
473
    //   If non-null, this field holds the syntax parser used to attempt lazy
474
    //   parsing of inner functions. If null, then lazy parsing is disabled.
475
    //
476
    // When ParseHandler is SyntaxParseHandler:
477
    //
478
    //   If non-null, this field must be a sentinel value signaling that the
479
    //   syntax parse was aborted. If null, then lazy parsing was aborted due
480
    //   to encountering unsupported language constructs.
481
    //
482
    // |internalSyntaxParser_| is really a |Parser<SyntaxParseHandler, CharT>*|
483
    // where |CharT| varies per |Parser<ParseHandler, CharT>|.  But this
484
    // template class doesn't know |CharT|, so we store a |void*| here and make
485
    // |GeneralParser<ParseHandler, CharT>::getSyntaxParser| impose the real type.
486
    void* internalSyntaxParser_;
487
488
  private:
489
    // NOTE: The argument ordering here is deliberately different from the
490
    //       public constructor so that typos calling the public constructor
491
    //       are less likely to select this overload.
492
    PerHandlerParser(JSContext* cx, LifoAlloc& alloc, const JS::ReadOnlyCompileOptions& options,
493
                     bool foldConstants, UsedNameTracker& usedNames, LazyScript* lazyOuterFunction,
494
                     ScriptSourceObject* sourceObject, ParseGoal parseGoal,
495
                     void* internalSyntaxParser);
496
497
  protected:
498
    template<typename CharT>
499
    PerHandlerParser(JSContext* cx, LifoAlloc& alloc, const JS::ReadOnlyCompileOptions& options,
500
                     bool foldConstants, UsedNameTracker& usedNames,
501
                     GeneralParser<SyntaxParseHandler, CharT>* syntaxParser,
502
                     LazyScript* lazyOuterFunction, ScriptSourceObject* sourceObject,
503
                     ParseGoal parseGoal)
504
      : PerHandlerParser(cx, alloc, options, foldConstants, usedNames, lazyOuterFunction,
505
                         sourceObject, parseGoal,
506
                         // JSOPTION_EXTRA_WARNINGS adds extra warnings not
507
                         // generated when functions are parsed lazily.
508
                         // ("use strict" doesn't inhibit lazy parsing.)
509
                         static_cast<void*>(options.extraWarningsOption ? nullptr : syntaxParser))
510
8
    {}
Unexecuted instantiation: js::frontend::PerHandlerParser<js::frontend::FullParseHandler>::PerHandlerParser<mozilla::Utf8Unit>(JSContext*, js::LifoAlloc&, JS::ReadOnlyCompileOptions const&, bool, js::frontend::UsedNameTracker&, js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>*, js::LazyScript*, js::ScriptSourceObject*, js::frontend::ParseGoal)
Unexecuted instantiation: js::frontend::PerHandlerParser<js::frontend::SyntaxParseHandler>::PerHandlerParser<mozilla::Utf8Unit>(JSContext*, js::LifoAlloc&, JS::ReadOnlyCompileOptions const&, bool, js::frontend::UsedNameTracker&, js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>*, js::LazyScript*, js::ScriptSourceObject*, js::frontend::ParseGoal)
js::frontend::PerHandlerParser<js::frontend::FullParseHandler>::PerHandlerParser<char16_t>(JSContext*, js::LifoAlloc&, JS::ReadOnlyCompileOptions const&, bool, js::frontend::UsedNameTracker&, js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, char16_t>*, js::LazyScript*, js::ScriptSourceObject*, js::frontend::ParseGoal)
Line
Count
Source
510
8
    {}
Unexecuted instantiation: js::frontend::PerHandlerParser<js::frontend::SyntaxParseHandler>::PerHandlerParser<char16_t>(JSContext*, js::LifoAlloc&, JS::ReadOnlyCompileOptions const&, bool, js::frontend::UsedNameTracker&, js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, char16_t>*, js::LazyScript*, js::ScriptSourceObject*, js::frontend::ParseGoal)
511
512
4.20k
    static typename ParseHandler::NullNode null() { return ParseHandler::null(); }
js::frontend::PerHandlerParser<js::frontend::FullParseHandler>::null()
Line
Count
Source
512
4.20k
    static typename ParseHandler::NullNode null() { return ParseHandler::null(); }
Unexecuted instantiation: js::frontend::PerHandlerParser<js::frontend::SyntaxParseHandler>::null()
513
514
    NameNodeType stringLiteral();
515
516
    const char* nameIsArgumentsOrEval(Node node);
517
518
    bool noteDestructuredPositionalFormalParameter(CodeNodeType funNode, Node destruct);
519
520
32.2k
    bool noteUsedName(HandlePropertyName name) {
521
32.2k
        // If the we are delazifying, the LazyScript already has all the
522
32.2k
        // closed-over info for bindings and there's no need to track used
523
32.2k
        // names.
524
32.2k
        if (handler.canSkipLazyClosedOverBindings()) {
525
0
            return true;
526
0
        }
527
32.2k
528
32.2k
        return ParserBase::noteUsedNameInternal(name);
529
32.2k
    }
js::frontend::PerHandlerParser<js::frontend::FullParseHandler>::noteUsedName(JS::Handle<js::PropertyName*>)
Line
Count
Source
520
32.2k
    bool noteUsedName(HandlePropertyName name) {
521
32.2k
        // If the we are delazifying, the LazyScript already has all the
522
32.2k
        // closed-over info for bindings and there's no need to track used
523
32.2k
        // names.
524
32.2k
        if (handler.canSkipLazyClosedOverBindings()) {
525
0
            return true;
526
0
        }
527
32.2k
528
32.2k
        return ParserBase::noteUsedNameInternal(name);
529
32.2k
    }
Unexecuted instantiation: js::frontend::PerHandlerParser<js::frontend::SyntaxParseHandler>::noteUsedName(JS::Handle<js::PropertyName*>)
530
531
    // Required on Scope exit.
532
    bool propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope);
533
534
    bool finishFunctionScopes(bool isStandaloneFunction);
535
    LexicalScopeNodeType finishLexicalScope(ParseContext::Scope& scope, Node body);
536
    bool finishFunction(bool isStandaloneFunction = false);
537
538
    bool declareFunctionThis();
539
    bool declareFunctionArgumentsObject();
540
541
    inline NameNodeType newName(PropertyName* name);
542
    inline NameNodeType newName(PropertyName* name, TokenPos pos);
543
544
    NameNodeType newInternalDotName(HandlePropertyName name);
545
    NameNodeType newThisName();
546
    NameNodeType newDotGeneratorName();
547
548
    NameNodeType identifierReference(Handle<PropertyName*> name);
549
550
    Node noSubstitutionTaggedTemplate();
551
552
    inline bool processExport(Node node);
553
    inline bool processExportFrom(BinaryNodeType node);
554
555
    // If ParseHandler is SyntaxParseHandler:
556
    //   Do nothing.
557
    // If ParseHandler is FullParseHandler:
558
    //   Disable syntax parsing of all future inner functions during this
559
    //   full-parse.
560
    inline void disableSyntaxParser();
561
562
    // If ParseHandler is SyntaxParseHandler:
563
    //   Flag the current syntax parse as aborted due to unsupported language
564
    //   constructs and return false.  Aborting the current syntax parse does
565
    //   not disable attempts to syntax-parse future inner functions.
566
    // If ParseHandler is FullParseHandler:
567
    //    Disable syntax parsing of all future inner functions and return true.
568
    inline bool abortIfSyntaxParser();
569
570
    // If ParseHandler is SyntaxParseHandler:
571
    //   Return whether the last syntax parse was aborted due to unsupported
572
    //   language constructs.
573
    // If ParseHandler is FullParseHandler:
574
    //   Return false.
575
    inline bool hadAbortedSyntaxParse();
576
577
    // If ParseHandler is SyntaxParseHandler:
578
    //   Clear whether the last syntax parse was aborted.
579
    // If ParseHandler is FullParseHandler:
580
    //   Do nothing.
581
    inline void clearAbortedSyntaxParse();
582
583
  public:
584
    bool isValidSimpleAssignmentTarget(Node node,
585
                                       FunctionCallBehavior behavior = ForbidAssignmentToFunctionCalls);
586
587
12
    NameNodeType newPropertyName(PropertyName* key, const TokenPos& pos) {
588
12
        return handler.newPropertyName(key, pos);
589
12
    }
js::frontend::PerHandlerParser<js::frontend::FullParseHandler>::newPropertyName(js::PropertyName*, js::frontend::TokenPos const&)
Line
Count
Source
587
12
    NameNodeType newPropertyName(PropertyName* key, const TokenPos& pos) {
588
12
        return handler.newPropertyName(key, pos);
589
12
    }
Unexecuted instantiation: js::frontend::PerHandlerParser<js::frontend::SyntaxParseHandler>::newPropertyName(js::PropertyName*, js::frontend::TokenPos const&)
590
591
12
    PropertyAccessType newPropertyAccess(Node expr, NameNodeType key) {
592
12
        return handler.newPropertyAccess(expr, key);
593
12
    }
js::frontend::PerHandlerParser<js::frontend::FullParseHandler>::newPropertyAccess(js::frontend::ParseNode*, js::frontend::NameNode*)
Line
Count
Source
591
12
    PropertyAccessType newPropertyAccess(Node expr, NameNodeType key) {
592
12
        return handler.newPropertyAccess(expr, key);
593
12
    }
Unexecuted instantiation: js::frontend::PerHandlerParser<js::frontend::SyntaxParseHandler>::newPropertyAccess(js::frontend::SyntaxParseHandler::Node, js::frontend::SyntaxParseHandler::Node)
594
595
    FunctionBox* newFunctionBox(CodeNodeType funNode, JSFunction* fun, uint32_t toStringStart,
596
                                Directives directives, GeneratorKind generatorKind,
597
                                FunctionAsyncKind asyncKind);
598
};
599
600
0
#define ABORTED_SYNTAX_PARSE_SENTINEL reinterpret_cast<void*>(0x1)
601
602
template<>
603
inline void
604
PerHandlerParser<SyntaxParseHandler>::disableSyntaxParser()
605
0
{
606
0
}
607
608
template<>
609
inline bool
610
PerHandlerParser<SyntaxParseHandler>::abortIfSyntaxParser()
611
0
{
612
0
    internalSyntaxParser_ = ABORTED_SYNTAX_PARSE_SENTINEL;
613
0
    return false;
614
0
}
615
616
template<>
617
inline bool
618
PerHandlerParser<SyntaxParseHandler>::hadAbortedSyntaxParse()
619
0
{
620
0
    return internalSyntaxParser_ == ABORTED_SYNTAX_PARSE_SENTINEL;
621
0
}
622
623
template<>
624
inline void
625
PerHandlerParser<SyntaxParseHandler>::clearAbortedSyntaxParse()
626
0
{
627
0
    internalSyntaxParser_ = nullptr;
628
0
}
629
630
#undef ABORTED_SYNTAX_PARSE_SENTINEL
631
632
// Disable syntax parsing of all future inner functions during this
633
// full-parse.
634
template<>
635
inline void
636
PerHandlerParser<FullParseHandler>::disableSyntaxParser()
637
0
{
638
0
    internalSyntaxParser_ = nullptr;
639
0
}
640
641
template<>
642
inline bool
643
PerHandlerParser<FullParseHandler>::abortIfSyntaxParser()
644
0
{
645
0
    disableSyntaxParser();
646
0
    return true;
647
0
}
648
649
template<>
650
inline bool
651
PerHandlerParser<FullParseHandler>::hadAbortedSyntaxParse()
652
0
{
653
0
    return false;
654
0
}
655
656
template<>
657
inline void
658
PerHandlerParser<FullParseHandler>::clearAbortedSyntaxParse()
659
0
{
660
0
}
661
662
template<class Parser>
663
class ParserAnyCharsAccess
664
{
665
  public:
666
    using TokenStreamSpecific = typename Parser::TokenStream;
667
    using GeneralTokenStreamChars = typename TokenStreamSpecific::GeneralCharsBase;
668
669
    static inline TokenStreamAnyChars& anyChars(GeneralTokenStreamChars* ts);
670
    static inline const TokenStreamAnyChars& anyChars(const GeneralTokenStreamChars* ts);
671
};
672
673
// Specify a value for an ES6 grammar parametrization.  We have no enum for
674
// [Return] because its behavior is exactly equivalent to checking whether
675
// we're in a function box -- easier and simpler than passing an extra
676
// parameter everywhere.
677
enum YieldHandling { YieldIsName, YieldIsKeyword };
678
enum InHandling { InAllowed, InProhibited };
679
enum DefaultHandling { NameRequired, AllowDefaultName };
680
enum TripledotHandling { TripledotAllowed, TripledotProhibited };
681
682
template <class ParseHandler, typename CharT>
683
class Parser;
684
685
template <class ParseHandler, typename CharT>
686
class MOZ_STACK_CLASS GeneralParser
687
  : public PerHandlerParser<ParseHandler>
688
{
689
  public:
690
    using TokenStream = TokenStreamSpecific<CharT, ParserAnyCharsAccess<GeneralParser>>;
691
692
  private:
693
    using Base = PerHandlerParser<ParseHandler>;
694
    using FinalParser = Parser<ParseHandler, CharT>;
695
    using Node = typename ParseHandler::Node;
696
697
#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \
698
    using longTypeName = typename ParseHandler::longTypeName;
699
FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
700
#undef DECLARE_TYPE
701
702
    using typename Base::InvokedPrediction;
703
    using SyntaxParser = Parser<SyntaxParseHandler, CharT>;
704
705
  protected:
706
    using Modifier = TokenStreamShared::Modifier;
707
    using Position = typename TokenStream::Position;
708
709
    using Base::PredictUninvoked;
710
    using Base::PredictInvoked;
711
712
    using Base::alloc;
713
    using Base::awaitIsKeyword;
714
    using Base::inParametersOfAsyncFunction;
715
    using Base::parseGoal;
716
#if DEBUG
717
    using Base::checkOptionsCalled;
718
#endif
719
    using Base::finishFunctionScopes;
720
    using Base::finishLexicalScope;
721
    using Base::foldConstants;
722
    using Base::getFilename;
723
    using Base::hasUsedFunctionSpecialName;
724
    using Base::hasValidSimpleStrictParameterNames;
725
    using Base::isUnexpectedEOF_;
726
    using Base::keepAtoms;
727
    using Base::nameIsArgumentsOrEval;
728
    using Base::newFunction;
729
    using Base::newFunctionBox;
730
    using Base::newName;
731
    using Base::null;
732
    using Base::options;
733
    using Base::pos;
734
    using Base::propagateFreeNamesAndMarkClosedOverBindings;
735
    using Base::setLocalStrictMode;
736
    using Base::stringLiteral;
737
    using Base::traceListHead;
738
    using Base::yieldExpressionsSupported;
739
740
    using Base::disableSyntaxParser;
741
    using Base::abortIfSyntaxParser;
742
    using Base::hadAbortedSyntaxParse;
743
    using Base::clearAbortedSyntaxParse;
744
745
  public:
746
    using Base::anyChars;
747
    using Base::context;
748
    using Base::handler;
749
    using Base::isValidSimpleAssignmentTarget;
750
    using Base::pc;
751
    using Base::usedNames;
752
753
  private:
754
    using Base::checkAndMarkSuperScope;
755
    using Base::declareDotGeneratorName;
756
    using Base::declareFunctionArgumentsObject;
757
    using Base::declareFunctionThis;
758
    using Base::finishFunction;
759
    using Base::hasUsedName;
760
    using Base::identifierReference;
761
    using Base::leaveInnerFunction;
762
    using Base::newDotGeneratorName;
763
    using Base::newInternalDotName;
764
    using Base::newThisName;
765
    using Base::nextTokenContinuesLetDeclaration;
766
    using Base::noSubstitutionTaggedTemplate;
767
    using Base::noteDestructuredPositionalFormalParameter;
768
    using Base::noteUsedName;
769
    using Base::prefixAccessorName;
770
    using Base::processExport;
771
    using Base::processExportFrom;
772
773
  private:
774
    inline FinalParser* asFinalParser();
775
    inline const FinalParser* asFinalParser() const;
776
777
    /*
778
     * A class for temporarily stashing errors while parsing continues.
779
     *
780
     * The ability to stash an error is useful for handling situations where we
781
     * aren't able to verify that an error has occurred until later in the parse.
782
     * For instance | ({x=1}) | is always parsed as an object literal with
783
     * a SyntaxError, however, in the case where it is followed by '=>' we rewind
784
     * and reparse it as a valid arrow function. Here a PossibleError would be
785
     * set to 'pending' when the initial SyntaxError was encountered then 'resolved'
786
     * just before rewinding the parser.
787
     *
788
     * There are currently two kinds of PossibleErrors: Expression and
789
     * Destructuring errors. Expression errors are used to mark a possible
790
     * syntax error when a grammar production is used in an expression context.
791
     * For example in |{x = 1}|, we mark the CoverInitializedName |x = 1| as a
792
     * possible expression error, because CoverInitializedName productions
793
     * are disallowed when an actual ObjectLiteral is expected.
794
     * Destructuring errors are used to record possible syntax errors in
795
     * destructuring contexts. For example in |[...rest, ] = []|, we initially
796
     * mark the trailing comma after the spread expression as a possible
797
     * destructuring error, because the ArrayAssignmentPattern grammar
798
     * production doesn't allow a trailing comma after the rest element.
799
     *
800
     * When using PossibleError one should set a pending error at the location
801
     * where an error occurs. From that point, the error may be resolved
802
     * (invalidated) or left until the PossibleError is checked.
803
     *
804
     * Ex:
805
     *   PossibleError possibleError(*this);
806
     *   possibleError.setPendingExpressionErrorAt(pos, JSMSG_BAD_PROP_ID);
807
     *   // A JSMSG_BAD_PROP_ID ParseError is reported, returns false.
808
     *   if (!possibleError.checkForExpressionError())
809
     *       return false; // we reach this point with a pending exception
810
     *
811
     *   PossibleError possibleError(*this);
812
     *   possibleError.setPendingExpressionErrorAt(pos, JSMSG_BAD_PROP_ID);
813
     *   // Returns true, no error is reported.
814
     *   if (!possibleError.checkForDestructuringError())
815
     *       return false; // not reached, no pending exception
816
     *
817
     *   PossibleError possibleError(*this);
818
     *   // Returns true, no error is reported.
819
     *   if (!possibleError.checkForExpressionError())
820
     *       return false; // not reached, no pending exception
821
     */
822
    class MOZ_STACK_CLASS PossibleError
823
    {
824
      private:
825
        enum class ErrorKind { Expression, Destructuring, DestructuringWarning };
826
827
        enum class ErrorState { None, Pending };
828
829
        struct Error {
830
            ErrorState state_ = ErrorState::None;
831
832
            // Error reporting fields.
833
            uint32_t offset_;
834
            unsigned errorNumber_;
835
        };
836
837
        GeneralParser<ParseHandler, CharT>& parser_;
838
        Error exprError_;
839
        Error destructuringError_;
840
        Error destructuringWarning_;
841
842
        // Returns the error report.
843
        Error& error(ErrorKind kind);
844
845
        // Return true if an error is pending without reporting.
846
        bool hasError(ErrorKind kind);
847
848
        // Resolve any pending error.
849
        void setResolved(ErrorKind kind);
850
851
        // Set a pending error. Only a single error may be set per instance and
852
        // error kind.
853
        void setPending(ErrorKind kind, const TokenPos& pos, unsigned errorNumber);
854
855
        // If there is a pending error, report it and return false, otherwise
856
        // return true.
857
        MOZ_MUST_USE bool checkForError(ErrorKind kind);
858
859
        // If there is a pending warning, report it and return either false or
860
        // true depending on the werror option, otherwise return true.
861
        MOZ_MUST_USE bool checkForWarning(ErrorKind kind);
862
863
        // Transfer an existing error to another instance.
864
        void transferErrorTo(ErrorKind kind, PossibleError* other);
865
866
      public:
867
        explicit PossibleError(GeneralParser<ParseHandler, CharT>& parser);
868
869
        // Return true if a pending destructuring error is present.
870
        bool hasPendingDestructuringError();
871
872
        // Set a pending destructuring error. Only a single error may be set
873
        // per instance, i.e. subsequent calls to this method are ignored and
874
        // won't overwrite the existing pending error.
875
        void setPendingDestructuringErrorAt(const TokenPos& pos, unsigned errorNumber);
876
877
        // Set a pending destructuring warning. Only a single warning may be
878
        // set per instance, i.e. subsequent calls to this method are ignored
879
        // and won't overwrite the existing pending warning.
880
        void setPendingDestructuringWarningAt(const TokenPos& pos, unsigned errorNumber);
881
882
        // Set a pending expression error. Only a single error may be set per
883
        // instance, i.e. subsequent calls to this method are ignored and won't
884
        // overwrite the existing pending error.
885
        void setPendingExpressionErrorAt(const TokenPos& pos, unsigned errorNumber);
886
887
        // If there is a pending destructuring error or warning, report it and
888
        // return false, otherwise return true. Clears any pending expression
889
        // error.
890
        MOZ_MUST_USE bool checkForDestructuringErrorOrWarning();
891
892
        // If there is a pending expression error, report it and return false,
893
        // otherwise return true. Clears any pending destructuring error or
894
        // warning.
895
        MOZ_MUST_USE bool checkForExpressionError();
896
897
        // Pass pending errors between possible error instances. This is useful
898
        // for extending the lifetime of a pending error beyond the scope of
899
        // the PossibleError where it was initially set (keeping in mind that
900
        // PossibleError is a MOZ_STACK_CLASS).
901
        void transferErrorsTo(PossibleError* other);
902
    };
903
904
  protected:
905
13.5k
    SyntaxParser* getSyntaxParser() const {
906
13.5k
        return reinterpret_cast<SyntaxParser*>(Base::internalSyntaxParser_);
907
13.5k
    }
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::FullParseHandler, mozilla::Utf8Unit>::getSyntaxParser() const
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>::getSyntaxParser() const
js::frontend::GeneralParser<js::frontend::FullParseHandler, char16_t>::getSyntaxParser() const
Line
Count
Source
905
13.5k
    SyntaxParser* getSyntaxParser() const {
906
13.5k
        return reinterpret_cast<SyntaxParser*>(Base::internalSyntaxParser_);
907
13.5k
    }
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, char16_t>::getSyntaxParser() const
908
909
  public:
910
    TokenStream tokenStream;
911
912
  public:
913
    GeneralParser(JSContext* cx, LifoAlloc& alloc, const JS::ReadOnlyCompileOptions& options,
914
                  const CharT* chars, size_t length, bool foldConstants,
915
                  UsedNameTracker& usedNames, SyntaxParser* syntaxParser,
916
                  LazyScript* lazyOuterFunction,
917
                  ScriptSourceObject* sourceObject,
918
                  ParseGoal parseGoal);
919
920
    inline void setAwaitHandling(AwaitHandling awaitHandling);
921
    inline void setInParametersOfAsyncFunction(bool inParameters);
922
923
    /*
924
     * Parse a top-level JS script.
925
     */
926
    ListNodeType parse();
927
928
    /* Report the given error at the current offset. */
929
    void error(unsigned errorNumber, ...);
930
    void errorWithNotes(UniquePtr<JSErrorNotes> notes, unsigned errorNumber, ...);
931
932
    /* Report the given error at the given offset. */
933
    void errorAt(uint32_t offset, unsigned errorNumber, ...);
934
    void errorWithNotesAt(UniquePtr<JSErrorNotes> notes, uint32_t offset,
935
                          unsigned errorNumber, ...);
936
937
    /*
938
     * Handle a strict mode error at the current offset.  Report an error if in
939
     * strict mode code, or warn if not, using the given error number and
940
     * arguments.
941
     */
942
    MOZ_MUST_USE bool strictModeError(unsigned errorNumber, ...);
943
944
    /*
945
     * Handle a strict mode error at the given offset.  Report an error if in
946
     * strict mode code, or warn if not, using the given error number and
947
     * arguments.
948
     */
949
    MOZ_MUST_USE bool strictModeErrorAt(uint32_t offset, unsigned errorNumber, ...);
950
951
    /* Report the given warning at the current offset. */
952
    MOZ_MUST_USE bool warning(unsigned errorNumber, ...);
953
954
    /* Report the given warning at the given offset. */
955
    MOZ_MUST_USE bool warningAt(uint32_t offset, unsigned errorNumber, ...);
956
957
    /*
958
     * If extra warnings are enabled, report the given warning at the current
959
     * offset.
960
     */
961
    MOZ_MUST_USE bool extraWarning(unsigned errorNumber, ...);
962
963
    /*
964
     * If extra warnings are enabled, report the given warning at the given
965
     * offset.
966
     */
967
    MOZ_MUST_USE bool extraWarningAt(uint32_t offset, unsigned errorNumber, ...);
968
969
  private:
970
0
    GeneralParser* thisForCtor() { return this; }
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::FullParseHandler, mozilla::Utf8Unit>::thisForCtor()
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>::thisForCtor()
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::FullParseHandler, char16_t>::thisForCtor()
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, char16_t>::thisForCtor()
971
972
    NameNodeType noSubstitutionUntaggedTemplate();
973
    ListNodeType templateLiteral(YieldHandling yieldHandling);
974
    bool taggedTemplate(YieldHandling yieldHandling, ListNodeType tagArgsList, TokenKind tt);
975
    bool appendToCallSiteObj(CallSiteNodeType callSiteObj);
976
    bool addExprAndGetNextTemplStrToken(YieldHandling yieldHandling, ListNodeType nodeList,
977
                                        TokenKind* ttp);
978
979
    inline bool trySyntaxParseInnerFunction(CodeNodeType* funNode, HandleFunction fun,
980
                                            uint32_t toStringStart, InHandling inHandling,
981
                                            YieldHandling yieldHandling, FunctionSyntaxKind kind,
982
                                            GeneratorKind generatorKind,
983
                                            FunctionAsyncKind asyncKind, bool tryAnnexB,
984
                                            Directives inheritedDirectives,
985
                                            Directives* newDirectives);
986
987
    inline bool skipLazyInnerFunction(CodeNodeType funNode, uint32_t toStringStart,
988
                                      FunctionSyntaxKind kind, bool tryAnnexB);
989
990
  public:
991
    /* Public entry points for parsing. */
992
    Node statementListItem(YieldHandling yieldHandling, bool canHaveDirectives = false);
993
994
    // Parse an inner function given an enclosing ParseContext and a
995
    // FunctionBox for the inner function.
996
    MOZ_MUST_USE CodeNodeType
997
    innerFunctionForFunctionBox(CodeNodeType funNode, ParseContext* outerpc, FunctionBox* funbox,
998
                                InHandling inHandling, YieldHandling yieldHandling,
999
                                FunctionSyntaxKind kind, Directives* newDirectives);
1000
1001
    // Parse a function's formal parameters and its body assuming its function
1002
    // ParseContext is already on the stack.
1003
    bool functionFormalParametersAndBody(InHandling inHandling, YieldHandling yieldHandling,
1004
                                         CodeNodeType* funNode, FunctionSyntaxKind kind,
1005
                                         const mozilla::Maybe<uint32_t>& parameterListEnd = mozilla::Nothing(),
1006
                                         bool isStandaloneFunction = false);
1007
1008
  private:
1009
    /*
1010
     * JS parsers, from lowest to highest precedence.
1011
     *
1012
     * Each parser must be called during the dynamic scope of a ParseContext
1013
     * object, pointed to by this->pc.
1014
     *
1015
     * Each returns a parse node tree or null on error.
1016
     */
1017
    CodeNodeType functionStmt(uint32_t toStringStart,
1018
                              YieldHandling yieldHandling, DefaultHandling defaultHandling,
1019
                              FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
1020
    CodeNodeType functionExpr(uint32_t toStringStart, InvokedPrediction invoked,
1021
                              FunctionAsyncKind asyncKind);
1022
1023
    Node statement(YieldHandling yieldHandling);
1024
    bool maybeParseDirective(ListNodeType list, Node pn, bool* cont);
1025
1026
    LexicalScopeNodeType blockStatement(YieldHandling yieldHandling,
1027
                                        unsigned errorNumber = JSMSG_CURLY_IN_COMPOUND);
1028
    BinaryNodeType doWhileStatement(YieldHandling yieldHandling);
1029
    BinaryNodeType whileStatement(YieldHandling yieldHandling);
1030
1031
    Node forStatement(YieldHandling yieldHandling);
1032
    bool forHeadStart(YieldHandling yieldHandling,
1033
                      ParseNodeKind* forHeadKind,
1034
                      Node* forInitialPart,
1035
                      mozilla::Maybe<ParseContext::Scope>& forLetImpliedScope,
1036
                      Node* forInOrOfExpression);
1037
    Node expressionAfterForInOrOf(ParseNodeKind forHeadKind, YieldHandling yieldHandling);
1038
1039
    SwitchStatementType switchStatement(YieldHandling yieldHandling);
1040
    ContinueStatementType continueStatement(YieldHandling yieldHandling);
1041
    BreakStatementType breakStatement(YieldHandling yieldHandling);
1042
    UnaryNodeType returnStatement(YieldHandling yieldHandling);
1043
    BinaryNodeType withStatement(YieldHandling yieldHandling);
1044
    UnaryNodeType throwStatement(YieldHandling yieldHandling);
1045
    TernaryNodeType tryStatement(YieldHandling yieldHandling);
1046
    LexicalScopeNodeType catchBlockStatement(YieldHandling yieldHandling, ParseContext::Scope& catchParamScope);
1047
    DebuggerStatementType debuggerStatement();
1048
1049
    Node variableStatement(YieldHandling yieldHandling);
1050
1051
    LabeledStatementType labeledStatement(YieldHandling yieldHandling);
1052
    Node labeledItem(YieldHandling yieldHandling);
1053
1054
    TernaryNodeType ifStatement(YieldHandling yieldHandling);
1055
    Node consequentOrAlternative(YieldHandling yieldHandling);
1056
1057
    ListNodeType lexicalDeclaration(YieldHandling yieldHandling, DeclarationKind kind);
1058
1059
    inline BinaryNodeType importDeclaration();
1060
    Node importDeclarationOrImportExpr(YieldHandling yieldHandling);
1061
1062
    BinaryNodeType exportFrom(uint32_t begin, Node specList);
1063
    BinaryNodeType exportBatch(uint32_t begin);
1064
    inline bool checkLocalExportNames(ListNodeType node);
1065
    Node exportClause(uint32_t begin);
1066
    UnaryNodeType exportFunctionDeclaration(uint32_t begin, uint32_t toStringStart,
1067
                                            FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
1068
    UnaryNodeType exportVariableStatement(uint32_t begin);
1069
    UnaryNodeType exportClassDeclaration(uint32_t begin);
1070
    UnaryNodeType exportLexicalDeclaration(uint32_t begin, DeclarationKind kind);
1071
    BinaryNodeType exportDefaultFunctionDeclaration(uint32_t begin, uint32_t toStringStart,
1072
                                                    FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
1073
    BinaryNodeType exportDefaultClassDeclaration(uint32_t begin);
1074
    BinaryNodeType exportDefaultAssignExpr(uint32_t begin);
1075
    BinaryNodeType exportDefault(uint32_t begin);
1076
    Node exportDeclaration();
1077
1078
    UnaryNodeType expressionStatement(YieldHandling yieldHandling,
1079
                                      InvokedPrediction invoked = PredictUninvoked);
1080
1081
    // Declaration parsing.  The main entrypoint is Parser::declarationList,
1082
    // with sub-functionality split out into the remaining methods.
1083
1084
    // |blockScope| may be non-null only when |kind| corresponds to a lexical
1085
    // declaration (that is, PNK_LET or PNK_CONST).
1086
    //
1087
    // The for* parameters, for normal declarations, should be null/ignored.
1088
    // They should be non-null only when Parser::forHeadStart parses a
1089
    // declaration at the start of a for-loop head.
1090
    //
1091
    // In this case, on success |*forHeadKind| is PNK_FORHEAD, PNK_FORIN, or
1092
    // PNK_FOROF, corresponding to the three for-loop kinds.  The precise value
1093
    // indicates what was parsed.
1094
    //
1095
    // If parsing recognized a for(;;) loop, the next token is the ';' within
1096
    // the loop-head that separates the init/test parts.
1097
    //
1098
    // Otherwise, for for-in/of loops, the next token is the ')' ending the
1099
    // loop-head.  Additionally, the expression that the loop iterates over was
1100
    // parsed into |*forInOrOfExpression|.
1101
    ListNodeType declarationList(YieldHandling yieldHandling,
1102
                                 ParseNodeKind kind,
1103
                                 ParseNodeKind* forHeadKind = nullptr,
1104
                                 Node* forInOrOfExpression = nullptr);
1105
1106
    // The items in a declaration list are either patterns or names, with or
1107
    // without initializers.  These two methods parse a single pattern/name and
1108
    // any associated initializer -- and if parsing an |initialDeclaration|
1109
    // will, if parsing in a for-loop head (as specified by |forHeadKind| being
1110
    // non-null), consume additional tokens up to the closing ')' in a
1111
    // for-in/of loop head, returning the iterated expression in
1112
    // |*forInOrOfExpression|.  (An "initial declaration" is the first
1113
    // declaration in a declaration list: |a| but not |b| in |var a, b|, |{c}|
1114
    // but not |d| in |let {c} = 3, d|.)
1115
    Node declarationPattern(DeclarationKind declKind, TokenKind tt,
1116
                            bool initialDeclaration, YieldHandling yieldHandling,
1117
                            ParseNodeKind* forHeadKind, Node* forInOrOfExpression);
1118
    NameNodeType declarationName(DeclarationKind declKind, TokenKind tt,
1119
                                 bool initialDeclaration, YieldHandling yieldHandling,
1120
                                 ParseNodeKind* forHeadKind, Node* forInOrOfExpression);
1121
1122
    // Having parsed a name (not found in a destructuring pattern) declared by
1123
    // a declaration, with the current token being the '=' separating the name
1124
    // from its initializer, parse and bind that initializer -- and possibly
1125
    // consume trailing in/of and subsequent expression, if so directed by
1126
    // |forHeadKind|.
1127
    bool initializerInNameDeclaration(NameNodeType binding,
1128
                                      DeclarationKind declKind, bool initialDeclaration,
1129
                                      YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
1130
                                      Node* forInOrOfExpression);
1131
1132
    Node expr(InHandling inHandling, YieldHandling yieldHandling,
1133
              TripledotHandling tripledotHandling, PossibleError* possibleError = nullptr,
1134
              InvokedPrediction invoked = PredictUninvoked);
1135
    Node assignExpr(InHandling inHandling, YieldHandling yieldHandling,
1136
                    TripledotHandling tripledotHandling, PossibleError* possibleError = nullptr,
1137
                    InvokedPrediction invoked = PredictUninvoked);
1138
    Node assignExprWithoutYieldOrAwait(YieldHandling yieldHandling);
1139
    UnaryNodeType yieldExpression(InHandling inHandling);
1140
    Node condExpr(InHandling inHandling, YieldHandling yieldHandling,
1141
                  TripledotHandling tripledotHandling, PossibleError* possibleError,
1142
                  InvokedPrediction invoked = PredictUninvoked);
1143
    Node orExpr(InHandling inHandling, YieldHandling yieldHandling,
1144
                TripledotHandling tripledotHandling, PossibleError* possibleError,
1145
                InvokedPrediction invoked = PredictUninvoked);
1146
    Node unaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
1147
                   PossibleError* possibleError = nullptr,
1148
                   InvokedPrediction invoked = PredictUninvoked);
1149
    Node memberExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling, TokenKind tt,
1150
                    bool allowCallSyntax = true, PossibleError* possibleError = nullptr,
1151
                    InvokedPrediction invoked = PredictUninvoked);
1152
    Node primaryExpr(YieldHandling yieldHandling, TripledotHandling tripledotHandling,
1153
                     TokenKind tt, PossibleError* possibleError,
1154
                     InvokedPrediction invoked = PredictUninvoked);
1155
    Node exprInParens(InHandling inHandling, YieldHandling yieldHandling,
1156
                      TripledotHandling tripledotHandling, PossibleError* possibleError = nullptr);
1157
1158
    bool tryNewTarget(BinaryNodeType* newTarget);
1159
1160
    BinaryNodeType importExpr(YieldHandling yieldHandling);
1161
1162
    CodeNodeType methodDefinition(uint32_t toStringStart, PropertyType propType,
1163
                                  HandleAtom funName);
1164
1165
    /*
1166
     * Additional JS parsers.
1167
     */
1168
    bool functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind,
1169
                           CodeNodeType funNode);
1170
1171
    CodeNodeType functionDefinition(CodeNodeType funNode, uint32_t toStringStart,
1172
                                    InHandling inHandling, YieldHandling yieldHandling,
1173
                                    HandleAtom name, FunctionSyntaxKind kind,
1174
                                    GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
1175
                                    bool tryAnnexB = false);
1176
1177
    // Parse a function body.  Pass StatementListBody if the body is a list of
1178
    // statements; pass ExpressionBody if the body is a single expression.
1179
    enum FunctionBodyType { StatementListBody, ExpressionBody };
1180
    LexicalScopeNodeType functionBody(InHandling inHandling, YieldHandling yieldHandling,
1181
                                      FunctionSyntaxKind kind, FunctionBodyType type);
1182
1183
    UnaryNodeType unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind, uint32_t begin);
1184
1185
    Node condition(InHandling inHandling, YieldHandling yieldHandling);
1186
1187
    ListNodeType argumentList(YieldHandling yieldHandling, bool* isSpread,
1188
                              PossibleError* possibleError = nullptr);
1189
    Node destructuringDeclaration(DeclarationKind kind, YieldHandling yieldHandling,
1190
                                  TokenKind tt);
1191
    Node destructuringDeclarationWithoutYieldOrAwait(DeclarationKind kind, YieldHandling yieldHandling,
1192
                                                     TokenKind tt);
1193
1194
    inline bool checkExportedName(JSAtom* exportName);
1195
    inline bool checkExportedNamesForArrayBinding(ListNodeType array);
1196
    inline bool checkExportedNamesForObjectBinding(ListNodeType obj);
1197
    inline bool checkExportedNamesForDeclaration(Node node);
1198
    inline bool checkExportedNamesForDeclarationList(ListNodeType node);
1199
    inline bool checkExportedNameForFunction(CodeNodeType funNode);
1200
    inline bool checkExportedNameForClass(ClassNodeType classNode);
1201
    inline bool checkExportedNameForClause(NameNodeType nameNode);
1202
1203
    enum ClassContext { ClassStatement, ClassExpression };
1204
    ClassNodeType classDefinition(YieldHandling yieldHandling, ClassContext classContext,
1205
                                  DefaultHandling defaultHandling);
1206
1207
    bool checkBindingIdentifier(PropertyName* ident,
1208
                                uint32_t offset,
1209
                                YieldHandling yieldHandling,
1210
                                TokenKind hint = TokenKind::Limit);
1211
1212
    PropertyName* labelOrIdentifierReference(YieldHandling yieldHandling);
1213
1214
0
    PropertyName* labelIdentifier(YieldHandling yieldHandling) {
1215
0
        return labelOrIdentifierReference(yieldHandling);
1216
0
    }
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::FullParseHandler, mozilla::Utf8Unit>::labelIdentifier(js::frontend::YieldHandling)
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>::labelIdentifier(js::frontend::YieldHandling)
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::FullParseHandler, char16_t>::labelIdentifier(js::frontend::YieldHandling)
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, char16_t>::labelIdentifier(js::frontend::YieldHandling)
1217
1218
31.2k
    PropertyName* identifierReference(YieldHandling yieldHandling) {
1219
31.2k
        return labelOrIdentifierReference(yieldHandling);
1220
31.2k
    }
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::FullParseHandler, mozilla::Utf8Unit>::identifierReference(js::frontend::YieldHandling)
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>::identifierReference(js::frontend::YieldHandling)
js::frontend::GeneralParser<js::frontend::FullParseHandler, char16_t>::identifierReference(js::frontend::YieldHandling)
Line
Count
Source
1218
31.2k
    PropertyName* identifierReference(YieldHandling yieldHandling) {
1219
31.2k
        return labelOrIdentifierReference(yieldHandling);
1220
31.2k
    }
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, char16_t>::identifierReference(js::frontend::YieldHandling)
1221
1222
    bool matchLabel(YieldHandling yieldHandling, MutableHandle<PropertyName*> label);
1223
1224
    // Indicate if the next token (tokenized as Operand) is |in| or |of|.  If
1225
    // so, consume it.
1226
    bool matchInOrOf(bool* isForInp, bool* isForOfp);
1227
1228
  private:
1229
    bool checkIncDecOperand(Node operand, uint32_t operandOffset);
1230
    bool checkStrictAssignment(Node lhs);
1231
1232
    void reportMissingClosing(unsigned errorNumber, unsigned noteNumber, uint32_t openedPos);
1233
1234
    void reportRedeclaration(HandlePropertyName name, DeclarationKind prevKind, TokenPos pos,
1235
                             uint32_t prevPos);
1236
    bool notePositionalFormalParameter(CodeNodeType funNode, HandlePropertyName name,
1237
                                       uint32_t beginPos,
1238
                                       bool disallowDuplicateParams, bool* duplicatedParam);
1239
1240
    bool checkLexicalDeclarationDirectlyWithinBlock(ParseContext::Statement& stmt,
1241
                                                    DeclarationKind kind, TokenPos pos);
1242
1243
    Node propertyName(YieldHandling yieldHandling,
1244
                      const mozilla::Maybe<DeclarationKind>& maybeDecl,
1245
                      ListNodeType propList,
1246
                      PropertyType* propType, MutableHandleAtom propAtom);
1247
    UnaryNodeType computedPropertyName(YieldHandling yieldHandling,
1248
                                       const mozilla::Maybe<DeclarationKind>& maybeDecl,
1249
                                       ListNodeType literal);
1250
    ListNodeType arrayInitializer(YieldHandling yieldHandling, PossibleError* possibleError);
1251
    inline RegExpLiteralType newRegExp();
1252
1253
    ListNodeType objectLiteral(YieldHandling yieldHandling, PossibleError* possibleError);
1254
1255
    BinaryNodeType bindingInitializer(Node lhs, DeclarationKind kind, YieldHandling yieldHandling);
1256
    NameNodeType bindingIdentifier(DeclarationKind kind, YieldHandling yieldHandling);
1257
    Node bindingIdentifierOrPattern(DeclarationKind kind, YieldHandling yieldHandling,
1258
                                    TokenKind tt);
1259
    ListNodeType objectBindingPattern(DeclarationKind kind, YieldHandling yieldHandling);
1260
    ListNodeType arrayBindingPattern(DeclarationKind kind, YieldHandling yieldHandling);
1261
1262
    enum class TargetBehavior {
1263
        PermitAssignmentPattern,
1264
        ForbidAssignmentPattern
1265
    };
1266
    bool checkDestructuringAssignmentTarget(Node expr, TokenPos exprPos,
1267
                                            PossibleError* exprPossibleError,
1268
                                            PossibleError* possibleError,
1269
                                            TargetBehavior behavior = TargetBehavior::PermitAssignmentPattern);
1270
    void checkDestructuringAssignmentName(NameNodeType name, TokenPos namePos,
1271
                                          PossibleError* possibleError);
1272
    bool checkDestructuringAssignmentElement(Node expr, TokenPos exprPos,
1273
                                             PossibleError* exprPossibleError,
1274
                                             PossibleError* possibleError);
1275
1276
7.90k
    NumericLiteralType newNumber(const Token& tok) {
1277
7.90k
        return handler.newNumber(tok.number(), tok.decimalPoint(), tok.pos);
1278
7.90k
    }
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::FullParseHandler, mozilla::Utf8Unit>::newNumber(js::frontend::Token const&)
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>::newNumber(js::frontend::Token const&)
js::frontend::GeneralParser<js::frontend::FullParseHandler, char16_t>::newNumber(js::frontend::Token const&)
Line
Count
Source
1276
7.90k
    NumericLiteralType newNumber(const Token& tok) {
1277
7.90k
        return handler.newNumber(tok.number(), tok.decimalPoint(), tok.pos);
1278
7.90k
    }
Unexecuted instantiation: js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, char16_t>::newNumber(js::frontend::Token const&)
1279
1280
  protected:
1281
    // Match the current token against the BindingIdentifier production with
1282
    // the given Yield parameter.  If there is no match, report a syntax
1283
    // error.
1284
    PropertyName* bindingIdentifier(YieldHandling yieldHandling);
1285
1286
    bool checkLabelOrIdentifierReference(PropertyName* ident, uint32_t offset,
1287
                                         YieldHandling yieldHandling,
1288
                                         TokenKind hint = TokenKind::Limit);
1289
1290
    ListNodeType statementList(YieldHandling yieldHandling);
1291
1292
    MOZ_MUST_USE CodeNodeType
1293
    innerFunction(CodeNodeType funNode, ParseContext* outerpc, HandleFunction fun,
1294
                  uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling,
1295
                  FunctionSyntaxKind kind, GeneratorKind generatorKind,
1296
                  FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives,
1297
                  Directives* newDirectives);
1298
1299
    bool matchOrInsertSemicolon();
1300
1301
    bool noteDeclaredName(HandlePropertyName name, DeclarationKind kind, TokenPos pos);
1302
1303
  private:
1304
    inline bool asmJS(ListNodeType list);
1305
};
1306
1307
template <typename CharT>
1308
class MOZ_STACK_CLASS Parser<SyntaxParseHandler, CharT> final
1309
  : public GeneralParser<SyntaxParseHandler, CharT>
1310
{
1311
    using Base = GeneralParser<SyntaxParseHandler, CharT>;
1312
    using Node = SyntaxParseHandler::Node;
1313
1314
#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \
1315
    using longTypeName = SyntaxParseHandler::longTypeName;
1316
FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
1317
#undef DECLARE_TYPE
1318
1319
    using SyntaxParser = Parser<SyntaxParseHandler, CharT>;
1320
1321
    // Numerous Base::* functions have bodies like
1322
    //
1323
    //   return asFinalParser()->func(...);
1324
    //
1325
    // and must be able to call functions here.  Add a friendship relationship
1326
    // so functions here can be hidden when appropriate.
1327
    friend class GeneralParser<SyntaxParseHandler, CharT>;
1328
1329
  public:
1330
    using Base::Base;
1331
1332
    // Inherited types, listed here to have non-dependent names.
1333
    using typename Base::Modifier;
1334
    using typename Base::Position;
1335
    using typename Base::TokenStream;
1336
1337
    // Inherited functions, listed here to have non-dependent names.
1338
1339
  public:
1340
    using Base::anyChars;
1341
    using Base::clearAbortedSyntaxParse;
1342
    using Base::context;
1343
    using Base::hadAbortedSyntaxParse;
1344
    using Base::innerFunctionForFunctionBox;
1345
    using Base::tokenStream;
1346
1347
  private:
1348
    using Base::alloc;
1349
#if DEBUG
1350
    using Base::checkOptionsCalled;
1351
#endif
1352
    using Base::error;
1353
    using Base::errorAt;
1354
    using Base::finishFunctionScopes;
1355
    using Base::functionFormalParametersAndBody;
1356
    using Base::handler;
1357
    using Base::innerFunction;
1358
    using Base::keepAtoms;
1359
    using Base::matchOrInsertSemicolon;
1360
    using Base::newFunctionBox;
1361
    using Base::newLexicalScopeData;
1362
    using Base::newModuleScopeData;
1363
    using Base::newName;
1364
    using Base::noteDeclaredName;
1365
    using Base::null;
1366
    using Base::options;
1367
    using Base::pc;
1368
    using Base::pos;
1369
    using Base::propagateFreeNamesAndMarkClosedOverBindings;
1370
    using Base::ss;
1371
    using Base::statementList;
1372
    using Base::stringLiteral;
1373
    using Base::usedNames;
1374
1375
  private:
1376
    using Base::abortIfSyntaxParser;
1377
    using Base::disableSyntaxParser;
1378
1379
  public:
1380
    // Functions with multiple overloads of different visibility.  We can't
1381
    // |using| the whole thing into existence because of the visibility
1382
    // distinction, so we instead must manually delegate the required overload.
1383
1384
0
    PropertyName* bindingIdentifier(YieldHandling yieldHandling) {
1385
0
        return Base::bindingIdentifier(yieldHandling);
1386
0
    }
Unexecuted instantiation: js::frontend::Parser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>::bindingIdentifier(js::frontend::YieldHandling)
Unexecuted instantiation: js::frontend::Parser<js::frontend::SyntaxParseHandler, char16_t>::bindingIdentifier(js::frontend::YieldHandling)
1387
1388
    // Functions present in both Parser<ParseHandler, CharT> specializations.
1389
1390
    inline void setAwaitHandling(AwaitHandling awaitHandling);
1391
    inline void setInParametersOfAsyncFunction(bool inParameters);
1392
1393
    RegExpLiteralType newRegExp();
1394
1395
    // Parse a module.
1396
    CodeNodeType moduleBody(ModuleSharedContext* modulesc);
1397
1398
    inline BinaryNodeType importDeclaration();
1399
    inline bool checkLocalExportNames(ListNodeType node);
1400
    inline bool checkExportedName(JSAtom* exportName);
1401
    inline bool checkExportedNamesForArrayBinding(ListNodeType array);
1402
    inline bool checkExportedNamesForObjectBinding(ListNodeType obj);
1403
    inline bool checkExportedNamesForDeclaration(Node node);
1404
    inline bool checkExportedNamesForDeclarationList(ListNodeType node);
1405
    inline bool checkExportedNameForFunction(CodeNodeType funNode);
1406
    inline bool checkExportedNameForClass(ClassNodeType classNode);
1407
    inline bool checkExportedNameForClause(NameNodeType nameNode);
1408
1409
    bool trySyntaxParseInnerFunction(CodeNodeType* funNode, HandleFunction fun,
1410
                                     uint32_t toStringStart,
1411
                                     InHandling inHandling, YieldHandling yieldHandling,
1412
                                     FunctionSyntaxKind kind, GeneratorKind generatorKind,
1413
                                     FunctionAsyncKind asyncKind, bool tryAnnexB,
1414
                                     Directives inheritedDirectives, Directives* newDirectives);
1415
1416
    bool skipLazyInnerFunction(CodeNodeType funNode, uint32_t toStringStart,
1417
                               FunctionSyntaxKind kind, bool tryAnnexB);
1418
1419
    bool asmJS(ListNodeType list);
1420
1421
    // Functions present only in Parser<SyntaxParseHandler, CharT>.
1422
};
1423
1424
template <typename CharT>
1425
class MOZ_STACK_CLASS Parser<FullParseHandler, CharT> final
1426
  : public GeneralParser<FullParseHandler, CharT>
1427
{
1428
    using Base = GeneralParser<FullParseHandler, CharT>;
1429
    using Node = FullParseHandler::Node;
1430
1431
#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \
1432
    using longTypeName = FullParseHandler::longTypeName;
1433
FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
1434
#undef DECLARE_TYPE
1435
1436
    using SyntaxParser = Parser<SyntaxParseHandler, CharT>;
1437
1438
    // Numerous Base::* functions have bodies like
1439
    //
1440
    //   return asFinalParser()->func(...);
1441
    //
1442
    // and must be able to call functions here.  Add a friendship relationship
1443
    // so functions here can be hidden when appropriate.
1444
    friend class GeneralParser<FullParseHandler, CharT>;
1445
1446
  public:
1447
    using Base::Base;
1448
1449
    // Inherited types, listed here to have non-dependent names.
1450
    using typename Base::Modifier;
1451
    using typename Base::Position;
1452
    using typename Base::TokenStream;
1453
1454
    // Inherited functions, listed here to have non-dependent names.
1455
1456
  public:
1457
    using Base::anyChars;
1458
    using Base::clearAbortedSyntaxParse;
1459
    using Base::functionFormalParametersAndBody;
1460
    using Base::hadAbortedSyntaxParse;
1461
    using Base::handler;
1462
    using Base::newFunctionBox;
1463
    using Base::options;
1464
    using Base::pc;
1465
    using Base::pos;
1466
    using Base::ss;
1467
    using Base::tokenStream;
1468
1469
  private:
1470
    using Base::alloc;
1471
    using Base::checkLabelOrIdentifierReference;
1472
#if DEBUG
1473
    using Base::checkOptionsCalled;
1474
#endif
1475
    using Base::context;
1476
    using Base::error;
1477
    using Base::errorAt;
1478
    using Base::finishFunctionScopes;
1479
    using Base::finishLexicalScope;
1480
    using Base::innerFunction;
1481
    using Base::innerFunctionForFunctionBox;
1482
    using Base::keepAtoms;
1483
    using Base::matchOrInsertSemicolon;
1484
    using Base::newEvalScopeData;
1485
    using Base::newFunctionScopeData;
1486
    using Base::newGlobalScopeData;
1487
    using Base::newLexicalScopeData;
1488
    using Base::newModuleScopeData;
1489
    using Base::newName;
1490
    using Base::newVarScopeData;
1491
    using Base::noteDeclaredName;
1492
    using Base::null;
1493
    using Base::propagateFreeNamesAndMarkClosedOverBindings;
1494
    using Base::statementList;
1495
    using Base::stringLiteral;
1496
    using Base::usedNames;
1497
1498
    using Base::abortIfSyntaxParser;
1499
    using Base::disableSyntaxParser;
1500
    using Base::getSyntaxParser;
1501
1502
  public:
1503
    // Functions with multiple overloads of different visibility.  We can't
1504
    // |using| the whole thing into existence because of the visibility
1505
    // distinction, so we instead must manually delegate the required overload.
1506
1507
0
    PropertyName* bindingIdentifier(YieldHandling yieldHandling) {
1508
0
        return Base::bindingIdentifier(yieldHandling);
1509
0
    }
Unexecuted instantiation: js::frontend::Parser<js::frontend::FullParseHandler, char16_t>::bindingIdentifier(js::frontend::YieldHandling)
Unexecuted instantiation: js::frontend::Parser<js::frontend::FullParseHandler, mozilla::Utf8Unit>::bindingIdentifier(js::frontend::YieldHandling)
1510
1511
    // Functions present in both Parser<ParseHandler, CharT> specializations.
1512
1513
    friend class AutoAwaitIsKeyword<SyntaxParseHandler, CharT>;
1514
    inline void setAwaitHandling(AwaitHandling awaitHandling);
1515
1516
    friend class AutoInParametersOfAsyncFunction<SyntaxParseHandler, CharT>;
1517
    inline void setInParametersOfAsyncFunction(bool inParameters);
1518
1519
    RegExpLiteralType newRegExp();
1520
1521
    // Parse a module.
1522
    CodeNodeType moduleBody(ModuleSharedContext* modulesc);
1523
1524
    BinaryNodeType importDeclaration();
1525
    bool checkLocalExportNames(ListNodeType node);
1526
    bool checkExportedName(JSAtom* exportName);
1527
    bool checkExportedNamesForArrayBinding(ListNodeType array);
1528
    bool checkExportedNamesForObjectBinding(ListNodeType obj);
1529
    bool checkExportedNamesForDeclaration(Node node);
1530
    bool checkExportedNamesForDeclarationList(ListNodeType node);
1531
    bool checkExportedNameForFunction(CodeNodeType funNode);
1532
    bool checkExportedNameForClass(ClassNodeType classNode);
1533
    inline bool checkExportedNameForClause(NameNodeType nameNode);
1534
1535
    bool trySyntaxParseInnerFunction(CodeNodeType* funNode, HandleFunction fun,
1536
                                     uint32_t toStringStart,
1537
                                     InHandling inHandling, YieldHandling yieldHandling,
1538
                                     FunctionSyntaxKind kind, GeneratorKind generatorKind,
1539
                                     FunctionAsyncKind asyncKind, bool tryAnnexB,
1540
                                     Directives inheritedDirectives, Directives* newDirectives);
1541
1542
    bool skipLazyInnerFunction(CodeNodeType funNode, uint32_t toStringStart,
1543
                               FunctionSyntaxKind kind, bool tryAnnexB);
1544
1545
    // Functions present only in Parser<FullParseHandler, CharT>.
1546
1547
    // Parse the body of an eval.
1548
    //
1549
    // Eval scripts are distinguished from global scripts in that in ES6, per
1550
    // 18.2.1.1 steps 9 and 10, all eval scripts are executed under a fresh
1551
    // lexical scope.
1552
    LexicalScopeNodeType evalBody(EvalSharedContext* evalsc);
1553
1554
    // Parse a function, given only its arguments and body. Used for lazily
1555
    // parsed functions.
1556
    CodeNodeType standaloneLazyFunction(HandleFunction fun, uint32_t toStringStart, bool strict,
1557
                                        GeneratorKind generatorKind, FunctionAsyncKind asyncKind);
1558
1559
    // Parse a function, used for the Function, GeneratorFunction, and
1560
    // AsyncFunction constructors.
1561
    CodeNodeType standaloneFunction(HandleFunction fun, HandleScope enclosingScope,
1562
                                    const mozilla::Maybe<uint32_t>& parameterListEnd,
1563
                                    GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
1564
                                    Directives inheritedDirectives, Directives* newDirectives);
1565
1566
    bool checkStatementsEOF();
1567
1568
    // Parse the body of a global script.
1569
    ListNodeType globalBody(GlobalSharedContext* globalsc);
1570
1571
    bool namedImportsOrNamespaceImport(TokenKind tt, ListNodeType importSpecSet);
1572
1573
0
    PropertyName* importedBinding() {
1574
0
        return bindingIdentifier(YieldIsName);
1575
0
    }
Unexecuted instantiation: js::frontend::Parser<js::frontend::FullParseHandler, mozilla::Utf8Unit>::importedBinding()
Unexecuted instantiation: js::frontend::Parser<js::frontend::FullParseHandler, char16_t>::importedBinding()
1576
1577
0
    bool checkLocalExportName(PropertyName* ident, uint32_t offset) {
1578
0
        return checkLabelOrIdentifierReference(ident, offset, YieldIsName);
1579
0
    }
Unexecuted instantiation: js::frontend::Parser<js::frontend::FullParseHandler, mozilla::Utf8Unit>::checkLocalExportName(js::PropertyName*, unsigned int)
Unexecuted instantiation: js::frontend::Parser<js::frontend::FullParseHandler, char16_t>::checkLocalExportName(js::PropertyName*, unsigned int)
1580
1581
    bool asmJS(ListNodeType list);
1582
};
1583
1584
template<class Parser>
1585
/* static */ inline const TokenStreamAnyChars&
1586
ParserAnyCharsAccess<Parser>::anyChars(const GeneralTokenStreamChars* ts)
1587
1.06M
{
1588
1.06M
    // The structure we're walking through looks like this:
1589
1.06M
    //
1590
1.06M
    //   struct ParserBase
1591
1.06M
    //   {
1592
1.06M
    //       ...;
1593
1.06M
    //       TokenStreamAnyChars anyChars;
1594
1.06M
    //       ...;
1595
1.06M
    //   };
1596
1.06M
    //   struct Parser : <class that ultimately inherits from ParserBase>
1597
1.06M
    //   {
1598
1.06M
    //       ...;
1599
1.06M
    //       TokenStreamSpecific tokenStream;
1600
1.06M
    //       ...;
1601
1.06M
    //   };
1602
1.06M
    //
1603
1.06M
    // We're passed a GeneralTokenStreamChars* (this being a base class of
1604
1.06M
    // Parser::tokenStream).  We cast that pointer to a TokenStreamSpecific*,
1605
1.06M
    // then translate that to the enclosing Parser*, then return the |anyChars|
1606
1.06M
    // member within.
1607
1.06M
1608
1.06M
    static_assert(mozilla::IsBaseOf<GeneralTokenStreamChars,
1609
1.06M
                                    TokenStreamSpecific>::value,
1610
1.06M
                  "the static_cast<> below assumes a base-class relationship");
1611
1.06M
    const auto* tss = static_cast<const TokenStreamSpecific*>(ts);
1612
1.06M
1613
1.06M
    auto tssAddr = reinterpret_cast<uintptr_t>(tss);
1614
1.06M
1615
1.06M
    using ActualTokenStreamType = decltype(static_cast<Parser*>(nullptr)->tokenStream);
1616
1.06M
    static_assert(mozilla::IsSame<ActualTokenStreamType, TokenStreamSpecific>::value,
1617
1.06M
                                  "Parser::tokenStream must have type TokenStreamSpecific");
1618
1.06M
1619
1.06M
    uintptr_t parserAddr = tssAddr - offsetof(Parser, tokenStream);
1620
1.06M
1621
1.06M
    return reinterpret_cast<const Parser*>(parserAddr)->anyChars;
1622
1.06M
}
js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::FullParseHandler, char16_t> >::anyChars(js::frontend::GeneralTokenStreamChars<char16_t, js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::FullParseHandler, char16_t> > > const*)
Line
Count
Source
1587
1.06M
{
1588
1.06M
    // The structure we're walking through looks like this:
1589
1.06M
    //
1590
1.06M
    //   struct ParserBase
1591
1.06M
    //   {
1592
1.06M
    //       ...;
1593
1.06M
    //       TokenStreamAnyChars anyChars;
1594
1.06M
    //       ...;
1595
1.06M
    //   };
1596
1.06M
    //   struct Parser : <class that ultimately inherits from ParserBase>
1597
1.06M
    //   {
1598
1.06M
    //       ...;
1599
1.06M
    //       TokenStreamSpecific tokenStream;
1600
1.06M
    //       ...;
1601
1.06M
    //   };
1602
1.06M
    //
1603
1.06M
    // We're passed a GeneralTokenStreamChars* (this being a base class of
1604
1.06M
    // Parser::tokenStream).  We cast that pointer to a TokenStreamSpecific*,
1605
1.06M
    // then translate that to the enclosing Parser*, then return the |anyChars|
1606
1.06M
    // member within.
1607
1.06M
1608
1.06M
    static_assert(mozilla::IsBaseOf<GeneralTokenStreamChars,
1609
1.06M
                                    TokenStreamSpecific>::value,
1610
1.06M
                  "the static_cast<> below assumes a base-class relationship");
1611
1.06M
    const auto* tss = static_cast<const TokenStreamSpecific*>(ts);
1612
1.06M
1613
1.06M
    auto tssAddr = reinterpret_cast<uintptr_t>(tss);
1614
1.06M
1615
1.06M
    using ActualTokenStreamType = decltype(static_cast<Parser*>(nullptr)->tokenStream);
1616
1.06M
    static_assert(mozilla::IsSame<ActualTokenStreamType, TokenStreamSpecific>::value,
1617
1.06M
                                  "Parser::tokenStream must have type TokenStreamSpecific");
1618
1.06M
1619
1.06M
    uintptr_t parserAddr = tssAddr - offsetof(Parser, tokenStream);
1620
1.06M
1621
1.06M
    return reinterpret_cast<const Parser*>(parserAddr)->anyChars;
1622
1.06M
}
Unexecuted instantiation: js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, char16_t> >::anyChars(js::frontend::GeneralTokenStreamChars<char16_t, js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, char16_t> > > const*)
Unexecuted instantiation: js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::FullParseHandler, mozilla::Utf8Unit> >::anyChars(js::frontend::GeneralTokenStreamChars<mozilla::Utf8Unit, js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::FullParseHandler, mozilla::Utf8Unit> > > const*)
Unexecuted instantiation: js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit> >::anyChars(js::frontend::GeneralTokenStreamChars<mozilla::Utf8Unit, js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit> > > const*)
1623
1624
template<class Parser>
1625
/* static */ inline TokenStreamAnyChars&
1626
ParserAnyCharsAccess<Parser>::anyChars(GeneralTokenStreamChars* ts)
1627
890k
{
1628
890k
    const TokenStreamAnyChars& anyCharsConst =
1629
890k
        anyChars(const_cast<const GeneralTokenStreamChars*>(ts));
1630
890k
1631
890k
    return const_cast<TokenStreamAnyChars&>(anyCharsConst);
1632
890k
}
js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::FullParseHandler, char16_t> >::anyChars(js::frontend::GeneralTokenStreamChars<char16_t, js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::FullParseHandler, char16_t> > >*)
Line
Count
Source
1627
890k
{
1628
890k
    const TokenStreamAnyChars& anyCharsConst =
1629
890k
        anyChars(const_cast<const GeneralTokenStreamChars*>(ts));
1630
890k
1631
890k
    return const_cast<TokenStreamAnyChars&>(anyCharsConst);
1632
890k
}
Unexecuted instantiation: js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, char16_t> >::anyChars(js::frontend::GeneralTokenStreamChars<char16_t, js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, char16_t> > >*)
Unexecuted instantiation: js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::FullParseHandler, mozilla::Utf8Unit> >::anyChars(js::frontend::GeneralTokenStreamChars<mozilla::Utf8Unit, js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::FullParseHandler, mozilla::Utf8Unit> > >*)
Unexecuted instantiation: js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit> >::anyChars(js::frontend::GeneralTokenStreamChars<mozilla::Utf8Unit, js::frontend::ParserAnyCharsAccess<js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit> > >*)
1633
1634
template <class ParseHandler, typename CharT>
1635
class MOZ_STACK_CLASS AutoAwaitIsKeyword
1636
{
1637
    using GeneralParser = frontend::GeneralParser<ParseHandler, CharT>;
1638
1639
  private:
1640
    GeneralParser* parser_;
1641
    AwaitHandling oldAwaitHandling_;
1642
1643
  public:
1644
3.08k
    AutoAwaitIsKeyword(GeneralParser* parser, AwaitHandling awaitHandling) {
1645
3.08k
        parser_ = parser;
1646
3.08k
        oldAwaitHandling_ = static_cast<AwaitHandling>(parser_->awaitHandling_);
1647
3.08k
1648
3.08k
        // 'await' is always a keyword in module contexts, so we don't modify
1649
3.08k
        // the state when the original handling is AwaitIsModuleKeyword.
1650
3.08k
        if (oldAwaitHandling_ != AwaitIsModuleKeyword) {
1651
3.08k
            parser_->setAwaitHandling(awaitHandling);
1652
3.08k
        }
1653
3.08k
    }
Unexecuted instantiation: js::frontend::AutoAwaitIsKeyword<js::frontend::FullParseHandler, mozilla::Utf8Unit>::AutoAwaitIsKeyword(js::frontend::GeneralParser<js::frontend::FullParseHandler, mozilla::Utf8Unit>*, js::frontend::AwaitHandling)
Unexecuted instantiation: js::frontend::AutoAwaitIsKeyword<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>::AutoAwaitIsKeyword(js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>*, js::frontend::AwaitHandling)
js::frontend::AutoAwaitIsKeyword<js::frontend::FullParseHandler, char16_t>::AutoAwaitIsKeyword(js::frontend::GeneralParser<js::frontend::FullParseHandler, char16_t>*, js::frontend::AwaitHandling)
Line
Count
Source
1644
3.08k
    AutoAwaitIsKeyword(GeneralParser* parser, AwaitHandling awaitHandling) {
1645
3.08k
        parser_ = parser;
1646
3.08k
        oldAwaitHandling_ = static_cast<AwaitHandling>(parser_->awaitHandling_);
1647
3.08k
1648
3.08k
        // 'await' is always a keyword in module contexts, so we don't modify
1649
3.08k
        // the state when the original handling is AwaitIsModuleKeyword.
1650
3.08k
        if (oldAwaitHandling_ != AwaitIsModuleKeyword) {
1651
3.08k
            parser_->setAwaitHandling(awaitHandling);
1652
3.08k
        }
1653
3.08k
    }
Unexecuted instantiation: js::frontend::AutoAwaitIsKeyword<js::frontend::SyntaxParseHandler, char16_t>::AutoAwaitIsKeyword(js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, char16_t>*, js::frontend::AwaitHandling)
1654
1655
3.08k
    ~AutoAwaitIsKeyword() {
1656
3.08k
        parser_->setAwaitHandling(oldAwaitHandling_);
1657
3.08k
    }
Unexecuted instantiation: js::frontend::AutoAwaitIsKeyword<js::frontend::FullParseHandler, mozilla::Utf8Unit>::~AutoAwaitIsKeyword()
Unexecuted instantiation: js::frontend::AutoAwaitIsKeyword<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>::~AutoAwaitIsKeyword()
js::frontend::AutoAwaitIsKeyword<js::frontend::FullParseHandler, char16_t>::~AutoAwaitIsKeyword()
Line
Count
Source
1655
3.08k
    ~AutoAwaitIsKeyword() {
1656
3.08k
        parser_->setAwaitHandling(oldAwaitHandling_);
1657
3.08k
    }
Unexecuted instantiation: js::frontend::AutoAwaitIsKeyword<js::frontend::SyntaxParseHandler, char16_t>::~AutoAwaitIsKeyword()
1658
};
1659
1660
template <class ParseHandler, typename CharT>
1661
class MOZ_STACK_CLASS AutoInParametersOfAsyncFunction
1662
{
1663
    using GeneralParser = frontend::GeneralParser<ParseHandler, CharT>;
1664
1665
  private:
1666
    GeneralParser* parser_;
1667
    bool oldInParametersOfAsyncFunction_;
1668
1669
  public:
1670
2.96k
    AutoInParametersOfAsyncFunction(GeneralParser* parser, bool inParameters) {
1671
2.96k
        parser_ = parser;
1672
2.96k
        oldInParametersOfAsyncFunction_ = parser_->inParametersOfAsyncFunction_;
1673
2.96k
        parser_->setInParametersOfAsyncFunction(inParameters);
1674
2.96k
    }
Unexecuted instantiation: js::frontend::AutoInParametersOfAsyncFunction<js::frontend::FullParseHandler, mozilla::Utf8Unit>::AutoInParametersOfAsyncFunction(js::frontend::GeneralParser<js::frontend::FullParseHandler, mozilla::Utf8Unit>*, bool)
Unexecuted instantiation: js::frontend::AutoInParametersOfAsyncFunction<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>::AutoInParametersOfAsyncFunction(js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>*, bool)
js::frontend::AutoInParametersOfAsyncFunction<js::frontend::FullParseHandler, char16_t>::AutoInParametersOfAsyncFunction(js::frontend::GeneralParser<js::frontend::FullParseHandler, char16_t>*, bool)
Line
Count
Source
1670
2.96k
    AutoInParametersOfAsyncFunction(GeneralParser* parser, bool inParameters) {
1671
2.96k
        parser_ = parser;
1672
2.96k
        oldInParametersOfAsyncFunction_ = parser_->inParametersOfAsyncFunction_;
1673
2.96k
        parser_->setInParametersOfAsyncFunction(inParameters);
1674
2.96k
    }
Unexecuted instantiation: js::frontend::AutoInParametersOfAsyncFunction<js::frontend::SyntaxParseHandler, char16_t>::AutoInParametersOfAsyncFunction(js::frontend::GeneralParser<js::frontend::SyntaxParseHandler, char16_t>*, bool)
1675
1676
2.96k
    ~AutoInParametersOfAsyncFunction() {
1677
2.96k
        parser_->setInParametersOfAsyncFunction(oldInParametersOfAsyncFunction_);
1678
2.96k
    }
Unexecuted instantiation: js::frontend::AutoInParametersOfAsyncFunction<js::frontend::FullParseHandler, mozilla::Utf8Unit>::~AutoInParametersOfAsyncFunction()
Unexecuted instantiation: js::frontend::AutoInParametersOfAsyncFunction<js::frontend::SyntaxParseHandler, mozilla::Utf8Unit>::~AutoInParametersOfAsyncFunction()
js::frontend::AutoInParametersOfAsyncFunction<js::frontend::FullParseHandler, char16_t>::~AutoInParametersOfAsyncFunction()
Line
Count
Source
1676
2.96k
    ~AutoInParametersOfAsyncFunction() {
1677
2.96k
        parser_->setInParametersOfAsyncFunction(oldInParametersOfAsyncFunction_);
1678
2.96k
    }
Unexecuted instantiation: js::frontend::AutoInParametersOfAsyncFunction<js::frontend::SyntaxParseHandler, char16_t>::~AutoInParametersOfAsyncFunction()
1679
};
1680
1681
template <typename Scope>
1682
extern typename Scope::Data*
1683
NewEmptyBindingData(JSContext* cx, LifoAlloc& alloc, uint32_t numBindings);
1684
1685
mozilla::Maybe<GlobalScope::Data*>
1686
NewGlobalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc);
1687
mozilla::Maybe<EvalScope::Data*>
1688
NewEvalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc);
1689
mozilla::Maybe<FunctionScope::Data*>
1690
NewFunctionScopeData(JSContext* context, ParseContext::Scope& scope, bool hasParameterExprs, LifoAlloc& alloc, ParseContext* pc);
1691
mozilla::Maybe<VarScope::Data*>
1692
NewVarScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc);
1693
mozilla::Maybe<LexicalScope::Data*>
1694
NewLexicalScopeData(JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc, ParseContext* pc);
1695
1696
JSFunction*
1697
AllocNewFunction(JSContext* cx, HandleAtom atom, FunctionSyntaxKind kind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
1698
                 HandleObject proto, bool isSelfHosting = false, bool inFunctionBox = false);
1699
1700
} /* namespace frontend */
1701
} /* namespace js */
1702
1703
#endif /* frontend_Parser_h */