public IntPtr BuildReader(Type type, bool ignoreCustomSerialization) { var constantsBuilder = module.DefineType(type.Name + "_GroBufReader_" + Guid.NewGuid(), TypeAttributes.Class | TypeAttributes.Public); constantsBuilder.DefineField("pointers", typeof(IntPtr[]), FieldAttributes.Private | FieldAttributes.Static); constantsBuilder.DefineField("delegates", typeof(Delegate[]), FieldAttributes.Private | FieldAttributes.Static); var constantsBuilderContext = new ReaderConstantsBuilderContext(groBufReader, constantsBuilder, readerCollection, dataMembersExtractor); constantsBuilderContext.BuildConstants(type, true, ignoreCustomSerialization); var constantsType = constantsBuilder.CreateTypeInfo(); var fields = constantsBuilderContext.GetFields().ToDictionary(pair => pair.Key, pair => pair.Value.Select(constantsType.GetField).ToArray()); var context = new ReaderTypeBuilderContext(groBufReader, module, constantsType, fields, readerCollection, dataMembersExtractor); var reader = context.GetReader(type, true, ignoreCustomSerialization); var initializer = BuildInitializer(constantsType.GetField("pointers", BindingFlags.Static | BindingFlags.NonPublic), constantsType.GetField("delegates", BindingFlags.Static | BindingFlags.NonPublic)); var compiledDynamicMethods = context.GetMethods(); var pointers = new IntPtr[compiledDynamicMethods.Length]; var delegates = new Delegate[compiledDynamicMethods.Length]; foreach (var pair in compiledDynamicMethods) { var compiledDynamicMethod = pair.Value; var index = compiledDynamicMethod.Index; pointers[index] = compiledDynamicMethod.Pointer; delegates[index] = compiledDynamicMethod.Delegate; if (compiledDynamicMethod.Pointer != reader.Pointer) { groBufReader.readMethodsWithCustomSerialization[pair.Key] = (IntPtr?)compiledDynamicMethod.Pointer; } } initializer(pointers, delegates, context.GetFieldInitializers()); return(reader.Pointer); }
public static void LoadReader(GroboIL il, Type type, ReaderTypeBuilderContext context) { var counter = context.GetReader(type); if (counter.Pointer != IntPtr.Zero) { il.Ldc_IntPtr(counter.Pointer); } else { il.Ldfld(context.ConstantsType.GetField("pointers", BindingFlags.Static | BindingFlags.NonPublic)); il.Ldc_I4(counter.Index); il.Ldelem(typeof(IntPtr)); } }