#ifndef frontend_Parser_h
#define frontend_Parser_h
#include "mozilla/Array.h"
#include "mozilla/Maybe.h"
#include "mozilla/TypeTraits.h"
#include "jspubtd.h"
#include "ds/Nestable.h"
#include "frontend/BytecodeCompiler.h"
#include "frontend/ErrorReporter.h"
#include "frontend/FullParseHandler.h"
#include "frontend/NameAnalysisTypes.h"
#include "frontend/NameCollections.h"
#include "frontend/ParseContext.h"
#include "frontend/SharedContext.h"
#include "frontend/SyntaxParseHandler.h"
#include "frontend/TokenStream.h"
#include "vm/ErrorReporting.h"
namespace js {
class ModuleObject;
namespace frontend {
template <class ParseHandler, typename Unit>
class GeneralParser;
class SourceParseContext : public ParseContext {
public:
template <typename ParseHandler, typename Unit>
SourceParseContext(GeneralParser<ParseHandler, Unit>* prs, SharedContext* sc,
Directives* newDirectives)
: ParseContext(prs->cx_, prs->pc_, sc, prs->tokenStream, prs->usedNames_,
newDirectives,
mozilla::IsSame<ParseHandler, FullParseHandler>::value) {}
};
enum VarContext { HoistVars, DontHoistVars };
enum PropListType { ObjectLiteral, ClassBody, DerivedClassBody };
enum class PropertyType {
Normal,
Shorthand,
CoverInitializedName,
Getter,
Setter,
Method,
GeneratorMethod,
AsyncMethod,
AsyncGeneratorMethod,
Constructor,
DerivedConstructor,
Field,
};
enum AwaitHandling : uint8_t {
AwaitIsName,
AwaitIsKeyword,
AwaitIsModuleKeyword
};
template <class ParseHandler, typename Unit>
class AutoAwaitIsKeyword;
template <class ParseHandler, typename Unit>
class AutoInParametersOfAsyncFunction;
class MOZ_STACK_CLASS ParserSharedBase : private JS::AutoGCRooter {
public:
enum class Kind { Parser, BinASTParser };
ParserSharedBase(JSContext* cx, LifoAlloc& alloc, UsedNameTracker& usedNames,
ScriptSourceObject* sourceObject, Kind kind);
~ParserSharedBase();
public:
JSContext* const cx_;
LifoAlloc& alloc_;
LifoAlloc::Mark tempPoolMark_;
TraceListNode* traceListHead_;
ParseContext* pc_;
UsedNameTracker& usedNames_;
RootedScriptSourceObject sourceObject_;
AutoKeepAtoms keepAtoms_;
private:
friend void js::frontend::TraceParser(JSTracer* trc,
JS::AutoGCRooter* parser);
#if defined(JS_BUILD_BINAST)
friend void js::frontend::TraceBinASTParser(JSTracer* trc,
JS::AutoGCRooter* parser);
#endif
private:
template <typename BoxT, typename ArgT>
BoxT* newTraceListNode(ArgT* arg);
public:
ObjectBox* newObjectBox(JSObject* obj);
BigIntBox* newBigIntBox(BigInt* val);
};
class MOZ_STACK_CLASS ParserBase : public ParserSharedBase,
public ErrorReportMixin {
using Base = ErrorReportMixin;
private:
ParserBase* thisForCtor() { return this; }
public:
TokenStreamAnyChars anyChars;
ScriptSource* ss;
const bool foldConstants_ : 1;
protected:
#if DEBUG
bool checkOptionsCalled_ : 1;
#endif
bool isUnexpectedEOF_ : 1;
uint8_t awaitHandling_ : 2;
bool inParametersOfAsyncFunction_ : 1;
uint8_t parseGoal_ : 1;
public:
bool awaitIsKeyword() const { return awaitHandling_ != AwaitIsName; }
bool inParametersOfAsyncFunction() const {
return inParametersOfAsyncFunction_;
}
ParseGoal parseGoal() const { return ParseGoal(parseGoal_); }
template <class, typename>
friend class AutoAwaitIsKeyword;
template <class, typename>
friend class AutoInParametersOfAsyncFunction;
ParserBase(JSContext* cx, LifoAlloc& alloc,
const JS::ReadOnlyCompileOptions& options, bool foldConstants,
UsedNameTracker& usedNames, ScriptSourceObject* sourceObject,
ParseGoal parseGoal);
~ParserBase();
bool checkOptions();
void trace(JSTracer* trc);
const char* getFilename() const { return anyChars.getFilename(); }
TokenPos pos() const { return anyChars.currentToken().pos; }
bool yieldExpressionsSupported() const { return pc_->isGenerator(); }
bool setLocalStrictMode(bool strict) {
MOZ_ASSERT(anyChars.debugHasNoLookahead());
return pc_->sc()->setLocalStrictMode(strict);
}
public:
JSContext* getContext() const override { return cx_; }
bool strictMode() const override { return pc_->sc()->strict(); }
const JS::ReadOnlyCompileOptions& options() const override {
return anyChars.options();
}
using Base::error;
using Base::errorAt;
using Base::errorNoOffset;
using Base::errorWithNotes;
using Base::errorWithNotesAt;
using Base::errorWithNotesNoOffset;
using Base::extraWarning;
using Base::extraWarningAt;
using Base::extraWarningNoOffset;
using Base::extraWarningWithNotes;
using Base::extraWarningWithNotesAt;
using Base::extraWarningWithNotesNoOffset;
using Base::strictModeError;
using Base::strictModeErrorAt;
using Base::strictModeErrorNoOffset;
using Base::strictModeErrorWithNotes;
using Base::strictModeErrorWithNotesAt;
using Base::strictModeErrorWithNotesNoOffset;
using Base::warning;
using Base::warningAt;
using Base::warningNoOffset;
using Base::warningWithNotes;
using Base::warningWithNotesAt;
using Base::warningWithNotesNoOffset;
public:
bool isUnexpectedEOF() const { return isUnexpectedEOF_; }
bool isValidStrictBinding(PropertyName* name);
bool hasValidSimpleStrictParameterNames();
JSFunction* newFunction(HandleAtom atom, FunctionSyntaxKind kind,
GeneratorKind generatorKind,
FunctionAsyncKind asyncKind,
HandleObject proto = nullptr);
class Mark {
friend class ParserBase;
LifoAlloc::Mark mark;
TraceListNode* traceListHead;
};
Mark mark() const {
Mark m;
m.mark = alloc_.mark();
m.traceListHead = traceListHead_;
return m;
}
void release(Mark m) {
alloc_.release(m.mark);
traceListHead_ = m.traceListHead;
}
public:
mozilla::Maybe<GlobalScope::Data*> newGlobalScopeData(
ParseContext::Scope& scope);
mozilla::Maybe<ModuleScope::Data*> newModuleScopeData(
ParseContext::Scope& scope);
mozilla::Maybe<EvalScope::Data*> newEvalScopeData(ParseContext::Scope& scope);
mozilla::Maybe<FunctionScope::Data*> newFunctionScopeData(
ParseContext::Scope& scope, bool hasParameterExprs);
mozilla::Maybe<VarScope::Data*> newVarScopeData(ParseContext::Scope& scope);
mozilla::Maybe<LexicalScope::Data*> newLexicalScopeData(
ParseContext::Scope& scope);
protected:
enum InvokedPrediction { PredictUninvoked = false, PredictInvoked = true };
enum ForInitLocation { InForInit, NotInForInit };
bool nextTokenContinuesLetDeclaration(TokenKind next);
bool noteUsedNameInternal(HandlePropertyName name);
bool checkAndMarkSuperScope();
bool leaveInnerFunction(ParseContext* outerpc);
JSAtom* prefixAccessorName(PropertyType propType, HandleAtom propAtom);
MOZ_MUST_USE bool setSourceMapInfo();
};
enum FunctionCallBehavior {
PermitAssignmentToFunctionCalls,
ForbidAssignmentToFunctionCalls
};
template <class ParseHandler>
class MOZ_STACK_CLASS PerHandlerParser : public ParserBase {
using Base = ParserBase;
private:
using Node = typename ParseHandler::Node;
#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \
using longTypeName = typename ParseHandler::longTypeName;
FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
#undef DECLARE_TYPE
protected:
ParseHandler handler_;
void* internalSyntaxParser_;
private:
PerHandlerParser(JSContext* cx, LifoAlloc& alloc,
const JS::ReadOnlyCompileOptions& options,
bool foldConstants, UsedNameTracker& usedNames,
LazyScript* lazyOuterFunction,
ScriptSourceObject* sourceObject, ParseGoal parseGoal,
void* internalSyntaxParser);
protected:
template <typename Unit>
PerHandlerParser(JSContext* cx, LifoAlloc& alloc,
const JS::ReadOnlyCompileOptions& options,
bool foldConstants, UsedNameTracker& usedNames,
GeneralParser<SyntaxParseHandler, Unit>* syntaxParser,
LazyScript* lazyOuterFunction,
ScriptSourceObject* sourceObject, ParseGoal parseGoal)
: PerHandlerParser(
cx, alloc, options, foldConstants, usedNames, lazyOuterFunction,
sourceObject, parseGoal,
static_cast<void*>(options.extraWarningsOption ? nullptr
: syntaxParser)) {}
static typename ParseHandler::NullNode null() { return ParseHandler::null(); }
NameNodeType stringLiteral();
const char* nameIsArgumentsOrEval(Node node);
bool noteDestructuredPositionalFormalParameter(FunctionNodeType funNode,
Node destruct);
bool noteUsedName(HandlePropertyName name) {
if (handler_.canSkipLazyClosedOverBindings()) {
return true;
}
return ParserBase::noteUsedNameInternal(name);
}
bool propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope);
bool finishFunctionScopes(bool isStandaloneFunction);
LexicalScopeNodeType finishLexicalScope(ParseContext::Scope& scope,
Node body);
bool finishFunction(bool isStandaloneFunction = false);
inline NameNodeType newName(PropertyName* name);
inline NameNodeType newName(PropertyName* name, TokenPos pos);
NameNodeType newInternalDotName(HandlePropertyName name);
NameNodeType newThisName();
NameNodeType newDotGeneratorName();
NameNodeType identifierReference(Handle<PropertyName*> name);
Node noSubstitutionTaggedTemplate();
inline bool processExport(Node node);
inline bool processExportFrom(BinaryNodeType node);
inline void disableSyntaxParser();
inline bool abortIfSyntaxParser();
inline bool hadAbortedSyntaxParse();
inline void clearAbortedSyntaxParse();
public:
bool isValidSimpleAssignmentTarget(
Node node,
FunctionCallBehavior behavior = ForbidAssignmentToFunctionCalls);
NameNodeType newPropertyName(PropertyName* key, const TokenPos& pos) {
return handler_.newPropertyName(key, pos);
}
PropertyAccessType newPropertyAccess(Node expr, NameNodeType key) {
return handler_.newPropertyAccess(expr, key);
}
FunctionBox* newFunctionBox(FunctionNodeType funNode, JSFunction* fun,
uint32_t toStringStart, Directives directives,
GeneratorKind generatorKind,
FunctionAsyncKind asyncKind);
public:
using Base::error;
using Base::errorAt;
using Base::errorNoOffset;
using Base::errorWithNotes;
using Base::errorWithNotesAt;
using Base::errorWithNotesNoOffset;
using Base::extraWarning;
using Base::extraWarningAt;
using Base::extraWarningNoOffset;
using Base::extraWarningWithNotes;
using Base::extraWarningWithNotesAt;
using Base::extraWarningWithNotesNoOffset;
using Base::strictModeError;
using Base::strictModeErrorAt;
using Base::strictModeErrorNoOffset;
using Base::strictModeErrorWithNotes;
using Base::strictModeErrorWithNotesAt;
using Base::strictModeErrorWithNotesNoOffset;
using Base::warning;
using Base::warningAt;
using Base::warningNoOffset;
using Base::warningWithNotes;
using Base::warningWithNotesAt;
using Base::warningWithNotesNoOffset;
};
#define ABORTED_SYNTAX_PARSE_SENTINEL reinterpret_cast<void*>(0x1)
template <>
inline void PerHandlerParser<SyntaxParseHandler>::disableSyntaxParser() {}
template <>
inline bool PerHandlerParser<SyntaxParseHandler>::abortIfSyntaxParser() {
internalSyntaxParser_ = ABORTED_SYNTAX_PARSE_SENTINEL;
return false;
}
template <>
inline bool PerHandlerParser<SyntaxParseHandler>::hadAbortedSyntaxParse() {
return internalSyntaxParser_ == ABORTED_SYNTAX_PARSE_SENTINEL;
}
template <>
inline void PerHandlerParser<SyntaxParseHandler>::clearAbortedSyntaxParse() {
internalSyntaxParser_ = nullptr;
}
#undef ABORTED_SYNTAX_PARSE_SENTINEL
template <>
inline void PerHandlerParser<FullParseHandler>::disableSyntaxParser() {
internalSyntaxParser_ = nullptr;
}
template <>
inline bool PerHandlerParser<FullParseHandler>::abortIfSyntaxParser() {
disableSyntaxParser();
return true;
}
template <>
inline bool PerHandlerParser<FullParseHandler>::hadAbortedSyntaxParse() {
return false;
}
template <>
inline void PerHandlerParser<FullParseHandler>::clearAbortedSyntaxParse() {}
template <class Parser>
class ParserAnyCharsAccess {
public:
using TokenStreamSpecific = typename Parser::TokenStream;
using GeneralTokenStreamChars =
typename TokenStreamSpecific::GeneralCharsBase;
static inline TokenStreamAnyChars& anyChars(GeneralTokenStreamChars* ts);
static inline const TokenStreamAnyChars& anyChars(
const GeneralTokenStreamChars* ts);
};
enum YieldHandling { YieldIsName, YieldIsKeyword };
enum InHandling { InAllowed, InProhibited };
enum DefaultHandling { NameRequired, AllowDefaultName };
enum TripledotHandling { TripledotAllowed, TripledotProhibited };
template <class ParseHandler, typename Unit>
class Parser;
template <class ParseHandler, typename Unit>
class MOZ_STACK_CLASS GeneralParser : public PerHandlerParser<ParseHandler> {
public:
using TokenStream =
TokenStreamSpecific<Unit, ParserAnyCharsAccess<GeneralParser>>;
private:
using Base = PerHandlerParser<ParseHandler>;
using FinalParser = Parser<ParseHandler, Unit>;
using Node = typename ParseHandler::Node;
#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \
using longTypeName = typename ParseHandler::longTypeName;
FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
#undef DECLARE_TYPE
using typename Base::InvokedPrediction;
using SyntaxParser = Parser<SyntaxParseHandler, Unit>;
protected:
using Modifier = TokenStreamShared::Modifier;
using Position = typename TokenStream::Position;
using Base::PredictInvoked;
using Base::PredictUninvoked;
using Base::alloc_;
using Base::awaitIsKeyword;
using Base::inParametersOfAsyncFunction;
using Base::parseGoal;
#if DEBUG
using Base::checkOptionsCalled_;
#endif
using Base::finishFunctionScopes;
using Base::finishLexicalScope;
using Base::foldConstants_;
using Base::getFilename;
using Base::hasValidSimpleStrictParameterNames;
using Base::isUnexpectedEOF_;
using Base::keepAtoms_;
using Base::nameIsArgumentsOrEval;
using Base::newFunction;
using Base::newFunctionBox;
using Base::newName;
using Base::null;
using Base::options;
using Base::pos;
using Base::propagateFreeNamesAndMarkClosedOverBindings;
using Base::setLocalStrictMode;
using Base::stringLiteral;
using Base::traceListHead_;
using Base::yieldExpressionsSupported;
using Base::abortIfSyntaxParser;
using Base::clearAbortedSyntaxParse;
using Base::disableSyntaxParser;
using Base::hadAbortedSyntaxParse;
public:
MOZ_MUST_USE bool computeErrorMetadata(
ErrorMetadata* err, const ErrorReportMixin::ErrorOffset& offset) override;
using Base::error;
using Base::errorAt;
using Base::errorNoOffset;
using Base::errorWithNotes;
using Base::errorWithNotesAt;
using Base::errorWithNotesNoOffset;
using Base::extraWarning;
using Base::extraWarningAt;
using Base::extraWarningNoOffset;
using Base::extraWarningWithNotes;
using Base::extraWarningWithNotesAt;
using Base::extraWarningWithNotesNoOffset;
using Base::strictModeError;
using Base::strictModeErrorAt;
using Base::strictModeErrorNoOffset;
using Base::strictModeErrorWithNotes;
using Base::strictModeErrorWithNotesAt;
using Base::strictModeErrorWithNotesNoOffset;
using Base::warning;
using Base::warningAt;
using Base::warningNoOffset;
using Base::warningWithNotes;
using Base::warningWithNotesAt;
using Base::warningWithNotesNoOffset;
public:
using Base::anyChars;
using Base::cx_;
using Base::handler_;
using Base::isValidSimpleAssignmentTarget;
using Base::pc_;
using Base::usedNames_;
private:
using Base::checkAndMarkSuperScope;
using Base::finishFunction;
using Base::identifierReference;
using Base::leaveInnerFunction;
using Base::newDotGeneratorName;
using Base::newInternalDotName;
using Base::newThisName;
using Base::nextTokenContinuesLetDeclaration;
using Base::noSubstitutionTaggedTemplate;
using Base::noteDestructuredPositionalFormalParameter;
using Base::noteUsedName;
using Base::prefixAccessorName;
using Base::processExport;
using Base::processExportFrom;
private:
inline FinalParser* asFinalParser();
inline const FinalParser* asFinalParser() const;
class MOZ_STACK_CLASS PossibleError {
private:
enum class ErrorKind { Expression, Destructuring, DestructuringWarning };
enum class ErrorState { None, Pending };
struct Error {
ErrorState state_ = ErrorState::None;
uint32_t offset_;
unsigned errorNumber_;
};
GeneralParser<ParseHandler, Unit>& parser_;
Error exprError_;
Error destructuringError_;
Error destructuringWarning_;
Error& error(ErrorKind kind);
bool hasError(ErrorKind kind);
void setResolved(ErrorKind kind);
void setPending(ErrorKind kind, const TokenPos& pos, unsigned errorNumber);
MOZ_MUST_USE bool checkForError(ErrorKind kind);
MOZ_MUST_USE bool checkForWarning(ErrorKind kind);
void transferErrorTo(ErrorKind kind, PossibleError* other);
public:
explicit PossibleError(GeneralParser<ParseHandler, Unit>& parser);
bool hasPendingDestructuringError();
void setPendingDestructuringErrorAt(const TokenPos& pos,
unsigned errorNumber);
void setPendingDestructuringWarningAt(const TokenPos& pos,
unsigned errorNumber);
void setPendingExpressionErrorAt(const TokenPos& pos, unsigned errorNumber);
MOZ_MUST_USE bool checkForDestructuringErrorOrWarning();
MOZ_MUST_USE bool checkForExpressionError();
void transferErrorsTo(PossibleError* other);
};
protected:
SyntaxParser* getSyntaxParser() const {
return reinterpret_cast<SyntaxParser*>(Base::internalSyntaxParser_);
}
public:
TokenStream tokenStream;
public:
GeneralParser(JSContext* cx, LifoAlloc& alloc,
const JS::ReadOnlyCompileOptions& options, const Unit* units,
size_t length, bool foldConstants, UsedNameTracker& usedNames,
SyntaxParser* syntaxParser, LazyScript* lazyOuterFunction,
ScriptSourceObject* sourceObject, ParseGoal parseGoal);
inline void setAwaitHandling(AwaitHandling awaitHandling);
inline void setInParametersOfAsyncFunction(bool inParameters);
ListNodeType parse();
private:
template <typename ConditionT, typename ErrorReportT>
MOZ_MUST_USE bool mustMatchTokenInternal(ConditionT condition,
Modifier modifier,
ErrorReportT errorReport);
public:
MOZ_MUST_USE bool mustMatchToken(TokenKind expected, Modifier modifier,
JSErrNum errorNumber) {
return mustMatchTokenInternal(
[expected](TokenKind actual) { return actual == expected; }, modifier,
[this, errorNumber](TokenKind) { this->error(errorNumber); });
}
MOZ_MUST_USE bool mustMatchToken(TokenKind excpected, JSErrNum errorNumber) {
return mustMatchToken(excpected, TokenStream::None, errorNumber);
}
template <typename ConditionT>
MOZ_MUST_USE bool mustMatchToken(ConditionT condition, JSErrNum errorNumber) {
return mustMatchTokenInternal(
condition, TokenStream::None,
[this, errorNumber](TokenKind) { this->error(errorNumber); });
}
template <typename ErrorReportT>
MOZ_MUST_USE bool mustMatchToken(TokenKind expected, Modifier modifier,
ErrorReportT errorReport) {
return mustMatchTokenInternal(
[expected](TokenKind actual) { return actual == expected; }, modifier,
errorReport);
}
template <typename ErrorReportT>
MOZ_MUST_USE bool mustMatchToken(TokenKind expected,
ErrorReportT errorReport) {
return mustMatchToken(expected, TokenStream::None, errorReport);
}
private:
GeneralParser* thisForCtor() { return this; }
NameNodeType noSubstitutionUntaggedTemplate();
ListNodeType templateLiteral(YieldHandling yieldHandling);
bool taggedTemplate(YieldHandling yieldHandling, ListNodeType tagArgsList,
TokenKind tt);
bool appendToCallSiteObj(CallSiteNodeType callSiteObj);
bool addExprAndGetNextTemplStrToken(YieldHandling yieldHandling,
ListNodeType nodeList, TokenKind* ttp);
inline bool trySyntaxParseInnerFunction(
FunctionNodeType* funNode, HandleFunction fun, uint32_t toStringStart,
InHandling inHandling, YieldHandling yieldHandling,
FunctionSyntaxKind kind, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind, bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives);
inline bool skipLazyInnerFunction(FunctionNodeType funNode,
uint32_t toStringStart,
FunctionSyntaxKind kind, bool tryAnnexB);
public:
Node statementListItem(YieldHandling yieldHandling,
bool canHaveDirectives = false);
MOZ_MUST_USE FunctionNodeType innerFunctionForFunctionBox(
FunctionNodeType funNode, ParseContext* outerpc, FunctionBox* funbox,
InHandling inHandling, YieldHandling yieldHandling,
FunctionSyntaxKind kind, Directives* newDirectives);
bool functionFormalParametersAndBody(
InHandling inHandling, YieldHandling yieldHandling,
FunctionNodeType* funNode, FunctionSyntaxKind kind,
const mozilla::Maybe<uint32_t>& parameterListEnd = mozilla::Nothing(),
bool isStandaloneFunction = false);
private:
FunctionNodeType functionStmt(
uint32_t toStringStart, YieldHandling yieldHandling,
DefaultHandling defaultHandling,
FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
FunctionNodeType functionExpr(uint32_t toStringStart,
InvokedPrediction invoked,
FunctionAsyncKind asyncKind);
Node statement(YieldHandling yieldHandling);
bool maybeParseDirective(ListNodeType list, Node pn, bool* cont);
LexicalScopeNodeType blockStatement(
YieldHandling yieldHandling,
unsigned errorNumber = JSMSG_CURLY_IN_COMPOUND);
BinaryNodeType doWhileStatement(YieldHandling yieldHandling);
BinaryNodeType whileStatement(YieldHandling yieldHandling);
Node forStatement(YieldHandling yieldHandling);
bool forHeadStart(YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
Node* forInitialPart,
mozilla::Maybe<ParseContext::Scope>& forLetImpliedScope,
Node* forInOrOfExpression);
Node expressionAfterForInOrOf(ParseNodeKind forHeadKind,
YieldHandling yieldHandling);
SwitchStatementType switchStatement(YieldHandling yieldHandling);
ContinueStatementType continueStatement(YieldHandling yieldHandling);
BreakStatementType breakStatement(YieldHandling yieldHandling);
UnaryNodeType returnStatement(YieldHandling yieldHandling);
BinaryNodeType withStatement(YieldHandling yieldHandling);
UnaryNodeType throwStatement(YieldHandling yieldHandling);
TernaryNodeType tryStatement(YieldHandling yieldHandling);
LexicalScopeNodeType catchBlockStatement(
YieldHandling yieldHandling, ParseContext::Scope& catchParamScope);
DebuggerStatementType debuggerStatement();
Node variableStatement(YieldHandling yieldHandling);
LabeledStatementType labeledStatement(YieldHandling yieldHandling);
Node labeledItem(YieldHandling yieldHandling);
TernaryNodeType ifStatement(YieldHandling yieldHandling);
Node consequentOrAlternative(YieldHandling yieldHandling);
ListNodeType lexicalDeclaration(YieldHandling yieldHandling,
DeclarationKind kind);
inline BinaryNodeType importDeclaration();
Node importDeclarationOrImportExpr(YieldHandling yieldHandling);
BinaryNodeType exportFrom(uint32_t begin, Node specList);
BinaryNodeType exportBatch(uint32_t begin);
inline bool checkLocalExportNames(ListNodeType node);
Node exportClause(uint32_t begin);
UnaryNodeType exportFunctionDeclaration(
uint32_t begin, uint32_t toStringStart,
FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
UnaryNodeType exportVariableStatement(uint32_t begin);
UnaryNodeType exportClassDeclaration(uint32_t begin);
UnaryNodeType exportLexicalDeclaration(uint32_t begin, DeclarationKind kind);
BinaryNodeType exportDefaultFunctionDeclaration(
uint32_t begin, uint32_t toStringStart,
FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction);
BinaryNodeType exportDefaultClassDeclaration(uint32_t begin);
BinaryNodeType exportDefaultAssignExpr(uint32_t begin);
BinaryNodeType exportDefault(uint32_t begin);
Node exportDeclaration();
UnaryNodeType expressionStatement(
YieldHandling yieldHandling,
InvokedPrediction invoked = PredictUninvoked);
ListNodeType declarationList(YieldHandling yieldHandling, ParseNodeKind kind,
ParseNodeKind* forHeadKind = nullptr,
Node* forInOrOfExpression = nullptr);
Node declarationPattern(DeclarationKind declKind, TokenKind tt,
bool initialDeclaration, YieldHandling yieldHandling,
ParseNodeKind* forHeadKind,
Node* forInOrOfExpression);
Node declarationName(DeclarationKind declKind, TokenKind tt,
bool initialDeclaration, YieldHandling yieldHandling,
ParseNodeKind* forHeadKind, Node* forInOrOfExpression);
Node initializerInNameDeclaration(NameNodeType binding,
DeclarationKind declKind,
bool initialDeclaration,
YieldHandling yieldHandling,
ParseNodeKind* forHeadKind,
Node* forInOrOfExpression);
Node expr(InHandling inHandling, YieldHandling yieldHandling,
TripledotHandling tripledotHandling,
PossibleError* possibleError = nullptr,
InvokedPrediction invoked = PredictUninvoked);
Node assignExpr(InHandling inHandling, YieldHandling yieldHandling,
TripledotHandling tripledotHandling,
PossibleError* possibleError = nullptr,
InvokedPrediction invoked = PredictUninvoked);
Node assignExprWithoutYieldOrAwait(YieldHandling yieldHandling);
UnaryNodeType yieldExpression(InHandling inHandling);
Node condExpr(InHandling inHandling, YieldHandling yieldHandling,
TripledotHandling tripledotHandling,
PossibleError* possibleError,
InvokedPrediction invoked = PredictUninvoked);
Node orExpr(InHandling inHandling, YieldHandling yieldHandling,
TripledotHandling tripledotHandling, PossibleError* possibleError,
InvokedPrediction invoked = PredictUninvoked);
Node unaryExpr(YieldHandling yieldHandling,
TripledotHandling tripledotHandling,
PossibleError* possibleError = nullptr,
InvokedPrediction invoked = PredictUninvoked);
Node memberExpr(YieldHandling yieldHandling,
TripledotHandling tripledotHandling, TokenKind tt,
bool allowCallSyntax = true,
PossibleError* possibleError = nullptr,
InvokedPrediction invoked = PredictUninvoked);
Node primaryExpr(YieldHandling yieldHandling,
TripledotHandling tripledotHandling, TokenKind tt,
PossibleError* possibleError,
InvokedPrediction invoked = PredictUninvoked);
Node exprInParens(InHandling inHandling, YieldHandling yieldHandling,
TripledotHandling tripledotHandling,
PossibleError* possibleError = nullptr);
bool tryNewTarget(BinaryNodeType* newTarget);
BinaryNodeType importExpr(YieldHandling yieldHandling, bool allowCallSyntax);
FunctionNodeType methodDefinition(uint32_t toStringStart,
PropertyType propType, HandleAtom funName);
bool functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind,
FunctionNodeType funNode);
FunctionNodeType functionDefinition(
FunctionNodeType funNode, uint32_t toStringStart, InHandling inHandling,
YieldHandling yieldHandling, HandleAtom name, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
bool tryAnnexB = false);
enum FunctionBodyType { StatementListBody, ExpressionBody };
LexicalScopeNodeType functionBody(InHandling inHandling,
YieldHandling yieldHandling,
FunctionSyntaxKind kind,
FunctionBodyType type);
UnaryNodeType unaryOpExpr(YieldHandling yieldHandling, ParseNodeKind kind,
uint32_t begin);
Node condition(InHandling inHandling, YieldHandling yieldHandling);
ListNodeType argumentList(YieldHandling yieldHandling, bool* isSpread,
PossibleError* possibleError = nullptr);
Node destructuringDeclaration(DeclarationKind kind,
YieldHandling yieldHandling, TokenKind tt);
Node destructuringDeclarationWithoutYieldOrAwait(DeclarationKind kind,
YieldHandling yieldHandling,
TokenKind tt);
inline bool checkExportedName(JSAtom* exportName);
inline bool checkExportedNamesForArrayBinding(ListNodeType array);
inline bool checkExportedNamesForObjectBinding(ListNodeType obj);
inline bool checkExportedNamesForDeclaration(Node node);
inline bool checkExportedNamesForDeclarationList(ListNodeType node);
inline bool checkExportedNameForFunction(FunctionNodeType funNode);
inline bool checkExportedNameForClass(ClassNodeType classNode);
inline bool checkExportedNameForClause(NameNodeType nameNode);
enum ClassContext { ClassStatement, ClassExpression };
ClassNodeType classDefinition(YieldHandling yieldHandling,
ClassContext classContext,
DefaultHandling defaultHandling);
MOZ_MUST_USE bool classMember(YieldHandling yieldHandling,
DefaultHandling defaultHandling,
const ParseContext::ClassStatement& classStmt,
HandlePropertyName className,
uint32_t classStartOffset, bool hasHeritage,
size_t& numFieldsWithInitializers,
ListNodeType& classMembers, bool* done);
MOZ_MUST_USE bool finishClassConstructor(
const ParseContext::ClassStatement& classStmt,
HandlePropertyName className, uint32_t classStartOffset,
uint32_t classEndOffset, size_t numFieldsWithInitializers,
ListNodeType& classMembers);
FunctionNodeType fieldInitializer(YieldHandling yieldHandling,
HandleAtom atom);
FunctionNodeType synthesizeConstructor(HandleAtom className,
uint32_t classNameOffset);
bool checkBindingIdentifier(PropertyName* ident, uint32_t offset,
YieldHandling yieldHandling,
TokenKind hint = TokenKind::Limit);
PropertyName* labelOrIdentifierReference(YieldHandling yieldHandling);
PropertyName* labelIdentifier(YieldHandling yieldHandling) {
return labelOrIdentifierReference(yieldHandling);
}
PropertyName* identifierReference(YieldHandling yieldHandling) {
return labelOrIdentifierReference(yieldHandling);
}
bool matchLabel(YieldHandling yieldHandling,
MutableHandle<PropertyName*> label);
bool matchInOrOf(bool* isForInp, bool* isForOfp);
private:
bool checkIncDecOperand(Node operand, uint32_t operandOffset);
bool checkStrictAssignment(Node lhs);
void reportMissingClosing(unsigned errorNumber, unsigned noteNumber,
uint32_t openedPos);
void reportRedeclaration(HandlePropertyName name, DeclarationKind prevKind,
TokenPos pos, uint32_t prevPos);
bool notePositionalFormalParameter(FunctionNodeType funNode,
HandlePropertyName name, uint32_t beginPos,
bool disallowDuplicateParams,
bool* duplicatedParam);
bool checkLexicalDeclarationDirectlyWithinBlock(ParseContext::Statement& stmt,
DeclarationKind kind,
TokenPos pos);
enum PropertyNameContext {
PropertyNameInLiteral,
PropertyNameInPattern,
PropertyNameInClass
};
Node propertyName(YieldHandling yieldHandling,
PropertyNameContext propertyNameContext,
const mozilla::Maybe<DeclarationKind>& maybeDecl,
ListNodeType propList, PropertyType* propType,
MutableHandleAtom propAtom);
UnaryNodeType computedPropertyName(
YieldHandling yieldHandling,
const mozilla::Maybe<DeclarationKind>& maybeDecl,
PropertyNameContext propertyNameContext, ListNodeType literal);
ListNodeType arrayInitializer(YieldHandling yieldHandling,
PossibleError* possibleError);
inline RegExpLiteralType newRegExp();
ListNodeType objectLiteral(YieldHandling yieldHandling,
PossibleError* possibleError);
BinaryNodeType bindingInitializer(Node lhs, DeclarationKind kind,
YieldHandling yieldHandling);
NameNodeType bindingIdentifier(DeclarationKind kind,
YieldHandling yieldHandling);
Node bindingIdentifierOrPattern(DeclarationKind kind,
YieldHandling yieldHandling, TokenKind tt);
ListNodeType objectBindingPattern(DeclarationKind kind,
YieldHandling yieldHandling);
ListNodeType arrayBindingPattern(DeclarationKind kind,
YieldHandling yieldHandling);
enum class TargetBehavior {
PermitAssignmentPattern,
ForbidAssignmentPattern
};
bool checkDestructuringAssignmentTarget(
Node expr, TokenPos exprPos, PossibleError* exprPossibleError,
PossibleError* possibleError,
TargetBehavior behavior = TargetBehavior::PermitAssignmentPattern);
void checkDestructuringAssignmentName(NameNodeType name, TokenPos namePos,
PossibleError* possibleError);
bool checkDestructuringAssignmentElement(Node expr, TokenPos exprPos,
PossibleError* exprPossibleError,
PossibleError* possibleError);
NumericLiteralType newNumber(const Token& tok) {
return handler_.newNumber(tok.number(), tok.decimalPoint(), tok.pos);
}
inline BigIntLiteralType newBigInt();
protected:
PropertyName* bindingIdentifier(YieldHandling yieldHandling);
bool checkLabelOrIdentifierReference(PropertyName* ident, uint32_t offset,
YieldHandling yieldHandling,
TokenKind hint = TokenKind::Limit);
ListNodeType statementList(YieldHandling yieldHandling);
MOZ_MUST_USE FunctionNodeType innerFunction(
FunctionNodeType funNode, ParseContext* outerpc, HandleFunction fun,
uint32_t toStringStart, InHandling inHandling,
YieldHandling yieldHandling, FunctionSyntaxKind kind,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives);
bool matchOrInsertSemicolon();
bool noteDeclaredName(HandlePropertyName name, DeclarationKind kind,
TokenPos pos);
private:
inline bool asmJS(ListNodeType list);
};
template <typename Unit>
class MOZ_STACK_CLASS Parser<SyntaxParseHandler, Unit> final
: public GeneralParser<SyntaxParseHandler, Unit> {
using Base = GeneralParser<SyntaxParseHandler, Unit>;
using Node = SyntaxParseHandler::Node;
#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \
using longTypeName = SyntaxParseHandler::longTypeName;
FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
#undef DECLARE_TYPE
using SyntaxParser = Parser<SyntaxParseHandler, Unit>;
friend class GeneralParser<SyntaxParseHandler, Unit>;
public:
using Base::Base;
using typename Base::Modifier;
using typename Base::Position;
using typename Base::TokenStream;
public:
using Base::anyChars;
using Base::clearAbortedSyntaxParse;
using Base::cx_;
using Base::hadAbortedSyntaxParse;
using Base::innerFunctionForFunctionBox;
using Base::tokenStream;
public:
using Base::error;
using Base::errorAt;
using Base::errorNoOffset;
using Base::errorWithNotes;
using Base::errorWithNotesAt;
using Base::errorWithNotesNoOffset;
using Base::extraWarning;
using Base::extraWarningAt;
using Base::extraWarningNoOffset;
using Base::extraWarningWithNotes;
using Base::extraWarningWithNotesAt;
using Base::extraWarningWithNotesNoOffset;
using Base::strictModeError;
using Base::strictModeErrorAt;
using Base::strictModeErrorNoOffset;
using Base::strictModeErrorWithNotes;
using Base::strictModeErrorWithNotesAt;
using Base::strictModeErrorWithNotesNoOffset;
using Base::warning;
using Base::warningAt;
using Base::warningNoOffset;
using Base::warningWithNotes;
using Base::warningWithNotesAt;
using Base::warningWithNotesNoOffset;
private:
using Base::alloc_;
#if DEBUG
using Base::checkOptionsCalled_;
#endif
using Base::finishFunctionScopes;
using Base::functionFormalParametersAndBody;
using Base::handler_;
using Base::innerFunction;
using Base::keepAtoms_;
using Base::matchOrInsertSemicolon;
using Base::mustMatchToken;
using Base::newFunctionBox;
using Base::newLexicalScopeData;
using Base::newModuleScopeData;
using Base::newName;
using Base::noteDeclaredName;
using Base::null;
using Base::options;
using Base::pc_;
using Base::pos;
using Base::propagateFreeNamesAndMarkClosedOverBindings;
using Base::ss;
using Base::statementList;
using Base::stringLiteral;
using Base::usedNames_;
private:
using Base::abortIfSyntaxParser;
using Base::disableSyntaxParser;
public:
PropertyName* bindingIdentifier(YieldHandling yieldHandling) {
return Base::bindingIdentifier(yieldHandling);
}
inline void setAwaitHandling(AwaitHandling awaitHandling);
inline void setInParametersOfAsyncFunction(bool inParameters);
RegExpLiteralType newRegExp();
BigIntLiteralType newBigInt();
ModuleNodeType moduleBody(ModuleSharedContext* modulesc);
inline BinaryNodeType importDeclaration();
inline bool checkLocalExportNames(ListNodeType node);
inline bool checkExportedName(JSAtom* exportName);
inline bool checkExportedNamesForArrayBinding(ListNodeType array);
inline bool checkExportedNamesForObjectBinding(ListNodeType obj);
inline bool checkExportedNamesForDeclaration(Node node);
inline bool checkExportedNamesForDeclarationList(ListNodeType node);
inline bool checkExportedNameForFunction(FunctionNodeType funNode);
inline bool checkExportedNameForClass(ClassNodeType classNode);
inline bool checkExportedNameForClause(NameNodeType nameNode);
bool trySyntaxParseInnerFunction(
FunctionNodeType* funNode, HandleFunction fun, uint32_t toStringStart,
InHandling inHandling, YieldHandling yieldHandling,
FunctionSyntaxKind kind, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind, bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives);
bool skipLazyInnerFunction(FunctionNodeType funNode, uint32_t toStringStart,
FunctionSyntaxKind kind, bool tryAnnexB);
bool asmJS(ListNodeType list);
};
template <typename Unit>
class MOZ_STACK_CLASS Parser<FullParseHandler, Unit> final
: public GeneralParser<FullParseHandler, Unit> {
using Base = GeneralParser<FullParseHandler, Unit>;
using Node = FullParseHandler::Node;
#define DECLARE_TYPE(typeName, longTypeName, asMethodName) \
using longTypeName = FullParseHandler::longTypeName;
FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
#undef DECLARE_TYPE
using SyntaxParser = Parser<SyntaxParseHandler, Unit>;
friend class GeneralParser<FullParseHandler, Unit>;
public:
using Base::Base;
using typename Base::Modifier;
using typename Base::Position;
using typename Base::TokenStream;
public:
using Base::anyChars;
using Base::clearAbortedSyntaxParse;
using Base::functionFormalParametersAndBody;
using Base::hadAbortedSyntaxParse;
using Base::handler_;
using Base::newFunctionBox;
using Base::options;
using Base::pc_;
using Base::pos;
using Base::ss;
using Base::tokenStream;
public:
using Base::error;
using Base::errorAt;
using Base::errorNoOffset;
using Base::errorWithNotes;
using Base::errorWithNotesAt;
using Base::errorWithNotesNoOffset;
using Base::extraWarning;
using Base::extraWarningAt;
using Base::extraWarningNoOffset;
using Base::extraWarningWithNotes;
using Base::extraWarningWithNotesAt;
using Base::extraWarningWithNotesNoOffset;
using Base::strictModeError;
using Base::strictModeErrorAt;
using Base::strictModeErrorNoOffset;
using Base::strictModeErrorWithNotes;
using Base::strictModeErrorWithNotesAt;
using Base::strictModeErrorWithNotesNoOffset;
using Base::warning;
using Base::warningAt;
using Base::warningNoOffset;
using Base::warningWithNotes;
using Base::warningWithNotesAt;
using Base::warningWithNotesNoOffset;
private:
using Base::alloc_;
using Base::checkLabelOrIdentifierReference;
#if DEBUG
using Base::checkOptionsCalled_;
#endif
using Base::cx_;
using Base::finishFunctionScopes;
using Base::finishLexicalScope;
using Base::innerFunction;
using Base::innerFunctionForFunctionBox;
using Base::keepAtoms_;
using Base::matchOrInsertSemicolon;
using Base::mustMatchToken;
using Base::newEvalScopeData;
using Base::newFunctionScopeData;
using Base::newGlobalScopeData;
using Base::newLexicalScopeData;
using Base::newModuleScopeData;
using Base::newName;
using Base::newVarScopeData;
using Base::noteDeclaredName;
using Base::null;
using Base::propagateFreeNamesAndMarkClosedOverBindings;
using Base::statementList;
using Base::stringLiteral;
using Base::usedNames_;
using Base::abortIfSyntaxParser;
using Base::disableSyntaxParser;
using Base::getSyntaxParser;
public:
PropertyName* bindingIdentifier(YieldHandling yieldHandling) {
return Base::bindingIdentifier(yieldHandling);
}
friend class AutoAwaitIsKeyword<SyntaxParseHandler, Unit>;
inline void setAwaitHandling(AwaitHandling awaitHandling);
friend class AutoInParametersOfAsyncFunction<SyntaxParseHandler, Unit>;
inline void setInParametersOfAsyncFunction(bool inParameters);
RegExpLiteralType newRegExp();
BigIntLiteralType newBigInt();
ModuleNodeType moduleBody(ModuleSharedContext* modulesc);
BinaryNodeType importDeclaration();
bool checkLocalExportNames(ListNodeType node);
bool checkExportedName(JSAtom* exportName);
bool checkExportedNamesForArrayBinding(ListNodeType array);
bool checkExportedNamesForObjectBinding(ListNodeType obj);
bool checkExportedNamesForDeclaration(Node node);
bool checkExportedNamesForDeclarationList(ListNodeType node);
bool checkExportedNameForFunction(FunctionNodeType funNode);
bool checkExportedNameForClass(ClassNodeType classNode);
inline bool checkExportedNameForClause(NameNodeType nameNode);
bool trySyntaxParseInnerFunction(
FunctionNodeType* funNode, HandleFunction fun, uint32_t toStringStart,
InHandling inHandling, YieldHandling yieldHandling,
FunctionSyntaxKind kind, GeneratorKind generatorKind,
FunctionAsyncKind asyncKind, bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives);
bool skipLazyInnerFunction(FunctionNodeType funNode, uint32_t toStringStart,
FunctionSyntaxKind kind, bool tryAnnexB);
LexicalScopeNodeType evalBody(EvalSharedContext* evalsc);
FunctionNodeType standaloneLazyFunction(HandleFunction fun,
uint32_t toStringStart, bool strict,
GeneratorKind generatorKind,
FunctionAsyncKind asyncKind);
FunctionNodeType standaloneFunction(
HandleFunction fun, HandleScope enclosingScope,
const mozilla::Maybe<uint32_t>& parameterListEnd,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
Directives inheritedDirectives, Directives* newDirectives);
bool checkStatementsEOF();
ListNodeType globalBody(GlobalSharedContext* globalsc);
bool namedImportsOrNamespaceImport(TokenKind tt, ListNodeType importSpecSet);
PropertyName* importedBinding() { return bindingIdentifier(YieldIsName); }
bool checkLocalExportName(PropertyName* ident, uint32_t offset) {
return checkLabelOrIdentifierReference(ident, offset, YieldIsName);
}
bool asmJS(ListNodeType list);
};
template <class Parser>
inline const TokenStreamAnyChars&
ParserAnyCharsAccess<Parser>::anyChars(const GeneralTokenStreamChars* ts) {
static_assert(
mozilla::IsBaseOf<GeneralTokenStreamChars, TokenStreamSpecific>::value,
"the static_cast<> below assumes a base-class relationship");
const auto* tss = static_cast<const TokenStreamSpecific*>(ts);
auto tssAddr = reinterpret_cast<uintptr_t>(tss);
using ActualTokenStreamType =
decltype(static_cast<Parser*>(nullptr)->tokenStream);
static_assert(
mozilla::IsSame<ActualTokenStreamType, TokenStreamSpecific>::value,
"Parser::tokenStream must have type TokenStreamSpecific");
uintptr_t parserAddr = tssAddr - offsetof(Parser, tokenStream);
return reinterpret_cast<const Parser*>(parserAddr)->anyChars;
}
template <class Parser>
inline TokenStreamAnyChars& ParserAnyCharsAccess<Parser>::anyChars(
GeneralTokenStreamChars* ts) {
const TokenStreamAnyChars& anyCharsConst =
anyChars(const_cast<const GeneralTokenStreamChars*>(ts));
return const_cast<TokenStreamAnyChars&>(anyCharsConst);
}
template <class ParseHandler, typename Unit>
class MOZ_STACK_CLASS AutoAwaitIsKeyword {
using GeneralParser = frontend::GeneralParser<ParseHandler, Unit>;
private:
GeneralParser* parser_;
AwaitHandling oldAwaitHandling_;
public:
AutoAwaitIsKeyword(GeneralParser* parser, AwaitHandling awaitHandling) {
parser_ = parser;
oldAwaitHandling_ = static_cast<AwaitHandling>(parser_->awaitHandling_);
if (oldAwaitHandling_ != AwaitIsModuleKeyword) {
parser_->setAwaitHandling(awaitHandling);
}
}
~AutoAwaitIsKeyword() { parser_->setAwaitHandling(oldAwaitHandling_); }
};
template <class ParseHandler, typename Unit>
class MOZ_STACK_CLASS AutoInParametersOfAsyncFunction {
using GeneralParser = frontend::GeneralParser<ParseHandler, Unit>;
private:
GeneralParser* parser_;
bool oldInParametersOfAsyncFunction_;
public:
AutoInParametersOfAsyncFunction(GeneralParser* parser, bool inParameters) {
parser_ = parser;
oldInParametersOfAsyncFunction_ = parser_->inParametersOfAsyncFunction_;
parser_->setInParametersOfAsyncFunction(inParameters);
}
~AutoInParametersOfAsyncFunction() {
parser_->setInParametersOfAsyncFunction(oldInParametersOfAsyncFunction_);
}
};
template <typename Scope>
extern typename Scope::Data* NewEmptyBindingData(JSContext* cx,
LifoAlloc& alloc,
uint32_t numBindings);
mozilla::Maybe<GlobalScope::Data*> NewGlobalScopeData(
JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc,
ParseContext* pc);
mozilla::Maybe<EvalScope::Data*> NewEvalScopeData(JSContext* context,
ParseContext::Scope& scope,
LifoAlloc& alloc,
ParseContext* pc);
mozilla::Maybe<FunctionScope::Data*> NewFunctionScopeData(
JSContext* context, ParseContext::Scope& scope, bool hasParameterExprs,
LifoAlloc& alloc, ParseContext* pc);
mozilla::Maybe<VarScope::Data*> NewVarScopeData(JSContext* context,
ParseContext::Scope& scope,
LifoAlloc& alloc,
ParseContext* pc);
mozilla::Maybe<LexicalScope::Data*> NewLexicalScopeData(
JSContext* context, ParseContext::Scope& scope, LifoAlloc& alloc,
ParseContext* pc);
JSFunction* AllocNewFunction(JSContext* cx, HandleAtom atom,
FunctionSyntaxKind kind,
GeneratorKind generatorKind,
FunctionAsyncKind asyncKind, HandleObject proto,
bool isSelfHosting = false,
bool inFunctionBox = false);
}
}
#endif