コード例 #1
0
        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();
            }
        }
コード例 #2
0
ファイル: Exporter.cs プロジェクト: DragonXYZ/cilpe
        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();
        }