aboutsummaryrefslogtreecommitdiffstats
path: root/qv4codegen.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2012-11-26 23:26:39 +0100
committerErik Verbruggen <erik.verbruggen@digia.com>2012-11-27 11:51:28 +0100
commitb32c10a8d36aef52c38ad8b51cef33c100c8df9e (patch)
treeba8c937b55d09d4b1ab85631161338bd7acfb630 /qv4codegen.cpp
parent102aff16a896e2e237a00843731e84ef3d824b25 (diff)
Correctly instantiate variables in the local scope
This fixes cases where eval() would create variables in the wrong scope. Change-Id: Ie93ec2d1fb125e588c1b6ffa2ca8ca4b6e3112c9 Reviewed-by: Erik Verbruggen <erik.verbruggen@digia.com>
Diffstat (limited to 'qv4codegen.cpp')
-rw-r--r--qv4codegen.cpp25
1 files changed, 20 insertions, 5 deletions
diff --git a/qv4codegen.cpp b/qv4codegen.cpp
index cd4cbebb0a..e605e2493a 100644
--- a/qv4codegen.cpp
+++ b/qv4codegen.cpp
@@ -1517,15 +1517,30 @@ IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast,
function->maxNumberOfArguments = _env->maxNumberOfArguments;
// variables in global code are properties of the global context object, not locals as with other functions.
- for (int i = 0; i < _env->vars.size(); ++i) {
- const QString &local = _env->vars.at(i);
- if (!_env->parent) {
- entryBlock->MOVE(entryBlock->NAME(local, 0, 0), entryBlock->CONST(IR::UndefinedType, 0));
- } else {
+ if (_mode == FunctionCode) {
+ for (int i = 0; i < _env->vars.size(); ++i) {
+ const QString &local = _env->vars.at(i);
function->LOCAL(local);
unsigned t = entryBlock->newTemp();
assert(t == unsigned(i));
}
+ } else {
+ IR::ExprList *args = 0;
+ for (int i = 0; i < _env->vars.size(); ++i) {
+ const QString &local = _env->vars.at(i);
+ IR::ExprList *next = function->New<IR::ExprList>();
+ next->expr = entryBlock->NAME(local, 0, 0);
+ next->next = args;
+ args = next;
+ }
+ if (args) {
+ IR::ExprList *next = function->New<IR::ExprList>();
+ next->expr = entryBlock->CONST(IR::BoolType, mode == EvalCode);
+ next->next = args;
+ args = next;
+
+ entryBlock->EXP(entryBlock->CALL(entryBlock->NAME(IR::Name::builtin_declare_vars, 0, 0), args));
+ }
}
unsigned returnAddress = entryBlock->newTemp();