public void EmitDeserialize(Emit <Func <BinaryReader, object> > emiter, Local value) { var elementType = value.LocalType.GetElementType(); if (_length <= 0) { emiter.Call(typeof(Array) .GetMethod(nameof(Array.Empty)) .GetGenericMethodDefinition() .MakeGenericMethod(elementType)); emiter.StoreLocal(value); } else { // value = new [length] emiter.LoadConstant(_length); emiter.NewArray(elementType); emiter.StoreLocal(value); var loop = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "Loop" + Guid.NewGuid()); var loopCheck = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "LoopCheck" + Guid.NewGuid()); // Little optimization for byte arrays if (elementType == typeof(byte)) { // value = reader.ReadBytes(length); emiter.LoadArgument(1); emiter.LoadConstant(_length); emiter.CallVirtual(typeof(BinaryReader).GetMethod(nameof(BinaryReader.ReadBytes))); emiter.StoreLocal(value); } else { using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <int>("i")) { emiter.MarkLabel(loop); emiter.CallDeserializerForType(elementType, element); // value[i] = element emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadLocal(element); emiter.StoreElement(elementType); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadConstant(_length); emiter.BranchIfLess(loop); } } } }
public void EmitSerialize(Emit emiter, Local value) { var elementType = value.LocalType.GetElementType(); using (var length = emiter.DeclareLocal <int>("length")) { // length = value.Length emiter.LoadLocal(value); emiter.Call(value.LocalType.GetProperty(nameof(Array.Length)).GetMethod); emiter.StoreLocal(length); emiter.CallSerializerForType(length.LocalType, length); var loop = emiter.DefineLabel(); var loopCheck = emiter.DefineLabel(); using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <int>("i")) { emiter.Branch(loopCheck); emiter.MarkLabel(loop); // element = value[i] emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadElement(elementType); emiter.StoreLocal(element); if (_compiler != null) { _compiler.EmitSerialize(emiter, element); } else if (_serializer != null) { emiter.CallSerializer(_serializer, element); } else { emiter.CallSerializerForType(elementType, element); } // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadLocal(length); emiter.BranchIfLess(loop); } } }
public void EmitDeserialize(Emit emiter, Local value) { var elementType = value.LocalType.GetElementType(); //value = new Type[100]; emiter.LoadConstant(100); emiter.NewArray(elementType); emiter.StoreLocal(value); var loop = emiter.DefineLabel(); var loopCheck = emiter.DefineLabel(); using (var ex = emiter.DeclareLocal <Exception>("_ex")) using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <int>("i")) { emiter.MarkLabel(loop); var eb = emiter.BeginExceptionBlock(); if (_compiler != null) { _compiler.EmitDeserialize(emiter, element); } else if (_serializer != null) { emiter.CallDeserializer(_serializer, element); } else { emiter.CallDeserializerForType(elementType, element); } var cb = emiter.BeginCatchBlock <Exception>(eb); emiter.StoreLocal(ex); emiter.EndCatchBlock(cb); emiter.EndExceptionBlock(eb); // value[i] = element emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadLocal(element); emiter.StoreElement(elementType); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadConstant(100); emiter.BranchIfLess(loop); } }
public void EmitSerialize(Emit emiter, Local value) { var elementType = value.LocalType.GetElementType(); using (var length = emiter.DeclareLocal <int>("length")) { // length = value.Length emiter.LoadLocal(value); emiter.Call(value.LocalType.GetProperty(nameof(Array.Length)).GetMethod); emiter.StoreLocal(length); emiter.CallSerializerForType(length.LocalType, length); var loop = emiter.DefineLabel(); var loopCheck = emiter.DefineLabel(); using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <int>("i")) { emiter.Branch(loopCheck); emiter.MarkLabel(loop); // element = value[i] emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadElement(elementType); emiter.StoreLocal(element); // writer.Write((byte)i) emiter.LoadArgument(1); emiter.LoadLocal(i); emiter.Convert <byte>(); emiter.CallVirtual(typeof(BinaryWriter).GetMethod(nameof(BinaryWriter.Write), new[] { typeof(byte) })); emiter.CallSerializerForType(elementType, element); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadLocal(length); emiter.BranchIfLess(loop); } } }
public void EmitSerialize(Emit emiter, Local value) { // ToDo check for null var elementType = value.LocalType.GetElementType(); using (var length = emiter.DeclareLocal <int>("length")) { // length = value.Length emiter.LoadLocal(value); emiter.Call(value.LocalType.GetProperty(nameof(Array.Length)).GetMethod); emiter.StoreLocal(length); // ProudNetBinaryWriterExtensions.WriteScalar(writer, length) emiter.LoadArgument(1); emiter.LoadLocal(length); emiter.Call(ReflectionHelper.GetMethod((BinaryWriter x) => x.WriteScalar(default(int)))); var loop = emiter.DefineLabel(); var loopCheck = emiter.DefineLabel(); using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <int>("i")) { emiter.Branch(loopCheck); emiter.MarkLabel(loop); // element = value[i] emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadElement(elementType); emiter.StoreLocal(element); emiter.CallSerializerForType(elementType, element); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadLocal(length); emiter.BranchIfLess(loop); } } }
public void EmitSerialize(Emit emiter, Local value) { var elementType = value.LocalType.GetElementType(); using (var length = emiter.DeclareLocal <short>("length")) { // length = value.Length emiter.LoadLocal(value); emiter.Call(value.LocalType.GetProperty(nameof(Array.Length)).GetMethod); emiter.StoreLocal(length); emiter.CallSerializerForType(length.LocalType, length); var loop = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "Loop" + Guid.NewGuid()); var loopCheck = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "LoopCheck" + Guid.NewGuid()); using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <int>("i")) { emiter.Branch(loopCheck); emiter.MarkLabel(loop); // element = value[i] emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadElement(elementType); emiter.StoreLocal(element); emiter.CallSerializerForType(elementType, element); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadLocal(length); emiter.BranchIfLess(loop); } } }
public void EmitSerialize(Emit <Action <BinaryWriter, object> > emiter, Local value) { var elementType = value.LocalType.GetElementType(); if (_length <= 0) { return; } var loop = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "Loop" + Guid.NewGuid()); var loopCheck = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "LoopCheck" + Guid.NewGuid()); using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <int>("i")) { emiter.Branch(loopCheck); emiter.MarkLabel(loop); // element = value[i] emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadElement(elementType); emiter.StoreLocal(element); emiter.CallSerializerForType(elementType, element); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadConstant(_length); emiter.BranchIfLess(loop); } }
public void EmitDeserialize(Emit <Func <BinaryReader, object> > emiter, Local value) { var elementType = value.LocalType.GetElementType(); var emptyArray = emiter.DefineLabel(nameof(ArrayWithIntPrefixAndIndexSerializer) + "EmptyArray" + Guid.NewGuid()); var end = emiter.DefineLabel(nameof(ArrayWithIntPrefixAndIndexSerializer) + "End" + Guid.NewGuid()); using (var length = emiter.DeclareLocal <int>("length")) { emiter.CallDeserializerForType(length.LocalType, length); // if(length < 1) { // value = Array.Empty<>() // return // } emiter.LoadLocal(length); emiter.LoadConstant(1); emiter.BranchIfLess(emptyArray); // value = new [length] emiter.LoadLocal(length); emiter.NewArray(elementType); emiter.StoreLocal(value); var loop = emiter.DefineLabel(nameof(ArrayWithIntPrefixAndIndexSerializer) + "Loop" + Guid.NewGuid()); var loopCheck = emiter.DefineLabel(nameof(ArrayWithIntPrefixAndIndexSerializer) + "LoopCheck" + Guid.NewGuid()); using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <int>("i")) { emiter.MarkLabel(loop); // reader.ReadByte() -> index emiter.LoadArgument(1); emiter.CallVirtual(typeof(BinaryReader).GetMethod(nameof(BinaryReader.ReadByte))); emiter.Pop(); emiter.CallDeserializerForType(elementType, element); // value[i] = element emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadLocal(element); emiter.StoreElement(elementType); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadLocal(length); emiter.BranchIfLess(loop); } emiter.Branch(end); } // value = Array.Empty<>() emiter.MarkLabel(emptyArray); emiter.Call(typeof(Array) .GetMethod(nameof(Array.Empty)) .GetGenericMethodDefinition() .MakeGenericMethod(elementType)); emiter.StoreLocal(value); emiter.MarkLabel(end); }
public void EmitDeserialize(Emit emiter, Local value) { var elementType = value.LocalType.GetElementType(); var emptyArray = emiter.DefineLabel(); var end = emiter.DefineLabel(); using (var length = emiter.DeclareLocal <short>("length")) { emiter.CallDeserializerForType(length.LocalType, length); // if(length < 1) { // value = Array.Empty<>() // return // } emiter.LoadLocal(length); emiter.LoadConstant(1); emiter.BranchIfLess(emptyArray); // value = new [length] emiter.LoadLocal(length); emiter.NewArray(elementType); emiter.StoreLocal(value); var loop = emiter.DefineLabel(); var loopCheck = emiter.DefineLabel(); // Little optimization for byte arrays if (elementType == typeof(byte)) { // value = reader.ReadBytes(length); emiter.LoadArgument(1); emiter.LoadLocal(length); emiter.CallVirtual(typeof(BinaryReader).GetMethod(nameof(BinaryReader.ReadBytes))); emiter.StoreLocal(value); emiter.Branch(end); } else { using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <int>("i")) { emiter.MarkLabel(loop); emiter.CallDeserializerForType(elementType, element); // value[i] = element emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadLocal(element); emiter.StoreElement(elementType); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadLocal(length); emiter.BranchIfLess(loop); } } emiter.Branch(end); } // value = Array.Empty<>() emiter.MarkLabel(emptyArray); emiter.Call(typeof(Array) .GetMethod(nameof(Array.Empty)) .GetGenericMethodDefinition() .MakeGenericMethod(elementType)); emiter.StoreLocal(value); emiter.MarkLabel(end); }
public void EmitDeserialize(Emit emiter, Local value) { var elementType = value.LocalType.GetElementType(); var emptyArray = emiter.DefineLabel(); var end = emiter.DefineLabel(); using (var length = emiter.DeclareLocal <T>("length")) { emiter.CallDeserializerForType(length.LocalType, length); // if(length < 1) { // value = Array.Empty<>() // return // } emiter.LoadLocal(length); emiter.LoadConstant(1); emiter.BranchIfLess(emptyArray); // value = new [length] emiter.LoadLocal(length); emiter.NewArray(elementType); emiter.StoreLocal(value); var loop = emiter.DefineLabel(); var loopCheck = emiter.DefineLabel(); using (var element = emiter.DeclareLocal(elementType, "element")) using (var i = emiter.DeclareLocal <T>("i")) { emiter.MarkLabel(loop); if (_compiler != null) { _compiler.EmitDeserialize(emiter, element); } else if (_serializer != null) { emiter.CallDeserializer(_serializer, element); } else { emiter.CallDeserializerForType(elementType, element); } // value[i] = element emiter.LoadLocal(value); emiter.LoadLocal(i); emiter.LoadLocal(element); emiter.StoreElement(elementType); // ++i emiter.LoadLocal(i); emiter.LoadConstant(1); emiter.Add(); emiter.StoreLocal(i); // i < length emiter.MarkLabel(loopCheck); emiter.LoadLocal(i); emiter.LoadLocal(length); emiter.BranchIfLess(loop); } emiter.Branch(end); } // value = Array.Empty<>() emiter.MarkLabel(emptyArray); emiter.Call(typeof(Array) .GetMethod(nameof(Array.Empty)) .GetGenericMethodDefinition() .MakeGenericMethod(elementType)); emiter.StoreLocal(value); emiter.MarkLabel(end); }