Source code

Revision control

Other Tools

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