diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2013-03-20 14:53:27 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@digia.com> | 2013-03-21 22:43:26 +0100 |
commit | 96ef0e4010b1be01a7b89c136ae9c518eb8492db (patch) | |
tree | 29c024d1b09bca8bd92beeb8ea4811df13d19ac3 /src | |
parent | 4c0166323c440ea05d1bd817ef6812c08968f792 (diff) |
Fix shadowing of arguments through local variables
The declaration binding instantiation paragraph in the spec (10.5) says that
the formal parameters are entered into the environment before anything else.
Later when processing the variable declarations, CreateMutableBinding and
SetMutableBinding is only called if the HasBinding return false. That means in
the following example the "var foo" declaration does not have any effect, not
even setting foo to undefined:
function fun(foo) {
var foo;
return foo;
}
fun("a") === "a"
This patch implements this behaviour at compile-time by ensuring that no formal
parameter can be entered as member into the environment and thus writes to
these variables will overwrite the parameter values only.
This also advances execution on the EarleyBoyer benchmarks a little further,
which tries to re-declare a lot of parameters again as local variables.
Change-Id: Ic12d71fd39caa44169fc4b62526f03078c2513c4
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/v4/qv4codegen.cpp | 1 | ||||
-rw-r--r-- | src/v4/qv4codegen_p.h | 6 |
2 files changed, 7 insertions, 0 deletions
diff --git a/src/v4/qv4codegen.cpp b/src/v4/qv4codegen.cpp index c73b58a5b9..1aa73be267 100644 --- a/src/v4/qv4codegen.cpp +++ b/src/v4/qv4codegen.cpp @@ -957,6 +957,7 @@ private: checkForArguments(formals); _env->isNamedFunctionExpression = isExpression && !name.isEmpty(); + _env->formals = formals; if (body) checkDirectivePrologue(body->elements); diff --git a/src/v4/qv4codegen_p.h b/src/v4/qv4codegen_p.h index a3ba261347..e150c75d02 100644 --- a/src/v4/qv4codegen_p.h +++ b/src/v4/qv4codegen_p.h @@ -44,6 +44,7 @@ #include "qv4global.h" #include "qv4jsir_p.h" #include <private/qqmljsastvisitor_p.h> +#include <private/qqmljsast_p.h> #include <QtCore/QStringList> #include <assert.h> @@ -144,6 +145,7 @@ protected: typedef QMap<QString, Member> MemberMap; MemberMap members; + AST::FormalParameterList *formals; int maxNumberOfArguments; bool hasDirectEval; bool hasNestedFunctions; @@ -159,6 +161,7 @@ protected: Environment(Environment *parent) : parent(parent) + , formals(0) , maxNumberOfArguments(0) , hasDirectEval(false) , hasNestedFunctions(false) @@ -197,6 +200,9 @@ protected: void enter(const QString &name, MemberType type, AST::FunctionExpression *function = 0) { if (! name.isEmpty()) { + for (AST::FormalParameterList *it = formals; it; it = it->next) + if (it->name == name) + return; MemberMap::iterator it = members.find(name); if (it == members.end()) { Member m; |