aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
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
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')
-rw-r--r--src/qml/compiler/qqmlcodegenerator.cpp12
-rw-r--r--src/qml/compiler/qqmlcodegenerator_p.h4
-rw-r--r--src/qml/compiler/qv4codegen.cpp46
-rw-r--r--src/qml/compiler/qv4codegen_p.h20
4 files changed, 39 insertions, 43 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp
index fb2ca7c14e..83f3dfe84a 100644
--- a/src/qml/compiler/qqmlcodegenerator.cpp
+++ b/src/qml/compiler/qqmlcodegenerator.cpp
@@ -1161,20 +1161,20 @@ void JSCodeGen::generateJSCodeForFunctionsAndBindings(const QString &fileName, P
_module->setFileName(fileName);
QmlScanner scan(this, output->code);
- scan.begin(output->program);
+ scan.begin(output->program, QmlBinding);
foreach (AST::Node *node, output->functions) {
if (node == output->program)
continue;
AST::FunctionDeclaration *function = AST::cast<AST::FunctionDeclaration*>(node);
- scan.enterEnvironment(node);
+ scan.enterEnvironment(node, function ? FunctionCode : QmlBinding);
scan(function ? function->body : node);
scan.leaveEnvironment();
}
scan.end();
_env = 0;
- _function = defineFunction(QString("context scope"), output->program, 0, 0, QmlBinding);
+ _function = defineFunction(QString("context scope"), output->program, 0, 0);
foreach (AST::Node *node, output->functions) {
if (node == output->program)
@@ -1201,7 +1201,7 @@ void JSCodeGen::generateJSCodeForFunctionsAndBindings(const QString &fileName, P
defineFunction(name, node,
function ? function->formals : 0,
- body, function ? FunctionCode : QmlBinding);
+ body);
}
@@ -1210,9 +1210,9 @@ void JSCodeGen::generateJSCodeForFunctionsAndBindings(const QString &fileName, P
}
-void JSCodeGen::QmlScanner::begin(AST::Node *rootNode)
+void JSCodeGen::QmlScanner::begin(AST::Node *rootNode, CompilationMode compilationMode)
{
- enterEnvironment(0);
+ enterEnvironment(0, compilationMode);
enterFunction(rootNode, "context scope", 0, 0, 0, /*isExpression*/false);
}
diff --git a/src/qml/compiler/qqmlcodegenerator_p.h b/src/qml/compiler/qqmlcodegenerator_p.h
index ec75c38160..09faec2374 100644
--- a/src/qml/compiler/qqmlcodegenerator_p.h
+++ b/src/qml/compiler/qqmlcodegenerator_p.h
@@ -341,11 +341,11 @@ private:
struct QmlScanner : public ScanFunctions
{
QmlScanner(JSCodeGen *cg, const QString &sourceCode)
- : ScanFunctions(cg, sourceCode)
+ : ScanFunctions(cg, sourceCode, /*default program mode*/GlobalCode)
, codeGen(cg)
{}
- void begin(AST::Node *rootNode);
+ void begin(AST::Node *rootNode, CompilationMode compilationMode);
void end();
JSCodeGen *codeGen;
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);
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index ea32b5b349..2da65fae79 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -68,7 +68,7 @@ class Q_QML_EXPORT Codegen: protected AST::Visitor
public:
Codegen(bool strict);
- enum Mode {
+ enum CompilationMode {
GlobalCode,
EvalCode,
FunctionCode,
@@ -79,7 +79,7 @@ public:
const QString &sourceCode,
AST::Program *ast,
V4IR::Module *module,
- Mode mode = GlobalCode,
+ CompilationMode mode = GlobalCode,
const QStringList &inheritedLocals = QStringList());
V4IR::Function *generateFromFunctionExpression(const QString &fileName,
const QString &sourceCode,
@@ -153,7 +153,9 @@ protected:
UsesArgumentsObject usesArgumentsObject;
- Environment(Environment *parent)
+ CompilationMode compilationMode;
+
+ Environment(Environment *parent, CompilationMode mode)
: parent(parent)
, formals(0)
, maxNumberOfArguments(0)
@@ -162,6 +164,7 @@ protected:
, isStrict(false)
, isNamedFunctionExpression(false)
, usesArgumentsObject(ArgumentsObjectUnknown)
+ , compilationMode(mode)
{
if (parent && parent->isStrict)
isStrict = true;
@@ -216,9 +219,9 @@ protected:
}
};
- Environment *newEnvironment(AST::Node *node, Environment *parent)
+ Environment *newEnvironment(AST::Node *node, Environment *parent, CompilationMode compilationMode)
{
- Environment *env = new Environment(parent);
+ Environment *env = new Environment(parent, compilationMode);
_envMap.insert(node, env);
return env;
}
@@ -283,7 +286,6 @@ protected:
V4IR::Function *defineFunction(const QString &name, AST::Node *ast,
AST::FormalParameterList *formals,
AST::SourceElements *body,
- Mode mode = FunctionCode,
const QStringList &inheritedLocals = QStringList());
void unwindException(ScopeAndFinally *outest);
@@ -427,7 +429,6 @@ protected:
V4IR::BasicBlock *_exitBlock;
V4IR::BasicBlock *_throwBlock;
unsigned _returnAddress;
- Mode _mode;
Environment *_env;
Loop *_loop;
AST::LabelledStatement *_labelledStatement;
@@ -442,10 +443,10 @@ protected:
{
typedef QV4::TemporaryAssignment<bool> TemporaryBoolAssignment;
public:
- ScanFunctions(Codegen *cg, const QString &sourceCode);
+ ScanFunctions(Codegen *cg, const QString &sourceCode, CompilationMode defaultProgramMode);
void operator()(AST::Node *node);
- void enterEnvironment(AST::Node *node);
+ void enterEnvironment(AST::Node *node, CompilationMode compilationMode);
void leaveEnvironment();
protected:
@@ -500,6 +501,7 @@ protected:
QStack<Environment *> _envStack;
bool _allowFuncDecls;
+ CompilationMode defaultProgramMode;
};
};