From 499ba09295088f9d822f147a0ad5cb39de4c3c77 Mon Sep 17 00:00:00 2001
From: zznty <94796179+zznty@users.noreply.github.com>
Date: Sun, 24 Nov 2024 14:28:35 +0700
Subject: [PATCH] Add test for CecilILGenerator declare local
---
src/MonoMod.UnitTest/CecilIlGeneratorTest.cs | 73 ++++++++++++++++++++
1 file changed, 73 insertions(+)
create mode 100644 src/MonoMod.UnitTest/CecilIlGeneratorTest.cs
diff --git a/src/MonoMod.UnitTest/CecilIlGeneratorTest.cs b/src/MonoMod.UnitTest/CecilIlGeneratorTest.cs
new file mode 100644
index 00000000..6e0edbb7
--- /dev/null
+++ b/src/MonoMod.UnitTest/CecilIlGeneratorTest.cs
@@ -0,0 +1,73 @@
+using Mono.Cecil;
+using MonoMod.Utils.Cil;
+using System;
+using System.IO;
+using System.Reflection;
+using System.Reflection.Emit;
+using Xunit;
+using Xunit.Abstractions;
+using MethodAttributes = Mono.Cecil.MethodAttributes;
+using TypeAttributes = Mono.Cecil.TypeAttributes;
+
+namespace MonoMod.UnitTest
+{
+ public class CecilIlGeneratorTest : TestBase
+ {
+ public CecilIlGeneratorTest(ITestOutputHelper helper) : base(helper)
+ {
+ }
+
+ [Fact]
+ public void TestLocalEmit()
+ {
+ using var moduleStream = new MemoryStream();
+ using (var moduleDef = ModuleDefinition.CreateModule("TestModule", ModuleKind.Dll))
+ {
+ var methodDef = new MethodDefinition("TestMethod",
+ MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static,
+ moduleDef.TypeSystem.String);
+
+ moduleDef.Types.Add(new TypeDefinition("Test", "TestType",
+ TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.AnsiClass |
+ TypeAttributes.BeforeFieldInit)
+ {
+ Methods = { methodDef },
+ BaseType = moduleDef.TypeSystem.Object
+ });
+
+ methodDef.Parameters.Add(new ParameterDefinition(moduleDef.TypeSystem.Boolean));
+
+ {
+ var il = new CecilILGenerator(methodDef.Body.GetILProcessor()).GetProxy();
+
+ var local = il.DeclareLocal(typeof(string));
+
+ il.Emit(OpCodes.Ldarga_S, 0);
+ var toStringMethod = typeof(bool).GetMethod(nameof(bool.ToString), []);
+
+ Assert.NotNull(toStringMethod);
+
+ il.Emit(OpCodes.Callvirt, toStringMethod);
+ il.Emit(OpCodes.Stloc, local);
+
+ il.Emit(OpCodes.Ldloc, local);
+ il.Emit(OpCodes.Ret);
+ }
+
+ moduleDef.Write(moduleStream);
+ }
+
+ var assembly = Assembly.Load(moduleStream.ToArray());
+
+ var type = assembly.GetType("Test.TestType");
+
+ Assert.NotNull(type);
+
+ var method = type.GetMethod("TestMethod");
+
+ Assert.NotNull(method);
+ Assert.Equal(bool.TrueString, method.Invoke(null, new object[] { true }));
+ Assert.Equal(bool.FalseString, method.Invoke(null, new object[] { false }));
+ }
+ }
+}
\ No newline at end of file