public static void Export(ResidualAssemblyHolder resHolder, string assemblyStringName) { Assembly assembly = resHolder.SourceHolder.Assembly; AssemblyName assemblyName = assembly.GetName(true); AppDomain domain = AppDomain.CurrentDomain; if(! Directory.Exists("CILPEOutPut")) Directory.CreateDirectory("CILPEOutPut"); AssemblyBuilder assemblyB = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save, "CILPEOutPut"); Module module = assembly.GetModules()[0]; ModuleBuilder moduleB = assemblyB.DefineDynamicModule(module.Name); Set replacedMethods = GetReplacedMethods(resHolder); MetaDataMapper mapper = new MetaDataMapper(moduleB, resHolder); Type[] allTypes = EmitSource(module, moduleB, replacedMethods, mapper); EmitResidual(resHolder, moduleB, replacedMethods, mapper); foreach(TypeBuilder type in allTypes) type.CreateType(); moduleB.CreateGlobalFunctions(); MethodInfo entryPoint = assembly.EntryPoint; if(entryPoint != null) assemblyB.SetEntryPoint(mapper.Map(entryPoint) as MethodInfo); assemblyB.Save(assemblyStringName); }
private Hashtable types; //Name -> Type mapping. To patch MS bug in ModuleBuilder #endregion Fields #region Constructors public MetaDataMapper(Module module, ResidualAssemblyHolder holder) { map = new Hashtable();; methodByMBB = new Hashtable(); types = new Hashtable(); specialCtors = new Set(); this.module = module; this.holder = holder; }
private Set specialCtors; //ctors with pseudo parameter RefsAndArraysBuilder public MetaDataMapper(Module module, ResidualAssemblyHolder holder) { map = new Hashtable();; methodByMBB = new Hashtable(); types = new Hashtable(); specialCtors = new Set(); this.module = module; this.holder = holder; }
private static Set GetReplacedMethods(ResidualAssemblyHolder resHolder) { //Andrew: ZLP, waiting for Sergei ArrayList methods = new ArrayList(); foreach (MethodBase method in resHolder.SourceHolder.getMethods()) { if (method.IsDefined(typeof(SpecializeAttribute), false)) { methods.Add(method); } } return(new Set(methods)); }
public static void Export(ResidualAssemblyHolder resHolder, string assemblyStringName) { Assembly assembly = resHolder.SourceHolder.Assembly; AssemblyName assemblyName = assembly.GetName(true); AppDomain domain = AppDomain.CurrentDomain; if (!Directory.Exists("CILPEOutPut")) { Directory.CreateDirectory("CILPEOutPut"); } AssemblyBuilder assemblyB = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save, "CILPEOutPut"); Module module = assembly.GetModules()[0]; ModuleBuilder moduleB = assemblyB.DefineDynamicModule(module.Name); Set replacedMethods = GetReplacedMethods(resHolder); MetaDataMapper mapper = new MetaDataMapper(moduleB, resHolder); Type[] allTypes = EmitSource(module, moduleB, replacedMethods, mapper); EmitResidual(resHolder, moduleB, replacedMethods, mapper); foreach (TypeBuilder type in allTypes) { type.CreateType(); } moduleB.CreateGlobalFunctions(); MethodInfo entryPoint = assembly.EntryPoint; if (entryPoint != null) { assemblyB.SetEntryPoint(mapper.Map(entryPoint) as MethodInfo); } assemblyB.Save(assemblyStringName); }
static void Evaluate() { WhiteList whiteList = new WhiteList(); whiteList.AddFromXml("wlist.xml"); if (showProgress) { Console.WriteLine("White list reading - OK"); } Assembly assembly = Assembly.LoadFrom(sourceAssemblyName); AssemblyHolder srcHolder = new AssemblyHolder(assembly); if (showProgress) { Console.WriteLine("Source assembly reading - OK"); } if (showSourceCFG) { Console.WriteLine("\nSource CFG:\n----------\n"); Console.Write(srcHolder); } markTime(); AnnotatedAssemblyHolder btaHolder = new AnnotatedAssemblyHolder(srcHolder, whiteList); btaTime = getSpan(); if (showProgress) { Console.WriteLine("Assembly annotation - OK"); } if (showAnnotatedCFG) { Console.WriteLine("\nAnnotated CFG:\n-------------\n"); Console.Write(btaHolder.ToString("CSharp", ReflectionFormatter.formatter, new string[] { Annotation.BTTypeOption, Annotation.MethodBTTypeOption })); } markTime(); ResidualAssemblyHolder resHolder = new ResidualAssemblyHolder(btaHolder); specTime = getSpan(); if (showProgress) { Console.WriteLine("Assembly specialization - OK"); } if (showResidualCFG) { Console.WriteLine("\nResidual CFG:\n-------------\n"); Console.Write(resHolder.ToString("CSharp", ReflectionFormatter.formatter)); } if (enablePostprocessing) { markTime(); resHolder.Optimize(); pprocTime = getSpan(); if (showProgress) { Console.WriteLine("Assembly postprocessing - OK"); } if (showPostprocessedCFG) { Console.WriteLine("\nPostprocessed CFG:\n-----------------\n"); Console.Write(resHolder.ToString("CSharp", ReflectionFormatter.formatter)); } } Exporter.Export(resHolder, targetAssemblyName); if (showProgress) { Console.WriteLine("Assembly export - OK"); } if (enableClock) { Console.WriteLine("Timings:"); Console.WriteLine(" BTA - " + btaTime); Console.WriteLine(" Specializer - " + specTime); if (enablePostprocessing) { Console.WriteLine(" Postprocessing - " + pprocTime); } } }
internal static void SpecializeMethod(ResidualAssemblyHolder holder, ResidualMethod method) { Value[] args = method.Arguments; PointerValue[] ptrs = method.Pointers; MethodBodyBlock mbbDown = holder.AnnotatedHolder[method.AnnotatedMethod]; MethodBodyBlock mbbUp = new MethodBodyBlock(mbbDown.ReturnType); holder.AddMethod(method, mbbUp); SpecState state = new SpecState(mbbDown.Variables.Count); VariablesHashtable varsHash = new VariablesHashtable(); int varCount = 0; int argCount = 0; foreach (Variable varDown in mbbDown.Variables.ParameterMapper) { state.Pool[varDown] = new Location(varDown.Type); Variable varUp; if (Annotation.GetValueBTType(method.AnnotatedMethod.ParamVals[varCount++].Val) == BTType.Static) { state.Pool[varDown].Val = args[argCount++]; varUp = mbbUp.Variables.CreateVar(varDown.Type, VariableKind.Local); } else varUp = mbbUp.Variables.CreateVar(varDown.Type, VariableKind.Parameter); varsHash[new PointerToLocationValue(state.Pool[varDown])] = varUp; } foreach (Variable varDown in mbbDown.Variables) if (! state.Pool.ContainsVar(varDown)) { state.Pool[varDown] = new Location(varDown.Type); Variable varUp = mbbUp.Variables.CreateVar(varDown.Type, VariableKind.Local); varsHash[new PointerToLocationValue(state.Pool[varDown])] = varUp; } PointerToNode ptrUpNode = new PointerToNode(mbbUp); Node dummyUp = new DummyNode(mbbUp); Node upNode = dummyUp; for (int i = 0; i < ptrs.Length; i++) { Type ptrType = ptrs[i].Type; Type type = ptrType.GetElementType(); Variable newVar1 = mbbUp.Variables.CreateVar(ptrType, VariableKind.Parameter); Variable newVar2 = mbbUp.Variables.CreateVar(type, VariableKind.Local); varsHash[ptrs[i]] = newVar2; ptrUpNode = new PointerToNode(ptrUpNode.Node = new LoadVar(newVar1)); ptrUpNode = new PointerToNode(ptrUpNode.Node = new LoadIndirect(type)); ptrUpNode = new PointerToNode(ptrUpNode.Node = new StoreVar(newVar2)); upNode = upNode.Next = new LoadVar(newVar1); upNode = upNode.Next = new LoadVar(newVar2); upNode = upNode.Next = new StoreIndirect(type); } upNode.Next = new Leave(); upNode = dummyUp.Next; dummyUp.RemoveFromGraph(); GraphProcessor graphProc = new GraphProcessor(); SpecializingVisitor visitor = new SpecializingVisitor(graphProc, holder, mbbUp, state, varsHash); visitor.AddTask(mbbDown.Next, ptrUpNode); graphProc.Process(); visitor.SetLastNode(upNode); }
internal SpecializingVisitor(GraphProcessor graphProcessor, ResidualAssemblyHolder holder, MethodBodyBlock mbbUp, SpecState state, VariablesHashtable varsHash) : base(graphProcessor) { this.holder = holder; this.mbbUp = mbbUp; this.state = state; this.varsHash = varsHash; this.upDownNodes = new Hashtable(); this.exitData = new ArrayList(); }
static void Evaluate() { WhiteList whiteList = new WhiteList(); whiteList.AddFromXml("wlist.xml"); if (showProgress) Console.WriteLine("White list reading - OK"); Assembly assembly = Assembly.LoadFrom(sourceAssemblyName); AssemblyHolder srcHolder = new AssemblyHolder(assembly); if (showProgress) Console.WriteLine("Source assembly reading - OK"); if (showSourceCFG) { Console.WriteLine("\nSource CFG:\n----------\n"); Console.Write(srcHolder); } markTime(); AnnotatedAssemblyHolder btaHolder = new AnnotatedAssemblyHolder(srcHolder, whiteList); btaTime = getSpan(); if (showProgress) Console.WriteLine("Assembly annotation - OK"); if (showAnnotatedCFG) { Console.WriteLine("\nAnnotated CFG:\n-------------\n"); Console.Write(btaHolder.ToString("CSharp",ReflectionFormatter.formatter,new string[] { Annotation.BTTypeOption, Annotation.MethodBTTypeOption })); } markTime(); ResidualAssemblyHolder resHolder = new ResidualAssemblyHolder(btaHolder); specTime = getSpan(); if (showProgress) Console.WriteLine("Assembly specialization - OK"); if (showResidualCFG) { Console.WriteLine("\nResidual CFG:\n-------------\n"); Console.Write(resHolder.ToString("CSharp",ReflectionFormatter.formatter)); } if (enablePostprocessing) { markTime(); resHolder.Optimize(); pprocTime = getSpan(); if (showProgress) Console.WriteLine("Assembly postprocessing - OK"); if (showPostprocessedCFG) { Console.WriteLine("\nPostprocessed CFG:\n-----------------\n"); Console.Write(resHolder.ToString("CSharp",ReflectionFormatter.formatter)); } } Exporter.Export(resHolder, targetAssemblyName); if (showProgress) Console.WriteLine("Assembly export - OK"); if (enableClock) { Console.WriteLine("Timings:"); Console.WriteLine(" BTA - " + btaTime); Console.WriteLine(" Specializer - " + specTime); if (enablePostprocessing) Console.WriteLine(" Postprocessing - " + pprocTime); } }
private static void EmitResidual(ResidualAssemblyHolder resHolder, ModuleBuilder moduleB, Set replacedMethods, MetaDataMapper mapper) { int freeIndex = 0; ArrayList pseudoClasses = new ArrayList(); Hashtable pseudoClassesUsage = new Hashtable(); // Type --> int mapping Hashtable replacingMethods = new Hashtable(); //MBB --> MethodBase foreach (MethodBase method in replacedMethods) { replacingMethods[resHolder[method]] = method; } TypeBuilder cilpeClass = moduleB.DefineType("$CILPE$", TypeAttributes.NotPublic | TypeAttributes.Class); foreach (ResidualMethod id in resHolder.getMethods()) { MethodBodyBlock mbb = resHolder[id]; MethodBase method = replacingMethods[mbb] as MethodBase; if (method != null) //replacing, (Method/Constructor)Builder already defined { mapper.AddMethodBodyBlock(mbb, mapper.Map(method)); } else //a new method { if (id.IsConstructor) { Type[] paramTypes = mapper.Map(MetaDataResolver.GetParamTypes(mbb, false)); TypeBuilder typeB = mapper.Map(id.SourceMethod.DeclaringType) as TypeBuilder; if (typeB != paramTypes[0]) { throw new ExportException(); } for (int i = 0; i < paramTypes.Length - 1; i++) { paramTypes[i] = paramTypes[i + 1]; } Type pseudoClass = GetOrBuild(cilpeClass, pseudoClasses, GetAndInc(pseudoClassesUsage, typeB)); paramTypes[paramTypes.Length - 1] = pseudoClass; mapper.AddSpecialCtor(mbb); ConstructorBuilder ctorB = typeB.DefineConstructor(MethodAttributes.Assembly, CallingConventions.Standard, paramTypes); for (int i = 0; i < paramTypes.Length - 1; i++) { ctorB.DefineParameter(i + 1, ParameterAttributes.None, "A_" + (i + 1)); } ctorB.DefineParameter(paramTypes.Length, ParameterAttributes.Optional, "__noname"); mapper.AddMethodBodyBlock(mbb, ctorB); } else { Type[] paramTypes = mapper.Map(MetaDataResolver.GetParamTypes(mbb, false)); string name = "$CILPE$" + id.SourceMethod.DeclaringType.FullName + "+" + id.SourceMethod.Name + "$" + (freeIndex++); MethodAttributes attributes = MethodAttributes.Assembly | MethodAttributes.Static; MethodBuilder methodB = cilpeClass.DefineMethod(name, attributes, CallingConventions.Standard, mapper.Map(mbb.ReturnType), paramTypes); for (int i = 0; i < paramTypes.Length; i++) { methodB.DefineParameter(i + 1, ParameterAttributes.None, "A_" + (i + 1)); } mapper.AddMethodBodyBlock(mbb, methodB); } } } //All residual methods are declared. Define them now foreach (MethodBodyBlock body in resHolder) { MethodBase method = mapper.Map(body); MetaDataResolver.Map(body, mapper); bool verified = CFGVerifier.Check(body); if (!verified) { throw new ExportException(); } MethodBuilder methodB = method as MethodBuilder; ConstructorBuilder ctorB = method as ConstructorBuilder; ILGenerator generator = methodB == null?ctorB.GetILGenerator() : methodB.GetILGenerator(); Emitter.Emit(generator, body); } cilpeClass.CreateType(); foreach (TypeBuilder pseudoClass in pseudoClasses) { pseudoClass.CreateType(); } }
private static void EmitResidual(ResidualAssemblyHolder resHolder, ModuleBuilder moduleB, Set replacedMethods, MetaDataMapper mapper) { int freeIndex = 0; ArrayList pseudoClasses = new ArrayList(); Hashtable pseudoClassesUsage = new Hashtable(); // Type --> int mapping Hashtable replacingMethods = new Hashtable(); //MBB --> MethodBase foreach(MethodBase method in replacedMethods) replacingMethods[resHolder[method]] = method; TypeBuilder cilpeClass = moduleB.DefineType("$CILPE$", TypeAttributes.NotPublic | TypeAttributes.Class); foreach(ResidualMethod id in resHolder.getMethods()) { MethodBodyBlock mbb = resHolder[id]; MethodBase method = replacingMethods[mbb] as MethodBase; if(method != null) //replacing, (Method/Constructor)Builder already defined { mapper.AddMethodBodyBlock(mbb, mapper.Map(method)); } else //a new method { if(id.IsConstructor) { Type[] paramTypes = mapper.Map(MetaDataResolver.GetParamTypes(mbb,false)); TypeBuilder typeB = mapper.Map(id.SourceMethod.DeclaringType) as TypeBuilder; if(typeB != paramTypes[0]) throw new ExportException(); for(int i=0; i<paramTypes.Length-1; i++) paramTypes[i] = paramTypes[i+1]; Type pseudoClass = GetOrBuild(cilpeClass, pseudoClasses, GetAndInc(pseudoClassesUsage, typeB)); paramTypes[paramTypes.Length-1] = pseudoClass; mapper.AddSpecialCtor(mbb); ConstructorBuilder ctorB = typeB.DefineConstructor(MethodAttributes.Assembly, CallingConventions.Standard, paramTypes); for(int i=0; i<paramTypes.Length-1; i++) ctorB.DefineParameter(i+1, ParameterAttributes.None, "A_"+(i+1)); ctorB.DefineParameter(paramTypes.Length,ParameterAttributes.Optional, "__noname"); mapper.AddMethodBodyBlock(mbb,ctorB); } else { Type[] paramTypes = mapper.Map(MetaDataResolver.GetParamTypes(mbb,false)); string name = "$CILPE$" + id.SourceMethod.DeclaringType.FullName + "+" + id.SourceMethod.Name + "$" + (freeIndex++); MethodAttributes attributes = MethodAttributes.Assembly | MethodAttributes.Static; MethodBuilder methodB = cilpeClass.DefineMethod(name, attributes, CallingConventions.Standard, mapper.Map(mbb.ReturnType), paramTypes); for(int i=0; i<paramTypes.Length; i++) methodB.DefineParameter(i+1, ParameterAttributes.None, "A_"+(i+1)); mapper.AddMethodBodyBlock(mbb,methodB); } } } //All residual methods are declared. Define them now foreach(MethodBodyBlock body in resHolder) { MethodBase method = mapper.Map(body); MetaDataResolver.Map(body,mapper); bool verified = CFGVerifier.Check(body); if(!verified) throw new ExportException(); MethodBuilder methodB = method as MethodBuilder; ConstructorBuilder ctorB = method as ConstructorBuilder; ILGenerator generator = methodB == null ? ctorB.GetILGenerator() : methodB.GetILGenerator(); Emitter.Emit(generator,body); } cilpeClass.CreateType(); foreach(TypeBuilder pseudoClass in pseudoClasses) pseudoClass.CreateType(); }
private static Set GetReplacedMethods(ResidualAssemblyHolder resHolder) { //Andrew: ZLP, waiting for Sergei ArrayList methods = new ArrayList(); foreach (MethodBase method in resHolder.SourceHolder.getMethods()) if (method.IsDefined(typeof(SpecializeAttribute), false)) methods.Add(method); return(new Set(methods)); }