mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-04 14:58:37 +09:00
Issue #2142 - Ensure 'await' is always a restricted identifier when parsing modules
Based-on: m-c 1356189
This commit is contained in:
parent
3b9b111b2f
commit
faed047e3f
2 changed files with 38 additions and 21 deletions
|
|
@ -785,7 +785,7 @@ ParserBase::ParserBase(ExclusiveContext* cx, LifoAlloc& alloc,
|
|||
#endif
|
||||
abortedSyntaxParse(false),
|
||||
isUnexpectedEOF_(false),
|
||||
awaitIsKeyword_(false),
|
||||
awaitHandling_(AwaitIsName),
|
||||
parseGoal_(uint8_t(parseGoal))
|
||||
{
|
||||
cx->perThreadData->frontendCollectionPool.addActiveCompilation();
|
||||
|
|
@ -846,18 +846,18 @@ Parser<ParseHandler>::~Parser()
|
|||
|
||||
template <>
|
||||
void
|
||||
Parser<SyntaxParseHandler>::setAwaitIsKeyword(bool isKeyword)
|
||||
Parser<SyntaxParseHandler>::setAwaitHandling(AwaitHandling awaitHandling)
|
||||
{
|
||||
awaitIsKeyword_ = isKeyword;
|
||||
awaitHandling_ = awaitHandling;
|
||||
}
|
||||
|
||||
template <>
|
||||
void
|
||||
Parser<FullParseHandler>::setAwaitIsKeyword(bool isKeyword)
|
||||
Parser<FullParseHandler>::setAwaitHandling(AwaitHandling awaitHandling)
|
||||
{
|
||||
awaitIsKeyword_ = isKeyword;
|
||||
awaitHandling_ = awaitHandling;
|
||||
if (Parser<SyntaxParseHandler>* parser = handler.syntaxParser)
|
||||
parser->setAwaitIsKeyword(isKeyword);
|
||||
parser->setAwaitHandling(awaitHandling);
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
|
|
@ -2217,7 +2217,7 @@ Parser<FullParseHandler>::moduleBody(ModuleSharedContext* modulesc)
|
|||
if (!moduleNode)
|
||||
return null();
|
||||
|
||||
AutoAwaitIsKeyword<FullParseHandler> awaitIsKeyword(this, true);
|
||||
AutoAwaitIsKeyword<FullParseHandler> awaitIsKeyword(this, AwaitIsModuleKeyword);
|
||||
ListNode* stmtList = statementList(YieldIsName);
|
||||
if (!stmtList) {
|
||||
return null();
|
||||
|
|
@ -2490,6 +2490,14 @@ GetYieldHandling(GeneratorKind generatorKind)
|
|||
return YieldIsKeyword;
|
||||
}
|
||||
|
||||
static AwaitHandling
|
||||
GetAwaitHandling(FunctionAsyncKind asyncKind)
|
||||
{
|
||||
if (asyncKind == SyncFunction)
|
||||
return AwaitIsName;
|
||||
return AwaitIsKeyword;
|
||||
}
|
||||
|
||||
template <>
|
||||
FunctionNode*
|
||||
Parser<FullParseHandler>::standaloneFunction(HandleFunction fun,
|
||||
|
|
@ -2549,7 +2557,8 @@ Parser<FullParseHandler>::standaloneFunction(HandleFunction fun,
|
|||
funpc.setIsStandaloneFunctionBody();
|
||||
|
||||
YieldHandling yieldHandling = GetYieldHandling(generatorKind);
|
||||
AutoAwaitIsKeyword<FullParseHandler> awaitIsKeyword(this, asyncKind == AsyncFunction);
|
||||
AwaitHandling awaitHandling = GetAwaitHandling(asyncKind);
|
||||
AutoAwaitIsKeyword<FullParseHandler> awaitIsKeyword(this, awaitHandling);
|
||||
if (!functionFormalParametersAndBody(InAllowed, yieldHandling, funNode, FunctionSyntaxKind::Statement,
|
||||
parameterListEnd, /* isStandaloneFunction = */ true))
|
||||
{
|
||||
|
|
@ -3641,9 +3650,11 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
|
|||
// See below for an explanation why arrow function parameters and arrow
|
||||
// function bodies are parsed with different yield/await settings.
|
||||
{
|
||||
bool asyncOrArrowInAsync = funbox->isAsync() ||
|
||||
(kind == FunctionSyntaxKind::Arrow && awaitIsKeyword());
|
||||
AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, asyncOrArrowInAsync);
|
||||
AwaitHandling awaitHandling = funbox->isAsync() ||
|
||||
(kind == FunctionSyntaxKind::Arrow && awaitIsKeyword())
|
||||
? AwaitIsKeyword
|
||||
: AwaitIsName;
|
||||
AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, awaitHandling);
|
||||
if (!functionArguments(yieldHandling, kind, funNode))
|
||||
return false;
|
||||
}
|
||||
|
|
@ -3713,9 +3724,10 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
|
|||
// Whereas the |yield| in the function body is always parsed as a name.
|
||||
// The same goes when parsing |await| in arrow functions.
|
||||
YieldHandling bodyYieldHandling = GetYieldHandling(pc->generatorKind());
|
||||
AwaitHandling bodyAwaitHandling = GetAwaitHandling(pc->asyncKind());
|
||||
LexicalScopeNodeType body;
|
||||
{
|
||||
AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, funbox->isAsync());
|
||||
AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, bodyAwaitHandling);
|
||||
body = functionBody(inHandling, bodyYieldHandling, kind, bodyType);
|
||||
if (!body)
|
||||
return false;
|
||||
|
|
@ -3873,7 +3885,7 @@ Parser<ParseHandler>::functionExpr(uint32_t toStringStart, InvokedPrediction inv
|
|||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FUNCTION));
|
||||
|
||||
AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, asyncKind == AsyncFunction);
|
||||
AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, GetAwaitHandling(asyncKind));
|
||||
GeneratorKind generatorKind = NotGenerator;
|
||||
TokenKind tt;
|
||||
if (!tokenStream.getToken(&tt))
|
||||
|
|
|
|||
|
|
@ -591,6 +591,7 @@ enum class PropertyType {
|
|||
// we're in a function box -- easier and simpler than passing an extra
|
||||
// parameter everywhere.
|
||||
enum YieldHandling { YieldIsName, YieldIsKeyword };
|
||||
enum AwaitHandling : uint8_t { AwaitIsName, AwaitIsKeyword, AwaitIsModuleKeyword };
|
||||
enum InHandling { InAllowed, InProhibited };
|
||||
enum DefaultHandling { NameRequired, AllowDefaultName };
|
||||
enum TripledotHandling { TripledotAllowed, TripledotProhibited };
|
||||
|
|
@ -800,13 +801,13 @@ class ParserBase : public StrictModeGetter
|
|||
/* Unexpected end of input, i.e. TOK_EOF not at top-level. */
|
||||
bool isUnexpectedEOF_:1;
|
||||
|
||||
bool awaitIsKeyword_:1;
|
||||
/* AwaitHandling */ uint8_t awaitHandling_:2;
|
||||
|
||||
uint8_t parseGoal_:1;
|
||||
|
||||
public:
|
||||
bool awaitIsKeyword() const {
|
||||
return awaitIsKeyword_;
|
||||
return awaitHandling_ != AwaitIsName;
|
||||
}
|
||||
|
||||
ParseGoal parseGoal() const {
|
||||
|
|
@ -1058,7 +1059,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_TYPE)
|
|||
~Parser();
|
||||
|
||||
friend class AutoAwaitIsKeyword<ParseHandler>;
|
||||
void setAwaitIsKeyword(bool isKeyword);
|
||||
void setAwaitHandling(AwaitHandling awaitHandling);
|
||||
|
||||
bool checkOptions();
|
||||
|
||||
|
|
@ -1643,17 +1644,21 @@ class MOZ_STACK_CLASS AutoAwaitIsKeyword
|
|||
{
|
||||
private:
|
||||
Parser<ParseHandler>* parser_;
|
||||
bool oldAwaitIsKeyword_;
|
||||
AwaitHandling oldAwaitHandling_;
|
||||
|
||||
public:
|
||||
AutoAwaitIsKeyword(Parser<ParseHandler>* parser, bool awaitIsKeyword) {
|
||||
AutoAwaitIsKeyword(Parser<ParseHandler>* parser, AwaitHandling awaitHandling) {
|
||||
parser_ = parser;
|
||||
oldAwaitIsKeyword_ = parser_->awaitIsKeyword_;
|
||||
parser_->setAwaitIsKeyword(awaitIsKeyword);
|
||||
oldAwaitHandling_ = static_cast<AwaitHandling>(parser_->awaitHandling_);
|
||||
|
||||
// 'await' is always a keyword in module contexts, so we don't modify
|
||||
// the state when the original handling is AwaitIsModuleKeyword.
|
||||
if (oldAwaitHandling_ != AwaitIsModuleKeyword)
|
||||
parser_->setAwaitHandling(awaitHandling);
|
||||
}
|
||||
|
||||
~AutoAwaitIsKeyword() {
|
||||
parser_->setAwaitIsKeyword(oldAwaitIsKeyword_);
|
||||
parser_->setAwaitHandling(oldAwaitHandling_);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue