Fix visibility of named function expressions in surrounding environment
authorSimon Hausmann <simon.hausmann@digia.com>
Fri, 10 May 2013 11:06:32 +0000 (13:06 +0200)
committerLars Knoll <lars.knoll@digia.com>
Fri, 10 May 2013 13:45:58 +0000 (15:45 +0200)
Quoting from the spec: "However, unlike in a FunctionDeclaration, the
Identifier in a FunctionExpression cannot be referenced from and does not
affect the scope enclosing the FunctionExpression."

This was visible in QML start-up when evaluating helper functions: "(function
foo() { ...})" was compiled and run in the global scope and the returned
funtcion expression is executed later on. However we incorrectly also ended up
entering "foo" as a name into the global scope (which it was executed in),
causing then for example "foo" to become part of the "illegal" names in QML.

The case at point was that qv8sequencewrapper.cpp evaluates a helper script
with a named function expression "compare" and then later the QML canvas
auto-test failed because somewhere it declared a JS function in the scope
of a QML item called "compare".

All tests still pass, we do handle the case of looking up the named function
already in qv4context.cpp (getProperty, etc.).

Change-Id: Id9daaff355ce35ae4bc96dcbaba9710cd8cc2211
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/qml/qml/v4/qv4codegen.cpp

index 9cfe50a..e5459c9 100644 (file)
@@ -977,7 +977,9 @@ private:
         bool wasStrict = false;
         if (_env) {
             _env->hasNestedFunctions = true;
-            _env->enter(name, Environment::FunctionDefinition, expr);
+            // The identifier of a function expression cannot be referenced from the enclosing environment.
+            if (expr)
+                _env->enter(name, Environment::FunctionDefinition, expr);
             if (name == QLatin1String("arguments"))
                 _env->usesArgumentsObject = Environment::ArgumentsObjectNotUsed;
             wasStrict = _env->isStrict;