archives

« Bugzilla Issues Index

#4419 — 14.1.18 Wrong scoping of non-strict direct evals in ComputedPropertyNames in parameters


On Jul 8, 2015, at 12:25 PM, Kevin Gibbons wrote:

In the final ECMAScript 2015 spec, each function for which ContainsExpression of that function's [[FormalParameters]] internal slot is true has a scope object for its parameters. Additionally, these functions have a separate scope object under this one for each parameter that has an initializer. See 14.1.18 for the production "FormalParameter : BindingElement". The last sentence of this section states

The new Environment Record created in step 6 is only used if the BindElement’s Initializer contains a direct eval.

This is shown to be incorrect (aside from the "BindElement" typo) with the following program.

var x = "outer";
function f({ [eval('var x="inner"; "a";')]: y } = null) {
console.log(x);
}
f({a: "z"});

Because the presence of an initializer causes a new scope to be created, in which the entire BindingElement is evaluated, this should print "outer". Therefore, the scope is used any time there is a direct eval in BindingElement.

The intent, per the last sentence of 14.1.18 and bug 3383, is that direct evals in the parameter list cannot introduce new variables in the function's parameters scope mentioned earlier. However, non-strict direct evals can also occur in computed property names in parameters which do not have initializers

var x = "outer";
function f({ [eval("var x='inner'; 'a';")]: y }) {
console.log(x);
}
f({a: "z"});

Because the separate scope is not created if no initializer is present, this should print "inner".

Introducing an initializer, even an initializer which is just a simple value, causes a separate scope to be created. This is non-intuitive, and appears to be unintentional.

There are multiple ways that this behavior can be fixed

Create a new scope for each parameter, unconditionally
Create a new scope for parameters for which ContainsExpression is true, instead of just those that have an initializer
Define code in computed property names as strict code

The erroneous sentence at the end of section 14.1.18 may be fixed by replacing it with "The new Environment Record created in step 6 is only used if the BindElement contains a direct eval.".


This is an oversight, I forget about the possibility of computer property name expressions in a parameter position.

The appropriate fix is: Create a new scope for parameters for which ContainsExpression is true, instead of just those that have an initializer

this reflects what we originally intended.

Finally the sentence at the end should be converted to a NOTE in addition to the suggested change


Fixed in ES2016 Draft.