--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -2218,32 +2218,33 @@ Parser<SyntaxParseHandler>::finishFuncti
}
template <>
ParseNode*
Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun,
HandleScope enclosingScope,
Handle<PropertyNameVector> formals,
GeneratorKind generatorKind,
+ FunctionAsyncKind asyncKind,
Directives inheritedDirectives,
Directives* newDirectives)
{
MOZ_ASSERT(checkOptionsCalled);
Node fn = handler.newFunctionDefinition();
if (!fn)
return null();
ParseNode* argsbody = handler.newList(PNK_PARAMSBODY);
if (!argsbody)
return null();
fn->pn_body = argsbody;
FunctionBox* funbox = newFunctionBox(fn, fun, inheritedDirectives, generatorKind,
- SyncFunction, /* tryAnnexB = */ false);
+ asyncKind, /* tryAnnexB = */ false);
if (!funbox)
return null();
funbox->initStandaloneFunction(enclosingScope);
ParseContext funpc(this, funbox, newDirectives);
if (!funpc.init())
return null();
funpc.setIsStandaloneFunctionBody();
@@ -2451,17 +2452,18 @@ Parser<ParseHandler>::functionBody(InHan
}
return finishLexicalScope(pc->varScope(), pn);
}
template <typename ParseHandler>
JSFunction*
Parser<ParseHandler>::newFunction(HandleAtom atom, FunctionSyntaxKind kind,
- GeneratorKind generatorKind, HandleObject proto)
+ GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
+ HandleObject proto)
{
MOZ_ASSERT_IF(kind == Statement, atom != nullptr);
RootedFunction fun(context);
gc::AllocKind allocKind = gc::AllocKind::FUNCTION;
JSFunction::Flags flags;
#ifdef DEBUG
@@ -3027,17 +3029,18 @@ Parser<ParseHandler>::templateLiteral(Yi
} while (tt == TOK_TEMPLATE_HEAD);
return nodeList;
}
template <typename ParseHandler>
typename ParseHandler::Node
Parser<ParseHandler>::functionDefinition(InHandling inHandling, YieldHandling yieldHandling,
HandleAtom funName, FunctionSyntaxKind kind,
- GeneratorKind generatorKind, InvokedPrediction invoked)
+ GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
+ InvokedPrediction invoked)
{
MOZ_ASSERT_IF(kind == Statement, funName);
Node pn = handler.newFunctionDefinition();
if (!pn)
return null();
if (invoked)
@@ -3062,17 +3065,17 @@ Parser<ParseHandler>::functionDefinition
// If we are off the main thread, the generator meta-objects have
// already been created by js::StartOffThreadParseScript, so cx will not
// be necessary.
JSContext* cx = context->maybeJSContext();
proto = GlobalObject::getOrCreateStarGeneratorFunctionPrototype(cx, context->global());
if (!proto)
return null();
}
- RootedFunction fun(context, newFunction(funName, kind, generatorKind, proto));
+ RootedFunction fun(context, newFunction(funName, kind, generatorKind, asyncKind, proto));
if (!fun)
return null();
// Speculatively parse using the directives of the parent parsing context.
// If a directive is encountered (e.g., "use strict") that changes how the
// function should have been parsed, we backup and reparse with the new set
// of directives.
Directives directives(pc);
@@ -3081,17 +3084,17 @@ Parser<ParseHandler>::functionDefinition
TokenStream::Position start(keepAtoms);
tokenStream.tell(&start);
// Parse the inner function. The following is a loop as we may attempt to
// reparse a function due to failed syntax parsing and encountering new
// "use foo" directives.
while (true) {
if (trySyntaxParseInnerFunction(pn, fun, inHandling, yieldHandling, kind, generatorKind,
- tryAnnexB, directives, &newDirectives))
+ asyncKind, tryAnnexB, directives, &newDirectives))
{
break;
}
// Return on error.
if (tokenStream.hadError() || directives == newDirectives)
return null();
@@ -3112,16 +3115,17 @@ Parser<ParseHandler>::functionDefinition
template <>
bool
Parser<FullParseHandler>::trySyntaxParseInnerFunction(ParseNode* pn, HandleFunction fun,
InHandling inHandling,
YieldHandling yieldHandling,
FunctionSyntaxKind kind,
GeneratorKind generatorKind,
+ FunctionAsyncKind asyncKind,
bool tryAnnexB,
Directives inheritedDirectives,
Directives* newDirectives)
{
// Try a syntax parse for this inner function.
do {
// If we're assuming this function is an IIFE, always perform a full
// parse to avoid the overhead of a lazy syntax-only parse. Although
@@ -3141,17 +3145,17 @@ Parser<FullParseHandler>::trySyntaxParse
tokenStream.tell(&position);
if (!parser->tokenStream.seek(position, tokenStream))
return false;
// Make a FunctionBox before we enter the syntax parser, because |pn|
// still expects a FunctionBox to be attached to it during BCE, and
// the syntax parser cannot attach one to it.
FunctionBox* funbox = newFunctionBox(pn, fun, inheritedDirectives, generatorKind,
- SyncFunction, tryAnnexB);
+ asyncKind, tryAnnexB);
if (!funbox)
return false;
funbox->initWithEnclosingParseContext(pc, kind);
if (!parser->innerFunction(SyntaxParseHandler::NodeGeneric, pc, funbox, inHandling,
yieldHandling, kind, inheritedDirectives, newDirectives))
{
if (parser->hadAbortedSyntaxParse()) {
@@ -3173,34 +3177,35 @@ Parser<FullParseHandler>::trySyntaxParse
return false;
// Update the end position of the parse node.
pn->pn_pos.end = tokenStream.currentToken().pos.end;
return true;
} while (false);
// We failed to do a syntax parse above, so do the full parse.
- return innerFunction(pn, pc, fun, inHandling, yieldHandling, kind, generatorKind, tryAnnexB,
- inheritedDirectives, newDirectives);
+ return innerFunction(pn, pc, fun, inHandling, yieldHandling, kind, generatorKind, asyncKind,
+ tryAnnexB, inheritedDirectives, newDirectives);
}
template <>
bool
Parser<SyntaxParseHandler>::trySyntaxParseInnerFunction(Node pn, HandleFunction fun,
InHandling inHandling,
YieldHandling yieldHandling,
FunctionSyntaxKind kind,
GeneratorKind generatorKind,
+ FunctionAsyncKind asyncKind,
bool tryAnnexB,
Directives inheritedDirectives,
Directives* newDirectives)
{
// This is already a syntax parser, so just parse the inner function.
- return innerFunction(pn, pc, fun, inHandling, yieldHandling, kind, generatorKind, tryAnnexB,
- inheritedDirectives, newDirectives);
+ return innerFunction(pn, pc, fun, inHandling, yieldHandling, kind, generatorKind, asyncKind,
+ tryAnnexB, inheritedDirectives, newDirectives);
}
template <typename ParseHandler>
bool
Parser<ParseHandler>::innerFunction(Node pn, ParseContext* outerpc, FunctionBox* funbox,
InHandling inHandling, YieldHandling yieldHandling,
FunctionSyntaxKind kind, Directives inheritedDirectives,
Directives* newDirectives)
@@ -3220,27 +3225,28 @@ Parser<ParseHandler>::innerFunction(Node
return leaveInnerFunction(outerpc);
}
template <typename ParseHandler>
bool
Parser<ParseHandler>::innerFunction(Node pn, ParseContext* outerpc, HandleFunction fun,
InHandling inHandling, YieldHandling yieldHandling,
- FunctionSyntaxKind kind, GeneratorKind generatorKind,
- bool tryAnnexB, Directives inheritedDirectives,
- Directives* newDirectives)
+ FunctionSyntaxKind kind,
+ GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
+ bool tryAnnexB,
+ Directives inheritedDirectives, Directives* newDirectives)
{
// Note that it is possible for outerpc != this->pc, as we may be
// attempting to syntax parse an inner function from an outer full
// parser. In that case, outerpc is a ParseContext from the full parser
// instead of the current top of the stack of the syntax parser.
FunctionBox* funbox = newFunctionBox(pn, fun, inheritedDirectives, generatorKind,
- SyncFunction, tryAnnexB);
+ asyncKind, tryAnnexB);
if (!funbox)
return false;
funbox->initWithEnclosingParseContext(outerpc, kind);
return innerFunction(pn, outerpc, funbox, inHandling, yieldHandling, kind, inheritedDirectives,
newDirectives);
}
@@ -3261,26 +3267,27 @@ Parser<ParseHandler>::appendToCallSiteOb
handler.addToCallSiteObject(callSiteObj, rawNode, cookedNode);
return true;
}
template <>
ParseNode*
Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict,
- GeneratorKind generatorKind)
+ GeneratorKind generatorKind,
+ FunctionAsyncKind asyncKind)
{
MOZ_ASSERT(checkOptionsCalled);
Node pn = handler.newFunctionDefinition();
if (!pn)
return null();
Directives directives(strict);
- FunctionBox* funbox = newFunctionBox(pn, fun, directives, generatorKind, SyncFunction,
+ FunctionBox* funbox = newFunctionBox(pn, fun, directives, generatorKind, asyncKind,
/* tryAnnexB = */ false);
if (!funbox)
return null();
funbox->initFromLazyFunction();
Directives newDirectives = directives;
ParseContext funpc(this, funbox, &newDirectives);
if (!funpc.init())
@@ -3480,17 +3487,17 @@ Parser<ParseHandler>::functionStmt(Yield
} else {
/* Unnamed function expressions are forbidden in statement context. */
report(ParseError, false, null(), JSMSG_UNNAMED_FUNCTION_STMT);
return null();
}
YieldHandling newYieldHandling = generatorKind != NotGenerator ? YieldIsKeyword : YieldIsName;
Node fun = functionDefinition(InAllowed, newYieldHandling, name, Statement, generatorKind,
- PredictUninvoked);
+ SyncFunction, PredictUninvoked);
if (!fun)
return null();
if (synthesizedStmtForAnnexB) {
Node synthesizedStmtList = handler.newStatementList(handler.getPosition(fun));
if (!synthesizedStmtList)
return null();
handler.addStatementToList(synthesizedStmtList, fun);
@@ -3523,17 +3530,18 @@ Parser<ParseHandler>::functionExpr(Invok
if (tt == TOK_NAME || tt == TOK_YIELD) {
name = bindingIdentifier(yieldHandling);
if (!name)
return null();
} else {
tokenStream.ungetToken();
}
- return functionDefinition(InAllowed, yieldHandling, name, Expression, generatorKind, invoked);
+ return functionDefinition(InAllowed, yieldHandling, name, Expression, generatorKind,
+ SyncFunction, invoked);
}
/*
* Return true if this node, known to be an unparenthesized string literal,
* could be the string of a directive in a Directive Prologue. Directive
* strings never contain escape sequences or line continuations.
* isEscapeFreeStringLiteral, below, checks whether the node itself could be
* a directive.
@@ -7484,17 +7492,17 @@ Parser<ParseHandler>::assignExpr(InHandl
tokenStream.seek(start);
TokenKind ignored;
if (!tokenStream.peekToken(&ignored, TokenStream::Operand))
return null();
Node arrowFunc = functionDefinition(inHandling, yieldHandling, nullptr,
- Arrow, NotGenerator);
+ Arrow, NotGenerator, SyncFunction);
if (!arrowFunc)
return null();
if (isBlock) {
// This arrow function could be a non-trailing member of a comma
// expression or a semicolon terminating a full expression. If so,
// the next token is that comma/semicolon, gotten with None:
//
@@ -7810,17 +7818,17 @@ Parser<ParseHandler>::generatorComprehen
// be necessary.
RootedObject proto(context);
JSContext* cx = context->maybeJSContext();
proto = GlobalObject::getOrCreateStarGeneratorFunctionPrototype(cx, context->global());
if (!proto)
return null();
RootedFunction fun(context, newFunction(/* atom = */ nullptr, Expression,
- StarGenerator, proto));
+ StarGenerator, SyncFunction, proto));
if (!fun)
return null();
// Create box for fun->object early to root it.
Directives directives(/* strict = */ outerpc->sc()->strict());
FunctionBox* genFunbox = newFunctionBox(genfn, fun, directives, StarGenerator, SyncFunction,
/* tryAnnexB = */ false);
if (!genFunbox)
@@ -9042,17 +9050,17 @@ Parser<ParseHandler>::objectLiteral(Yiel
template <typename ParseHandler>
typename ParseHandler::Node
Parser<ParseHandler>::methodDefinition(PropertyType propType, HandleAtom funName)
{
FunctionSyntaxKind kind = FunctionSyntaxKindFromPropertyType(propType);
GeneratorKind generatorKind = GeneratorKindFromPropertyType(propType);
YieldHandling yieldHandling = generatorKind != NotGenerator ? YieldIsKeyword : YieldIsName;
- return functionDefinition(InAllowed, yieldHandling, funName, kind, generatorKind);
+ return functionDefinition(InAllowed, yieldHandling, funName, kind, generatorKind, SyncFunction);
}
template <typename ParseHandler>
bool
Parser<ParseHandler>::tryNewTarget(Node &newTarget)
{
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_NEW));
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -946,17 +946,18 @@ class Parser final : private JS::AutoGCR
FunctionBox* newFunctionBox(Node fn, JSFunction* fun, Directives directives,
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
bool tryAnnexB);
/*
* Create a new function object given a name (which is optional if this is
* a function expression).
*/
- JSFunction* newFunction(HandleAtom atom, FunctionSyntaxKind kind, GeneratorKind generatorKind,
+ JSFunction* newFunction(HandleAtom atom, FunctionSyntaxKind kind,
+ GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
HandleObject proto);
void trace(JSTracer* trc);
bool hadAbortedSyntaxParse() {
return abortedSyntaxParse;
}
void clearAbortedSyntaxParse() {
@@ -1005,22 +1006,24 @@ class Parser final : private JS::AutoGCR
Node globalBody(GlobalSharedContext* globalsc);
// Parse a module.
Node moduleBody(ModuleSharedContext* modulesc);
// Parse a function, given only its body. Used for the Function and
// Generator constructors.
Node standaloneFunctionBody(HandleFunction fun, HandleScope enclosingScope,
- Handle<PropertyNameVector> formals, GeneratorKind generatorKind,
+ Handle<PropertyNameVector> formals,
+ GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
Directives inheritedDirectives, Directives* newDirectives);
// Parse a function, given only its arguments and body. Used for lazily
// parsed functions.
- Node standaloneLazyFunction(HandleFunction fun, bool strict, GeneratorKind generatorKind);
+ Node standaloneLazyFunction(HandleFunction fun, bool strict,
+ GeneratorKind generatorKind, FunctionAsyncKind asyncKind);
// Parse an inner function given an enclosing ParseContext and a
// FunctionBox for the inner function.
bool innerFunction(Node pn, ParseContext* outerpc, FunctionBox* funbox, InHandling inHandling,
YieldHandling yieldHandling, FunctionSyntaxKind kind,
Directives inheritedDirectives, Directives* newDirectives);
// Parse a function's formal parameters and its body assuming its function
@@ -1207,17 +1210,18 @@ class Parser final : private JS::AutoGCR
/*
* Additional JS parsers.
*/
bool functionArguments(YieldHandling yieldHandling, FunctionSyntaxKind kind,
Node funcpn);
Node functionDefinition(InHandling inHandling, YieldHandling yieldHandling, HandleAtom name,
- FunctionSyntaxKind kind, GeneratorKind generatorKind,
+ FunctionSyntaxKind kind,
+ GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
InvokedPrediction invoked = PredictUninvoked);
// Parse a function body. Pass StatementListBody if the body is a list of
// statements; pass ExpressionBody if the body is a single expression.
enum FunctionBodyType { StatementListBody, ExpressionBody };
Node functionBody(InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind,
FunctionBodyType type);
@@ -1298,21 +1302,23 @@ class Parser final : private JS::AutoGCR
Node newDotGeneratorName();
bool declareDotGeneratorName();
bool checkFunctionDefinition(HandleAtom funAtom, Node pn, FunctionSyntaxKind kind,
GeneratorKind generatorKind, bool* tryAnnexB);
bool skipLazyInnerFunction(Node pn, FunctionSyntaxKind kind, bool tryAnnexB);
bool innerFunction(Node pn, ParseContext* outerpc, HandleFunction fun,
InHandling inHandling, YieldHandling yieldHandling,
- FunctionSyntaxKind kind, GeneratorKind generatorKind, bool tryAnnexB,
+ FunctionSyntaxKind kind,
+ GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives);
bool trySyntaxParseInnerFunction(Node pn, HandleFunction fun, InHandling inHandling,
YieldHandling yieldHandling, FunctionSyntaxKind kind,
- GeneratorKind generatorKind, bool tryAnnexB,
+ GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
+ bool tryAnnexB,
Directives inheritedDirectives, Directives* newDirectives);
bool finishFunctionScopes();
bool finishFunction();
bool leaveInnerFunction(ParseContext* outerpc);
public:
enum FunctionCallBehavior {
PermitAssignmentToFunctionCalls,