[Webkit-unassigned] [Bug 27226] Possibly faulty handling of function statements enclosed in other statements (i.e. block, if, etc). JavaScriptCore test ecma_3/FunExpr/fe-001.js failed.

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Fri Feb 10 12:54:18 PST 2012


https://bugs.webkit.org/show_bug.cgi?id=27226


Oliver Hunt <oliver at apple.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID




--- Comment #4 from Oliver Hunt <oliver at apple.com>  2012-02-10 12:54:17 PST ---
Alas this is one of those icky bits in ecmascript, where we have been unable to define a common set of semantics for nested functions (they're prohibited in strict mode).

This is behaviour we can't change, but the basic problem is that the grammar does not _allow_ nested function statements.  Alas as with so many things in ES a few implementation bugs crept into an implementation that allowed nested function statements.  This was then picked up in various ways by the various JS engines (sans V8, which targeted bug-for-bug compat with JSC, at least initially).

So once you allow nested function statements you hit a "fun" problem.  The ES spec defines the behaviour of a function statement as being hoisted to the head of the function code.  Although a function declaration is similar to a var declaration (in the sense that they're both simply defining a variable with a local environment binding) function declarations are expected to hoist the definition as well.  That allows code like this to work:

f();
function f() { alert("yay!") }

But if you nest the function statement in a new scope (with(), catch(), etc) you get an interesting problem:
When you go to initialize the function the scope chain for the function isn't there yet.  So you can either break spec (again) and delay function initialization in that case (which i assume SM must do) or you accept that like so much else in ES, you should _ignore_ lexical scope.  Some engines do it one way, some do it the other (and there may even be an additional set of idiosyncrasies in another engine).

We tried to standardize this in TC39 (the ES standardization committee), but realized that the behaviors are mutually incompatible, that there is no differing semantic that is mutually compatible, and that there are sites that depend (hilariously) on the different implementations in order to work correctly, eg.

if (somethingThatIsTrueInMozillaAndWebKit())
    function foo() { somethingThatOnlyWorksInMozilla(); }
else
    function foo() { somethingThatWorksInIEAndWebKit(); }

In Mozilla this would work as expected (due to SM function statement semantics), it works in IE and WebKit because the second definition of foo() overwrites the first.  The real killer is that WebKit gets the second function, even though it ostensibly executes the true part of the if() statement.

The net result is that if IE and Webkit picked up the SM behaviour, this site would stop working in webkit but still work in IE and Mozilla.  If Mozilla moves to the behaviour of IE and WebKit this site will stop working in Mozilla (as they'll get the second IE/WebKit only function instead of the mozilla one).  There are alternative pieces of code that would work in both mozilla and webkit while breaking IE (WebKit is a chameleon, due to the large amounts of IE and Firefox specific code that exists we've got lots of the "features" of both of them so can run some "IE" only content and some "Mozilla" only content).

The end result was the realization that we simply could not standardize this behaviour, and so the ES5.1 spec now specifically calls out nested functions as being a place where there are dragons, and explicitly disallows them in strict mode.

-- 
Configure bugmail: https://bugs.webkit.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are the assignee for the bug.



More information about the webkit-unassigned mailing list