2 using System.Collections.Generic;
6 namespace Inference.src.Core
10 private static string OPTIMIZER_NAMESPACE =
"StaDyn.Server";
11 private static string OPTIMIZER_NAME =
"Optimizer";
12 private static string OPTIMIZER_FULLNAME = OPTIMIZER_NAMESPACE +
"." + OPTIMIZER_NAME;
13 private static string GET_TYPE =
"callvirt instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()";
14 private static string GET_FIELD =
"callvirt instance class [mscorlib]System.Reflection.FieldInfo [mscorlib]System.Type::GetField(string)";
15 private static string INVOKE =
"callvirt instance object [mscorlib]System.Reflection.MethodBase::Invoke(object, object[])";
17 private static IDictionary<int, String> ProcessGetFields(IList<String> lines)
19 IDictionary<int, String> fields =
new Dictionary<int, String>();
20 for (
int i = 0; i < lines.Count; i++)
22 if (lines[i].EndsWith(GET_TYPE) && lines[i + 2].EndsWith(GET_FIELD) && lines[i + 17].EndsWith(INVOKE))
24 String name = lines[i + 1].Split(
'\t')[1];
25 fields.Add(i, name.Replace(
"\"",
""));
31 private static IList<String> CreateGetFields(IList<String> lines, IDictionary<int, String> fields)
33 IList<String> result =
new List<String>();
34 for (
int i = 0; i < lines.Count; i++)
36 if (fields.ContainsKey(i))
38 result.Add(
".locals init(object cs_param_" + i +
")");
39 result.Add(
"stloc cs_param_" + i);
40 result.Add(
"ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite,object,object>> " + OPTIMIZER_FULLNAME +
"::get" + fields[i] +
"Field");
41 result.Add(
"ldfld !0 class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite,object,object>>::Target");
42 result.Add(
"ldsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite,object,object>> " + OPTIMIZER_FULLNAME +
"::get" + fields[i] +
"Field");
43 result.Add(
"ldloc cs_param_" + i);
44 result.Add(
"callvirt instance !2 class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite,object,object>::Invoke(!0,!1)");
54 private static IList<String> CreateOptimizerClass(ICollection<String> fields)
56 fields =
new List<String>(fields.Distinct());
57 IList<String> result =
new List<String>();
58 result.Add(
".namespace " + OPTIMIZER_NAMESPACE);
60 result.Add(
".class public auto ansi beforefieldinit " + OPTIMIZER_NAME +
" extends [mscorlib]System.Object");
62 foreach (var field
in fields)
63 result.Add(
" .field public static class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite,object,object>> get" + field +
"Field");
64 result.Add(
".method public hidebysig specialname rtspecialname instance void .ctor() cil managed");
66 result.Add(
".maxstack 8");
67 result.Add(
"ldarg.0");
68 result.Add(
"call instance void [mscorlib]System.Object::.ctor()");
71 result.Add(
".method private hidebysig specialname rtspecialname static void .cctor() cil managed");
73 result.Add(
".maxstack 7");
74 result.Add(
".locals init ");
76 foreach (var field
in fields)
77 result.Add(
"class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[] V_" + field +
",");
78 result.RemoveAt(result.Count - 1);
79 result.Add(
"class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo[] V_" + fields.Last());
82 foreach (var field
in fields)
84 result.Add(
"ldc.i4.0");
85 result.Add(
"ldstr \"" + field +
"\"");
86 result.Add(
"ldtoken " + OPTIMIZER_FULLNAME);
87 result.Add(
"call class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)");
88 result.Add(
"ldc.i4.1");
89 result.Add(
"newarr [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo");
90 result.Add(
"stloc V_" + field);
91 result.Add(
"ldloc V_" + field);
92 result.Add(
"ldc.i4.0");
93 result.Add(
"ldc.i4.0");
95 result.Add(
"call class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo::Create(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags,string)");
96 result.Add(
"stelem.ref");
97 result.Add(
"ldloc V_" + field);
98 result.Add(
"call class [System.Core]System.Runtime.CompilerServices.CallSiteBinder [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.Binder::GetMember(valuetype [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags,string,class [mscorlib]System.Type,class [mscorlib]System.Collections.Generic.IEnumerable`1<class [Microsoft.CSharp]Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)");
99 result.Add(
"call class [System.Core]System.Runtime.CompilerServices.CallSite`1<!0> class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite,object,object>>::Create(class [System.Core]System.Runtime.CompilerServices.CallSiteBinder)");
100 result.Add(
"stsfld class [System.Core]System.Runtime.CompilerServices.CallSite`1<class [mscorlib]System.Func`3<class [System.Core]System.Runtime.CompilerServices.CallSite,object,object>> " + OPTIMIZER_FULLNAME +
"::get" + field +
"Field");
103 result.Add(
"} //End of .cctor");
104 result.Add(
"} //" + OPTIMIZER_FULLNAME);
109 private static IList<String> CreateHeader(IList<String> lines, IList<String> optimizerClass)
111 IList<String> result =
new List<String>();
112 result.Add(
".assembly extern System.Core");
114 result.Add(
".publickeytoken = (B7 7A 5C 56 19 34 E0 89 )");
115 result.Add(
".ver 4:0:0:0");
117 result.Add(
".assembly extern Microsoft.CSharp");
119 result.Add(
".publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )");
120 result.Add(
".ver 4:0:0:0");
125 for (
int i = 0; i < lines.Count && String.IsNullOrEmpty(name) ; i++)
127 if (lines[i].StartsWith(
".module"))
128 name = lines[i].Split(
' ')[1].Split(
'.')[0];
131 for (
int i = 0; i < lines.Count; i++)
133 if (lines[i].StartsWith(
".assembly " + name))
135 if (lines[i].EndsWith(
"{}"))
137 result.Add(
".assembly " + name);
139 result.Add(
".custom instance void [mscorlib]System.Runtime.CompilerServices.CompilationRelaxationsAttribute::.ctor(int32) = ( 01 00 08 00 00 00 00 00 ) ");
140 result.Add(
".custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = ( 01 00 01 00 54 02 16 57 72 61 70 4E 6F 6E 45 78 // ....T..WrapNonEx");
141 result.Add(
"63 65 70 74 69 6F 6E 54 68 72 6F 77 73 01 ) // ceptionThrows.");
142 result.Add(
".hash algorithm 0x00008004");
143 result.Add(
".ver 0:0:0:0");
148 result.Add(lines[i]);
151 foreach (var line
in optimizerClass)
159 StreamReader ilFile = File.OpenText(path);
160 String line = ilFile.ReadLine();
161 IList<String> lines =
new List<String>();
165 line = ilFile.ReadLine();
168 var fields = ProcessGetFields(lines);
169 var withFields = CreateGetFields(lines, fields);
170 var optimizerClass = CreateOptimizerClass(fields.Values);
171 var result = CreateHeader(withFields, optimizerClass);
172 StreamWriter ilOptimizedFile =
new StreamWriter(path);
173 foreach (var resultLine
in result)
174 ilOptimizedFile.WriteLine(resultLine);
175 ilOptimizedFile.Close();
static void OptimizeIlFile(String path)