The StaDyn Programming Language
Source code documentation of StaDyn, a hybrid static and dynamic typing language.
ServerOptimizer.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Linq;
5 
6 namespace Inference.src.Core
7 {
8  public class ServerOptimizer
9  {
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[])";
16 
17  private static IDictionary<int, String> ProcessGetFields(IList<String> lines)
18  {
19  IDictionary<int, String> fields = new Dictionary<int, String>();
20  for (int i = 0; i < lines.Count; i++)
21  {
22  if (lines[i].EndsWith(GET_TYPE) && lines[i + 2].EndsWith(GET_FIELD) && lines[i + 17].EndsWith(INVOKE))
23  {
24  String name = lines[i + 1].Split('\t')[1];
25  fields.Add(i, name.Replace("\"", ""));
26  }
27  }
28  return fields;
29  }
30 
31  private static IList<String> CreateGetFields(IList<String> lines, IDictionary<int, String> fields)
32  {
33  IList<String> result = new List<String>();
34  for (int i = 0; i < lines.Count; i++)
35  {
36  if (fields.ContainsKey(i))
37  {
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)");
45  i = i + 18;
46  }
47  else
48  result.Add(lines[i]);
49 
50  }
51  return result;
52  }
53 
54  private static IList<String> CreateOptimizerClass(ICollection<String> fields)
55  {
56  fields = new List<String>(fields.Distinct());
57  IList<String> result = new List<String>();
58  result.Add(".namespace " + OPTIMIZER_NAMESPACE);
59  result.Add("{");
60  result.Add(".class public auto ansi beforefieldinit " + OPTIMIZER_NAME + " extends [mscorlib]System.Object");
61  result.Add("{");
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");
65  result.Add("{");
66  result.Add(".maxstack 8");
67  result.Add("ldarg.0");
68  result.Add("call instance void [mscorlib]System.Object::.ctor()");
69  result.Add("ret");
70  result.Add("}");
71  result.Add(".method private hidebysig specialname rtspecialname static void .cctor() cil managed");
72  result.Add("{");
73  result.Add(".maxstack 7");
74  result.Add(".locals init ");
75  result.Add("(");
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());
80  result.Add(")");
81 
82  foreach (var field in fields)
83  {
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");
94  result.Add("ldnull");
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");
101  }
102  result.Add("ret");
103  result.Add("} //End of .cctor");
104  result.Add("} //" + OPTIMIZER_FULLNAME);
105  result.Add("}");
106  return result;
107  }
108 
109  private static IList<String> CreateHeader(IList<String> lines, IList<String> optimizerClass)
110  {
111  IList<String> result = new List<String>();
112  result.Add(".assembly extern System.Core");
113  result.Add("{");
114  result.Add(".publickeytoken = (B7 7A 5C 56 19 34 E0 89 )");
115  result.Add(".ver 4:0:0:0");
116  result.Add("}");
117  result.Add(".assembly extern Microsoft.CSharp");
118  result.Add("{");
119  result.Add(".publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )");
120  result.Add(".ver 4:0:0:0");
121  result.Add("}");
122 
123 
124  String name = "";
125  for (int i = 0; i < lines.Count && String.IsNullOrEmpty(name) ; i++)
126  {
127  if (lines[i].StartsWith(".module"))
128  name = lines[i].Split(' ')[1].Split('.')[0];
129  }
130 
131  for (int i = 0; i < lines.Count; i++)
132  {
133  if (lines[i].StartsWith(".assembly " + name))
134  {
135  if (lines[i].EndsWith("{}"))
136  {
137  result.Add(".assembly " + name);
138  result.Add("{");
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");
144  result.Add("}");
145  }
146  }
147  else
148  result.Add(lines[i]);
149  }
150 
151  foreach (var line in optimizerClass)
152  result.Add(line);
153 
154  return result;
155  }
156 
157  public static void OptimizeIlFile(String path)
158  {
159  StreamReader ilFile = File.OpenText(path);
160  String line = ilFile.ReadLine();
161  IList<String> lines = new List<String>();
162  while (line != null)
163  {
164  lines.Add(line);
165  line = ilFile.ReadLine();
166  }
167  ilFile.Close();
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();
176  }
177  }
178 }
static void OptimizeIlFile(String path)