diff options
author | Gaming4JC <g4jc@hyperbola.info> | 2019-07-14 22:12:08 -0400 |
---|---|---|
committer | Gaming4JC <g4jc@hyperbola.info> | 2019-07-18 22:38:49 -0400 |
commit | 4a84afdc892dcc3a1732b45e5ac65812daa53fae (patch) | |
tree | 905ade1458ef3a877f2d736534d85795b81bdb85 /js/src/frontend/Parser.cpp | |
parent | 28c5b8c0589d7548382d205de8df03b42b32ccc7 (diff) | |
download | UXP-4a84afdc892dcc3a1732b45e5ac65812daa53fae.tar UXP-4a84afdc892dcc3a1732b45e5ac65812daa53fae.tar.gz UXP-4a84afdc892dcc3a1732b45e5ac65812daa53fae.tar.lz UXP-4a84afdc892dcc3a1732b45e5ac65812daa53fae.tar.xz UXP-4a84afdc892dcc3a1732b45e5ac65812daa53fae.zip |
1353691 - Report SyntaxError when arrow function has await-identifier in async function context.
Diffstat (limited to 'js/src/frontend/Parser.cpp')
-rw-r--r-- | js/src/frontend/Parser.cpp | 59 |
1 files changed, 34 insertions, 25 deletions
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 47e0f943d..0c279591f 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -3623,9 +3623,14 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling, FunctionBox* funbox = pc->functionBox(); RootedFunction fun(context, funbox->function()); - AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, funbox->isAsync()); - if (!functionArguments(yieldHandling, kind, pn)) - return false; + // 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 == Arrow && awaitIsKeyword()); + AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, asyncOrArrowInAsync); + if (!functionArguments(yieldHandling, kind, pn)) + return false; + } Maybe<ParseContext::VarScope> varScope; if (funbox->hasParameterExprs) { @@ -3689,32 +3694,36 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling, // |yield| in the parameters is either a name or keyword, depending on // whether the arrow function is enclosed in a generator function or not. // 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(), pc->asyncKind()); - Node body = functionBody(inHandling, bodyYieldHandling, kind, bodyType); - if (!body) - return false; + Node body; + { + AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, funbox->isAsync()); + body = functionBody(inHandling, bodyYieldHandling, kind, bodyType); + if (!body) + return false; + } - if ((kind != Method && !IsConstructorKind(kind)) && fun->explicitName()) { + if ((kind == Statement || kind == Expression) && fun->explicitName()) { RootedPropertyName propertyName(context, fun->explicitName()->asPropertyName()); - // `await` cannot be checked at this point because of different context. - // It should already be checked before this point. - if (propertyName != context->names().await) { - YieldHandling nameYieldHandling; - if (kind == Expression) { - // Named lambda has binding inside it. - nameYieldHandling = bodyYieldHandling; - } else { - // Otherwise YieldHandling cannot be checked at this point - // because of different context. - // It should already be checked before this point. - nameYieldHandling = YieldIsName; - } + YieldHandling nameYieldHandling; + if (kind == Expression) { + // Named lambda has binding inside it. + nameYieldHandling = bodyYieldHandling; + } else { + // Otherwise YieldHandling cannot be checked at this point + // because of different context. + // It should already be checked before this point. + nameYieldHandling = YieldIsName; + } - if (!checkBindingIdentifier(propertyName, handler.getPosition(pn).begin, - nameYieldHandling)) - { - return false; - } + // We already use the correct await-handling at this point, therefore + // we don't need call AutoAwaitIsKeyword here. + + if (!checkBindingIdentifier(propertyName, handler.getPosition(pn).begin, + nameYieldHandling)) + { + return false; } } |