From 245f7f14d3e88c654f92eacaf005df2be96c691b Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 17 Sep 2025 13:37:28 +0200 Subject: [PATCH 01/11] Load ICU data on wasm --- src/coreclr/hosts/corerun/corerun.cpp | 8 +- src/coreclr/hosts/corerun/corerun.wasm.cpp | 85 +++++++++++++++++++ src/coreclr/hosts/corerun/corerun.wasm.hpp | 1 + src/coreclr/hosts/corewasmrun/corewasmrun.cpp | 10 +++ 4 files changed, 103 insertions(+), 1 deletion(-) diff --git a/src/coreclr/hosts/corerun/corerun.cpp b/src/coreclr/hosts/corerun/corerun.cpp index 2b8105f3b3081a..a85649c0253bb1 100644 --- a/src/coreclr/hosts/corerun/corerun.cpp +++ b/src/coreclr/hosts/corerun/corerun.cpp @@ -490,12 +490,18 @@ static int run(const configuration& config) coreclr_set_error_writer_func(log_error_info); } + int result; #ifdef TARGET_WASM // install the pinvoke override callback to resolve p/invokes to statically linked libraries wasm_add_pinvoke_override(); + result = wasm_load_icu_data(entry_assembly_utf8.c_str()); + if (result != 1) + { + std::fprintf(stderr, "Failed to load the ICU data\n"); + return -1; + } #endif - int result; result = coreclr_init_func( exe_path_utf8.c_str(), "corerun", diff --git a/src/coreclr/hosts/corerun/corerun.wasm.cpp b/src/coreclr/hosts/corerun/corerun.wasm.cpp index 6e383db9206a12..795113631367f0 100644 --- a/src/coreclr/hosts/corerun/corerun.wasm.cpp +++ b/src/coreclr/hosts/corerun/corerun.wasm.cpp @@ -1,7 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#include #include +#include +#include +#include #define _In_z_ #define _In_ @@ -27,3 +31,84 @@ void wasm_add_pinvoke_override() { PInvokeOverride::SetPInvokeOverride(pinvoke_override, PInvokeOverride::Source::RuntimeConfiguration); } + +extern "C" int32_t mono_wasm_load_icu_data(const void* pData); + +static char* _wasm_get_icu_dat_file_path(const char* assemblyPath) +{ + if (!assemblyPath || !*assemblyPath) + return nullptr; + + const char* lastSlash = strrchr(assemblyPath, '/'); + const char* lastBackslash = strrchr(assemblyPath, '\\'); + + const char* lastSeparator = nullptr; + if (lastSlash && lastBackslash) + lastSeparator = (lastSlash > lastBackslash) ? lastSlash : lastBackslash; + else if (lastSlash) + lastSeparator = lastSlash; + else if (lastBackslash) + lastSeparator = lastBackslash; + + const char icuFileName[] = "icudt.dat"; + + if (!lastSeparator) + return strdup(icuFileName); + + size_t dirLen = (size_t)(lastSeparator - assemblyPath) + 1; // include separator + size_t fileNameLen = sizeof(icuFileName) - 1; + + char* icuPath = (char*)malloc(dirLen + fileNameLen + 1); + if (!icuPath) + return nullptr; + + memcpy(icuPath, assemblyPath, dirLen); + memcpy(icuPath + dirLen, icuFileName, fileNameLen); + icuPath[dirLen + fileNameLen] = '\0'; + + return icuPath; +} + +int32_t wasm_load_icu_data(const char* assemblyPath) +{ + char* icuFile = _wasm_get_icu_dat_file_path(assemblyPath); + if (!icuFile) { + return 0; + } + + int fd = open(icuFile, O_RDONLY); + if (fd < 0) { + free(icuFile); + return 0; + } + + struct stat st; + if (stat(icuFile, &st) != 0 || !S_ISREG(st.st_mode) || st.st_size <= 0) { + close(fd); + free(icuFile); + return 0; + } + + free(icuFile); + + size_t size = static_cast(st.st_size); + void* buffer = malloc(size); + if (!buffer) { + close(fd); + return 0; + } + + size_t total = 0; + while (total < size) { + ssize_t n = read(fd, static_cast(buffer) + total, size - total); + if (n <= 0) { + free(buffer); + close(fd); + return 0; + } + total += static_cast(n); + } + close(fd); + + return mono_wasm_load_icu_data(buffer); +} diff --git a/src/coreclr/hosts/corerun/corerun.wasm.hpp b/src/coreclr/hosts/corerun/corerun.wasm.hpp index 302ef58542ac83..8cf6af48a1af3c 100644 --- a/src/coreclr/hosts/corerun/corerun.wasm.hpp +++ b/src/coreclr/hosts/corerun/corerun.wasm.hpp @@ -5,5 +5,6 @@ #define __CORERUN_WASM_HPP__ void wasm_add_pinvoke_override(); +int32_t wasm_load_icu_data(const char* assemblyPath); #endif // __CORERUN_WASM_HPP__ diff --git a/src/coreclr/hosts/corewasmrun/corewasmrun.cpp b/src/coreclr/hosts/corewasmrun/corewasmrun.cpp index 02ba088cfd5996..6b5e745231f905 100644 --- a/src/coreclr/hosts/corewasmrun/corewasmrun.cpp +++ b/src/coreclr/hosts/corewasmrun/corewasmrun.cpp @@ -35,6 +35,16 @@ static int run() wasm_add_pinvoke_override(); + printf("BEGIN: call wasm_load_icu_data\n"); + retval = wasm_load_icu_data("/"); + printf("END: call wasm_load_icu_data\n"); + + if (retval == 0) + { + std::fprintf(stderr, "Failed to load the ICU data\n"); + return -1; + } + printf("BEGIN: call coreclr_initialize\n"); int retval = coreclr_initialize(exe_path, app_domain_name, (int)propertyKeys.size(), propertyKeys.data(), propertyValues.data(), &CurrentClrInstance, &CurrentAppDomainId); printf("END: call coreclr_initialize\n"); From 4de3190a3316c2bd9ca8b051926d1caedfb43630 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Wed, 17 Sep 2025 15:14:51 +0200 Subject: [PATCH 02/11] Handle instance signatures --- src/coreclr/vm/wasm/helpers.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/coreclr/vm/wasm/helpers.cpp b/src/coreclr/vm/wasm/helpers.cpp index 23c8a03d13fe10..fdd3b73d191ce5 100644 --- a/src/coreclr/vm/wasm/helpers.cpp +++ b/src/coreclr/vm/wasm/helpers.cpp @@ -438,6 +438,12 @@ namespace (*fptr)(ARG(0), ARG(1), ARG(2)); } + void CallFunc_I32_I32_I32_I32_RetVoid(PCODE pcode, int8_t *pArgs, int8_t *pRet) + { + void (*fptr)(int32_t, int32_t, int32_t, int32_t) = (void (*)(int32_t, int32_t, int32_t, int32_t))pcode; + (*fptr)(ARG(0), ARG(1), ARG(2), ARG(3)); + } + void CallFunc_I32_I32_I32_I32_I32_I32_RetVoid(PCODE pcode, int8_t *pArgs, int8_t *pRet) { void (*fptr)(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t) = (void (*)(int32_t, int32_t, int32_t, int32_t, int32_t, int32_t))pcode; @@ -521,7 +527,7 @@ namespace (void*)&CallFunc_I32_RetVoid, (void*)&CallFunc_I32_I32_RetVoid, (void*)&CallFunc_I32_I32_I32_RetVoid, - NULL, + (void*)&CallFunc_I32_I32_I32_I32_RetVoid, NULL, (void*)&CallFunc_I32_I32_I32_I32_I32_I32_RetVoid, }; @@ -687,10 +693,17 @@ namespace if (!returnsVoid && ConvertibleTo(sig.GetReturnType(), sig, true /* isReturn */) != ConvertType::ToI32) return NULL; + uint32_t numArgs = sig.NumFixedArgs() + (sig.HasThis() ? 1 : 0); ConvertType args[16]; - _ASSERTE(sig.NumFixedArgs() < ARRAY_SIZE(args)); + _ASSERTE(numArgs < ARRAY_SIZE(args)); uint32_t i = 0; + + if (sig.HasThis()) + { + args[i++] = ConvertType::ToI32; + } + // Ensure all arguments are wasm i32 compatible types. for (CorElementType argType = sig.NextArg(); argType != ELEMENT_TYPE_END; @@ -704,8 +717,6 @@ namespace args[i++] = type; } - uint32_t numArgs = sig.NumFixedArgs(); - // Check for homogeneous i32 argument types. for (uint32_t j = 0; j < numArgs; j++) { From f566b4a211d7d021155e6524f18ad4e779516f68 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 18 Sep 2025 18:53:15 +0200 Subject: [PATCH 03/11] Progress with EH on wasm --- .../Runtime/ExceptionServices/AsmOffsets.cs | 8 ++-- src/coreclr/inc/regdisp.h | 11 +++-- src/coreclr/pal/inc/pal.h | 7 ++- src/coreclr/vm/eetwain.cpp | 8 +++- src/coreclr/vm/wasm/cgencpu.h | 40 ++++++++--------- src/coreclr/vm/wasm/helpers.cpp | 44 ++++++++++++++++++- 6 files changed, 84 insertions(+), 34 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs index 105c8321b2849e..193c7456e0803b 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs @@ -51,9 +51,9 @@ class AsmOffsets public const int OFFSETOF__REGDISPLAY__SP = 0xba8; public const int OFFSETOF__REGDISPLAY__ControlPC = 0xbb0; #elif TARGET_WASM - public const int SIZEOF__REGDISPLAY = 0x38; - public const int OFFSETOF__REGDISPLAY__SP = 0x30; - public const int OFFSETOF__REGDISPLAY__ControlPC = 0x34; + public const int SIZEOF__REGDISPLAY = 0x58; + public const int OFFSETOF__REGDISPLAY__SP = 0x50; + public const int OFFSETOF__REGDISPLAY__ControlPC = 0x54; #endif #if TARGET_64BIT @@ -177,7 +177,7 @@ class AsmOffsets #elif TARGET_LOONGARCH64 public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x520; #elif TARGET_WASM - public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x04; + public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x14; #endif #if TARGET_AMD64 diff --git a/src/coreclr/inc/regdisp.h b/src/coreclr/inc/regdisp.h index 78340a4268431b..889975344690dd 100644 --- a/src/coreclr/inc/regdisp.h +++ b/src/coreclr/inc/regdisp.h @@ -356,10 +356,6 @@ struct REGDISPLAY : public REGDISPLAY_BASE { } }; -inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD) -{ -} - // This function tells us if the given stack pointer is in one of the frames of the functions called by the given frame inline BOOL IsInCalleesFrames(REGDISPLAY *display, LPVOID stackPointer) { _ASSERTE("IsInCalleesFrames is not implemented on wasm"); @@ -370,7 +366,7 @@ inline BOOL IsInCalleesFrames(REGDISPLAY *display, LPVOID stackPointer) { #error "RegDisplay functions are not implemented on this platform." #endif -#if defined(TARGET_64BIT) || defined(TARGET_ARM) || (defined(TARGET_X86) && defined(FEATURE_EH_FUNCLETS)) +#if defined(TARGET_64BIT) || defined(TARGET_ARM) || (defined(TARGET_X86) && defined(FEATURE_EH_FUNCLETS) || defined(TARGET_WASM)) // This needs to be implemented for platforms that have funclets. inline LPVOID GetRegdisplayReturnValue(REGDISPLAY *display) { @@ -407,7 +403,10 @@ inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD) #elif defined(TARGET_X86) pRD->SP = (DWORD)GetSP(pRD->pCurrentContext); pRD->ControlPC = (DWORD)GetIP(pRD->pCurrentContext); -#else // TARGET_X86 +#elif defined(TARGET_WASM) + pRD->SP = (DWORD)GetSP(pRD->pCurrentContext); + pRD->ControlPC = (DWORD)GetIP(pRD->pCurrentContext); +#else // TARGET_WASM PORTABILITY_ASSERT("SyncRegDisplayToCurrentContext"); #endif diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 766d4cdc9f7c8c..9b3fe625cab77c 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -2402,10 +2402,15 @@ typedef struct _KNONVOLATILE_CONTEXT_POINTERS { typedef struct _CONTEXT { ULONG ContextFlags; + + DWORD InterpreterWalkFramePointer; + DWORD InterpreterSP; + DWORD InterpreterFP; + DWORD InterpreterIP; } CONTEXT, *PCONTEXT, *LPCONTEXT; typedef struct _KNONVOLATILE_CONTEXT_POINTERS { - DWORD none; + PDWORD InterpreterFP; } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS; #else diff --git a/src/coreclr/vm/eetwain.cpp b/src/coreclr/vm/eetwain.cpp index 4d84204dee347b..5c8b653a3c3a8b 100644 --- a/src/coreclr/vm/eetwain.cpp +++ b/src/coreclr/vm/eetwain.cpp @@ -2204,10 +2204,13 @@ DWORD_PTR InterpreterCodeManager::CallFunclet(OBJECTREF throwable, void* pHandle void InterpreterCodeManager::ResumeAfterCatch(CONTEXT *pContext, size_t targetSSP, bool fIntercepted) { - Thread *pThread = GetThread(); - InterpreterFrame * pInterpreterFrame = (InterpreterFrame*)pThread->GetFrame(); TADDR resumeSP = GetSP(pContext); TADDR resumeIP = GetIP(pContext); +#ifdef TARGET_WASM + throw ResumeAfterCatchException(resumeSP, resumeIP); +#else + Thread *pThread = GetThread(); + InterpreterFrame * pInterpreterFrame = (InterpreterFrame*)pThread->GetFrame(); ClrCaptureContext(pContext); @@ -2237,6 +2240,7 @@ void InterpreterCodeManager::ResumeAfterCatch(CONTEXT *pContext, size_t targetSS targetSSP = pInterpreterFrame->GetInterpExecMethodSSP(); #endif ExecuteFunctionBelowContext((PCODE)ThrowResumeAfterCatchException, pContext, targetSSP, resumeSP, resumeIP); +#endif // TARGET_WASM } #if defined(HOST_AMD64) && defined(HOST_WINDOWS) diff --git a/src/coreclr/vm/wasm/cgencpu.h b/src/coreclr/vm/wasm/cgencpu.h index e36a95297127b6..535aa409eeb051 100644 --- a/src/coreclr/vm/wasm/cgencpu.h +++ b/src/coreclr/vm/wasm/cgencpu.h @@ -26,12 +26,6 @@ inline unsigned StackElemSize(unsigned parmSize, bool isValueType = false /* unu return 0; } -inline TADDR GetSP(const T_CONTEXT * context) -{ - _ASSERTE("The function is not implemented on wasm, it lacks registers"); - return 0; -} - struct HijackArgs { }; @@ -92,27 +86,34 @@ class StubLinkerCPU : public StubLinker // Exception handling //********************************************************************** -inline PCODE GetIP(const T_CONTEXT * context) { - _ASSERT("GetIP is not implemented on wasm, it lacks registers"); - return 0; +inline PCODE GetIP(const T_CONTEXT * context) +{ + return context->InterpreterIP; } -inline void SetIP(T_CONTEXT *context, PCODE eip) { - _ASSERT("SetIP is not implemented on wasm, it lacks registers"); +inline void SetIP(T_CONTEXT *context, PCODE eip) +{ + context->InterpreterIP = eip; } -inline void SetSP(T_CONTEXT *context, TADDR esp) { - _ASSERT("SetSP is not implemented on wasm, it lacks registers"); +inline TADDR GetSP(const T_CONTEXT * context) +{ + return (TADDR)context->InterpreterSP; +} + +inline void SetSP(T_CONTEXT *context, TADDR esp) +{ + context->InterpreterSP = (TADDR)esp; } -inline void SetFP(T_CONTEXT *context, TADDR ebp) { - _ASSERT("SetFP is not implemented on wasm, it lacks registers"); +inline void SetFP(T_CONTEXT *context, TADDR ebp) +{ + context->InterpreterFP = (TADDR)ebp; } inline TADDR GetFP(const T_CONTEXT * context) { - _ASSERT("GetFP is not implemented on wasm, it lacks registers"); - return 0; + return context->InterpreterFP; } #define ENUM_CALLEE_SAVED_REGISTERS() @@ -162,13 +163,12 @@ FORCEINLINE int64_t PalInterlockedCompareExchange64(_Inout_ int64_t volatile *pD inline void SetFirstArgReg(T_CONTEXT *context, TADDR value) { - PORTABILITY_ASSERT("SetFirstArgReg is not implemented on wasm"); + context->InterpreterWalkFramePointer = (TADDR)value; } inline TADDR GetFirstArgReg(T_CONTEXT *context) { - PORTABILITY_ASSERT("GetFirstArgReg is not implemented on wasm"); - return 0; + return (TADDR)context->InterpreterWalkFramePointer; } inline void SetSecondArgReg(T_CONTEXT *context, TADDR value) diff --git a/src/coreclr/vm/wasm/helpers.cpp b/src/coreclr/vm/wasm/helpers.cpp index fdd3b73d191ce5..22d5e6f21edcab 100644 --- a/src/coreclr/vm/wasm/helpers.cpp +++ b/src/coreclr/vm/wasm/helpers.cpp @@ -119,7 +119,49 @@ void FuncEvalFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloa void InlinedCallFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats) { - PORTABILITY_ASSERT("InlinedCallFrame::UpdateRegDisplay_Impl is not implemented on wasm"); + CONTRACTL + { + NOTHROW; + GC_NOTRIGGER; +#ifdef PROFILING_SUPPORTED + PRECONDITION(CORProfilerStackSnapshotEnabled() || InlinedCallFrame::FrameHasActiveCall(this)); +#endif + MODE_ANY; + SUPPORTS_DAC; + } + CONTRACTL_END; + + if (!InlinedCallFrame::FrameHasActiveCall(this)) + { + LOG((LF_CORDB, LL_ERROR, "WARNING: InlinedCallFrame::UpdateRegDisplay called on inactive frame %p\n", this)); + return; + } + + pRD->pCurrentContext->InterpreterIP = *(DWORD *)&m_pCallerReturnAddress; + + pRD->IsCallerContextValid = FALSE; + pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary. + + pRD->pCurrentContext->InterpreterSP = *(DWORD *)&m_pCallSiteSP; + pRD->pCurrentContext->InterpreterFP = *(DWORD *)&m_pCalleeSavedFP; + +#define CALLEE_SAVED_REGISTER(regname) pRD->pCurrentContextPointers->regname = NULL; + ENUM_CALLEE_SAVED_REGISTERS(); +#undef CALLEE_SAVED_REGISTER + + pRD->pCurrentContextPointers->InterpreterFP = (DWORD *)&m_pCalleeSavedFP; + + SyncRegDisplayToCurrentContext(pRD); + +#ifdef FEATURE_INTERPRETER + if ((m_Next != FRAME_TOP) && (m_Next->GetFrameIdentifier() == FrameIdentifier::InterpreterFrame)) + { + // If the next frame is an interpreter frame, we also need to set the first argument register to point to the interpreter frame. + SetFirstArgReg(pRD->pCurrentContext, dac_cast(m_Next)); + } +#endif // FEATURE_INTERPRETER + + LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK InlinedCallFrame::UpdateRegDisplay_Impl(rip:%p, rsp:%p)\n", pRD->ControlPC, pRD->SP)); } void FaultingExceptionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats) From 3a0f4821a299417c9fad6d595ec4f8ad7f8ad39a Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 18 Sep 2025 19:24:45 +0200 Subject: [PATCH 04/11] Feedback --- src/coreclr/inc/regdisp.h | 8 +------- src/coreclr/pal/inc/pal.h | 2 +- src/coreclr/vm/wasm/cgencpu.h | 12 ++++++------ src/coreclr/vm/wasm/helpers.cpp | 2 -- 4 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/coreclr/inc/regdisp.h b/src/coreclr/inc/regdisp.h index 889975344690dd..4560d7a493392e 100644 --- a/src/coreclr/inc/regdisp.h +++ b/src/coreclr/inc/regdisp.h @@ -397,13 +397,7 @@ inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD) #if defined(TARGET_64BIT) pRD->SP = (INT_PTR)GetSP(pRD->pCurrentContext); pRD->ControlPC = (INT_PTR)GetIP(pRD->pCurrentContext); -#elif defined(TARGET_ARM) - pRD->SP = (DWORD)GetSP(pRD->pCurrentContext); - pRD->ControlPC = (DWORD)GetIP(pRD->pCurrentContext); -#elif defined(TARGET_X86) - pRD->SP = (DWORD)GetSP(pRD->pCurrentContext); - pRD->ControlPC = (DWORD)GetIP(pRD->pCurrentContext); -#elif defined(TARGET_WASM) +#elif defined(TARGET_ARM) || defined(TARGET_X86) || defined(TARGET_WASM) pRD->SP = (DWORD)GetSP(pRD->pCurrentContext); pRD->ControlPC = (DWORD)GetIP(pRD->pCurrentContext); #else // TARGET_WASM diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 9b3fe625cab77c..f48f662fac9cf1 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -2410,7 +2410,7 @@ typedef struct _CONTEXT { } CONTEXT, *PCONTEXT, *LPCONTEXT; typedef struct _KNONVOLATILE_CONTEXT_POINTERS { - PDWORD InterpreterFP; + DWORD none; } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS; #else diff --git a/src/coreclr/vm/wasm/cgencpu.h b/src/coreclr/vm/wasm/cgencpu.h index 535aa409eeb051..bb8f6a23ef49ce 100644 --- a/src/coreclr/vm/wasm/cgencpu.h +++ b/src/coreclr/vm/wasm/cgencpu.h @@ -91,9 +91,9 @@ inline PCODE GetIP(const T_CONTEXT * context) return context->InterpreterIP; } -inline void SetIP(T_CONTEXT *context, PCODE eip) +inline void SetIP(T_CONTEXT *context, PCODE ip) { - context->InterpreterIP = eip; + context->InterpreterIP = ip; } inline TADDR GetSP(const T_CONTEXT * context) @@ -101,14 +101,14 @@ inline TADDR GetSP(const T_CONTEXT * context) return (TADDR)context->InterpreterSP; } -inline void SetSP(T_CONTEXT *context, TADDR esp) +inline void SetSP(T_CONTEXT *context, TADDR sp) { - context->InterpreterSP = (TADDR)esp; + context->InterpreterSP = (TADDR)sp; } -inline void SetFP(T_CONTEXT *context, TADDR ebp) +inline void SetFP(T_CONTEXT *context, TADDR fp) { - context->InterpreterFP = (TADDR)ebp; + context->InterpreterFP = (TADDR)fp; } inline TADDR GetFP(const T_CONTEXT * context) diff --git a/src/coreclr/vm/wasm/helpers.cpp b/src/coreclr/vm/wasm/helpers.cpp index 22d5e6f21edcab..ca00099be2fd1b 100644 --- a/src/coreclr/vm/wasm/helpers.cpp +++ b/src/coreclr/vm/wasm/helpers.cpp @@ -149,8 +149,6 @@ void InlinedCallFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateF ENUM_CALLEE_SAVED_REGISTERS(); #undef CALLEE_SAVED_REGISTER - pRD->pCurrentContextPointers->InterpreterFP = (DWORD *)&m_pCalleeSavedFP; - SyncRegDisplayToCurrentContext(pRD); #ifdef FEATURE_INTERPRETER From 4ac4b0d9581f76d825edd2f05c749c6510dd17e0 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 18 Sep 2025 19:27:48 +0200 Subject: [PATCH 05/11] Revert "Feedback" This reverts commit 3a0f4821a299417c9fad6d595ec4f8ad7f8ad39a. --- src/coreclr/inc/regdisp.h | 8 +++++++- src/coreclr/pal/inc/pal.h | 2 +- src/coreclr/vm/wasm/cgencpu.h | 12 ++++++------ src/coreclr/vm/wasm/helpers.cpp | 2 ++ 4 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/coreclr/inc/regdisp.h b/src/coreclr/inc/regdisp.h index 4560d7a493392e..889975344690dd 100644 --- a/src/coreclr/inc/regdisp.h +++ b/src/coreclr/inc/regdisp.h @@ -397,7 +397,13 @@ inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD) #if defined(TARGET_64BIT) pRD->SP = (INT_PTR)GetSP(pRD->pCurrentContext); pRD->ControlPC = (INT_PTR)GetIP(pRD->pCurrentContext); -#elif defined(TARGET_ARM) || defined(TARGET_X86) || defined(TARGET_WASM) +#elif defined(TARGET_ARM) + pRD->SP = (DWORD)GetSP(pRD->pCurrentContext); + pRD->ControlPC = (DWORD)GetIP(pRD->pCurrentContext); +#elif defined(TARGET_X86) + pRD->SP = (DWORD)GetSP(pRD->pCurrentContext); + pRD->ControlPC = (DWORD)GetIP(pRD->pCurrentContext); +#elif defined(TARGET_WASM) pRD->SP = (DWORD)GetSP(pRD->pCurrentContext); pRD->ControlPC = (DWORD)GetIP(pRD->pCurrentContext); #else // TARGET_WASM diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index f48f662fac9cf1..9b3fe625cab77c 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -2410,7 +2410,7 @@ typedef struct _CONTEXT { } CONTEXT, *PCONTEXT, *LPCONTEXT; typedef struct _KNONVOLATILE_CONTEXT_POINTERS { - DWORD none; + PDWORD InterpreterFP; } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS; #else diff --git a/src/coreclr/vm/wasm/cgencpu.h b/src/coreclr/vm/wasm/cgencpu.h index bb8f6a23ef49ce..535aa409eeb051 100644 --- a/src/coreclr/vm/wasm/cgencpu.h +++ b/src/coreclr/vm/wasm/cgencpu.h @@ -91,9 +91,9 @@ inline PCODE GetIP(const T_CONTEXT * context) return context->InterpreterIP; } -inline void SetIP(T_CONTEXT *context, PCODE ip) +inline void SetIP(T_CONTEXT *context, PCODE eip) { - context->InterpreterIP = ip; + context->InterpreterIP = eip; } inline TADDR GetSP(const T_CONTEXT * context) @@ -101,14 +101,14 @@ inline TADDR GetSP(const T_CONTEXT * context) return (TADDR)context->InterpreterSP; } -inline void SetSP(T_CONTEXT *context, TADDR sp) +inline void SetSP(T_CONTEXT *context, TADDR esp) { - context->InterpreterSP = (TADDR)sp; + context->InterpreterSP = (TADDR)esp; } -inline void SetFP(T_CONTEXT *context, TADDR fp) +inline void SetFP(T_CONTEXT *context, TADDR ebp) { - context->InterpreterFP = (TADDR)fp; + context->InterpreterFP = (TADDR)ebp; } inline TADDR GetFP(const T_CONTEXT * context) diff --git a/src/coreclr/vm/wasm/helpers.cpp b/src/coreclr/vm/wasm/helpers.cpp index ca00099be2fd1b..22d5e6f21edcab 100644 --- a/src/coreclr/vm/wasm/helpers.cpp +++ b/src/coreclr/vm/wasm/helpers.cpp @@ -149,6 +149,8 @@ void InlinedCallFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateF ENUM_CALLEE_SAVED_REGISTERS(); #undef CALLEE_SAVED_REGISTER + pRD->pCurrentContextPointers->InterpreterFP = (DWORD *)&m_pCalleeSavedFP; + SyncRegDisplayToCurrentContext(pRD); #ifdef FEATURE_INTERPRETER From a3ca1d05b515480a8fea01da04579838e0dbe823 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 18 Sep 2025 19:27:49 +0200 Subject: [PATCH 06/11] Revert "Progress with EH on wasm" This reverts commit f566b4a211d7d021155e6524f18ad4e779516f68. --- .../Runtime/ExceptionServices/AsmOffsets.cs | 8 ++-- src/coreclr/inc/regdisp.h | 11 ++--- src/coreclr/pal/inc/pal.h | 7 +-- src/coreclr/vm/eetwain.cpp | 8 +--- src/coreclr/vm/wasm/cgencpu.h | 40 ++++++++--------- src/coreclr/vm/wasm/helpers.cpp | 44 +------------------ 6 files changed, 34 insertions(+), 84 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs index 193c7456e0803b..105c8321b2849e 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/ExceptionServices/AsmOffsets.cs @@ -51,9 +51,9 @@ class AsmOffsets public const int OFFSETOF__REGDISPLAY__SP = 0xba8; public const int OFFSETOF__REGDISPLAY__ControlPC = 0xbb0; #elif TARGET_WASM - public const int SIZEOF__REGDISPLAY = 0x58; - public const int OFFSETOF__REGDISPLAY__SP = 0x50; - public const int OFFSETOF__REGDISPLAY__ControlPC = 0x54; + public const int SIZEOF__REGDISPLAY = 0x38; + public const int OFFSETOF__REGDISPLAY__SP = 0x30; + public const int OFFSETOF__REGDISPLAY__ControlPC = 0x34; #endif #if TARGET_64BIT @@ -177,7 +177,7 @@ class AsmOffsets #elif TARGET_LOONGARCH64 public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x520; #elif TARGET_WASM - public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x14; + public const int SIZEOF__PAL_LIMITED_CONTEXT = 0x04; #endif #if TARGET_AMD64 diff --git a/src/coreclr/inc/regdisp.h b/src/coreclr/inc/regdisp.h index 889975344690dd..78340a4268431b 100644 --- a/src/coreclr/inc/regdisp.h +++ b/src/coreclr/inc/regdisp.h @@ -356,6 +356,10 @@ struct REGDISPLAY : public REGDISPLAY_BASE { } }; +inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD) +{ +} + // This function tells us if the given stack pointer is in one of the frames of the functions called by the given frame inline BOOL IsInCalleesFrames(REGDISPLAY *display, LPVOID stackPointer) { _ASSERTE("IsInCalleesFrames is not implemented on wasm"); @@ -366,7 +370,7 @@ inline BOOL IsInCalleesFrames(REGDISPLAY *display, LPVOID stackPointer) { #error "RegDisplay functions are not implemented on this platform." #endif -#if defined(TARGET_64BIT) || defined(TARGET_ARM) || (defined(TARGET_X86) && defined(FEATURE_EH_FUNCLETS) || defined(TARGET_WASM)) +#if defined(TARGET_64BIT) || defined(TARGET_ARM) || (defined(TARGET_X86) && defined(FEATURE_EH_FUNCLETS)) // This needs to be implemented for platforms that have funclets. inline LPVOID GetRegdisplayReturnValue(REGDISPLAY *display) { @@ -403,10 +407,7 @@ inline void SyncRegDisplayToCurrentContext(REGDISPLAY* pRD) #elif defined(TARGET_X86) pRD->SP = (DWORD)GetSP(pRD->pCurrentContext); pRD->ControlPC = (DWORD)GetIP(pRD->pCurrentContext); -#elif defined(TARGET_WASM) - pRD->SP = (DWORD)GetSP(pRD->pCurrentContext); - pRD->ControlPC = (DWORD)GetIP(pRD->pCurrentContext); -#else // TARGET_WASM +#else // TARGET_X86 PORTABILITY_ASSERT("SyncRegDisplayToCurrentContext"); #endif diff --git a/src/coreclr/pal/inc/pal.h b/src/coreclr/pal/inc/pal.h index 9b3fe625cab77c..766d4cdc9f7c8c 100644 --- a/src/coreclr/pal/inc/pal.h +++ b/src/coreclr/pal/inc/pal.h @@ -2402,15 +2402,10 @@ typedef struct _KNONVOLATILE_CONTEXT_POINTERS { typedef struct _CONTEXT { ULONG ContextFlags; - - DWORD InterpreterWalkFramePointer; - DWORD InterpreterSP; - DWORD InterpreterFP; - DWORD InterpreterIP; } CONTEXT, *PCONTEXT, *LPCONTEXT; typedef struct _KNONVOLATILE_CONTEXT_POINTERS { - PDWORD InterpreterFP; + DWORD none; } KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS; #else diff --git a/src/coreclr/vm/eetwain.cpp b/src/coreclr/vm/eetwain.cpp index 5c8b653a3c3a8b..4d84204dee347b 100644 --- a/src/coreclr/vm/eetwain.cpp +++ b/src/coreclr/vm/eetwain.cpp @@ -2204,13 +2204,10 @@ DWORD_PTR InterpreterCodeManager::CallFunclet(OBJECTREF throwable, void* pHandle void InterpreterCodeManager::ResumeAfterCatch(CONTEXT *pContext, size_t targetSSP, bool fIntercepted) { - TADDR resumeSP = GetSP(pContext); - TADDR resumeIP = GetIP(pContext); -#ifdef TARGET_WASM - throw ResumeAfterCatchException(resumeSP, resumeIP); -#else Thread *pThread = GetThread(); InterpreterFrame * pInterpreterFrame = (InterpreterFrame*)pThread->GetFrame(); + TADDR resumeSP = GetSP(pContext); + TADDR resumeIP = GetIP(pContext); ClrCaptureContext(pContext); @@ -2240,7 +2237,6 @@ void InterpreterCodeManager::ResumeAfterCatch(CONTEXT *pContext, size_t targetSS targetSSP = pInterpreterFrame->GetInterpExecMethodSSP(); #endif ExecuteFunctionBelowContext((PCODE)ThrowResumeAfterCatchException, pContext, targetSSP, resumeSP, resumeIP); -#endif // TARGET_WASM } #if defined(HOST_AMD64) && defined(HOST_WINDOWS) diff --git a/src/coreclr/vm/wasm/cgencpu.h b/src/coreclr/vm/wasm/cgencpu.h index 535aa409eeb051..e36a95297127b6 100644 --- a/src/coreclr/vm/wasm/cgencpu.h +++ b/src/coreclr/vm/wasm/cgencpu.h @@ -26,6 +26,12 @@ inline unsigned StackElemSize(unsigned parmSize, bool isValueType = false /* unu return 0; } +inline TADDR GetSP(const T_CONTEXT * context) +{ + _ASSERTE("The function is not implemented on wasm, it lacks registers"); + return 0; +} + struct HijackArgs { }; @@ -86,34 +92,27 @@ class StubLinkerCPU : public StubLinker // Exception handling //********************************************************************** -inline PCODE GetIP(const T_CONTEXT * context) -{ - return context->InterpreterIP; -} - -inline void SetIP(T_CONTEXT *context, PCODE eip) -{ - context->InterpreterIP = eip; +inline PCODE GetIP(const T_CONTEXT * context) { + _ASSERT("GetIP is not implemented on wasm, it lacks registers"); + return 0; } -inline TADDR GetSP(const T_CONTEXT * context) -{ - return (TADDR)context->InterpreterSP; +inline void SetIP(T_CONTEXT *context, PCODE eip) { + _ASSERT("SetIP is not implemented on wasm, it lacks registers"); } -inline void SetSP(T_CONTEXT *context, TADDR esp) -{ - context->InterpreterSP = (TADDR)esp; +inline void SetSP(T_CONTEXT *context, TADDR esp) { + _ASSERT("SetSP is not implemented on wasm, it lacks registers"); } -inline void SetFP(T_CONTEXT *context, TADDR ebp) -{ - context->InterpreterFP = (TADDR)ebp; +inline void SetFP(T_CONTEXT *context, TADDR ebp) { + _ASSERT("SetFP is not implemented on wasm, it lacks registers"); } inline TADDR GetFP(const T_CONTEXT * context) { - return context->InterpreterFP; + _ASSERT("GetFP is not implemented on wasm, it lacks registers"); + return 0; } #define ENUM_CALLEE_SAVED_REGISTERS() @@ -163,12 +162,13 @@ FORCEINLINE int64_t PalInterlockedCompareExchange64(_Inout_ int64_t volatile *pD inline void SetFirstArgReg(T_CONTEXT *context, TADDR value) { - context->InterpreterWalkFramePointer = (TADDR)value; + PORTABILITY_ASSERT("SetFirstArgReg is not implemented on wasm"); } inline TADDR GetFirstArgReg(T_CONTEXT *context) { - return (TADDR)context->InterpreterWalkFramePointer; + PORTABILITY_ASSERT("GetFirstArgReg is not implemented on wasm"); + return 0; } inline void SetSecondArgReg(T_CONTEXT *context, TADDR value) diff --git a/src/coreclr/vm/wasm/helpers.cpp b/src/coreclr/vm/wasm/helpers.cpp index 22d5e6f21edcab..fdd3b73d191ce5 100644 --- a/src/coreclr/vm/wasm/helpers.cpp +++ b/src/coreclr/vm/wasm/helpers.cpp @@ -119,49 +119,7 @@ void FuncEvalFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloa void InlinedCallFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats) { - CONTRACTL - { - NOTHROW; - GC_NOTRIGGER; -#ifdef PROFILING_SUPPORTED - PRECONDITION(CORProfilerStackSnapshotEnabled() || InlinedCallFrame::FrameHasActiveCall(this)); -#endif - MODE_ANY; - SUPPORTS_DAC; - } - CONTRACTL_END; - - if (!InlinedCallFrame::FrameHasActiveCall(this)) - { - LOG((LF_CORDB, LL_ERROR, "WARNING: InlinedCallFrame::UpdateRegDisplay called on inactive frame %p\n", this)); - return; - } - - pRD->pCurrentContext->InterpreterIP = *(DWORD *)&m_pCallerReturnAddress; - - pRD->IsCallerContextValid = FALSE; - pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary. - - pRD->pCurrentContext->InterpreterSP = *(DWORD *)&m_pCallSiteSP; - pRD->pCurrentContext->InterpreterFP = *(DWORD *)&m_pCalleeSavedFP; - -#define CALLEE_SAVED_REGISTER(regname) pRD->pCurrentContextPointers->regname = NULL; - ENUM_CALLEE_SAVED_REGISTERS(); -#undef CALLEE_SAVED_REGISTER - - pRD->pCurrentContextPointers->InterpreterFP = (DWORD *)&m_pCalleeSavedFP; - - SyncRegDisplayToCurrentContext(pRD); - -#ifdef FEATURE_INTERPRETER - if ((m_Next != FRAME_TOP) && (m_Next->GetFrameIdentifier() == FrameIdentifier::InterpreterFrame)) - { - // If the next frame is an interpreter frame, we also need to set the first argument register to point to the interpreter frame. - SetFirstArgReg(pRD->pCurrentContext, dac_cast(m_Next)); - } -#endif // FEATURE_INTERPRETER - - LOG((LF_GCROOTS, LL_INFO100000, "STACKWALK InlinedCallFrame::UpdateRegDisplay_Impl(rip:%p, rsp:%p)\n", pRD->ControlPC, pRD->SP)); + PORTABILITY_ASSERT("InlinedCallFrame::UpdateRegDisplay_Impl is not implemented on wasm"); } void FaultingExceptionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats) From 737f8a53582019f9f74a6bf4f1790cc9e707ed66 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 18 Sep 2025 19:34:35 +0200 Subject: [PATCH 07/11] Fix build --- src/coreclr/hosts/corewasmrun/corewasmrun.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/hosts/corewasmrun/corewasmrun.cpp b/src/coreclr/hosts/corewasmrun/corewasmrun.cpp index 6b5e745231f905..a0db7b5f2256f1 100644 --- a/src/coreclr/hosts/corewasmrun/corewasmrun.cpp +++ b/src/coreclr/hosts/corewasmrun/corewasmrun.cpp @@ -36,7 +36,7 @@ static int run() wasm_add_pinvoke_override(); printf("BEGIN: call wasm_load_icu_data\n"); - retval = wasm_load_icu_data("/"); + int retval = wasm_load_icu_data("/"); printf("END: call wasm_load_icu_data\n"); if (retval == 0) @@ -46,7 +46,7 @@ static int run() } printf("BEGIN: call coreclr_initialize\n"); - int retval = coreclr_initialize(exe_path, app_domain_name, (int)propertyKeys.size(), propertyKeys.data(), propertyValues.data(), &CurrentClrInstance, &CurrentAppDomainId); + retval = coreclr_initialize(exe_path, app_domain_name, (int)propertyKeys.size(), propertyKeys.data(), propertyValues.data(), &CurrentClrInstance, &CurrentAppDomainId); printf("END: call coreclr_initialize\n"); if (retval < 0) From b51566f89b9c3a6b24c842bc808aa1629d683431 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Tue, 23 Sep 2025 16:16:59 +0200 Subject: [PATCH 08/11] Disable fat tokes temporarily and update VirtualCallStubManager::Resolver To work with protable entrypoints --- src/coreclr/vm/contractimpl.h | 3 ++- src/coreclr/vm/virtualcallstub.cpp | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/coreclr/vm/contractimpl.h b/src/coreclr/vm/contractimpl.h index 0f74d8b22545ac..a9466cfe72ebac 100644 --- a/src/coreclr/vm/contractimpl.h +++ b/src/coreclr/vm/contractimpl.h @@ -317,7 +317,8 @@ struct DispatchToken { LIMITED_METHOD_CONTRACT; return typeID > MAX_TYPE_ID_SMALL -#ifdef _DEBUG +// WASM-TODO: fix fat tokens +#if defined(_DEBUG) && !defined(TARGET_WASM) // Stress the overflow mechanism in debug builds. || ((typeID != TYPE_ID_THIS_CLASS) && ((typeID % 7) < 4)) #endif diff --git a/src/coreclr/vm/virtualcallstub.cpp b/src/coreclr/vm/virtualcallstub.cpp index 96160b3cacf20a..cb661080668b14 100644 --- a/src/coreclr/vm/virtualcallstub.cpp +++ b/src/coreclr/vm/virtualcallstub.cpp @@ -2318,7 +2318,7 @@ VirtualCallStubManager::Resolver( } } #endif // defined(LOGGING) || defined(_DEBUG) - +#ifndef FEATURE_PORTABLE_ENTRYPOINTS BOOL fSlotCallsPrestub = DoesSlotCallPrestub(implSlot.GetTarget()); if (!fSlotCallsPrestub) { @@ -2326,6 +2326,10 @@ VirtualCallStubManager::Resolver( fShouldPatch = TRUE; } else +#else + BOOL fSlotCallsPrestub = FALSE; + fShouldPatch = TRUE; +#endif // !FEATURE_PORTABLE_ENTRYPOINTS { // Getting the MethodDesc is very expensive, // so only call this when we are calling the prestub From 4185cad2f51b7dc3a9d4cb46e4bdb5cc0a33f605 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Tue, 23 Sep 2025 16:38:20 +0200 Subject: [PATCH 09/11] Add calli helper for GlobalizationNative_GetLocaleInfoString --- src/coreclr/vm/wasm/helpers.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/coreclr/vm/wasm/helpers.cpp b/src/coreclr/vm/wasm/helpers.cpp index fdd3b73d191ce5..a46eda4f696e5c 100644 --- a/src/coreclr/vm/wasm/helpers.cpp +++ b/src/coreclr/vm/wasm/helpers.cpp @@ -480,6 +480,12 @@ namespace *(int32_t*)pRet = (*fptr)(ARG(0), ARG(1), ARG(2), ARG(3)); } + void CallFunc_I32_I32_I32_I32_I32_RetI32(PCODE pcode, int8_t *pArgs, int8_t *pRet) + { + int32_t (*fptr)(int32_t, int32_t, int32_t, int32_t, int32_t) = (int32_t (*)(int32_t, int32_t, int32_t, int32_t, int32_t))pcode; + *(int32_t*)pRet = (*fptr)(ARG(0), ARG(1), ARG(2), ARG(3), ARG(4)); + } + // Special thunks for signatures with indirect arguments. void CallFunc_I32IND_RetVoid(PCODE pcode, int8_t *pArgs, int8_t *pRet) @@ -539,6 +545,7 @@ namespace (void*)&CallFunc_I32_I32_RetI32, (void*)&CallFunc_I32_I32_I32_RetI32, (void*)&CallFunc_I32_I32_I32_I32_RetI32, + (void*)&CallFunc_I32_I32_I32_I32_I32_RetI32, }; enum class ConvertType From e5c747275de170620fe085c973c43e23e0827c51 Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 25 Sep 2025 11:45:05 +0200 Subject: [PATCH 10/11] Fix build after merge --- src/coreclr/vm/virtualcallstub.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/coreclr/vm/virtualcallstub.cpp b/src/coreclr/vm/virtualcallstub.cpp index 9bd7d80f4f06dc..a7498525c98ee6 100644 --- a/src/coreclr/vm/virtualcallstub.cpp +++ b/src/coreclr/vm/virtualcallstub.cpp @@ -2326,10 +2326,6 @@ VirtualCallStubManager::Resolver( fShouldPatch = TRUE; } else -#else - BOOL fSlotCallsPrestub = FALSE; - fShouldPatch = TRUE; -#endif // !FEATURE_PORTABLE_ENTRYPOINTS { // Getting the MethodDesc is very expensive, // so only call this when we are calling the prestub From df7cda424f2296f57f4af0abb602d23a50032bfb Mon Sep 17 00:00:00 2001 From: Radek Doulik Date: Thu, 25 Sep 2025 13:23:51 +0200 Subject: [PATCH 11/11] Fix non-working asserts --- src/coreclr/vm/wasm/cgencpu.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/coreclr/vm/wasm/cgencpu.h b/src/coreclr/vm/wasm/cgencpu.h index 0472cd2c2e937e..868c43244078e4 100644 --- a/src/coreclr/vm/wasm/cgencpu.h +++ b/src/coreclr/vm/wasm/cgencpu.h @@ -32,7 +32,8 @@ struct HijackArgs inline LPVOID STDCALL GetCurrentSP() { - _ASSERTE("The function is not implemented on wasm, it lacks registers"); + // WASM-TODO: check where we reach that, return nullptr for now to not break runtime initialization + //PORTABILITY_ASSERT("The function is not implemented on wasm, it lacks registers"); return nullptr; } @@ -75,10 +76,10 @@ class StubLinkerCPU : public StubLinker public: static void Init() { /* no-op on wasm */ } inline void EmitShuffleThunk(struct ShuffleEntry *pShuffleEntryArray) { - _ASSERTE("The EmitShuffleThunk is not implemented on wasm"); + PORTABILITY_ASSERT("The EmitShuffleThunk is not implemented on wasm"); } inline VOID EmitComputedInstantiatingMethodStub(MethodDesc* pSharedMD, struct ShuffleEntry *pShuffleEntryArray, void* extraArg) { - _ASSERTE("The EmitComputedInstantiatingMethodStub is not implemented on wasm"); + PORTABILITY_ASSERT("The EmitComputedInstantiatingMethodStub is not implemented on wasm"); } }; @@ -144,13 +145,13 @@ inline BOOL ClrFlushInstructionCache(LPCVOID pCodeAddr, size_t sizeOfCode, bool //------------------------------------------------------------------------ inline void emitBackToBackJump(LPBYTE pBufferRX, LPBYTE pBufferRW, LPVOID target) { - _ASSERTE("emitBackToBackJump is not implemented on wasm"); + PORTABILITY_ASSERT("emitBackToBackJump is not implemented on wasm"); } //------------------------------------------------------------------------ inline PCODE decodeBackToBackJump(PCODE pBuffer) { - _ASSERTE("decodeBackToBackJump is not implemented on wasm"); + PORTABILITY_ASSERT("decodeBackToBackJump is not implemented on wasm"); return 0; }