aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2017-06-13 22:51:51 +0200
committerLars Knoll <lars.knoll@qt.io>2017-06-20 09:46:45 +0000
commit8776da68f53afe7e2f5cb50a242aa97a80383b43 (patch)
tree82fbca31bf3e946bbedb94f3fbe2d370182e5c10 /src/qml
parent0cb56e810c587de469ee483bfbaafb325c871930 (diff)
Implement support for conditional expressions
Change-Id: Ifcd57713e1cfa9514d3955e26f739a359cdaa8e5 Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/qv4bytecodegenerator.cpp7
-rw-r--r--src/qml/compiler/qv4bytecodegenerator_p.h15
-rw-r--r--src/qml/compiler/qv4codegen.cpp44
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp16
4 files changed, 44 insertions, 38 deletions
diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp
index 0073cb4598..444d8385d4 100644
--- a/src/qml/compiler/qv4bytecodegenerator.cpp
+++ b/src/qml/compiler/qv4bytecodegenerator.cpp
@@ -70,12 +70,15 @@ QByteArray BytecodeGenerator::finalize()
}
// resolve jumps
+// qDebug() << "resolving jumps";
for (const auto &j : jumps) {
Q_ASSERT(j.linkedInstruction != -1);
int offset = instructionOffsets.at(j.instructionIndex) + j.offset;
+// qDebug() << "offset data is at" << offset;
char *c = code.data() + offset;
- int linkedInstruction = instructionOffsets.at(j.linkedInstruction) - offset;
- memcpy(c, &linkedInstruction, sizeof(int));
+ ptrdiff_t linkedInstruction = instructionOffsets.at(j.linkedInstruction) - offset;
+// qDebug() << "linked instruction" << j.linkedInstruction << "at " << instructionOffsets.at(j.linkedInstruction);
+ memcpy(c, &linkedInstruction, sizeof(ptrdiff_t));
}
return code;
diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h
index 5c7480fc89..384fb22aa3 100644
--- a/src/qml/compiler/qv4bytecodegenerator_p.h
+++ b/src/qml/compiler/qv4bytecodegenerator_p.h
@@ -92,26 +92,33 @@ public:
addInstructionHelper(InstrMeta<InstrT>::Size, genericInstr);
}
- Q_REQUIRED_RESULT Jump addInstruction(const Instruction::Jump &data)
+ Q_REQUIRED_RESULT Jump jump()
{
+ Instruction::Jump data;
return addJumpInstruction(data);
}
- Q_REQUIRED_RESULT Jump addInstruction(const Instruction::SetExceptionHandler &data)
+ Q_REQUIRED_RESULT Jump jumpEq(const QV4::Moth::Param &cond)
{
+ Instruction::JumpEq data;
+ data.condition = cond;
return addJumpInstruction(data);
}
- Q_REQUIRED_RESULT Jump addInstruction(const Instruction::JumpEq &data)
+ Q_REQUIRED_RESULT Jump jumpNe(const QV4::Moth::Param &cond)
{
+ Instruction::JumpNe data;
+ data.condition = cond;
return addJumpInstruction(data);
}
- Q_REQUIRED_RESULT Jump addInstruction(const Instruction::JumpNe &data)
+ Q_REQUIRED_RESULT Jump setExceptionHandler()
{
+ Instruction::SetExceptionHandler data;
return addJumpInstruction(data);
}
+
unsigned newTemp();
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 921556ddf8..b16d28518d 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1638,32 +1638,26 @@ bool Codegen::visit(ConditionalExpression *ast)
if (hasError)
return true;
- IR::BasicBlock *iftrue = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *iffalse = _function->newBasicBlock(exceptionHandler());
- IR::BasicBlock *endif = _function->newBasicBlock(exceptionHandler());
-
const unsigned t = _block->newTemp();
+ _expr = Reference::fromTemp(this, t);
+
TempScope scope(_function);
- condition(ast->expression, iftrue, iffalse);
+ Reference r = expression(ast->expression);
- _block = iftrue;
- Result ok = expression(ast->ok);
- if (hasError)
- return false;
- move(_block->TEMP(t), *ok);
- _block->JUMP(endif);
+ // ### handle const Reference
- _block = iffalse;
- Result ko = expression(ast->ko);
- if (hasError)
- return false;
- move(_block->TEMP(t), *ko);
- _block->JUMP(endif);
+ Moth::BytecodeGenerator::Jump jump_else = bytecodeGenerator->jumpNe(r.asRValue());
- _block = endif;
+ _expr.result.store(expression(ast->ok));
- _expr.code = _block->TEMP(t);
+ Moth::BytecodeGenerator::Jump jump_endif = bytecodeGenerator->jump();
+
+ jump_else.link();
+
+ _expr.result.store(expression(ast->ko));
+
+ jump_endif.link();
return false;
}
@@ -1723,11 +1717,7 @@ bool Codegen::visit(FalseLiteral *)
if (hasError)
return false;
- if (_expr.accept(cx)) {
- _block->JUMP(_expr.iffalse);
- } else {
- _expr.result = Reference::fromConst(this, QV4::Encode(false));
- }
+ _expr.result = Reference::fromConst(this, QV4::Encode(false));
return false;
}
@@ -2264,11 +2254,7 @@ bool Codegen::visit(TrueLiteral *)
if (hasError)
return false;
- if (_expr.accept(cx)) {
- _block->JUMP(_expr.iftrue);
- } else {
- _expr.result = Reference::fromConst(this, QV4::Encode(false));
- }
+ _expr.result = Reference::fromConst(this, QV4::Encode(true));
return false;
}
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index e1a6a4395c..33ca111bf1 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -59,6 +59,16 @@ QByteArray alignedNumber(int n) {
return number;
}
+QString toString(QV4::ReturnedValue v)
+{
+#ifdef V4_BOOTSTRAP
+ return QStringLiteral("string-const(%1)").arg(v);
+#else // !V4_BOOTSTRAP
+ Value val = Value::fromReturnedValue(v);
+ return QLatin1String("const(") + val.toQStringNoThrow() + QLatin1String(")");
+#endif // V4_BOOTSTRAP
+}
+
#define MOTH_BEGIN_INSTR(I) \
case Instr::I: {\
const InstrMeta<(int)Instr::I>::DataType &instr = InstrMeta<(int)Instr::I>::data(*genericInstr); \
@@ -104,7 +114,7 @@ void dumpBytecode(const char *code, int len)
MOTH_END_INSTR(Move)
MOTH_BEGIN_INSTR(MoveConst)
- d << instr.result << ", " << instr.source;
+ d << instr.result << ", " << toString(instr.source).toUtf8().constData();
MOTH_END_INSTR(MoveConst)
MOTH_BEGIN_INSTR(SwapTemps)
@@ -349,11 +359,11 @@ void dumpBytecode(const char *code, int len)
MOTH_END_INSTR(Jump)
MOTH_BEGIN_INSTR(JumpEq)
- d << instr.offset;
+ d << instr.condition << " " << instr.offset;
MOTH_END_INSTR(JumpEq)
MOTH_BEGIN_INSTR(JumpNe)
- d << instr.offset;
+ d << instr.condition << " " << instr.offset;
MOTH_END_INSTR(JumpNe)
MOTH_BEGIN_INSTR(UNot)