diff options
author | Maximilian Goldstein <max.goldstein@qt.io> | 2019-11-29 16:52:16 +0100 |
---|---|---|
committer | Maximilian Goldstein <max.goldstein@qt.io> | 2019-12-05 14:28:47 +0100 |
commit | 8fadf5d374936e50b8bce5adb1f10da2f66eac2b (patch) | |
tree | 9fa8808718e47673413980aa4448fe8d11dde0c7 /src/qml/compiler | |
parent | 79166592d17135309a070065e7cb947ffa293828 (diff) |
qml/parser: Implement nullish coalescing
Implements the '??' operator as specified in https://github.com/tc39/proposal-nullish-coalescing.
Also adds a few tests.
Task-number: QTBUG-77926
Change-Id: I3993450c192d11bf1ade0662d945c1553b4c6976
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index fff6a2fe4c..d61456f38d 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -1371,6 +1371,40 @@ bool Codegen::visit(BinaryExpression *ast) setExprResult(Reference::fromAccumulator(this)); } return false; + } else if (ast->op == QSOperator::Coalesce) { + + Reference left = expression(ast->left); + if (hasError()) + return false; + + BytecodeGenerator::Label iftrue = bytecodeGenerator->newLabel(); + BytecodeGenerator::Label iffalse = bytecodeGenerator->newLabel(); + + Instruction::CmpNeNull cmp; + + left = left.storeOnStack(); + left.loadInAccumulator(); + bytecodeGenerator->addInstruction(cmp); + + bytecodeGenerator->jumpTrue().link(iftrue); + bytecodeGenerator->jumpFalse().link(iffalse); + + blockTailCalls.unblock(); + + iftrue.link(); + + left.loadInAccumulator(); + + BytecodeGenerator::Jump jump_endif = bytecodeGenerator->jump(); + + iffalse.link(); + + Reference right = expression(ast->right); + right.loadInAccumulator(); + jump_endif.link(); + setExprResult(Reference::fromAccumulator(this)); + + return false; } else if (ast->op == QSOperator::Assign) { if (AST::Pattern *p = ast->left->patternCast()) { RegisterScope scope(this); |