aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@theqtcompany.com>2015-04-20 13:38:31 +0200
committerSimon Hausmann <simon.hausmann@theqtcompany.com>2015-04-20 13:30:06 +0000
commita41dc6147436f3c1c977ff8c04379ff4bde3f0a6 (patch)
tree743146494dfe3683971ef3cf71def64e51214106 /src
parentca4dbd5675ad3aabffb9fb92f19b53b4c5028981 (diff)
Always return a proper Value from JIT generated code
When throwing an exception, we ended up having junk data in the return value register. That could end up being written onto the JS stack when returning from the function, and then causing crashes in the garbage collector afterwards. Fix it by returning undefined in case we throw an exception. Change-Id: Ice380f2de673b179c1e2c98fbeb87e47347ef520 Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/jit/qv4isel_masm.cpp15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp
index 05d3876466..da511cd1eb 100644
--- a/src/qml/jit/qv4isel_masm.cpp
+++ b/src/qml/jit/qv4isel_masm.cpp
@@ -1485,7 +1485,7 @@ void InstructionSelection::visitRet(IR::Ret *s)
Q_UNUSED(s);
}
- _as->exceptionReturnLabel = _as->label();
+ Assembler::Label leaveStackFrame = _as->label();
const int locals = _as->stackLayout().calculateJSStackFrameSize();
_as->subPtr(Assembler::TrustedImm32(sizeof(QV4::Value)*locals), Assembler::LocalsRegister);
@@ -1495,6 +1495,19 @@ void InstructionSelection::visitRet(IR::Ret *s)
_as->leaveStandardStackFrame(regularRegistersToSave, fpRegistersToSave);
_as->ret();
+
+ _as->exceptionReturnLabel = _as->label();
+ QV4::Primitive retVal = Primitive::undefinedValue();
+#if CPU(X86)
+ _as->move(Assembler::TrustedImm32(retVal.int_32), JSC::X86Registers::eax);
+ _as->move(Assembler::TrustedImm32(retVal.tag), JSC::X86Registers::edx);
+#elif CPU(ARM)
+ _as->move(Assembler::TrustedImm32(retVal.int_32), JSC::ARMRegisters::r0);
+ _as->move(Assembler::TrustedImm32(retVal.tag), JSC::ARMRegisters::r1);
+#else
+ _as->move(Assembler::TrustedImm64(retVal.val), Assembler::ReturnValueRegister);
+#endif
+ _as->jump(leaveStackFrame);
}
int InstructionSelection::prepareVariableArguments(IR::ExprList* args)