protected override void EmitWrite(ProtoBuf.Compiler.CompilerContext ctx, ProtoBuf.Compiler.Local valueFrom) { if (arrayType.GetArrayRank() > 1) { return; } // int i and T[] arr using (Compiler.Local arr = ctx.GetLocalWithValue(arrayType, valueFrom)) using (Compiler.Local len = new Compiler.Local(ctx, typeof(int))) using (Compiler.Local i = new ProtoBuf.Compiler.Local(ctx, typeof(int))) using (Compiler.Local writeObject = new Compiler.Local(ctx, typeof(bool))) { // int len = arr.Count; ctx.LoadValue(arr); ctx.LoadValue(arrayType.GetProperty("Length")); ctx.StoreValue(len); // writeObject = true; ctx.LoadValue(true); ctx.StoreValue(writeObject); bool writePacked = (options & OPTIONS_WritePacked) != 0; using (Compiler.Local token = writePacked ? new Compiler.Local(ctx, typeof(SubItemToken)) : null) { if (writePacked) { ctx.LoadValue(fieldNumber); ctx.LoadValue((int)WireType.String); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoWriter).GetMethod("WriteFieldHeader")); ctx.LoadValue(arr); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoWriter).GetMethod("StartSubItem")); ctx.StoreValue(token); ctx.LoadValue(fieldNumber); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoWriter).GetMethod("SetPackedField")); } else { ctx.LoadValue(fieldNumber); ctx.LoadValue((int)WireType.Variant); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoWriter).GetMethod("WriteFieldHeader")); if (AsReference) { using (Compiler.Local existing = new Compiler.Local(ctx, typeof(bool))) using (Compiler.Local objectKey = new Compiler.Local(ctx, typeof(int))) { //int objectKey = dest.NetCache.AddObjectKey(value, out existing); ctx.LoadReaderWriter(); ctx.LoadValue(typeof(ProtoWriter).GetProperty("NetCache")); //dest.NetCache ctx.LoadValue(arr); ctx.LoadAddress(existing, typeof(bool)); ctx.EmitCall(typeof(NetObjectCache).GetMethod("AddObjectKey", new Type[] { typeof(object), typeof(bool).MakeByRefType() })); ctx.StoreValue(objectKey); //writeObject = !existing; ctx.LoadValue(existing); Compiler.CodeLabel @writeBoolean = ctx.DefineLabel(); Compiler.CodeLabel @trueCase = ctx.DefineLabel(); ctx.BranchIfTrue(@trueCase, true); ctx.LoadValue(true); ctx.Branch(@writeBoolean, true); ctx.MarkLabel(@trueCase); ctx.LoadValue(false); ctx.MarkLabel(@writeBoolean); ctx.StoreValue(writeObject); //ProtoWriter.WriteUInt32(existing ? (uint)objectKey : 0, dest); using (Compiler.Local valueToWrite = new Compiler.Local(ctx, typeof(uint))) { ctx.LoadValue(0); ctx.StoreValue(valueToWrite); Compiler.CodeLabel @endValueWrite = ctx.DefineLabel(); ctx.LoadValue(existing); ctx.BranchIfFalse(@endValueWrite, true); ctx.LoadValue(objectKey); ctx.CastToObject(typeof(uint)); ctx.StoreValue(valueToWrite); ctx.MarkLabel(@endValueWrite); ctx.LoadValue(valueToWrite); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoWriter).GetMethod("WriteUInt32")); } } } else { // bool isEmpty = len == 0; // ProtoWriter.WriteBoolean(isEmpty, dest); ctx.LoadValue(len); ctx.LoadValue(0); ctx.TestEqual(); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoWriter).GetMethod("WriteBoolean")); } } Compiler.CodeLabel @endWrite = ctx.DefineLabel(); ctx.LoadValue(writeObject); ctx.BranchIfFalse(@endWrite, false); EmitWriteArrayLoop(ctx, i, arr); ctx.MarkLabel(@endWrite); if (writePacked) { ctx.LoadValue(token); ctx.LoadReaderWriter(); ctx.EmitCall(typeof(ProtoWriter).GetMethod("EndSubItem")); } } } }