1339137 - Don't do Annex B lexical function behavior.
This commit is contained in:
parent
c979d57203
commit
f4a5088c68
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user