static void EmitSerializeValue(ILGenerator il, TypeInfo type, UnionSerializationInfo.EmittableMember member) { var t = member.Type; if (IsOptimizeTargetType(t)) { EmitOffsetPlusEqual(il, null, () => { il.EmitLoadArg(type, 3); member.EmitLoadValue(il); if (t == typeof(byte[])) { il.EmitCall(MessagePackBinaryTypeInfo.WriteBytes); } else { il.EmitCall(MessagePackBinaryTypeInfo.TypeInfo.GetDeclaredMethods("Write" + t.Name).OrderByDescending(x => x.GetParameters().Length).First()); } }); } else { EmitOffsetPlusEqual(il, () => { il.EmitLdarg(4); il.Emit(OpCodes.Call, getFormatterWithVerify.MakeGenericMethod(t)); }, () => { il.EmitLoadArg(type, 3); member.EmitLoadValue(il); il.EmitLdarg(4); il.EmitCall(getSerialize(t)); }); } }
static void EmitDeserializeValue( ILGenerator il, DeserializeInfo info, int index, ArgumentField argReader, ArgumentField argOptions, LocalBuilder localResolver ) { Label storeLabel = il.DefineLabel(); UnionSerializationInfo.EmittableMember member = info.MemberInfo; Type t = member.Type; if (IsOptimizeTargetType(t)) { if (!t.GetTypeInfo().IsValueType) { // As a nullable type (e.g. byte[] and string) we need to first call TryReadNil // if (reader.TryReadNil()) Label readNonNilValueLabel = il.DefineLabel(); argReader.EmitLdarg(); il.EmitCall(MessagePackReaderTypeInfo.TryReadNil); il.Emit(OpCodes.Brfalse_S, readNonNilValueLabel); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Br, storeLabel); il.MarkLabel(readNonNilValueLabel); } argReader.EmitLdarg(); if (t == typeof(byte[])) { LocalBuilder local = il.DeclareLocal(typeof(ReadOnlySequence <byte>?)); il.EmitCall(MessagePackReaderTypeInfo.ReadBytes); il.EmitStloc(local); il.EmitLdloca(local); il.EmitCall(ArrayFromNullableReadOnlySequence); } else { il.EmitCall(MessagePackReaderTypeInfo.TypeInfo.GetDeclaredMethods("Read" + t.Name).First(x => x.GetParameters().Length == 0)); } } else { il.EmitLdloc(localResolver); il.EmitCall(getFormatterWithVerify.MakeGenericMethod(t)); argReader.EmitLdarg(); argOptions.EmitLoad(); il.EmitCall(getDeserialize(t)); } il.MarkLabel(storeLabel); il.EmitStloc(info.LocalField); }
static void EmitSerializeValue( ILGenerator il, TypeInfo type, UnionSerializationInfo.EmittableMember member, int index, ArgumentField argWriter, ArgumentField argValue, ArgumentField argOptions, LocalBuilder localResolver ) { Label endLabel = il.DefineLabel(); Type t = member.Type; if (IsOptimizeTargetType(t)) { if (!t.GetTypeInfo().IsValueType) { // As a nullable type (e.g. byte[] and string) we need to call WriteNil for null values. Label writeNonNilValueLabel = il.DefineLabel(); LocalBuilder memberValue = il.DeclareLocal(t); argValue.EmitLoad(); member.EmitLoadValue(il); il.Emit(OpCodes.Dup); il.EmitStloc(memberValue); il.Emit(OpCodes.Brtrue, writeNonNilValueLabel); argWriter.EmitLoad(); il.EmitCall(MessagePackWriterTypeInfo.WriteNil); il.Emit(OpCodes.Br, endLabel); il.MarkLabel(writeNonNilValueLabel); argWriter.EmitLoad(); il.EmitLdloc(memberValue); } else { argWriter.EmitLoad(); argValue.EmitLoad(); member.EmitLoadValue(il); } if (t == typeof(byte[])) { il.EmitCall(ReadOnlySpanFromByteArray); il.EmitCall(MessagePackWriterTypeInfo.WriteBytes); } else { il.EmitCall(typeof(MessagePackWriter).GetRuntimeMethod("Write", new Type[] { t })); } } else { il.EmitLdloc(localResolver); il.Emit(OpCodes.Call, getFormatterWithVerify.MakeGenericMethod(t)); argWriter.EmitLoad(); argValue.EmitLoad(); member.EmitLoadValue(il); argOptions.EmitLoad(); il.EmitCall(getSerialize(t)); } il.MarkLabel(endLabel); }