diff options
author | Lars Knoll <lars.knoll@digia.com> | 2012-11-26 23:26:39 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@digia.com> | 2012-11-27 11:51:28 +0100 |
commit | b32c10a8d36aef52c38ad8b51cef33c100c8df9e (patch) | |
tree | ba8c937b55d09d4b1ab85631161338bd7acfb630 /qv4codegen.cpp | |
parent | 102aff16a896e2e237a00843731e84ef3d824b25 (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.cpp | 25 |
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(); |