aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2014-01-24 10:01:55 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-01-24 11:35:51 +0100
commitf27184dcb319748417181babe6fe03d659d6a515 (patch)
treeddc73152ecf7e8d1ba6ba9e8b931845b8ce5f91c
parentf9ba7d29464eb7f13004918faa73d37f7b4ea725 (diff)
Don't write into the callers stack frame
Never usee addressForArgument when arguments are passed in registers, as it points into the callers stack frame. The address was used as a temporary location when encoding a unsigned return value. The code has now been rewritten to only use registers instead. Change-Id: Id85b668a5a74dbd6c41621a9672e53a1cb5f242b Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp19
-rw-r--r--src/qml/compiler/qv4isel_masm_p.h2
2 files changed, 16 insertions, 5 deletions
diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp
index 35097bae49..0cfb684e93 100644
--- a/src/qml/compiler/qv4isel_masm.cpp
+++ b/src/qml/compiler/qv4isel_masm.cpp
@@ -1957,12 +1957,21 @@ void InstructionSelection::visitRet(V4IR::Ret *s)
Assembler::ScratchRegister);
_as->xor64(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
} else if (t->type == V4IR::UInt32Type) {
- Address tmp = addressForArgument(0);
- _as->storeUInt32((Assembler::RegisterID) t->index, Pointer(tmp));
- _as->load64(tmp, Assembler::ReturnValueRegister);
+ Assembler::RegisterID srcReg = (Assembler::RegisterID) t->index;
+ Assembler::Jump intRange = _as->branch32(Assembler::GreaterThanOrEqual, srcReg, Assembler::TrustedImm32(0));
+ _as->convertUInt32ToDouble(srcReg, Assembler::FPGpr0, Assembler::ReturnValueRegister);
+ _as->moveDoubleTo64(Assembler::FPGpr0, Assembler::ReturnValueRegister);
+ _as->move(Assembler::TrustedImm64(QV4::Value::NaNEncodeMask), Assembler::ScratchRegister);
+ _as->xor64(Assembler::ScratchRegister, Assembler::ReturnValueRegister);
+ Assembler::Jump done = _as->jump();
+ intRange.link(_as);
+ _as->zeroExtend32ToPtr(srcReg, Assembler::ReturnValueRegister);
+ quint64 tag = QV4::Value::_Integer_Type;
+ _as->or64(Assembler::TrustedImm64(tag << 32),
+ Assembler::ReturnValueRegister);
+ done.link(_as);
} else {
- _as->zeroExtend32ToPtr((Assembler::RegisterID) t->index,
- Assembler::ReturnValueRegister);
+ _as->zeroExtend32ToPtr((Assembler::RegisterID) t->index, Assembler::ReturnValueRegister);
quint64 tag;
switch (t->type) {
case V4IR::SInt32Type:
diff --git a/src/qml/compiler/qv4isel_masm_p.h b/src/qml/compiler/qv4isel_masm_p.h
index f5d4e469e5..a146220015 100644
--- a/src/qml/compiler/qv4isel_masm_p.h
+++ b/src/qml/compiler/qv4isel_masm_p.h
@@ -1481,6 +1481,7 @@ protected:
typedef Assembler::Address Address;
typedef Assembler::Pointer Pointer;
+#if !defined(ARGUMENTS_IN_REGISTERS)
Address addressForArgument(int index) const
{
// StackFrameRegister points to its old value on the stack, and above
@@ -1488,6 +1489,7 @@ protected:
// values before reaching the first argument.
return Address(Assembler::StackFrameRegister, (index + 2) * sizeof(void*));
}
+#endif
Pointer baseAddressForCallArguments()
{