private static void EmitCalculateFields(ILGenerator il, Type type) { int num = 0; foreach (FieldInfo fieldInfo in type.GetFields(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { if (!fieldInfo.IsInitOnly && !fieldInfo.IsLiteral && !fieldInfo.IsNotSerialized) { Type fieldType = fieldInfo.FieldType; int staticSize = SerializedSizeCalculatorHelper <T, C> .GetStaticSize(fieldType); if (0 < staticSize) { num += staticSize; } else { MethodInfo methodInfo = SerializedSizeCalculatorHelper <T, C> .FindDefinedCalculateMethod(fieldType); if (methodInfo == null) { methodInfo = typeof(SerializedSizeCalculatorHelper <, >).MakeGenericType(new Type[] { fieldType, typeof(C) }).GetMethod("CalculateSerializedSize"); } il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, fieldInfo); il.EmitCall(OpCodes.Call, methodInfo, null); il.Emit(OpCodes.Add); } } } if (0 < num) { il.Emit(OpCodes.Ldc_I4, num); il.Emit(OpCodes.Add); } }
private static void GenerateCalculator() { DynamicMethod dynamicMethod = new DynamicMethod(string.Format("{0}.{1}.CalculateSerializedSizeCore[{2}.{3}]", new object[] { typeof(SerializedSizeCalculatorHelper <T, C>).Namespace, typeof(SerializedSizeCalculatorHelper <T, C>).Name, typeof(T).Namespace, typeof(T).Name }), typeof(int), new Type[] { typeof(T) }, typeof(SerializedSizeCalculatorHelper <T, C>), true); dynamicMethod.DefineParameter(1, ParameterAttributes.In, "value"); ILGenerator ilgenerator = dynamicMethod.GetILGenerator(); Type type = typeof(T); Label? label = null; if (!type.IsValueType && SerializedSizeCalculatorHelper <T, C> .FindDefinedCalculateMethod(type) == null) { ilgenerator.Emit(OpCodes.Ldc_I4_1); ilgenerator.Emit(OpCodes.Ldarg_0); label = new Label?(ilgenerator.DefineLabel()); ilgenerator.Emit(OpCodes.Brfalse, label.Value); } while (type != null) { MethodInfo methodInfo = SerializedSizeCalculatorHelper <T, C> .FindDefinedCalculateMethod(type); if (methodInfo != null) { ilgenerator.Emit(OpCodes.Ldarg_0); ilgenerator.EmitCall(OpCodes.Call, methodInfo, null); if (type != typeof(T)) { ilgenerator.Emit(OpCodes.Add); break; } break; } else { if (type == typeof(T)) { int staticSize = SerializedSizeCalculatorHelper <T, C> .GetStaticSize(type); if (staticSize >= 1) { ilgenerator.Emit(OpCodes.Ldc_I4, staticSize); break; } ilgenerator.Emit(OpCodes.Ldc_I4_0); } SerializedSizeCalculatorHelper <T, C> .EmitCalculateFields(ilgenerator, type); type = type.BaseType; } } if (label != null) { ilgenerator.Emit(OpCodes.Add); ilgenerator.MarkLabel(label.Value); } ilgenerator.Emit(OpCodes.Ret); SerializedSizeCalculatorHelper <T, C> .calculateSerializedSizeCore = (dynamicMethod.CreateDelegate(typeof(SerializedSizeCalculatorHelper <T, C> .CalculateSerializedSizeDelegate)) as SerializedSizeCalculatorHelper <T, C> .CalculateSerializedSizeDelegate); if (typeof(T).IsSealed || SerializedSizeCalculatorHelper <T, C> .FindDefinedCalculateMethod(typeof(T)) != null) { SerializedSizeCalculatorHelper <T, C> .calculateSerializedSize = SerializedSizeCalculatorHelper <T, C> .calculateSerializedSizeCore; return; } SerializedSizeCalculatorHelper <T, C> .calculateSerializedSize = new SerializedSizeCalculatorHelper <T, C> .CalculateSerializedSizeDelegate(SerializedSizeCalculatorHelper <T, C> .CalculateSerializedSizeVirtual); }