public void EmitSerialize(CompilerContext context, Local value) { using (var address = context.Emit.DeclareLocal <string>("str")) using (var port = context.Emit.DeclareLocal <ushort>("port")) { var isNullLabel = context.Emit.DefineLabel(); var writeLabel = context.Emit.DefineLabel(); // if (value == null) goto isNull context.Emit.LoadLocal(value); context.Emit.LoadNull(); context.Emit.BranchIfEqual(isNullLabel); // address = value.Address.ToString() context.Emit.LoadLocal(value); context.Emit.Call(typeof(IPEndPoint).GetProperty(nameof(IPEndPoint.Address)).GetMethod); context.Emit.CallVirtual(ReflectionHelper.GetMethod((IPEndPoint _) => _.ToString())); context.Emit.StoreLocal(address); // port = (ushort)value.Port context.Emit.LoadLocal(value); context.Emit.Call(typeof(IPEndPoint).GetProperty(nameof(IPEndPoint.Port)).GetMethod); context.Emit.Convert <ushort>(); context.Emit.StoreLocal(port); context.Emit.Branch(writeLabel); context.Emit.MarkLabel(isNullLabel); // address = "255.255.255.255" context.Emit.LoadConstant("255.255.255.255"); context.Emit.StoreLocal(address); context.Emit.MarkLabel(writeLabel); // ProudNetBinaryWriterExtensions.WriteProudString(writer, address, false) context.Emit.LoadReaderOrWriterParam(); context.Emit.LoadLocal(address); context.Emit.LoadConstant(false); context.Emit.Call(ReflectionHelper.GetMethod((BinaryWriter _) => _.WriteProudString(default(string), default(bool)))); // writer.Write(port) context.EmitSerialize(port); } }
public void EmitSerialize(CompilerContext context, Local value) { var elementType = value.LocalType.GetElementType(); using (var length = context.Emit.DeclareLocal <int>("length")) { var writeLabel = context.Emit.DefineLabel(); // if (value != null) goto write context.Emit.LoadLocal(value); context.Emit.LoadNull(); context.Emit.CompareEqual(); context.Emit.BranchIfFalse(writeLabel); // value = Array.Empty<>() context.Emit.Call(typeof(Array) .GetMethod(nameof(Array.Empty)) .GetGenericMethodDefinition() .MakeGenericMethod(elementType)); context.Emit.StoreLocal(value); // length = value.Length context.Emit.MarkLabel(writeLabel); context.Emit.LoadLocal(value); context.Emit.Call(value.LocalType.GetProperty(nameof(Array.Length)).GetMethod); context.Emit.StoreLocal(length); // ProudNetBinaryWriterExtensions.WriteScalar(writer, length) context.Emit.LoadReaderOrWriterParam(); context.Emit.LoadLocal(length); context.Emit.Call(ReflectionHelper.GetMethod((BinaryWriter _) => _.WriteScalar(default(int)))); var loopLabel = context.Emit.DefineLabel(); var loopCheckLabel = context.Emit.DefineLabel(); using (var element = context.Emit.DeclareLocal(elementType, "element")) using (var i = context.Emit.DeclareLocal <int>("i")) { context.Emit.Branch(loopCheckLabel); context.Emit.MarkLabel(loopLabel); // element = value[i] context.Emit.LoadLocal(value); context.Emit.LoadLocal(i); context.Emit.LoadElement(elementType); context.Emit.StoreLocal(element); context.EmitSerialize(element); // ++i context.Emit.LoadLocal(i); context.Emit.LoadConstant(1); context.Emit.Add(); context.Emit.StoreLocal(i); // i < length context.Emit.MarkLabel(loopCheckLabel); context.Emit.LoadLocal(i); context.Emit.LoadLocal(length); context.Emit.BranchIfLess(loopLabel); } } }