aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4codegen.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2013-10-11 13:50:23 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-10-11 19:38:47 +0200
commit6adb0693a2e408c388a0939e0a3d711da7b651df (patch)
tree3f7a2c2d1cf53d8079f5ac8c2e4c6e4e11d69edf /src/qml/compiler/qv4codegen.cpp
parenta4449295c3051e42b1aa80a1c7cc91671ad05765 (diff)
Fix determination of lookup mode in V4 code generator
In order to determine the type of lookup we need (name or directly in environment members), we used Codegen::_mode, which is set to the currently suitable mode depending on the function (parameter to defineFunction). However that's not quite correct, the look-up mode depends on the function itself, not where it was called from. This patch corrects that by moving the compilation mode into the Environment itself. This is needed by follow-up patches. Additionally the "bool deletable" parameter to the builtin_declare_vars was always set to false, because it used mode instead of _mode, which was never set to Eval or QmlBinding. This will be cleaned up in a future patch. Change-Id: I878f187945e5de091689ab5d70a0f33eb5a9e38f Reviewed-by: Lars Knoll <lars.knoll@digia.com>
Diffstat (limited to 'src/qml/compiler/qv4codegen.cpp')
-rw-r--r--src/qml/compiler/qv4codegen.cpp46
1 files changed, 20 insertions, 26 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 94562ead7f..1f1ed42530 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -64,11 +64,12 @@
using namespace QQmlJS;
using namespace AST;
-Codegen::ScanFunctions::ScanFunctions(Codegen *cg, const QString &sourceCode)
+Codegen::ScanFunctions::ScanFunctions(Codegen *cg, const QString &sourceCode, CompilationMode defaultProgramMode)
: _cg(cg)
, _sourceCode(sourceCode)
, _env(0)
, _allowFuncDecls(true)
+ , defaultProgramMode(defaultProgramMode)
{
}
@@ -78,9 +79,9 @@ void Codegen::ScanFunctions::operator()(Node *node)
node->accept(this);
}
-void Codegen::ScanFunctions::enterEnvironment(Node *node)
+void Codegen::ScanFunctions::enterEnvironment(Node *node, CompilationMode compilationMode)
{
- Environment *e = _cg->newEnvironment(node, _env);
+ Environment *e = _cg->newEnvironment(node, _env, compilationMode);
if (!e->isStrict)
e->isStrict = _cg->_strictMode;
_envStack.append(e);
@@ -146,7 +147,7 @@ void Codegen::ScanFunctions::checkForArguments(AST::FormalParameterList *paramet
bool Codegen::ScanFunctions::visit(Program *ast)
{
- enterEnvironment(ast);
+ enterEnvironment(ast, defaultProgramMode);
checkDirectivePrologue(ast->elements);
return true;
}
@@ -374,7 +375,7 @@ void Codegen::ScanFunctions::enterFunction(Node *ast, const QString &name, Forma
wasStrict = _env->isStrict;
}
- enterEnvironment(ast);
+ enterEnvironment(ast, FunctionCode);
checkForArguments(formals);
_env->isNamedFunctionExpression = isExpression && !name.isEmpty();
@@ -404,7 +405,6 @@ Codegen::Codegen(bool strict)
, _exitBlock(0)
, _throwBlock(0)
, _returnAddress(0)
- , _mode(GlobalCode)
, _env(0)
, _loop(0)
, _labelledStatement(0)
@@ -417,7 +417,7 @@ V4IR::Function *Codegen::generateFromProgram(const QString &fileName,
const QString &sourceCode,
Program *node,
V4IR::Module *module,
- Mode mode,
+ CompilationMode mode,
const QStringList &inheritedLocals)
{
assert(node);
@@ -427,11 +427,11 @@ V4IR::Function *Codegen::generateFromProgram(const QString &fileName,
_module->setFileName(fileName);
- ScanFunctions scan(this, sourceCode);
+ ScanFunctions scan(this, sourceCode, mode);
scan(node);
V4IR::Function *globalCode = defineFunction(QStringLiteral("%entry"), node, 0,
- node->elements, mode, inheritedLocals);
+ node->elements, inheritedLocals);
qDeleteAll(_envMap);
_envMap.clear();
@@ -447,9 +447,9 @@ V4IR::Function *Codegen::generateFromFunctionExpression(const QString &fileName,
_module->setFileName(fileName);
_env = 0;
- ScanFunctions scan(this, sourceCode);
+ ScanFunctions scan(this, sourceCode, GlobalCode);
// fake a global environment
- scan.enterEnvironment(0);
+ scan.enterEnvironment(0, FunctionCode);
scan(ast);
scan.leaveEnvironment();
@@ -804,7 +804,7 @@ void Codegen::variableDeclaration(VariableDeclaration *ast)
assert(expr.code);
initializer = *expr;
- if (! _env->parent || _function->insideWithOrCatch || _mode == QmlBinding) {
+ if (! _env->parent || _function->insideWithOrCatch || _env->compilationMode == QmlBinding) {
// it's global code.
move(_block->NAME(ast->name.toString(), ast->identifierToken.startLine, ast->identifierToken.startColumn), initializer);
} else {
@@ -1355,10 +1355,7 @@ V4IR::Expr *Codegen::identifier(const QString &name, int line, int col)
Environment *e = _env;
V4IR::Function *f = _function;
- if (_mode == QmlBinding)
- return _block->NAME(name, line, col);
-
- while (f && e->parent) {
+ while (f && e->parent && e->compilationMode != QmlBinding) {
if (f->insideWithOrCatch || (f->isNamedExpression && f->name == name))
return _block->NAME(name, line, col);
@@ -1382,7 +1379,7 @@ V4IR::Expr *Codegen::identifier(const QString &name, int line, int col)
f = f->outer;
}
- if (!e->parent && (!f || !f->insideWithOrCatch) && _mode != EvalCode && _mode != QmlBinding)
+ if (!e->parent && (!f || !f->insideWithOrCatch) && e->compilationMode != EvalCode && e->compilationMode != QmlBinding)
return _block->GLOBALNAME(name, line, col);
// global context or with. Lookup by name
@@ -1752,7 +1749,7 @@ bool Codegen::visit(VoidExpression *ast)
bool Codegen::visit(FunctionDeclaration * ast)
{
- if (_mode == QmlBinding)
+ if (_env->compilationMode == QmlBinding)
move(_block->TEMP(_returnAddress), _block->NAME(ast->name.toString(), 0, 0));
_expr.accept(nx);
return false;
@@ -1760,10 +1757,9 @@ bool Codegen::visit(FunctionDeclaration * ast)
V4IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast,
AST::FormalParameterList *formals,
- AST::SourceElements *body, Mode mode,
+ AST::SourceElements *body,
const QStringList &inheritedLocals)
{
- qSwap(_mode, mode); // enter function code.
Loop *loop = 0;
qSwap(_loop, loop);
@@ -1789,7 +1785,7 @@ V4IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast,
_env->enter("arguments", Environment::VariableDeclaration);
// variables in global code are properties of the global context object, not locals as with other functions.
- if (_mode == FunctionCode) {
+ if (_env->compilationMode == FunctionCode) {
unsigned t = 0;
for (Environment::MemberMap::iterator it = _env->members.begin(); it != _env->members.end(); ++it) {
const QString &local = it.key();
@@ -1819,7 +1815,7 @@ V4IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast,
}
if (args) {
V4IR::ExprList *next = function->New<V4IR::ExprList>();
- next->expr = entryBlock->CONST(V4IR::BoolType, (mode == EvalCode || mode == QmlBinding));
+ next->expr = entryBlock->CONST(V4IR::BoolType, false); // ### Investigate removal of bool deletable
next->next = args;
args = next;
@@ -1882,8 +1878,6 @@ V4IR::Function *Codegen::defineFunction(const QString &name, AST::Node *ast,
leaveEnvironment();
- qSwap(_mode, mode);
-
return function;
}
@@ -2008,7 +2002,7 @@ bool Codegen::visit(EmptyStatement *)
bool Codegen::visit(ExpressionStatement *ast)
{
- if (_mode == EvalCode || _mode == QmlBinding) {
+ if (_env->compilationMode == EvalCode || _env->compilationMode == QmlBinding) {
Result e = expression(ast->expression);
if (*e)
move(_block->TEMP(_returnAddress), *e);
@@ -2217,7 +2211,7 @@ bool Codegen::visit(LocalForStatement *ast)
bool Codegen::visit(ReturnStatement *ast)
{
- if (_mode != FunctionCode && _mode != QmlBinding)
+ if (_env->compilationMode != FunctionCode && _env->compilationMode != QmlBinding)
throwSyntaxError(ast->returnToken, QCoreApplication::translate("qv4codegen", "Return statement outside of function"));
if (ast->expression) {
Result expr = expression(ast->expression);