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