예제 #1
0
        private void generatePackMethod(ClassDescriptor desc, MethodBuilder builder)
        {
            ILGenerator il = builder.GetILGenerator();

            il.Emit(OpCodes.Ldarg_2); // obj
            il.Emit(OpCodes.Castclass, desc.cls);
            obj = il.DeclareLocal(desc.cls);
            il.Emit(OpCodes.Stloc_0, obj);
            il.Emit(OpCodes.Ldc_I4, ObjectHeader.Sizeof);
            offs = il.DeclareLocal(typeof(int));
            il.Emit(OpCodes.Stloc_1, offs);

            ClassDescriptor.FieldDescriptor[] flds = desc.allFields;

            for (int i = 0, n = flds.Length; i < n; i++)
            {
                ClassDescriptor.FieldDescriptor fd = flds[i];
                FieldInfo f = fd.field;
                switch (fd.type)
                {
                case ClassDescriptor.FieldType.tpByte:
                case ClassDescriptor.FieldType.tpSByte:
                    generatePackField(il, f, packI1);
                    continue;

                case ClassDescriptor.FieldType.tpBoolean:
                    generatePackField(il, f, packBool);
                    continue;

                case ClassDescriptor.FieldType.tpShort:
                case ClassDescriptor.FieldType.tpUShort:
                case ClassDescriptor.FieldType.tpChar:
                    generatePackField(il, f, packI2);
                    continue;

                case ClassDescriptor.FieldType.tpEnum:
                case ClassDescriptor.FieldType.tpInt:
                case ClassDescriptor.FieldType.tpUInt:
                    generatePackField(il, f, packI4);
                    continue;

                case ClassDescriptor.FieldType.tpLong:
                case ClassDescriptor.FieldType.tpULong:
                    generatePackField(il, f, packI8);
                    continue;

                case ClassDescriptor.FieldType.tpFloat:
                    generatePackField(il, f, packF4);
                    continue;

                case ClassDescriptor.FieldType.tpDouble:
                    generatePackField(il, f, packF8);
                    continue;

                case ClassDescriptor.FieldType.tpDecimal:
                    generatePackField(il, f, packDecimal);
                    continue;

                case ClassDescriptor.FieldType.tpGuid:
                    generatePackField(il, f, packGuid);
                    continue;

                case ClassDescriptor.FieldType.tpDate:
                    generatePackField(il, f, packDate);
                    continue;

                case ClassDescriptor.FieldType.tpString:
                    generatePackField(il, f, packString);
                    continue;

                default:
                    il.Emit(OpCodes.Ldarg_1);     // db
                    il.Emit(OpCodes.Ldarg_3);     // buf
                    il.Emit(OpCodes.Ldloc_1, offs);
                    il.Emit(OpCodes.Ldloc_0, obj);
                    il.Emit(OpCodes.Ldfld, f);
                    il.Emit(OpCodes.Ldnull);     // fd
                    il.Emit(OpCodes.Ldc_I4, (int)fd.type);
                    il.Emit(OpCodes.Ldloc_0, obj);
                    il.Emit(OpCodes.Call, packField);
                    il.Emit(OpCodes.Stloc_1, offs);
                    continue;
                }
            }
            il.Emit(OpCodes.Ldloc_1, offs);
            il.Emit(OpCodes.Ret);
        }
예제 #2
0
        private void generateUnpackMethod(ClassDescriptor desc, MethodBuilder builder)
        {
            ILGenerator il = builder.GetILGenerator();

            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Castclass, desc.cls);
            LocalBuilder obj = il.DeclareLocal(desc.cls);

            il.Emit(OpCodes.Stloc_0, obj);
            il.Emit(OpCodes.Ldc_I4, ObjectHeader.Sizeof);
            LocalBuilder offs = il.DeclareLocal(typeof(int));

            il.Emit(OpCodes.Stloc_1, offs);
            LocalBuilder val = il.DeclareLocal(typeof(object));

            ClassDescriptor.FieldDescriptor[] flds = desc.allFields;

            for (int i = 0, n = flds.Length; i < n; i++)
            {
                ClassDescriptor.FieldDescriptor fd = flds[i];
                FieldInfo f = fd.field;
                if (f == null)
                {
                    switch (fd.type)
                    {
                    case ClassDescriptor.FieldType.tpByte:
                    case ClassDescriptor.FieldType.tpSByte:
                    case ClassDescriptor.FieldType.tpBoolean:
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_1);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpShort:
                    case ClassDescriptor.FieldType.tpUShort:
                    case ClassDescriptor.FieldType.tpChar:
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_2);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpEnum:
                    case ClassDescriptor.FieldType.tpInt:
                    case ClassDescriptor.FieldType.tpUInt:
                    case ClassDescriptor.FieldType.tpFloat:
                        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:
                    case ClassDescriptor.FieldType.tpDate:
                    case ClassDescriptor.FieldType.tpDouble:
                        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:
                    case ClassDescriptor.FieldType.tpGuid:
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4, 16);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    default:
                        il.Emit(OpCodes.Ldarg_1);    // db
                        il.Emit(OpCodes.Ldarg_3);    // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldnull);     // fd
                        il.Emit(OpCodes.Ldc_I4, (int)fd.type);
                        il.Emit(OpCodes.Call, skipField);
                        il.Emit(OpCodes.Stloc_1, offs);     // offs
                        continue;
                    }
                }
                else
                {
                    switch (fd.type)
                    {
                    case ClassDescriptor.FieldType.tpByte:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldelem_U1);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_1);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpSByte:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldelem_U1);
                        il.Emit(OpCodes.Conv_I1);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_1);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpBoolean:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldelem_U1);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_1);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpShort:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Call, unpackI2);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_2);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpUShort:
                    case ClassDescriptor.FieldType.tpChar:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Call, unpackI2);
                        il.Emit(OpCodes.Conv_U2);
                        il.Emit(OpCodes.Stfld, f);
                        il.Emit(OpCodes.Ldloc_1, offs);
                        il.Emit(OpCodes.Ldc_I4_2);
                        il.Emit(OpCodes.Add);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    case ClassDescriptor.FieldType.tpEnum:
                    case ClassDescriptor.FieldType.tpInt:
                    case ClassDescriptor.FieldType.tpUInt:
                        il.Emit(OpCodes.Ldloc_0, obj);
                        il.Emit(OpCodes.Ldarg_3);     // body
                        il.Emit(OpCodes.Ldloc_1, offs);
                        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.Call, unpackString);
                        il.Emit(OpCodes.Stloc_1, offs);
                        continue;

                    default:
                        il.Emit(OpCodes.Ldarg_1);    // db
                        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);
        }