diff options
author | Lars Knoll <lars.knoll@digia.com> | 2014-01-24 10:01:55 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-01-24 11:35:51 +0100 |
commit | f27184dcb319748417181babe6fe03d659d6a515 (patch) | |
tree | ddc73152ecf7e8d1ba6ba9e8b931845b8ce5f91c | |
parent | f9ba7d29464eb7f13004918faa73d37f7b4ea725 (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.cpp | 19 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_masm_p.h | 2 |
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() { |