1339137 - Don't do Annex B lexical function behavior.

This commit is contained in:
Fedor 2019-09-05 20:06:00 +03:00
parent c979d57203
commit f4a5088c68
4 changed files with 41 additions and 9 deletions

View File

@ -1211,6 +1211,25 @@ Parser<ParseHandler>::tryDeclareVarForAnnexBLexicalFunction(HandlePropertyName n
if (!tryDeclareVar(name, DeclarationKind::VarForAnnexBLexicalFunction, &redeclaredKind))
return false;
if (!redeclaredKind && pc->isFunctionBox()) {
ParseContext::Scope& funScope = pc->functionScope();
ParseContext::Scope& varScope = pc->varScope();
if (&funScope != &varScope) {
// Annex B.3.3.1 disallows redeclaring parameter names. In the
// presence of parameter expressions, parameter names are on the
// function scope, which encloses the var scope. This means
// tryDeclareVar call above would not catch this case, so test it
// manually.
if (AddDeclaredNamePtr p = funScope.lookupDeclaredNameForAdd(name)) {
DeclarationKind declaredKind = p->value()->kind();
if (DeclarationKindIsParameter(declaredKind))
redeclaredKind = Some(declaredKind);
else
MOZ_ASSERT(FunctionScope::isSpecialName(context, name));
}
}
}
if (redeclaredKind) {
// If an early error would have occurred, undo all the
// VarForAnnexBLexicalFunction declarations.
@ -1751,11 +1770,8 @@ Parser<FullParseHandler>::newFunctionScopeData(ParseContext::Scope& scope, bool
case BindingKind::Var:
// The only vars in the function scope when there are parameter
// exprs, which induces a separate var environment, should be the
// special internal bindings.
MOZ_ASSERT_IF(hasParameterExprs,
bi.name() == context->names().arguments ||
bi.name() == context->names().dotThis ||
bi.name() == context->names().dotGenerator);
// special bindings.
MOZ_ASSERT_IF(hasParameterExprs, FunctionScope::isSpecialName(context, bi.name()));
if (!vars.append(binding))
return Nothing();
break;

View File

@ -11,6 +11,11 @@
assertEq(f, 123);
}(123));
(function(f = 123) {
assertEq(f, 123);
{ function f() { } }
assertEq(f, 123);
}());
if (typeof reportCompare === "function")
reportCompare(true, true);

View File

@ -669,6 +669,14 @@ FunctionScope::script() const
return canonicalFunction()->nonLazyScript();
}
/* static */ bool
FunctionScope::isSpecialName(ExclusiveContext* cx, JSAtom* name)
{
return name == cx->names().arguments ||
name == cx->names().dotThis ||
name == cx->names().dotGenerator;
}
/* static */ Shape*
FunctionScope::getEmptyEnvironmentShape(ExclusiveContext* cx, bool hasParameterExprs)
{

View File

@ -446,10 +446,11 @@ Scope::is<LexicalScope>() const
}
//
// Scope corresponding to a function. Holds formal parameter names and, if the
// function parameters contain no expressions that might possibly be
// evaluated, the function's var bindings. For example, in these functions,
// the FunctionScope will store a/b/c bindings but not d/e/f bindings:
// Scope corresponding to a function. Holds formal parameter names, special
// internal names (see FunctionScope::isSpecialName), and, if the function
// parameters contain no expressions that might possibly be evaluated, the
// function's var bindings. For example, in these functions, the FunctionScope
// will store a/b/c bindings but not d/e/f bindings:
//
// function f1(a, b) {
// var c;
@ -562,6 +563,8 @@ class FunctionScope : public Scope
return data().nonPositionalFormalStart;
}
static bool isSpecialName(ExclusiveContext* cx, JSAtom* name);
static Shape* getEmptyEnvironmentShape(ExclusiveContext* cx, bool hasParameterExprs);
};