Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,8 @@ class AsmOffsets
public const int OFFSETOF__PAL_LIMITED_CONTEXT__IP = 0x108;
public const int OFFSETOF__PAL_LIMITED_CONTEXT__FP = 0xb8;
#elif TARGET_WASM
// offset to dummy field
public const int OFFSETOF__PAL_LIMITED_CONTEXT__IP = 0x04;
public const int OFFSETOF__PAL_LIMITED_CONTEXT__FP = 0x04;
public const int OFFSETOF__PAL_LIMITED_CONTEXT__IP = 0x10;
public const int OFFSETOF__PAL_LIMITED_CONTEXT__FP = 0x0c;
#endif

// Offsets / sizes that are different in 64 / 32 bit mode
Expand Down Expand Up @@ -280,6 +279,9 @@ class AsmOffsets
#elif TARGET_LOONGARCH64
static_assert(offsetof(CONTEXT, Pc) == AsmOffsets::OFFSETOF__PAL_LIMITED_CONTEXT__IP);
static_assert(offsetof(CONTEXT, Fp) == AsmOffsets::OFFSETOF__PAL_LIMITED_CONTEXT__FP);
#elif TARGET_WASM
static_assert(offsetof(CONTEXT, InterpreterIP) == AsmOffsets::OFFSETOF__PAL_LIMITED_CONTEXT__IP);
static_assert(offsetof(CONTEXT, InterpreterFP) == AsmOffsets::OFFSETOF__PAL_LIMITED_CONTEXT__FP);
#endif
static_assert(sizeof(REGDISPLAY) == AsmOffsets::SIZEOF__REGDISPLAY);
static_assert(offsetof(REGDISPLAY, SP) == AsmOffsets::OFFSETOF__REGDISPLAY__SP);
Expand Down
21 changes: 11 additions & 10 deletions src/coreclr/pal/src/arch/wasm/stubs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,57 +25,58 @@ DBG_DebugBreak()
/* context */

extern "C" void
RtlCaptureContext(OUT PCONTEXT ContextRecord)
RtlCaptureContext(OUT PCONTEXT pContextRecord)
{
_ASSERT("RtlCaptureContext not implemented on wasm");
// we cannot implement this function for wasm because there is no way to capture the current execution context
memset(pContextRecord, 0, sizeof(*pContextRecord));
}

extern "C" void
CONTEXT_CaptureContext(LPCONTEXT lpContext)
{
_ASSERT("CONTEXT_CaptureContext not implemented on wasm");
_ASSERT(!"CONTEXT_CaptureContext not implemented on wasm");
}

extern "C" void ThrowExceptionFromContextInternal(CONTEXT* context, PAL_SEHException* ex)
{
_ASSERT("ThrowExceptionFromContextInternal not implemented on wasm");
_ASSERT(!"ThrowExceptionFromContextInternal not implemented on wasm");
}

/* unwind */

void ExecuteHandlerOnCustomStack(int code, siginfo_t *siginfo, void *context, size_t sp, SignalHandlerWorkerReturnPoint* returnPoint)
{
_ASSERT("ExecuteHandlerOnCustomStack not implemented on wasm");
_ASSERT(!"ExecuteHandlerOnCustomStack not implemented on wasm");
}

extern "C" int unw_getcontext(int)
{
_ASSERT("unw_getcontext not implemented on wasm");
_ASSERT(!"unw_getcontext not implemented on wasm");
return 0;
}

extern "C" int unw_init_local(int, int)
{
_ASSERT("unw_init_local not implemented on wasm");
_ASSERT(!"unw_init_local not implemented on wasm");
return 0;
}

extern "C" int unw_step(int)
{
_ASSERT("unw_step not implemented on wasm");
_ASSERT(!"unw_step not implemented on wasm");
return 0;
}

extern "C" int unw_is_signal_frame(int)
{
_ASSERT("unw_is_signal_frame not implemented on wasm");
_ASSERT(!"unw_is_signal_frame not implemented on wasm");
return 0;
}

/* threading */

extern "C" int pthread_setschedparam(pthread_t, int, const struct sched_param *)
{
_ASSERT("pthread_setschedparam not implemented on wasm");
_ASSERT(!"pthread_setschedparam not implemented on wasm");
return 0;
}
3 changes: 3 additions & 0 deletions src/coreclr/pal/src/exception/seh-unwind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -935,11 +935,14 @@ RaiseException(IN DWORD dwExceptionCode,

// Capture the context of RaiseException.
ZeroMemory(contextRecord, sizeof(CONTEXT));
// WASM-TODO: reconsider this
#ifndef TARGET_WASM
contextRecord->ContextFlags = CONTEXT_FULL;
CONTEXT_CaptureContext(contextRecord);

// We have to unwind one level to get the actual context user code could be resumed at.
PAL_VirtualUnwind(contextRecord, NULL);
#endif // TARGET_WASM

exceptionRecord->ExceptionAddress = (void *)CONTEXTGetPC(contextRecord);

Expand Down
14 changes: 6 additions & 8 deletions src/coreclr/pal/src/include/pal/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -1394,9 +1394,8 @@ inline static DWORD64 CONTEXTGetPC(LPCONTEXT pContext)
return pContext->PSWAddr;
#elif defined(HOST_POWERPC64)
return pContext->Nip;
#elif defined(HOST_WASM) // wasm has no PC
_ASSERT(false);
return 0;
#elif defined(HOST_WASM)
return pContext->InterpreterIP;
#else
return pContext->Pc;
#endif
Expand All @@ -1412,8 +1411,8 @@ inline static void CONTEXTSetPC(LPCONTEXT pContext, DWORD64 pc)
pContext->PSWAddr = pc;
#elif defined(HOST_POWERPC64)
pContext->Nip = pc;
#elif defined(HOST_WASM) // wasm has no PC
_ASSERT(false);
#elif defined(HOST_WASM)
pContext->InterpreterIP = pc;
#else
pContext->Pc = pc;
#endif
Expand All @@ -1431,9 +1430,8 @@ inline static DWORD64 CONTEXTGetFP(LPCONTEXT pContext)
return pContext->R11;
#elif defined(HOST_POWERPC64)
return pContext->R31;
#elif defined(HOST_WASM) // wasm has no PC
_ASSERT(false);
return 0;
#elif defined(HOST_WASM)
return pContext->InterpreterFP;
#else
return pContext->Fp;
#endif
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/vm/exceptionhandling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3292,7 +3292,12 @@ void CallCatchFunclet(OBJECTREF throwable, BYTE* pHandlerIP, REGDISPLAY* pvRegDi
#endif
{
STRESS_LOG2(LF_EH, LL_INFO100, "Resuming propagation of managed exception through native frames at IP=%p, SP=%p\n", GetIP(pvRegDisplay->pCurrentContext), GetSP(pvRegDisplay->pCurrentContext));
#ifdef TARGET_WASM
// wasm cannot unwind frames, so we let C++ exception handling do all the work
PropagateExceptionThroughNativeFrames(OBJECTREFToObject(throwable));
#else // !TARGET_WASM
ExecuteFunctionBelowContext((PCODE)PropagateExceptionThroughNativeFrames, pvRegDisplay->pCurrentContext, targetSSP, (size_t)OBJECTREFToObject(throwable));
#endif // TARGET_WASM
}
#undef FIRST_ARG_REG
}
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/vm/interpexec.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ struct ExceptionClauseArgs
void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFrame *pFrame, InterpThreadContext *pThreadContext, ExceptionClauseArgs *pExceptionClauseArgs = NULL);

extern "C" void LookupMethodByName(const char* fullQualifiedTypeName, const char* methodName, MethodDesc** ppMD);
extern "C" void ExecuteInterpretedMethodFromUnmanaged(MethodDesc* pMD, int8_t* args, size_t argSize, int8_t* ret);
extern "C" void ExecuteInterpretedMethodFromUnmanaged(MethodDesc* pMD, int8_t* args, size_t argSize, int8_t* ret, PCODE callerIp);

CallStubHeader *CreateNativeToInterpreterCallStub(InterpMethod* pInterpMethod);

Expand Down
11 changes: 6 additions & 5 deletions src/coreclr/vm/prestub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2056,7 +2056,7 @@ extern "C" void* STDCALL ExecuteInterpretedMethod(TransitionBlock* pTransitionBl
return frames.interpMethodContextFrame.pRetVal;
}

void ExecuteInterpretedMethodWithArgs(TADDR targetIp, int8_t* args, size_t argSize, void* retBuff)
void ExecuteInterpretedMethodWithArgs(TADDR targetIp, int8_t* args, size_t argSize, void* retBuff, PCODE callerIp)
{
// Copy arguments to the stack
if (argSize > 0)
Expand All @@ -2067,11 +2067,12 @@ void ExecuteInterpretedMethodWithArgs(TADDR targetIp, int8_t* args, size_t argSi
memcpy(sp, args, argSize);
}

TransitionBlock dummy{};
(void)ExecuteInterpretedMethod(&dummy, (TADDR)targetIp, retBuff);
TransitionBlock block{};
block.m_ReturnAddress = (TADDR)callerIp;
(void)ExecuteInterpretedMethod(&block, (TADDR)targetIp, retBuff);
}

extern "C" void ExecuteInterpretedMethodFromUnmanaged(MethodDesc* pMD, int8_t* args, size_t argSize, int8_t* ret)
extern "C" void ExecuteInterpretedMethodFromUnmanaged(MethodDesc* pMD, int8_t* args, size_t argSize, int8_t* ret, PCODE callerIp)
{
_ASSERTE(pMD != NULL);

Expand All @@ -2086,7 +2087,7 @@ extern "C" void ExecuteInterpretedMethodFromUnmanaged(MethodDesc* pMD, int8_t* a
(void)pMD->DoPrestub(NULL /* MethodTable */, CallerGCMode::Coop);
targetIp = pMD->GetInterpreterCode();
}
(void)ExecuteInterpretedMethodWithArgs((TADDR)targetIp, args, argSize, ret);
(void)ExecuteInterpretedMethodWithArgs((TADDR)targetIp, args, argSize, ret, callerIp);
}
#endif // FEATURE_INTERPRETER

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/vm/wasm/calldescrworkerwasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include <interpexec.h>

// Forward declaration
void ExecuteInterpretedMethodWithArgs(TADDR targetIp, int8_t* args, size_t argSize, void* retBuff);
void ExecuteInterpretedMethodWithArgs(TADDR targetIp, int8_t* args, size_t argSize, void* retBuff, PCODE callerIp);

extern "C" void STDCALL CallDescrWorkerInternal(CallDescrData* pCallDescrData)
{
Expand All @@ -26,5 +26,5 @@ extern "C" void STDCALL CallDescrWorkerInternal(CallDescrData* pCallDescrData)
targetIp = pMethod->GetInterpreterCode();
}

ExecuteInterpretedMethodWithArgs((TADDR)targetIp, (int8_t*)pCallDescrData->pSrc, pCallDescrData->nArgsSize, (int8_t*)pCallDescrData->returnValue);
ExecuteInterpretedMethodWithArgs((TADDR)targetIp, (int8_t*)pCallDescrData->pSrc, pCallDescrData->nArgsSize, (int8_t*)pCallDescrData->returnValue, (PCODE)&CallDescrWorkerInternal);
}
6 changes: 3 additions & 3 deletions src/coreclr/vm/wasm/callhelpers-reverse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class MethodDesc;
// WASM-TODO: The method lookup would ideally be fully qualified assembly and then methodDef token.
// The current approach has limitations with overloaded methods.
extern "C" void LookupMethodByName(const char* fullQualifiedTypeName, const char* methodName, MethodDesc** ppMD);
extern "C" void ExecuteInterpretedMethodFromUnmanaged(MethodDesc* pMD, int8_t* args, size_t argSize, int8_t* ret);
extern "C" void ExecuteInterpretedMethodFromUnmanaged(MethodDesc* pMD, int8_t* args, size_t argSize, int8_t* ret, PCODE callerIp);

static MethodDesc* MD_System_Private_CoreLib_System_Threading_ThreadPool_BackgroundJobHandler_Void_RetVoid = nullptr;
static void Call_System_Private_CoreLib_System_Threading_ThreadPool_BackgroundJobHandler()
Expand All @@ -22,7 +22,7 @@ static void Call_System_Private_CoreLib_System_Threading_ThreadPool_BackgroundJo
{
LookupMethodByName("System.Threading.ThreadPool, System.Private.CoreLib", "BackgroundJobHandler", &MD_System_Private_CoreLib_System_Threading_ThreadPool_BackgroundJobHandler_Void_RetVoid);
}
ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Threading_ThreadPool_BackgroundJobHandler_Void_RetVoid, nullptr, 0, nullptr);
ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Threading_ThreadPool_BackgroundJobHandler_Void_RetVoid, nullptr, 0, nullptr, (PCODE)&Call_System_Private_CoreLib_System_Threading_ThreadPool_BackgroundJobHandler);
}

extern "C" void SystemJS_ExecuteBackgroundJobCallback()
Expand All @@ -38,7 +38,7 @@ static void Call_System_Private_CoreLib_System_Threading_TimerQueue_TimerHandler
{
LookupMethodByName("System.Threading.TimerQueue, System.Private.CoreLib", "TimerHandler", &MD_System_Private_CoreLib_System_Threading_TimerQueue_TimerHandler_Void_RetVoid);
}
ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Threading_TimerQueue_TimerHandler_Void_RetVoid, nullptr, 0, nullptr);
ExecuteInterpretedMethodFromUnmanaged(MD_System_Private_CoreLib_System_Threading_TimerQueue_TimerHandler_Void_RetVoid, nullptr, 0, nullptr, (PCODE)&Call_System_Private_CoreLib_System_Threading_TimerQueue_TimerHandler);
}

extern "C" void SystemJS_ExecuteTimerCallback()
Expand Down
9 changes: 7 additions & 2 deletions src/coreclr/vm/wasm/helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,15 @@ void FaultingExceptionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool u

void TransitionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats)
{
PORTABILITY_ASSERT("TransitionFrame::UpdateRegDisplay_Impl is not implemented on wasm");
pRD->pCurrentContext->InterpreterIP = GetReturnAddress();
pRD->pCurrentContext->InterpreterSP = GetSP();

SyncRegDisplayToCurrentContext(pRD);

LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK TransitionFrame::UpdateRegDisplay_Impl(rip:%p, rsp:%p)\n", pRD->ControlPC, pRD->SP));
}

size_t CallDescrWorkerInternalReturnAddressOffset;
size_t CallDescrWorkerInternalReturnAddressOffset = 0;

VOID PALAPI RtlRestoreContext(IN PCONTEXT ContextRecord, IN PEXCEPTION_RECORD ExceptionRecord)
{
Expand Down
Loading