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 <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.Deserializer> EmitDeserializer(Type type, List <FieldInfo> fields) { var il = new ILDelegateBuilder <SerializationManager.Deserializer>( FieldBuilder, type.Name + "Deserializer", SerializationMethodInfos.DeserializerDelegate); // Declare local variables. var result = il.DeclareLocal(type); // Construct the result. il.CreateInstance(type, result, SerializationMethodInfos.GetUninitializedObject); // Record the object. il.LoadArgument(1); // Load the 'context' parameter. il.LoadLocal(result); il.BoxIfValueType(type); il.Call(SerializationMethodInfos.RecordObjectWhileDeserializing); // Deserialize each field. foreach (var field in fields) { // Deserialize the field. SimpleTypeSerializer serializer; var fieldType = field.FieldType.GetTypeInfo(); if (fieldType.IsEnum) { var typeHandle = fieldType.GetEnumUnderlyingType().TypeHandle; il.LoadLocalAsReference(type, result); il.LoadArgument(1); il.Call(SerializationMethodInfos.GetStreamFromDeserializationContext); il.Call(DirectSerializers[typeHandle].ReadMethod); il.StoreField(field); } else if (DirectSerializers.TryGetValue(field.FieldType.TypeHandle, out serializer)) { il.LoadLocalAsReference(type, result); il.LoadArgument(1); il.Call(SerializationMethodInfos.GetStreamFromDeserializationContext); il.Call(serializer.ReadMethod); il.StoreField(field); } else { var deserializeMethod = SerializationMethodInfos.DeserializeInner; il.LoadLocalAsReference(type, result); il.LoadType(field.FieldType); il.LoadArgument(1); il.Call(deserializeMethod); // Store the value on the result. il.CastOrUnbox(field.FieldType); il.StoreField(field); } } il.LoadLocal(result); il.BoxIfValueType(type); il.Return(); return(il); }
private ILDelegateBuilder <Deserializer> EmitDeserializer(Type type, List <FieldInfo> fields, SerializationCallbacks callbacks) { var il = new ILDelegateBuilder <Deserializer>( FieldBuilder, type.Name + "Deserializer", SerializationMethodInfos.DeserializerDelegate); var streamingContext = default(ILDelegateBuilder <Deserializer> .Local); if (callbacks.OnDeserializing != null || callbacks.OnDeserialized != 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) })); } // Declare local variables. var result = il.DeclareLocal(type); // Construct the result. il.CreateInstance(type, result, SerializationMethodInfos.GetUninitializedObject); // Record the object. il.LoadArgument(1); // Load the 'context' parameter. il.LoadLocal(result); il.BoxIfValueType(type); il.Call(SerializationMethodInfos.RecordObjectWhileDeserializing); if (callbacks.OnDeserializing != null) { il.LoadLocalAsReference(type, result); il.LoadLocal(streamingContext); il.Call(callbacks.OnDeserializing); } // Deserialize each field. foreach (var field in fields) { // Deserialize the field. var fieldType = field.FieldType; if (fieldType.IsEnum) { var typeHandle = fieldType.GetEnumUnderlyingType().TypeHandle; il.LoadLocalAsReference(type, result); il.LoadArgument(1); il.Call(SerializationMethodInfos.GetStreamFromDeserializationContext); il.Call(DirectSerializers[typeHandle].ReadMethod); il.StoreField(field); } else if (DirectSerializers.TryGetValue(field.FieldType.TypeHandle, out var serializer)) { il.LoadLocalAsReference(type, result); il.LoadArgument(1); il.Call(SerializationMethodInfos.GetStreamFromDeserializationContext); il.Call(serializer.ReadMethod); il.StoreField(field); } else { var deserializeMethod = SerializationMethodInfos.DeserializeInner; il.LoadLocalAsReference(type, result); il.LoadType(field.FieldType); il.LoadArgument(1); il.Call(deserializeMethod); // Store the value on the result. il.CastOrUnbox(field.FieldType); il.StoreField(field); } } if (callbacks.OnDeserialized != null) { il.LoadLocalAsReference(type, result); il.LoadLocal(streamingContext); il.Call(callbacks.OnDeserialized); } // If the type implements the IOnDeserialized lifecycle handler, call that method now. if (typeof(IOnDeserialized).IsAssignableFrom(type)) { il.LoadLocalAsReference(type, result); il.LoadArgument(1); var concreteMethod = GetConcreteMethod( type, TypeUtils.Method((IOnDeserialized i) => i.OnDeserialized(default(ISerializerContext)))); il.Call(concreteMethod); } // If the type implements the IDeserializationCallback lifecycle handler, call that method now. if (typeof(IDeserializationCallback).IsAssignableFrom(type)) { il.LoadLocalAsReference(type, result); il.LoadArgument(1); var concreteMethod = GetConcreteMethod( type, TypeUtils.Method((IDeserializationCallback i) => i.OnDeserialization(default(object)))); il.Call(concreteMethod); } 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); }