From d3185c0aa73cce511cee66fb0c7d0bceef348976 Mon Sep 17 00:00:00 2001 From: Katelyn Gadd Date: Thu, 22 May 2025 09:00:33 -0700 Subject: [PATCH] Implement CEE_LDOBJ and CEE_STOBJ in the interpreter via ldind/stind --- src/coreclr/interpreter/compiler.cpp | 19 ++++++++++++++++ src/tests/JIT/interpreter/Interpreter.cs | 29 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/src/coreclr/interpreter/compiler.cpp b/src/coreclr/interpreter/compiler.cpp index 9b3a3a809a26f8..d0d5b90e2090ab 100644 --- a/src/coreclr/interpreter/compiler.cpp +++ b/src/coreclr/interpreter/compiler.cpp @@ -2427,6 +2427,25 @@ int InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) m_ip++; break; + case CEE_LDOBJ: + case CEE_STOBJ: + { + CHECK_STACK(*m_ip == CEE_LDOBJ ? 1 : 2); + CORINFO_RESOLVED_TOKEN resolvedToken; + ResolveToken(getU4LittleEndian(m_ip + 1), CORINFO_TOKENKIND_Class, &resolvedToken); + InterpType interpType = GetInterpType(m_compHnd->asCorInfoType(resolvedToken.hClass)); + if (*m_ip == CEE_LDOBJ) + { + EmitLdind(interpType, resolvedToken.hClass, 0); + } + else + { + EmitStind(interpType, resolvedToken.hClass, 0, false); + } + m_ip += 5; + break; + } + case CEE_RET: { CORINFO_SIG_INFO sig = methodInfo->args; diff --git a/src/tests/JIT/interpreter/Interpreter.cs b/src/tests/JIT/interpreter/Interpreter.cs index a78df5ef49b14e..b0b059a422e62c 100644 --- a/src/tests/JIT/interpreter/Interpreter.cs +++ b/src/tests/JIT/interpreter/Interpreter.cs @@ -416,6 +416,9 @@ public static void RunInterpreterTests() if (!TestArray()) Environment.FailFast(null); + if (!TestXxObj()) + Environment.FailFast(null); + if (!TestSizeof()) Environment.FailFast(null); @@ -956,6 +959,32 @@ public static bool ArrayDouble(int length, double value) return true; } + public static unsafe bool TestXxObj() + { + // FIXME: There is no way to generate cpobj opcodes with roslyn at present. + // The only source of cpobj I've found other than hand-written IL tests is ilmarshalers.h, so once pinvoke marshaling is + // supported, we can use that to verify that cpobj works. Until then, this method only tests ldobj/stobj. + TestStruct4fi a = new TestStruct4fi + { + a = 1, + b = 2, + c = 3, + d = 4, + }, b = default; + ref TestStruct4fi c = ref a, + d = ref b; + + if (b.a == a.a) + return false; + + c = d; + + if (b.a != a.a) + return false; + + return true; + } + public static unsafe bool TestSizeof() { if (sizeof(int) != 4)