From 640356be3199823483f8e8764f73e90e7a0f617a Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Mon, 29 Oct 2018 09:29:36 +0100 Subject: Make sure not to clobber tail call arguments when unrolling stack When the accumulator doesn't overlap the return value registers, we move the accumulator value there when doing a function exit. This happens for arm32 and arm64. This is a problem when doing a tail call: these registers are also used to store the first two arguments for the call, so restorating will wipe them. Task-number: QTBUG-71212 Change-Id: Ifd82729e8741418c1b54e804724893e02bd180c7 Reviewed-by: Ulf Hermann Reviewed-by: Simon Hausmann --- src/qml/jit/qv4assemblercommon_p.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/qml/jit/qv4assemblercommon_p.h b/src/qml/jit/qv4assemblercommon_p.h index cbbd6464d9..bf239fcfd8 100644 --- a/src/qml/jit/qv4assemblercommon_p.h +++ b/src/qml/jit/qv4assemblercommon_p.h @@ -398,7 +398,8 @@ public: void generatePlatformFunctionExit(bool tailCall = false) { - move(AccumulatorRegister, ReturnValueRegister); + if (!tailCall) // do not overwrite arg0 (used in the tail call) + move(AccumulatorRegister, ReturnValueRegister); popPair(EngineRegister, CppStackFrameRegister); popPair(JSStackFrameRegister, AccumulatorRegister); popPair(JSC::ARM64Registers::fp, JSC::ARM64Registers::lr); @@ -492,8 +493,10 @@ public: void generatePlatformFunctionExit(bool tailCall = false) { - move(AccumulatorRegisterValue, ReturnValueRegisterValue); - move(AccumulatorRegisterTag, ReturnValueRegisterTag); + if (!tailCall) { // do not overwrite arg0 and arg1 (used in the tail call) + move(AccumulatorRegisterValue, ReturnValueRegisterValue); + move(AccumulatorRegisterTag, ReturnValueRegisterTag); + } addPtr(TrustedImm32(4), StackPointerRegister); // stack alignment pop(EngineRegister); pop(CppStackFrameRegister); -- cgit v1.2.3