aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;
};
};