-
Notifications
You must be signed in to change notification settings - Fork 14
/
DynamicCompilation.cs
55 lines (52 loc) · 2.15 KB
/
DynamicCompilation.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
using UnityEngine;
// https://en.wikipedia.org/wiki/List_of_CIL_instructions
public class DynamicCompilation : MonoBehaviour
{
void CreateDynamicMethodA()
{
DynamicMethod dynamicMethod = new DynamicMethod("SortList", null, new Type[] {typeof(List<string>)}, typeof(DynamicCompilation).Module);
ILGenerator il = dynamicMethod.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
MethodInfo methodInfo = typeof(List<string>).GetMethod("Sort", Type.EmptyTypes);
il.Emit(OpCodes.Callvirt, methodInfo);
il.Emit(OpCodes.Ret);
Action<List<string>> action = (Action<List<string>>)dynamicMethod.CreateDelegate(typeof(Action<List<string>>));
List<string> list = new List<string> {"banana", "apple", "date", "cherry"};
Debug.LogError("Before sorting: " + string.Join(", ", list));
action(list);
Debug.LogError("After sorting: " + string.Join(", ", list));
}
void CreateDynamicMethodB()
{
AssemblyName assemblyName = new AssemblyName("DynamicAssembly");
AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
TypeBuilder typeBuilder = moduleBuilder.DefineType("DynamicClass", TypeAttributes.Public);
MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.Static;
MethodBuilder methodBuilder = typeBuilder.DefineMethod("Add", attributes, typeof(int), new Type[] {typeof(int), typeof(int)});
ILGenerator il = methodBuilder.GetILGenerator();
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Add);
il.Emit(OpCodes.Ret);
Type type = typeBuilder.CreateType();
MethodInfo methodInfo = type.GetMethod("Add");
object result = methodInfo.Invoke(null, new object[] { 10, 20 });
Debug.LogError("Result of dynamically generated Add method: " + result); // Should print: 30
}
void Update()
{
if (Input.GetKeyDown(KeyCode.O))
{
CreateDynamicMethodA();
}
if (Input.GetKeyDown(KeyCode.P))
{
CreateDynamicMethodB();
}
}
}