private ILDelegateBuilder <SerializationManager.Serializer> EmitSerializer(Type type, List <FieldInfo> fields) { var il = new ILDelegateBuilder <SerializationManager.Serializer>( FieldBuilder, type.Name + "Serializer", SerializationMethodInfos, SerializationMethodInfos.SerializerDelegate); // Declare local variables. var typedInput = il.DeclareLocal(type); // Set the typed input variable from the method parameter. il.LoadArgument(0); il.CastOrUnbox(type); il.StoreLocal(typedInput); // Serialize each field foreach (var field in fields) { SimpleTypeSerializer serializer; var fieldType = field.FieldType.GetTypeInfo(); var typeHandle = field.FieldType.TypeHandle; if (fieldType.IsEnum) { typeHandle = fieldType.GetEnumUnderlyingType().TypeHandle; } if (DirectSerializers.TryGetValue(typeHandle, out serializer)) { il.LoadArgument(1); il.Call(SerializationMethodInfos.GetStreamFromSerializationContext); il.LoadLocal(typedInput); il.LoadField(field); il.Call(serializer.WriteMethod); } else { var serializeMethod = SerializationMethodInfos.SerializeInner; // Load the field. il.LoadLocal(typedInput); il.LoadField(field); il.BoxIfValueType(field.FieldType); // Serialize the field. il.LoadArgument(1); il.LoadType(field.FieldType); il.Call(serializeMethod); } } il.Return(); return(il); }
private ILDelegateBuilder <SerializationManager.DeepCopier> EmitCopier(Type type, List <FieldInfo> fields) { var il = new ILDelegateBuilder <SerializationManager.DeepCopier>( FieldBuilder, type.Name + "DeepCopier", SerializationMethodInfos, SerializationMethodInfos.DeepCopierDelegate); // Declare local variables. var result = il.DeclareLocal(type); var typedInput = il.DeclareLocal(type); // Set the typed input variable from the method parameter. il.LoadArgument(0); il.CastOrUnbox(type); il.StoreLocal(typedInput); // Construct the result. il.CreateInstance(type, result); // Record the object. il.LoadArgument(1); // Load 'context' parameter. il.LoadArgument(0); // Load 'original' parameter. il.LoadLocal(result); // Load 'result' local. il.BoxIfValueType(type); il.Call(SerializationMethodInfos.RecordObjectWhileCopying); // Copy each field. foreach (var field in fields) { // Load the field. il.LoadLocalAsReference(type, result); il.LoadLocal(typedInput); il.LoadField(field); // Deep-copy the field if needed, otherwise just leave it as-is. if (!field.FieldType.IsOrleansShallowCopyable()) { var copyMethod = SerializationMethodInfos.DeepCopyInner; il.BoxIfValueType(field.FieldType); il.LoadArgument(1); il.Call(copyMethod); il.CastOrUnbox(field.FieldType); } // Store the copy of the field on the result. il.StoreField(field); } il.LoadLocal(result); il.BoxIfValueType(type); il.Return(); return(il); }
private ILDelegateBuilder <Serializer> EmitSerializer(Type type, List <FieldInfo> fields, SerializationCallbacks callbacks) { var il = new ILDelegateBuilder <Serializer>( FieldBuilder, type.Name + "Serializer", SerializationMethodInfos.SerializerDelegate); // Declare local variables. var typedInput = il.DeclareLocal(type); var streamingContext = default(ILDelegateBuilder <Serializer> .Local); if (callbacks.OnSerializing != null || callbacks.OnSerialized != null) { streamingContext = il.DeclareLocal(typeof(StreamingContext)); il.LoadLocalAddress(streamingContext); il.LoadConstant((int)StreamingContextStates.All); il.LoadArgument(1); il.Call(typeof(StreamingContext).GetConstructor(new[] { typeof(StreamingContextStates), typeof(object) })); } // Set the typed input variable from the method parameter. il.LoadArgument(0); il.CastOrUnbox(type); il.StoreLocal(typedInput); if (callbacks.OnSerializing != null) { il.LoadLocalAsReference(type, typedInput); il.LoadLocal(streamingContext); il.Call(callbacks.OnSerializing); } // Serialize each field foreach (var field in fields) { var fieldType = field.FieldType; var typeHandle = field.FieldType.TypeHandle; if (fieldType.IsEnum) { typeHandle = fieldType.GetEnumUnderlyingType().TypeHandle; } if (DirectSerializers.TryGetValue(typeHandle, out var serializer)) { il.LoadArgument(1); il.Call(SerializationMethodInfos.GetStreamFromSerializationContext); il.LoadLocal(typedInput); il.LoadField(field); il.Call(serializer.WriteMethod); } else { var serializeMethod = SerializationMethodInfos.SerializeInner; // Load the field. il.LoadLocal(typedInput); il.LoadField(field); il.BoxIfValueType(field.FieldType); // Serialize the field. il.LoadArgument(1); il.LoadType(field.FieldType); il.Call(serializeMethod); } } if (callbacks.OnSerialized != null) { il.LoadLocalAsReference(type, typedInput); il.LoadLocal(streamingContext); il.Call(callbacks.OnSerialized); } il.Return(); return(il); }