diff --git a/js/src/wasm/WasmBaselineCompile.cpp b/js/src/wasm/WasmBaselineCompile.cpp index a0c8456ae9..09cb43306b 100644 --- a/js/src/wasm/WasmBaselineCompile.cpp +++ b/js/src/wasm/WasmBaselineCompile.cpp @@ -2083,10 +2083,21 @@ class BaseCompiler maxFramePushed_ = localSize_; - // We won't know until after we've generated code how big the - // frame will be (we may need arbitrary spill slots and - // outgoing param slots) so branch to code emitted after the - // function body that will perform the check. + // The TLS pointer is always passed as a hidden argument in WasmTlsReg. + // Save it into its assigned local slot. + storeToFramePtr(WasmTlsReg, localInfo_[tlsSlot_].offs()); + if (debugEnabled_) { + // Initialize funcIndex and flag fields of DebugFrame. + size_t debugFrame = masm.framePushed() - DebugFrame::offsetOfFrame(); + masm.store32(Imm32(func_.index()), + Address(masm.getStackPointer(), debugFrame + DebugFrame::offsetOfFuncIndex())); + masm.storePtr(ImmWord(0), + Address(masm.getStackPointer(), debugFrame + DebugFrame::offsetOfFlagsWord())); + } + + // We won't know until after we've generated code how big the frame will + // be (we may need arbitrary spill slots and outgoing param slots) so + // emit a patchable add that is patched in endFunction(). // // Code there will also assume that the fixed-size stack frame // has been allocated. @@ -2121,19 +2132,7 @@ class BaseCompiler MOZ_CRASH("Function argument type"); } } - - // The TLS pointer is always passed as a hidden argument in WasmTlsReg. - // Save it into its assigned local slot. - storeToFramePtr(WasmTlsReg, localInfo_[tlsSlot_].offs()); - if (debugEnabled_) { - // Initialize funcIndex and flag fields of DebugFrame. - size_t debugFrame = masm.framePushed() - DebugFrame::offsetOfFrame(); - masm.store32(Imm32(func_.index()), - Address(masm.getStackPointer(), debugFrame + DebugFrame::offsetOfFuncIndex())); - masm.storePtr(ImmWord(0), - Address(masm.getStackPointer(), debugFrame + DebugFrame::offsetOfFlagsWord())); - } - + // Initialize the stack locals to zero. // // The following are all Bug 1316820: @@ -2228,10 +2227,16 @@ class BaseCompiler // Since we just overflowed the stack, to be on the safe side, pop the // stack so that, when the trap exit stub executes, it is a safe - // distance away from the end of the native stack. - if (localSize_) - masm.addToStackPtr(Imm32(localSize_)); - masm.jump(TrapDesc(prologueTrapOffset_, Trap::StackOverflow, /* framePushed = */ 0)); + // distance away from the end of the native stack. If debugEnabled_ is + // set, we pop all locals space except allocated for DebugFrame to + // maintain the invariant that, when debugEnabled_, all wasm::Frames + // are valid wasm::DebugFrames which is observable by WasmHandleThrow. + masm.bind(&stackOverflowLabel_); + int32_t debugFrameReserved = debugEnabled_ ? DebugFrame::offsetOfFrame() : 0; + MOZ_ASSERT(localSize_ >= debugFrameReserved); + if (localSize_ > debugFrameReserved) + masm.addToStackPtr(Imm32(localSize_ - debugFrameReserved)); + masm.jump(TrapDesc(prologueTrapOffset_, Trap::StackOverflow, debugFrameReserved)); masm.bind(&returnLabel_);