diff --git a/js/src/ion/BaselineIC.cpp b/js/src/ion/BaselineIC.cpp index a10270ad6cc4..e86452709a03 100644 --- a/js/src/ion/BaselineIC.cpp +++ b/js/src/ion/BaselineIC.cpp @@ -7178,8 +7178,23 @@ ICCallScriptedCompiler::generateStubCode(MacroAssembler &masm) Label skipThisReplace; masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace); + Register scratchReg = JSReturnOperand.scratchReg(); + // Current stack: [ ARGVALS..., ThisVal, ActualArgc, Callee, Descriptor ] - masm.loadValue(Address(BaselineStackReg, 3*sizeof(size_t)), JSReturnOperand); + // However, we can't use this ThisVal, because it hasn't been traced. We need to use + // The ThisVal higher up the stack: + // Current stack: [ ThisVal, ARGVALS..., ...STUB FRAME..., + // ARGVALS..., ThisVal, ActualArgc, Callee, Descriptor ] + masm.loadPtr(Address(BaselineStackReg, 2*sizeof(size_t)), scratchReg); + + // scratchReg now contains actualArgCount. Double it to account for skipping past two + // pushed copies of argument values. Additionally, we need to add: + // STUB_FRAME_SIZE + sizeof(ThisVal) + sizeof(size_t) + sizeof(void *) + sizoef(size_t) + // for: stub frame, this value, actual argc, callee, and descriptor + masm.lshiftPtr(Imm32(1), scratchReg); + BaseIndex reloadThisSlot(BaselineStackReg, scratchReg, TimesEight, + STUB_FRAME_SIZE + sizeof(Value) + 3*sizeof(size_t)); + masm.loadValue(reloadThisSlot, JSReturnOperand); #ifdef DEBUG masm.branchTestObject(Assembler::Equal, JSReturnOperand, &skipThisReplace); masm.breakpoint();