Lexical scoping of 'function' in sloppy mode breaks legal ES5

Andreas Rossberg rossberg at google.com
Tue Aug 20 04:13:07 PDT 2013


On 20 August 2013 10:54, André Bargull <andre.bargull at udo.edu> wrote:
> Andreas Rossberg wrote:
>> On 19 August 2013 19:02, Allen Wirfs-Brock <allen at wirfs-brock.com> wrote:
>>>
>>> On Aug 19, 2013, at 8:38 AM, Andreas Rossberg wrote:
>>>
>>>> While debugging a V8 issue I just realised another incompatibility
>>>> with introducing lexical function declarations in sloppy mode that I
>>>> think we haven't observed yet. Consider the following code:
>>>>
>>>> function f() {
>>>>  var x = 0
>>>>  try {
>>>>    throw 1
>>>>  } catch (x) {
>>>>    eval("function g() { return x }")
>>>>  }
>>>>  return g()
>>>> }
>>>>
>>>> This function is legal, and supposed to return 1 according to my
>>>> reading of the ES5 spec.
>>>
>>> I don't think so.  according to ES5 10.4.2 The VariableEnvironment of the
>>> eval'ed code should be set to the VariableEnvironment of the calling
>>> context.  That variable environment is the outer cope of function f that has
>>> 0 as the value of its x binding. When g is instantiated that variable
>>> environment will be its [[Scope]] so "return x" should return 0.
>>
>> You are right, although the discrepancy between FunctionExpression and
>> FunctionDeclaration feels really odd -- I wonder how that came about.
>> It also means that both Firefox and Safari handle the example
>> incorrectly (though at least they don't crash :) ).
>
> This difference was introduced between 8. Dec. 2008 and 15. Dec. 2008, in
> the earlier drafts both, function declarations and function expressions,
> used the LexicalEnvironment of the running execution context for their
> [[Scope]]. And this is also what ES3 specified ("Pass in the scope chain of
> the running execution context as the Scope."). So maybe this is just another
> bug in the ES5 specification?

I tend to agree that this particular detail should be considered a
spec bug. As far as I can tell, examples like the above are the only
way one can actually tell the difference in proper ES5, and it seems
rather wrong there. In all other contexts allowing function
declarations, Lexical- and VariableEnvironment are the same anyway.
Perhaps this change was made in vague anticipation of local function
declarations?

Either way, for ES6, this necessarily will change back again, since
otherwise lexical scoping for function declarations would be
completely broken. The current draft already does the equivalent
(modulo some major refactoring).

/Andreas


More information about the es-discuss mailing list