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(); }