From b32c10a8d36aef52c38ad8b51cef33c100c8df9e Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 26 Nov 2012 23:26:39 +0100 Subject: 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 --- qv4codegen.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) (limited to 'qv4codegen.cpp') 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(); + next->expr = entryBlock->NAME(local, 0, 0); + next->next = args; + args = next; + } + if (args) { + IR::ExprList *next = function->New(); + 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(); -- cgit v1.2.3