summaryrefslogtreecommitdiffstats
path: root/js/src
diff options
context:
space:
mode:
Diffstat (limited to 'js/src')
-rw-r--r--js/src/frontend/Parser.cpp138
-rw-r--r--js/src/frontend/Parser.h5
2 files changed, 70 insertions, 73 deletions
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index 9b057fb72..560dc5ec8 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -975,44 +975,6 @@ ParserBase::isValidStrictBinding(PropertyName* name)
}
/*
- * Check that it is permitted to introduce a binding for |name|. Use |pos| for
- * reporting error locations.
- */
-template <typename ParseHandler>
-bool
-Parser<ParseHandler>::checkStrictBinding(PropertyName* name, TokenPos pos)
-{
- if (!pc->sc()->needStrictChecks())
- return true;
-
- if (name == context->names().arguments)
- return strictModeErrorAt(pos.begin, JSMSG_BAD_BINDING, "arguments");
-
- if (name == context->names().eval)
- return strictModeErrorAt(pos.begin, JSMSG_BAD_BINDING, "eval");
-
- if (name == context->names().let) {
- errorAt(pos.begin, JSMSG_RESERVED_ID, "let");
- return false;
- }
-
- if (name == context->names().static_) {
- errorAt(pos.begin, JSMSG_RESERVED_ID, "static");
- return false;
- }
-
- if (name == context->names().yield) {
- errorAt(pos.begin, JSMSG_RESERVED_ID, "yield");
- return false;
- }
-
- if (IsStrictReservedWord(name))
- return strictModeErrorAt(pos.begin, JSMSG_RESERVED_ID, ReservedWordToCharZ(name));
-
- return true;
-}
-
-/*
* Returns true if all parameter names are valid strict mode binding names and
* no duplicate parameter names are present.
*/
@@ -1094,9 +1056,6 @@ Parser<ParseHandler>::notePositionalFormalParameter(Node fn, HandlePropertyName
if (!paramNode)
return false;
- if (!checkStrictBinding(name, pos()))
- return false;
-
handler.addFunctionFormalParameter(fn, paramNode);
return true;
}
@@ -1357,9 +1316,6 @@ Parser<ParseHandler>::noteDeclaredName(HandlePropertyName name, DeclarationKind
if (pc->useAsmOrInsideUseAsm())
return true;
- if (!checkStrictBinding(name, pos))
- return false;
-
switch (kind) {
case DeclarationKind::Var:
case DeclarationKind::BodyLevelFunction:
@@ -3608,8 +3564,26 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling,
if ((kind != Method && !IsConstructorKind(kind)) && fun->explicitName()) {
RootedPropertyName propertyName(context, fun->explicitName()->asPropertyName());
- if (!checkStrictBinding(propertyName, handler.getPosition(pn)))
- return false;
+ // `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;
+ }
+
+ if (!checkBindingIdentifier(propertyName, handler.getPosition(pn).begin,
+ nameYieldHandling))
+ {
+ return false;
+ }
+ }
}
if (bodyType == StatementListBody) {
@@ -4178,6 +4152,9 @@ Parser<FullParseHandler>::checkDestructuringName(ParseNode* expr, Maybe<Declarat
}
RootedPropertyName name(context, expr->name());
+ // `yield` is already checked, so pass YieldIsName to skip that check.
+ if (!checkBindingIdentifier(name, expr->pn_pos.begin, YieldIsName))
+ return false;
return noteDeclaredName(name, *maybeDecl, expr->pn_pos);
}
@@ -8120,7 +8097,7 @@ Parser<ParseHandler>::comprehensionFor(GeneratorKind comprehensionKind)
// FIXME: Destructuring binding (bug 980828).
MUST_MATCH_TOKEN_FUNC(TokenKindIsPossibleIdentifier, JSMSG_NO_VARIABLE_NAME);
- RootedPropertyName name(context, tokenStream.currentName());
+ RootedPropertyName name(context, bindingIdentifier(YieldIsKeyword));
if (name == context->names().let) {
error(JSMSG_LET_COMP_BINDING);
return null();
@@ -8644,12 +8621,16 @@ Parser<ParseHandler>::checkLabelOrIdentifierReference(PropertyName* ident,
{
if (ident == context->names().yield) {
if (yieldHandling == YieldIsKeyword ||
- pc->sc()->strict() ||
versionNumber() >= JSVERSION_1_7)
{
errorAt(offset, JSMSG_RESERVED_ID, "yield");
return nullptr;
}
+ if (pc->sc()->needStrictChecks()) {
+ if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "yield"))
+ return nullptr;
+ }
+
return ident;
}
@@ -8671,20 +8652,49 @@ Parser<ParseHandler>::checkLabelOrIdentifierReference(PropertyName* ident,
return nullptr;
}
- if (pc->sc()->strict()) {
+ if (pc->sc()->needStrictChecks()) {
if (IsStrictReservedWord(ident)) {
- errorAt(offset, JSMSG_RESERVED_ID, ReservedWordToCharZ(ident));
- return nullptr;
+ if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, ReservedWordToCharZ(ident)))
+ return nullptr;
+ return ident;
}
if (ident == context->names().let) {
- errorAt(offset, JSMSG_RESERVED_ID, "let");
- return nullptr;
+ if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "let"))
+ return nullptr;
+ return ident;
}
if (ident == context->names().static_) {
- errorAt(offset, JSMSG_RESERVED_ID, "static");
- return nullptr;
+ if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "static"))
+ return nullptr;
+ return ident;
+ }
+ }
+
+ return ident;
+}
+
+template <typename ParseHandler>
+PropertyName*
+Parser<ParseHandler>::checkBindingIdentifier(PropertyName* ident,
+ uint32_t offset,
+ YieldHandling yieldHandling)
+{
+ if (!checkLabelOrIdentifierReference(ident, offset, yieldHandling))
+ return nullptr;
+
+ if (pc->sc()->needStrictChecks()) {
+ if (ident == context->names().arguments) {
+ if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "arguments"))
+ return nullptr;
+ return ident;
+ }
+
+ if (ident == context->names().eval) {
+ if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "eval"))
+ return nullptr;
+ return ident;
}
}
@@ -8709,23 +8719,7 @@ template <typename ParseHandler>
PropertyName*
Parser<ParseHandler>::bindingIdentifier(YieldHandling yieldHandling)
{
- PropertyName* ident = labelOrIdentifierReference(yieldHandling);
- if (!ident)
- return nullptr;
-
- if (pc->sc()->strict()) {
- if (ident == context->names().arguments) {
- error(JSMSG_BAD_STRICT_ASSIGN, "arguments");
- return nullptr;
- }
-
- if (ident == context->names().eval) {
- error(JSMSG_BAD_STRICT_ASSIGN, "eval");
- return nullptr;
- }
- }
-
- return ident;
+ return checkBindingIdentifier(tokenStream.currentName(), pos().begin, yieldHandling);
}
template <typename ParseHandler>
diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h
index 9ec862d92..d53a64eeb 100644
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -1335,6 +1335,10 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
uint32_t offset,
YieldHandling yieldHandling);
+ PropertyName* checkBindingIdentifier(PropertyName* ident,
+ uint32_t offset,
+ YieldHandling yieldHandling);
+
PropertyName* labelOrIdentifierReference(YieldHandling yieldHandling);
PropertyName* labelIdentifier(YieldHandling yieldHandling) {
@@ -1404,7 +1408,6 @@ class Parser final : public ParserBase, private JS::AutoGCRooter
private:
bool checkIncDecOperand(Node operand, uint32_t operandOffset);
bool checkStrictAssignment(Node lhs);
- bool checkStrictBinding(PropertyName* name, TokenPos pos);
bool hasValidSimpleStrictParameterNames();