⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codegenerator.cs

📁 Perst开源实时数据库
💻 CS
📖 第 1 页 / 共 2 页
字号:
                            il.Emit(OpCodes.Call, unpackI4);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_4);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;
					
                        case ClassDescriptor.FieldType.tpLong: 
                        case ClassDescriptor.FieldType.tpULong: 
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackI8);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_8);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;
					
                        case ClassDescriptor.FieldType.tpFloat: 
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackF4);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_4);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;
					
                        case ClassDescriptor.FieldType.tpDouble: 
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackF8);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_8);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;
					
                        case ClassDescriptor.FieldType.tpDecimal:
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackDecimal);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4, 16);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpGuid:
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackGuid);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4, 16);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;

                        case ClassDescriptor.FieldType.tpDate: 
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Call, unpackDate);
                            il.Emit(OpCodes.Stfld, f);
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldc_I4_8);
                            il.Emit(OpCodes.Add);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;
					
                        case ClassDescriptor.FieldType.tpString: 
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldflda, f);
                            il.Emit(OpCodes.Ldarg_S, 5); // encoding
                            il.Emit(OpCodes.Call, unpackString);
                            il.Emit(OpCodes.Stloc_1, offs);
                            continue;
                
                        default:
                            il.Emit(OpCodes.Ldarg_1); // storage
                            il.Emit(OpCodes.Ldarg_3); // body
                            il.Emit(OpCodes.Ldloc_1, offs);
                            il.Emit(OpCodes.Ldarg_S, 4); // recursiveLoading
                            il.Emit(OpCodes.Ldloca, val);
                            il.Emit(OpCodes.Ldnull); // fd
                            il.Emit(OpCodes.Ldc_I4, (int)fd.type);
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Call, unpackField);
                            il.Emit(OpCodes.Stloc_1, offs); // offs
                            il.Emit(OpCodes.Ldloc_0, obj);
                            il.Emit(OpCodes.Ldloc, val);
                            il.Emit(OpCodes.Castclass, f.FieldType);
                            il.Emit(OpCodes.Stfld, f);
                            continue;
                    }
                }
            }
            il.Emit(OpCodes.Ret);
        }

        private void generateNewMethod(ClassDescriptor desc, MethodBuilder builder)
        {
            ILGenerator il = builder.GetILGenerator();
            il.Emit(OpCodes.Newobj, desc.defaultConstructor);
            il.Emit(OpCodes.Ret);
        }

        private Type EmitClass(ModuleBuilder module, ClassDescriptor desc)
        {
            counter += 1;
            String generatedClassName = "GeneratedSerializerClass" + counter;
            TypeBuilder serializerType = module.DefineType(generatedClassName, TypeAttributes.Public);

            Type serializerInterface = typeof(GeneratedSerializer);
            serializerType.AddInterfaceImplementation(serializerInterface);
            //Add a constructor
            ConstructorBuilder constructor =
                serializerType.DefineDefaultConstructor(MethodAttributes.Public);

            MethodInfo packInterface = serializerInterface.GetMethod("pack");
            MethodBuilder packBuilder = GetBuilder(serializerType, packInterface);
            generatePackMethod(desc, packBuilder);
            serializerType.DefineMethodOverride(packBuilder, packInterface);

            MethodInfo unpackInterface = serializerInterface.GetMethod("unpack");
            MethodBuilder unpackBuilder = GetBuilder(serializerType, unpackInterface);
            generateUnpackMethod(desc, unpackBuilder);
            serializerType.DefineMethodOverride(unpackBuilder, unpackInterface);

            MethodInfo newInterface = serializerInterface.GetMethod("newInstance");
            MethodBuilder newBuilder = GetBuilder(serializerType, newInterface);
            generateNewMethod(desc, newBuilder);
            serializerType.DefineMethodOverride(newBuilder, newInterface);

            serializerType.CreateType();
            return serializerType;
        }

        private Type EmitClassWrapper(ModuleBuilder module, Type type)
        {
            String generatedClassName = type.Name + "Wrapper";
            TypeBuilder wrapperType;
            
            if (type.IsInterface) 
            {
                wrapperType = module.DefineType(generatedClassName, TypeAttributes.Public, 
                    typeof(IResource).IsAssignableFrom(type) ? typeof(PersistentResource) : typeof(Persistent));
                wrapperType.AddInterfaceImplementation(type);
            } 
            else 
            {
                wrapperType = module.DefineType(generatedClassName, TypeAttributes.Public, type);
            }
            wrapperType.AddInterfaceImplementation(typeof(PersistentWrapper));

            //Add a constructor
            ConstructorBuilder constructor =
                wrapperType.DefineDefaultConstructor(MethodAttributes.Public);

            PropertyInfo[] properties = type.GetProperties(BindingFlags.Public|BindingFlags.NonPublic|BindingFlags.Instance);
            for (int i = 0; i < properties.Length; i++) 
            { 
                PropertyInfo prop = properties[i];
                MethodInfo getter = prop.GetGetMethod(true);
                MethodInfo setter = prop.GetSetMethod(true);
                if (getter != null && setter != null && getter.IsVirtual && setter.IsVirtual) 
                { 
                    Type returnType = getter.ReturnType;
                    String fieldName = prop.Name;
                    Type fieldType;
                    if (typeof(IPersistent).IsAssignableFrom(returnType)) 
                    {
                        fieldType = typeof(int);
                        fieldName = "r_" + fieldName;
                    } 
                    else 
                    {
                        fieldType = returnType;
                        fieldName = "s_" + fieldName;
                    }
                    if (fieldType.IsArray && typeof(IPersistent).IsAssignableFrom(fieldType.GetElementType()))
                    {
                        throw new StorageError(StorageError.ErrorCode.UNSUPPORTED_TYPE);
                    }

                    FieldBuilder fb = wrapperType.DefineField(fieldName, fieldType, FieldAttributes.Private);
                                
                    MethodBuilder getterImpl = wrapperType.DefineMethod(getter.Name,
                        MethodAttributes.Public|MethodAttributes.Virtual|MethodAttributes.NewSlot,    
                        returnType,
                        new Type[] { });

                    ILGenerator il = getterImpl.GetILGenerator();

                    if (fieldType != returnType) 
                    {
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Callvirt, getStorage);
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldfld, fb);
                        il.Emit(OpCodes.Callvirt, getByOid);
                        il.Emit(OpCodes.Castclass, returnType);
                    } 
                    else 
                    {
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Ldfld, fb);
                    }
                    il.Emit(OpCodes.Ret);

                    wrapperType.DefineMethodOverride(getterImpl, getter);

                    MethodBuilder setterImpl = wrapperType.DefineMethod(setter.Name,
                        MethodAttributes.Public|MethodAttributes.Virtual|MethodAttributes.NewSlot,    
                        null,
                        new Type[] { returnType });

                    il = setterImpl.GetILGenerator();

                    il.Emit(OpCodes.Ldarg_0);
                    if (fieldType != returnType) 
                    {
                        il.Emit(OpCodes.Ldarg_0);
                        il.Emit(OpCodes.Callvirt, getStorage);
                        il.Emit(OpCodes.Ldarg_1);
                        il.Emit(OpCodes.Callvirt, makePersistent);
                    } 
                    else 
                    {
                        il.Emit(OpCodes.Ldarg_1);
                    }
                    il.Emit(OpCodes.Stfld, fb);
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Callvirt, modify);
                    il.Emit(OpCodes.Ret);

                    wrapperType.DefineMethodOverride(setterImpl, setter);
                }
            }
            wrapperType.CreateType();
            return wrapperType;
        }

        public static CodeGenerator Instance 
        {                                
            get 
            {
                if (instance == null) 
                { 
                    instance = new CodeGenerator();
                }
                return instance;
            }
        }

        private static CodeGenerator instance;


        private LocalBuilder obj;
        private LocalBuilder offs;

        private MethodInfo packBool = typeof(ByteBuffer).GetMethod("packBool");
        private MethodInfo packI1 = typeof(ByteBuffer).GetMethod("packI1");
        private MethodInfo packI2 = typeof(ByteBuffer).GetMethod("packI2");
        private MethodInfo packI4 = typeof(ByteBuffer).GetMethod("packI4");
        private MethodInfo packI8 = typeof(ByteBuffer).GetMethod("packI8");
        private MethodInfo packF4 = typeof(ByteBuffer).GetMethod("packF4");
        private MethodInfo packF8 = typeof(ByteBuffer).GetMethod("packF8");
        private MethodInfo packDecimal = typeof(ByteBuffer).GetMethod("packDecimal");
        private MethodInfo packGuid = typeof(ByteBuffer).GetMethod("packGuid");
        private MethodInfo packDate = typeof(ByteBuffer).GetMethod("packDate");
        private MethodInfo packString = typeof(ByteBuffer).GetMethod("packString");
        private MethodInfo packField = typeof(StorageImpl).GetMethod("packField");

        private MethodInfo unpackI2 = typeof(Bytes).GetMethod("unpack2");
        private MethodInfo unpackI4 = typeof(Bytes).GetMethod("unpack4");
        private MethodInfo unpackI8 = typeof(Bytes).GetMethod("unpack8");
        private MethodInfo unpackF4 = typeof(Bytes).GetMethod("unpackF4");
        private MethodInfo unpackF8 = typeof(Bytes).GetMethod("unpackF8");
        private MethodInfo unpackDecimal = typeof(Bytes).GetMethod("unpackDecimal");
        private MethodInfo unpackGuid = typeof(Bytes).GetMethod("unpackGuid");
        private MethodInfo unpackDate = typeof(Bytes).GetMethod("unpackDate");
        private MethodInfo unpackString = typeof(Bytes).GetMethod("unpackString");
        private MethodInfo unpackField = typeof(StorageImpl).GetMethod("unpackField");
        private MethodInfo skipField = typeof(StorageImpl).GetMethod("skipField");

        private MethodInfo modify = typeof(IPersistent).GetMethod("Modify");
        private MethodInfo getStorage = typeof(IPersistent).GetProperty("Storage").GetGetMethod();
        private MethodInfo getByOid = typeof(Storage).GetMethod("GetObjectByOID");
        private MethodInfo makePersistent = typeof(Storage).GetMethod("MakePersistent");

        private int[] arrayOfInt = new int[0];

        private ModuleBuilder dynamicModule;
        private int           counter;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -