diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index c7536dc6062fe0..d3a640139b1a2e 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -1515,6 +1515,11 @@ void EEJitManager::SetCpuInfo() } #endif +#if defined(TARGET_WASM) + CPUCompileFlags.Set(InstructionSet_WasmBase); + CPUCompileFlags.Set(InstructionSet_PackedSimd); +#endif + #if defined(TARGET_X86) || defined(TARGET_AMD64) CPUCompileFlags.Set(InstructionSet_VectorT128); diff --git a/src/coreclr/vm/excep.cpp b/src/coreclr/vm/excep.cpp index 0bc243d9650e18..905be8e332348e 100644 --- a/src/coreclr/vm/excep.cpp +++ b/src/coreclr/vm/excep.cpp @@ -10728,7 +10728,7 @@ void SoftwareExceptionFrame::UpdateContextFromTransitionBlock(TransitionBlock *p } #elif defined(TARGET_WASM) - +TADDR GetWasmFramePointerFromStackPointer(TADDR sp); void SoftwareExceptionFrame::UpdateContextFromTransitionBlock(TransitionBlock *pTransitionBlock) { LIMITED_METHOD_CONTRACT; @@ -10740,7 +10740,7 @@ void SoftwareExceptionFrame::UpdateContextFromTransitionBlock(TransitionBlock *p if (pTransitionBlock != nullptr) { m_Context.InterpreterSP = pTransitionBlock->m_StackPointer; - m_Context.InterpreterFP = 0; + m_Context.InterpreterFP = GetWasmFramePointerFromStackPointer(m_Context.InterpreterSP); m_Context.InterpreterIP = GetWasmVirtualIPFromStackPointer(pTransitionBlock->m_StackPointer); m_ReturnAddress = m_Context.InterpreterIP; m_Context.InterpreterWalkFramePointer = 0; diff --git a/src/coreclr/vm/wasm/helpers.cpp b/src/coreclr/vm/wasm/helpers.cpp index 8abf0c736818f2..9fd937234028d7 100644 --- a/src/coreclr/vm/wasm/helpers.cpp +++ b/src/coreclr/vm/wasm/helpers.cpp @@ -520,12 +520,26 @@ void FaultingExceptionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool u PORTABILITY_ASSERT("FaultingExceptionFrame::UpdateRegDisplay_Impl is not implemented on wasm"); } +TADDR GetWasmFramePointerFromStackPointer(TADDR sp); + void TransitionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats) { pRD->IsCallerContextValid = FALSE; pRD->pCurrentContext->InterpreterIP = GetReturnAddress(); - pRD->pCurrentContext->InterpreterSP = GetSP(); + TADDR sp = GetSP(); + pRD->pCurrentContext->InterpreterSP = sp; + + // Recover the frame pointer so GC-info readers can locate frame slots, but only when + // the stack pointer refers to a real R2R frame. When this frame represents a transition + // out of interpreted code, GetSP() returns the address just past the TransitionBlock (the + // outgoing argument area) rather than a frame pointer (see TransitionFrame::GetSP). Decoding + // that would dereference arbitrary memory, so leave the frame pointer as 0 in that case. + TransitionBlock* pTransitionBlock = (TransitionBlock*)GetTransitionBlock(); + bool hasR2RStackPointer = (pTransitionBlock != NULL) && + (pTransitionBlock->m_ReturnAddress != 0) && + (pTransitionBlock->m_StackPointer != 0); + pRD->pCurrentContext->InterpreterFP = hasR2RStackPointer ? GetWasmFramePointerFromStackPointer(sp) : 0; SyncRegDisplayToCurrentContext(pRD); @@ -1514,6 +1528,7 @@ RtlVirtualUnwind ( PTR_BYTE pUnwindData = dac_cast(FunctionEntry->UnwindData + ImageBase); ContextRecord->InterpreterSP = fp + DecodeULEB128AsU32(&pUnwindData); // Unwind the frame pointer to the callers stack pointer ContextRecord->InterpreterIP = GetWasmVirtualIPFromStackPointer(ContextRecord->InterpreterSP); + ContextRecord->InterpreterFP = GetWasmFramePointerFromStackPointer(ContextRecord->InterpreterSP); } else { @@ -1521,6 +1536,7 @@ RtlVirtualUnwind ( _ASSERTE(FALSE); ContextRecord->InterpreterIP = 0; ContextRecord->InterpreterSP = 0; + ContextRecord->InterpreterFP = 0; } return nullptr; diff --git a/src/tests/Common/CLRTest.CrossGen.targets b/src/tests/Common/CLRTest.CrossGen.targets index 3cdbf07518e9e8..06439b9f381982 100644 --- a/src/tests/Common/CLRTest.CrossGen.targets +++ b/src/tests/Common/CLRTest.CrossGen.targets @@ -130,6 +130,10 @@ if [ ! -z ${RunCrossGen2+x} ]%3B then echo --targetos:$(TargetOS) >> "$__ResponseFile" echo --verify-type-and-field-layout >> "$__ResponseFile" echo --method-layout:random >> "$__ResponseFile" + if [ "$(CrossGen2OutputFormat)" == "wasm" ]; then + echo --codegenopt:JitWasmNyiToR2RUnsupported=1 >> "$__ResponseFile" + echo --codegenopt:JitWasmSimdNyiToR2RUnsupported=1 >> "$__ResponseFile" + fi if [ ! -z ${CrossGen2SynthesizePgo+x} ]%3B then echo --synthesize-random-mibc >> "$__ResponseFile" echo --embed-pgo-data >> "$__ResponseFile" @@ -339,6 +343,10 @@ if defined RunCrossGen2 ( echo --targetos:$(TargetOS)>>!__ResponseFile! echo --verify-type-and-field-layout>>!__ResponseFile! echo --method-layout:random>>!__ResponseFile! + if "$(CrossGen2OutputFormat)"=="wasm" ( + echo "--codegenopt:JitWasmNyiToR2RUnsupported=1">>!__ResponseFile! + echo "--codegenopt:JitWasmSimdNyiToR2RUnsupported=1">>!__ResponseFile! + ) if not "$(CrossGen2OutputFormat)"=="" ( echo -f:$(CrossGen2OutputFormat)>>!__ResponseFile! )