diff options
author | Erik Verbruggen <erik.verbruggen@qt.io> | 2018-03-09 13:04:53 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2018-03-15 15:10:04 +0000 |
commit | 86702c3be53fda404ebe331207f9062675c952e0 (patch) | |
tree | e63afbb295b643151abc99be4e68d72f2c0999cd /src/qml | |
parent | c3db3cfa296dbc5aa198520c1411830d165cd496 (diff) |
Fix JITted code for jump strict-not-equal undefined on 32bit
The generated code for jump-on-strict-not-equal-undefined used the
same logic (but with inverted conditions) as the equal case. For
equality, one can jump to else if the value parts are not the same.
So, for not-equal, if the value parts are the same, it would jump
to the else block if they are the same. Meaning, an encoded int
value of 0 (which is strict-not-equal to undefined) would end up
being evaluated as equal.
Task-number: QTBUG-66832
Change-Id: I5c6b8e9b11be53ae21a7164e0a1e0cbfd204f401
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/jit/qv4assembler_p.h | 37 |
1 files changed, 27 insertions, 10 deletions
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h index 8b5b307e84..87f73ccd6f 100644 --- a/src/qml/jit/qv4assembler_p.h +++ b/src/qml/jit/qv4assembler_p.h @@ -294,21 +294,38 @@ struct RegisterSizeDependentAssembler<JITAssembler, MacroAssembler, TargetPlatfo static void generateCJumpOnUndefined(JITAssembler *as, RelationalCondition cond, IR::Expr *right, - RegisterID scratchRegister, RegisterID tagRegister, + RegisterID scratchRegister, RegisterID varReg, IR::BasicBlock *nextBlock, IR::BasicBlock *currentBlock, IR::BasicBlock *trueBlock, IR::BasicBlock *falseBlock) { - Pointer tagAddr = as->loadAddress(scratchRegister, right); - as->load32(tagAddr, tagRegister); - Jump j = as->branch32(JITAssembler::invert(cond), tagRegister, TrustedImm32(0)); - as->addPatch(falseBlock, j); - - tagAddr.offset += 4; - as->load32(tagAddr, tagRegister); - const TrustedImm32 tag(QV4::Value::Managed_Type_Internal); Q_ASSERT(nextBlock == as->nextBlock()); Q_UNUSED(nextBlock); - as->generateCJumpOnCompare(cond, tagRegister, tag, currentBlock, trueBlock, falseBlock); + + const typename JITAssembler::TrustedImm32 undefinedTag(QV4::Value::Managed_Type_Internal); + const typename JITAssembler::TrustedImm32 undefinedValue(0); + + typename JITAssembler::Pointer varAddr = as->loadAddress(scratchRegister, right); + typename JITAssembler::Pointer tagAddr = varAddr; + tagAddr.offset += 4; + const typename JITAssembler::RegisterID tagReg = varReg; + + if (cond == JITAssembler::Equal) { + as->load32(tagAddr, tagReg); + // if the tags are not the same, we can fail already: + Jump j = as->branch32(JITAssembler::NotEqual, tagReg, undefinedTag); + as->addPatch(falseBlock, j); + as->load32(varAddr, varReg); + // ok, tags are the same, so if the values are the same then we're done + as->generateCJumpOnCompare(JITAssembler::Equal, varReg, undefinedValue, currentBlock, trueBlock, falseBlock); + } else { // strict not equal: + as->load32(varAddr, varReg); + // if the values are not the same, we're done + Jump j = as->branch32(JITAssembler::NotEqual, varReg, undefinedValue); + as->addPatch(trueBlock, j); + as->load32(tagAddr, tagReg); + // ok, so the values are the same, now check the tags + as->generateCJumpOnCompare(JITAssembler::NotEqual, tagReg, undefinedTag, currentBlock, trueBlock, falseBlock); + } } static void convertVarToSInt32(JITAssembler *as, IR::Expr *source, IR::Expr *target) |