diff options
author | Lars Knoll <lars.knoll@theqtcompany.com> | 2015-04-20 13:38:31 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-04-20 13:30:06 +0000 |
commit | a41dc6147436f3c1c977ff8c04379ff4bde3f0a6 (patch) | |
tree | 743146494dfe3683971ef3cf71def64e51214106 /src | |
parent | ca4dbd5675ad3aabffb9fb92f19b53b4c5028981 (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.cpp | 15 |
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) |